diff --git a/build.gradle.kts b/build.gradle.kts index 27c7c1e..92d600d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -27,8 +27,8 @@ group = mavenGroup repositories { maven("https://maven.architectury.dev/") maven("https://maven.nucleoid.xyz") - mavenCentral() mavenLocal() + mavenCentral() } dependencies { diff --git a/src/main/kotlin/net/superricky/tpaplusplus/TpaPlusPlus.kt b/src/main/kotlin/net/superricky/tpaplusplus/TpaPlusPlus.kt index edfba46..32efac2 100644 --- a/src/main/kotlin/net/superricky/tpaplusplus/TpaPlusPlus.kt +++ b/src/main/kotlin/net/superricky/tpaplusplus/TpaPlusPlus.kt @@ -6,6 +6,7 @@ import dev.architectury.event.events.common.PlayerEvent import dev.architectury.event.events.common.TickEvent import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.cancel import kotlinx.coroutines.launch import net.fabricmc.api.ModInitializer import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents @@ -106,5 +107,6 @@ object TpaPlusPlus : ModInitializer, CoroutineScope { private fun serverStopped(ignored: MinecraftServer) { logger.info("Shutting down TPA++") AsyncCommandHelper.stopTickLoop() + coroutineContext.cancel() } } diff --git a/src/main/kotlin/net/superricky/tpaplusplus/async/AsyncCommand.kt b/src/main/kotlin/net/superricky/tpaplusplus/async/AsyncCommand.kt index f1157e5..0c2efd1 100644 --- a/src/main/kotlin/net/superricky/tpaplusplus/async/AsyncCommand.kt +++ b/src/main/kotlin/net/superricky/tpaplusplus/async/AsyncCommand.kt @@ -3,14 +3,28 @@ package net.superricky.tpaplusplus.async import net.superricky.tpaplusplus.utility.LevelBoundVec3 import net.superricky.tpaplusplus.utility.getDimension -interface AsyncCommand { - fun checkWindupDistance(asyncCommandData: AsyncCommandData): Boolean +/** + * Abstract class for asyncCommand + */ +abstract class AsyncCommand { + protected lateinit var commandName: String - fun getCooldownTime(): Double + /** + * This function is used to check if the player's movement + * distance is within the limit when the command is executed + */ + abstract fun checkWindupDistance(asyncCommandData: AsyncCommandData): Boolean - fun getDelayTime(): Double + abstract fun getCooldownTime(): Double - fun checkWindupDistance( + abstract fun getDelayTime(): Double + + /** + * Command names cannot be hot loaded + */ + fun getCommandName(): String = commandName + + protected fun checkWindupDistance( asyncCommandData: AsyncCommandData, checkFunction: Function1, minDistance: Double @@ -25,14 +39,14 @@ interface AsyncCommand { return distance <= minDistance } - fun getSenderDistance(asyncCommandData: AsyncCommandData): Double { + protected fun getSenderDistance(asyncCommandData: AsyncCommandData): Double { val originPos = asyncCommandData.getPos() val sender = asyncCommandData.getRequest().sender val nowPos = LevelBoundVec3(sender.getDimension(), sender.pos) return originPos.distance(nowPos) } - fun getReceiverDistance(asyncCommandData: AsyncCommandData): Double { + protected fun getReceiverDistance(asyncCommandData: AsyncCommandData): Double { val originPos = asyncCommandData.getPos() val receiver = asyncCommandData.getRequest().receiver require(receiver != null) { "Receiver not found" } diff --git a/src/main/kotlin/net/superricky/tpaplusplus/async/AsyncCommandData.kt b/src/main/kotlin/net/superricky/tpaplusplus/async/AsyncCommandData.kt index 458e6b4..2d117d0 100644 --- a/src/main/kotlin/net/superricky/tpaplusplus/async/AsyncCommandData.kt +++ b/src/main/kotlin/net/superricky/tpaplusplus/async/AsyncCommandData.kt @@ -2,30 +2,32 @@ package net.superricky.tpaplusplus.async import kotlinx.atomicfu.AtomicBoolean import kotlinx.atomicfu.atomic +import net.minecraft.text.Text import net.superricky.tpaplusplus.config.CommonSpec import net.superricky.tpaplusplus.config.Config -import net.superricky.tpaplusplus.async.request.Request import net.superricky.tpaplusplus.utility.LevelBoundVec3 +import net.superricky.tpaplusplus.utility.TextColorPallet +import net.superricky.tpaplusplus.utility.sendRemainTime import net.superricky.tpaplusplus.utility.translateSecondToTick class AsyncCommandData( - private val request: Request, - private val pos: LevelBoundVec3, - private val callback: Function2 + private val asyncRequest: AsyncRequest, + private var pos: LevelBoundVec3, + private val callback: Function2 ) { private var canceled: AtomicBoolean = atomic(false) - private var timeout = Config.getConfig()[CommonSpec.tpaTimeout].toDouble().translateSecondToTick() + private var timeout = Config.getConfig()[CommonSpec.tpaTimeout].translateSecondToTick() - fun needDelay(): Boolean = request.delay != 0.0 + fun needDelay(): Boolean = asyncRequest.delay != 0.0 - fun getDelay(): Double = request.delay + fun getDelay(): Double = asyncRequest.delay fun updateDelay(delay: Double) { - request.delay = delay + asyncRequest.delay = delay } fun updateCooldown(cooldown: Double) { - request.cooldown = cooldown + asyncRequest.cooldown = cooldown } fun tick(): Boolean { @@ -35,15 +37,32 @@ class AsyncCommandData( fun getPos(): LevelBoundVec3 = pos - fun getRequest(): Request = request + fun getRequest(): AsyncRequest = asyncRequest fun isCanceled(): Boolean = canceled.value - fun call(commandResult: AsyncCommandResult) { + fun call(commandResult: AsyncCommandEvent) { if (isCanceled()) { return } - callback.invoke(commandResult, request) + when (commandResult) { + AsyncCommandEvent.REQUEST_OUT_DISTANCE -> { + asyncRequest.sender.sendMessage( + Text.translatable( + "command.windup.error.out_distance", + asyncRequest.commandType.handler.getCommandName() + ).setStyle(TextColorPallet.error) + ) + } + + AsyncCommandEvent.REQUEST_UPDATE_MESSAGE -> { + asyncRequest.sender.sendRemainTime(asyncRequest.delay) + } + + else -> { + callback.invoke(commandResult, this) + } + } } fun cancel() { diff --git a/src/main/kotlin/net/superricky/tpaplusplus/async/AsyncCommandEvent.kt b/src/main/kotlin/net/superricky/tpaplusplus/async/AsyncCommandEvent.kt new file mode 100644 index 0000000..c59a731 --- /dev/null +++ b/src/main/kotlin/net/superricky/tpaplusplus/async/AsyncCommandEvent.kt @@ -0,0 +1,15 @@ +package net.superricky.tpaplusplus.async + +enum class AsyncCommandEvent { + REQUEST_AFTER_DELAY, // Command windup finish event, take effect + REQUEST_UPDATE_MESSAGE, // windup message update event, show message to player + REQUEST_CANCELED, // Teleport canceled + REQUEST_OUT_DISTANCE, // Move too much, fail to execute command + REQUEST_TIMEOUT, // Request out of time event + REQUEST_UNDER_COOLDOWN, // command under cooldown event + REQUEST_ACCEPTED, // teleport request accepted event + REQUEST_NOT_FOUND, // can not find teleport request event + TELEPORT_OUT_DISTANCE, // move too much when teleporting + TELEPORT_UPDATE_MESSAGE, // teleport message update event, show message to player + USELESS_VOID // Placeholders, useless return values +} diff --git a/src/main/kotlin/net/superricky/tpaplusplus/async/AsyncCommandHelper.kt b/src/main/kotlin/net/superricky/tpaplusplus/async/AsyncCommandHelper.kt index 52c91e4..38c3b03 100644 --- a/src/main/kotlin/net/superricky/tpaplusplus/async/AsyncCommandHelper.kt +++ b/src/main/kotlin/net/superricky/tpaplusplus/async/AsyncCommandHelper.kt @@ -5,6 +5,8 @@ import kotlinx.atomicfu.atomic import kotlinx.coroutines.* import net.minecraft.server.network.ServerPlayerEntity import net.superricky.tpaplusplus.GlobalConst.ONE_SECOND +import net.superricky.tpaplusplus.config.CommonSpec +import net.superricky.tpaplusplus.config.Config import java.util.* import kotlin.coroutines.CoroutineContext @@ -47,6 +49,75 @@ object AsyncCommandHelper : CoroutineScope { playerData[type] = type.handler.getCooldownTime() * tickRate } + fun asyncWindupCheck( + asyncCommandData: AsyncCommandData, + successCallback: Function1? = null, + errorCallback: Function1? = null, + progressCallback: Function1? = null, + delay: Double? = null + ) { + val job = launch { + while (true) { + delay(tickDelay) + if (!asyncCommandData.getRequest().commandType.handler.checkWindupDistance(asyncCommandData)) { + errorCallback?.invoke(asyncCommandData) + return@launch + } + } + } + var delayTime = delay ?: asyncCommandData.getDelay() + asyncCommandData.updateDelay(delayTime) + launch { + progressCallback?.invoke(asyncCommandData) + while (true) { + delay(ONE_SECOND) + if (asyncCommandData.isCanceled()) { + return@launch + } + delayTime -= 1 + asyncCommandData.updateDelay(delayTime) + progressCallback?.invoke(asyncCommandData) + if (delayTime < 1.0) { + break + } + } + delay((delayTime * ONE_SECOND).toLong()) + if (asyncCommandData.isCanceled()) { + return@launch + } + job.cancel() + successCallback?.invoke(asyncCommandData) + } + } + + private fun teleportPlayer(from: ServerPlayerEntity, to: ServerPlayerEntity) = + from.teleport(to.serverWorld, to.x, to.y, to.z, to.yaw, to.pitch) + + fun teleport(asyncCommandData: AsyncCommandData) { + launch { + val asyncRequest = asyncCommandData.getRequest() + if (Config.getConfig()[CommonSpec.waitTimeBeforeTp] == 0.0) { + teleportPlayer(asyncRequest.from!!, asyncRequest.to!!) + return@launch + } + asyncWindupCheck( + asyncCommandData, + successCallback = { + teleportPlayer(asyncRequest.from!!, asyncRequest.to!!) + it.cancel() + }, + errorCallback = { + it.call(AsyncCommandEvent.TELEPORT_OUT_DISTANCE) + it.cancel() + }, + progressCallback = { + it.call(AsyncCommandEvent.TELEPORT_UPDATE_MESSAGE) + }, + Config.getConfig()[CommonSpec.waitTimeBeforeTp] + ) + } + } + fun schedule(request: AsyncCommandData) { val uuid = request.getRequest().sender.uuid val playerData = underCooldown[uuid] @@ -54,64 +125,53 @@ object AsyncCommandHelper : CoroutineScope { underCooldown[uuid] = mutableMapOf() } else if (playerData[request.getRequest().commandType] != null) { request.updateCooldown(playerData[request.getRequest().commandType]!!) - request.call(AsyncCommandResult.UNDER_COOLDOWN) + request.call(AsyncCommandEvent.REQUEST_UNDER_COOLDOWN) return } - if (request.needDelay()) { - var delayTime = request.getDelay() - val job = launch { - while (true) { - delay(tickDelay) - if (!request.getRequest().commandType.handler.checkWindupDistance(request)) { - request.call(AsyncCommandResult.OUT_OF_DISTANCE) - request.cancel() - return@launch - } - } - } - launch { - request.call(AsyncCommandResult.UPDATE_DELAY_MESSAGE) - while (true) { - delay(ONE_SECOND) - if (request.isCanceled()) { - return@launch - } - delayTime -= 1 - request.updateDelay(delayTime) - request.call(AsyncCommandResult.UPDATE_DELAY_MESSAGE) - if (delayTime < 1.0) { - break - } - } - delay((delayTime * ONE_SECOND).toLong()) - request.call(AsyncCommandResult.AFTER_DELAY) - job.cancel() + if (!request.needDelay()) { + request.call(AsyncCommandEvent.REQUEST_AFTER_DELAY) + // If request not a teleport request, then there are no necessary to consider timeout + if (request.getRequest().isTeleportRequest()) { requests.add(request) } - } else { - request.call(AsyncCommandResult.AFTER_DELAY) - requests.add(request) + return } + asyncWindupCheck( + request, + successCallback = { + it.call(AsyncCommandEvent.REQUEST_AFTER_DELAY) + if (it.getRequest().isTeleportRequest()) { + requests.add(it) + } + }, + errorCallback = { + it.call(AsyncCommandEvent.REQUEST_OUT_DISTANCE) + it.cancel() + }, + progressCallback = { + it.call(AsyncCommandEvent.REQUEST_UPDATE_MESSAGE) + } + ) } - fun acceptRequest(receiver: ServerPlayerEntity): AsyncCommandResult { + fun acceptRequest(receiver: ServerPlayerEntity): AsyncCommandEvent { val request = requests.find { it.getRequest().receiver == receiver } if (request == null) { - return AsyncCommandResult.REQUEST_NOT_FOUND + return AsyncCommandEvent.REQUEST_NOT_FOUND } - request.cancel() - request.call(AsyncCommandResult.REQUEST_ACCEPTED) - return AsyncCommandResult.ACCEPT_SUCCESS + requests.remove(request) + request.call(AsyncCommandEvent.REQUEST_ACCEPTED) + return AsyncCommandEvent.USELESS_VOID } - fun acceptRequest(receiver: ServerPlayerEntity, sender: ServerPlayerEntity): AsyncCommandResult { + fun acceptRequest(receiver: ServerPlayerEntity, sender: ServerPlayerEntity): AsyncCommandEvent { val request = requests.find { it.getRequest().receiver == receiver && it.getRequest().sender == sender } if (request == null) { - return AsyncCommandResult.REQUEST_NOT_FOUND + return AsyncCommandEvent.REQUEST_NOT_FOUND } - request.cancel() - request.call(AsyncCommandResult.REQUEST_ACCEPTED) - return AsyncCommandResult.ACCEPT_SUCCESS + requests.remove(request) + request.call(AsyncCommandEvent.REQUEST_ACCEPTED) + return AsyncCommandEvent.USELESS_VOID } fun runTick() { @@ -124,7 +184,7 @@ object AsyncCommandHelper : CoroutineScope { } // check timeout if (it.tick()) { - it.call(AsyncCommandResult.TIMEOUT) + it.call(AsyncCommandEvent.REQUEST_TIMEOUT) elementRemoved.add(it) return@forEach } diff --git a/src/main/kotlin/net/superricky/tpaplusplus/async/AsyncCommandResult.kt b/src/main/kotlin/net/superricky/tpaplusplus/async/AsyncCommandResult.kt deleted file mode 100644 index 89a2025..0000000 --- a/src/main/kotlin/net/superricky/tpaplusplus/async/AsyncCommandResult.kt +++ /dev/null @@ -1,13 +0,0 @@ -package net.superricky.tpaplusplus.async - -enum class AsyncCommandResult { - TPA_BE_CANCELED, - OUT_OF_DISTANCE, - TIMEOUT, - AFTER_DELAY, - UPDATE_DELAY_MESSAGE, - UNDER_COOLDOWN, - REQUEST_ACCEPTED, - REQUEST_NOT_FOUND, - ACCEPT_SUCCESS -} diff --git a/src/main/kotlin/net/superricky/tpaplusplus/async/AsyncRequest.kt b/src/main/kotlin/net/superricky/tpaplusplus/async/AsyncRequest.kt new file mode 100644 index 0000000..c71fc54 --- /dev/null +++ b/src/main/kotlin/net/superricky/tpaplusplus/async/AsyncRequest.kt @@ -0,0 +1,54 @@ +package net.superricky.tpaplusplus.async + +import net.minecraft.server.network.ServerPlayerEntity + +/** + * A class which store command request + */ +class AsyncRequest( + /** + * Player who send request, must exist + */ + val sender: ServerPlayerEntity, + /** + * Player who receive request + * For some command this is null + */ + val receiver: ServerPlayerEntity?, + /** + * Command type + * @see AsyncCommandType + */ + val commandType: AsyncCommandType, + /** + * Player who will be teleported + * For some command this is null + */ + val from: ServerPlayerEntity? = null, + /** + * Player who is the teleport target + * For some command this is null + */ + val to: ServerPlayerEntity? = null +) { + var delay: Double = commandType.handler.getDelayTime() + var cooldown: Double = commandType.handler.getCooldownTime() + + /** + * Check whether this request can execute teleport + * @return True if this command can execute teleport else return False + */ + fun canBeTeleported(): Boolean = isTeleportRequest() && from != null && to != null + + /** + * Check whether this is a teleport request + * @return True is it is else False + */ + fun isTeleportRequest(): Boolean = when (commandType) { + AsyncCommandType.TPA, AsyncCommandType.TPAHERE, AsyncCommandType.BACK -> true + else -> false + } + + override fun toString(): String = + "Request{sender=${sender.name}, receiver=${receiver?.name}, from=$from, to=$to, commandType=$commandType" +} diff --git a/src/main/kotlin/net/superricky/tpaplusplus/async/request/Request.kt b/src/main/kotlin/net/superricky/tpaplusplus/async/request/Request.kt deleted file mode 100644 index 63ddd0f..0000000 --- a/src/main/kotlin/net/superricky/tpaplusplus/async/request/Request.kt +++ /dev/null @@ -1,17 +0,0 @@ -package net.superricky.tpaplusplus.async.request - -import net.minecraft.server.network.ServerPlayerEntity -import net.superricky.tpaplusplus.async.AsyncCommandType - -class Request( - val sender: ServerPlayerEntity, - val receiver: ServerPlayerEntity?, - val commandType: AsyncCommandType, - val hereRequest: Boolean = false -) { - var delay: Double = commandType.handler.getDelayTime() - var cooldown: Double = commandType.handler.getCooldownTime() - - override fun toString(): String = - "Request{sender=${sender.name}, receiver=${receiver?.name}, commandType=$commandType, hereRequest=$hereRequest}" -} diff --git a/src/main/kotlin/net/superricky/tpaplusplus/async/request/RequestHelper.kt b/src/main/kotlin/net/superricky/tpaplusplus/async/request/RequestHelper.kt deleted file mode 100644 index f3cd54b..0000000 --- a/src/main/kotlin/net/superricky/tpaplusplus/async/request/RequestHelper.kt +++ /dev/null @@ -1,60 +0,0 @@ -package net.superricky.tpaplusplus.async.request - -import net.minecraft.server.network.ServerPlayerEntity - -object RequestHelper { - private val requestSet: MutableSet = HashSet() - - fun getRequestSet(): MutableSet = requestSet - - fun clearRequestSet() = requestSet.clear() - - fun teleportRequestExists(requestToFind: Request): Boolean { - requestSet.forEach { - if (requestToFind.sender == it.sender && requestToFind.sender == it.receiver) { - return true - } - } - return false - } - - fun alreadySentTeleportRequest(sender: ServerPlayerEntity, receiver: ServerPlayerEntity): Boolean { - requestSet.forEach { - if (sender == it.sender && receiver == it.receiver) { - return true - } - } - return false - } - - fun teleport(request: Request) { - val sender = request.sender - val receiver = request.receiver!! - - if (request.hereRequest) { - receiver.teleport(sender.serverWorld, sender.x, sender.y, sender.z, sender.yaw, sender.pitch) - } - - sender.teleport(receiver.serverWorld, receiver.x, receiver.y, receiver.z, receiver.yaw, receiver.pitch) - } - - fun getSenderRequest(sender: ServerPlayerEntity): Request? = - requestSet.firstOrNull { - it.sender == sender - } - - fun getSenderRequest(sender: ServerPlayerEntity, receiver: ServerPlayerEntity): Request? = - requestSet.firstOrNull { - it.sender == sender && it.receiver == receiver - } - - fun getReceiverRequest(receiver: ServerPlayerEntity): Request? = - requestSet.firstOrNull { - it.receiver == receiver - } - - fun getReceiverRequest(receiver: ServerPlayerEntity, sender: ServerPlayerEntity): Request? = - requestSet.firstOrNull { - it.sender == sender && it.receiver == receiver - } -} diff --git a/src/main/kotlin/net/superricky/tpaplusplus/command/CommandRegister.kt b/src/main/kotlin/net/superricky/tpaplusplus/command/CommandRegister.kt index e55c1d2..09f2d5a 100644 --- a/src/main/kotlin/net/superricky/tpaplusplus/command/CommandRegister.kt +++ b/src/main/kotlin/net/superricky/tpaplusplus/command/CommandRegister.kt @@ -52,8 +52,8 @@ object CommandRegister { return } - if (config[CommandEnableSpec.tpaacceptEnable]) { - logger.info("Register command /${config[CommandNameSpec.tpaacceptCommand]}...") + if (config[CommandEnableSpec.tpacceptEnable]) { + logger.info("Register command /${config[CommandNameSpec.tpacceptCommand]}...") dispatcher.root.addChild(AcceptCommand.build()) } diff --git a/src/main/kotlin/net/superricky/tpaplusplus/command/commands/AcceptCommand.kt b/src/main/kotlin/net/superricky/tpaplusplus/command/commands/AcceptCommand.kt index cd22d79..8bc3b64 100644 --- a/src/main/kotlin/net/superricky/tpaplusplus/command/commands/AcceptCommand.kt +++ b/src/main/kotlin/net/superricky/tpaplusplus/command/commands/AcceptCommand.kt @@ -4,7 +4,6 @@ import net.minecraft.command.argument.EntityArgumentType import net.minecraft.server.command.CommandManager.argument import net.minecraft.server.command.CommandManager.literal import net.superricky.tpaplusplus.async.* -import net.superricky.tpaplusplus.async.request.Request import net.superricky.tpaplusplus.command.BuildableCommand import net.superricky.tpaplusplus.command.CommandHelper import net.superricky.tpaplusplus.command.CommandHelper.checkSenderReceiver @@ -14,14 +13,15 @@ import net.superricky.tpaplusplus.config.command.CommandCooldownSpec import net.superricky.tpaplusplus.config.command.CommandDelaySpec import net.superricky.tpaplusplus.config.command.CommandDistanceSpec import net.superricky.tpaplusplus.config.command.CommandNameSpec -import net.superricky.tpaplusplus.utility.Context -import net.superricky.tpaplusplus.utility.LevelBoundVec3 -import net.superricky.tpaplusplus.utility.LiteralNode -import net.superricky.tpaplusplus.utility.getDimension +import net.superricky.tpaplusplus.utility.* + +object AcceptCommand : AsyncCommand(), BuildableCommand { + init { + commandName = Config.getConfig()[CommandNameSpec.tpacceptCommand] + } -object AcceptCommand : BuildableCommand, AsyncCommand { override fun build(): LiteralNode = - literal(Config.getConfig()[CommandNameSpec.tpaacceptCommand]) + literal(commandName) .then( argument("player", EntityArgumentType.player()) .executes { acceptCommandWithTarget(it) } @@ -41,14 +41,26 @@ object AcceptCommand : BuildableCommand, AsyncCommand { ) private fun acceptCommandWithTarget(context: Context): Int { - fun asyncCommandCallback(result: AsyncCommandResult, request: Request) { - if (result == AsyncCommandResult.AFTER_DELAY) { - val sender = request.sender - val receiver = request.receiver!! - val acceptResult = AsyncCommandHelper.acceptRequest(sender, receiver) - if (acceptResult == AsyncCommandResult.REQUEST_NOT_FOUND) { - CommandHelper.requestNotFound(sender, receiver) + fun asyncCommandCallback(result: AsyncCommandEvent, asyncCommandData: AsyncCommandData) { + val asyncRequest = asyncCommandData.getRequest() + when (result) { + AsyncCommandEvent.REQUEST_AFTER_DELAY -> { + val sender = asyncRequest.sender + val receiver = asyncRequest.receiver!! + val acceptResult = AsyncCommandHelper.acceptRequest(sender, receiver) + if (acceptResult == AsyncCommandEvent.REQUEST_NOT_FOUND) { + CommandHelper.requestNotFound(sender, receiver) + } + } + + AsyncCommandEvent.REQUEST_UNDER_COOLDOWN -> { + asyncRequest.sender.sendCooldownTime( + Config.getConfig()[CommandNameSpec.tpacceptCommand], + asyncRequest.cooldown.translateTickToSecond() + ) } + + else -> {} } } @@ -58,7 +70,7 @@ object AcceptCommand : BuildableCommand, AsyncCommand { sender!! receiver!! val asyncCommandData = AsyncCommandData( - Request(sender, receiver, AsyncCommandType.ACCEPT), + AsyncRequest(sender, receiver, AsyncCommandType.ACCEPT), LevelBoundVec3(sender.getDimension(), sender.pos), ::asyncCommandCallback ) @@ -67,13 +79,25 @@ object AcceptCommand : BuildableCommand, AsyncCommand { } private fun acceptCommand(context: Context): Int { - fun asyncCommandCallback(result: AsyncCommandResult, request: Request) { - if (result == AsyncCommandResult.AFTER_DELAY) { - val sender = request.sender - val acceptResult = AsyncCommandHelper.acceptRequest(sender) - if (acceptResult == AsyncCommandResult.REQUEST_NOT_FOUND) { - CommandHelper.requestNotFound(sender) + fun asyncCommandCallback(result: AsyncCommandEvent, asyncCommandData: AsyncCommandData) { + val asyncRequest = asyncCommandData.getRequest() + when (result) { + AsyncCommandEvent.REQUEST_AFTER_DELAY -> { + val sender = asyncRequest.sender + val acceptResult = AsyncCommandHelper.acceptRequest(sender) + if (acceptResult == AsyncCommandEvent.REQUEST_NOT_FOUND) { + CommandHelper.requestNotFound(sender) + } + } + + AsyncCommandEvent.REQUEST_UNDER_COOLDOWN -> { + asyncRequest.sender.sendCooldownTime( + Config.getConfig()[CommandNameSpec.tpacceptCommand], + asyncRequest.cooldown.translateTickToSecond() + ) } + + else -> {} } } @@ -81,7 +105,7 @@ object AcceptCommand : BuildableCommand, AsyncCommand { val sender = source.player sender ?: return CommandResult.SENDER_NOT_EXIST.status val asyncCommandData = AsyncCommandData( - Request(sender, null, AsyncCommandType.ACCEPT), + AsyncRequest(sender, null, AsyncCommandType.ACCEPT), LevelBoundVec3(sender.getDimension(), sender.pos), ::asyncCommandCallback ) diff --git a/src/main/kotlin/net/superricky/tpaplusplus/command/commands/BackCommand.kt b/src/main/kotlin/net/superricky/tpaplusplus/command/commands/BackCommand.kt index 87e701b..d794aea 100644 --- a/src/main/kotlin/net/superricky/tpaplusplus/command/commands/BackCommand.kt +++ b/src/main/kotlin/net/superricky/tpaplusplus/command/commands/BackCommand.kt @@ -1,8 +1,8 @@ package net.superricky.tpaplusplus.command.commands import net.minecraft.server.command.CommandManager.literal -import net.superricky.tpaplusplus.async.AsyncCommandData import net.superricky.tpaplusplus.async.AsyncCommand +import net.superricky.tpaplusplus.async.AsyncCommandData import net.superricky.tpaplusplus.command.BuildableCommand import net.superricky.tpaplusplus.config.Config import net.superricky.tpaplusplus.config.command.CommandCooldownSpec @@ -11,9 +11,13 @@ import net.superricky.tpaplusplus.config.command.CommandDistanceSpec import net.superricky.tpaplusplus.config.command.CommandNameSpec import net.superricky.tpaplusplus.utility.LiteralNode -object BackCommand : BuildableCommand, AsyncCommand { +object BackCommand : AsyncCommand(), BuildableCommand { + init { + commandName = Config.getConfig()[CommandNameSpec.backCommand] + } + override fun build(): LiteralNode = - literal(Config.getConfig()[CommandNameSpec.backCommand]) + literal(commandName) .build() override fun getCooldownTime(): Double = Config.getConfig()[CommandCooldownSpec.backCooldown] diff --git a/src/main/kotlin/net/superricky/tpaplusplus/command/commands/BlockCommand.kt b/src/main/kotlin/net/superricky/tpaplusplus/command/commands/BlockCommand.kt index 3071c88..ff96cf8 100644 --- a/src/main/kotlin/net/superricky/tpaplusplus/command/commands/BlockCommand.kt +++ b/src/main/kotlin/net/superricky/tpaplusplus/command/commands/BlockCommand.kt @@ -6,8 +6,8 @@ import net.minecraft.server.command.CommandManager.argument import net.minecraft.server.command.CommandManager.literal import net.minecraft.text.Text import net.superricky.tpaplusplus.TpaPlusPlus -import net.superricky.tpaplusplus.async.AsyncCommandData import net.superricky.tpaplusplus.async.AsyncCommand +import net.superricky.tpaplusplus.async.AsyncCommandData import net.superricky.tpaplusplus.command.BuildableCommand import net.superricky.tpaplusplus.command.CommandHelper.checkSenderReceiver import net.superricky.tpaplusplus.command.CommandResult @@ -23,9 +23,13 @@ import net.superricky.tpaplusplus.utility.LiteralNode import net.superricky.tpaplusplus.utility.TextColorPallet import net.superricky.tpaplusplus.utility.getColoredName -object BlockCommand : BuildableCommand, AsyncCommand { +object BlockCommand : AsyncCommand(), BuildableCommand { + init { + commandName = Config.getConfig()[CommandNameSpec.tpablockCommand] + } + override fun build(): LiteralNode = - literal(Config.getConfig()[CommandNameSpec.tpablockCommand]) + literal(commandName) .then( argument("player", EntityArgumentType.player()) .executes { blockPlayer(it) } diff --git a/src/main/kotlin/net/superricky/tpaplusplus/command/commands/CancelCommand.kt b/src/main/kotlin/net/superricky/tpaplusplus/command/commands/CancelCommand.kt index 44c02c9..dc55960 100644 --- a/src/main/kotlin/net/superricky/tpaplusplus/command/commands/CancelCommand.kt +++ b/src/main/kotlin/net/superricky/tpaplusplus/command/commands/CancelCommand.kt @@ -1,8 +1,8 @@ package net.superricky.tpaplusplus.command.commands import net.minecraft.server.command.CommandManager.literal -import net.superricky.tpaplusplus.async.AsyncCommandData import net.superricky.tpaplusplus.async.AsyncCommand +import net.superricky.tpaplusplus.async.AsyncCommandData import net.superricky.tpaplusplus.command.BuildableCommand import net.superricky.tpaplusplus.config.Config import net.superricky.tpaplusplus.config.command.CommandCooldownSpec @@ -11,9 +11,13 @@ import net.superricky.tpaplusplus.config.command.CommandDistanceSpec import net.superricky.tpaplusplus.config.command.CommandNameSpec import net.superricky.tpaplusplus.utility.LiteralNode -object CancelCommand : BuildableCommand, AsyncCommand { +object CancelCommand : AsyncCommand(), BuildableCommand { + init { + commandName = Config.getConfig()[CommandNameSpec.tpacancelCommand] + } + override fun build(): LiteralNode = - literal(Config.getConfig()[CommandNameSpec.tpacancelCommand]) + literal(commandName) .build() override fun getCooldownTime(): Double = Config.getConfig()[CommandCooldownSpec.cancelCooldown] diff --git a/src/main/kotlin/net/superricky/tpaplusplus/command/commands/DenyCommand.kt b/src/main/kotlin/net/superricky/tpaplusplus/command/commands/DenyCommand.kt index 713e489..99ae6a1 100644 --- a/src/main/kotlin/net/superricky/tpaplusplus/command/commands/DenyCommand.kt +++ b/src/main/kotlin/net/superricky/tpaplusplus/command/commands/DenyCommand.kt @@ -11,9 +11,13 @@ import net.superricky.tpaplusplus.config.command.CommandDistanceSpec import net.superricky.tpaplusplus.config.command.CommandNameSpec import net.superricky.tpaplusplus.utility.LiteralNode -object DenyCommand : BuildableCommand, AsyncCommand { +object DenyCommand : AsyncCommand(), BuildableCommand { + init { + commandName = Config.getConfig()[CommandNameSpec.tpadenyCommand] + } + override fun build(): LiteralNode = - literal(Config.getConfig()[CommandNameSpec.tpadenyCommand]) + literal(commandName) .build() override fun getCooldownTime(): Double = Config.getConfig()[CommandCooldownSpec.denyCooldown] diff --git a/src/main/kotlin/net/superricky/tpaplusplus/command/commands/ToggleCommand.kt b/src/main/kotlin/net/superricky/tpaplusplus/command/commands/ToggleCommand.kt index 657fac4..f28837e 100644 --- a/src/main/kotlin/net/superricky/tpaplusplus/command/commands/ToggleCommand.kt +++ b/src/main/kotlin/net/superricky/tpaplusplus/command/commands/ToggleCommand.kt @@ -19,9 +19,13 @@ import net.superricky.tpaplusplus.utility.LiteralNode import net.superricky.tpaplusplus.utility.toggleOff import net.superricky.tpaplusplus.utility.toggleOn -object ToggleCommand : BuildableCommand, AsyncCommand { +object ToggleCommand : AsyncCommand(), BuildableCommand { + init { + commandName = Config.getConfig()[CommandNameSpec.tpatoggleCommand] + } + override fun build(): LiteralNode = - literal(Config.getConfig()[CommandNameSpec.tpatoggleCommand]) + literal(commandName) .then( literal("on") .executes { switchToggle(it, true) } diff --git a/src/main/kotlin/net/superricky/tpaplusplus/command/commands/TpaCommand.kt b/src/main/kotlin/net/superricky/tpaplusplus/command/commands/TpaCommand.kt index 5d84369..629e9b6 100644 --- a/src/main/kotlin/net/superricky/tpaplusplus/command/commands/TpaCommand.kt +++ b/src/main/kotlin/net/superricky/tpaplusplus/command/commands/TpaCommand.kt @@ -5,8 +5,6 @@ import net.minecraft.server.command.CommandManager.argument import net.minecraft.server.command.CommandManager.literal import net.minecraft.text.Text import net.superricky.tpaplusplus.async.* -import net.superricky.tpaplusplus.async.request.Request -import net.superricky.tpaplusplus.async.request.RequestHelper import net.superricky.tpaplusplus.command.BuildableCommand import net.superricky.tpaplusplus.command.CommandHelper.checkSenderReceiver import net.superricky.tpaplusplus.command.CommandResult @@ -17,9 +15,13 @@ import net.superricky.tpaplusplus.config.command.CommandDistanceSpec import net.superricky.tpaplusplus.config.command.CommandNameSpec import net.superricky.tpaplusplus.utility.* -object TpaCommand : BuildableCommand, AsyncCommand { +object TpaCommand : AsyncCommand(), BuildableCommand { + init { + commandName = Config.getConfig()[CommandNameSpec.tpaCommand] + } + override fun build(): LiteralNode = - literal(Config.getConfig()[CommandNameSpec.tpaCommand]) + literal(commandName) .then( argument("player", EntityArgumentType.player()) .executes { tpaPlayer(it) } @@ -37,61 +39,61 @@ object TpaCommand : BuildableCommand, AsyncCommand { Config.getConfig()[CommandDistanceSpec.tpaDistance] ) - private fun asyncCommandCallback(result: AsyncCommandResult, request: Request) { - require(request.receiver != null) { "Receiver cannot be null" } + private fun asyncCommandCallback(result: AsyncCommandEvent, asyncCommandData: AsyncCommandData) { + val asyncRequest = asyncCommandData.getRequest() + require(asyncRequest.receiver != null) { "Receiver cannot be null" } when (result) { - AsyncCommandResult.AFTER_DELAY -> { - request.sender.sendMessage("command.tpa.request.sender", request.receiver) - request.receiver.sendMessage("command.tpa.request.receiver", request.sender) - } - - AsyncCommandResult.TIMEOUT -> { - request.sender.sendMessage("command.tpa.timeout.sender", request.receiver) - request.receiver.sendMessage("command.tpa.timeout.receiver", request.sender) - } - - AsyncCommandResult.OUT_OF_DISTANCE -> { - request.sender.sendMessage( - Text.translatable( - "command.windup.error.out_distance", - Config.getConfig()[CommandNameSpec.tpaCommand].literal().setStyle(TextColorPallet.secondary) - ).setStyle(TextColorPallet.primary) - ) + AsyncCommandEvent.REQUEST_AFTER_DELAY -> { + asyncRequest.sender.sendMessageWithPlayerName("command.tpa.request.sender", asyncRequest.receiver) + asyncRequest.receiver.sendMessageWithPlayerName("command.tpa.request.receiver", asyncRequest.sender) } - AsyncCommandResult.UPDATE_DELAY_MESSAGE -> { - request.sender.sendRemainTime(request.delay) + AsyncCommandEvent.REQUEST_TIMEOUT -> { + asyncRequest.sender.sendMessageWithPlayerName("command.tpa.timeout.sender", asyncRequest.receiver) + asyncRequest.receiver.sendMessageWithPlayerName("command.tpa.timeout.receiver", asyncRequest.sender) } - AsyncCommandResult.REQUEST_ACCEPTED -> { - RequestHelper.teleport(request) + AsyncCommandEvent.REQUEST_ACCEPTED -> { + require(asyncRequest.canBeTeleported()) { "Request can't be teleported!" } + asyncRequest.sender.sendMessageWithPlayerName("command.tpa.request.accept.from", asyncRequest.receiver) + asyncRequest.receiver.sendMessageWithPlayerName("command.tpa.request.accept.to", asyncRequest.sender) + AsyncCommandHelper.teleport(asyncCommandData) if (AsyncCommandType.TPA.handler.getCooldownTime() != 0.0) { - AsyncCommandHelper.addCooldown(request.sender.uuid, AsyncCommandType.TPA) + AsyncCommandHelper.addCooldown(asyncRequest.sender.uuid, AsyncCommandType.TPA) } - if (AsyncCommandType.ACCEPT.handler.getDelayTime() != 0.0) { - AsyncCommandHelper.addCooldown(request.receiver.uuid, AsyncCommandType.ACCEPT) + if (AsyncCommandType.ACCEPT.handler.getCooldownTime() != 0.0) { + AsyncCommandHelper.addCooldown(asyncRequest.receiver.uuid, AsyncCommandType.ACCEPT) } } - AsyncCommandResult.UNDER_COOLDOWN -> { - request.sender.sendCooldownTime( + AsyncCommandEvent.REQUEST_UNDER_COOLDOWN -> { + asyncRequest.sender.sendCooldownTime( Config.getConfig()[CommandNameSpec.tpaCommand], - request.cooldown.translateTickToSecond() + asyncRequest.cooldown.translateTickToSecond() + ) + } + + AsyncCommandEvent.TELEPORT_OUT_DISTANCE -> { + asyncRequest.from?.sendMessage( + Text.translatable("command.teleport.out_distance").setStyle(TextColorPallet.error) ) } + AsyncCommandEvent.TELEPORT_UPDATE_MESSAGE -> { + asyncRequest.from?.sendTeleportTime(asyncRequest.delay) + } + else -> {} } } private fun tpaPlayer(context: Context): Int { - val source = context.source val (result, sender, target) = checkSenderReceiver(context) if (result != CommandResult.NORMAL) return result.status sender!! target!! val asyncCommandData = AsyncCommandData( - Request(sender, target, AsyncCommandType.TPA), + AsyncRequest(sender, target, AsyncCommandType.TPA, sender, target), LevelBoundVec3(sender.getDimension(), sender.pos), ::asyncCommandCallback ) diff --git a/src/main/kotlin/net/superricky/tpaplusplus/command/commands/TpaHereCommand.kt b/src/main/kotlin/net/superricky/tpaplusplus/command/commands/TpaHereCommand.kt index a5aac48..7668551 100644 --- a/src/main/kotlin/net/superricky/tpaplusplus/command/commands/TpaHereCommand.kt +++ b/src/main/kotlin/net/superricky/tpaplusplus/command/commands/TpaHereCommand.kt @@ -11,9 +11,13 @@ import net.superricky.tpaplusplus.config.command.CommandDistanceSpec import net.superricky.tpaplusplus.config.command.CommandNameSpec import net.superricky.tpaplusplus.utility.LiteralNode -object TpaHereCommand : BuildableCommand, AsyncCommand { +object TpaHereCommand : AsyncCommand(), BuildableCommand { + init { + commandName = Config.getConfig()[CommandNameSpec.tpahereCommand] + } + override fun build(): LiteralNode = - literal(Config.getConfig()[CommandNameSpec.tpahereCommand]) + literal(commandName) .build() override fun getCooldownTime(): Double = Config.getConfig()[CommandCooldownSpec.tpahereCooldown] diff --git a/src/main/kotlin/net/superricky/tpaplusplus/command/commands/UnblockCommand.kt b/src/main/kotlin/net/superricky/tpaplusplus/command/commands/UnblockCommand.kt index 65ba080..48ccf3e 100644 --- a/src/main/kotlin/net/superricky/tpaplusplus/command/commands/UnblockCommand.kt +++ b/src/main/kotlin/net/superricky/tpaplusplus/command/commands/UnblockCommand.kt @@ -23,9 +23,13 @@ import net.superricky.tpaplusplus.utility.LiteralNode import net.superricky.tpaplusplus.utility.TextColorPallet import net.superricky.tpaplusplus.utility.getColoredName -object UnblockCommand : BuildableCommand, AsyncCommand { +object UnblockCommand : AsyncCommand(), BuildableCommand { + init { + commandName = Config.getConfig()[CommandNameSpec.tpaunblockCommand] + } + override fun build(): LiteralNode = - literal(Config.getConfig()[CommandNameSpec.tpaunblockCommand]) + literal(commandName) .then( argument("player", EntityArgumentType.player()) .executes { unBlockPlayer(it) } diff --git a/src/main/kotlin/net/superricky/tpaplusplus/config/CommonSpec.kt b/src/main/kotlin/net/superricky/tpaplusplus/config/CommonSpec.kt index 72a2e7c..d85a39f 100644 --- a/src/main/kotlin/net/superricky/tpaplusplus/config/CommonSpec.kt +++ b/src/main/kotlin/net/superricky/tpaplusplus/config/CommonSpec.kt @@ -5,6 +5,6 @@ import com.uchuhimo.konf.ConfigSpec object CommonSpec : ConfigSpec("common") { val showBlockedMessage by required() val toggledPlayerCommand by required() - val tpaTimeout by required() - val waitTimeBeforeTp by required() + val tpaTimeout by required() + val waitTimeBeforeTp by required() } diff --git a/src/main/kotlin/net/superricky/tpaplusplus/config/command/CommandEnableSpec.kt b/src/main/kotlin/net/superricky/tpaplusplus/config/command/CommandEnableSpec.kt index 2ec9639..3a824ec 100644 --- a/src/main/kotlin/net/superricky/tpaplusplus/config/command/CommandEnableSpec.kt +++ b/src/main/kotlin/net/superricky/tpaplusplus/config/command/CommandEnableSpec.kt @@ -9,7 +9,7 @@ object CommandEnableSpec : ConfigSpec("command.enable") { val tpablockEnable by required() val tpatoggleEnable by required() val tpahereEnable by required() - val tpaacceptEnable by required() + val tpacceptEnable by required() val tpadenyEnable by required() val tpaEnable by required() } diff --git a/src/main/kotlin/net/superricky/tpaplusplus/config/command/CommandNameSpec.kt b/src/main/kotlin/net/superricky/tpaplusplus/config/command/CommandNameSpec.kt index e7478fb..35d2417 100644 --- a/src/main/kotlin/net/superricky/tpaplusplus/config/command/CommandNameSpec.kt +++ b/src/main/kotlin/net/superricky/tpaplusplus/config/command/CommandNameSpec.kt @@ -9,7 +9,7 @@ object CommandNameSpec : ConfigSpec("command.name") { val tpablockCommand by required() val tpatoggleCommand by required() val tpahereCommand by required() - val tpaacceptCommand by required() + val tpacceptCommand by required() val tpadenyCommand by required() val tpaCommand by required() } diff --git a/src/main/kotlin/net/superricky/tpaplusplus/utility/Extensions.kt b/src/main/kotlin/net/superricky/tpaplusplus/utility/Extensions.kt index c59abbd..f8cb05f 100644 --- a/src/main/kotlin/net/superricky/tpaplusplus/utility/Extensions.kt +++ b/src/main/kotlin/net/superricky/tpaplusplus/utility/Extensions.kt @@ -27,7 +27,7 @@ fun PlayerEntity.toggleOff() = TpaPlusPlus.launch { fun PlayerEntity.getColoredName(color: Style): MutableText? = this.name.literalString?.literal()?.setStyle(color) fun PlayerEntity.getDimension(): ServerDimension = this.world.registryKey -fun PlayerEntity.sendMessage( +fun PlayerEntity.sendMessageWithPlayerName( translateKey: String, player: PlayerEntity, outStyle: Style = TextColorPallet.primary, @@ -69,6 +69,19 @@ fun PlayerEntity.sendCooldownTime( ) } +fun PlayerEntity.sendTeleportTime( + time: Double, + outStyle: Style = TextColorPallet.primary, + inStyle: Style = TextColorPallet.secondary +) { + this.sendMessage( + Text.translatable( + "command.teleport.wait", + String.format("%.1f", time).literal().setStyle(inStyle) + ).setStyle(outStyle) + ) +} + fun Double.translateSecondToTick(): Double = this * Config.getTickRate() fun Double.translateTickToSecond(): Double = this / Config.getTickRate() diff --git a/src/main/resources/data/tpaplusplus/lang/en_us.json b/src/main/resources/data/tpaplusplus/lang/en_us.json index bb21e82..60caca7 100644 --- a/src/main/resources/data/tpaplusplus/lang/en_us.json +++ b/src/main/resources/data/tpaplusplus/lang/en_us.json @@ -13,6 +13,14 @@ "command.error.request.notfound.all": "Could not find your teleport request", "command.error.request.notfound.target": "Could not find your teleport request to %s", + "command.windup.remain": "The command is executing, please wait %s s", + "command.windup.error.out_distance": "You moved too much while trying to execute /%s, so it was cancelled", + + "command.teleport.out_distance": "You moved too much while teleport, so it was cancelled", + "command.teleport.wait": "Teleporting, please wait %s s", + + "command.cooldown.command": "Command /%s is currently on cooldown, please wait %s s!", + "command.toggle.success.on": "Automatically blocks all TPA requests", "command.toggle.success.off": "Turn off automatically blocking all TPA requests", @@ -29,12 +37,9 @@ "command.tpa.request.cancel": "Teleport request from %s has been canceled!", "command.tpa.timeout.sender": "Your teleport request to %s timed out", "command.tpa.timeout.receiver": "Your teleport request from %s timed out", + "command.tpa.request.accept.from": "Teleport request to %s has been accepted, preparing for teleport", + "command.tpa.request.accept.to": "You have accepted teleport request from %s", "command.tpaaccept.request.accept.sender": "Your teleport request for %s was accepted!", - "command.tpaaccept.request.accept.receiver": "Accepted teleport request from %s", - - "command.windup.remain": "The command is executing, please wait %s s", - "command.windup.error.out_distance": "You moved too much whilst trying to execute /%s, so it was cancelled", - - "command.cooldown.command": "Command /%s is currently on cooldown, please wait %s s!" + "command.tpaaccept.request.accept.receiver": "Accepted teleport request from %s" } diff --git a/src/main/resources/data/tpaplusplus/lang/zh_cn.json b/src/main/resources/data/tpaplusplus/lang/zh_cn.json index b02b301..688d46d 100644 --- a/src/main/resources/data/tpaplusplus/lang/zh_cn.json +++ b/src/main/resources/data/tpaplusplus/lang/zh_cn.json @@ -13,6 +13,14 @@ "command.error.request.notfound.all": "找不到传送请求", "command.error.request.notfound.target": "找不到传送到 %s 的传送请求", + "command.windup.remain": "正在执行命令,请等待 %s 秒", + "command.windup.error.out_distance": "执行 /%s 的时候移动幅度过大, 取消执行", + + "command.teleport.out_distance": "在传送过程中移动幅度过大", + "command.teleport.wait": "正在传送,请等待 %s 秒", + + "command.cooldown.command": "/%s 当前正在冷却,请在%s秒后重试!", + "command.toggle.success.on": "自动阻止所有 TPA 请求", "command.toggle.success.off": "取消阻止所有 TPA 请求", @@ -29,12 +37,9 @@ "command.tpa.request.cancel": "来自 %s 的传送请求已被取消!", "command.tpa.timeout.sender": "传送到 %s 的传送请求超时", "command.tpa.timeout.receiver": "来自 %s 的传送请求超时", + "command.tpa.request.accept.from": "传送到 %s 的传送请求已被接受,正在准备传送", + "command.tpa.request.accept.to": "已接受来自 %s 的传送请求", "command.tpaaccept.request.accept.sender": "%s 已接收你的传送请求!", - "command.tpaaccept.request.accept.receiver": "已接受来自 %s 的传送请求", - - "command.windup.remain": "正在执行命令,请等待 %s 秒", - "command.windup.error.out_distance": "执行 /%s 的时候移动幅度过大, 取消执行", - - "command.cooldown.command": "/%s 当前正在冷却,请在%s秒后重试!" + "command.tpaaccept.request.accept.receiver": "已接受来自 %s 的传送请求" } diff --git a/src/main/resources/data/tpaplusplus/lang/zh_tw.json b/src/main/resources/data/tpaplusplus/lang/zh_tw.json index cade7cc..0fe9969 100644 --- a/src/main/resources/data/tpaplusplus/lang/zh_tw.json +++ b/src/main/resources/data/tpaplusplus/lang/zh_tw.json @@ -13,6 +13,14 @@ "command.error.request.notfound.all": "找不到傳送請求", "command.error.request.notfound.target": "找不到傳送到 %s 的傳送請求", + "command.windup.remain": "正在執行命令,請等待 %s 秒", + "command.windup.error.out_distance": "執行 /%s 的時候移動幅度過大,取消執行", + + "command.teleport.out_distance": "在傳送過程中移動幅度過大", + "command.teleport.wait": "正在傳送,請等待 %s 秒", + + "command.cooldown.command": "/%s 當前正在冷卻,請在%s秒後重試!", + "command.toggle.success.on": "自動阻止所有 TPA 請求", "command.toggle.success.off": "取消阻止所有 TPA 請求", @@ -29,12 +37,9 @@ "command.tpa.request.cancel": "來自 %s 的傳送請求已被取消!", "command.tpa.timeout.sender": "傳送到 %s 的傳送請求超時", "command.tpa.timeout.receiver": "來自 %s 的傳送請求超時", + "command.tpa.request.accept.from": "傳送到 %s 的傳送請求已被接受,正在準備傳送", + "command.tpa.request.accept.to": "已接受來自 %s 的傳送請求", "command.tpaaccept.request.accept.sender": "%s 已接收你的傳送請求!", - "command.tpaaccept.request.accept.receiver": "已接受來自 %s 的傳送請求", - - "command.windup.remain": "正在執行命令,請等待 %s 秒", - "command.windup.error.out_distance": "執行 /%s 的時候移動幅度過大,取消執行", - - "command.cooldown.command": "/%s 當前正在冷卻,請在%s秒後重試!" + "command.tpaaccept.request.accept.receiver": "已接受來自 %s 的傳送請求" } diff --git a/src/main/resources/tpaplusplus.toml b/src/main/resources/tpaplusplus.toml index 0f7bf50..7cf743e 100644 --- a/src/main/resources/tpaplusplus.toml +++ b/src/main/resources/tpaplusplus.toml @@ -9,14 +9,14 @@ toggledPlayerCommand = false # How long until teleport requests expire (in seconds) # This is measured in seconds. # If you wish to disable this set this to 0 -# Default: 60 +# Default: 60.0 # Range: > 0 -tpaTimeout = 60 +tpaTimeout = 60.0 # How long does the player have to wait to be teleported # This is measured in seconds. -# Default: 5 -# Range: > 0 -waitTimeBeforeTp = 5 +# Default: 5.0 +# Range: >= 0 +waitTimeBeforeTp = 5.0 [common.color] # Colors in hex format @@ -86,7 +86,7 @@ tpaunblockEnable = true tpablockEnable = true tpatoggleEnable = true tpahereEnable = true -tpaacceptEnable = true +tpacceptEnable = true tpadenyEnable = true tpaEnable = true @@ -105,7 +105,7 @@ tpaunblockCommand = "tpaunblock" tpablockCommand = "tpablock" tpatoggleCommand = "tpatoggle" tpahereCommand = "tpahere" -tpaacceptCommand = "tpaaccept" +tpacceptCommand = "tpaccept" tpadenyCommand = "tpadeny" tpaCommand = "tpa"