Add diamondsToShards API and API docs #21

Merged
SKBotNL merged 3 commits from master into master 2026-02-12 14:00:37 -05:00
11 changed files with 253 additions and 31 deletions

No files matched your search

+3 -1
View File
@@ -1,7 +1,9 @@
# DiamondBank-OG
A FOSS and reliable Diamond Economy plugin for Spigot inspired by [The Diamond Bank](https://www.spigotmc.org/resources/the-diamond-bank.72020/).\
Maintained for TrueOG.
Maintained for TrueOG Network.
**For developers: see the [API README](src/main/kotlin/net/trueog/diamondbankog/api/README.md).**
## PostgreSQL
This plugin uses PostgreSQL which needs to be set up first. The Arch Linux wiki has a [pretty good guide](https://wiki.archlinux.org/title/PostgreSQL#Initial_configuration).\
@@ -3,6 +3,7 @@ package net.trueog.diamondbankog
import java.util.*
import net.trueog.diamondbankog.DiamondBankException.InsufficientFundsException
import net.trueog.diamondbankog.DiamondBankException.InsufficientInventorySpaceException
import net.trueog.diamondbankog.DiamondBankException.MoreThanOneDecimalDigitException
import net.trueog.diamondbankog.DiamondBankOG.Companion.balanceManager
object CommonOperations {
@@ -33,4 +34,12 @@ object CommonOperations {
}
return Result.success(Unit)
}
fun diamondsToShards(diamonds: Float): Result<Long> {
val split = diamonds.toString().split('.')
if (split[1].length > 1) {
return Result.failure(MoreThanOneDecimalDigitException())
}
return Result.success((split[0].toLong() * 9) + split[1].toLong())
}
}
@@ -17,5 +17,7 @@ sealed class DiamondBankException(message: String) : Exception(message) {
class InsufficientInventorySpaceException : DiamondBankException("Insufficient inventory space for the change")
class MoreThanOneDecimalDigitException : DiamondBankException("More than one decimal digit")
class InvalidArgumentException : Exception()
}
@@ -5,6 +5,8 @@ import net.kyori.adventure.text.minimessage.MiniMessage
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver
import net.kyori.adventure.text.minimessage.tag.standard.StandardTags
import net.luckperms.api.LuckPerms
import net.trueog.diamondbankog.api.DiamondBankAPIJava
import net.trueog.diamondbankog.api.DiamondBankAPIKotlin
import net.trueog.diamondbankog.commands.*
import net.trueog.diamondbankog.commands.AutoCompress
import net.trueog.diamondbankog.commands.AutoDeposit
@@ -35,7 +35,6 @@ internal object InventoryExtensions {
val lockMap: MutableSet<PlayerInventory> = Collections.newSetFromMap(Collections.synchronizedMap(WeakHashMap()))
/** @return true is the inventory was locked, else false */
fun PlayerInventory.lock(): Boolean {
val added = lockMap.add(this)
if (!added) throw IllegalStateException("Inventory was already locked")
@@ -1,8 +1,10 @@
package net.trueog.diamondbankog
package net.trueog.diamondbankog.api
import java.util.*
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.runBlocking
import net.trueog.diamondbankog.CommonOperations
import net.trueog.diamondbankog.DiamondBankException
import net.trueog.diamondbankog.DiamondBankException.*
import net.trueog.diamondbankog.DiamondBankOG.Companion.balanceManager
import net.trueog.diamondbankog.DiamondBankOG.Companion.economyDisabled
@@ -11,7 +13,9 @@ import net.trueog.diamondbankog.DiamondBankOG.Companion.transactionLock
import net.trueog.diamondbankog.ErrorHandler.handleError
import net.trueog.diamondbankog.InventoryExtensions.lock
import net.trueog.diamondbankog.InventoryExtensions.unlock
import net.trueog.diamondbankog.InventorySnapshot
import net.trueog.diamondbankog.MainThreadBlock.runOnMainThread
import net.trueog.diamondbankog.PlayerBalanceChangedListener
import net.trueog.diamondbankog.PostgreSQL.PlayerShards
import net.trueog.diamondbankog.PostgreSQL.ShardType
import org.bukkit.Bukkit
@@ -289,8 +293,18 @@ class DiamondBankAPIJava {
}
}
/** Register a PlayerBalanceChangedListener to listen for player balance changes */
@Suppress("unused")
fun registerEventListener(eventListener: PlayerBalanceChangedListener) {
eventManager.register(eventListener)
}
/**
* Converts a Diamond value to Shards
*
* @throws MoreThanOneDecimalDigitException
*/
@Throws(MoreThanOneDecimalDigitException::class)
@Suppress("unused")
fun diamondsToShards(diamonds: Float): Long = CommonOperations.diamondsToShards(diamonds).getOrThrow()
}
@@ -1,7 +1,8 @@
package net.trueog.diamondbankog
package net.trueog.diamondbankog.api
import java.util.*
import kotlinx.coroutines.DelicateCoroutinesApi
import net.trueog.diamondbankog.CommonOperations
import net.trueog.diamondbankog.DiamondBankException.*
import net.trueog.diamondbankog.DiamondBankOG.Companion.balanceManager
import net.trueog.diamondbankog.DiamondBankOG.Companion.economyDisabled
@@ -10,7 +11,9 @@ import net.trueog.diamondbankog.DiamondBankOG.Companion.transactionLock
import net.trueog.diamondbankog.ErrorHandler.handleError
import net.trueog.diamondbankog.InventoryExtensions.lock
import net.trueog.diamondbankog.InventoryExtensions.unlock
import net.trueog.diamondbankog.InventorySnapshot
import net.trueog.diamondbankog.MainThreadBlock.runOnMainThread
import net.trueog.diamondbankog.PlayerBalanceChangedListener
import net.trueog.diamondbankog.PostgreSQL.PlayerShards
import net.trueog.diamondbankog.PostgreSQL.ShardType
import org.bukkit.Bukkit
@@ -217,4 +220,8 @@ class DiamondBankAPIKotlin {
fun registerEventListener(eventListener: PlayerBalanceChangedListener) {
eventManager.register(eventListener)
}
/** Converts a Diamond value to Shards */
@Suppress("unused")
fun diamondsToShards(diamonds: Float): Result<Long> = CommonOperations.diamondsToShards(diamonds)
}
@@ -0,0 +1,188 @@
# DiamondBank-OG API
## Getting started
In your `onEnable` function:\
Kotlin:
```kotlin
val diamondBankAPIProvider = server.servicesManager.getRegistration(DiamondBankAPIKotlin::class.java)
if (diamondBankAPIProvider == null) {
logger.severe("DiamondBank-OG API is null")
Bukkit.getPluginManager().disablePlugin(this)
return
}
val diamondBankAPI = diamondBankAPIProvider.getProvider()
```
Java:
```java
final RegisteredServiceProvider<DiamondBankAPIJava> provider = getServer().getServicesManager().getRegistration(DiamondBankAPIJava.class);
if (provider == null) {
getLogger().severe("DiamondBank-OG API is null – disabling plugin.");
Bukkit.getPluginManager().disablePlugin(this);
return;
}
```
## Available functions
> [!IMPORTANT]
> Always convert Diamonds to Shards before using the API using [`diamondsToShards`](#diamondstoshards)
Exceptions are only applicable when using the Java API, when using the Kotlin API the function will return a `Result` instead.
### addToPlayerShards
```kotlin
/**
* WARNING: if the player has a transaction lock applied this function will wait until its released.
*
* This function also blocks for the database call, this is so you don't have to manually run .get() on a
* CompletableFuture
*
* @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.DatabaseException
*/
fun addToPlayerBankShards(uuid: UUID, shards: Long, transactionReason: String, notes: String?)
```
### subtractFromPlayerBankShards
```kotlin
/**
* WARNING: if the player has a transaction lock applied this function will wait until its released
*
* This function also blocks for the database call, this is so you don't have to manually run .get() on a
* CompletableFuture
*
* @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.DatabaseException
* @throws DiamondBankException.InsufficientBalanceException
*/
fun subtractFromPlayerBankShards(uuid: UUID, shards: Long, transactionReason: String, notes: String?)
```
### getBankShards
```kotlin
/**
* WARNING: if the player has a transaction lock applied this function will wait until its released
*
* This function also blocks for the database call, this is so you don't have to manually run .get() on a
* CompletableFuture
*
* @throws DiamondBankException.EconomyDisabledException
* @throws DiamondBankException.DatabaseException
*/
fun getBankShards(uuid: UUID): Long
```
### getInventoryShards
```kotlin
/**
* WARNING: if the player has a transaction lock applied this function will wait until its released
*
* This function also blocks for the database call, this is so you don't have to manually run .get() on a
* CompletableFuture
*
* @throws DiamondBankException.EconomyDisabledException
* @throws DiamondBankException.DatabaseException
*/
fun getInventoryShards(uuid: UUID): Long
```
### getEnderChestShards
```kotlin
/**
* WARNING: if the player has a transaction lock applied this function will wait until its released
*
* This function also blocks for the database call, this is so you don't have to manually run .get() on a
* CompletableFuture
*
* @throws DiamondBankException.EconomyDisabledException
* @throws DiamondBankException.DatabaseException
*/
fun getEnderChestShards(uuid: UUID): Long
```
### getTotalShards
```kotlin
/**
* WARNING: if the player has a transaction lock applied this function will wait until its released
*
* This function also blocks for the database call, this is so you don't have to manually run .get() on a
* CompletableFuture
*
* @throws DiamondBankException.EconomyDisabledException
* @throws DiamondBankException.DatabaseException
*/
fun getTotalShards(uuid: UUID): Long
```
### getBaltop
```kotlin
/**
* WARNING: if the player has a transaction lock applied this function will wait until its released
*
* This function also blocks for the database call, this is so you don't have to manually run .get() on a
* CompletableFuture
*
* @throws DiamondBankException.EconomyDisabledException
* @throws DiamondBankException.DatabaseException
*/
fun getBaltop(offset: Int): Map<UUID?, Long>
```
### consumeFromPlayer
```kotlin
/**
* WARNING: if the player has a transaction lock applied this function will wait until its released
*
* This function also blocks for the database call, this is so you don't have to manually run .get() on a
* CompletableFuture
*
* @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.InsufficientFundsException
* @throws DiamondBankException.InsufficientInventorySpaceException
* @throws DiamondBankException.DatabaseException
*/
fun consumeFromPlayer(uuid: UUID, shards: Long, transactionReason: String, notes: String?)
```
### playerPayPlayer
```kotlin
/**
* WARNING: if the player has a transaction lock applied this function will wait until its released
*
* This function also blocks for the database call, this is so you don't have to manually run .get() on a
* CompletableFuture
*
* @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.PayerNotOnlineException
* @throws DiamondBankException.InsufficientFundsException
* @throws DiamondBankException.InsufficientInventorySpaceException
* @throws DiamondBankException.DatabaseException
*/
fun playerPayPlayer(payerUuid: UUID, receiverUuid: UUID, shards: Long, transactionReason: String, notes: String?)
```
### registerEventListener
```kotlin
/**
* Register a PlayerBalanceChangedListener to listen for player balance changes
*/
fun registerEventListener(eventListener: PlayerBalanceChangedListener)
```
### diamondsToShards
```kotlin
/**
* Converts a Diamond value to Shards
*
* @throws DiamondBankException.MoreThanOneDecimalDigitException
*/
fun diamondsToShards(diamonds: Float): Long
```
@@ -3,6 +3,7 @@ package net.trueog.diamondbankog.commands
import kotlin.math.floor
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.launch
import net.trueog.diamondbankog.CommonOperations
import net.trueog.diamondbankog.DiamondBankOG.Companion.balanceManager
import net.trueog.diamondbankog.DiamondBankOG.Companion.config
import net.trueog.diamondbankog.DiamondBankOG.Companion.mm
@@ -59,16 +60,15 @@ internal class Deposit : CommandExecutor {
sender.sendMessage(mm.deserialize("${config.prefix}<reset>: <red>Invalid argument."))
return true
}
val split = amount.toString().split(".")
if (split[1].length > 1) {
sender.sendMessage(
mm.deserialize(
"${config.prefix}<reset>: <red><aqua>Diamonds<red> can only have one decimal digit. Issue /diamondbankhelp for more information."
shards =
CommonOperations.diamondsToShards(amount).getOrElse {
sender.sendMessage(
mm.deserialize(
"${config.prefix}<reset>: <red><aqua>Diamonds<red> can only have one decimal digit. Issue /diamondbankhelp for more information."
)
)
)
return true
}
shards = (split[0].toLong() * 9) + split[1].toLong()
return true
}
}
scope.launch {
@@ -82,16 +82,15 @@ internal class Pay : CommandExecutor {
sender.sendMessage(mm.deserialize("${config.prefix}<reset>: <red>Invalid argument."))
return true
}
val split = amount.toString().split(".")
if (split[1].length > 1) {
sender.sendMessage(
mm.deserialize(
"${config.prefix}<reset>: <red><aqua>Diamonds<red> can only have one decimal digit. Issue /diamondbankhelp for more information."
val shards =
CommonOperations.diamondsToShards(amount).getOrElse {
sender.sendMessage(
mm.deserialize(
"${config.prefix}<reset>: <red><aqua>Diamonds<red> can only have one decimal digit. Issue /diamondbankhelp for more information."
)
)
)
return true
}
val shards = (split[0].toLong() * 9) + split[1].toLong()
return true
}
scope.launch {
when (
@@ -3,6 +3,7 @@ package net.trueog.diamondbankog.commands
import kotlin.math.floor
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.launch
import net.trueog.diamondbankog.CommonOperations
import net.trueog.diamondbankog.DiamondBankOG.Companion.balanceManager
import net.trueog.diamondbankog.DiamondBankOG.Companion.config
import net.trueog.diamondbankog.DiamondBankOG.Companion.mm
@@ -60,16 +61,15 @@ internal class Withdraw : CommandExecutor {
sender.sendMessage(mm.deserialize("${config.prefix}<reset>: <red>Invalid argument."))
return true
}
val split = amount.toString().split(".")
if (split[1].length > 1) {
sender.sendMessage(
mm.deserialize(
"${config.prefix}<reset>: <red><aqua>Diamonds<red> can only have one decimal digit. Issue /diamondbankhelp for more information."
shards =
CommonOperations.diamondsToShards(amount).getOrElse {
sender.sendMessage(
mm.deserialize(
"${config.prefix}<reset>: <red><aqua>Diamonds<red> can only have one decimal digit. Issue /diamondbankhelp for more information."
)
)
)
return true
}
shards = (split[0].toLong() * 9) + split[1].toLong()
return true
}
}
sender.inventory.lock()