From 9cf19d24d2b5be9214a4a64a9983b30140a5cecb Mon Sep 17 00:00:00 2001 From: Liam Sage Date: Wed, 24 Apr 2024 10:29:47 +0200 Subject: [PATCH] feat: Fly Command (#43) --- .../database/functions/Users.kt | 2 +- .../database/model/DatabaseUser.kt | 2 +- .../extensions/PlayerExtension.kt | 10 +- .../general/commands/club/FlyCommand.kt | 133 ++++++++++++++++++ .../commands/{ => crew}/BuildCommand.kt | 9 +- .../commands/{ => crew}/RankCommand.kt | 8 +- .../commands/{ => crew}/TestCommand.kt | 4 +- .../{ => guests}/OnlinetimeCommand.kt | 6 +- .../modules/general/model/Ranks.kt | 6 +- .../blockventuremc/utils/RegisterManager.kt | 2 +- src/main/resources/translations/en-US.json | 5 +- 11 files changed, 171 insertions(+), 16 deletions(-) create mode 100644 src/main/kotlin/net/blockventuremc/modules/general/commands/club/FlyCommand.kt rename src/main/kotlin/net/blockventuremc/modules/general/commands/{ => crew}/BuildCommand.kt (77%) rename src/main/kotlin/net/blockventuremc/modules/general/commands/{ => crew}/RankCommand.kt (90%) rename src/main/kotlin/net/blockventuremc/modules/general/commands/{ => crew}/TestCommand.kt (90%) rename src/main/kotlin/net/blockventuremc/modules/general/commands/{ => guests}/OnlinetimeCommand.kt (85%) diff --git a/src/main/kotlin/net/blockventuremc/database/functions/Users.kt b/src/main/kotlin/net/blockventuremc/database/functions/Users.kt index cb2ddbd..a2e598f 100644 --- a/src/main/kotlin/net/blockventuremc/database/functions/Users.kt +++ b/src/main/kotlin/net/blockventuremc/database/functions/Users.kt @@ -15,7 +15,7 @@ import kotlin.time.Duration.Companion.seconds object TableUsers : Table("users") { val userUUID = varchar("uuid", 45) val userName = varchar("username", 24) - val userRank = enumerationByName("rank", 24, Ranks::class).default(Ranks.Default) + val userRank = enumerationByName("rank", 24, Ranks::class).default(Ranks.Guest) val userLanguage = enumerationByName("language", 2, Languages::class).default(Languages.EN) val userFirstJoined = timestamp("firstJoined").defaultExpression(CurrentTimestamp()) diff --git a/src/main/kotlin/net/blockventuremc/database/model/DatabaseUser.kt b/src/main/kotlin/net/blockventuremc/database/model/DatabaseUser.kt index d003ae2..7760315 100644 --- a/src/main/kotlin/net/blockventuremc/database/model/DatabaseUser.kt +++ b/src/main/kotlin/net/blockventuremc/database/model/DatabaseUser.kt @@ -12,7 +12,7 @@ import kotlin.time.Duration data class DatabaseUser( val uuid: UUID, val username: String, - val rank: Ranks = Ranks.Default, + val rank: Ranks = Ranks.Guest, val language: Languages = Languages.EN, // Other diff --git a/src/main/kotlin/net/blockventuremc/extensions/PlayerExtension.kt b/src/main/kotlin/net/blockventuremc/extensions/PlayerExtension.kt index 2d6fe42..a46f1fe 100644 --- a/src/main/kotlin/net/blockventuremc/extensions/PlayerExtension.kt +++ b/src/main/kotlin/net/blockventuremc/extensions/PlayerExtension.kt @@ -56,7 +56,7 @@ fun String.toOfflinePlayerIfCached(): OfflinePlayer? { val Player.canBuild: Boolean - get() = gameMode == GameMode.SPECTATOR || (this.toDatabaseUser().rank.isHigherOrEqual(Ranks.Staff) && hasBuildTag) + get() = gameMode == GameMode.SPECTATOR || (this.toDatabaseUser().rank.isHigherOrEqual(Ranks.Trial) && hasBuildTag) var Player.hasBuildTag: Boolean get() = this.scoreboardTags.contains("builder") @@ -82,4 +82,12 @@ fun UUID.toDatabaseUser(): DatabaseUser { fun UUID.toDatabaseUserDB(): DatabaseUser { return getDatabaseUserOrNull(this) ?: createDatabaseUser(DatabaseUser(this, Bukkit.getPlayer(this)?.name ?: Bukkit.getOfflinePlayer(this).name ?: "Unknown")) +} + +fun CommandSender.isRankOrHigher(rank: Ranks): Boolean { + return if (this is Player) { + this.toDatabaseUser().rank.isHigherOrEqual(rank) + } else { + true + } } \ No newline at end of file diff --git a/src/main/kotlin/net/blockventuremc/modules/general/commands/club/FlyCommand.kt b/src/main/kotlin/net/blockventuremc/modules/general/commands/club/FlyCommand.kt new file mode 100644 index 0000000..53a0d57 --- /dev/null +++ b/src/main/kotlin/net/blockventuremc/modules/general/commands/club/FlyCommand.kt @@ -0,0 +1,133 @@ +package net.blockventuremc.modules.general.commands.club + +import net.blockventuremc.annotations.BlockCommand +import net.blockventuremc.extensions.isRankOrHigher +import net.blockventuremc.extensions.sendMessagePrefixed +import net.blockventuremc.extensions.toDatabaseUser +import net.blockventuremc.extensions.translate +import net.blockventuremc.modules.general.model.Ranks +import org.bukkit.command.Command +import org.bukkit.command.CommandExecutor +import org.bukkit.command.CommandSender +import org.bukkit.entity.Player +import org.bukkit.permissions.PermissionDefault + +/** + * Class representing a command for toggling fly mode. + * + * @property name The name of the command. + * @property description The description of the command. + * @property permission The permission required to use the command. + * @property permissionDefault The default permission level for the command. + * @property usage The usage of the command. + */ +@BlockCommand( + name = "fly", + description = "Toggle fly mode", + permission = "blockventure.fly", + permissionDefault = PermissionDefault.TRUE, + usage = "/fly", +) +class FlyCommand : CommandExecutor { + + /** + * Executes the command when it is invoked. + * + * @param sender The command sender. + * @param command The command being executed. + * @param label The command label. + * @param args The command arguments. + * @return True if the command was executed successfully, false otherwise. + */ + override fun onCommand( + sender: CommandSender, + command: Command, + label: String, + args: Array + ): Boolean { + if (args.isNotEmpty() && sender.isRankOrHigher(Ranks.Trial)) { + val target = sender.server.getPlayerExact(args[0]) + if (target == null) { + sender.sendMessagePrefixed("Player not found.") + return true + } + changeFlyModeOfUser(sender, target) + return true + } + + if (sender !is Player) { + sender.sendMessagePrefixed("This command is only available to players. Use /fly to toggle fly mode for another player.") + return true + } + + if (!sender.isRankOrHigher(Ranks.ClubMember)) { + sender.sendMessagePrefixed(sender.translate("no_permission.club_member")?.message ?: "This command is only available to Club Members.") + sender.allowFlight = false + return true + } + + changeFlyModeOfUser(sender, sender) + + return true + } + + /** + * Toggles the fly mode of a given player. + * + * @param commandExecutor The command executor. + * @param targetPlayer The player whose fly mode will be changed. + */ + private fun changeFlyModeOfUser(commandExecutor: CommandSender, targetPlayer: Player) { + val wasFlightAllowed = targetPlayer.allowFlight + + targetPlayer.allowFlight = !wasFlightAllowed + val flightModeStatusMessage = if (targetPlayer.allowFlight) "enabled" else "disabled" + + sendFlightModeToggleMessage(targetPlayer, flightModeStatusMessage) + + if (targetPlayer != commandExecutor) { + sendNotifyExecutorMessage(commandExecutor, targetPlayer, flightModeStatusMessage) + } + } + + /** + * Sends a flight mode toggle message to the player. + * + * @param player The player who will receive the message. + * @param flightModeStatusMessage The status message indicating whether the flight mode is enabled or disabled. + */ + private fun sendFlightModeToggleMessage(player: Player, flightModeStatusMessage: String) { + val message = player.toDatabaseUser().translate( + "fly_mode_toggled", + mapOf("enabled" to flightModeStatusMessage) + )?.message ?: "Fly mode is now $flightModeStatusMessage" + player.sendMessagePrefixed(message) + } + + /** + * Sends a notification message to the command executor. + * + * @param commandExecutor The command sender who executed the command. + * @param targetPlayer The player for which the flight mode was toggled. + * @param flightModeStatusMessage The status message indicating whether the flight mode is enabled or disabled. + */ + private fun sendNotifyExecutorMessage( + commandExecutor: CommandSender, + targetPlayer: Player, + flightModeStatusMessage: String + ) { + val message = if (commandExecutor is Player) { + val translatedMessage = commandExecutor.toDatabaseUser().translate( + "fly_mode_toggled_by", + mapOf( + "enabled" to flightModeStatusMessage, + "player" to targetPlayer.name + ) + )?.message + translatedMessage ?: "Fly mode of ${targetPlayer.name} is now $flightModeStatusMessage" + } else { + "Fly mode of ${targetPlayer.name} is now $flightModeStatusMessage" + } + commandExecutor.sendMessagePrefixed(message) + } +} \ No newline at end of file diff --git a/src/main/kotlin/net/blockventuremc/modules/general/commands/BuildCommand.kt b/src/main/kotlin/net/blockventuremc/modules/general/commands/crew/BuildCommand.kt similarity index 77% rename from src/main/kotlin/net/blockventuremc/modules/general/commands/BuildCommand.kt rename to src/main/kotlin/net/blockventuremc/modules/general/commands/crew/BuildCommand.kt index 422ec7b..f265874 100644 --- a/src/main/kotlin/net/blockventuremc/modules/general/commands/BuildCommand.kt +++ b/src/main/kotlin/net/blockventuremc/modules/general/commands/crew/BuildCommand.kt @@ -1,13 +1,16 @@ -package net.blockventuremc.modules.general.commands +package net.blockventuremc.modules.general.commands.crew import net.blockventuremc.annotations.BlockCommand -import net.blockventuremc.consts.* -import net.blockventuremc.extensions.* +import net.blockventuremc.extensions.hasBuildTag +import net.blockventuremc.extensions.sendMessagePrefixed +import net.blockventuremc.extensions.toDatabaseUser +import net.blockventuremc.extensions.translate import org.bukkit.command.CommandExecutor import org.bukkit.permissions.PermissionDefault import org.bukkit.command.Command import org.bukkit.command.CommandSender import org.bukkit.entity.Player +import kotlin.to @BlockCommand( diff --git a/src/main/kotlin/net/blockventuremc/modules/general/commands/RankCommand.kt b/src/main/kotlin/net/blockventuremc/modules/general/commands/crew/RankCommand.kt similarity index 90% rename from src/main/kotlin/net/blockventuremc/modules/general/commands/RankCommand.kt rename to src/main/kotlin/net/blockventuremc/modules/general/commands/crew/RankCommand.kt index 21ff3b6..59a76ef 100644 --- a/src/main/kotlin/net/blockventuremc/modules/general/commands/RankCommand.kt +++ b/src/main/kotlin/net/blockventuremc/modules/general/commands/crew/RankCommand.kt @@ -1,4 +1,4 @@ -package net.blockventuremc.modules.general.commands +package net.blockventuremc.modules.general.commands.crew import net.blockventuremc.annotations.BlockCommand import net.blockventuremc.cache.PlayerCache @@ -10,6 +10,12 @@ import org.bukkit.command.TabCompleter import org.bukkit.permissions.PermissionDefault import org.bukkit.command.Command import org.bukkit.command.CommandSender +import kotlin.collections.filter +import kotlin.collections.find +import kotlin.collections.map +import kotlin.collections.sortedByDescending +import kotlin.text.equals +import kotlin.text.startsWith @BlockCommand( name = "rank", diff --git a/src/main/kotlin/net/blockventuremc/modules/general/commands/TestCommand.kt b/src/main/kotlin/net/blockventuremc/modules/general/commands/crew/TestCommand.kt similarity index 90% rename from src/main/kotlin/net/blockventuremc/modules/general/commands/TestCommand.kt rename to src/main/kotlin/net/blockventuremc/modules/general/commands/crew/TestCommand.kt index 0a98bdb..0d98194 100644 --- a/src/main/kotlin/net/blockventuremc/modules/general/commands/TestCommand.kt +++ b/src/main/kotlin/net/blockventuremc/modules/general/commands/crew/TestCommand.kt @@ -1,4 +1,4 @@ -package net.blockventuremc.modules.general.commands +package net.blockventuremc.modules.general.commands.crew import net.blockventuremc.annotations.BlockCommand import net.blockventuremc.database.model.DatabaseUser @@ -21,7 +21,7 @@ class TestCommand: CommandExecutor { val u = DatabaseUser(sender.uniqueId, sender.name) - if (!u.rank.isHigherOrEqual(Ranks.Staff)) { + if (!u.rank.isHigherOrEqual(Ranks.Crew)) { sender.sendMessagePrefixed("You do not have permission to use this command.") return true } diff --git a/src/main/kotlin/net/blockventuremc/modules/general/commands/OnlinetimeCommand.kt b/src/main/kotlin/net/blockventuremc/modules/general/commands/guests/OnlinetimeCommand.kt similarity index 85% rename from src/main/kotlin/net/blockventuremc/modules/general/commands/OnlinetimeCommand.kt rename to src/main/kotlin/net/blockventuremc/modules/general/commands/guests/OnlinetimeCommand.kt index 4721626..1ced923 100644 --- a/src/main/kotlin/net/blockventuremc/modules/general/commands/OnlinetimeCommand.kt +++ b/src/main/kotlin/net/blockventuremc/modules/general/commands/guests/OnlinetimeCommand.kt @@ -1,4 +1,4 @@ -package net.blockventuremc.modules.general.commands +package net.blockventuremc.modules.general.commands.guests import net.blockventuremc.annotations.BlockCommand import net.blockventuremc.extensions.getLogger @@ -10,7 +10,9 @@ import org.bukkit.command.CommandExecutor import org.bukkit.command.CommandSender import org.bukkit.entity.Player import org.bukkit.permissions.PermissionDefault +import java.lang.management.ManagementFactory import kotlin.time.Duration.Companion.milliseconds +import kotlin.to @BlockCommand( @@ -31,7 +33,7 @@ class OnlinetimeCommand : CommandExecutor { args: Array ): Boolean { if (sender !is Player) { - val jreRunningSince = System.currentTimeMillis() - java.lang.management.ManagementFactory.getRuntimeMXBean().startTime + val jreRunningSince = System.currentTimeMillis() - ManagementFactory.getRuntimeMXBean().startTime val runTimeDuration = jreRunningSince.milliseconds getLogger().info("The server is running for $runTimeDuration") return true diff --git a/src/main/kotlin/net/blockventuremc/modules/general/model/Ranks.kt b/src/main/kotlin/net/blockventuremc/modules/general/model/Ranks.kt index 6b43b73..16b41a4 100644 --- a/src/main/kotlin/net/blockventuremc/modules/general/model/Ranks.kt +++ b/src/main/kotlin/net/blockventuremc/modules/general/model/Ranks.kt @@ -2,9 +2,9 @@ package net.blockventuremc.modules.general.model enum class Ranks(val color: String) { Crew("#54a0ff"), - Staff("#576574"), - Plus("#f368e0"), - Default("#c8d6e5"); + Trial("#576574"), + ClubMember("#ea8685"), + Guest("#c8d6e5"); fun isHigherOrEqual(rank: Ranks): Boolean { return this.ordinal <= rank.ordinal diff --git a/src/main/kotlin/net/blockventuremc/utils/RegisterManager.kt b/src/main/kotlin/net/blockventuremc/utils/RegisterManager.kt index 6a0e545..505a83c 100644 --- a/src/main/kotlin/net/blockventuremc/utils/RegisterManager.kt +++ b/src/main/kotlin/net/blockventuremc/utils/RegisterManager.kt @@ -37,7 +37,7 @@ object RegisterManager { try { commandInstance.onCommand(sender, command, label, args) } catch (e: Exception) { - sender.sendMessagePrefixed("Ein Fehler ist aufgetreten!") + sender.sendMessagePrefixed("An error occurred while executing the command.") throw e } } diff --git a/src/main/resources/translations/en-US.json b/src/main/resources/translations/en-US.json index b039c20..f467cc8 100644 --- a/src/main/resources/translations/en-US.json +++ b/src/main/resources/translations/en-US.json @@ -1,4 +1,7 @@ { "build_mode_toggled": "Build mode is now %enabled%.", - "onlinetime": "Your online time is %onlinetime%." + "fly_mode_toggled": "Fly mode is now %enabled%.", + "fly_mode_toggled_by": "Fly mode of %player% is now %enabled%.", + "onlinetime": "Your online time is %onlinetime%.", + "no_permission.club_member": "This command is only available to Club Members." } \ No newline at end of file