diff --git a/build.gradle.kts b/build.gradle.kts index 1dec210..f2ce0f7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,7 +4,6 @@ plugins { kotlin("jvm") version "2.1.21" // Import kotlin jvm plugin for kotlin/java integration. id("com.diffplug.spotless") version "7.0.4" id("com.gradleup.shadow") version "8.3.6" // Import shadow API. - id("maven-publish") eclipse // Import eclipse plugin for IDE integration. } @@ -42,7 +41,6 @@ configurations.all { exclude(group = "io.projectreactor") } tasks.build { dependsOn(tasks.spotlessApply) dependsOn(tasks.shadowJar) - dependsOn(tasks.publishToMavenLocal) } tasks.jar { archiveClassifier.set("part") } @@ -75,17 +73,6 @@ tasks.withType().configureEach { isReproducibleFileOrder = true } -publishing { - publications { - create("shadow") { - groupId = "net.trueog.diamondbank-og" - artifactId = "diamondbank-og" - version = project.version.toString() - artifact(tasks.shadowJar) - } - } -} - spotless { kotlin { ktfmt().kotlinlangStyle().configure { it.setMaxWidth(120) } } kotlinGradle { diff --git a/src/main/kotlin/net/trueog/diamondbankog/AutoDeposit.kt b/src/main/kotlin/net/trueog/diamondbankog/AutoDeposit.kt index d010408..cba9abf 100644 --- a/src/main/kotlin/net/trueog/diamondbankog/AutoDeposit.kt +++ b/src/main/kotlin/net/trueog/diamondbankog/AutoDeposit.kt @@ -38,8 +38,7 @@ internal object AutoDeposit { DiamondBankOG.scope.launch { DiamondBankOG.transactionLock.withLockSuspend(player.uniqueId) { - val error = DiamondBankOG.postgreSQL.addToPlayerShards(player.uniqueId, shards, ShardType.BANK) - if (error) { + DiamondBankOG.postgreSQL.addToPlayerShards(player.uniqueId, shards, ShardType.BANK).getOrElse { handleError(player.uniqueId, shards, null) player.sendMessage( DiamondBankOG.mm.deserialize( diff --git a/src/main/kotlin/net/trueog/diamondbankog/DiamondBankAPIJava.kt b/src/main/kotlin/net/trueog/diamondbankog/DiamondBankAPIJava.kt index 38d8734..6687a24 100644 --- a/src/main/kotlin/net/trueog/diamondbankog/DiamondBankAPIJava.kt +++ b/src/main/kotlin/net/trueog/diamondbankog/DiamondBankAPIJava.kt @@ -2,8 +2,10 @@ package net.trueog.diamondbankog import java.util.* import java.util.concurrent.CompletableFuture +import kotlin.getOrThrow import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.future.future +import kotlinx.coroutines.runBlocking import net.trueog.diamondbankog.ErrorHandler.handleError import net.trueog.diamondbankog.PostgreSQL.PlayerShards import net.trueog.diamondbankog.PostgreSQL.ShardType @@ -13,32 +15,25 @@ import org.bukkit.Bukkit @OptIn(DelicateCoroutinesApi::class) class DiamondBankAPIJava(private var postgreSQL: PostgreSQL) { /** - * WARNING: blocking, if the player has a transaction lock applied this function will wait until its released + * WARNING: do not run on a thread where blocking is unacceptable WARNING: lock is blocking, if the player has a + * transaction lock applied this function will wait until its released * * @param transactionReason the reason for this transaction for in the transaction log * @param notes any specifics for this transaction that may be nice to know for in the transaction log * @throws DiamondBankException.EconomyDisabledException - * @throws DiamondBankException.OtherException + * @throws DiamondBankException.DatabaseException */ - @Throws(DiamondBankException.EconomyDisabledException::class, DiamondBankException.OtherException::class) + @Throws(DiamondBankException.EconomyDisabledException::class, DiamondBankException.DatabaseException::class) @Suppress("unused") - fun blockingAddToPlayerBankShards( - uuid: UUID, - shards: Int, - transactionReason: String, - notes: String?, - ): CompletableFuture { + fun blockingAddToPlayerBankShards(uuid: UUID, shards: Int, transactionReason: String, notes: String?) { if (DiamondBankOG.economyDisabled) throw DiamondBankException.EconomyDisabledException - return DiamondBankOG.scope.future { + return runBlocking { DiamondBankOG.transactionLock.withLockSuspend(uuid) { - val error = postgreSQL.addToPlayerShards(uuid, shards, ShardType.BANK) - if (error) { - throw DiamondBankException.OtherException + postgreSQL.addToPlayerShards(uuid, shards, ShardType.BANK).getOrElse { + throw DiamondBankException.DatabaseException(it.message ?: "Database exception") } - val transactionLogError = - DiamondBankOG.postgreSQL.insertTransactionLog(uuid, shards, null, transactionReason, notes) - if (transactionLogError) { + DiamondBankOG.postgreSQL.insertTransactionLog(uuid, shards, null, transactionReason, notes).getOrElse { handleError(uuid, shards, null, null, true) } } @@ -46,11 +41,13 @@ class DiamondBankAPIJava(private var postgreSQL: PostgreSQL) { } /** + * WARNING: do not run on a thread where blocking is unacceptable + * * @param transactionReason the reason for this transaction for in the transaction log * @param notes any specifics for this transaction that may be nice to know for in the transaction log * @throws DiamondBankException.EconomyDisabledException * @throws DiamondBankException.TransactionsLockedException - * @throws DiamondBankException.OtherException + * @throws DiamondBankException.DatabaseException */ @Throws( DiamondBankException.EconomyDisabledException::class, @@ -58,69 +55,50 @@ class DiamondBankAPIJava(private var postgreSQL: PostgreSQL) { DiamondBankException.OtherException::class, ) @Suppress("unused") - fun addToPlayerBankShards( - uuid: UUID, - shards: Int, - transactionReason: String, - notes: String?, - ): CompletableFuture { + fun addToPlayerBankShards(uuid: UUID, shards: Int, transactionReason: String, notes: String?) { if (DiamondBankOG.economyDisabled) throw DiamondBankException.EconomyDisabledException - return DiamondBankOG.scope.future { + return runBlocking { when ( val result = DiamondBankOG.transactionLock.tryWithLockSuspend(uuid) { - val error = postgreSQL.addToPlayerShards(uuid, shards, ShardType.BANK) - if (error) { - throw DiamondBankException.OtherException + postgreSQL.addToPlayerShards(uuid, shards, ShardType.BANK).getOrElse { + throw DiamondBankException.DatabaseException(it.message ?: "Database exception") } - val transactionLogError = - DiamondBankOG.postgreSQL.insertTransactionLog(uuid, shards, null, transactionReason, notes) - if (transactionLogError) { - handleError(uuid, shards, null, null, true) - } + DiamondBankOG.postgreSQL + .insertTransactionLog(uuid, shards, null, transactionReason, notes) + .getOrElse { handleError(uuid, shards, null, null, true) } } ) { - is LockResult.Acquired -> { - result.result - } + is LockResult.Acquired -> result.result - LockResult.Failed -> { - throw DiamondBankException.TransactionsLockedException - } + is LockResult.Failed -> throw DiamondBankException.TransactionsLockedException } } } /** - * WARNING: blocking, if the player has a transaction lock applied this function will wait until its released + * WARNING: do not run on a thread where blocking is unacceptable WARNING: blocking, if the player has a transaction + * lock applied this function will wait until its released * * @param transactionReason the reason for this transaction for in the transaction log * @param notes any specifics for this transaction that may be nice to know for in the transaction log * @throws DiamondBankException.EconomyDisabledException - * @throws DiamondBankException.OtherException + * @throws DiamondBankException.DatabaseException */ - @Throws(DiamondBankException.EconomyDisabledException::class, DiamondBankException.OtherException::class) + @Throws(DiamondBankException.EconomyDisabledException::class, DiamondBankException.DatabaseException::class) @Suppress("unused") - fun blockingSubtractFromPlayerBankShards( - uuid: UUID, - shards: Int, - transactionReason: String, - notes: String?, - ): CompletableFuture { + fun blockingSubtractFromPlayerBankShards(uuid: UUID, shards: Int, transactionReason: String, notes: String?) { if (DiamondBankOG.economyDisabled) throw DiamondBankException.EconomyDisabledException - return DiamondBankOG.scope.future { + return runBlocking { DiamondBankOG.transactionLock.withLockSuspend(uuid) { - val error = postgreSQL.subtractFromPlayerShards(uuid, shards, ShardType.BANK) - if (error) { - throw DiamondBankException.OtherException + postgreSQL.subtractFromBankShards(uuid, shards).getOrElse { + throw DiamondBankException.DatabaseException(it.message ?: "Database exception") } - val transactionLogError = - DiamondBankOG.postgreSQL.insertTransactionLog(uuid, shards, null, transactionReason, notes) - if (transactionLogError) { + DiamondBankOG.postgreSQL.insertTransactionLog(uuid, shards, null, transactionReason, notes).getOrElse { handleError(uuid, shards, null, null, true) } } @@ -128,144 +106,293 @@ class DiamondBankAPIJava(private var postgreSQL: PostgreSQL) { } /** + * WARNING: do not run on a thread where blocking is unacceptable + * * @param transactionReason the reason for this transaction for in the transaction log * @param notes any specifics for this transaction that may be nice to know for in the transaction log * @throws DiamondBankException.EconomyDisabledException * @throws DiamondBankException.TransactionsLockedException - * @throws DiamondBankException.OtherException + * @throws DiamondBankException.DatabaseException */ @Throws( DiamondBankException.EconomyDisabledException::class, DiamondBankException.TransactionsLockedException::class, - DiamondBankException.OtherException::class, + DiamondBankException.DatabaseException::class, ) @Suppress("unused") - fun subtractFromPlayerBankShards( - uuid: UUID, - shards: Int, - transactionReason: String, - notes: String?, - ): CompletableFuture { + fun subtractFromPlayerBankShards(uuid: UUID, shards: Int, transactionReason: String, notes: String?) { if (DiamondBankOG.economyDisabled) throw DiamondBankException.EconomyDisabledException - return DiamondBankOG.scope.future { + return runBlocking { when ( val result = DiamondBankOG.transactionLock.tryWithLockSuspend(uuid) { - val error = postgreSQL.subtractFromPlayerShards(uuid, shards, ShardType.BANK) - if (error) { - throw DiamondBankException.OtherException + postgreSQL.subtractFromBankShards(uuid, shards).getOrElse { + throw DiamondBankException.DatabaseException(it.message ?: "Database exception") } - val transactionLogError = - DiamondBankOG.postgreSQL.insertTransactionLog(uuid, shards, null, transactionReason, notes) - if (transactionLogError) { - handleError(uuid, shards, null, null, true) - } + DiamondBankOG.postgreSQL + .insertTransactionLog(uuid, shards, null, transactionReason, notes) + .getOrElse { handleError(uuid, shards, null, null, true) } } ) { - is LockResult.Acquired -> { - result.result - } + is LockResult.Acquired -> result.result - LockResult.Failed -> { - throw DiamondBankException.TransactionsLockedException - } + is LockResult.Failed -> throw DiamondBankException.TransactionsLockedException } } } /** - * WARNING: blocking, if the player has a transaction lock applied this function will wait until its released + * WARNING: do not run on a thread where blocking is unacceptable WARNING: blocking, if the player has a transaction + * lock applied this function will wait until its released * * @throws DiamondBankException.EconomyDisabledException - * @throws DiamondBankException.OtherException + * @throws DiamondBankException.DatabaseException */ - @Throws(DiamondBankException.EconomyDisabledException::class, DiamondBankException.OtherException::class) + @Throws(DiamondBankException.EconomyDisabledException::class, DiamondBankException.DatabaseException::class) @Suppress("unused") - fun blockingGetPlayerShards(uuid: UUID, type: ShardType): CompletableFuture { + fun blockingGetBankShards(uuid: UUID): Int = blockingGetShardTypeShards(uuid, ShardType.BANK) + + /** + * WARNING: do not run on a thread where blocking is unacceptable WARNING: blocking, if the player has a transaction + * lock applied this function will wait until its released + * + * @throws DiamondBankException.EconomyDisabledException + * @throws DiamondBankException.DatabaseException + */ + @Throws(DiamondBankException.EconomyDisabledException::class, DiamondBankException.DatabaseException::class) + @Suppress("unused") + fun blockingGetInventoryShards(uuid: UUID): Int = blockingGetShardTypeShards(uuid, ShardType.INVENTORY) + + /** + * WARNING: do not run on a thread where blocking is unacceptable WARNING: blocking, if the player has a transaction + * lock applied this function will wait until its released + * + * @throws DiamondBankException.EconomyDisabledException + * @throws DiamondBankException.DatabaseException + */ + @Throws(DiamondBankException.EconomyDisabledException::class, DiamondBankException.DatabaseException::class) + @Suppress("unused") + fun blockingGetEnderChestShards(uuid: UUID): Int = blockingGetShardTypeShards(uuid, ShardType.ENDER_CHEST) + + /** + * WARNING: do not run on a thread where blocking is unacceptable WARNING: blocking, if the player has a transaction + * lock applied this function will wait until its released + * + * @throws DiamondBankException.EconomyDisabledException + * @throws DiamondBankException.DatabaseException + */ + @Throws(DiamondBankException.EconomyDisabledException::class, DiamondBankException.DatabaseException::class) + @Suppress("unused") + fun blockingGetTotalShards(uuid: UUID): Int = blockingGetShardTypeShards(uuid, ShardType.TOTAL) + + /** + * WARNING: do not run on a thread where blocking is unacceptable WARNING: blocking, if the player has a transaction + * lock applied this function will wait until its released + * + * @throws DiamondBankException.EconomyDisabledException + * @throws DiamondBankException.DatabaseException + */ + @Throws(DiamondBankException.EconomyDisabledException::class, DiamondBankException.DatabaseException::class) + @Suppress("unused") + fun blockingGetAllShards(uuid: UUID): PlayerShards { if (DiamondBankOG.economyDisabled) throw DiamondBankException.EconomyDisabledException - return DiamondBankOG.scope.future { + return runBlocking { DiamondBankOG.transactionLock.withLockSuspend(uuid) { - val playerShards = postgreSQL.getPlayerShards(uuid, type) - if (playerShards.isNeededShardTypeNull(type)) { - throw DiamondBankException.OtherException + val result = postgreSQL.getAllShards(uuid) + result.exceptionOrNull()?.let { + throw DiamondBankException.DatabaseException(it.message ?: "Database exception") } - playerShards + result.getOrThrow() } } } /** + * WARNING: do not run on a thread where blocking is unacceptable WARNING: blocking, if the player has a transaction + * lock applied this function will wait until its released + * + * @throws DiamondBankException.EconomyDisabledException + * @throws DiamondBankException.DatabaseException + */ + @Throws(DiamondBankException.EconomyDisabledException::class, DiamondBankException.DatabaseException::class) + private fun blockingGetShardTypeShards(uuid: UUID, type: ShardType): Int { + if (DiamondBankOG.economyDisabled) throw DiamondBankException.EconomyDisabledException + + return runBlocking { + val result = + DiamondBankOG.transactionLock.withLockSuspend(uuid) { + when (type) { + ShardType.BANK -> postgreSQL.getBankShards(uuid) + ShardType.INVENTORY -> postgreSQL.getInventoryShards(uuid) + ShardType.ENDER_CHEST -> postgreSQL.getEnderChestShards(uuid) + ShardType.TOTAL -> postgreSQL.getTotalShards(uuid) + } + } + result.exceptionOrNull()?.let { + throw DiamondBankException.DatabaseException(it.message ?: "Database exception") + } + result.getOrThrow() + } + } + + /** + * WARNING: do not run on a thread where blocking is unacceptable + * * @throws DiamondBankException.EconomyDisabledException * @throws DiamondBankException.TransactionsLockedException - * @throws DiamondBankException.OtherException + * @throws DiamondBankException.DatabaseException */ @Throws( DiamondBankException.EconomyDisabledException::class, DiamondBankException.TransactionsLockedException::class, - DiamondBankException.OtherException::class, + DiamondBankException.DatabaseException::class, ) @Suppress("unused") - fun getPlayerShards(uuid: UUID, type: ShardType): CompletableFuture { + fun getBankShards(uuid: UUID): Int = getShardTypeShards(uuid, ShardType.BANK) + + /** + * WARNING: do not run on a thread where blocking is unacceptable + * + * @throws DiamondBankException.EconomyDisabledException + * @throws DiamondBankException.TransactionsLockedException + * @throws DiamondBankException.DatabaseException + */ + @Throws( + DiamondBankException.EconomyDisabledException::class, + DiamondBankException.TransactionsLockedException::class, + DiamondBankException.DatabaseException::class, + ) + @Suppress("unused") + fun getInventoryShards(uuid: UUID): Int = getShardTypeShards(uuid, ShardType.INVENTORY) + + /** + * WARNING: do not run on a thread where blocking is unacceptable + * + * @throws DiamondBankException.EconomyDisabledException + * @throws DiamondBankException.TransactionsLockedException + * @throws DiamondBankException.DatabaseException + */ + @Throws( + DiamondBankException.EconomyDisabledException::class, + DiamondBankException.TransactionsLockedException::class, + DiamondBankException.DatabaseException::class, + ) + @Suppress("unused") + fun getEnderChestShards(uuid: UUID): Int = getShardTypeShards(uuid, ShardType.ENDER_CHEST) + + /** + * WARNING: do not run on a thread where blocking is unacceptable + * + * @throws DiamondBankException.EconomyDisabledException + * @throws DiamondBankException.TransactionsLockedException + * @throws DiamondBankException.DatabaseException + */ + @Throws( + DiamondBankException.EconomyDisabledException::class, + DiamondBankException.TransactionsLockedException::class, + DiamondBankException.DatabaseException::class, + ) + @Suppress("unused") + fun getTotalShards(uuid: UUID): Int = getShardTypeShards(uuid, ShardType.TOTAL) + + /** + * WARNING: do not run on a thread where blocking is unacceptable + * + * @throws DiamondBankException.EconomyDisabledException + * @throws DiamondBankException.TransactionsLockedException + * @throws DiamondBankException.DatabaseException + */ + @Throws( + DiamondBankException.EconomyDisabledException::class, + DiamondBankException.TransactionsLockedException::class, + DiamondBankException.DatabaseException::class, + ) + @Suppress("unused") + fun getAllShards(uuid: UUID): PlayerShards { if (DiamondBankOG.economyDisabled) throw DiamondBankException.EconomyDisabledException - return DiamondBankOG.scope.future { + return runBlocking { + when ( + val result = DiamondBankOG.transactionLock.tryWithLockSuspend(uuid) { postgreSQL.getAllShards(uuid) } + ) { + is LockResult.Acquired -> { + result.result.exceptionOrNull()?.let { + throw DiamondBankException.DatabaseException(it.message ?: "Database exception") + } + result.result.getOrThrow() + } + + is LockResult.Failed -> throw DiamondBankException.TransactionsLockedException + } + } + } + + private fun getShardTypeShards(uuid: UUID, type: ShardType): Int { + if (DiamondBankOG.economyDisabled) throw DiamondBankException.EconomyDisabledException + + return runBlocking { when ( val result = DiamondBankOG.transactionLock.tryWithLockSuspend(uuid) { - val playerShards = postgreSQL.getPlayerShards(uuid, type) - if (playerShards.isNeededShardTypeNull(type)) { - throw DiamondBankException.OtherException + when (type) { + ShardType.BANK -> postgreSQL.getBankShards(uuid) + ShardType.INVENTORY -> postgreSQL.getInventoryShards(uuid) + ShardType.ENDER_CHEST -> postgreSQL.getEnderChestShards(uuid) + ShardType.TOTAL -> postgreSQL.getTotalShards(uuid) } - playerShards } ) { is LockResult.Acquired -> { - result.result + result.result.exceptionOrNull()?.let { + throw DiamondBankException.DatabaseException(it.message ?: "Database exception") + } + result.result.getOrThrow() } - LockResult.Failed -> { - throw DiamondBankException.TransactionsLockedException - } + is LockResult.Failed -> throw DiamondBankException.TransactionsLockedException } } } /** + * WARNING: do not run on a thread where blocking is unacceptable + * * @throws DiamondBankException.EconomyDisabledException - * @throws DiamondBankException.OtherException + * @throws DiamondBankException.DatabaseException */ - @Throws(DiamondBankException.EconomyDisabledException::class, DiamondBankException.OtherException::class) + @Throws(DiamondBankException.EconomyDisabledException::class, DiamondBankException.DatabaseException::class) @Suppress("unused") fun getBaltop(offset: Int): CompletableFuture> { if (DiamondBankOG.economyDisabled) throw DiamondBankException.EconomyDisabledException return DiamondBankOG.scope.future { - val baltop = postgreSQL.getBaltop(offset) - if (baltop == null) { - throw DiamondBankException.OtherException - } + val baltop = + postgreSQL.getBaltop(offset).getOrElse { + throw DiamondBankException.DatabaseException(it.message ?: "Database exception") + } baltop } } /** - * WARNING: blocking, if the player has a transaction lock applied this function will wait until its released + * WARNING: do not run on a thread where blocking is unacceptable WARNING: blocking, if the player has a transaction + * lock applied this function will wait until its released * * @param transactionReason the reason for this transaction for in the transaction log * @param notes any specifics for this transaction that may be nice to know for in the transaction log * @throws DiamondBankException.EconomyDisabledException * @throws DiamondBankException.InvalidPlayerException * @throws DiamondBankException.PlayerNotOnlineException - * @throws DiamondBankException.OtherException + * @throws DiamondBankException.DatabaseException */ @Throws( DiamondBankException.EconomyDisabledException::class, DiamondBankException.InvalidPlayerException::class, DiamondBankException.PlayerNotOnlineException::class, - DiamondBankException.OtherException::class, + DiamondBankException.DatabaseException::class, ) @Suppress("unused") fun blockingWithdrawFromPlayer( @@ -286,12 +413,10 @@ class DiamondBankAPIJava(private var postgreSQL: PostgreSQL) { val notRemoved = WithdrawHelper.withdrawFromPlayer(playerPlayer, shards) if (notRemoved != 0) { handleError(uuid, shards, null) - throw DiamondBankException.OtherException + throw DiamondBankException.DatabaseException("Database exception") } - val transactionLogError = - DiamondBankOG.postgreSQL.insertTransactionLog(uuid, shards, null, transactionReason, notes) - if (transactionLogError) { + DiamondBankOG.postgreSQL.insertTransactionLog(uuid, shards, null, transactionReason, notes).getOrElse { handleError(uuid, shards, null, null, true) } } @@ -299,20 +424,22 @@ class DiamondBankAPIJava(private var postgreSQL: PostgreSQL) { } /** + * WARNING: do not run on a thread where blocking is unacceptable + * * @param transactionReason the reason for this transaction for in the transaction log * @param notes any specifics for this transaction that may be nice to know for in the transaction log * @throws DiamondBankException.EconomyDisabledException * @throws DiamondBankException.InvalidPlayerException * @throws DiamondBankException.PlayerNotOnlineException * @throws DiamondBankException.TransactionsLockedException - * @throws DiamondBankException.OtherException + * @throws DiamondBankException.DatabaseException */ @Throws( DiamondBankException.EconomyDisabledException::class, DiamondBankException.InvalidPlayerException::class, DiamondBankException.PlayerNotOnlineException::class, DiamondBankException.TransactionsLockedException::class, - DiamondBankException.OtherException::class, + DiamondBankException.DatabaseException::class, ) @Suppress("unused") fun withdrawFromPlayer( @@ -335,41 +462,38 @@ class DiamondBankAPIJava(private var postgreSQL: PostgreSQL) { val notRemoved = WithdrawHelper.withdrawFromPlayer(playerPlayer, shards) if (notRemoved != 0) { handleError(uuid, shards, null) - throw DiamondBankException.OtherException + throw DiamondBankException.DatabaseException("Database exception") } - val transactionLogError = - DiamondBankOG.postgreSQL.insertTransactionLog(uuid, shards, null, transactionReason, notes) - if (transactionLogError) { - handleError(uuid, shards, null, null, true) - } + DiamondBankOG.postgreSQL + .insertTransactionLog(uuid, shards, null, transactionReason, notes) + .getOrElse { handleError(uuid, shards, null, null, true) } } ) { - is LockResult.Acquired -> { - result.result - } + is LockResult.Acquired -> result.result - LockResult.Failed -> { - throw DiamondBankException.TransactionsLockedException - } + is LockResult.Failed -> throw DiamondBankException.TransactionsLockedException } } } /** - * WARNING: blocking, if the player has a transaction lock applied this function will wait until its released + * WARNING: do not run on a thread where blocking is unacceptable WARNING: blocking, if the player has a transaction + * lock applied this function will wait until its released * * @param transactionReason the reason for this transaction for in the transaction log * @param notes any specifics for this transaction that may be nice to know for in the transaction log * @throws DiamondBankException.EconomyDisabledException * @throws DiamondBankException.InvalidPlayerException * @throws DiamondBankException.PlayerNotOnlineException + * @throws DiamondBankException.DatabaseException * @throws DiamondBankException.OtherException */ @Throws( DiamondBankException.EconomyDisabledException::class, DiamondBankException.InvalidPlayerException::class, DiamondBankException.PlayerNotOnlineException::class, + DiamondBankException.DatabaseException::class, DiamondBankException.OtherException::class, ) @Suppress("unused") @@ -398,34 +522,28 @@ class DiamondBankAPIJava(private var postgreSQL: PostgreSQL) { throw DiamondBankException.OtherException } - val error = postgreSQL.addToPlayerShards(receiver.uniqueId, shards, ShardType.BANK) - if (error) { + postgreSQL.addToPlayerShards(receiver.uniqueId, shards, ShardType.BANK).getOrElse { handleError(sender.uniqueId, shards, null) - throw DiamondBankException.OtherException + throw DiamondBankException.DatabaseException(it.message ?: "Database exception") } - val transactionLogError = - DiamondBankOG.postgreSQL.insertTransactionLog( - payerUuid, - shards, - receiverUuid, - transactionReason, - notes, - ) - if (transactionLogError) { - handleError(payerUuid, shards, null, receiverUuid, true) - } + DiamondBankOG.postgreSQL + .insertTransactionLog(payerUuid, shards, receiverUuid, transactionReason, notes) + .getOrElse { handleError(payerUuid, shards, null, receiverUuid, true) } } } } /** + * WARNING: do not run on a thread where blocking is unacceptable + * * @param transactionReason the reason for this transaction for in the transaction log * @param notes any specifics for this transaction that may be nice to know for in the transaction log * @throws DiamondBankException.EconomyDisabledException * @throws DiamondBankException.InvalidPlayerException * @throws DiamondBankException.PlayerNotOnlineException * @throws DiamondBankException.TransactionsLockedException + * @throws DiamondBankException.DatabaseException * @throws DiamondBankException.OtherException */ @Throws( @@ -433,6 +551,7 @@ class DiamondBankAPIJava(private var postgreSQL: PostgreSQL) { DiamondBankException.InvalidPlayerException::class, DiamondBankException.PlayerNotOnlineException::class, DiamondBankException.TransactionsLockedException::class, + DiamondBankException.DatabaseException::class, DiamondBankException.OtherException::class, ) @Suppress("unused") @@ -463,32 +582,19 @@ class DiamondBankAPIJava(private var postgreSQL: PostgreSQL) { throw DiamondBankException.OtherException } - val error = postgreSQL.addToPlayerShards(receiver.uniqueId, shards, ShardType.BANK) - if (error) { + postgreSQL.addToPlayerShards(receiver.uniqueId, shards, ShardType.BANK).getOrElse { handleError(sender.uniqueId, shards, null) - throw DiamondBankException.OtherException + throw DiamondBankException.DatabaseException(it.message ?: "Database exception") } - val transactionLogError = - DiamondBankOG.postgreSQL.insertTransactionLog( - payerUuid, - shards, - receiverUuid, - transactionReason, - notes, - ) - if (transactionLogError) { - handleError(payerUuid, shards, null, receiverUuid, true) - } + DiamondBankOG.postgreSQL + .insertTransactionLog(payerUuid, shards, receiverUuid, transactionReason, notes) + .getOrElse { handleError(payerUuid, shards, null, receiverUuid, true) } } ) { - is LockResult.Acquired -> { - result.result - } + is LockResult.Acquired -> result.result - LockResult.Failed -> { - throw DiamondBankException.TransactionsLockedException - } + is LockResult.Failed -> throw DiamondBankException.TransactionsLockedException } } } diff --git a/src/main/kotlin/net/trueog/diamondbankog/DiamondBankAPIKotlin.kt b/src/main/kotlin/net/trueog/diamondbankog/DiamondBankAPIKotlin.kt index 47ba5d4..f80c10a 100644 --- a/src/main/kotlin/net/trueog/diamondbankog/DiamondBankAPIKotlin.kt +++ b/src/main/kotlin/net/trueog/diamondbankog/DiamondBankAPIKotlin.kt @@ -25,14 +25,13 @@ class DiamondBankAPIKotlin(private var postgreSQL: PostgreSQL) { ): Result { if (DiamondBankOG.economyDisabled) return Result.failure(DiamondBankException.EconomyDisabledException) return DiamondBankOG.transactionLock.withLockSuspend(uuid) { - val error = postgreSQL.addToPlayerShards(uuid, shards, ShardType.BANK) - if (error) { - return@withLockSuspend Result.failure(DiamondBankException.OtherException) + postgreSQL.addToPlayerShards(uuid, shards, ShardType.BANK).getOrElse { + return@withLockSuspend Result.failure( + DiamondBankException.DatabaseException(it.message ?: "Database exception") + ) } - val transactionLogError = - DiamondBankOG.postgreSQL.insertTransactionLog(uuid, shards, null, transactionReason, notes) - if (transactionLogError) { + DiamondBankOG.postgreSQL.insertTransactionLog(uuid, shards, null, transactionReason, notes).getOrElse { handleError(uuid, shards, null, null, true) } @@ -56,27 +55,22 @@ class DiamondBankAPIKotlin(private var postgreSQL: PostgreSQL) { return when ( val result = DiamondBankOG.transactionLock.tryWithLockSuspend(uuid) { - val error = postgreSQL.addToPlayerShards(uuid, shards, ShardType.BANK) - if (error) { - return@tryWithLockSuspend Result.failure(DiamondBankException.OtherException) + postgreSQL.addToPlayerShards(uuid, shards, ShardType.BANK).getOrElse { + return@tryWithLockSuspend Result.failure( + DiamondBankException.DatabaseException(it.message ?: "Database exception") + ) } - val transactionLogError = - DiamondBankOG.postgreSQL.insertTransactionLog(uuid, shards, null, transactionReason, notes) - if (transactionLogError) { - handleError(uuid, shards, null, null, true) - } + DiamondBankOG.postgreSQL + .insertTransactionLog(uuid, shards, null, transactionReason, notes) + .getOrElse { handleError(uuid, shards, null, null, true) } Result.success(Unit) } ) { - is LockResult.Acquired -> { - result.result - } + is LockResult.Acquired -> result.result - LockResult.Failed -> { - return Result.failure(DiamondBankException.TransactionsLockedException) - } + is LockResult.Failed -> throw DiamondBankException.TransactionsLockedException } } @@ -96,14 +90,13 @@ class DiamondBankAPIKotlin(private var postgreSQL: PostgreSQL) { if (DiamondBankOG.economyDisabled) return Result.failure(DiamondBankException.EconomyDisabledException) return DiamondBankOG.transactionLock.withLockSuspend(uuid) { - val error = postgreSQL.subtractFromPlayerShards(uuid, shards, ShardType.BANK) - if (error) { - return@withLockSuspend Result.failure(DiamondBankException.OtherException) + postgreSQL.subtractFromBankShards(uuid, shards).getOrElse { + return@withLockSuspend Result.failure( + DiamondBankException.DatabaseException(it.message ?: "Database exception") + ) } - val transactionLogError = - DiamondBankOG.postgreSQL.insertTransactionLog(uuid, shards, null, transactionReason, notes) - if (transactionLogError) { + DiamondBankOG.postgreSQL.insertTransactionLog(uuid, shards, null, transactionReason, notes).getOrElse { handleError(uuid, shards, null, null, true) } @@ -127,66 +120,118 @@ class DiamondBankAPIKotlin(private var postgreSQL: PostgreSQL) { return when ( val result = DiamondBankOG.transactionLock.tryWithLockSuspend(uuid) { - val error = postgreSQL.subtractFromPlayerShards(uuid, shards, ShardType.BANK) - if (error) { - return@tryWithLockSuspend Result.failure(DiamondBankException.OtherException) + postgreSQL.subtractFromBankShards(uuid, shards).getOrElse { + return@tryWithLockSuspend Result.failure( + DiamondBankException.DatabaseException(it.message ?: "Database exception") + ) } - val transactionLogError = - DiamondBankOG.postgreSQL.insertTransactionLog(uuid, shards, null, transactionReason, notes) - if (transactionLogError) { - handleError(uuid, shards, null, null, true) - } + DiamondBankOG.postgreSQL + .insertTransactionLog(uuid, shards, null, transactionReason, notes) + .getOrElse { handleError(uuid, shards, null, null, true) } Result.success(Unit) } ) { - is LockResult.Acquired -> { - result.result - } + is LockResult.Acquired -> result.result - LockResult.Failed -> { - Result.failure(DiamondBankException.TransactionsLockedException) - } + is LockResult.Failed -> throw DiamondBankException.TransactionsLockedException } } /** WARNING: blocking, if the player has a transaction lock applied this function will wait until its released */ @Suppress("unused") - suspend fun blockingGetPlayerShards(uuid: UUID, type: ShardType): Result { + suspend fun blockingGetBankShards(uuid: UUID): Result = blockingGetShardTypeShards(uuid, ShardType.BANK) + + /** WARNING: blocking, if the player has a transaction lock applied this function will wait until its released */ + @Suppress("unused") + suspend fun blockingGetInventoryShards(uuid: UUID): Result = + blockingGetShardTypeShards(uuid, ShardType.INVENTORY) + + /** WARNING: blocking, if the player has a transaction lock applied this function will wait until its released */ + @Suppress("unused") + suspend fun blockingGetEnderChestShards(uuid: UUID): Result = + blockingGetShardTypeShards(uuid, ShardType.ENDER_CHEST) + + /** WARNING: blocking, if the player has a transaction lock applied this function will wait until its released */ + @Suppress("unused") + suspend fun blockingGetTotalShards(uuid: UUID): Result = blockingGetShardTypeShards(uuid, ShardType.TOTAL) + + /** WARNING: blocking, if the player has a transaction lock applied this function will wait until its released */ + @Suppress("unused") + suspend fun blockingGetAllShards(uuid: UUID): Result { + if (DiamondBankOG.economyDisabled) return Result.failure(DiamondBankException.EconomyDisabledException) + return postgreSQL.getAllShards(uuid) + } + + private suspend fun blockingGetShardTypeShards(uuid: UUID, type: ShardType): Result { if (DiamondBankOG.economyDisabled) return Result.failure(DiamondBankException.EconomyDisabledException) return DiamondBankOG.transactionLock.withLockSuspend(uuid) { - val playerShards = postgreSQL.getPlayerShards(uuid, type) - if (playerShards.isNeededShardTypeNull(type)) { - return@withLockSuspend Result.failure(DiamondBankException.OtherException) + val result = + when (type) { + ShardType.BANK -> postgreSQL.getBankShards(uuid) + ShardType.INVENTORY -> postgreSQL.getInventoryShards(uuid) + ShardType.ENDER_CHEST -> postgreSQL.getEnderChestShards(uuid) + ShardType.TOTAL -> postgreSQL.getTotalShards(uuid) + } + result.exceptionOrNull()?.let { + Result.failure(DiamondBankException.DatabaseException(it.message ?: "Database exception")) } - - Result.success(playerShards) + Result.success(result.getOrThrow()) } } + @Suppress("unused") suspend fun getBankShards(uuid: UUID) = getShardTypeShards(uuid, ShardType.BANK) + + @Suppress("unused") suspend fun getInventoryShards(uuid: UUID) = getShardTypeShards(uuid, ShardType.INVENTORY) + + @Suppress("unused") suspend fun getEnderChestShards(uuid: UUID) = getShardTypeShards(uuid, ShardType.ENDER_CHEST) + + @Suppress("unused") suspend fun getTotalShards(uuid: UUID) = getShardTypeShards(uuid, ShardType.TOTAL) + @Suppress("unused") - suspend fun getPlayerShards(uuid: UUID, type: ShardType): Result { + suspend fun getAllShards(uuid: UUID): Result { if (DiamondBankOG.economyDisabled) return Result.failure(DiamondBankException.EconomyDisabledException) return when ( val result = DiamondBankOG.transactionLock.tryWithLockSuspend(uuid) { - val playerShards = postgreSQL.getPlayerShards(uuid, type) - if (playerShards.isNeededShardTypeNull(type)) { - return@tryWithLockSuspend Result.failure(DiamondBankException.OtherException) + val result = postgreSQL.getAllShards(uuid) + result.exceptionOrNull()?.let { + Result.failure(DiamondBankException.DatabaseException(it.message ?: "Database exception")) } - Result.success(playerShards) + Result.success(result.getOrThrow()) } ) { - is LockResult.Acquired -> { - result.result - } + is LockResult.Acquired -> result.result - LockResult.Failed -> { - return Result.failure(DiamondBankException.TransactionsLockedException) - } + is LockResult.Failed -> throw DiamondBankException.TransactionsLockedException + } + } + + private suspend fun getShardTypeShards(uuid: UUID, type: ShardType): Result { + if (DiamondBankOG.economyDisabled) return Result.failure(DiamondBankException.EconomyDisabledException) + + return when ( + val result = + DiamondBankOG.transactionLock.tryWithLockSuspend(uuid) { + val result = + when (type) { + ShardType.BANK -> postgreSQL.getBankShards(uuid) + ShardType.INVENTORY -> postgreSQL.getInventoryShards(uuid) + ShardType.ENDER_CHEST -> postgreSQL.getEnderChestShards(uuid) + ShardType.TOTAL -> postgreSQL.getTotalShards(uuid) + } + result.exceptionOrNull()?.let { + Result.failure(DiamondBankException.DatabaseException(it.message ?: "Database exception")) + } + Result.success(result.getOrThrow()) + } + ) { + is LockResult.Acquired -> result.result + + is LockResult.Failed -> throw DiamondBankException.TransactionsLockedException } } @@ -194,10 +239,10 @@ class DiamondBankAPIKotlin(private var postgreSQL: PostgreSQL) { suspend fun getBaltop(offset: Int): Result> { if (DiamondBankOG.economyDisabled) return Result.failure(DiamondBankException.EconomyDisabledException) - val baltop = postgreSQL.getBaltop(offset) - if (baltop == null) { - return Result.failure(DiamondBankException.OtherException) - } + val baltop = + postgreSQL.getBaltop(offset).getOrElse { + return Result.failure(DiamondBankException.DatabaseException(it.message ?: "Database exception")) + } return Result.success(baltop) } @@ -230,9 +275,7 @@ class DiamondBankAPIKotlin(private var postgreSQL: PostgreSQL) { return@withLockSuspend Result.failure(DiamondBankException.OtherException) } - val transactionLogError = - DiamondBankOG.postgreSQL.insertTransactionLog(uuid, shards, null, transactionReason, notes) - if (transactionLogError) { + DiamondBankOG.postgreSQL.insertTransactionLog(uuid, shards, null, transactionReason, notes).getOrElse { handleError(uuid, shards, null, null, true) } @@ -266,22 +309,16 @@ class DiamondBankAPIKotlin(private var postgreSQL: PostgreSQL) { return@tryWithLockSuspend Result.failure(DiamondBankException.OtherException) } - val transactionLogError = - DiamondBankOG.postgreSQL.insertTransactionLog(uuid, shards, null, transactionReason, notes) - if (transactionLogError) { - handleError(uuid, shards, null, null, true) - } + DiamondBankOG.postgreSQL + .insertTransactionLog(uuid, shards, null, transactionReason, notes) + .getOrElse { handleError(uuid, shards, null, null, true) } Result.success(Unit) } ) { - is LockResult.Acquired -> { - result.result - } + is LockResult.Acquired -> result.result - LockResult.Failed -> { - Result.failure(DiamondBankException.TransactionsLockedException) - } + is LockResult.Failed -> throw DiamondBankException.TransactionsLockedException } } @@ -319,17 +356,16 @@ class DiamondBankAPIKotlin(private var postgreSQL: PostgreSQL) { return@withLockSuspend Result.failure(DiamondBankException.OtherException) } - val error = postgreSQL.addToPlayerShards(receiver.uniqueId, shards, ShardType.BANK) - if (error) { + postgreSQL.addToPlayerShards(receiver.uniqueId, shards, ShardType.BANK).getOrElse { handleError(sender.uniqueId, shards, null) - return@withLockSuspend Result.failure(DiamondBankException.OtherException) + return@withLockSuspend Result.failure( + DiamondBankException.DatabaseException(it.message ?: "Database exception") + ) } - val transactionLogError = - DiamondBankOG.postgreSQL.insertTransactionLog(payerUuid, shards, receiverUuid, transactionReason, notes) - if (transactionLogError) { - handleError(payerUuid, shards, null, receiverUuid, true) - } + DiamondBankOG.postgreSQL + .insertTransactionLog(payerUuid, shards, receiverUuid, transactionReason, notes) + .getOrElse { handleError(payerUuid, shards, null, receiverUuid, true) } Result.success(Unit) } @@ -371,34 +407,23 @@ class DiamondBankAPIKotlin(private var postgreSQL: PostgreSQL) { return@tryWithLockSuspend Result.failure(DiamondBankException.OtherException) } - val error = postgreSQL.addToPlayerShards(receiver.uniqueId, shards, ShardType.BANK) - if (error) { + postgreSQL.addToPlayerShards(receiver.uniqueId, shards, ShardType.BANK).getOrElse { handleError(sender.uniqueId, shards, null) - return@tryWithLockSuspend Result.failure(DiamondBankException.OtherException) + return@tryWithLockSuspend Result.failure( + DiamondBankException.DatabaseException(it.message ?: "Database exception") + ) } - val transactionLogError = - DiamondBankOG.postgreSQL.insertTransactionLog( - payerUuid, - shards, - receiverUuid, - transactionReason, - notes, - ) - if (transactionLogError) { - handleError(payerUuid, shards, null, receiverUuid, true) - } + DiamondBankOG.postgreSQL + .insertTransactionLog(payerUuid, shards, receiverUuid, transactionReason, notes) + .getOrElse { handleError(payerUuid, shards, null, receiverUuid, true) } Result.success(Unit) } ) { - is LockResult.Acquired -> { - result.result - } + is LockResult.Acquired -> result.result - LockResult.Failed -> { - Result.failure(DiamondBankException.TransactionsLockedException) - } + is LockResult.Failed -> throw DiamondBankException.TransactionsLockedException } } } diff --git a/src/main/kotlin/net/trueog/diamondbankog/DiamondBankException.kt b/src/main/kotlin/net/trueog/diamondbankog/DiamondBankException.kt index 75c32e6..b319762 100644 --- a/src/main/kotlin/net/trueog/diamondbankog/DiamondBankException.kt +++ b/src/main/kotlin/net/trueog/diamondbankog/DiamondBankException.kt @@ -21,6 +21,8 @@ sealed class DiamondBankException(message: String) : Exception(message) { @Suppress("unused") private fun readResolve(): Any = PlayerNotOnlineException } + class DatabaseException(message: String) : DiamondBankException(message) + object OtherException : DiamondBankException("Other exception") { @Suppress("unused") private fun readResolve(): Any = OtherException } diff --git a/src/main/kotlin/net/trueog/diamondbankog/ErrorHandler.kt b/src/main/kotlin/net/trueog/diamondbankog/ErrorHandler.kt index e70fb89..aa6a1c8 100644 --- a/src/main/kotlin/net/trueog/diamondbankog/ErrorHandler.kt +++ b/src/main/kotlin/net/trueog/diamondbankog/ErrorHandler.kt @@ -24,15 +24,15 @@ internal object ErrorHandler { if (otherUuid != null) "Other Player UUID: $otherUuid" else "" }Expected Mutated Shards = $expectedMutatedShards${ if (playerShards != null) { - if (playerShards.shardsInBank != -1) "Player Bank Balance: ${playerShards.shardsInBank}" else "" + if (playerShards.bank != -1) "Player Bank Balance: ${playerShards.bank}" else "" } else "" }${ if (playerShards != null) { - if (playerShards.shardsInInventory != -1) "Player Inventory Balance: ${playerShards.shardsInInventory}" else "" + if (playerShards.inventory != -1) "Player Inventory Balance: ${playerShards.inventory}" else "" } else "" }${ if (playerShards != null) { - if (playerShards.shardsInEnderChest != -1) "Player Ender Chest Balance: ${playerShards.shardsInEnderChest}" else "" + if (playerShards.enderChest != -1) "Player Ender Chest Balance: ${playerShards.enderChest}" else "" } else "" } """ diff --git a/src/main/kotlin/net/trueog/diamondbankog/Events.kt b/src/main/kotlin/net/trueog/diamondbankog/Events.kt index 1e0d539..f0c7700 100644 --- a/src/main/kotlin/net/trueog/diamondbankog/Events.kt +++ b/src/main/kotlin/net/trueog/diamondbankog/Events.kt @@ -42,24 +42,20 @@ internal class Events : Listener { DiamondBankOG.scope.launch { val inventoryShards = event.player.inventory.countTotal() - var error = - DiamondBankOG.postgreSQL.setPlayerShards(event.player.uniqueId, inventoryShards, ShardType.INVENTORY) - if (error) { - handleError(event.player.uniqueId, inventoryShards, null) - return@launch - } + DiamondBankOG.postgreSQL + .setPlayerShards(event.player.uniqueId, inventoryShards, ShardType.INVENTORY) + .getOrElse { + handleError(event.player.uniqueId, inventoryShards, null) + return@launch + } val enderChestDiamonds = event.player.enderChest.countTotal() - error = - DiamondBankOG.postgreSQL.setPlayerShards( - event.player.uniqueId, - enderChestDiamonds, - ShardType.ENDER_CHEST, - ) - if (error) { - handleError(event.player.uniqueId, enderChestDiamonds, null) - return@launch - } + DiamondBankOG.postgreSQL + .setPlayerShards(event.player.uniqueId, enderChestDiamonds, ShardType.ENDER_CHEST) + .getOrElse { + handleError(event.player.uniqueId, enderChestDiamonds, null) + return@launch + } } } @@ -108,12 +104,12 @@ internal class Events : Listener { DiamondBankOG.transactionLock.withLockSuspend(player.uniqueId) { val inventoryShards = runOnMainThread { player.inventory.countTotal() } - val error = - DiamondBankOG.postgreSQL.setPlayerShards(player.uniqueId, inventoryShards, ShardType.INVENTORY) - if (error) { - handleError(player.uniqueId, inventoryShards, null) - return@withLockSuspend - } + DiamondBankOG.postgreSQL + .setPlayerShards(player.uniqueId, inventoryShards, ShardType.INVENTORY) + .getOrElse { + handleError(player.uniqueId, inventoryShards, null) + return@withLockSuspend + } } } } @@ -152,16 +148,12 @@ internal class Events : Listener { DiamondBankOG.scope.launch { DiamondBankOG.transactionLock.withLockSuspend(event.player.uniqueId) { val inventoryShards = runOnMainThread { event.player.inventory.countTotal() } - val error = - DiamondBankOG.postgreSQL.setPlayerShards( - event.player.uniqueId, - inventoryShards, - ShardType.INVENTORY, - ) - if (error) { - handleError(event.player.uniqueId, inventoryShards, null) - return@withLockSuspend - } + DiamondBankOG.postgreSQL + .setPlayerShards(event.player.uniqueId, inventoryShards, ShardType.INVENTORY) + .getOrElse { + handleError(event.player.uniqueId, inventoryShards, null) + return@withLockSuspend + } } } } @@ -324,24 +316,20 @@ internal class Events : Listener { else null, ) } - var error = - DiamondBankOG.postgreSQL.setPlayerShards(player.uniqueId, inventoryShards, ShardType.INVENTORY) - if (error) { - handleError(player.uniqueId, inventoryShards, null) - return@withLockSuspend - } + DiamondBankOG.postgreSQL + .setPlayerShards(player.uniqueId, inventoryShards, ShardType.INVENTORY) + .getOrElse { + handleError(player.uniqueId, inventoryShards, null) + return@withLockSuspend + } if (enderChestShards == null) return@withLockSuspend - error = - DiamondBankOG.postgreSQL.setPlayerShards( - player.uniqueId, - enderChestShards, - ShardType.ENDER_CHEST, - ) - if (error) { - handleError(player.uniqueId, enderChestShards, null) - return@withLockSuspend - } + DiamondBankOG.postgreSQL + .setPlayerShards(player.uniqueId, enderChestShards, ShardType.ENDER_CHEST) + .getOrElse { + handleError(player.uniqueId, enderChestShards, null) + return@withLockSuspend + } } } } diff --git a/src/main/kotlin/net/trueog/diamondbankog/InventoryExtensions.kt b/src/main/kotlin/net/trueog/diamondbankog/InventoryExtensions.kt index dcdfe97..fd722e4 100644 --- a/src/main/kotlin/net/trueog/diamondbankog/InventoryExtensions.kt +++ b/src/main/kotlin/net/trueog/diamondbankog/InventoryExtensions.kt @@ -82,13 +82,13 @@ internal object InventoryExtensions { val leftOver = addMap[0]!!.amount - val error = DiamondBankOG.postgreSQL.addToPlayerShards(player.uniqueId, leftOver, ShardType.BANK) + val result = DiamondBankOG.postgreSQL.addToPlayerShards(player.uniqueId, leftOver, ShardType.BANK) player.sendMessage( DiamondBankOG.mm.deserialize( "${Config.prefix}: The change of $leftOver Diamond ${if (leftOver == 1) "Shard" else "Shards"} has been deposited into your bank." ) ) - return error + return result.isFailure } /** ONLY USE FOR INVENTORIES THAT DO NOT HAVE A HOLDER (for example shulker boxes) */ @@ -106,8 +106,9 @@ internal object InventoryExtensions { if (inventoryAddMap.isNotEmpty()) { val inventoryLeftOver = inventoryAddMap[0]!!.amount - val error = DiamondBankOG.postgreSQL.addToPlayerShards(player.uniqueId, inventoryLeftOver, ShardType.BANK) - if (error) return true + DiamondBankOG.postgreSQL.addToPlayerShards(player.uniqueId, inventoryLeftOver, ShardType.BANK).getOrElse { + return true + } player.sendMessage( DiamondBankOG.mm.deserialize( "${Config.prefix}: The change of ${leftOver - inventoryLeftOver} Diamond ${if (leftOver == 1) "Shard" else "Shards"} has been added to your inventory, and the remaining $inventoryLeftOver Diamond ${if (leftOver == 1) "Shard" else "Shards"} has been deposited into your bank." @@ -195,20 +196,16 @@ internal object InventoryExtensions { DiamondBankOG.scope.launch { DiamondBankOG.transactionLock.withLockSuspend(player.uniqueId) { val inventoryShards = player.inventory.countTotal() - val error = - DiamondBankOG.postgreSQL.setPlayerShards( - player.uniqueId, - inventoryShards, - ShardType.INVENTORY, - ) - if (error) { - handleError(player.uniqueId, inventoryShards, null) - player.sendMessage( - DiamondBankOG.mm.deserialize( - "${Config.prefix}: Something went wrong while trying to recount the Diamonds amount in your inventory, try opening and closing your inventory to force a recount." + DiamondBankOG.postgreSQL + .setPlayerShards(player.uniqueId, inventoryShards, ShardType.INVENTORY) + .getOrElse { + handleError(player.uniqueId, inventoryShards, null) + player.sendMessage( + DiamondBankOG.mm.deserialize( + "${Config.prefix}: Something went wrong while trying to recount the Diamonds amount in your inventory, try opening and closing your inventory to force a recount." + ) ) - ) - } + } } } } diff --git a/src/main/kotlin/net/trueog/diamondbankog/PostgreSQL.kt b/src/main/kotlin/net/trueog/diamondbankog/PostgreSQL.kt index ee47cbc..5b09f44 100644 --- a/src/main/kotlin/net/trueog/diamondbankog/PostgreSQL.kt +++ b/src/main/kotlin/net/trueog/diamondbankog/PostgreSQL.kt @@ -12,11 +12,19 @@ import kotlinx.coroutines.future.await class PostgreSQL { lateinit var pool: ConnectionPool + object InvalidArgumentException : Exception() { + @Suppress("unused") private fun readResolve(): Any = InvalidArgumentException + } + + object NoRowsException : Exception() { + @Suppress("unused") private fun readResolve(): Any = NoRowsException + } + enum class ShardType(val string: String) { BANK("bank_shards"), INVENTORY("inventory_shards"), ENDER_CHEST("ender_chest_shards"), - ALL("bank_shards, inventory_shards, ender_chest_shards"), + TOTAL("bank_shards, inventory_shards, ender_chest_shards"), } @Throws(SQLException::class, ClassNotFoundException::class) @@ -78,42 +86,10 @@ class PostgreSQL { } } - data class PlayerShards(val shardsInBank: Int?, val shardsInInventory: Int?, val shardsInEnderChest: Int?) { - fun isNeededShardTypeNull(type: ShardType): Boolean { - when (type) { - ShardType.BANK -> { - if (this.shardsInBank == null) { - return true - } - } + data class PlayerShards(val bank: Int, val inventory: Int, val enderChest: Int) - ShardType.INVENTORY -> { - if (this.shardsInInventory == null) { - return true - } - } - - ShardType.ENDER_CHEST -> { - if (this.shardsInEnderChest == null) { - return true - } - } - - ShardType.ALL -> { - if ( - this.shardsInBank == null || this.shardsInInventory == null || this.shardsInEnderChest == null - ) { - return true - } - } - } - return false - } - } - - /** @return True if failed */ - suspend fun setPlayerShards(uuid: UUID, shards: Int, type: ShardType): Boolean { - if (type == ShardType.ALL) return true + suspend fun setPlayerShards(uuid: UUID, shards: Int, type: ShardType): Result { + if (type == ShardType.TOTAL) return Result.failure(InvalidArgumentException) try { val connection = pool.asSuspending.connect() @@ -123,54 +99,130 @@ class PostgreSQL { listOf(uuid, shards), ) preparedStatement.await() - } catch (_: Exception) { - return true + } catch (e: Exception) { + return Result.failure(e) } - return false + return Result.success(Unit) } - /** @return True if failed */ - suspend fun addToPlayerShards(uuid: UUID, shards: Int, type: ShardType): Boolean { - if (type == ShardType.ALL) return true + suspend fun addToPlayerShards(uuid: UUID, shards: Int, type: ShardType): Result { + if (type == ShardType.TOTAL) return Result.failure(InvalidArgumentException) - val playerDiamonds = getPlayerShardsWrapper(uuid, type) ?: return true + val playerShards = + when (type) { + ShardType.BANK -> getBankShards(uuid) + ShardType.INVENTORY -> getInventoryShards(uuid) + ShardType.ENDER_CHEST -> getEnderChestShards(uuid) + else -> { + return Result.failure(InvalidArgumentException) + } + } - val error = setPlayerShards(uuid, playerDiamonds + shards, type) - return error + playerShards.exceptionOrNull()?.let { + return Result.failure(it) + } + + return setPlayerShards(uuid, playerShards.getOrThrow() + shards, type) } - /** @return True if failed */ - suspend fun subtractFromPlayerShards(uuid: UUID, shards: Int, type: ShardType): Boolean { - if (type == ShardType.ALL) return true + suspend fun subtractFromBankShards(uuid: UUID, shards: Int): Result { + val bankShards = getBankShards(uuid) + bankShards.exceptionOrNull()?.let { + return Result.failure(it) + } - val playerDiamonds = getPlayerShardsWrapper(uuid, type) ?: return true - - val error = setPlayerShards(uuid, playerDiamonds - shards, type) - return error + return setPlayerShards(uuid, bankShards.getOrThrow() - shards, ShardType.BANK) } - private suspend fun getPlayerShardsWrapper(uuid: UUID, type: ShardType): Int? { - val getResponse = getPlayerShards(uuid, type) + suspend fun getBankShards(uuid: UUID) = getShardTypeShards(uuid, ShardType.BANK) - return when (type) { - ShardType.BANK -> getResponse.shardsInBank - ShardType.INVENTORY -> getResponse.shardsInInventory - ShardType.ENDER_CHEST -> getResponse.shardsInEnderChest - ShardType.ALL -> - if ( - getResponse.shardsInBank != null && - getResponse.shardsInInventory != null && - getResponse.shardsInEnderChest != null + suspend fun getInventoryShards(uuid: UUID) = getShardTypeShards(uuid, ShardType.INVENTORY) + + suspend fun getEnderChestShards(uuid: UUID) = getShardTypeShards(uuid, ShardType.ENDER_CHEST) + + suspend fun getTotalShards(uuid: UUID): Result { + var totalShards: Int? + try { + val connection = pool.asSuspending.connect() + + val preparedStatement = + connection.sendPreparedStatement( + "SELECT bank_shards, inventory_shards, ender_chest_shards FROM ${Config.postgresTable} WHERE uuid = ? LIMIT 1", + listOf(uuid), ) - getResponse.shardsInBank + getResponse.shardsInInventory + getResponse.shardsInEnderChest - else null + val result = preparedStatement.await() + + totalShards = + if (result.rows.isNotEmpty()) { + val rowData = result.rows[0] as ArrayRowData + val bankShards = + if (rowData.columns[0] != null) { + rowData.columns[0] as Int + } else 0 + val inventoryShards = + if (rowData.columns[1] != null) { + rowData.columns[1] as Int + } else 0 + val enderChestShards = + if (rowData.columns[2] != null) { + rowData.columns[2] as Int + } else 0 + + bankShards + inventoryShards + enderChestShards + } else { + 0 + } + } catch (e: Exception) { + DiamondBankOG.plugin.logger.severe(e.toString()) + return Result.failure(e) } + + return Result.success(totalShards) } - suspend fun getPlayerShards(uuid: UUID, type: ShardType): PlayerShards { - var bankShards: Int? = null - var inventoryShards: Int? = null - var enderChestShards: Int? = null + suspend fun getAllShards(uuid: UUID): Result { + var bankShards: Int? + var inventoryShards: Int? + var enderChestShards: Int? + try { + val connection = pool.asSuspending.connect() + + val preparedStatement = + connection.sendPreparedStatement( + "SELECT bank_shards, inventory_shards, ender_chest_shards FROM ${Config.postgresTable} WHERE uuid = ? LIMIT 1", + listOf(uuid), + ) + val result = preparedStatement.await() + + if (result.rows.isNotEmpty()) { + val rowData = result.rows[0] as ArrayRowData + bankShards = + if (rowData.columns[0] != null) { + rowData.columns[0] as Int + } else 0 + inventoryShards = + if (rowData.columns[1] != null) { + rowData.columns[1] as Int + } else 0 + enderChestShards = + if (rowData.columns[2] != null) { + rowData.columns[2] as Int + } else 0 + } else { + bankShards = 0 + inventoryShards = 0 + enderChestShards = 0 + } + } catch (e: Exception) { + DiamondBankOG.plugin.logger.severe(e.toString()) + return Result.failure(e) + } + + return Result.success(PlayerShards(bankShards, inventoryShards, enderChestShards)) + } + + private suspend fun getShardTypeShards(uuid: UUID, type: ShardType): Result { + var shards: Int? try { val connection = pool.asSuspending.connect() @@ -181,59 +233,24 @@ class PostgreSQL { ) val result = preparedStatement.await() - if (result.rows.isNotEmpty()) { - val rowData = result.rows[0] as ArrayRowData - - when (type) { - ShardType.BANK -> { - bankShards = - if (rowData.columns[0] != null) { - rowData.columns[0] as Int - } else 0 - } - - ShardType.INVENTORY -> { - inventoryShards = - if (rowData.columns[0] != null) { - rowData.columns[0] as Int - } else 0 - } - - ShardType.ENDER_CHEST -> { - enderChestShards = - if (rowData.columns[0] != null) { - rowData.columns[0] as Int - } else 0 - } - - ShardType.ALL -> { - bankShards = - if (rowData.columns[0] != null) { - rowData.columns[0] as Int - } else 0 - inventoryShards = - if (rowData.columns[1] != null) { - rowData.columns[1] as Int - } else 0 - enderChestShards = - if (rowData.columns[2] != null) { - rowData.columns[2] as Int - } else 0 - } + shards = + if (result.rows.isNotEmpty()) { + val rowData = result.rows[0] as ArrayRowData + if (rowData.columns[0] != null) { + rowData.columns[0] as Int + } else 0 + } else { + 0 } - } else { - bankShards = 0 - inventoryShards = 0 - enderChestShards = 0 - } } catch (e: Exception) { DiamondBankOG.plugin.logger.severe(e.toString()) + return Result.failure(e) } - return PlayerShards(bankShards, inventoryShards, enderChestShards) + return Result.success(shards) } - suspend fun getBaltop(offset: Int): Map? { + suspend fun getBaltop(offset: Int): Result> { try { val connection = pool.asSuspending.connect() val preparedStatement = @@ -258,18 +275,18 @@ class PostgreSQL { baltop[uuid] = totalShards } - return baltop + return Result.success(baltop) } catch (e: Exception) { DiamondBankOG.plugin.logger.severe(e.toString()) + return Result.failure(e) } - return null } /** * @return Pair with as the first value a map with the player name and total balance and as the second value the * offset */ - suspend fun getBaltopWithUuid(uuid: UUID): Pair, Long>? { + suspend fun getBaltopWithUuid(uuid: UUID): Result, Long>> { try { val connection = pool.asSuspending.connect() // @formatter:off @@ -311,15 +328,15 @@ class PostgreSQL { baltop[uuid] = totalShards } - return Pair(baltop, offset) + return Result.success(Pair(baltop, offset)) } catch (e: Exception) { DiamondBankOG.plugin.logger.severe(e.toString()) + return Result.failure(e) } - return null } - suspend fun getNumberOfRows(): Long? { - var number: Long? = null + suspend fun getNumberOfRows(): Result { + var number: Long? try { val connection = pool.asSuspending.connect() val preparedStatement = @@ -332,21 +349,23 @@ class PostgreSQL { if (rowData.columns[0] != null) { rowData.columns[0] as Long } else 0 + } else { + return Result.failure(NoRowsException) } + return Result.success(number) } catch (e: Exception) { DiamondBankOG.plugin.logger.severe(e.toString()) + return Result.failure(e) } - return number } - /** @return True if failed */ suspend fun insertTransactionLog( playerUuid: UUID, transferredShards: Int, playerToUuid: UUID?, transactionReason: String, notes: String?, - ): Boolean { + ): Result { try { val connection = pool.asSuspending.connect() @@ -358,8 +377,8 @@ class PostgreSQL { ) preparedStatement.await() } catch (_: Exception) { - return true + return Result.failure(Exception()) } - return false + return Result.success(Unit) } } diff --git a/src/main/kotlin/net/trueog/diamondbankog/TransactionLock.kt b/src/main/kotlin/net/trueog/diamondbankog/TransactionLock.kt index 8ec0599..fd56902 100644 --- a/src/main/kotlin/net/trueog/diamondbankog/TransactionLock.kt +++ b/src/main/kotlin/net/trueog/diamondbankog/TransactionLock.kt @@ -14,7 +14,7 @@ internal class TransactionLock { } fun withLock(uuid: UUID, block: () -> T): T { - val lock = locks.computeIfAbsent(uuid) { Semaphore(1) } + val lock = locks.computeIfAbsent(uuid) { Semaphore(1, true) } lock.acquire() try { return block() @@ -24,7 +24,7 @@ internal class TransactionLock { } suspend fun withLockSuspend(uuid: UUID, block: suspend () -> T): T { - val lock = locks.computeIfAbsent(uuid) { Semaphore(1) } + val lock = locks.computeIfAbsent(uuid) { Semaphore(1, true) } lock.acquire() try { return block() @@ -34,7 +34,7 @@ internal class TransactionLock { } fun tryWithLock(uuid: UUID, block: () -> T): LockResult { - val lock = locks.computeIfAbsent(uuid) { Semaphore(1) } + val lock = locks.computeIfAbsent(uuid) { Semaphore(1, true) } return if (lock.tryAcquire()) { try { return LockResult.Acquired(block()) @@ -47,7 +47,7 @@ internal class TransactionLock { } suspend fun tryWithLockSuspend(uuid: UUID, block: suspend () -> T): LockResult { - val lock = locks.computeIfAbsent(uuid) { Semaphore(1) } + val lock = locks.computeIfAbsent(uuid) { Semaphore(1, true) } return if (lock.tryAcquire()) { try { LockResult.Acquired(block()) diff --git a/src/main/kotlin/net/trueog/diamondbankog/WithdrawHelper.kt b/src/main/kotlin/net/trueog/diamondbankog/WithdrawHelper.kt index 9c2e2e8..bdfd53c 100644 --- a/src/main/kotlin/net/trueog/diamondbankog/WithdrawHelper.kt +++ b/src/main/kotlin/net/trueog/diamondbankog/WithdrawHelper.kt @@ -3,30 +3,19 @@ package net.trueog.diamondbankog import kotlin.math.floor import net.trueog.diamondbankog.ErrorHandler.handleError import net.trueog.diamondbankog.InventoryExtensions.withdraw -import net.trueog.diamondbankog.PostgreSQL.ShardType import org.bukkit.entity.Player internal object WithdrawHelper { /** @return The amount of not removed shards, -1 if error */ suspend fun withdrawFromPlayer(player: Player, shards: Int): Int { - val playerShards = DiamondBankOG.postgreSQL.getPlayerShards(player.uniqueId, ShardType.ALL) - if ( - playerShards.shardsInBank == null || - playerShards.shardsInInventory == null || - playerShards.shardsInEnderChest == null - ) { - return -1 - } + val playerShards = + DiamondBankOG.postgreSQL.getAllShards(player.uniqueId).getOrElse { + return -1 + } // Withdraw everything if (shards == -1) { - val error = - DiamondBankOG.postgreSQL.subtractFromPlayerShards( - player.uniqueId, - playerShards.shardsInBank, - ShardType.BANK, - ) - if (error) { + DiamondBankOG.postgreSQL.subtractFromBankShards(player.uniqueId, playerShards.bank).getOrElse { handleError(player.uniqueId, shards, playerShards) player.sendMessage( DiamondBankOG.mm.deserialize( @@ -36,22 +25,18 @@ internal object WithdrawHelper { return -1 } - val notRemovedInventory = player.inventory.withdraw(playerShards.shardsInInventory) + val notRemovedInventory = player.inventory.withdraw(playerShards.inventory) - val notRemovedEnderChest = player.enderChest.withdraw(playerShards.shardsInEnderChest) + val notRemovedEnderChest = player.enderChest.withdraw(playerShards.enderChest) return notRemovedInventory + notRemovedEnderChest } - if (shards > playerShards.shardsInBank + playerShards.shardsInInventory + playerShards.shardsInEnderChest) { + if (shards > playerShards.bank + playerShards.inventory + playerShards.enderChest) { val diamonds = String.format("%.1f", floor((shards / 9.0) * 10) / 10.0) val totalDiamonds = String.format( "%.1f", - floor( - ((playerShards.shardsInBank + - playerShards.shardsInInventory + - playerShards.shardsInEnderChest) / 9.0) * 10 - ) / 10.0, + floor(((playerShards.bank + playerShards.inventory + playerShards.enderChest) / 9.0) * 10) / 10.0, ) player.sendMessage( DiamondBankOG.mm.deserialize( @@ -61,9 +46,8 @@ internal object WithdrawHelper { return -1 } - if (shards <= playerShards.shardsInBank) { - val error = DiamondBankOG.postgreSQL.subtractFromPlayerShards(player.uniqueId, shards, ShardType.BANK) - if (error) { + if (shards <= playerShards.bank) { + DiamondBankOG.postgreSQL.subtractFromBankShards(player.uniqueId, shards).getOrElse { handleError(player.uniqueId, shards, playerShards) player.sendMessage( DiamondBankOG.mm.deserialize( @@ -75,14 +59,8 @@ internal object WithdrawHelper { return 0 } - if (shards <= playerShards.shardsInBank + playerShards.shardsInInventory) { - val error = - DiamondBankOG.postgreSQL.subtractFromPlayerShards( - player.uniqueId, - playerShards.shardsInBank, - ShardType.BANK, - ) - if (error) { + if (shards <= playerShards.bank + playerShards.inventory) { + DiamondBankOG.postgreSQL.subtractFromBankShards(player.uniqueId, playerShards.bank).getOrElse { handleError(player.uniqueId, shards, playerShards) player.sendMessage( DiamondBankOG.mm.deserialize( @@ -92,17 +70,11 @@ internal object WithdrawHelper { return -1 } - val notRemoved = player.inventory.withdraw(shards - playerShards.shardsInBank) + val notRemoved = player.inventory.withdraw(shards - playerShards.bank) return notRemoved } - val error = - DiamondBankOG.postgreSQL.subtractFromPlayerShards( - player.uniqueId, - playerShards.shardsInBank, - ShardType.BANK, - ) - if (error) { + DiamondBankOG.postgreSQL.subtractFromBankShards(player.uniqueId, playerShards.bank).getOrElse { handleError(player.uniqueId, shards, playerShards) player.sendMessage( DiamondBankOG.mm.deserialize( @@ -112,10 +84,9 @@ internal object WithdrawHelper { return -1 } - val notRemovedInventory = player.inventory.withdraw(playerShards.shardsInInventory) + val notRemovedInventory = player.inventory.withdraw(playerShards.inventory) - val notRemovedEnderChest = - player.enderChest.withdraw(shards - (playerShards.shardsInBank + playerShards.shardsInInventory)) + val notRemovedEnderChest = player.enderChest.withdraw(shards - (playerShards.bank + playerShards.inventory)) return notRemovedInventory + notRemovedEnderChest } diff --git a/src/main/kotlin/net/trueog/diamondbankog/commands/Balance.kt b/src/main/kotlin/net/trueog/diamondbankog/commands/Balance.kt index 95b0736..88b0c3b 100644 --- a/src/main/kotlin/net/trueog/diamondbankog/commands/Balance.kt +++ b/src/main/kotlin/net/trueog/diamondbankog/commands/Balance.kt @@ -7,7 +7,6 @@ import kotlinx.coroutines.launch import net.trueog.diamondbankog.Config import net.trueog.diamondbankog.DiamondBankOG import net.trueog.diamondbankog.PlayerPrefix.getPrefix -import net.trueog.diamondbankog.PostgreSQL.ShardType import org.bukkit.Bukkit import org.bukkit.command.Command import org.bukkit.command.CommandExecutor @@ -61,24 +60,21 @@ internal class Balance : CommandExecutor { return@launch } - val balance = DiamondBankOG.postgreSQL.getPlayerShards(otherPlayer.uniqueId, ShardType.ALL) - if ( - balance.shardsInBank == null || - balance.shardsInInventory == null || - balance.shardsInEnderChest == null - ) { - sender.sendMessage( - DiamondBankOG.mm.deserialize( - "${Config.prefix}: Something went wrong while trying to get their balance." + val balance = + DiamondBankOG.postgreSQL.getAllShards(otherPlayer.uniqueId).getOrElse { + sender.sendMessage( + DiamondBankOG.mm.deserialize( + "${Config.prefix}: Something went wrong while trying to get their balance." + ) ) - ) - return@launch - } - val totalBalance = balance.shardsInBank + balance.shardsInInventory + balance.shardsInEnderChest + return@launch + } + + val totalBalance = balance.bank + balance.inventory + balance.enderChest val totalDiamonds = String.format("%.1f", floor((totalBalance / 9.0) * 10) / 10.0) - val bankDiamonds = String.format("%.1f", floor((balance.shardsInBank / 9.0) * 10) / 10.0) - val inventoryDiamonds = String.format("%.1f", floor((balance.shardsInInventory / 9.0) * 10) / 10.0) - val enderChestDiamonds = String.format("%.1f", floor((balance.shardsInEnderChest / 9.0) * 10) / 10.0) + val bankDiamonds = String.format("%.1f", floor((balance.bank / 9.0) * 10) / 10.0) + val inventoryDiamonds = String.format("%.1f", floor((balance.inventory / 9.0) * 10) / 10.0) + val enderChestDiamonds = String.format("%.1f", floor((balance.enderChest / 9.0) * 10) / 10.0) sender.sendMessage( DiamondBankOG.mm.deserialize( "Balance of ${getPrefix(otherPlayer.uniqueId)}${otherPlayer.name}:\n" + @@ -119,22 +115,23 @@ internal class Balance : CommandExecutor { } otherPlayer } - val balance = DiamondBankOG.postgreSQL.getPlayerShards(balancePlayer.uniqueId, ShardType.ALL) - if (balance.isNeededShardTypeNull(ShardType.ALL)) { - sender.sendMessage( - DiamondBankOG.mm.deserialize( - "${Config.prefix}: Something went wrong while trying to get ${ + val balance = + DiamondBankOG.postgreSQL.getAllShards(balancePlayer.uniqueId).getOrElse { + sender.sendMessage( + DiamondBankOG.mm.deserialize( + "${Config.prefix}: Something went wrong while trying to get ${ if (balancePlayer.uniqueId != sender.uniqueId) "their" else "your" } balance." + ) ) - ) - return@launch - } - val totalBalance = balance.shardsInBank!! + balance.shardsInInventory!! + balance.shardsInEnderChest!! + return@launch + } + + val totalBalance = balance.bank + balance.inventory + balance.enderChest val totalDiamonds = String.format("%.1f", floor((totalBalance / 9.0) * 10) / 10.0) - val bankDiamonds = String.format("%.1f", floor((balance.shardsInBank / 9.0) * 10) / 10.0) - val inventoryDiamonds = String.format("%.1f", floor((balance.shardsInInventory / 9.0) * 10) / 10.0) - val enderChestDiamonds = String.format("%.1f", floor((balance.shardsInEnderChest / 9.0) * 10) / 10.0) + val bankDiamonds = String.format("%.1f", floor((balance.bank / 9.0) * 10) / 10.0) + val inventoryDiamonds = String.format("%.1f", floor((balance.inventory / 9.0) * 10) / 10.0) + val enderChestDiamonds = String.format("%.1f", floor((balance.enderChest / 9.0) * 10) / 10.0) sender.sendMessage( DiamondBankOG.mm.deserialize( "${Config.prefix}: ${ diff --git a/src/main/kotlin/net/trueog/diamondbankog/commands/Balancetop.kt b/src/main/kotlin/net/trueog/diamondbankog/commands/Balancetop.kt index c0da8df..44ef128 100644 --- a/src/main/kotlin/net/trueog/diamondbankog/commands/Balancetop.kt +++ b/src/main/kotlin/net/trueog/diamondbankog/commands/Balancetop.kt @@ -73,16 +73,15 @@ internal class Balancetop : CommandExecutor { } if (player != null) { - val baltopWithUuid = DiamondBankOG.postgreSQL.getBaltopWithUuid(player.uniqueId) - if (baltopWithUuid == null) { - sender.sendMessage( - DiamondBankOG.mm.deserialize( - "${Config.prefix}: Something went wrong while trying to get the information for balancetop." + val baltopWithUuid = + DiamondBankOG.postgreSQL.getBaltopWithUuid(player.uniqueId).getOrElse { + sender.sendMessage( + DiamondBankOG.mm.deserialize( + "${Config.prefix}: Something went wrong while trying to get the information for balancetop." + ) ) - ) - return@launch - } - + return@launch + } val (baltop, offset) = baltopWithUuid var baltopMessage = "${Config.prefix} Top Balances:" @@ -112,24 +111,25 @@ internal class Balancetop : CommandExecutor { return@launch } - val baltop = DiamondBankOG.postgreSQL.getBaltop(offset) - if (baltop == null) { - sender.sendMessage( - DiamondBankOG.mm.deserialize( - "${Config.prefix}: Something went wrong while trying to get the information for balancetop." + val baltop = + DiamondBankOG.postgreSQL.getBaltop(offset).getOrElse { + sender.sendMessage( + DiamondBankOG.mm.deserialize( + "${Config.prefix}: Something went wrong while trying to get the information for balancetop." + ) ) - ) - return@launch - } - val numberOfRows = DiamondBankOG.postgreSQL.getNumberOfRows() - if (numberOfRows == null) { - sender.sendMessage( - DiamondBankOG.mm.deserialize( - "${Config.prefix}: Something went wrong while trying to get the information for balancetop." + return@launch + } + + val numberOfRows = + DiamondBankOG.postgreSQL.getNumberOfRows().getOrElse { + sender.sendMessage( + DiamondBankOG.mm.deserialize( + "${Config.prefix}: Something went wrong while trying to get the information for balancetop." + ) ) - ) - return@launch - } + return@launch + } if (index > ceil(numberOfRows / 9.0)) { sender.sendMessage( diff --git a/src/main/kotlin/net/trueog/diamondbankog/commands/Compress.kt b/src/main/kotlin/net/trueog/diamondbankog/commands/Compress.kt index 01955d1..377e323 100644 --- a/src/main/kotlin/net/trueog/diamondbankog/commands/Compress.kt +++ b/src/main/kotlin/net/trueog/diamondbankog/commands/Compress.kt @@ -241,7 +241,7 @@ internal class Compress : CommandExecutor { result.result } - TransactionLock.LockResult.Failed -> { + is TransactionLock.LockResult.Failed -> { sender.sendMessage( DiamondBankOG.mm.deserialize( "${Config.prefix}: You are currently blocked from using /deposit." diff --git a/src/main/kotlin/net/trueog/diamondbankog/commands/Deposit.kt b/src/main/kotlin/net/trueog/diamondbankog/commands/Deposit.kt index 54c460f..14ad460 100644 --- a/src/main/kotlin/net/trueog/diamondbankog/commands/Deposit.kt +++ b/src/main/kotlin/net/trueog/diamondbankog/commands/Deposit.kt @@ -70,15 +70,14 @@ internal class Deposit : CommandExecutor { } val playerInventoryShards = - DiamondBankOG.postgreSQL.getPlayerShards(sender.uniqueId, ShardType.INVENTORY).shardsInInventory - if (playerInventoryShards == null) { - sender.sendMessage( - DiamondBankOG.mm.deserialize( - "${Config.prefix}: Something went wrong while trying to get your balance." + DiamondBankOG.postgreSQL.getInventoryShards(sender.uniqueId).getOrElse { + sender.sendMessage( + DiamondBankOG.mm.deserialize( + "${Config.prefix}: Something went wrong while trying to get your balance." + ) ) - ) - return@launch - } + return@launch + } if (playerInventoryShards == 0) { sender.sendMessage( DiamondBankOG.mm.deserialize( @@ -152,8 +151,7 @@ internal class Deposit : CommandExecutor { ) } - val error = DiamondBankOG.postgreSQL.addToPlayerShards(sender.uniqueId, shards, ShardType.BANK) - if (error) { + DiamondBankOG.postgreSQL.addToPlayerShards(sender.uniqueId, shards, ShardType.BANK).getOrElse { handleError(sender.uniqueId, shards, PlayerShards(-1, playerInventoryShards, -1)) sender.sendMessage( DiamondBankOG.mm.deserialize( @@ -171,7 +169,7 @@ internal class Deposit : CommandExecutor { } } - TransactionLock.LockResult.Failed -> { + is TransactionLock.LockResult.Failed -> { sender.sendMessage( DiamondBankOG.mm.deserialize( "${Config.prefix}: You are currently blocked from using /deposit." @@ -188,8 +186,8 @@ internal class Deposit : CommandExecutor { ) ) - val error = - DiamondBankOG.postgreSQL.insertTransactionLog( + DiamondBankOG.postgreSQL + .insertTransactionLog( sender.uniqueId, shards, null, @@ -197,9 +195,7 @@ internal class Deposit : CommandExecutor { if (shards != originalShards) "Could not withdraw $originalShards shards, continued with $shards" else null, ) - if (error) { - handleError(sender.uniqueId, shards, null, null, true) - } + .getOrElse { handleError(sender.uniqueId, shards, null, null, true) } } return true } diff --git a/src/main/kotlin/net/trueog/diamondbankog/commands/Pay.kt b/src/main/kotlin/net/trueog/diamondbankog/commands/Pay.kt index 64808d1..dcf804d 100644 --- a/src/main/kotlin/net/trueog/diamondbankog/commands/Pay.kt +++ b/src/main/kotlin/net/trueog/diamondbankog/commands/Pay.kt @@ -149,17 +149,17 @@ internal class Pay : CommandExecutor { ) } - val error = - DiamondBankOG.postgreSQL.addToPlayerShards(receiver.uniqueId, shards, ShardType.BANK) - if (error) { - handleError(sender.uniqueId, shards, null, receiver.uniqueId) - sender.sendMessage( - DiamondBankOG.mm.deserialize( - "${Config.prefix}: A severe error has occurred. Please notify a staff member." + DiamondBankOG.postgreSQL + .addToPlayerShards(receiver.uniqueId, shards, ShardType.BANK) + .getOrElse { + handleError(sender.uniqueId, shards, null, receiver.uniqueId) + sender.sendMessage( + DiamondBankOG.mm.deserialize( + "${Config.prefix}: A severe error has occurred. Please notify a staff member." + ) ) - ) - return@tryWithLockSuspend true - } + return@tryWithLockSuspend true + } false } ) { @@ -169,7 +169,7 @@ internal class Pay : CommandExecutor { } } - TransactionLock.LockResult.Failed -> { + is TransactionLock.LockResult.Failed -> { sender.sendMessage( DiamondBankOG.mm.deserialize( "${Config.prefix}: You are currently blocked from using /pay." @@ -204,8 +204,8 @@ internal class Pay : CommandExecutor { ) } - val error = - DiamondBankOG.postgreSQL.insertTransactionLog( + DiamondBankOG.postgreSQL + .insertTransactionLog( sender.uniqueId, shards, receiver.uniqueId, @@ -213,9 +213,7 @@ internal class Pay : CommandExecutor { if (shards != originalShards) "Could not withdraw $originalShards shards, continued with $shards" else null, ) - if (error) { - handleError(sender.uniqueId, shards, null, receiver.uniqueId, true) - } + .getOrElse { handleError(sender.uniqueId, shards, null, receiver.uniqueId, true) } } return true } diff --git a/src/main/kotlin/net/trueog/diamondbankog/commands/SetBankBalance.kt b/src/main/kotlin/net/trueog/diamondbankog/commands/SetBankBalance.kt index 7cab567..92dd05e 100644 --- a/src/main/kotlin/net/trueog/diamondbankog/commands/SetBankBalance.kt +++ b/src/main/kotlin/net/trueog/diamondbankog/commands/SetBankBalance.kt @@ -74,8 +74,7 @@ internal class SetBankBalance : CommandExecutor { return@launch } - var error = DiamondBankOG.postgreSQL.setPlayerShards(player.uniqueId, balance, ShardType.BANK) - if (error) { + DiamondBankOG.postgreSQL.setPlayerShards(player.uniqueId, balance, ShardType.BANK).getOrElse { sender.sendMessage( DiamondBankOG.mm.deserialize( "${Config.prefix}: Something went wrong while trying to set that player's balance." @@ -83,6 +82,7 @@ internal class SetBankBalance : CommandExecutor { ) return@launch } + sender.sendMessage( DiamondBankOG.mm.deserialize( "${Config.prefix}: Successfully set the balance of ${ @@ -93,17 +93,15 @@ internal class SetBankBalance : CommandExecutor { ) ) - error = - DiamondBankOG.postgreSQL.insertTransactionLog( + DiamondBankOG.postgreSQL + .insertTransactionLog( player.uniqueId, balance, null, "Set Bank Balance", "Bank Balance set by ${if (sender is Player) "${sender.uniqueId}" else "console"}", ) - if (error) { - handleError(player.uniqueId, balance, null, null, true) - } + .getOrElse { handleError(player.uniqueId, balance, null, null, true) } } return true } diff --git a/src/main/kotlin/net/trueog/diamondbankog/commands/Withdraw.kt b/src/main/kotlin/net/trueog/diamondbankog/commands/Withdraw.kt index 7dc3777..a96ea2d 100644 --- a/src/main/kotlin/net/trueog/diamondbankog/commands/Withdraw.kt +++ b/src/main/kotlin/net/trueog/diamondbankog/commands/Withdraw.kt @@ -99,24 +99,20 @@ internal class Withdraw : CommandExecutor { shards = (split[0].toInt() * 9) + split[1].toInt() } - val result = + val lockResult = DiamondBankOG.transactionLock.tryWithLockSuspend(sender.uniqueId) { - val playerShards = DiamondBankOG.postgreSQL.getPlayerShards(sender.uniqueId, ShardType.ALL) - if ( - playerShards.shardsInBank == null || - playerShards.shardsInInventory == null || - playerShards.shardsInEnderChest == null - ) { - sender.sendMessage( - DiamondBankOG.mm.deserialize( - "${Config.prefix}: Something went wrong while trying to get your balance." + val playerShards = + DiamondBankOG.postgreSQL.getAllShards(sender.uniqueId).getOrElse { + sender.sendMessage( + DiamondBankOG.mm.deserialize( + "${Config.prefix}: Something went wrong while trying to get your balance." + ) ) - ) - return@tryWithLockSuspend true - } + return@tryWithLockSuspend true + } - val playerBankShards = playerShards.shardsInBank - val playerInventoryShards = playerShards.shardsInInventory + val playerBankShards = playerShards.bank + val playerInventoryShards = playerShards.inventory if (shards == -1) shards = playerBankShards @@ -164,9 +160,7 @@ internal class Withdraw : CommandExecutor { return@tryWithLockSuspend true } - var error = - DiamondBankOG.postgreSQL.subtractFromPlayerShards(sender.uniqueId, shards, ShardType.BANK) - if (error) { + DiamondBankOG.postgreSQL.subtractFromBankShards(sender.uniqueId, shards).getOrElse { handleError(sender.uniqueId, shards, PostgreSQL.PlayerShards(playerBankShards, -1, -1)) sender.sendMessage( DiamondBankOG.mm.deserialize( @@ -196,8 +190,7 @@ internal class Withdraw : CommandExecutor { return@tryWithLockSuspend true } - error = DiamondBankOG.postgreSQL.addToPlayerShards(sender.uniqueId, shards, ShardType.INVENTORY) - if (error) { + DiamondBankOG.postgreSQL.addToPlayerShards(sender.uniqueId, shards, ShardType.INVENTORY).getOrElse { handleError(sender.uniqueId, shards, playerShards) sender.sendMessage( DiamondBankOG.mm.deserialize( @@ -208,14 +201,14 @@ internal class Withdraw : CommandExecutor { } false } - when (result) { + when (lockResult) { is TransactionLock.LockResult.Acquired -> { - if (result.result) { + if (lockResult.result) { return@launch } } - TransactionLock.LockResult.Failed -> { + is TransactionLock.LockResult.Failed -> { sender.sendMessage( DiamondBankOG.mm.deserialize( "${Config.prefix}: You are currently blocked from using /withdraw." @@ -232,8 +225,7 @@ internal class Withdraw : CommandExecutor { ) ) - val error = DiamondBankOG.postgreSQL.insertTransactionLog(sender.uniqueId, shards, null, "Withdraw", null) - if (error) { + DiamondBankOG.postgreSQL.insertTransactionLog(sender.uniqueId, shards, null, "Withdraw", null).getOrElse { handleError(sender.uniqueId, shards, null, null, true) } }