New API and internal changes #9

Merged
SKBotNL merged 8 commits from master into master 2025-07-20 09:39:33 -04:00
18 changed files with 717 additions and 642 deletions

No files matched your search

-13
View File
@@ -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<AbstractArchiveTask>().configureEach {
isReproducibleFileOrder = true
}
publishing {
publications {
create<MavenPublication>("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 {
@@ -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(
@@ -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<Unit> {
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<Unit> {
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<Unit> {
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<Unit> {
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<PlayerShards> {
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<PlayerShards> {
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<Map<UUID?, Int>> {
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
}
}
}
@@ -25,14 +25,13 @@ class DiamondBankAPIKotlin(private var postgreSQL: PostgreSQL) {
): Result<Unit> {
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<PlayerShards> {
suspend fun blockingGetBankShards(uuid: UUID): Result<Int> = 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<Int> =
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<Int> =
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<Int> = 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<PlayerShards> {
if (DiamondBankOG.economyDisabled) return Result.failure(DiamondBankException.EconomyDisabledException)
return postgreSQL.getAllShards(uuid)
}
private suspend fun blockingGetShardTypeShards(uuid: UUID, type: ShardType): Result<Int> {
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<Int>(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<PlayerShards> {
suspend fun getAllShards(uuid: UUID): Result<PlayerShards> {
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<Int>(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<Int> {
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<Int>(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<Map<UUID?, Int>> {
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
}
}
}
@@ -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
}
@@ -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 ""
}
"""
@@ -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
}
}
}
}
@@ -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}<reset>: The change of $leftOver <aqua>Diamond ${if (leftOver == 1) "Shard" else "Shards"} <reset>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}<reset>: The change of ${leftOver - inventoryLeftOver} <aqua>Diamond ${if (leftOver == 1) "Shard" else "Shards"} <reset>has been added to your inventory, and the remaining $inventoryLeftOver <aqua>Diamond ${if (leftOver == 1) "Shard" else "Shards"} <reset> 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}<reset>: <red>Something went wrong while trying to recount the <aqua>Diamonds<red> 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}<reset>: <red>Something went wrong while trying to recount the <aqua>Diamonds<red> amount in your inventory, try opening and closing your inventory to force a recount."
)
)
)
}
}
}
}
}
@@ -12,11 +12,19 @@ import kotlinx.coroutines.future.await
class PostgreSQL {
lateinit var pool: ConnectionPool<PostgreSQLConnection>
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<Unit> {
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<Unit> {
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<Unit> {
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<Int> {
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<PlayerShards> {
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<Int> {
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<UUID?, Int>? {
suspend fun getBaltop(offset: Int): Result<Map<UUID?, Int>> {
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<Map<UUID?, Int>, Long>? {
suspend fun getBaltopWithUuid(uuid: UUID): Result<Pair<Map<UUID?, Int>, 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<Long> {
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<Unit> {
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)
}
}
@@ -14,7 +14,7 @@ internal class TransactionLock {
}
fun <T> 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 <T> 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 <T> tryWithLock(uuid: UUID, block: () -> T): LockResult<T> {
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 <T> tryWithLockSuspend(uuid: UUID, block: suspend () -> T): LockResult<T> {
val lock = locks.computeIfAbsent(uuid) { Semaphore(1) }
val lock = locks.computeIfAbsent(uuid) { Semaphore(1, true) }
return if (lock.tryAcquire()) {
try {
LockResult.Acquired(block())
@@ -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
}
@@ -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}<reset>: <red>Something went wrong while trying to get their balance."
val balance =
DiamondBankOG.postgreSQL.getAllShards(otherPlayer.uniqueId).getOrElse {
sender.sendMessage(
DiamondBankOG.mm.deserialize(
"${Config.prefix}<reset>: <red>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(
"<green>Balance of ${getPrefix(otherPlayer.uniqueId)}${otherPlayer.name}<reset><green>:\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}<reset>: <red>Something went wrong while trying to get ${
val balance =
DiamondBankOG.postgreSQL.getAllShards(balancePlayer.uniqueId).getOrElse {
sender.sendMessage(
DiamondBankOG.mm.deserialize(
"${Config.prefix}<reset>: <red>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}<reset>: <green>${
@@ -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}<reset>: <red>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}<reset>: <red>Something went wrong while trying to get the information for balancetop."
)
)
)
return@launch
}
return@launch
}
val (baltop, offset) = baltopWithUuid
var baltopMessage = "${Config.prefix} <aqua>Top Balances:<reset>"
@@ -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}<reset>: <red>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}<reset>: <red>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}<reset>: <red>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}<reset>: <red>Something went wrong while trying to get the information for balancetop."
)
)
)
return@launch
}
return@launch
}
if (index > ceil(numberOfRows / 9.0)) {
sender.sendMessage(
@@ -241,7 +241,7 @@ internal class Compress : CommandExecutor {
result.result
}
TransactionLock.LockResult.Failed -> {
is TransactionLock.LockResult.Failed -> {
sender.sendMessage(
DiamondBankOG.mm.deserialize(
"${Config.prefix}<reset>: <red>You are currently blocked from using /deposit."
@@ -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}<reset>: <red>Something went wrong while trying to get your balance."
DiamondBankOG.postgreSQL.getInventoryShards(sender.uniqueId).getOrElse {
sender.sendMessage(
DiamondBankOG.mm.deserialize(
"${Config.prefix}<reset>: <red>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}<reset>: <red>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
}
@@ -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}<reset>: <red>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}<reset>: <red>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}<reset>: <red>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
}
@@ -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}<reset>: <red>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}<reset>: <green>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
}
@@ -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}<reset>: <red>Something went wrong while trying to get your balance."
val playerShards =
DiamondBankOG.postgreSQL.getAllShards(sender.uniqueId).getOrElse {
sender.sendMessage(
DiamondBankOG.mm.deserialize(
"${Config.prefix}<reset>: <red>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}<reset>: <red>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)
}
}