From c27ce111c80be086f5eaaf08149b4e4c764f8e65 Mon Sep 17 00:00:00 2001 From: Foxof7207 <167218619+Foxof7207@users.noreply.github.com> Date: Fri, 15 May 2026 14:27:38 -0400 Subject: [PATCH 1/4] feat: implement Essentials module with TPA command functionality --- .../rothes/esu/bukkit/EsuPluginBukkit.kt | 1 + .../esu/bukkit/module/EssentialsModule.kt | 17 +++ .../esu/bukkit/module/essentials/Teleports.kt | 29 +++++ .../bukkit/module/essentials/teleports/Tpa.kt | 101 ++++++++++++++++++ 4 files changed, 148 insertions(+) create mode 100644 bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/EssentialsModule.kt create mode 100644 bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/essentials/Teleports.kt create mode 100644 bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/essentials/teleports/Tpa.kt diff --git a/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/EsuPluginBukkit.kt b/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/EsuPluginBukkit.kt index de7a252e..21779a84 100644 --- a/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/EsuPluginBukkit.kt +++ b/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/EsuPluginBukkit.kt @@ -115,6 +115,7 @@ class EsuPluginBukkit( ModuleManager.addModule(NewsModule) ModuleManager.addModule(OptimizationsModule) ModuleManager.addModule(SpoofServerSettingsModule) + ModuleManager.addModule(EssentialsModule) ModuleManager.addModule(VanillaTweaks) ModuleManager.addModule(AutoReloadExtensionPluginsModule) diff --git a/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/EssentialsModule.kt b/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/EssentialsModule.kt new file mode 100644 index 00000000..311badd3 --- /dev/null +++ b/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/EssentialsModule.kt @@ -0,0 +1,17 @@ +package io.github.rothes.esu.bukkit.module + +import io.github.rothes.esu.bukkit.module.essentials.Teleports +import io.github.rothes.esu.core.module.configuration.BaseModuleConfiguration +import io.github.rothes.esu.core.module.configuration.EmptyConfiguration + +object EssentialsModule : BukkitModule() { + + init { + registerFeature(Teleports) + } + + override fun onEnable() {} + + class ModuleConfig : BaseModuleConfiguration() + +} diff --git a/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/essentials/Teleports.kt b/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/essentials/Teleports.kt new file mode 100644 index 00000000..480593a5 --- /dev/null +++ b/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/essentials/Teleports.kt @@ -0,0 +1,29 @@ +package io.github.rothes.esu.bukkit.module.essentials + +import io.github.rothes.esu.bukkit.module.essentials.teleports.Tpa +import io.github.rothes.esu.core.configuration.ConfigurationPart +import io.github.rothes.esu.core.configuration.data.MessageData +import io.github.rothes.esu.core.configuration.data.MessageData.Companion.message +import io.github.rothes.esu.core.module.CommonFeature + +object Teleports : CommonFeature() { + + init { + registerFeature(Tpa) + } + + override fun onEnable() {} + + data class Lang( + val tpaRequestSent: MessageData = "Teleport request sent to .".message, + val tpaRequestReceived: MessageData = " has requested to teleport to you.\nType /tpaccept to accept or /tpdeny to deny.".message, + val tpaNoPendingRequest: MessageData = "You have no pending teleport requests.".message, + val tpaRequestAccepted: MessageData = "Teleport request accepted.".message, + val tpaRequestDenied: MessageData = "Teleport request denied.".message, + val tpaRequestCancelled: MessageData = "Teleport request cancelled.".message, + val tpaPlayerNotOnline: MessageData = "That player is not online.".message, + val tpaCannotRequestSelf: MessageData = "You cannot teleport to yourself.".message, + val tpaRequestAlreadySent: MessageData = "You have already sent a teleport request to this player.".message, + ) : ConfigurationPart + +} diff --git a/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/essentials/teleports/Tpa.kt b/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/essentials/teleports/Tpa.kt new file mode 100644 index 00000000..277c6c67 --- /dev/null +++ b/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/essentials/teleports/Tpa.kt @@ -0,0 +1,101 @@ +package io.github.rothes.esu.bukkit.module.essentials.teleports + +import io.github.rothes.esu.bukkit.module.essentials.Teleports +import io.github.rothes.esu.bukkit.user +import io.github.rothes.esu.bukkit.user.PlayerUser +import io.github.rothes.esu.bukkit.util.ComponentBukkitUtils.player +import io.github.rothes.esu.bukkit.util.ServerCompatibility.tp +import io.github.rothes.esu.core.command.annotation.ShortPerm +import io.github.rothes.esu.core.module.CommonFeature +import io.github.rothes.esu.core.module.configuration.FeatureToggle +import io.github.rothes.esu.core.user.User +import org.bukkit.entity.Player +import org.incendo.cloud.annotations.Command +import java.util.* + +object Tpa : CommonFeature() { + + // target -> requester + private val pendingRequests = mutableMapOf() + + override fun onEnable() { + registerCommands(object { + + @Command("tpa ") + @ShortPerm + fun tpa(sender: User, target: Player) { + if (sender !is PlayerUser) return + if (sender.player == target) { + sender.message(Teleports.lang, { tpaCannotRequestSelf }) + return + } + + if (pendingRequests[target.uniqueId] == sender.uuid) { + sender.message(Teleports.lang, { tpaRequestAlreadySent }) + return + } + + pendingRequests[target.uniqueId] = sender.uuid + sender.message(Teleports.lang, { tpaRequestSent }, player(target)) + target.user.message(Teleports.lang, { tpaRequestReceived }, player(sender.player)) + } + + @Command("tpaccept [requester]") + @ShortPerm + fun tpaccept(sender: User, requester: Player?) { + if (sender !is PlayerUser) return + + val requesterId = requester?.uniqueId ?: pendingRequests[sender.uuid] + if (requesterId == null || (requester != null && pendingRequests[sender.uuid] != requesterId)) { + sender.message(Teleports.lang, { tpaNoPendingRequest }) + return + } + + val requesterPlayer = org.bukkit.Bukkit.getPlayer(requesterId) + if (requesterPlayer == null) { + sender.message(Teleports.lang, { tpaPlayerNotOnline }) + pendingRequests.remove(sender.uuid) + return + } + + pendingRequests.remove(sender.uuid) + requesterPlayer.tp(sender.player.location) + sender.message(Teleports.lang, { tpaRequestAccepted }) + requesterPlayer.user.message(Teleports.lang, { tpaRequestAccepted }) + } + + @Command("tpdeny [requester]") + @ShortPerm + fun tpdeny(sender: User, requester: Player?) { + if (sender !is PlayerUser) return + + val requesterId = requester?.uniqueId ?: pendingRequests[sender.uuid] + if (requesterId == null || (requester != null && pendingRequests[sender.uuid] != requesterId)) { + sender.message(Teleports.lang, { tpaNoPendingRequest }) + return + } + + pendingRequests.remove(sender.uuid) + sender.message(Teleports.lang, { tpaRequestDenied }) + org.bukkit.Bukkit.getPlayer(requesterId)?.user?.message(Teleports.lang, { tpaRequestDenied }) + } + + @Command("tpcancel [target]") + @ShortPerm + fun tpcancel(sender: User, target: Player?) { + if (sender !is PlayerUser) return + + val targetId = target?.uniqueId ?: pendingRequests.entries.find { it.value == sender.uuid }?.key + if (targetId == null || (target != null && pendingRequests[targetId] != sender.uuid)) { + sender.message(Teleports.lang, { tpaNoPendingRequest }) + return + } + + pendingRequests.remove(targetId) + sender.message(Teleports.lang, { tpaRequestCancelled }) + org.bukkit.Bukkit.getPlayer(targetId)?.user?.message(Teleports.lang, { tpaRequestCancelled }) + } + }) + } + +} From c7ce0da61bbe15405d8bf79924dcbca4853f48c5 Mon Sep 17 00:00:00 2001 From: Foxof7207 <167218619+Foxof7207@users.noreply.github.com> Date: Fri, 15 May 2026 14:35:42 -0400 Subject: [PATCH 2/4] fix: ensure teleportation occurs on main thread and clear pending requests on disable --- .../bukkit/module/essentials/teleports/Tpa.kt | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/essentials/teleports/Tpa.kt b/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/essentials/teleports/Tpa.kt index 277c6c67..974f461c 100644 --- a/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/essentials/teleports/Tpa.kt +++ b/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/essentials/teleports/Tpa.kt @@ -5,10 +5,12 @@ import io.github.rothes.esu.bukkit.user import io.github.rothes.esu.bukkit.user.PlayerUser import io.github.rothes.esu.bukkit.util.ComponentBukkitUtils.player import io.github.rothes.esu.bukkit.util.ServerCompatibility.tp +import io.github.rothes.esu.bukkit.util.scheduler.Scheduler.syncTick import io.github.rothes.esu.core.command.annotation.ShortPerm import io.github.rothes.esu.core.module.CommonFeature import io.github.rothes.esu.core.module.configuration.FeatureToggle import io.github.rothes.esu.core.user.User +import org.bukkit.Bukkit import org.bukkit.entity.Player import org.incendo.cloud.annotations.Command import java.util.* @@ -51,7 +53,7 @@ object Tpa : CommonFeature() { return } - val requesterPlayer = org.bukkit.Bukkit.getPlayer(requesterId) + val requesterPlayer = Bukkit.getPlayer(requesterId) if (requesterPlayer == null) { sender.message(Teleports.lang, { tpaPlayerNotOnline }) pendingRequests.remove(sender.uuid) @@ -59,7 +61,9 @@ object Tpa : CommonFeature() { } pendingRequests.remove(sender.uuid) - requesterPlayer.tp(sender.player.location) + requesterPlayer.syncTick { + requesterPlayer.tp(sender.player.location) + } sender.message(Teleports.lang, { tpaRequestAccepted }) requesterPlayer.user.message(Teleports.lang, { tpaRequestAccepted }) } @@ -77,7 +81,7 @@ object Tpa : CommonFeature() { pendingRequests.remove(sender.uuid) sender.message(Teleports.lang, { tpaRequestDenied }) - org.bukkit.Bukkit.getPlayer(requesterId)?.user?.message(Teleports.lang, { tpaRequestDenied }) + Bukkit.getPlayer(requesterId)?.user?.message(Teleports.lang, { tpaRequestDenied }) } @Command("tpcancel [target]") @@ -93,9 +97,14 @@ object Tpa : CommonFeature() { pendingRequests.remove(targetId) sender.message(Teleports.lang, { tpaRequestCancelled }) - org.bukkit.Bukkit.getPlayer(targetId)?.user?.message(Teleports.lang, { tpaRequestCancelled }) + Bukkit.getPlayer(targetId)?.user?.message(Teleports.lang, { tpaRequestCancelled }) } }) } + override fun onDisable() { + pendingRequests.clear() + super.onDisable() + } + } From 8817ebc440608f55100aa8a18bbaa08468c7e49c Mon Sep 17 00:00:00 2001 From: Foxof7207 <167218619+Foxof7207@users.noreply.github.com> Date: Sat, 16 May 2026 16:58:15 -0400 Subject: [PATCH 3/4] refactor: migrate TPA request storage to expiring cache and move Lang configuration to the Tpa module --- .../esu/bukkit/module/essentials/Teleports.kt | 14 +-- .../bukkit/module/essentials/teleports/Tpa.kt | 94 +++++++++++-------- 2 files changed, 57 insertions(+), 51 deletions(-) diff --git a/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/essentials/Teleports.kt b/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/essentials/Teleports.kt index 480593a5..3a025063 100644 --- a/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/essentials/Teleports.kt +++ b/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/essentials/Teleports.kt @@ -2,8 +2,6 @@ package io.github.rothes.esu.bukkit.module.essentials import io.github.rothes.esu.bukkit.module.essentials.teleports.Tpa import io.github.rothes.esu.core.configuration.ConfigurationPart -import io.github.rothes.esu.core.configuration.data.MessageData -import io.github.rothes.esu.core.configuration.data.MessageData.Companion.message import io.github.rothes.esu.core.module.CommonFeature object Teleports : CommonFeature() { @@ -14,16 +12,6 @@ object Teleports : CommonFeature() { override fun onEnable() {} - data class Lang( - val tpaRequestSent: MessageData = "Teleport request sent to .".message, - val tpaRequestReceived: MessageData = " has requested to teleport to you.\nType /tpaccept to accept or /tpdeny to deny.".message, - val tpaNoPendingRequest: MessageData = "You have no pending teleport requests.".message, - val tpaRequestAccepted: MessageData = "Teleport request accepted.".message, - val tpaRequestDenied: MessageData = "Teleport request denied.".message, - val tpaRequestCancelled: MessageData = "Teleport request cancelled.".message, - val tpaPlayerNotOnline: MessageData = "That player is not online.".message, - val tpaCannotRequestSelf: MessageData = "You cannot teleport to yourself.".message, - val tpaRequestAlreadySent: MessageData = "You have already sent a teleport request to this player.".message, - ) : ConfigurationPart + class Lang : ConfigurationPart } diff --git a/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/essentials/teleports/Tpa.kt b/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/essentials/teleports/Tpa.kt index 974f461c..a8f8fdcf 100644 --- a/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/essentials/teleports/Tpa.kt +++ b/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/essentials/teleports/Tpa.kt @@ -1,12 +1,16 @@ package io.github.rothes.esu.bukkit.module.essentials.teleports -import io.github.rothes.esu.bukkit.module.essentials.Teleports +import com.google.common.cache.Cache +import com.google.common.cache.CacheBuilder import io.github.rothes.esu.bukkit.user import io.github.rothes.esu.bukkit.user.PlayerUser import io.github.rothes.esu.bukkit.util.ComponentBukkitUtils.player import io.github.rothes.esu.bukkit.util.ServerCompatibility.tp import io.github.rothes.esu.bukkit.util.scheduler.Scheduler.syncTick import io.github.rothes.esu.core.command.annotation.ShortPerm +import io.github.rothes.esu.core.configuration.ConfigurationPart +import io.github.rothes.esu.core.configuration.data.MessageData +import io.github.rothes.esu.core.configuration.data.MessageData.Companion.message import io.github.rothes.esu.core.module.CommonFeature import io.github.rothes.esu.core.module.configuration.FeatureToggle import io.github.rothes.esu.core.user.User @@ -14,11 +18,26 @@ import org.bukkit.Bukkit import org.bukkit.entity.Player import org.incendo.cloud.annotations.Command import java.util.* - -object Tpa : CommonFeature() { +import java.util.concurrent.TimeUnit + +object Tpa : CommonFeature() { + + data class Lang( + val requestSent: MessageData = "Teleport request sent to .".message, + val requestReceived: MessageData = " has requested to teleport to you.\nType /tpaccept to accept or /tpdeny to deny.".message, + val noPendingRequest: MessageData = "You have no pending teleport requests.".message, + val requestAccepted: MessageData = "Teleport request accepted.".message, + val requestDenied: MessageData = "Teleport request denied.".message, + val requestCancelled: MessageData = "Teleport request cancelled.".message, + val playerNotOnline: MessageData = "That player is not online.".message, + val cannotRequestSelf: MessageData = "You cannot teleport to yourself.".message, + val requestAlreadySent: MessageData = "You have already sent a teleport request to this player.".message, + ) : ConfigurationPart // target -> requester - private val pendingRequests = mutableMapOf() + private val pendingRequests: Cache = CacheBuilder.newBuilder() + .expireAfterWrite(5, TimeUnit.MINUTES) + .build() override fun onEnable() { registerCommands(object { @@ -28,82 +47,81 @@ object Tpa : CommonFeature() { fun tpa(sender: User, target: Player) { if (sender !is PlayerUser) return if (sender.player == target) { - sender.message(Teleports.lang, { tpaCannotRequestSelf }) + sender.message(lang, { cannotRequestSelf }) return } - if (pendingRequests[target.uniqueId] == sender.uuid) { - sender.message(Teleports.lang, { tpaRequestAlreadySent }) + if (pendingRequests.getIfPresent(target.uniqueId) == sender.uuid) { + sender.message(lang, { requestAlreadySent }) return } - pendingRequests[target.uniqueId] = sender.uuid - sender.message(Teleports.lang, { tpaRequestSent }, player(target)) - target.user.message(Teleports.lang, { tpaRequestReceived }, player(sender.player)) + pendingRequests.put(target.uniqueId, sender.uuid) + sender.message(lang, { requestSent }, player(target)) + target.user.message(lang, { requestReceived }, player(sender.player)) } @Command("tpaccept [requester]") @ShortPerm - fun tpaccept(sender: User, requester: Player?) { + fun tpaccept(sender: User, requester: Player? = (sender as? PlayerUser)?.uuid?.let { pendingRequests.getIfPresent(it) }?.let(Bukkit::getPlayer)) { if (sender !is PlayerUser) return - val requesterId = requester?.uniqueId ?: pendingRequests[sender.uuid] - if (requesterId == null || (requester != null && pendingRequests[sender.uuid] != requesterId)) { - sender.message(Teleports.lang, { tpaNoPendingRequest }) + val expectedId = pendingRequests.getIfPresent(sender.uuid) + if (expectedId == null || (requester != null && expectedId != requester.uniqueId)) { + sender.message(lang, { noPendingRequest }) return } - val requesterPlayer = Bukkit.getPlayer(requesterId) - if (requesterPlayer == null) { - sender.message(Teleports.lang, { tpaPlayerNotOnline }) - pendingRequests.remove(sender.uuid) + if (requester == null) { + sender.message(lang, { playerNotOnline }) + pendingRequests.invalidate(sender.uuid) return } - pendingRequests.remove(sender.uuid) - requesterPlayer.syncTick { - requesterPlayer.tp(sender.player.location) + pendingRequests.invalidate(sender.uuid) + requester.syncTick { + requester.tp(sender.player.location) } - sender.message(Teleports.lang, { tpaRequestAccepted }) - requesterPlayer.user.message(Teleports.lang, { tpaRequestAccepted }) + sender.message(lang, { requestAccepted }) + requester.user.message(lang, { requestAccepted }) } @Command("tpdeny [requester]") @ShortPerm - fun tpdeny(sender: User, requester: Player?) { + fun tpdeny(sender: User, requester: Player? = (sender as? PlayerUser)?.uuid?.let { pendingRequests.getIfPresent(it) }?.let(Bukkit::getPlayer)) { if (sender !is PlayerUser) return - val requesterId = requester?.uniqueId ?: pendingRequests[sender.uuid] - if (requesterId == null || (requester != null && pendingRequests[sender.uuid] != requesterId)) { - sender.message(Teleports.lang, { tpaNoPendingRequest }) + val expectedId = pendingRequests.getIfPresent(sender.uuid) + if (expectedId == null || (requester != null && expectedId != requester.uniqueId)) { + sender.message(lang, { noPendingRequest }) return } - pendingRequests.remove(sender.uuid) - sender.message(Teleports.lang, { tpaRequestDenied }) - Bukkit.getPlayer(requesterId)?.user?.message(Teleports.lang, { tpaRequestDenied }) + pendingRequests.invalidate(sender.uuid) + sender.message(lang, { requestDenied }) + requester?.user?.message(lang, { requestDenied }) } @Command("tpcancel [target]") @ShortPerm - fun tpcancel(sender: User, target: Player?) { + fun tpcancel(sender: User, target: Player? = (sender as? PlayerUser)?.uuid?.let { senderId -> pendingRequests.asMap().entries.find { it.value == senderId }?.key }?.let(Bukkit::getPlayer)) { if (sender !is PlayerUser) return - val targetId = target?.uniqueId ?: pendingRequests.entries.find { it.value == sender.uuid }?.key - if (targetId == null || (target != null && pendingRequests[targetId] != sender.uuid)) { - sender.message(Teleports.lang, { tpaNoPendingRequest }) + val expectedTargetId = pendingRequests.asMap().entries.find { it.value == sender.uuid }?.key + if (expectedTargetId == null || (target != null && expectedTargetId != target.uniqueId)) { + sender.message(lang, { noPendingRequest }) return } - pendingRequests.remove(targetId) - sender.message(Teleports.lang, { tpaRequestCancelled }) - Bukkit.getPlayer(targetId)?.user?.message(Teleports.lang, { tpaRequestCancelled }) + pendingRequests.invalidate(expectedTargetId) + sender.message(lang, { requestCancelled }) + target?.user?.message(lang, { requestCancelled }) } }) } override fun onDisable() { - pendingRequests.clear() + pendingRequests.invalidateAll() super.onDisable() } From 354a0ad12c57c5631cde35e2717c8515f4b9e351 Mon Sep 17 00:00:00 2001 From: Foxof7207 <167218619+Foxof7207@users.noreply.github.com> Date: Sat, 16 May 2026 17:03:04 -0400 Subject: [PATCH 4/4] refactor: remove default argument logic from Tpa command methods to resolve command parameter issues --- .../bukkit/module/essentials/teleports/Tpa.kt | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/essentials/teleports/Tpa.kt b/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/essentials/teleports/Tpa.kt index a8f8fdcf..048b499c 100644 --- a/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/essentials/teleports/Tpa.kt +++ b/bukkit/src/main/kotlin/io/github/rothes/esu/bukkit/module/essentials/teleports/Tpa.kt @@ -63,59 +63,62 @@ object Tpa : CommonFeature() { @Command("tpaccept [requester]") @ShortPerm - fun tpaccept(sender: User, requester: Player? = (sender as? PlayerUser)?.uuid?.let { pendingRequests.getIfPresent(it) }?.let(Bukkit::getPlayer)) { + fun tpaccept(sender: User, requester: Player?) { if (sender !is PlayerUser) return - val expectedId = pendingRequests.getIfPresent(sender.uuid) - if (expectedId == null || (requester != null && expectedId != requester.uniqueId)) { + val pendingId = pendingRequests.getIfPresent(sender.uuid) + val requesterId = requester?.uniqueId ?: pendingId + if (requesterId == null || (requester != null && pendingId != requesterId)) { sender.message(lang, { noPendingRequest }) return } - if (requester == null) { + val requesterPlayer = requester ?: Bukkit.getPlayer(requesterId) + if (requesterPlayer == null) { sender.message(lang, { playerNotOnline }) pendingRequests.invalidate(sender.uuid) return } pendingRequests.invalidate(sender.uuid) - requester.syncTick { - requester.tp(sender.player.location) + requesterPlayer.syncTick { + requesterPlayer.tp(sender.player.location) } sender.message(lang, { requestAccepted }) - requester.user.message(lang, { requestAccepted }) + requesterPlayer.user.message(lang, { requestAccepted }) } @Command("tpdeny [requester]") @ShortPerm - fun tpdeny(sender: User, requester: Player? = (sender as? PlayerUser)?.uuid?.let { pendingRequests.getIfPresent(it) }?.let(Bukkit::getPlayer)) { + fun tpdeny(sender: User, requester: Player?) { if (sender !is PlayerUser) return - val expectedId = pendingRequests.getIfPresent(sender.uuid) - if (expectedId == null || (requester != null && expectedId != requester.uniqueId)) { + val pendingId = pendingRequests.getIfPresent(sender.uuid) + val requesterId = requester?.uniqueId ?: pendingId + if (requesterId == null || (requester != null && pendingId != requesterId)) { sender.message(lang, { noPendingRequest }) return } pendingRequests.invalidate(sender.uuid) sender.message(lang, { requestDenied }) - requester?.user?.message(lang, { requestDenied }) + Bukkit.getPlayer(requesterId)?.user?.message(lang, { requestDenied }) } @Command("tpcancel [target]") @ShortPerm - fun tpcancel(sender: User, target: Player? = (sender as? PlayerUser)?.uuid?.let { senderId -> pendingRequests.asMap().entries.find { it.value == senderId }?.key }?.let(Bukkit::getPlayer)) { + fun tpcancel(sender: User, target: Player?) { if (sender !is PlayerUser) return - val expectedTargetId = pendingRequests.asMap().entries.find { it.value == sender.uuid }?.key - if (expectedTargetId == null || (target != null && expectedTargetId != target.uniqueId)) { + val targetId = target?.uniqueId ?: pendingRequests.asMap().entries.find { it.value == sender.uuid }?.key + if (targetId == null || (target != null && pendingRequests.getIfPresent(targetId) != sender.uuid)) { sender.message(lang, { noPendingRequest }) return } - pendingRequests.invalidate(expectedTargetId) + pendingRequests.invalidate(targetId) sender.message(lang, { requestCancelled }) - target?.user?.message(lang, { requestCancelled }) + Bukkit.getPlayer(targetId)?.user?.message(lang, { requestCancelled }) } }) }