From 9835d793effcf47316b447c2d5159bd074aa1b38 Mon Sep 17 00:00:00 2001 From: Sven Date: Sat, 19 Sep 2026 17:05:33 +0200 Subject: [PATCH 1/4] Add tests for command permission checks --- .../net/trueog/diamondbankog/DiamondBankOG.kt | 44 +++++---- .../diamondbankog/balance/command/Balance.kt | 15 ++- .../balance/command/Balancetop.kt | 15 ++- .../balance/command/SetBankBalance.kt | 15 ++- .../diamondbankog/commands/BalanceTest.kt | 98 +++++++++++++++++++ .../diamondbankog/commands/BalancetopTest.kt | 98 +++++++++++++++++++ .../{ => commands}/CompressTest.kt | 3 +- .../{ => commands}/DepositTest.kt | 3 +- .../diamondbankog/{ => commands}/PayTest.kt | 3 +- .../commands/SetBankBalanceTest.kt | 98 +++++++++++++++++++ .../{ => commands}/WithdrawTest.kt | 3 +- 11 files changed, 356 insertions(+), 39 deletions(-) create mode 100644 src/test/kotlin/net/trueog/diamondbankog/commands/BalanceTest.kt create mode 100644 src/test/kotlin/net/trueog/diamondbankog/commands/BalancetopTest.kt rename src/test/kotlin/net/trueog/diamondbankog/{ => commands}/CompressTest.kt (99%) rename src/test/kotlin/net/trueog/diamondbankog/{ => commands}/DepositTest.kt (99%) rename src/test/kotlin/net/trueog/diamondbankog/{ => commands}/PayTest.kt (99%) create mode 100644 src/test/kotlin/net/trueog/diamondbankog/commands/SetBankBalanceTest.kt rename src/test/kotlin/net/trueog/diamondbankog/{ => commands}/WithdrawTest.kt (99%) diff --git a/src/main/kotlin/net/trueog/diamondbankog/DiamondBankOG.kt b/src/main/kotlin/net/trueog/diamondbankog/DiamondBankOG.kt index 9e0eabe..7e11faa 100644 --- a/src/main/kotlin/net/trueog/diamondbankog/DiamondBankOG.kt +++ b/src/main/kotlin/net/trueog/diamondbankog/DiamondBankOG.kt @@ -100,26 +100,7 @@ internal class DiamondBankOG : JavaPlugin() { this.server.pluginManager.registerEvents(Events(), this) - this.getCommand("deposit")?.setExecutor(Deposit()) - this.getCommand("withdraw")?.setExecutor(Withdraw()) - this.getCommand("setbankbalance")?.setExecutor(SetBankBalance()) - this.getCommand("setbankbal")?.setExecutor(SetBankBalance()) - this.getCommand("pay")?.setExecutor(Pay()) - this.getCommand("balancetop")?.setExecutor(Balancetop()) - this.getCommand("baltop")?.setExecutor(Balancetop()) - this.getCommand("balance")?.setExecutor(Balance()) - this.getCommand("bal")?.setExecutor(Balance()) - this.getCommand("compress")?.setExecutor(Compress()) - this.getCommand("autocompress")?.setExecutor(AutoCompress()) - this.getCommand("autodeposit")?.setExecutor(AutoDeposit()) - - this.getCommand("diamondbankreload")?.setExecutor(DiamondBankReload()) - this.getCommand("diamondbankhelp")?.setExecutor(DiamondBankHelp()) - - this.getCommand("enableeconomy")?.setExecutor(EnableEconomy()) - this.getCommand("disableeconomy")?.setExecutor(DisableEconomy()) - - this.getCommand("dbogtoggledebug")?.setExecutor(ToggleDebug()) + setUpCommands() Shard.createCraftingRecipes() @@ -140,6 +121,29 @@ internal class DiamondBankOG : JavaPlugin() { ) } + fun setUpCommands() { + this.getCommand("deposit")?.setExecutor(Deposit()) + this.getCommand("withdraw")?.setExecutor(Withdraw()) + this.getCommand("setbankbalance")?.setExecutor(SetBankBalance()) + this.getCommand("setbankbal")?.setExecutor(SetBankBalance()) + this.getCommand("pay")?.setExecutor(Pay()) + this.getCommand("balancetop")?.setExecutor(Balancetop()) + this.getCommand("baltop")?.setExecutor(Balancetop()) + this.getCommand("balance")?.setExecutor(Balance()) + this.getCommand("bal")?.setExecutor(Balance()) + this.getCommand("compress")?.setExecutor(Compress()) + this.getCommand("autocompress")?.setExecutor(AutoCompress()) + this.getCommand("autodeposit")?.setExecutor(AutoDeposit()) + + this.getCommand("diamondbankreload")?.setExecutor(DiamondBankReload()) + this.getCommand("diamondbankhelp")?.setExecutor(DiamondBankHelp()) + + this.getCommand("enableeconomy")?.setExecutor(EnableEconomy()) + this.getCommand("disableeconomy")?.setExecutor(DisableEconomy()) + + this.getCommand("dbogtoggledebug")?.setExecutor(ToggleDebug()) + } + override fun onDisable() { if (isRedisInitialized()) { redis.shutdown() diff --git a/src/main/kotlin/net/trueog/diamondbankog/balance/command/Balance.kt b/src/main/kotlin/net/trueog/diamondbankog/balance/command/Balance.kt index 34f57dd..c182553 100644 --- a/src/main/kotlin/net/trueog/diamondbankog/balance/command/Balance.kt +++ b/src/main/kotlin/net/trueog/diamondbankog/balance/command/Balance.kt @@ -1,12 +1,12 @@ package net.trueog.diamondbankog.balance.command +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch +import net.kyori.adventure.text.minimessage.MiniMessage import net.trueog.diamondbankog.DiamondBankOG -import net.trueog.diamondbankog.DiamondBankOG.Companion.balanceManager -import net.trueog.diamondbankog.DiamondBankOG.Companion.config import net.trueog.diamondbankog.DiamondBankOG.Companion.economyDisabled -import net.trueog.diamondbankog.DiamondBankOG.Companion.mm -import net.trueog.diamondbankog.DiamondBankOG.Companion.scope +import net.trueog.diamondbankog.balance.BalanceManager +import net.trueog.diamondbankog.config.Config import net.trueog.diamondbankog.transaction.CommonOperations import net.trueog.diamondbankog.util.PlayerPrefix.getPrefix import org.bukkit.command.Command @@ -14,7 +14,12 @@ import org.bukkit.command.CommandExecutor import org.bukkit.command.CommandSender import org.bukkit.entity.Player -internal class Balance : CommandExecutor { +internal class Balance( + val config: Config = DiamondBankOG.config, + val balanceManager: BalanceManager = DiamondBankOG.balanceManager, + val mm: MiniMessage = DiamondBankOG.mm, + val scope: CoroutineScope = DiamondBankOG.scope, +) : CommandExecutor { override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array?): Boolean { scope.launch { if (economyDisabled) { diff --git a/src/main/kotlin/net/trueog/diamondbankog/balance/command/Balancetop.kt b/src/main/kotlin/net/trueog/diamondbankog/balance/command/Balancetop.kt index 7c75524..9477291 100644 --- a/src/main/kotlin/net/trueog/diamondbankog/balance/command/Balancetop.kt +++ b/src/main/kotlin/net/trueog/diamondbankog/balance/command/Balancetop.kt @@ -1,13 +1,13 @@ package net.trueog.diamondbankog.balance.command import kotlin.math.ceil +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch +import net.kyori.adventure.text.minimessage.MiniMessage import net.trueog.diamondbankog.DiamondBankOG -import net.trueog.diamondbankog.DiamondBankOG.Companion.balanceManager -import net.trueog.diamondbankog.DiamondBankOG.Companion.config import net.trueog.diamondbankog.DiamondBankOG.Companion.economyDisabled -import net.trueog.diamondbankog.DiamondBankOG.Companion.mm -import net.trueog.diamondbankog.DiamondBankOG.Companion.scope +import net.trueog.diamondbankog.balance.BalanceManager +import net.trueog.diamondbankog.config.Config import net.trueog.diamondbankog.transaction.CommonOperations import net.trueog.diamondbankog.util.PlayerPrefix.getPrefix import org.bukkit.Bukkit @@ -16,7 +16,12 @@ import org.bukkit.command.Command import org.bukkit.command.CommandExecutor import org.bukkit.command.CommandSender -internal class Balancetop : CommandExecutor { +internal class Balancetop( + val config: Config = DiamondBankOG.config, + val balanceManager: BalanceManager = DiamondBankOG.balanceManager, + val mm: MiniMessage = DiamondBankOG.mm, + val scope: CoroutineScope = DiamondBankOG.scope, +) : CommandExecutor { override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array?): Boolean { scope.launch { if (economyDisabled) { diff --git a/src/main/kotlin/net/trueog/diamondbankog/balance/command/SetBankBalance.kt b/src/main/kotlin/net/trueog/diamondbankog/balance/command/SetBankBalance.kt index 671cbdf..74bc394 100644 --- a/src/main/kotlin/net/trueog/diamondbankog/balance/command/SetBankBalance.kt +++ b/src/main/kotlin/net/trueog/diamondbankog/balance/command/SetBankBalance.kt @@ -1,13 +1,13 @@ package net.trueog.diamondbankog.balance.command +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch +import net.kyori.adventure.text.minimessage.MiniMessage import net.trueog.diamondbankog.DiamondBankOG -import net.trueog.diamondbankog.DiamondBankOG.Companion.balanceManager -import net.trueog.diamondbankog.DiamondBankOG.Companion.config import net.trueog.diamondbankog.DiamondBankOG.Companion.economyDisabled -import net.trueog.diamondbankog.DiamondBankOG.Companion.mm -import net.trueog.diamondbankog.DiamondBankOG.Companion.scope +import net.trueog.diamondbankog.balance.BalanceManager import net.trueog.diamondbankog.balance.shard.ShardType +import net.trueog.diamondbankog.config.Config import net.trueog.diamondbankog.transaction.CommonOperations import net.trueog.diamondbankog.util.ErrorHandler.handleError import net.trueog.diamondbankog.util.PlayerPrefix.getPrefix @@ -16,7 +16,12 @@ import org.bukkit.command.CommandExecutor import org.bukkit.command.CommandSender import org.bukkit.entity.Player -internal class SetBankBalance : CommandExecutor { +internal class SetBankBalance( + val config: Config = DiamondBankOG.config, + val balanceManager: BalanceManager = DiamondBankOG.balanceManager, + val mm: MiniMessage = DiamondBankOG.mm, + val scope: CoroutineScope = DiamondBankOG.scope, +) : CommandExecutor { override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array?): Boolean { scope.launch { if (economyDisabled) { diff --git a/src/test/kotlin/net/trueog/diamondbankog/commands/BalanceTest.kt b/src/test/kotlin/net/trueog/diamondbankog/commands/BalanceTest.kt new file mode 100644 index 0000000..a30d603 --- /dev/null +++ b/src/test/kotlin/net/trueog/diamondbankog/commands/BalanceTest.kt @@ -0,0 +1,98 @@ +package net.trueog.diamondbankog.commands + +import io.mockk.MockKAnnotations +import io.mockk.Runs +import io.mockk.confirmVerified +import io.mockk.every +import io.mockk.impl.annotations.MockK +import io.mockk.just +import io.mockk.slot +import io.mockk.verify +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.test.runTest +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.minimessage.MiniMessage +import net.trueog.diamondbankog.BukkitMock +import net.trueog.diamondbankog.Constants.playerUuid +import net.trueog.diamondbankog.Utils.waitForCoroutines +import net.trueog.diamondbankog.balance.BalanceManager +import net.trueog.diamondbankog.balance.command.Balance +import net.trueog.diamondbankog.config.Config +import org.bukkit.Bukkit +import org.bukkit.Server +import org.bukkit.command.Command +import org.bukkit.entity.Player +import org.junit.jupiter.api.BeforeAll +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertAll + +class BalanceTest { + @MockK private lateinit var config: Config + + @MockK private lateinit var balanceManager: BalanceManager + + @MockK private lateinit var mm: MiniMessage + + @MockK private lateinit var player: Player + + @MockK private lateinit var command: Command + + val scope = CoroutineScope(Dispatchers.Default + SupervisorJob()) + + @BeforeEach + fun setup() { + MockKAnnotations.init(this) + + every { config.prefix } returns "DiamondBank-OG" + + val inputSlot = slot() + every { mm.deserialize(capture(inputSlot)) } answers { Component.text(inputSlot.captured) } + + every { player.uniqueId } returns playerUuid + every { player.world.name } returns "world" + every { player.hasPermission("diamondbank-og.balance") } returns true + + every { Bukkit.getPlayer("player") } returns player + every { server.getPlayer("player") } returns player + every { Bukkit.getPlayer(playerUuid) } returns player + every { server.getPlayer(playerUuid) } returns player + + every { player.sendMessage(any()) } just Runs + } + + companion object { + lateinit var server: Server + + @JvmStatic + @BeforeAll + fun setupBukkit() { + server = BukkitMock.mockBukkit() + } + } + + @Test + @DisplayName("Balance with no permission should fail") + fun balanceNoPermission() = runTest { + every { player.hasPermission("diamondbank-og.balance") } returns false + + val balance = Balance(config, balanceManager, mm, scope) + balance.onCommand(player, command, "balance", arrayOf()) + waitForCoroutines(scope) + + assertAll( + { verify { player.hasPermission("diamondbank-og.balance") } }, + { + verify { + player.sendMessage( + Component.text("DiamondBank-OG: You do not have permission to use this command.") + ) + } + }, + { confirmVerified(player) }, + ) + } +} diff --git a/src/test/kotlin/net/trueog/diamondbankog/commands/BalancetopTest.kt b/src/test/kotlin/net/trueog/diamondbankog/commands/BalancetopTest.kt new file mode 100644 index 0000000..475b39e --- /dev/null +++ b/src/test/kotlin/net/trueog/diamondbankog/commands/BalancetopTest.kt @@ -0,0 +1,98 @@ +package net.trueog.diamondbankog.commands + +import io.mockk.MockKAnnotations +import io.mockk.Runs +import io.mockk.confirmVerified +import io.mockk.every +import io.mockk.impl.annotations.MockK +import io.mockk.just +import io.mockk.slot +import io.mockk.verify +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.test.runTest +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.minimessage.MiniMessage +import net.trueog.diamondbankog.BukkitMock +import net.trueog.diamondbankog.Constants.playerUuid +import net.trueog.diamondbankog.Utils.waitForCoroutines +import net.trueog.diamondbankog.balance.BalanceManager +import net.trueog.diamondbankog.balance.command.Balancetop +import net.trueog.diamondbankog.config.Config +import org.bukkit.Bukkit +import org.bukkit.Server +import org.bukkit.command.Command +import org.bukkit.entity.Player +import org.junit.jupiter.api.BeforeAll +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertAll + +class BalancetopTest { + @MockK private lateinit var config: Config + + @MockK private lateinit var balanceManager: BalanceManager + + @MockK private lateinit var mm: MiniMessage + + @MockK private lateinit var player: Player + + @MockK private lateinit var command: Command + + val scope = CoroutineScope(Dispatchers.Default + SupervisorJob()) + + @BeforeEach + fun setup() { + MockKAnnotations.init(this) + + every { config.prefix } returns "DiamondBank-OG" + + val inputSlot = slot() + every { mm.deserialize(capture(inputSlot)) } answers { Component.text(inputSlot.captured) } + + every { player.uniqueId } returns playerUuid + every { player.world.name } returns "world" + every { player.hasPermission("diamondbank-og.balance") } returns true + + every { Bukkit.getPlayer("player") } returns player + every { server.getPlayer("player") } returns player + every { Bukkit.getPlayer(playerUuid) } returns player + every { server.getPlayer(playerUuid) } returns player + + every { player.sendMessage(any()) } just Runs + } + + companion object { + lateinit var server: Server + + @JvmStatic + @BeforeAll + fun setupBukkit() { + server = BukkitMock.mockBukkit() + } + } + + @Test + @DisplayName("Balancetop with no permission should fail") + fun balancetopNoPermission() = runTest { + every { player.hasPermission("diamondbank-og.balancetop") } returns false + + val balancetop = Balancetop(config, balanceManager, mm, scope) + balancetop.onCommand(player, command, "balancetop", arrayOf()) + waitForCoroutines(scope) + + assertAll( + { verify { player.hasPermission("diamondbank-og.balancetop") } }, + { + verify { + player.sendMessage( + Component.text("DiamondBank-OG: You do not have permission to use this command.") + ) + } + }, + { confirmVerified(player) }, + ) + } +} diff --git a/src/test/kotlin/net/trueog/diamondbankog/CompressTest.kt b/src/test/kotlin/net/trueog/diamondbankog/commands/CompressTest.kt similarity index 99% rename from src/test/kotlin/net/trueog/diamondbankog/CompressTest.kt rename to src/test/kotlin/net/trueog/diamondbankog/commands/CompressTest.kt index e4da1d6..c7cc3cb 100644 --- a/src/test/kotlin/net/trueog/diamondbankog/CompressTest.kt +++ b/src/test/kotlin/net/trueog/diamondbankog/commands/CompressTest.kt @@ -1,4 +1,4 @@ -package net.trueog.diamondbankog +package net.trueog.diamondbankog.commands import io.mockk.MockKAnnotations import io.mockk.Runs @@ -17,6 +17,7 @@ import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.test.runTest import net.kyori.adventure.text.Component import net.kyori.adventure.text.minimessage.MiniMessage +import net.trueog.diamondbankog.BukkitMock import net.trueog.diamondbankog.Constants.playerUuid import net.trueog.diamondbankog.Utils.mockPlayerInventory import net.trueog.diamondbankog.Utils.waitForCoroutines diff --git a/src/test/kotlin/net/trueog/diamondbankog/DepositTest.kt b/src/test/kotlin/net/trueog/diamondbankog/commands/DepositTest.kt similarity index 99% rename from src/test/kotlin/net/trueog/diamondbankog/DepositTest.kt rename to src/test/kotlin/net/trueog/diamondbankog/commands/DepositTest.kt index 21a3527..fcac061 100644 --- a/src/test/kotlin/net/trueog/diamondbankog/DepositTest.kt +++ b/src/test/kotlin/net/trueog/diamondbankog/commands/DepositTest.kt @@ -1,4 +1,4 @@ -package net.trueog.diamondbankog +package net.trueog.diamondbankog.commands import io.mockk.* import io.mockk.impl.annotations.MockK @@ -11,6 +11,7 @@ import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.test.runTest import net.kyori.adventure.text.Component import net.kyori.adventure.text.minimessage.MiniMessage +import net.trueog.diamondbankog.BukkitMock import net.trueog.diamondbankog.Constants.playerUuid import net.trueog.diamondbankog.Utils.mockPlayerInventory import net.trueog.diamondbankog.Utils.waitForCoroutines diff --git a/src/test/kotlin/net/trueog/diamondbankog/PayTest.kt b/src/test/kotlin/net/trueog/diamondbankog/commands/PayTest.kt similarity index 99% rename from src/test/kotlin/net/trueog/diamondbankog/PayTest.kt rename to src/test/kotlin/net/trueog/diamondbankog/commands/PayTest.kt index f6e27ae..bce5dd3 100644 --- a/src/test/kotlin/net/trueog/diamondbankog/PayTest.kt +++ b/src/test/kotlin/net/trueog/diamondbankog/commands/PayTest.kt @@ -1,4 +1,4 @@ -package net.trueog.diamondbankog +package net.trueog.diamondbankog.commands import io.mockk.* import io.mockk.impl.annotations.MockK @@ -15,6 +15,7 @@ import net.kyori.adventure.text.minimessage.MiniMessage import net.luckperms.api.LuckPerms import net.luckperms.api.model.user.User import net.luckperms.api.node.Node +import net.trueog.diamondbankog.BukkitMock import net.trueog.diamondbankog.Constants.otherPlayerUuid import net.trueog.diamondbankog.Constants.playerUuid import net.trueog.diamondbankog.Utils.mockPlayerInventory diff --git a/src/test/kotlin/net/trueog/diamondbankog/commands/SetBankBalanceTest.kt b/src/test/kotlin/net/trueog/diamondbankog/commands/SetBankBalanceTest.kt new file mode 100644 index 0000000..809e9b0 --- /dev/null +++ b/src/test/kotlin/net/trueog/diamondbankog/commands/SetBankBalanceTest.kt @@ -0,0 +1,98 @@ +package net.trueog.diamondbankog.commands + +import io.mockk.MockKAnnotations +import io.mockk.Runs +import io.mockk.coVerify +import io.mockk.every +import io.mockk.impl.annotations.MockK +import io.mockk.just +import io.mockk.slot +import io.mockk.verify +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.test.runTest +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.minimessage.MiniMessage +import net.trueog.diamondbankog.BukkitMock +import net.trueog.diamondbankog.Constants.playerUuid +import net.trueog.diamondbankog.Utils.waitForCoroutines +import net.trueog.diamondbankog.balance.BalanceManager +import net.trueog.diamondbankog.balance.command.SetBankBalance +import net.trueog.diamondbankog.config.Config +import org.bukkit.Bukkit +import org.bukkit.Server +import org.bukkit.command.Command +import org.bukkit.entity.Player +import org.junit.jupiter.api.BeforeAll +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertAll + +class SetBankBalanceTest { + @MockK private lateinit var config: Config + + @MockK private lateinit var balanceManager: BalanceManager + + @MockK private lateinit var mm: MiniMessage + + @MockK private lateinit var player: Player + + @MockK private lateinit var command: Command + + val scope = CoroutineScope(Dispatchers.Default + SupervisorJob()) + + @BeforeEach + fun setup() { + MockKAnnotations.init(this) + + every { config.prefix } returns "DiamondBank-OG" + + val inputSlot = slot() + every { mm.deserialize(capture(inputSlot)) } answers { Component.text(inputSlot.captured) } + + every { player.uniqueId } returns playerUuid + every { player.world.name } returns "world" + every { player.hasPermission("diamondbank-og.setbankbalance") } returns true + + every { Bukkit.getPlayer("player") } returns player + every { server.getPlayer("player") } returns player + every { Bukkit.getPlayer(playerUuid) } returns player + every { server.getPlayer(playerUuid) } returns player + + every { player.sendMessage(any()) } just Runs + } + + companion object { + lateinit var server: Server + + @JvmStatic + @BeforeAll + fun setupBukkit() { + server = BukkitMock.mockBukkit() + } + } + + @Test + @DisplayName("SetBankBalance with no permission should fail") + fun setBankBalanceNoPermission() = runTest { + every { player.hasPermission("diamondbank-og.setbankbalance") } returns false + + val setBankBalance = SetBankBalance(config, balanceManager, mm, scope) + setBankBalance.onCommand(player, command, "setbankbalance", arrayOf()) + waitForCoroutines(scope) + + assertAll( + { verify { player.hasPermission("diamondbank-og.setbankbalance") } }, + { + verify { + player.sendMessage( + Component.text("DiamondBank-OG: You do not have permission to use this command.") + ) + } + }, + { coVerify(exactly = 0) { balanceManager.setPlayerShards(any(), any(), any()) } }, + ) + } +} diff --git a/src/test/kotlin/net/trueog/diamondbankog/WithdrawTest.kt b/src/test/kotlin/net/trueog/diamondbankog/commands/WithdrawTest.kt similarity index 99% rename from src/test/kotlin/net/trueog/diamondbankog/WithdrawTest.kt rename to src/test/kotlin/net/trueog/diamondbankog/commands/WithdrawTest.kt index 2c601bf..e2abecc 100644 --- a/src/test/kotlin/net/trueog/diamondbankog/WithdrawTest.kt +++ b/src/test/kotlin/net/trueog/diamondbankog/commands/WithdrawTest.kt @@ -1,4 +1,4 @@ -package net.trueog.diamondbankog +package net.trueog.diamondbankog.commands import io.mockk.* import io.mockk.impl.annotations.MockK @@ -11,6 +11,7 @@ import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.test.runTest import net.kyori.adventure.text.Component import net.kyori.adventure.text.minimessage.MiniMessage +import net.trueog.diamondbankog.BukkitMock import net.trueog.diamondbankog.Constants.playerUuid import net.trueog.diamondbankog.Utils.mockPlayerInventory import net.trueog.diamondbankog.Utils.waitForCoroutines -- 2.47.3 From 2e64c211c93553afa5c0fe9e7f61404d0a467c58 Mon Sep 17 00:00:00 2001 From: Sven Date: Sat, 19 Sep 2026 17:19:03 +0200 Subject: [PATCH 2/4] Ignore cancelled events for a few event handlers --- src/main/kotlin/net/trueog/diamondbankog/Events.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/net/trueog/diamondbankog/Events.kt b/src/main/kotlin/net/trueog/diamondbankog/Events.kt index 678399c..1e25b92 100644 --- a/src/main/kotlin/net/trueog/diamondbankog/Events.kt +++ b/src/main/kotlin/net/trueog/diamondbankog/Events.kt @@ -145,7 +145,7 @@ internal class Events : Listener { } } - @EventHandler(priority = EventPriority.HIGHEST) + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) fun onEntityPickupItem(event: EntityPickupItemEvent) { val player = event.entity as? Player ?: return val worldName = player.world.name @@ -197,7 +197,7 @@ internal class Events : Listener { } } - @EventHandler(priority = EventPriority.HIGHEST) + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) fun onPlayerDropItem(event: PlayerDropItemEvent) { val worldName = event.player.world.name if (!vanillaWorlds.contains(worldName)) return @@ -239,7 +239,7 @@ internal class Events : Listener { } } - @EventHandler(priority = EventPriority.HIGHEST) + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) fun onInventoryClickEvent(event: InventoryClickEvent) { val player = event.whoClicked as? Player ?: return val worldName = player.world.name @@ -317,7 +317,7 @@ internal class Events : Listener { } } - @EventHandler(priority = EventPriority.HIGHEST) + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) fun onPlayerInteractEntity(event: PlayerInteractEntityEvent) { val player = event.player val worldName = player.world.name -- 2.47.3 From aba9961d7c7678f339f1634e006883a7f0949245 Mon Sep 17 00:00:00 2001 From: Sven Date: Sat, 19 Sep 2026 17:20:08 +0200 Subject: [PATCH 3/4] Fix currency items disappearing on pick up when inventory is almost full --- src/main/kotlin/net/trueog/diamondbankog/Events.kt | 2 +- .../net/trueog/diamondbankog/autodeposit/AutoDeposit.kt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/net/trueog/diamondbankog/Events.kt b/src/main/kotlin/net/trueog/diamondbankog/Events.kt index 1e25b92..216f161 100644 --- a/src/main/kotlin/net/trueog/diamondbankog/Events.kt +++ b/src/main/kotlin/net/trueog/diamondbankog/Events.kt @@ -178,7 +178,7 @@ internal class Events : Listener { } if (redis.getValue("diamondbankog:${player.uniqueId}:autodeposit") == "true") { - deposit(player, event.item) + deposit(player, event.item, event.remaining) } scope.launch { diff --git a/src/main/kotlin/net/trueog/diamondbankog/autodeposit/AutoDeposit.kt b/src/main/kotlin/net/trueog/diamondbankog/autodeposit/AutoDeposit.kt index 7e14e7f..8238e5d 100644 --- a/src/main/kotlin/net/trueog/diamondbankog/autodeposit/AutoDeposit.kt +++ b/src/main/kotlin/net/trueog/diamondbankog/autodeposit/AutoDeposit.kt @@ -13,7 +13,7 @@ import org.bukkit.entity.Item import org.bukkit.entity.Player internal object AutoDeposit { - fun deposit(player: Player, item: Item) { + fun deposit(player: Player, item: Item, remaining: Int) { val worldName = player.world.name if (worldName != "world" && worldName != "world_nether" && worldName != "world_the_end") { return @@ -24,7 +24,7 @@ internal object AutoDeposit { return } - val itemStack = item.itemStack + val itemStack = item.itemStack.clone().apply { amount += remaining } val shards = if (itemStack.type == Material.DIAMOND_BLOCK) { (itemStack.amount * 9 * 9).toLong() -- 2.47.3 From 35feaf69256d9a3fe03d1a8bff0c6547fed3cb33 Mon Sep 17 00:00:00 2001 From: Sven Date: Sat, 19 Sep 2026 17:20:59 +0200 Subject: [PATCH 4/4] Cancel and join coroutines before shutting down Redis and the BalanceManager --- src/main/kotlin/net/trueog/diamondbankog/DiamondBankOG.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/net/trueog/diamondbankog/DiamondBankOG.kt b/src/main/kotlin/net/trueog/diamondbankog/DiamondBankOG.kt index 7e11faa..6725709 100644 --- a/src/main/kotlin/net/trueog/diamondbankog/DiamondBankOG.kt +++ b/src/main/kotlin/net/trueog/diamondbankog/DiamondBankOG.kt @@ -145,6 +145,10 @@ internal class DiamondBankOG : JavaPlugin() { } override fun onDisable() { + scope.cancel() + + runBlocking { scope.coroutineContext[Job]?.join() } + if (isRedisInitialized()) { redis.shutdown() } @@ -153,10 +157,6 @@ internal class DiamondBankOG : JavaPlugin() { balanceManager.shutdown() } - scope.cancel() - - runBlocking { scope.coroutineContext[Job]?.join() } - transactionLock.removeAllLocks() } } -- 2.47.3