Skip to content

Commit 1cdea4a

Browse files
committed
Implemented /worldborder command.
Signed-off-by: Pavel Erokhin (MairwunNx) <MairwunNx@gmail.com>
1 parent e22b14b commit 1cdea4a

3 files changed

Lines changed: 369 additions & 1 deletion

File tree

src/main/kotlin/com/mairwunnx/projectessentials/core/EntryPoint.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ internal class EntryPoint : EssBase() {
130130
TitleCommand.register(dispatcher)
131131
TriggerCommand.register(dispatcher)
132132
WeatherCommand.register(dispatcher)
133+
WorldBorderCommand.register(dispatcher)
133134

134135
if (isDedicatedServer) {
135136
logger.info("Replacing native vanilla server commands")

src/main/kotlin/com/mairwunnx/projectessentials/core/configuration/commands/CommandsConfiguration.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ internal data class CommandsConfiguration(
4949
var saveon: List<String> = listOf("saveon"),
5050
var spawnpoint: List<String> = listOf("respawnhere"),
5151
var summon: List<String> = listOf("spawnmob"),
52-
var tellraw: List<String> = listOf("tr")
52+
var tellraw: List<String> = listOf("tr"),
53+
var worldborder: List<String> = listOf("wb")
5354
)
5455
}
Lines changed: 366 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,366 @@
1+
package com.mairwunnx.projectessentials.core.vanilla.commands
2+
3+
import com.mairwunnx.projectessentials.cooldown.essentials.CommandsAliases
4+
import com.mairwunnx.projectessentials.core.EntryPoint
5+
import com.mairwunnx.projectessentials.core.configuration.commands.CommandsConfigurationUtils
6+
import com.mairwunnx.projectessentials.core.helpers.PERMISSION_LEVEL
7+
import com.mojang.brigadier.CommandDispatcher
8+
import com.mojang.brigadier.arguments.FloatArgumentType
9+
import com.mojang.brigadier.arguments.IntegerArgumentType
10+
import com.mojang.brigadier.exceptions.CommandSyntaxException
11+
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType
12+
import net.minecraft.command.CommandException
13+
import net.minecraft.command.CommandSource
14+
import net.minecraft.command.Commands
15+
import net.minecraft.command.arguments.Vec2Argument
16+
import net.minecraft.util.math.MathHelper
17+
import net.minecraft.util.math.Vec2f
18+
import net.minecraft.util.text.TranslationTextComponent
19+
import org.apache.logging.log4j.LogManager
20+
import java.util.*
21+
22+
object WorldBorderCommand {
23+
private val CENTER_NO_CHANGE = SimpleCommandExceptionType(
24+
TranslationTextComponent("commands.worldborder.center.failed")
25+
)
26+
private val SIZE_NO_CHANGE = SimpleCommandExceptionType(
27+
TranslationTextComponent("commands.worldborder.set.failed.nochange")
28+
)
29+
private val SIZE_TOO_SMALL = SimpleCommandExceptionType(
30+
TranslationTextComponent("commands.worldborder.set.failed.small.")
31+
)
32+
private val SIZE_TOO_BIG = SimpleCommandExceptionType(
33+
TranslationTextComponent("commands.worldborder.set.failed.big.")
34+
)
35+
private val WARNING_TIME_NO_CHANGE = SimpleCommandExceptionType(
36+
TranslationTextComponent("commands.worldborder.warning.time.failed")
37+
)
38+
private val WARNING_DISTANCE_NO_CHANGE = SimpleCommandExceptionType(
39+
TranslationTextComponent("commands.worldborder.warning.distance.failed")
40+
)
41+
private val DAMAGE_BUFFER_NO_CHANGE = SimpleCommandExceptionType(
42+
TranslationTextComponent("commands.worldborder.damage.buffer.failed")
43+
)
44+
private val DAMAGE_AMOUNT_NO_CHANGE = SimpleCommandExceptionType(
45+
TranslationTextComponent("commands.worldborder.damage.amount.failed")
46+
)
47+
48+
private val logger = LogManager.getLogger()
49+
private var aliases =
50+
CommandsConfigurationUtils.getConfig().aliases.worldborder + "worldborder"
51+
52+
private fun tryAssignAliases() {
53+
if (!EntryPoint.cooldownInstalled) return
54+
CommandsAliases.aliases["worldborder"] = aliases.toMutableList()
55+
}
56+
57+
fun register(dispatcher: CommandDispatcher<CommandSource>) {
58+
logger.info("Replacing `/worldborder` vanilla command")
59+
tryAssignAliases()
60+
61+
aliases.forEach { command ->
62+
dispatcher.register(
63+
Commands.literal(command).then(
64+
Commands.literal("add").then(
65+
Commands.argument(
66+
"distance", FloatArgumentType.floatArg(-6.0E7f, 6.0E7f)
67+
).executes { p_198908_0_ ->
68+
setSize(
69+
p_198908_0_.source,
70+
p_198908_0_.source.world.worldBorder.diameter + FloatArgumentType.getFloat(
71+
p_198908_0_,
72+
"distance"
73+
).toDouble(),
74+
0L
75+
)
76+
}.then(
77+
Commands.argument(
78+
"time", IntegerArgumentType.integer(0)
79+
).executes { p_198901_0_ ->
80+
setSize(
81+
p_198901_0_.source,
82+
p_198901_0_.source.world.worldBorder.diameter + FloatArgumentType.getFloat(
83+
p_198901_0_,
84+
"distance"
85+
).toDouble(),
86+
p_198901_0_.source.world.worldBorder.timeUntilTarget + IntegerArgumentType.getInteger(
87+
p_198901_0_,
88+
"time"
89+
).toLong() * 1000L
90+
)
91+
}
92+
)
93+
)
94+
).then(
95+
Commands.literal("set").then(
96+
Commands.argument(
97+
"distance", FloatArgumentType.floatArg(-6.0E7f, 6.0E7f)
98+
).executes { p_198906_0_ ->
99+
setSize(
100+
p_198906_0_.source,
101+
FloatArgumentType.getFloat(p_198906_0_, "distance").toDouble(),
102+
0L
103+
)
104+
}.then(
105+
Commands.argument(
106+
"time", IntegerArgumentType.integer(0)
107+
).executes { p_198909_0_ ->
108+
setSize(
109+
p_198909_0_.source,
110+
FloatArgumentType.getFloat(p_198909_0_, "distance").toDouble(),
111+
IntegerArgumentType.getInteger(
112+
p_198909_0_,
113+
"time"
114+
).toLong() * 1000L
115+
)
116+
}
117+
)
118+
)
119+
).then(
120+
Commands.literal("center").then(
121+
Commands.argument(
122+
"pos", Vec2Argument.vec2()
123+
).executes { p_198893_0_ ->
124+
setCenter(
125+
p_198893_0_.source,
126+
Vec2Argument.getVec2f(p_198893_0_, "pos")
127+
)
128+
}
129+
)
130+
).then(
131+
Commands.literal("damage").then(
132+
Commands.literal("amount").then(
133+
Commands.argument(
134+
"damagePerBlock", FloatArgumentType.floatArg(0.0f)
135+
).executes { p_198897_0_ ->
136+
setDamageAmount(
137+
p_198897_0_.source,
138+
FloatArgumentType.getFloat(p_198897_0_, "damagePerBlock")
139+
)
140+
}
141+
)
142+
).then(
143+
Commands.literal("buffer").then(
144+
Commands.argument(
145+
"distance", FloatArgumentType.floatArg(0.0f)
146+
).executes { p_198905_0_ ->
147+
setDamageBuffer(
148+
p_198905_0_.source,
149+
FloatArgumentType.getFloat(p_198905_0_, "distance")
150+
)
151+
}
152+
)
153+
)
154+
).then(
155+
Commands.literal("get").executes { p_198900_0_ ->
156+
getSize(p_198900_0_.source)
157+
}
158+
).then(
159+
Commands.literal("warning").then(
160+
Commands.literal("distance").then(
161+
Commands.argument(
162+
"distance", IntegerArgumentType.integer(0)
163+
).executes { p_198892_0_ ->
164+
setWarningDistance(
165+
p_198892_0_.source,
166+
IntegerArgumentType.getInteger(p_198892_0_, "distance")
167+
)
168+
}
169+
)
170+
).then(
171+
Commands.literal("time").then(
172+
Commands.argument(
173+
"time", IntegerArgumentType.integer(0)
174+
).executes { p_198907_0_ ->
175+
setWarningTime(
176+
p_198907_0_.source,
177+
IntegerArgumentType.getInteger(p_198907_0_, "time")
178+
)
179+
}
180+
)
181+
)
182+
)
183+
)
184+
}
185+
}
186+
187+
private fun checkPermissions(source: CommandSource) {
188+
try {
189+
if (!EntryPoint.hasPermission(source.asPlayer(), "native.worldborder", 2)) {
190+
logger.info(
191+
PERMISSION_LEVEL
192+
.replace("%0", source.asPlayer().name.string)
193+
.replace("%1", "worldborder")
194+
)
195+
throw CommandException(
196+
TranslationTextComponent(
197+
"native.worldborder.restricted"
198+
)
199+
)
200+
}
201+
} catch (e: CommandSyntaxException) {
202+
// ignored, because command executed by server.
203+
}
204+
}
205+
206+
@Throws(CommandSyntaxException::class)
207+
private fun setDamageBuffer(source: CommandSource, distance: Float): Int {
208+
checkPermissions(source)
209+
210+
val worldborder = source.world.worldBorder
211+
return if (worldborder.damageBuffer == distance.toDouble()) {
212+
throw DAMAGE_BUFFER_NO_CHANGE.create()
213+
} else {
214+
worldborder.damageBuffer = distance.toDouble()
215+
source.sendFeedback(
216+
TranslationTextComponent(
217+
"commands.worldborder.damage.buffer.success", String.format(
218+
Locale.ROOT, "%.2f", distance
219+
)
220+
), true
221+
)
222+
distance.toInt()
223+
}
224+
}
225+
226+
@Throws(CommandSyntaxException::class)
227+
private fun setDamageAmount(source: CommandSource, damagePerBlock: Float): Int {
228+
checkPermissions(source)
229+
230+
val worldborder = source.world.worldBorder
231+
return if (worldborder.damagePerBlock == damagePerBlock.toDouble()) {
232+
throw DAMAGE_AMOUNT_NO_CHANGE.create()
233+
} else {
234+
worldborder.damagePerBlock = damagePerBlock.toDouble()
235+
source.sendFeedback(
236+
TranslationTextComponent(
237+
"commands.worldborder.damage.amount.success", String.format(
238+
Locale.ROOT, "%.2f", damagePerBlock
239+
)
240+
), true
241+
)
242+
damagePerBlock.toInt()
243+
}
244+
}
245+
246+
@Throws(CommandSyntaxException::class)
247+
private fun setWarningTime(source: CommandSource, time: Int): Int {
248+
checkPermissions(source)
249+
250+
val worldborder = source.world.worldBorder
251+
return if (worldborder.warningTime == time) {
252+
throw WARNING_TIME_NO_CHANGE.create()
253+
} else {
254+
worldborder.warningTime = time
255+
source.sendFeedback(
256+
TranslationTextComponent(
257+
"commands.worldborder.warning.time.success",
258+
time
259+
), true
260+
)
261+
time
262+
}
263+
}
264+
265+
@Throws(CommandSyntaxException::class)
266+
private fun setWarningDistance(source: CommandSource, distance: Int): Int {
267+
checkPermissions(source)
268+
269+
val worldborder = source.world.worldBorder
270+
return if (worldborder.warningDistance == distance) {
271+
throw WARNING_DISTANCE_NO_CHANGE.create()
272+
} else {
273+
worldborder.warningDistance = distance
274+
source.sendFeedback(
275+
TranslationTextComponent(
276+
"commands.worldborder.warning.distance.success",
277+
distance
278+
), true
279+
)
280+
distance
281+
}
282+
}
283+
284+
private fun getSize(source: CommandSource): Int {
285+
checkPermissions(source)
286+
287+
val d0 = source.world.worldBorder.diameter
288+
source.sendFeedback(
289+
TranslationTextComponent(
290+
"commands.worldborder.get", String.format(
291+
Locale.ROOT, "%.0f", d0
292+
)
293+
), false
294+
)
295+
return MathHelper.floor(d0 + 0.5)
296+
}
297+
298+
@Throws(CommandSyntaxException::class)
299+
private fun setCenter(source: CommandSource, pos: Vec2f): Int {
300+
checkPermissions(source)
301+
302+
val worldborder = source.world.worldBorder
303+
return if (
304+
worldborder.centerX == pos.x.toDouble() &&
305+
worldborder.centerZ == pos.y.toDouble()
306+
) {
307+
throw CENTER_NO_CHANGE.create()
308+
} else {
309+
worldborder.setCenter(pos.x.toDouble(), pos.y.toDouble())
310+
source.sendFeedback(
311+
TranslationTextComponent(
312+
"commands.worldborder.center.success", String.format(
313+
Locale.ROOT, "%.2f", pos.x
314+
), String.format("%.2f", pos.y)
315+
), true
316+
)
317+
0
318+
}
319+
}
320+
321+
@Throws(CommandSyntaxException::class)
322+
private fun setSize(source: CommandSource, newSize: Double, time: Long): Int {
323+
checkPermissions(source)
324+
325+
val worldborder = source.world.worldBorder
326+
val d0 = worldborder.diameter
327+
return if (d0 == newSize) {
328+
throw SIZE_NO_CHANGE.create()
329+
} else if (newSize < 1.0) {
330+
throw SIZE_TOO_SMALL.create()
331+
} else if (newSize > 6.0E7) {
332+
throw SIZE_TOO_BIG.create()
333+
} else {
334+
if (time > 0L) {
335+
worldborder.setTransition(d0, newSize, time)
336+
if (newSize > d0) {
337+
source.sendFeedback(
338+
TranslationTextComponent(
339+
"commands.worldborder.set.grow", String.format(
340+
Locale.ROOT, "%.1f", newSize
341+
), (time / 1000L).toString()
342+
), true
343+
)
344+
} else {
345+
source.sendFeedback(
346+
TranslationTextComponent(
347+
"commands.worldborder.set.shrink", String.format(
348+
Locale.ROOT, "%.1f", newSize
349+
), (time / 1000L).toString()
350+
), true
351+
)
352+
}
353+
} else {
354+
worldborder.setTransition(newSize)
355+
source.sendFeedback(
356+
TranslationTextComponent(
357+
"commands.worldborder.set.immediate", String.format(
358+
Locale.ROOT, "%.1f", newSize
359+
)
360+
), true
361+
)
362+
}
363+
(newSize - d0).toInt()
364+
}
365+
}
366+
}

0 commit comments

Comments
 (0)