1
0
Fork 0
mirror of https://github.com/xHyroM/lighteco.git synced 2024-09-19 21:03:18 +02:00

feat: handle maximum balance

This commit is contained in:
Jozef Steinhübl 2023-10-05 17:31:52 +02:00
parent f4d4bbe856
commit 1e86142a58
No known key found for this signature in database
GPG key ID: E944BC293F5FF7E7
13 changed files with 132 additions and 23 deletions

View file

@ -0,0 +1,7 @@
package dev.xhyrom.lighteco.api.exception;
public class CannotBeGreaterThan extends IllegalArgumentException {
public CannotBeGreaterThan(String message) {
super(message);
}
}

View file

@ -0,0 +1,7 @@
package dev.xhyrom.lighteco.api.exception;
public class CannotBeNegative extends IllegalArgumentException {
public CannotBeNegative(String message) {
super(message);
}
}

View file

@ -7,6 +7,7 @@ import dev.jorel.commandapi.arguments.OfflinePlayerArgument;
import dev.jorel.commandapi.executors.CommandArguments; import dev.jorel.commandapi.executors.CommandArguments;
import dev.xhyrom.lighteco.bukkit.chat.BukkitCommandSender; import dev.xhyrom.lighteco.bukkit.chat.BukkitCommandSender;
import dev.xhyrom.lighteco.bukkit.manager.BukkitCommandManager; import dev.xhyrom.lighteco.bukkit.manager.BukkitCommandManager;
import dev.xhyrom.lighteco.bukkit.util.Util;
import dev.xhyrom.lighteco.common.model.currency.Currency; import dev.xhyrom.lighteco.common.model.currency.Currency;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
@ -27,8 +28,8 @@ public class GiveCommand implements Command {
.withArguments( .withArguments(
new OfflinePlayerArgument("target"), new OfflinePlayerArgument("target"),
currency.getProxy().fractionalDigits() > 0 currency.getProxy().fractionalDigits() > 0
? new DoubleArgument("amount", 1) ? new DoubleArgument("amount", 1, Util.bigDecimalToDouble(this.manager.plugin.getConfig().maximumBalance))
: new IntegerArgument("amount", 1) : new IntegerArgument("amount", 1, this.manager.plugin.getConfig().maximumBalance.intValue())
) )
.executes((sender, args) -> { .executes((sender, args) -> {
this.handleGive(sender, args, currency); this.handleGive(sender, args, currency);

View file

@ -7,6 +7,7 @@ import dev.jorel.commandapi.arguments.OfflinePlayerArgument;
import dev.jorel.commandapi.executors.CommandArguments; import dev.jorel.commandapi.executors.CommandArguments;
import dev.xhyrom.lighteco.bukkit.chat.BukkitCommandSender; import dev.xhyrom.lighteco.bukkit.chat.BukkitCommandSender;
import dev.xhyrom.lighteco.bukkit.manager.BukkitCommandManager; import dev.xhyrom.lighteco.bukkit.manager.BukkitCommandManager;
import dev.xhyrom.lighteco.bukkit.util.Util;
import dev.xhyrom.lighteco.common.model.currency.Currency; import dev.xhyrom.lighteco.common.model.currency.Currency;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
@ -27,8 +28,8 @@ public class PayCommand implements Command {
.withArguments( .withArguments(
new OfflinePlayerArgument("target"), new OfflinePlayerArgument("target"),
currency.getProxy().fractionalDigits() > 0 currency.getProxy().fractionalDigits() > 0
? new DoubleArgument("amount", 1) ? new DoubleArgument("amount", 1, Util.bigDecimalToDouble(this.manager.plugin.getConfig().maximumBalance))
: new IntegerArgument("amount", 1) : new IntegerArgument("amount", 1, this.manager.plugin.getConfig().maximumBalance.intValue())
) )
.executesPlayer((sender, args) -> { .executesPlayer((sender, args) -> {
this.handlePay(sender, args, currency); this.handlePay(sender, args, currency);

View file

@ -7,6 +7,7 @@ import dev.jorel.commandapi.arguments.OfflinePlayerArgument;
import dev.jorel.commandapi.executors.CommandArguments; import dev.jorel.commandapi.executors.CommandArguments;
import dev.xhyrom.lighteco.bukkit.chat.BukkitCommandSender; import dev.xhyrom.lighteco.bukkit.chat.BukkitCommandSender;
import dev.xhyrom.lighteco.bukkit.manager.BukkitCommandManager; import dev.xhyrom.lighteco.bukkit.manager.BukkitCommandManager;
import dev.xhyrom.lighteco.bukkit.util.Util;
import dev.xhyrom.lighteco.common.model.currency.Currency; import dev.xhyrom.lighteco.common.model.currency.Currency;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
@ -27,8 +28,8 @@ public class SetCommand implements Command {
.withArguments( .withArguments(
new OfflinePlayerArgument("target"), new OfflinePlayerArgument("target"),
currency.getProxy().fractionalDigits() > 0 currency.getProxy().fractionalDigits() > 0
? new DoubleArgument("amount", 0) ? new DoubleArgument("amount", 0, Util.bigDecimalToDouble(this.manager.plugin.getConfig().maximumBalance))
: new IntegerArgument("amount", 0) : new IntegerArgument("amount", 0, this.manager.plugin.getConfig().maximumBalance.intValue())
) )
.executes((sender, args) -> { .executes((sender, args) -> {
this.handleSet(sender, args, currency); this.handleSet(sender, args, currency);

View file

@ -7,6 +7,7 @@ import dev.jorel.commandapi.arguments.OfflinePlayerArgument;
import dev.jorel.commandapi.executors.CommandArguments; import dev.jorel.commandapi.executors.CommandArguments;
import dev.xhyrom.lighteco.bukkit.chat.BukkitCommandSender; import dev.xhyrom.lighteco.bukkit.chat.BukkitCommandSender;
import dev.xhyrom.lighteco.bukkit.manager.BukkitCommandManager; import dev.xhyrom.lighteco.bukkit.manager.BukkitCommandManager;
import dev.xhyrom.lighteco.bukkit.util.Util;
import dev.xhyrom.lighteco.common.model.currency.Currency; import dev.xhyrom.lighteco.common.model.currency.Currency;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
@ -27,8 +28,8 @@ public class TakeCommand implements Command {
.withArguments( .withArguments(
new OfflinePlayerArgument("target"), new OfflinePlayerArgument("target"),
currency.getProxy().fractionalDigits() > 0 currency.getProxy().fractionalDigits() > 0
? new DoubleArgument("amount", 1) ? new DoubleArgument("amount", 1, Util.bigDecimalToDouble(this.manager.plugin.getConfig().maximumBalance))
: new IntegerArgument("amount", 1) : new IntegerArgument("amount", 1, this.manager.plugin.getConfig().maximumBalance.intValue())
) )
.executes((sender, args) -> { .executes((sender, args) -> {
this.handleTake(sender, args, currency); this.handleTake(sender, args, currency);

View file

@ -0,0 +1,19 @@
package dev.xhyrom.lighteco.bukkit.util;
import lombok.experimental.UtilityClass;
import java.math.BigDecimal;
@UtilityClass
public class Util {
public double bigDecimalToDouble(final BigDecimal value) {
double amount = value.doubleValue();
// Don't return bigger balance than user actually has
if (BigDecimal.valueOf(amount).compareTo(value) > 0) {
amount = Math.nextAfter(amount, Double.NEGATIVE_INFINITY);
}
return amount;
}
}

View file

@ -7,6 +7,8 @@ import eu.okaeri.configs.OkaeriConfig;
import eu.okaeri.configs.annotation.Comment; import eu.okaeri.configs.annotation.Comment;
import eu.okaeri.configs.annotation.Header; import eu.okaeri.configs.annotation.Header;
import java.math.BigDecimal;
@Header("LightEco configuration file.") @Header("LightEco configuration file.")
@Header("") @Header("")
public class Config extends OkaeriConfig { public class Config extends OkaeriConfig {
@ -21,6 +23,10 @@ public class Config extends OkaeriConfig {
@Comment("Save interval to storage in seconds.") @Comment("Save interval to storage in seconds.")
public long saveInterval = 5L; public long saveInterval = 5L;
@Comment("Maximum allowed balance.")
@Comment("If you want to change this value, you must also change the data type in the database.")
public BigDecimal maximumBalance = BigDecimal.valueOf(999999999999999.99);
@Comment("Messages") @Comment("Messages")
public MessageConfig messages = new MessageConfig(); public MessageConfig messages = new MessageConfig();

View file

@ -18,4 +18,5 @@ public class CurrencyMessageConfig extends OkaeriConfig {
public String wait = "<red>Please wait a moment before using this command again."; public String wait = "<red>Please wait a moment before using this command again.";
public String notEnoughMoney = "<red>You don't have enough money!"; public String notEnoughMoney = "<red>You don't have enough money!";
public String cannotPaySelf = "<red>You cannot pay yourself!"; public String cannotPaySelf = "<red>You cannot pay yourself!";
public String cannotBeGreaterThan = "<red>Amount cannot be greater than <gold><max>";
} }

View file

@ -1,5 +1,6 @@
package dev.xhyrom.lighteco.common.manager.command; package dev.xhyrom.lighteco.common.manager.command;
import dev.xhyrom.lighteco.api.exception.CannotBeGreaterThan;
import dev.xhyrom.lighteco.common.config.message.CurrencyMessageConfig; import dev.xhyrom.lighteco.common.config.message.CurrencyMessageConfig;
import dev.xhyrom.lighteco.common.model.chat.CommandSender; import dev.xhyrom.lighteco.common.model.chat.CommandSender;
import dev.xhyrom.lighteco.common.model.currency.Currency; import dev.xhyrom.lighteco.common.model.currency.Currency;
@ -101,7 +102,19 @@ public abstract class AbstractCommandManager implements CommandManager {
addToMustWait(sender.getUniqueId(), target.getUniqueId()); addToMustWait(sender.getUniqueId(), target.getUniqueId());
amount = amount.setScale(currency.getProxy().fractionalDigits(), RoundingMode.DOWN); amount = amount.setScale(currency.getProxy().fractionalDigits(), RoundingMode.DOWN);
target.setBalance(currency, amount); try {
target.setBalance(currency, amount);
} catch (CannotBeGreaterThan e) {
removeFromMustWait(target.getUniqueId(), sender.getUniqueId());
sender.sendMessage(
miniMessage.deserialize(
this.getConfig(currency).cannotBeGreaterThan,
Placeholder.parsed("max", this.plugin.getConfig().maximumBalance.toPlainString())
)
);
return;
}
sender.sendMessage( sender.sendMessage(
miniMessage.deserialize( miniMessage.deserialize(
@ -120,7 +133,19 @@ public abstract class AbstractCommandManager implements CommandManager {
addToMustWait(sender.getUniqueId(), target.getUniqueId()); addToMustWait(sender.getUniqueId(), target.getUniqueId());
amount = amount.setScale(currency.getProxy().fractionalDigits(), RoundingMode.DOWN); amount = amount.setScale(currency.getProxy().fractionalDigits(), RoundingMode.DOWN);
target.deposit(currency, amount); try {
target.deposit(currency, amount);
} catch (CannotBeGreaterThan e) {
removeFromMustWait(target.getUniqueId(), sender.getUniqueId());
sender.sendMessage(
miniMessage.deserialize(
this.getConfig(currency).cannotBeGreaterThan,
Placeholder.parsed("max", this.plugin.getConfig().maximumBalance.toPlainString())
)
);
return;
}
sender.sendMessage( sender.sendMessage(
miniMessage.deserialize( miniMessage.deserialize(
@ -140,7 +165,19 @@ public abstract class AbstractCommandManager implements CommandManager {
addToMustWait(sender.getUniqueId(), target.getUniqueId()); addToMustWait(sender.getUniqueId(), target.getUniqueId());
amount = amount.setScale(currency.getProxy().fractionalDigits(), RoundingMode.DOWN); amount = amount.setScale(currency.getProxy().fractionalDigits(), RoundingMode.DOWN);
target.withdraw(currency, amount); try {
target.withdraw(currency, amount);
} catch (CannotBeGreaterThan e) {
removeFromMustWait(target.getUniqueId(), sender.getUniqueId());
sender.sendMessage(
miniMessage.deserialize(
this.getConfig(currency).cannotBeGreaterThan,
Placeholder.parsed("max", this.plugin.getConfig().maximumBalance.toPlainString())
)
);
return;
}
sender.sendMessage( sender.sendMessage(
miniMessage.deserialize( miniMessage.deserialize(
@ -186,8 +223,20 @@ public abstract class AbstractCommandManager implements CommandManager {
// subtract tax from amount // subtract tax from amount
BigDecimal taxedAmount = amount.subtract(tax); BigDecimal taxedAmount = amount.subtract(tax);
target.deposit(currency, taxedAmount); try {
user.withdraw(currency, amount); target.deposit(currency, taxedAmount);
user.withdraw(currency, amount);
} catch (CannotBeGreaterThan e) {
removeFromMustWait(target.getUniqueId(), sender.getUniqueId());
sender.sendMessage(
miniMessage.deserialize(
this.getConfig(currency).cannotBeGreaterThan,
Placeholder.parsed("max", this.plugin.getConfig().maximumBalance.toPlainString())
)
);
return;
}
String template = tax.compareTo(BigDecimal.ZERO) > 0 String template = tax.compareTo(BigDecimal.ZERO) > 0
? this.getConfig(currency).payWithTax ? this.getConfig(currency).payWithTax

View file

@ -1,5 +1,7 @@
package dev.xhyrom.lighteco.common.model.user; package dev.xhyrom.lighteco.common.model.user;
import dev.xhyrom.lighteco.api.exception.CannotBeGreaterThan;
import dev.xhyrom.lighteco.api.exception.CannotBeNegative;
import dev.xhyrom.lighteco.common.api.impl.ApiUser; import dev.xhyrom.lighteco.common.api.impl.ApiUser;
import dev.xhyrom.lighteco.common.cache.RedisBackedMap; import dev.xhyrom.lighteco.common.cache.RedisBackedMap;
import dev.xhyrom.lighteco.common.model.currency.Currency; import dev.xhyrom.lighteco.common.model.currency.Currency;
@ -46,13 +48,17 @@ public class User {
return balances.getOrDefault(currency, currency.getDefaultBalance()); return balances.getOrDefault(currency, currency.getDefaultBalance());
} }
public void setBalance(@NonNull Currency currency, @NonNull BigDecimal balance) { public void setBalance(@NonNull Currency currency, @NonNull BigDecimal balance) throws CannotBeNegative, CannotBeGreaterThan {
this.setBalance(currency, balance, false); this.setBalance(currency, balance, false);
} }
public void setBalance(@NonNull Currency currency, @NonNull BigDecimal balance, boolean force) { public void setBalance(@NonNull Currency currency, @NonNull BigDecimal balance, boolean force) throws CannotBeNegative, CannotBeGreaterThan {
if (balance.compareTo(BigDecimal.ZERO) < 0) { if (balance.compareTo(BigDecimal.ZERO) < 0) {
throw new IllegalArgumentException("Balance cannot be negative"); throw new CannotBeNegative("Balance cannot be negative");
}
if (balance.compareTo(this.plugin.getConfig().maximumBalance) > 0) {
throw new CannotBeGreaterThan("Balance cannot be greater than " + this.plugin.getConfig().maximumBalance);
} }
balance = balance.setScale(currency.fractionalDigits(), RoundingMode.DOWN); balance = balance.setScale(currency.fractionalDigits(), RoundingMode.DOWN);
@ -62,19 +68,27 @@ public class User {
this.setDirty(true); this.setDirty(true);
} }
public void deposit(@NonNull Currency currency, @NonNull BigDecimal amount) throws IllegalArgumentException { public void deposit(@NonNull Currency currency, @NonNull BigDecimal amount) throws CannotBeNegative, CannotBeGreaterThan {
if (amount.compareTo(BigDecimal.ZERO) < 0) { if (amount.compareTo(BigDecimal.ZERO) < 0) {
throw new IllegalArgumentException("Amount cannot be negative"); throw new IllegalArgumentException("Amount cannot be negative");
} }
if (amount.compareTo(this.plugin.getConfig().maximumBalance) > 0) {
throw new CannotBeGreaterThan("Amount cannot be greater than " + this.plugin.getConfig().maximumBalance);
}
this.setBalance(currency, this.getBalance(currency).add(amount)); this.setBalance(currency, this.getBalance(currency).add(amount));
} }
public void withdraw(@NonNull Currency currency, @NonNull BigDecimal amount) throws IllegalArgumentException { public void withdraw(@NonNull Currency currency, @NonNull BigDecimal amount) throws CannotBeNegative, CannotBeGreaterThan {
if (amount.compareTo(BigDecimal.ZERO) < 0) { if (amount.compareTo(BigDecimal.ZERO) < 0) {
throw new IllegalArgumentException("Amount cannot be negative"); throw new IllegalArgumentException("Amount cannot be negative");
} }
if (amount.compareTo(this.plugin.getConfig().maximumBalance) > 0) {
throw new CannotBeGreaterThan("Amount cannot be greater than " + this.plugin.getConfig().maximumBalance);
}
if (this.getBalance(currency).compareTo(amount) < 0) { if (this.getBalance(currency).compareTo(amount) < 0) {
// Withdraw all // Withdraw all
amount = this.getBalance(currency); amount = this.getBalance(currency);

View file

@ -31,7 +31,7 @@ public class SqlStorageProvider implements StorageProvider {
private static final String CREATE_TABLE = """ private static final String CREATE_TABLE = """
CREATE TABLE IF NOT EXISTS '{prefix}_{table}' ( CREATE TABLE IF NOT EXISTS '{prefix}_{table}' (
'uuid' VARCHAR(36) NOT NULL, 'uuid' VARCHAR(36) NOT NULL,
'balance' DECIMAL(10, 2) NOT NULL, 'balance' DECIMAL(20, 2) NOT NULL,
PRIMARY KEY (`uuid`) PRIMARY KEY (`uuid`)
); );
""".trim(); """.trim();

View file

@ -2,6 +2,8 @@ package dev.xhyrom.lighteco.currency.money.bukkit.hooks.vault;
import dev.xhyrom.lighteco.api.LightEco; import dev.xhyrom.lighteco.api.LightEco;
import dev.xhyrom.lighteco.api.LightEcoProvider; import dev.xhyrom.lighteco.api.LightEcoProvider;
import dev.xhyrom.lighteco.api.exception.CannotBeGreaterThan;
import dev.xhyrom.lighteco.api.exception.CannotBeNegative;
import dev.xhyrom.lighteco.api.model.currency.Currency; import dev.xhyrom.lighteco.api.model.currency.Currency;
import dev.xhyrom.lighteco.api.model.user.User; import dev.xhyrom.lighteco.api.model.user.User;
import dev.xhyrom.lighteco.currency.money.common.Plugin; import dev.xhyrom.lighteco.currency.money.common.Plugin;
@ -114,12 +116,12 @@ public class Vault extends AbstractEconomy {
try { try {
user.withdraw(currency, BigDecimal.valueOf(amount)); user.withdraw(currency, BigDecimal.valueOf(amount));
} catch (IllegalArgumentException e) { } catch (CannotBeGreaterThan | CannotBeNegative e) {
return new EconomyResponse( return new EconomyResponse(
amount, amount,
bigDecimalToDouble(user.getBalance(currency)), bigDecimalToDouble(user.getBalance(currency)),
EconomyResponse.ResponseType.FAILURE, EconomyResponse.ResponseType.FAILURE,
"Cannot withdraw negative funds" e.getMessage()
); );
} }
@ -143,12 +145,12 @@ public class Vault extends AbstractEconomy {
try { try {
user.deposit(currency, BigDecimal.valueOf(amount)); user.deposit(currency, BigDecimal.valueOf(amount));
} catch (IllegalArgumentException e) { } catch (CannotBeGreaterThan | CannotBeNegative e) {
return new EconomyResponse( return new EconomyResponse(
amount, amount,
bigDecimalToDouble(user.getBalance(currency)), bigDecimalToDouble(user.getBalance(currency)),
EconomyResponse.ResponseType.FAILURE, EconomyResponse.ResponseType.FAILURE,
"Cannot deposit negative funds" e.getMessage()
); );
} }