From 661f96774b3bb859662b2cf6d5e37b3329c2284c Mon Sep 17 00:00:00 2001 From: xwinterkitty <141590124+snowycatdev@users.noreply.github.com> Date: Tue, 10 Mar 2026 09:37:49 -1000 Subject: [PATCH 01/10] Add files via upload --- ModeService.kt | 315 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 ModeService.kt diff --git a/ModeService.kt b/ModeService.kt new file mode 100644 index 0000000..7e44005 --- /dev/null +++ b/ModeService.kt @@ -0,0 +1,315 @@ +package me.clearedSpore.sporeCore.features.mode + +import de.exlll.configlib.ConfigurationException +import de.exlll.configlib.YamlConfigurations +import me.clearedSpore.sporeAPI.exception.LoggedException +import me.clearedSpore.sporeAPI.util.Logger +import me.clearedSpore.sporeAPI.util.Webhook +import me.clearedSpore.sporeCore.SporeCore +import me.clearedSpore.sporeCore.extension.PlayerExtension.uuid +import me.clearedSpore.sporeCore.features.discord.DiscordService +import me.clearedSpore.sporeCore.features.mode.config.ModeConfig +import me.clearedSpore.sporeCore.features.mode.item.ModeItemManager +import me.clearedSpore.sporeCore.features.mode.`object`.Mode +import me.clearedSpore.sporeCore.features.mode.`object`.ModeData +import me.clearedSpore.sporeCore.features.vanish.VanishService +import me.clearedSpore.sporeCore.inventory.InventoryManager +import org.bukkit.Bukkit +import org.bukkit.ChatColor +import org.bukkit.GameMode +import org.bukkit.entity.Player +import java.io.File + +object ModeService { + + lateinit var config: ModeConfig + private set + + val activeModes = mutableMapOf() + private val activeModeData = mutableMapOf() + + + fun initialize() { + loadConfig() + ModeItemManager.registerItems() + } + + + private fun loadConfig(): ModeConfig { + val configFile = File(SporeCore.instance.dataFolder, "modes.yml").toPath() + return try { + config = YamlConfigurations.update(configFile, ModeConfig::class.java) + Logger.info("Loaded modes.yml successfully.") + config + } catch (ex: ConfigurationException) { + Logger.error("Invalid modes.yml, using defaults!") + ex.printStackTrace() + config = ModeConfig() + config + } + } + + fun enableModeOnJoin(player: Player, mode: Mode) { + if (activeModes.containsKey(player)) return + + val invData = if (mode.clearInv) { + InventoryManager.addPlayerInventory(player, "Staffmode join") + } else null + + if (mode.clearInv) { + InventoryManager.clearPlayerInventory(player) + } + + activeModes[player] = mode + + applyModeSettings(player, mode.copy(clearInv = false)) + } + + + fun setMode(player: Player, enabled: Boolean, id: String? = null) { + if (enabled) { + val current = activeModes[player]!! + removeModeSettings(player, current) + activeModes.remove(player) + activeModeData.remove(player) + } else { + val selectedMode = if (id != null) getModeById(id) ?: return else getHighestMode(player) + ?: return + activeModes[player] = selectedMode + applyModeSettings(player, selectedMode) +// Bukkit.broadcastMessage("${ChatColor.YELLOW}${player.name} left the game") +// if (SporeCore.instance.coreConfig.discord.chat.isNotEmpty()) { +// val embed = Webhook.Embed() +// .setColor(0xFF0000) +// .setDescription("**${player.name} left the server**") +// +// val webhook = Webhook(SporeCore.instance.coreConfig.discord.chat) +// .setProfileURL(DiscordService.getAvatarURL(player.uuid())) +// .setUsername(player.name) +// .addEmbed(embed) +// +// try { +// webhook.send() +// } catch (ex: Exception) { +// throw LoggedException( +// userMessage = "Failed to send message to Discord.", +// internalMessage = "Failed to send message to Discord", +// channel = LoggedException.Channel.GENERAL, +// developerOnly = false, +// cause = ex +// ).also { it.log() } +// } +// } + } + } + + fun isInStaffInventory(player: Player): Boolean { + val data = activeModeData[player] ?: return false + return data.inventoryId != null + } + + fun forceRestoreAllInventoriesOnShutdown() { + activeModeData.forEach { (player, data) -> + if (data.inventoryId != null) { + InventoryManager.getInventory(data.inventoryId)?.let { + InventoryManager.restoreInventory(player, it) + } + } + } + activeModes.clear() + activeModeData.clear() + } + + + fun getModes(): Collection = config.modes.values + + fun getModeById(id: String): Mode? = + config.modes[id.lowercase()] ?: config.modes.values.firstOrNull { it.id.equals(id, true) } + + fun getAvailableModes(player: Player): List = + config.modes.values.filter { player.hasPermission(it.permission) } + + fun getHighestMode(player: Player): Mode? = + getAvailableModes(player).maxByOrNull { it.weight } + + fun getPlayerMode(player: Player): Mode? = activeModes[player] + fun getPlayerModeData(player: Player): ModeData? = activeModeData[player] + fun isInMode(player: Player) = activeModes.containsKey(player) + + + fun toggleMode(player: Player, id: String? = null): Mode? { + val selectedMode = if (id != null) getModeById(id) ?: return null else getHighestMode(player) + ?: return null + + val current = activeModes[player] + + if (current != null && current.id.equals(selectedMode.id, true)) { + removeModeSettings(player, current) + activeModes.remove(player) + activeModeData.remove(player) + return null + } + + if (current != null && current != selectedMode) { + removeModeSettings(player, current) + activeModes.remove(player) + activeModeData.remove(player) + } + + activeModes[player] = selectedMode + applyModeSettings(player, selectedMode) + + return selectedMode + } + + + private fun removeModeSettings(player: Player, mode: Mode) { + try { + mode.disableCommands?.forEach { cmd -> + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd.replace("%player%", player.name)) + } + val data = activeModeData[player] + + if (mode.clearInv && data?.inventoryId != null) { + InventoryManager.getInventory(data.inventoryId)?.let { inv -> + InventoryManager.restoreInventory(player, inv) + } + } + + if (mode.vanish) VanishService.unVanish(player.uniqueId) + + data?.let { + player.gameMode = it.previousGamemode + player.allowFlight = it.previousFlight + // Always set this to false!! + player.isInvulnerable = false + if (mode.tpBack) { + it.previousLocation?.let { loc -> player.teleport(loc) } + } + } + + activeModeData.remove(player) + + } catch (ex: Exception) { + Logger.error("Error removing mode for ${player.name}: ${ex.message}") + ex.printStackTrace() + } + } + + fun disableAll() { + Bukkit.getOnlinePlayers().forEach { player -> + if (isInMode(player)) { + setMode(player, false) + } + } + } + + fun applyModeSettings(player: Player, mode: Mode) { + try { + val previousGamemode = player.gameMode + val previousLocation = player.location + val previousFlight = player.allowFlight + val previousInvulnerable = player.isInvulnerable + + var inventoryId: String? = null + + if (mode.clearInv && !activeModeData.containsKey(player)) { + val invData = InventoryManager.addPlayerInventory(player, "${mode.id} mode enabled") + InventoryManager.clearPlayerInventory(player) + inventoryId = invData.id + } + + + + + mode.items?.forEach { (slot, itemId) -> + + if (ModeItemManager.getItem(itemId) == null) { + Logger.error("Failed to give item ${itemId}: Item does not exist!") + return + } + + ModeItemManager.getItem(itemId)?.let { modeItem -> + player.inventory.setItem(slot, modeItem.getItemStack()) + } + } + + val gamemode = GameMode.valueOf(mode.gamemode.uppercase()) + if (gamemode == null) { + Logger.error("Failed to apply gamemode!") + } else { + player.gameMode = gamemode + } + player.isInvulnerable = mode.invulnerable + player.allowFlight = mode.flight + player.isFlying = mode.flight + player.foodLevel = 20 + player.saturation = 20f + + mode.enableCommands?.forEach { cmd -> + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd.replace("%player%", player.name)) + } + + if (mode.vanish) VanishService.vanish(player.uniqueId) + + activeModeData[player] = ModeData( + mode = mode, + inventoryId = inventoryId, + previousGamemode = previousGamemode, + previousLocation = previousLocation, + previousFlight = previousFlight, + previousInvulnerable = previousInvulnerable + ) + + } catch (ex: Exception) { + Logger.error("Error applying mode for ${player.name}: ${ex.message}") + ex.printStackTrace() + } + } + + fun applyModeSettingsNonDestructive(player: Player, mode: Mode) { + val previousGamemode = player.gameMode + val previousLocation = player.location + val previousFlight = player.allowFlight + val previousInvulnerable = player.isInvulnerable + + mode.items?.forEach { (slot, itemId) -> + ModeItemManager.getItem(itemId)?.let { + player.inventory.setItem(slot, it.getItemStack()) + } + } + + player.gameMode = GameMode.valueOf(mode.gamemode.uppercase()) + player.isInvulnerable = mode.invulnerable + player.allowFlight = mode.flight + player.isFlying = mode.flight + player.foodLevel = 20 + player.saturation = 20f + + mode.enableCommands?.forEach { cmd -> + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd.replace("%player%", player.name)) + } + + if (mode.vanish) VanishService.vanish(player.uniqueId) + + activeModeData[player] = ModeData( + mode = mode, + inventoryId = null, + previousGamemode = previousGamemode, + previousLocation = previousLocation, + previousFlight = previousFlight, + previousInvulnerable = previousInvulnerable + ) + } + + + fun enableModeSafely(player: Player, mode: Mode) { + if (activeModes.containsKey(player)) return + if (activeModeData.containsKey(player)) return + + activeModes[player] = mode + applyModeSettingsNonDestructive(player, mode) + } + + +} From b717fd42d6482b4a61e151c02fd613ac34ff2972 Mon Sep 17 00:00:00 2001 From: xwinterkitty <141590124+snowycatdev@users.noreply.github.com> Date: Tue, 10 Mar 2026 10:10:31 -1000 Subject: [PATCH 02/10] feat: Added the WorldEdit wand to Staff Mode --- .../features/mode/item/ModeItemManager.kt | 8 ++--- .../features/mode/item/impl/WorldEditItem.kt | 31 +++++++++++++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 src/main/kotlin/me/clearedSpore/sporeCore/features/mode/item/impl/WorldEditItem.kt diff --git a/src/main/kotlin/me/clearedSpore/sporeCore/features/mode/item/ModeItemManager.kt b/src/main/kotlin/me/clearedSpore/sporeCore/features/mode/item/ModeItemManager.kt index 1d4ef9e..d25f764 100644 --- a/src/main/kotlin/me/clearedSpore/sporeCore/features/mode/item/ModeItemManager.kt +++ b/src/main/kotlin/me/clearedSpore/sporeCore/features/mode/item/ModeItemManager.kt @@ -1,12 +1,7 @@ package me.clearedSpore.sporeCore.features.mode.item import me.clearedSpore.sporeCore.SporeCore -import me.clearedSpore.sporeCore.features.mode.item.impl.InvseeItem -import me.clearedSpore.sporeCore.features.mode.item.impl.CompassItem -import me.clearedSpore.sporeCore.features.mode.item.impl.FreezeItem -import me.clearedSpore.sporeCore.features.mode.item.impl.HistoryItem -import me.clearedSpore.sporeCore.features.mode.item.impl.PunishSwordItem -import me.clearedSpore.sporeCore.features.mode.item.impl.SpeedItem +import me.clearedSpore.sporeCore.features.mode.item.impl.* import me.clearedSpore.sporeCore.features.mode.item.`object`.ModeItem import org.bukkit.Bukkit @@ -21,6 +16,7 @@ object ModeItemManager { register(HistoryItem()) register(InvseeItem()) register(CompassItem()) + register(WorldEditItem()) } fun register(item: ModeItem) { diff --git a/src/main/kotlin/me/clearedSpore/sporeCore/features/mode/item/impl/WorldEditItem.kt b/src/main/kotlin/me/clearedSpore/sporeCore/features/mode/item/impl/WorldEditItem.kt new file mode 100644 index 0000000..a83a77e --- /dev/null +++ b/src/main/kotlin/me/clearedSpore/sporeCore/features/mode/item/impl/WorldEditItem.kt @@ -0,0 +1,31 @@ +package me.clearedSpore.sporeCore.features.mode.item.impl + +import me.clearedSpore.sporeAPI.util.CC.blue +import me.clearedSpore.sporeAPI.util.CC.gray +import me.clearedSpore.sporeAPI.util.Logger +import me.clearedSpore.sporeCore.features.mode.item.`object`.ModeItem +import me.clearedSpore.sporeCore.util.ItemBuilder +import org.bukkit.Bukkit +import org.bukkit.Material +import org.bukkit.event.Listener +import org.bukkit.inventory.ItemStack + + +class WorldEditItem : ModeItem("worldedit"), Listener { + override fun getItemStack(): ItemStack { + if (Bukkit.getPluginManager().isPluginEnabled("WorldEdit") || Bukkit.getPluginManager() + .isPluginEnabled("FastAsyncWorldEdit") + ) { + val item = ItemBuilder(Material.WOODEN_AXE) + .addNBTTag("worldedit_item", id) + .setName("WorldEdit Wand".blue()) + .addLoreLine("Left Click to set the first position".gray()) + .addLoreLine("Right Click to set the second position".gray()) + .setGlow(true) + .build() + return item + } + Logger.info("WorldEdit is not installed on this server. The 'worldedit' item will not be given.") + return ItemStack.empty() + } +} \ No newline at end of file From 2aed994d07c8ff598707503e4a3d8a0138b833fc Mon Sep 17 00:00:00 2001 From: xwinterkitty <141590124+snowycatdev@users.noreply.github.com> Date: Tue, 10 Mar 2026 10:11:13 -1000 Subject: [PATCH 03/10] Revert "Add files via upload" This reverts commit 661f96774b3bb859662b2cf6d5e37b3329c2284c. --- ModeService.kt | 315 ------------------------------------------------- 1 file changed, 315 deletions(-) delete mode 100644 ModeService.kt diff --git a/ModeService.kt b/ModeService.kt deleted file mode 100644 index 7e44005..0000000 --- a/ModeService.kt +++ /dev/null @@ -1,315 +0,0 @@ -package me.clearedSpore.sporeCore.features.mode - -import de.exlll.configlib.ConfigurationException -import de.exlll.configlib.YamlConfigurations -import me.clearedSpore.sporeAPI.exception.LoggedException -import me.clearedSpore.sporeAPI.util.Logger -import me.clearedSpore.sporeAPI.util.Webhook -import me.clearedSpore.sporeCore.SporeCore -import me.clearedSpore.sporeCore.extension.PlayerExtension.uuid -import me.clearedSpore.sporeCore.features.discord.DiscordService -import me.clearedSpore.sporeCore.features.mode.config.ModeConfig -import me.clearedSpore.sporeCore.features.mode.item.ModeItemManager -import me.clearedSpore.sporeCore.features.mode.`object`.Mode -import me.clearedSpore.sporeCore.features.mode.`object`.ModeData -import me.clearedSpore.sporeCore.features.vanish.VanishService -import me.clearedSpore.sporeCore.inventory.InventoryManager -import org.bukkit.Bukkit -import org.bukkit.ChatColor -import org.bukkit.GameMode -import org.bukkit.entity.Player -import java.io.File - -object ModeService { - - lateinit var config: ModeConfig - private set - - val activeModes = mutableMapOf() - private val activeModeData = mutableMapOf() - - - fun initialize() { - loadConfig() - ModeItemManager.registerItems() - } - - - private fun loadConfig(): ModeConfig { - val configFile = File(SporeCore.instance.dataFolder, "modes.yml").toPath() - return try { - config = YamlConfigurations.update(configFile, ModeConfig::class.java) - Logger.info("Loaded modes.yml successfully.") - config - } catch (ex: ConfigurationException) { - Logger.error("Invalid modes.yml, using defaults!") - ex.printStackTrace() - config = ModeConfig() - config - } - } - - fun enableModeOnJoin(player: Player, mode: Mode) { - if (activeModes.containsKey(player)) return - - val invData = if (mode.clearInv) { - InventoryManager.addPlayerInventory(player, "Staffmode join") - } else null - - if (mode.clearInv) { - InventoryManager.clearPlayerInventory(player) - } - - activeModes[player] = mode - - applyModeSettings(player, mode.copy(clearInv = false)) - } - - - fun setMode(player: Player, enabled: Boolean, id: String? = null) { - if (enabled) { - val current = activeModes[player]!! - removeModeSettings(player, current) - activeModes.remove(player) - activeModeData.remove(player) - } else { - val selectedMode = if (id != null) getModeById(id) ?: return else getHighestMode(player) - ?: return - activeModes[player] = selectedMode - applyModeSettings(player, selectedMode) -// Bukkit.broadcastMessage("${ChatColor.YELLOW}${player.name} left the game") -// if (SporeCore.instance.coreConfig.discord.chat.isNotEmpty()) { -// val embed = Webhook.Embed() -// .setColor(0xFF0000) -// .setDescription("**${player.name} left the server**") -// -// val webhook = Webhook(SporeCore.instance.coreConfig.discord.chat) -// .setProfileURL(DiscordService.getAvatarURL(player.uuid())) -// .setUsername(player.name) -// .addEmbed(embed) -// -// try { -// webhook.send() -// } catch (ex: Exception) { -// throw LoggedException( -// userMessage = "Failed to send message to Discord.", -// internalMessage = "Failed to send message to Discord", -// channel = LoggedException.Channel.GENERAL, -// developerOnly = false, -// cause = ex -// ).also { it.log() } -// } -// } - } - } - - fun isInStaffInventory(player: Player): Boolean { - val data = activeModeData[player] ?: return false - return data.inventoryId != null - } - - fun forceRestoreAllInventoriesOnShutdown() { - activeModeData.forEach { (player, data) -> - if (data.inventoryId != null) { - InventoryManager.getInventory(data.inventoryId)?.let { - InventoryManager.restoreInventory(player, it) - } - } - } - activeModes.clear() - activeModeData.clear() - } - - - fun getModes(): Collection = config.modes.values - - fun getModeById(id: String): Mode? = - config.modes[id.lowercase()] ?: config.modes.values.firstOrNull { it.id.equals(id, true) } - - fun getAvailableModes(player: Player): List = - config.modes.values.filter { player.hasPermission(it.permission) } - - fun getHighestMode(player: Player): Mode? = - getAvailableModes(player).maxByOrNull { it.weight } - - fun getPlayerMode(player: Player): Mode? = activeModes[player] - fun getPlayerModeData(player: Player): ModeData? = activeModeData[player] - fun isInMode(player: Player) = activeModes.containsKey(player) - - - fun toggleMode(player: Player, id: String? = null): Mode? { - val selectedMode = if (id != null) getModeById(id) ?: return null else getHighestMode(player) - ?: return null - - val current = activeModes[player] - - if (current != null && current.id.equals(selectedMode.id, true)) { - removeModeSettings(player, current) - activeModes.remove(player) - activeModeData.remove(player) - return null - } - - if (current != null && current != selectedMode) { - removeModeSettings(player, current) - activeModes.remove(player) - activeModeData.remove(player) - } - - activeModes[player] = selectedMode - applyModeSettings(player, selectedMode) - - return selectedMode - } - - - private fun removeModeSettings(player: Player, mode: Mode) { - try { - mode.disableCommands?.forEach { cmd -> - Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd.replace("%player%", player.name)) - } - val data = activeModeData[player] - - if (mode.clearInv && data?.inventoryId != null) { - InventoryManager.getInventory(data.inventoryId)?.let { inv -> - InventoryManager.restoreInventory(player, inv) - } - } - - if (mode.vanish) VanishService.unVanish(player.uniqueId) - - data?.let { - player.gameMode = it.previousGamemode - player.allowFlight = it.previousFlight - // Always set this to false!! - player.isInvulnerable = false - if (mode.tpBack) { - it.previousLocation?.let { loc -> player.teleport(loc) } - } - } - - activeModeData.remove(player) - - } catch (ex: Exception) { - Logger.error("Error removing mode for ${player.name}: ${ex.message}") - ex.printStackTrace() - } - } - - fun disableAll() { - Bukkit.getOnlinePlayers().forEach { player -> - if (isInMode(player)) { - setMode(player, false) - } - } - } - - fun applyModeSettings(player: Player, mode: Mode) { - try { - val previousGamemode = player.gameMode - val previousLocation = player.location - val previousFlight = player.allowFlight - val previousInvulnerable = player.isInvulnerable - - var inventoryId: String? = null - - if (mode.clearInv && !activeModeData.containsKey(player)) { - val invData = InventoryManager.addPlayerInventory(player, "${mode.id} mode enabled") - InventoryManager.clearPlayerInventory(player) - inventoryId = invData.id - } - - - - - mode.items?.forEach { (slot, itemId) -> - - if (ModeItemManager.getItem(itemId) == null) { - Logger.error("Failed to give item ${itemId}: Item does not exist!") - return - } - - ModeItemManager.getItem(itemId)?.let { modeItem -> - player.inventory.setItem(slot, modeItem.getItemStack()) - } - } - - val gamemode = GameMode.valueOf(mode.gamemode.uppercase()) - if (gamemode == null) { - Logger.error("Failed to apply gamemode!") - } else { - player.gameMode = gamemode - } - player.isInvulnerable = mode.invulnerable - player.allowFlight = mode.flight - player.isFlying = mode.flight - player.foodLevel = 20 - player.saturation = 20f - - mode.enableCommands?.forEach { cmd -> - Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd.replace("%player%", player.name)) - } - - if (mode.vanish) VanishService.vanish(player.uniqueId) - - activeModeData[player] = ModeData( - mode = mode, - inventoryId = inventoryId, - previousGamemode = previousGamemode, - previousLocation = previousLocation, - previousFlight = previousFlight, - previousInvulnerable = previousInvulnerable - ) - - } catch (ex: Exception) { - Logger.error("Error applying mode for ${player.name}: ${ex.message}") - ex.printStackTrace() - } - } - - fun applyModeSettingsNonDestructive(player: Player, mode: Mode) { - val previousGamemode = player.gameMode - val previousLocation = player.location - val previousFlight = player.allowFlight - val previousInvulnerable = player.isInvulnerable - - mode.items?.forEach { (slot, itemId) -> - ModeItemManager.getItem(itemId)?.let { - player.inventory.setItem(slot, it.getItemStack()) - } - } - - player.gameMode = GameMode.valueOf(mode.gamemode.uppercase()) - player.isInvulnerable = mode.invulnerable - player.allowFlight = mode.flight - player.isFlying = mode.flight - player.foodLevel = 20 - player.saturation = 20f - - mode.enableCommands?.forEach { cmd -> - Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd.replace("%player%", player.name)) - } - - if (mode.vanish) VanishService.vanish(player.uniqueId) - - activeModeData[player] = ModeData( - mode = mode, - inventoryId = null, - previousGamemode = previousGamemode, - previousLocation = previousLocation, - previousFlight = previousFlight, - previousInvulnerable = previousInvulnerable - ) - } - - - fun enableModeSafely(player: Player, mode: Mode) { - if (activeModes.containsKey(player)) return - if (activeModeData.containsKey(player)) return - - activeModes[player] = mode - applyModeSettingsNonDestructive(player, mode) - } - - -} From 03be1d7cd5f1421c0ee64f44ebd935d8608b2a2f Mon Sep 17 00:00:00 2001 From: xwinterkitty <141590124+snowycatdev@users.noreply.github.com> Date: Tue, 10 Mar 2026 10:16:51 -1000 Subject: [PATCH 04/10] fix: Added a event handler for when players in staff mode attempt to shoot a bow --- .../sporeCore/features/mode/listener/ModeListener.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/kotlin/me/clearedSpore/sporeCore/features/mode/listener/ModeListener.kt b/src/main/kotlin/me/clearedSpore/sporeCore/features/mode/listener/ModeListener.kt index b24fa0b..7b7bb07 100644 --- a/src/main/kotlin/me/clearedSpore/sporeCore/features/mode/listener/ModeListener.kt +++ b/src/main/kotlin/me/clearedSpore/sporeCore/features/mode/listener/ModeListener.kt @@ -111,6 +111,14 @@ class ModeListener(private val modeProvider: (Player) -> Mode?) : Listener { if (!mode.inventory) event.isCancelled = true } + @EventHandler + fun onBowPrepare(event: EntityShootBowEvent) { + val player = event.entity as? Player ?: return + val mode = modeProvider(player) ?: return + if (!mode.pvp) event.isCancelled = true + + } + @EventHandler fun onSilentChest(event: PlayerInteractEvent) { val player = event.player From 073f4a0d9c31505c2dd0aba04a8b32c25f663893 Mon Sep 17 00:00:00 2001 From: xwinterkitty <141590124+snowycatdev@users.noreply.github.com> Date: Tue, 10 Mar 2026 10:17:26 -1000 Subject: [PATCH 05/10] fix: Fixed being able to interact with everything when in staffmode and if it's disallowed. --- .../sporeCore/features/mode/listener/ModeListener.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/kotlin/me/clearedSpore/sporeCore/features/mode/listener/ModeListener.kt b/src/main/kotlin/me/clearedSpore/sporeCore/features/mode/listener/ModeListener.kt index 7b7bb07..ab856d6 100644 --- a/src/main/kotlin/me/clearedSpore/sporeCore/features/mode/listener/ModeListener.kt +++ b/src/main/kotlin/me/clearedSpore/sporeCore/features/mode/listener/ModeListener.kt @@ -158,5 +158,6 @@ class ModeListener(private val modeProvider: (Player) -> Mode?) : Listener { } }, 0L, 20L) } + event.isCancelled = true } } From 9be38fb8852cb83db5f669a1e4dbf0f6996473f4 Mon Sep 17 00:00:00 2001 From: xwinterkitty <141590124+snowycatdev@users.noreply.github.com> Date: Tue, 10 Mar 2026 10:18:08 -1000 Subject: [PATCH 06/10] chore: Made some changes to the reboot messages and titles --- .../sporeCore/features/reboot/RebootService.kt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/me/clearedSpore/sporeCore/features/reboot/RebootService.kt b/src/main/kotlin/me/clearedSpore/sporeCore/features/reboot/RebootService.kt index 81b60ac..cc7c92e 100644 --- a/src/main/kotlin/me/clearedSpore/sporeCore/features/reboot/RebootService.kt +++ b/src/main/kotlin/me/clearedSpore/sporeCore/features/reboot/RebootService.kt @@ -68,15 +68,17 @@ object RebootService { cancelled = true rebootTask?.cancel() rebootTask = null + Bukkit.broadcastMessage("§m-------------------------------------") Bukkit.broadcastMessage("") Bukkit.broadcastMessage("Reboot has been cancelled.".red()) Bukkit.broadcastMessage("") + Bukkit.broadcastMessage("§m-------------------------------------") } private fun sendRebootMessage(timeLeft: Long, isCountdown: Boolean = false) { val formatted = TimeUtil.formatDuration(timeLeft) - val title = "§lReboot!!".red() - val subtitle = "Rebooting in §f$formatted".blue() + val title = "§lServer Reboot".red() + val subtitle = "The server is rebooting in §f$formatted".blue() Bukkit.getOnlinePlayers().forEach { if (isCountdown) { @@ -87,9 +89,11 @@ object RebootService { it.playSound(it, Sound.ENTITY_PLAYER_LEVELUP, 1.0f, 1.0f) } + Bukkit.broadcastMessage("§m-------------------------------------") Bukkit.broadcastMessage("") - Bukkit.broadcastMessage("§lReboot!!".red()) - Bukkit.broadcastMessage("Rebooting in §f$formatted".blue()) + Bukkit.broadcastMessage("§lServer Reboot".red()) + Bukkit.broadcastMessage("The server is rebooting in §f$formatted".blue()) Bukkit.broadcastMessage("") + Bukkit.broadcastMessage("§m-------------------------------------") } } \ No newline at end of file From cf4113146708c9c079048399a5f4ec98b24193b4 Mon Sep 17 00:00:00 2001 From: xwinterkitty <141590124+snowycatdev@users.noreply.github.com> Date: Sun, 15 Mar 2026 02:25:58 -1000 Subject: [PATCH 07/10] fix: fixed a bug where you would not be unvanished if it was enabled before modmode --- .../kotlin/me/clearedSpore/sporeCore/user/UserListener.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/me/clearedSpore/sporeCore/user/UserListener.kt b/src/main/kotlin/me/clearedSpore/sporeCore/user/UserListener.kt index de488bb..c240a5a 100644 --- a/src/main/kotlin/me/clearedSpore/sporeCore/user/UserListener.kt +++ b/src/main/kotlin/me/clearedSpore/sporeCore/user/UserListener.kt @@ -307,7 +307,7 @@ class UserListener : Listener { } - if (config.discord.chat.isNotEmpty() && !autoStaff && !VanishService.isVanished(player.uniqueId)) { + if (config.discord.chat.isNotEmpty() && !ModeService.isInMode(player) && !VanishService.isVanished(player.uniqueId)) { val embed = Webhook.Embed() .setColor(0x00FF00) .setDescription("**${player.name} joined the server**") @@ -352,6 +352,8 @@ class UserListener : Listener { event.quitMessage(null) wasVanished = true ModeService.toggleMode(player) + VanishService.vanishedPlayers.remove(player.uniqueId) + player.isSleepingIgnored = false } From f1e6227e3d55939581ef63f491320af5aaa794ef Mon Sep 17 00:00:00 2001 From: xwinterkitty <141590124+snowycatdev@users.noreply.github.com> Date: Sun, 15 Mar 2026 02:33:55 -1000 Subject: [PATCH 08/10] fix: made it so your sleeping status is ignored when in vanish --- .../me/clearedSpore/sporeCore/features/vanish/VanishService.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/kotlin/me/clearedSpore/sporeCore/features/vanish/VanishService.kt b/src/main/kotlin/me/clearedSpore/sporeCore/features/vanish/VanishService.kt index e890d12..c68ef6e 100644 --- a/src/main/kotlin/me/clearedSpore/sporeCore/features/vanish/VanishService.kt +++ b/src/main/kotlin/me/clearedSpore/sporeCore/features/vanish/VanishService.kt @@ -24,6 +24,7 @@ object VanishService { val wasInMode = ModeService.isInMode(userPlayer) vanishedPlayers.add(uuid) + userPlayer.isSleepingIgnored = true val config = SporeCore.instance.coreConfig if (!wasInMode && config.joinLeaveMessages.vanish && config.joinLeaveMessages.leave.isNotEmpty()) { Bukkit.broadcastMessage( @@ -72,6 +73,7 @@ object VanishService { } vanishedPlayers.remove(uuid) + userPlayer.isSleepingIgnored = false val config = SporeCore.instance.coreConfig if (!wasInMode && config.joinLeaveMessages.vanish && config.joinLeaveMessages.join.isNotEmpty()) { Bukkit.broadcastMessage( From 0dac4277106b3992c4146a5a308f932bb3fcbd67 Mon Sep 17 00:00:00 2001 From: xwinterkitty <141590124+snowycatdev@users.noreply.github.com> Date: Sun, 15 Mar 2026 02:40:20 -1000 Subject: [PATCH 09/10] fix: changed from 'join' to 'leave' when getting joinLeaveMessages config --- src/main/kotlin/me/clearedSpore/sporeCore/user/UserListener.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/me/clearedSpore/sporeCore/user/UserListener.kt b/src/main/kotlin/me/clearedSpore/sporeCore/user/UserListener.kt index c240a5a..4274a7e 100644 --- a/src/main/kotlin/me/clearedSpore/sporeCore/user/UserListener.kt +++ b/src/main/kotlin/me/clearedSpore/sporeCore/user/UserListener.kt @@ -383,7 +383,7 @@ class UserListener : Listener { event.quitMessage = null } else { if (config.joinLeaveMessages.leave.isNotBlank()) { - event.quitMessage = config.joinLeaveMessages.join + event.quitMessage = config.joinLeaveMessages.leave .translate() .parsePlaceholders(player) } From 64ce46111ec10432bf2d4543190ebcfa29ba5ef4 Mon Sep 17 00:00:00 2001 From: xwinterkitty <141590124+snowycatdev@users.noreply.github.com> Date: Sun, 15 Mar 2026 02:40:41 -1000 Subject: [PATCH 10/10] Update ModeListener.kt --- .../sporeCore/features/mode/listener/ModeListener.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/kotlin/me/clearedSpore/sporeCore/features/mode/listener/ModeListener.kt b/src/main/kotlin/me/clearedSpore/sporeCore/features/mode/listener/ModeListener.kt index ab856d6..ba74e5e 100644 --- a/src/main/kotlin/me/clearedSpore/sporeCore/features/mode/listener/ModeListener.kt +++ b/src/main/kotlin/me/clearedSpore/sporeCore/features/mode/listener/ModeListener.kt @@ -16,6 +16,7 @@ import org.bukkit.event.block.BlockBreakEvent import org.bukkit.event.block.BlockPlaceEvent import org.bukkit.event.entity.EntityDamageByEntityEvent import org.bukkit.event.entity.EntityPickupItemEvent +import org.bukkit.event.entity.EntityShootBowEvent import org.bukkit.event.entity.FoodLevelChangeEvent import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.player.*