From 5e6308ec21d7a899184d5310f090f68b1c099562 Mon Sep 17 00:00:00 2001
From: WinTone01 <103455948+WinTone01@users.noreply.github.com>
Date: Mon, 2 Oct 2023 19:25:28 +0300
Subject: [PATCH 01/25] Create tr-TR.yml
---
src/main/resources/tr-TR.yml | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
create mode 100644 src/main/resources/tr-TR.yml
diff --git a/src/main/resources/tr-TR.yml b/src/main/resources/tr-TR.yml
new file mode 100644
index 0000000..17177ef
--- /dev/null
+++ b/src/main/resources/tr-TR.yml
@@ -0,0 +1,34 @@
+#Turkish language file by WinTone01
+noConsole: Bu komutu kullanabilmek için oyunda olmalısınız!
+noPermission: Bu komutu kullanma izniniz yok!
+missingArguments: Komut için bazı parametreler eksik!
+playerNotFound: Oyuncu bulunamadı!
+invalidAmount: Girilen değer geçersiz!
+invalidCurrency: Geçersiz para birimi!
+insufficientFunds: Yeterli paranız yok!
+balance: Bakiyeniz: %balance%!
+balanceSet: %player% hesabının bakiyesi %balance% olarak ayarlandı!
+balanceOther: %player% adlı oyuncunun bakiyesi: %balance%!
+balanceTop: En zengin oyuncular:
%prevpage% %page% %nextpage%
+balanceTopFormat: %pos% - %player% %balance%
+paySelf: Kendinize ödeme yapamazsınız!
+paySuccess: %player% adlı oyuncuya %amount% ödediniz, %tax_percentage% vergi (%tax_applied% uygulandı)!
+payFail: Ödeme başarısız oldu!
+payReceived: %player% adlı oyuncudan %amount% aldınız!
+purgeUserSuccess: %player% adlı kullanıcı temizlendi!
+switchCurrencySuccess: %currency% para biriminden %switch-currency% para birimine geçildi.
Lütfen çakışmaları önlemek için her RedisEconomy örneğini yeniden başlatın!
+noTransactionFound: %player% için hiçbir işlem bulunamadı!
+transactionsStart: %player% adlı oyuncunun işlemleri %after% - %before% arası!
+transactionsEnd: %player% adlı oyuncunun işlemlerinin sonu, %time% ms içinde tamamlandı
+editMessageError: Bu yapılandırma alanı mevcut değil veya bir dize değil!
+editMessageClickHere: %field%'yi düzenlemek için buraya tıklayın!
+editMessageSuccess: %field% başarıyla kaydedildi!
+transactionItem:
+ outgoingFunds: '#%id% Kopyalamak için tıklayın:
%timestamp%">[Zaman Damgası⌛] [←Geri Al]
%account-owner% > %amount%%symbol% > %other-account%
Sebep: %reason%'
+ incomingFunds: '#%id% Kopyalamak için tıklayın:
%timestamp%">[Zaman Damgası⌛] [←Geri Al]
%other-account% > %amount%%symbol% > %account-owner%
Sebep: %reason%'
+unitSymbols:
+ thousand: k
+ million: m
+ billion: M
+ trillion: T
+ quadrillion: Q
From 7e9f1e53ee586f59742b7ec7de7311630b774eef Mon Sep 17 00:00:00 2001
From: WinTone01 <103455948+WinTone01@users.noreply.github.com>
Date: Fri, 19 Jan 2024 16:27:36 +0300
Subject: [PATCH 02/25] Update tr-TR.yml
---
src/main/resources/tr-TR.yml | 43 ++++++++++++++++++++++--------------
1 file changed, 26 insertions(+), 17 deletions(-)
diff --git a/src/main/resources/tr-TR.yml b/src/main/resources/tr-TR.yml
index 17177ef..9153add 100644
--- a/src/main/resources/tr-TR.yml
+++ b/src/main/resources/tr-TR.yml
@@ -1,31 +1,40 @@
#Turkish language file by WinTone01
-noConsole: Bu komutu kullanabilmek için oyunda olmalısınız!
+noConsole: Oyuncu olmalısınız, bu komutu kullanmak için!
noPermission: Bu komutu kullanma izniniz yok!
-missingArguments: Komut için bazı parametreler eksik!
+missingArguments: Komut için eksik parametreler!
playerNotFound: Oyuncu bulunamadı!
invalidAmount: Girilen değer geçersiz!
invalidCurrency: Geçersiz para birimi!
-insufficientFunds: Yeterli paranız yok!
-balance: Bakiyeniz: %balance%!
-balanceSet: %player% hesabının bakiyesi %balance% olarak ayarlandı!
-balanceOther: %player% adlı oyuncunun bakiyesi: %balance%!
+insufficientFunds: Yeterli bakiyeniz yok!
+balance: Bakiyeniz %balance%!
+balanceSet: %player% adlı oyuncunun hesabına %balance% eklediniz!
+balanceOther: %player%'in bakiyesi %balance%!
balanceTop: En zengin oyuncular:
%prevpage% %page% %nextpage%
balanceTopFormat: %pos% - %player% %balance%
paySelf: Kendinize ödeme yapamazsınız!
-paySuccess: %player% adlı oyuncuya %amount% ödediniz, %tax_percentage% vergi (%tax_applied% uygulandı)!
+paySuccess: %amount% tutarındaki ödemeyi %player% adlı oyuncuya yaptınız. Komisyon oranı %tax_percentage% (%tax_applied%)!
payFail: Ödeme başarısız oldu!
-payReceived: %player% adlı oyuncudan %amount% aldınız!
-purgeUserSuccess: %player% adlı kullanıcı temizlendi!
-switchCurrencySuccess: %currency% para biriminden %switch-currency% para birimine geçildi.
Lütfen çakışmaları önlemek için her RedisEconomy örneğini yeniden başlatın!
-noTransactionFound: %player% için hiçbir işlem bulunamadı!
-transactionsStart: %player% adlı oyuncunun işlemleri %after% - %before% arası!
-transactionsEnd: %player% adlı oyuncunun işlemlerinin sonu, %time% ms içinde tamamlandı
+payReceived: %player% adlı oyuncudan %amount% tutarında ödeme aldınız!
+purgeUserSuccess: %player%'e eşleşen kullanıcı temizlendi!
+switchCurrencySuccess: %currency% başarıyla %switch-currency% ile değiştirildi. Lütfen çakışmaları önlemek için RedisEconomy'nin her örneğini yeniden başlatın!
+noTransactionFound: %player% adlı oyuncu için herhangi bir işlem bulunamadı!
+transactionsStart: %player%'in işlemleri %after% - %before% arasında!
+transactionsEnd: %player%'in işlemleri %time% ms içinde sona erdi
editMessageError: Bu yapılandırma alanı mevcut değil veya bir dize değil!
-editMessageClickHere: %field%'yi düzenlemek için buraya tıklayın!
-editMessageSuccess: %field% başarıyla kaydedildi!
+editMessageClickHere: %field% düzenlemek için buraya tıklayın!
+editMessageSuccess: %field% başarıyla kaydedildi!
transactionItem:
- outgoingFunds: '#%id% Kopyalamak için tıklayın:
%timestamp%">[Zaman Damgası⌛] [←Geri Al]
%account-owner% > %amount%%symbol% > %other-account%
Sebep: %reason%'
- incomingFunds: '#%id% Kopyalamak için tıklayın:
%timestamp%">[Zaman Damgası⌛] [←Geri Al]
%other-account% > %amount%%symbol% > %account-owner%
Sebep: %reason%'
+ outgoingFunds: '#%id% Kopyalamak için tıkla:
%timestamp%">[Zaman Damgası⌛]
+ [←Geri Al]
%account-owner%
+ > %amount%%symbol% > %other-account%
Neden:
+ %reason%'
+ incomingFunds: '#%id% Kopyalamak için tıkla:
%timestamp%">[Zaman Damgası⌛]
+ [←Geri Al]
%other-account% > %amount%%symbol%
+ > %account-owner%
Neden:
+ %reason%'
unitSymbols:
thousand: k
million: m
From 8b7a0091beee0ea14c5138e478798c0c0c0b05c3 Mon Sep 17 00:00:00 2001
From: Emibergo02 <36164338+Emibergo02@users.noreply.github.com>
Date: Sat, 16 Mar 2024 13:01:56 +0100
Subject: [PATCH 03/25] 4.3.9 Fixed desynchronization issue Fixed migration:
moved to enable instead of load Updated all dependencies Java 17 Dropped
support for 1.16
---
jitpack.yml | 6 +-
pom.xml | 30 ++--
.../rediseconomy/RedisEconomyPlugin.java | 38 ++---
.../rediseconomy/command/MainCommand.java | 16 ++
.../rediseconomy/config/ConfigManager.java | 45 +++---
.../currency/CurrenciesManager.java | 84 +++++-----
.../rediseconomy/currency/Currency.java | 72 ++++-----
.../currency/CurrencyWithBanks.java | 38 +++--
.../rediseconomy/redis/RedisManager.java | 15 ++
.../transaction/EconomyExchange.java | 143 +++++++++---------
src/main/resources/plugin.yml | 4 +-
11 files changed, 265 insertions(+), 226 deletions(-)
diff --git a/jitpack.yml b/jitpack.yml
index f0cebce..f29a667 100644
--- a/jitpack.yml
+++ b/jitpack.yml
@@ -1,5 +1,5 @@
jdk:
- - openjdk16
+ - openjdk17
before_install:
- - sdk install java 16.0.1-open
- - sdk use java 16.0.1-open
\ No newline at end of file
+ - sdk install java 17.0.1-open
+ - sdk use java 17.0.1-open
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index b5eb37d..be2f964 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,13 +6,13 @@
dev.unnm3d
RedisEconomy
- 4.3.8-SNAPSHOT
+ 4.3.9-SNAPSHOT
jar
RedisEconomy
- 16
+ 17
UTF-8
@@ -23,8 +23,8 @@
maven-compiler-plugin
3.8.1
-
- 16
+
+ 17
@@ -113,17 +113,13 @@
placeholderapi
https://repo.extendedclip.com/content/repositories/placeholderapi/
-
- devmart-other
- https://nexuslite.gcnt.net/repos/other/
-
org.spigotmc
spigot-api
- 1.16.5-R0.1-SNAPSHOT
+ 1.17.1-R0.1-SNAPSHOT
provided
@@ -135,35 +131,35 @@
org.projectlombok
lombok
- 1.18.26
+ 1.18.30
provided
net.kyori
adventure-text-minimessage
- 4.14.0
+ 4.16.0
net.kyori
adventure-platform-bukkit
- 4.3.0
+ 4.3.2
me.clip
placeholderapi
- 2.11.3
+ 2.11.5
provided
io.lettuce
lettuce-core
- 6.2.4.RELEASE
+ 6.3.2.RELEASE
provided
- com.github.Emibergo02
- ConfigLib
- master-SNAPSHOT
+ de.exlll
+ configlib-yaml
+ 4.5.0
com.github.Anon8281
diff --git a/src/main/java/dev/unnm3d/rediseconomy/RedisEconomyPlugin.java b/src/main/java/dev/unnm3d/rediseconomy/RedisEconomyPlugin.java
index 740ce43..b3d4766 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/RedisEconomyPlugin.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/RedisEconomyPlugin.java
@@ -34,6 +34,7 @@
public final class RedisEconomyPlugin extends JavaPlugin {
+ @Getter
private static RedisEconomyPlugin instance;
//private EzRedisMessenger ezRedisMessenger;
@Getter
@@ -43,6 +44,8 @@ public final class RedisEconomyPlugin extends JavaPlugin {
private RedisManager redisManager;
@Getter
private TaskScheduler scheduler;
+ @Getter
+ private Plugin vaultPlugin;
public Settings settings() {
@@ -53,10 +56,6 @@ public Langs langs() {
return configManager.getLangs();
}
- public static RedisEconomyPlugin getInstance() {
- return instance;
- }
-
@Override
public void onLoad() {
instance = this;
@@ -67,27 +66,30 @@ public void onLoad() {
this.getLogger().severe("Disabling: redis server unreachable!");
this.getLogger().severe("Please setup a redis server before running this plugin!");
this.getServer().getPluginManager().disablePlugin(this);
- return;
} else {
this.getLogger().info("Redis server connected!");
}
-
- if (!setupVault()) { //creates currenciesManager and exchange
- this.getLogger().severe("Disabled due to no Vault dependency found!");
- this.getServer().getPluginManager().disablePlugin(this);
- } else {
- this.getLogger().info("Hooked into Vault!");
- }
}
@Override
public void onEnable() {
this.scheduler = UniversalScheduler.getScheduler(this);
this.configManager.postStartupLoad();
+ this.vaultPlugin = getServer().getPluginManager().getPlugin("Vault");
+ if (this.vaultPlugin == null) { //creates currenciesManager and exchange
+ this.getLogger().severe("Disabled due to no Vault dependency found!");
+ this.getServer().getPluginManager().disablePlugin(this);
+ return;
+ }
+
+ this.currenciesManager = new CurrenciesManager(redisManager, this, configManager);
+ this.getLogger().info("Hooked into Vault!");
+
if (settings().migrationEnabled) {
scheduler.runTaskLater(() ->
- currenciesManager.getCompleteMigration().complete(null),
- 100L);//load: STARTUP doesn't consider dependencies on load so i have to wait a bit (bukkit bug?)
+ currenciesManager.migrateFromOfflinePlayers(getServer().getOfflinePlayers()), 100L);
+ } else {
+ currenciesManager.loadDefaultCurrency(this.vaultPlugin);
}
getServer().getPluginManager().registerEvents(currenciesManager, this);
@@ -164,14 +166,6 @@ private boolean setupRedis() {
}
}
- private boolean setupVault() {
- Plugin vault = getServer().getPluginManager().getPlugin("Vault");
- if (vault == null)
- return false;
- this.currenciesManager = new CurrenciesManager(redisManager, this, configManager);
- currenciesManager.loadDefaultCurrency(vault);
- return true;
- }
private void loadCommand(String cmdName, CommandExecutor executor, TabCompleter tabCompleter) {
PluginCommand cmd = getServer().getPluginCommand(cmdName);
diff --git a/src/main/java/dev/unnm3d/rediseconomy/command/MainCommand.java b/src/main/java/dev/unnm3d/rediseconomy/command/MainCommand.java
index 2e143ba..2c2f34b 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/command/MainCommand.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/command/MainCommand.java
@@ -7,6 +7,7 @@
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
+import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
@@ -25,6 +26,9 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command
plugin.getConfigManager().getLangs().send(sender, plugin.langs().missingArguments);
return true;
} else if (args.length == 1) {
+ if(args[0].equalsIgnoreCase("stress")){
+ stress();
+ }
if (!args[0].equalsIgnoreCase("reload")) return true;
if (!sender.hasPermission("rediseconomy.admin")) return true;
String serverId = plugin.getConfigManager().getSettings().serverId; //Keep serverId
@@ -79,6 +83,18 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command
return true;
}
+ private void stress() {
+ Player p=plugin.getServer().getPlayer("Unnm3d");
+ for(int i=0;i<1000;i++){
+ if(i==400)plugin.getServer().dispatchCommand(plugin.getServer().getConsoleSender(), "balance Unnm3d vault set 0");
+ plugin.getServer().dispatchCommand(plugin.getServer().getConsoleSender(), "balance Unnm3d vault give 1");
+ plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> {
+ plugin.getCurrenciesManager().getDefaultCurrency().depositPlayer(p, 1);
+ });
+ }
+
+ }
+
@Override
public @NotNull List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
diff --git a/src/main/java/dev/unnm3d/rediseconomy/config/ConfigManager.java b/src/main/java/dev/unnm3d/rediseconomy/config/ConfigManager.java
index c10ab23..e5dadd0 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/config/ConfigManager.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/config/ConfigManager.java
@@ -11,8 +11,10 @@
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
+import org.bukkit.plugin.messaging.ChannelNotRegisteredException;
import java.io.File;
+import java.nio.charset.StandardCharsets;
import java.util.concurrent.CompletableFuture;
public class ConfigManager {
@@ -22,6 +24,19 @@ public class ConfigManager {
@Getter
private Langs langs;
+ private static final YamlConfigurationProperties PROPERTIES = YamlConfigurationProperties.newBuilder()
+ .header(
+ """
+ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
+ ┃ RedisEconomy Config ┃
+ ┃ Developed by Unnm3d ┃
+ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
+ """
+ )
+ .footer("Authors: Unnm3d")
+ .charset(StandardCharsets.UTF_8)
+ .build();
+
public ConfigManager(RedisEconomyPlugin plugin) {
this.plugin = plugin;
loadSettingsConfig();
@@ -36,28 +51,18 @@ public void postStartupLoad() {
}
public void loadSettingsConfig() {
- YamlConfigurationProperties properties = YamlConfigurationProperties.newBuilder()
- .header(
- """
- ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
- ┃ RedisEconomy Config ┃
- ┃ Developed by Unnm3d ┃
- ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
- """
- )
- .footer("Authors: Unnm3d")
- .build();
+
File settingsFile = new File(plugin.getDataFolder(), "config.yml");
settings = YamlConfigurations.update(
settingsFile.toPath(),
Settings.class,
- properties
+ PROPERTIES
);
}
public void saveConfigs() {
- YamlConfigurations.save(new File(plugin.getDataFolder(), "config.yml").toPath(), Settings.class, settings);
- YamlConfigurations.save(new File(plugin.getDataFolder(), settings.lang + ".yml").toPath(), Langs.class, langs);
+ YamlConfigurations.save(new File(plugin.getDataFolder(), "config.yml").toPath(), Settings.class, settings, PROPERTIES);
+ YamlConfigurations.save(new File(plugin.getDataFolder(), settings.lang + ".yml").toPath(), Langs.class, langs, PROPERTIES);
}
public void loadLangs() {
@@ -67,7 +72,8 @@ public void loadLangs() {
}
langs = YamlConfigurations.update(
settingsFile.toPath(),
- Langs.class
+ Langs.class,
+ PROPERTIES
);
}
@@ -92,8 +98,11 @@ public void onJoin(org.bukkit.event.player.PlayerJoinEvent event) {
plugin.getScheduler().runTaskLaterAsynchronously(() -> sendServerIdRequest(event.getPlayer()), 20L);
}
};
- if (plugin.getServer().getOnlinePlayers().size() > 0) {
- sendServerIdRequest(plugin.getServer().getOnlinePlayers().iterator().next());
+ if (!plugin.getServer().getOnlinePlayers().isEmpty()) {
+ try {
+ sendServerIdRequest(plugin.getServer().getOnlinePlayers().iterator().next());
+ } catch (ChannelNotRegisteredException ignored) {
+ }
} else {
plugin.getServer().getPluginManager().registerEvents(listener, plugin);
}
@@ -107,7 +116,7 @@ public void onJoin(org.bukkit.event.player.PlayerJoinEvent event) {
}
@SuppressWarnings("UnstableApiUsage")
- private void sendServerIdRequest(Player p) {
+ private void sendServerIdRequest(Player p) throws ChannelNotRegisteredException {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("GetServer");
p.sendPluginMessage(plugin, "BungeeCord", out.toByteArray());//Request server name
diff --git a/src/main/java/dev/unnm3d/rediseconomy/currency/CurrenciesManager.java b/src/main/java/dev/unnm3d/rediseconomy/currency/CurrenciesManager.java
index e786bc3..18640a0 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/currency/CurrenciesManager.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/currency/CurrenciesManager.java
@@ -17,6 +17,7 @@
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
+import org.bukkit.event.server.PluginEnableEvent;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.ServicePriority;
@@ -76,54 +77,56 @@ public CurrenciesManager(RedisManager redisManager, RedisEconomyPlugin plugin, C
}
-
+ /**
+ * Loads the default currency into the vault economy provider
+ * Unregisters the existent economy provider
+ *
+ * @param vaultPlugin the vault plugin
+ */
public void loadDefaultCurrency(Plugin vaultPlugin) {
- Currency defaultCurrency = getDefaultCurrency();
-
for (RegisteredServiceProvider registration : plugin.getServer().getServicesManager().getRegistrations(Economy.class)) {
plugin.getServer().getServicesManager().unregister(Economy.class, registration.getProvider());
}
+ plugin.getServer().getServicesManager().register(Economy.class, getDefaultCurrency(), vaultPlugin, ServicePriority.High);
+ }
- if (!configManager.getSettings().migrationEnabled) {
- plugin.getServer().getServicesManager().register(Economy.class, defaultCurrency, vaultPlugin, ServicePriority.High);
- return;
- }
-
+ /**
+ * Migrates the balances from the existent economy provider to the new one
+ * using the offline players
+ *
+ * @param offlinePlayers the offline players to migrate
+ */
+ public void migrateFromOfflinePlayers(OfflinePlayer[] offlinePlayers) {
+ final Currency defaultCurrency = getDefaultCurrency();
RegisteredServiceProvider existentProvider = plugin.getServer().getServicesManager().getRegistration(Economy.class);
if (existentProvider == null) {
plugin.getLogger().severe("Vault economy provider not found!");
return;
}
- completeMigration.thenApply(voids -> {
- plugin.getLogger().info("§aMigrating from " + existentProvider.getProvider().getName() + "...");
- if (existentProvider.getProvider() == defaultCurrency) {
- plugin.getLogger().info("There's no other provider apart RedisEconomy!");
- return defaultCurrency;
+ plugin.getLogger().info("§aMigrating from " + existentProvider.getProvider().getName() + "...");
+
+ final List> balances = new ArrayList<>();
+ final Map nameUniqueIds = new HashMap<>();
+ for (int i = 0; i < offlinePlayers.length; i++) {
+ final OfflinePlayer offlinePlayer = offlinePlayers[i];
+ try {
+ double bal = existentProvider.getProvider().getBalance(offlinePlayer);
+ balances.add(ScoredValue.just(bal, offlinePlayer.getUniqueId().toString()));
+ if (offlinePlayer.getName() != null)
+ nameUniqueIds.put(offlinePlayer.getName(), offlinePlayer.getUniqueId().toString());
+ defaultCurrency.updateAccountLocal(offlinePlayer.getUniqueId(), offlinePlayer.getName() == null ? offlinePlayer.getUniqueId().toString() : offlinePlayer.getName(), bal);
+ } catch (Exception e) {
+ e.printStackTrace();
}
-
- List> balances = new ArrayList<>();
- Map nameUniqueIds = new HashMap<>();
- for (OfflinePlayer offlinePlayer : Bukkit.getOfflinePlayers()) {
- try {
- double bal = existentProvider.getProvider().getBalance(offlinePlayer);
- balances.add(ScoredValue.just(bal, offlinePlayer.getUniqueId().toString()));
- if (offlinePlayer.getName() != null)
- nameUniqueIds.put(offlinePlayer.getName(), offlinePlayer.getUniqueId().toString());
- defaultCurrency.updateAccountLocal(offlinePlayer.getUniqueId(), offlinePlayer.getName() == null ? offlinePlayer.getUniqueId().toString() : offlinePlayer.getName(), bal);
- } catch (Exception e) {
- e.printStackTrace();
- }
+ if (i % 100 == 0) {
+ plugin.getLogger().info("Progress: " + i + "/" + offlinePlayers.length);
}
-
- defaultCurrency.updateBulkAccountsCloudCache(balances, nameUniqueIds);
- return defaultCurrency;
- }).thenAccept((vaultCurrency) -> {
- plugin.getServer().getServicesManager().register(Economy.class, vaultCurrency, vaultPlugin, ServicePriority.High);
- plugin.getLogger().info("§aMigration completed!");
- configManager.getSettings().migrationEnabled = false;
- configManager.saveConfigs();
- });
-
+ }
+ defaultCurrency.updateBulkAccountsCloudCache(balances, nameUniqueIds);
+ plugin.getLogger().info("§aMigration completed!");
+ plugin.getLogger().info("§aRestart the server to apply the changes.");
+ configManager.getSettings().migrationEnabled = false;
+ configManager.saveConfigs();
}
@Override
@@ -258,6 +261,15 @@ private void onJoin(PlayerJoinEvent e) {
}));
}
+ @EventHandler
+ private void onPluginEnable(PluginEnableEvent pluginEnableEvent) {
+ if (plugin.settings().migrationEnabled) return;
+ if (!plugin.getServer().getServicesManager().getRegistrations(net.milkbowl.vault.economy.Economy.class)
+ .stream().allMatch(registration -> registration.getPlugin().equals(plugin))) {
+ loadDefaultCurrency(plugin.getVaultPlugin());
+ }
+ }
+
private CompletionStage> loadRedisNameUniqueIds() {
return redisManager.getConnectionAsync(connection ->
connection.hgetall(NAME_UUID.toString())
diff --git a/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java b/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java
index 6f57fcf..1170a00 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java
@@ -4,7 +4,6 @@
import dev.unnm3d.rediseconomy.config.Settings;
import dev.unnm3d.rediseconomy.transaction.AccountID;
import dev.unnm3d.rediseconomy.transaction.Transaction;
-import io.lettuce.core.RedisFuture;
import io.lettuce.core.ScoredValue;
import io.lettuce.core.pubsub.StatefulRedisPubSubConnection;
import lombok.AllArgsConstructor;
@@ -19,7 +18,10 @@
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.*;
-import java.util.concurrent.*;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
import static dev.unnm3d.rediseconomy.redis.RedisKeys.*;
@@ -43,6 +45,7 @@ public class Currency implements Economy {
private double transactionTax;
@Getter
private final boolean taxOnlyPay;
+ protected final ExecutorService updateExecutor;
/**
@@ -55,6 +58,7 @@ public class Currency implements Economy {
public Currency(CurrenciesManager currenciesManager, Settings.CurrencySettings currencySettings) {
this.currenciesManager = currenciesManager;
this.enabled = true;
+ this.updateExecutor = Executors.newSingleThreadExecutor();
this.currencyName = currencySettings.currencyName();
this.currencySingular = currencySettings.currencySingle();
this.currencyPlural = currencySettings.currencyPlural();
@@ -440,8 +444,8 @@ public EconomyResponse setPlayerBalance(@NotNull OfflinePlayer player, double am
public EconomyResponse setPlayerBalance(@NotNull UUID playerUUID, @Nullable String playerName, double amount) {
if (amount == Double.POSITIVE_INFINITY || amount == Double.NEGATIVE_INFINITY || Double.isNaN(amount))
return new EconomyResponse(0, 0, EconomyResponse.ResponseType.FAILURE, "Invalid decimal amount format");
- currenciesManager.getExchange().saveTransaction(new AccountID(playerUUID), new AccountID(), -getBalance(playerUUID), currencyName, "Reset balance");
updateAccount(playerUUID, playerName, amount);
+ currenciesManager.getExchange().saveTransaction(new AccountID(playerUUID), new AccountID(), -getBalance(playerUUID), currencyName, "Reset balance");
currenciesManager.getExchange().saveTransaction(new AccountID(playerUUID), new AccountID(), amount, currencyName, "Set balance");
return new EconomyResponse(amount, getBalance(playerUUID), EconomyResponse.ResponseType.SUCCESS, null);
}
@@ -508,33 +512,32 @@ void updateAccountLocal(@NotNull UUID uuid, @Nullable String playerName, double
protected void updateAccount(@NotNull UUID uuid, @Nullable String playerName, double balance) {
updateAccountCloudCache(uuid, playerName, balance, 0);
updateAccountLocal(uuid, playerName, balance);
+
}
- private void updateAccountCloudCache(@NotNull UUID uuid, @Nullable String playerName, double balance, int tries) {
- try {
- currenciesManager.getRedisManager().getConnectionPipeline(commands -> {
- commands.zadd(BALANCE_PREFIX + currencyName, balance, uuid.toString());
+ private synchronized void updateAccountCloudCache(@NotNull UUID uuid, @Nullable String playerName, double balance, int tries) {
+ updateExecutor.submit(() -> {
+ currenciesManager.getRedisManager().executeTransaction(reactiveCommands -> {
+ reactiveCommands.zadd(BALANCE_PREFIX + currencyName, balance, uuid.toString());
if (playerName != null)
- commands.hset(NAME_UUID.toString(), playerName, uuid.toString());
- commands.publish(UPDATE_PLAYER_CHANNEL_PREFIX + currencyName, RedisEconomyPlugin.getInstance().settings().serverId + ";;" + uuid + ";;" + playerName + ";;" + balance).thenAccept((result) -> {
- if (RedisEconomyPlugin.getInstance().settings().debug) {
- Bukkit.getLogger().info("01 Sent update account " + playerName + " to " + balance);
- }
- });
- return null;
- });
-
- } catch (Exception e) {
- if (tries < 3) {
- e.printStackTrace();
- Bukkit.getLogger().severe("Failed to update account " + playerName + " after 3 tries");
- Bukkit.getLogger().severe("Player accounts are desynchronized");
- updateAccountCloudCache(uuid, playerName, balance, tries + 1);
- } else {
- e.printStackTrace();
- }
- }
+ reactiveCommands.hset(NAME_UUID.toString(), playerName, uuid.toString());
+ reactiveCommands.publish(UPDATE_PLAYER_CHANNEL_PREFIX + currencyName,
+ RedisEconomyPlugin.getInstance().settings().serverId + ";;" + uuid + ";;" + playerName + ";;" + balance);
+ }).ifPresentOrElse(result -> {
+ if (RedisEconomyPlugin.getInstance().settings().debug) {
+ Bukkit.getLogger().info("01 Sent update account " + playerName + " to " + balance + " currency " + currencyName);
+ }
+ }, () -> {
+ if (tries < 3) {
+ Bukkit.getLogger().severe("Player accounts are desynchronized");
+ updateAccountCloudCache(uuid, playerName, balance, tries + 1);
+ } else {
+ Bukkit.getLogger().severe("Failed to update account " + playerName + " after 3 tries");
+ throw new RuntimeException("Player accounts are desynchronized");
+ }
+ });
+ });
}
/**
@@ -546,19 +549,16 @@ private void updateAccountCloudCache(@NotNull UUID uuid, @Nullable String player
*/
@SuppressWarnings("unchecked")
public void updateBulkAccountsCloudCache(@NotNull List> balances, @NotNull Map nameUUIDs) {
- currenciesManager.getRedisManager().getConnectionPipeline(commands -> {
+ currenciesManager.getRedisManager().executeTransaction(commands -> {
ScoredValue[] balancesArray = new ScoredValue[balances.size()];
balances.toArray(balancesArray);
- RedisFuture sortedAddFuture = commands.zadd(BALANCE_PREFIX + currencyName, balancesArray);
- RedisFuture hstFuture = commands.hset(NAME_UUID.toString(), nameUUIDs);
- try {
- Bukkit.getLogger().info("migration01 updated balances into " + BALANCE_PREFIX + currencyName + " accounts. result " + sortedAddFuture.get(20, TimeUnit.SECONDS));
- Bukkit.getLogger().info("migration02 updated nameuuids into " + NAME_UUID + " accounts. result " + hstFuture.get(20, TimeUnit.SECONDS));
- } catch (ExecutionException | InterruptedException | TimeoutException e) {
- e.printStackTrace();
- }
- return null;
+ commands.zadd(BALANCE_PREFIX + currencyName, balancesArray);
+ commands.hset(NAME_UUID.toString(), nameUUIDs);
+ }).ifPresent(result -> {
+ Bukkit.getLogger().info("migration01 updated balances into " + BALANCE_PREFIX + currencyName + " accounts. result " + result.get(0));
+ Bukkit.getLogger().info("migration02 updated nameuuids into " + NAME_UUID + " accounts. result " + result.get(1));
+
});
}
diff --git a/src/main/java/dev/unnm3d/rediseconomy/currency/CurrencyWithBanks.java b/src/main/java/dev/unnm3d/rediseconomy/currency/CurrencyWithBanks.java
index 029f544..3dfaf99 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/currency/CurrencyWithBanks.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/currency/CurrencyWithBanks.java
@@ -287,27 +287,25 @@ private void updateBankAccount(@NotNull String accountId, double balance) {
updateBankAccountLocal(accountId, balance);
}
- private void updateBankAccountCloudCache(@NotNull String accountId, double balance, int tries) {
- try {
- currenciesManager.getRedisManager().getConnectionPipeline(commands -> {
- commands.zadd(BALANCE_BANK_PREFIX + currencyName, balance, accountId);
- return commands.publish(UPDATE_BANK_CHANNEL_PREFIX + currencyName, RedisEconomyPlugin.getInstance().settings().serverId + ";;" + accountId + ";;" + balance).thenAccept((result) -> {
- if (RedisEconomyPlugin.getInstance().settings().debug) {
- Bukkit.getLogger().info("01 Sent bank update account " + accountId + " to " + balance);
- }
- });
+ private synchronized void updateBankAccountCloudCache(@NotNull String accountId, double balance, int tries) {
+ updateExecutor.submit(() -> {
+ currenciesManager.getRedisManager().executeTransaction(reactiveCommands -> {
+ reactiveCommands.zadd(BALANCE_BANK_PREFIX + currencyName, balance, accountId);
+ reactiveCommands.publish(UPDATE_BANK_CHANNEL_PREFIX + currencyName, RedisEconomyPlugin.getInstance().settings().serverId + ";;" + accountId + ";;" + balance);
+ }).ifPresentOrElse(result -> {
+ if (RedisEconomyPlugin.getInstance().settings().debug) {
+ Bukkit.getLogger().info("01 Sent bank update accoun " + accountId + " to " + balance);
+ }
+ }, () -> {
+ if (tries < 3) {
+ Bukkit.getLogger().severe("Player accounts are desynchronized");
+ updateBankAccountCloudCache(accountId, balance, tries + 1);
+ } else {
+ Bukkit.getLogger().severe("Failed to update account " + accountId + " after 3 tries");
+ throw new RuntimeException("Bank accounts are desynchronized");
+ }
});
-
- } catch (Exception e) {
- if (tries < 3) {
- e.printStackTrace();
- Bukkit.getLogger().severe("Failed to update bank account " + accountId + " after 3 tries");
- Bukkit.getLogger().severe("Bank accounts are desynchronized");
- updateBankAccountCloudCache(accountId, balance, tries + 1);
- } else {
- e.printStackTrace();
- }
- }
+ });
}
/**
diff --git a/src/main/java/dev/unnm3d/rediseconomy/redis/RedisManager.java b/src/main/java/dev/unnm3d/rediseconomy/redis/RedisManager.java
index 2965065..6939cb9 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/redis/RedisManager.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/redis/RedisManager.java
@@ -2,16 +2,20 @@
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisFuture;
+import io.lettuce.core.TransactionResult;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.async.RedisAsyncCommands;
+import io.lettuce.core.api.sync.RedisCommands;
import io.lettuce.core.pubsub.StatefulRedisPubSubConnection;
import java.time.Duration;
import java.util.List;
+import java.util.Optional;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
+import java.util.function.Consumer;
import java.util.function.Function;
public class RedisManager {
@@ -30,6 +34,9 @@ public RedisManager(RedisClient lettuceRedisClient) {
public CompletionStage getConnectionAsync(Function, CompletionStage> redisCallBack) {
return redisCallBack.apply(roundRobinConnectionPool.get().async());
}
+ public T getConnectionSync(Function, T> redisCallBack) {
+ return redisCallBack.apply(roundRobinConnectionPool.get().sync());
+ }
public CompletionStage getConnectionPipeline(Function, CompletionStage> redisCallBack) {
StatefulRedisConnection connection = roundRobinConnectionPool.get();
@@ -40,6 +47,14 @@ public CompletionStage getConnectionPipeline(Function> executeTransaction(Consumer> redisCommandsConsumer) {
+ final RedisCommands syncCommands = roundRobinConnectionPool.get().sync();
+ syncCommands.multi();
+ redisCommandsConsumer.accept(syncCommands);
+ final TransactionResult transactionResult = syncCommands.exec();
+ return Optional.ofNullable(transactionResult.wasDiscarded() ? null : transactionResult.stream().toList());
+ }
+
public StatefulRedisPubSubConnection getPubSubConnection() {
StatefulRedisPubSubConnection pubSubConnection = lettuceRedisClient.connectPubSub();
pubSubConnections.add(pubSubConnection);
diff --git a/src/main/java/dev/unnm3d/rediseconomy/transaction/EconomyExchange.java b/src/main/java/dev/unnm3d/rediseconomy/transaction/EconomyExchange.java
index 1b1e830..1d16be1 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/transaction/EconomyExchange.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/transaction/EconomyExchange.java
@@ -13,9 +13,7 @@
import java.util.List;
import java.util.Map;
import java.util.UUID;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.CompletionStage;
-import java.util.concurrent.ExecutionException;
+import java.util.concurrent.*;
import static dev.unnm3d.rediseconomy.redis.RedisKeys.NEW_TRANSACTIONS;
@@ -23,6 +21,7 @@
public class EconomyExchange {
private final RedisEconomyPlugin plugin;
+ private final ExecutorService executorService = Executors.newSingleThreadExecutor();
/**
* Get transactions from an account id
@@ -50,7 +49,7 @@ public CompletionStage removeAllTransactions() {
return plugin.getCurrenciesManager().getRedisManager().getConnectionAsync(connection -> {
try {
List keys = connection.keys(NEW_TRANSACTIONS + "*").get();
- if (keys.size() == 0) {
+ if (keys.isEmpty()) {
return CompletableFuture.completedFuture(0L);
}
return connection.del(keys.toArray(new String[0]));
@@ -89,54 +88,54 @@ public CompletionStage getTransaction(AccountID accountId, int id)
* @return List of ids: the first one is the id of the transaction on the sender side, the second one is the id of the transaction on the target side
*/
public CompletionStage> savePaymentTransaction(@NotNull UUID sender, @NotNull UUID target, double amount, @NotNull Currency currency, @NotNull String reason) {
+ final CompletableFuture> future = new CompletableFuture<>();
long init = System.currentTimeMillis();
- reason += getCallerPluginString();
- TransactionEvent transactionSenderEvent = new TransactionEvent(new Transaction(
- new AccountID(sender),
- System.currentTimeMillis(),
- new AccountID(target),
- -amount,
- currency.getCurrencyName(),
- reason,
- null));
- TransactionEvent transactionReceiverEvent = new TransactionEvent(new Transaction(
- new AccountID(target),
- System.currentTimeMillis(),
- new AccountID(sender),
- amount,
- currency.getCurrencyName(),
- reason,
- null));
+ executorService.submit(() -> {
+ final String finalReason = reason + getCallerPluginString();
+ TransactionEvent transactionSenderEvent = new TransactionEvent(new Transaction(
+ new AccountID(sender),
+ System.currentTimeMillis(),
+ new AccountID(target),
+ -amount,
+ currency.getCurrencyName(),
+ finalReason,
+ null));
+ TransactionEvent transactionReceiverEvent = new TransactionEvent(new Transaction(
+ new AccountID(target),
+ System.currentTimeMillis(),
+ new AccountID(sender),
+ amount,
+ currency.getCurrencyName(),
+ finalReason,
+ null));
- plugin.getScheduler().runTask(() -> {
- plugin.getServer().getPluginManager().callEvent(transactionSenderEvent);
- plugin.getServer().getPluginManager().callEvent(transactionReceiverEvent);
- });
+ plugin.getScheduler().runTask(() -> {
+ plugin.getServer().getPluginManager().callEvent(transactionSenderEvent);
+ plugin.getServer().getPluginManager().callEvent(transactionReceiverEvent);
+ });
+ future.complete(plugin.getCurrenciesManager().getRedisManager().getConnectionSync(connection ->
+ connection.eval(
+ "local senderCurrentId=redis.call('hlen', KEYS[1]);" +
+ "local receiverCurrentId=redis.call('hlen', KEYS[2]);" +
+ "redis.call('hset', KEYS[1], senderCurrentId, ARGV[1]);" +
+ "redis.call('hset', KEYS[2], receiverCurrentId, ARGV[2]);" +
+ "return {senderCurrentId,receiverCurrentId};", //Return the id of the new transaction
+ ScriptOutputType.MULTI,
+ new String[]{
+ NEW_TRANSACTIONS + sender.toString(),
+ NEW_TRANSACTIONS + target.toString()}, //Key rediseco:transactions:playerUUID
+ transactionSenderEvent.getTransaction().toString(),
+ transactionReceiverEvent.getTransaction().toString())));
- return plugin.getCurrenciesManager().getRedisManager().getConnectionAsync(connection ->
- connection.>eval(
- "local senderCurrentId=redis.call('hlen', KEYS[1]);" +
- "local receiverCurrentId=redis.call('hlen', KEYS[2]);" +
- "redis.call('hset', KEYS[1], senderCurrentId, ARGV[1]);" +
- "redis.call('hset', KEYS[2], receiverCurrentId, ARGV[2]);" +
- "return {senderCurrentId,receiverCurrentId};", //Return the id of the new transaction
- ScriptOutputType.MULTI,
- new String[]{
- NEW_TRANSACTIONS + sender.toString(),
- NEW_TRANSACTIONS + target.toString()}, //Key rediseco:transactions:playerUUID
- transactionSenderEvent.getTransaction().toString(),
- transactionReceiverEvent.getTransaction().toString()))
- .thenApply(response -> {
- if (RedisEconomyPlugin.getInstance().settings().debug) {
- Bukkit.getLogger().info("03payment Transaction for " + sender + " saved in " + (System.currentTimeMillis() - init) + " ms with id " + response.get(0) + " !");
- Bukkit.getLogger().info("03payment Transaction for " + target + " saved in " + (System.currentTimeMillis() - init) + " ms with id " + response.get(1) + " !");
- }
- return response;
- }).exceptionally(throwable -> {
- throwable.printStackTrace();
- return null;
- });
+ });
+ return future.thenApply(response -> {
+ if (RedisEconomyPlugin.getInstance().settings().debug) {
+ Bukkit.getLogger().info("03payment Transaction for " + sender + " saved in " + (System.currentTimeMillis() - init) + " ms with id " + response.get(0) + " !");
+ Bukkit.getLogger().info("03payment Transaction for " + target + " saved in " + (System.currentTimeMillis() - init) + " ms with id " + response.get(1) + " !");
+ }
+ return response;
+ });
}
@@ -151,33 +150,31 @@ public CompletionStage> savePaymentTransaction(@NotNull UUID sende
* @return The transaction id
*/
public CompletionStage saveTransaction(@NotNull AccountID accountOwner, @NotNull AccountID target, double amount, @NotNull String currencyName, @NotNull String reason) {
+ final CompletableFuture future = new CompletableFuture<>();
long init = System.currentTimeMillis();
- return plugin.getCurrenciesManager().getRedisManager().getConnectionAsync(commands -> {
-
- TransactionEvent transactionEvent = new TransactionEvent(new Transaction(
- accountOwner,
- System.currentTimeMillis(),
- target, //If target is null, it has been sent from the server
- amount, currencyName, reason + getCallerPluginString(), null));
- plugin.getScheduler().runTask(() -> plugin.getServer().getPluginManager().callEvent(transactionEvent));
- return commands.eval(
- "local currentId=redis.call('hlen', KEYS[1]);" + //Get the current size of the hash
- "redis.call('hset', KEYS[1], currentId, ARGV[1]);" + //Add the new transaction
- "return currentId;", //Return the id of the new transaction
- ScriptOutputType.INTEGER,
- new String[]{NEW_TRANSACTIONS + accountOwner.toString()}, //Key rediseco:transactions:playerUUID
- transactionEvent.getTransaction().toString()).thenApply(response -> {
- if (RedisEconomyPlugin.getInstance().settings().debug) {
- Bukkit.getLogger().info("03 Transaction for " + accountOwner + " saved in " + (System.currentTimeMillis() - init) + " ms with id " + response + " !");
- }
- return ((Long) response).intValue();
- }).exceptionally(throwable -> {
- throwable.printStackTrace();
- return null;
- });
- }
- );
+ executorService.submit(() -> {
+ TransactionEvent transactionEvent = new TransactionEvent(new Transaction(
+ accountOwner,
+ System.currentTimeMillis(),
+ target, //If target is null, it has been sent from the server
+ amount, currencyName, reason + getCallerPluginString(), null));
+ plugin.getScheduler().runTask(() -> plugin.getServer().getPluginManager().callEvent(transactionEvent));
+ Long longResult=plugin.getCurrenciesManager().getRedisManager().getConnectionSync(commands -> commands.eval(
+ "local currentId=redis.call('hlen', KEYS[1]);" + //Get the current size of the hash
+ "redis.call('hset', KEYS[1], currentId, ARGV[1]);" + //Add the new transaction
+ "return currentId;", //Return the id of the new transaction
+ ScriptOutputType.INTEGER,
+ new String[]{NEW_TRANSACTIONS + accountOwner.toString()}, //Key rediseco:transactions:playerUUID
+ transactionEvent.getTransaction().toString()));
+ future.complete(longResult.intValue());
+ });
+ return future.thenApply(response -> {
+ if (RedisEconomyPlugin.getInstance().settings().debug) {
+ Bukkit.getLogger().info("03 Transaction for " + accountOwner + " saved in " + (System.currentTimeMillis() - init) + " ms with id " + response + " !");
+ }
+ return response;
+ });
}
/**
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 397b99f..a31a8c1 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -6,7 +6,8 @@ load: STARTUP
depend:
- Vault
libraries:
- - io.lettuce:lettuce-core:6.2.4.RELEASE
+ - io.lettuce:lettuce-core:6.3.2.RELEASE
+ - de.exlll:configlib-yaml:4.5.0
softdepend:
- PlaceholderAPI
- Essentials
@@ -17,6 +18,7 @@ softdepend:
- BetterEconomy
- ArcaneEconomy
- EasyConomy
+ - Towny
folia-supported: true
commands:
pay:
From c8eb73cc6beb45ac8d727a7cdce85cc0a1c3e3ec Mon Sep 17 00:00:00 2001
From: Emibergo02 <36164338+Emibergo02@users.noreply.github.com>
Date: Sat, 16 Mar 2024 15:44:40 +0100
Subject: [PATCH 04/25] Removed stress command
---
.../unnm3d/rediseconomy/command/MainCommand.java | 16 ----------------
1 file changed, 16 deletions(-)
diff --git a/src/main/java/dev/unnm3d/rediseconomy/command/MainCommand.java b/src/main/java/dev/unnm3d/rediseconomy/command/MainCommand.java
index 2c2f34b..2e143ba 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/command/MainCommand.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/command/MainCommand.java
@@ -7,7 +7,6 @@
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
-import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
@@ -26,9 +25,6 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command
plugin.getConfigManager().getLangs().send(sender, plugin.langs().missingArguments);
return true;
} else if (args.length == 1) {
- if(args[0].equalsIgnoreCase("stress")){
- stress();
- }
if (!args[0].equalsIgnoreCase("reload")) return true;
if (!sender.hasPermission("rediseconomy.admin")) return true;
String serverId = plugin.getConfigManager().getSettings().serverId; //Keep serverId
@@ -83,18 +79,6 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command
return true;
}
- private void stress() {
- Player p=plugin.getServer().getPlayer("Unnm3d");
- for(int i=0;i<1000;i++){
- if(i==400)plugin.getServer().dispatchCommand(plugin.getServer().getConsoleSender(), "balance Unnm3d vault set 0");
- plugin.getServer().dispatchCommand(plugin.getServer().getConsoleSender(), "balance Unnm3d vault give 1");
- plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> {
- plugin.getCurrenciesManager().getDefaultCurrency().depositPlayer(p, 1);
- });
- }
-
- }
-
@Override
public @NotNull List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
From 9f0709f96be84c3cfe71d82124f5b83854bf4d53 Mon Sep 17 00:00:00 2001
From: Emibergo02 <36164338+Emibergo02@users.noreply.github.com>
Date: Sun, 17 Mar 2024 14:07:41 +0100
Subject: [PATCH 05/25] Reduced verbose
---
.../dev/unnm3d/rediseconomy/RedisEconomyPlugin.java | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/src/main/java/dev/unnm3d/rediseconomy/RedisEconomyPlugin.java b/src/main/java/dev/unnm3d/rediseconomy/RedisEconomyPlugin.java
index b3d4766..69a2225 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/RedisEconomyPlugin.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/RedisEconomyPlugin.java
@@ -36,7 +36,6 @@ public final class RedisEconomyPlugin extends JavaPlugin {
@Getter
private static RedisEconomyPlugin instance;
- //private EzRedisMessenger ezRedisMessenger;
@Getter
private ConfigManager configManager;
@Getter
@@ -73,6 +72,8 @@ public void onLoad() {
@Override
public void onEnable() {
+ if (redisManager == null) return;
+
this.scheduler = UniversalScheduler.getScheduler(this);
this.configManager.postStartupLoad();
this.vaultPlugin = getServer().getPluginManager().getPlugin("Vault");
@@ -126,7 +127,8 @@ public void onEnable() {
@Override
public void onDisable() {
- redisManager.close();
+ if (redisManager != null)
+ redisManager.close();
if (currenciesManager != null)
this.getServer().getServicesManager().unregister(Economy.class, currenciesManager.getDefaultCurrency());
this.getServer().getMessenger().unregisterOutgoingPluginChannel(this);
@@ -145,16 +147,16 @@ private boolean setupRedis() {
if (configManager.getSettings().redis.user().equals("changecredentials"))
getLogger().warning("You are using default redis credentials. Please change them in the config.yml file!");
//Authentication params
- redisURIBuilder = configManager.getSettings().redis.password().equals("") ?
+ redisURIBuilder = configManager.getSettings().redis.password().isEmpty() ?
redisURIBuilder :
- configManager.getSettings().redis.user().equals("") ?
+ configManager.getSettings().redis.user().isEmpty() ?
redisURIBuilder.withPassword(configManager.getSettings().redis.password().toCharArray()) :
redisURIBuilder.withAuthentication(configManager.getSettings().redis.user(), configManager.getSettings().redis.password());
getLogger().info("Connecting to redis server " + redisURIBuilder.build().toString() + "...");
this.redisManager = new RedisManager(RedisClient.create(redisURIBuilder.build()));
redisManager.isConnected().get(1, java.util.concurrent.TimeUnit.SECONDS);
- if (!configManager.getSettings().clusterId.equals(""))
+ if (!configManager.getSettings().clusterId.isEmpty())
RedisKeys.setClusterId(configManager.getSettings().clusterId);
return true;
} catch (Exception e) {
From cbe46bdc2c394a98308b31e3b8862f52ab59215f Mon Sep 17 00:00:00 2001
From: Emibergo02 <36164338+Emibergo02@users.noreply.github.com>
Date: Thu, 28 Mar 2024 20:21:36 +0100
Subject: [PATCH 06/25] max balance and save transactions
---
pom.xml | 2 +-
.../unnm3d/rediseconomy/config/Settings.java | 5 +-
.../currency/CurrenciesManager.java | 2 +-
.../rediseconomy/currency/Currency.java | 48 ++++++++++++++-----
.../currency/CurrencyWithBanks.java | 10 ++--
.../transaction/EconomyExchange.java | 11 +++--
6 files changed, 53 insertions(+), 25 deletions(-)
diff --git a/pom.xml b/pom.xml
index be2f964..b80d6ef 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
dev.unnm3d
RedisEconomy
- 4.3.9-SNAPSHOT
+ 4.3.10-SNAPSHOT
jar
RedisEconomy
diff --git a/src/main/java/dev/unnm3d/rediseconomy/config/Settings.java b/src/main/java/dev/unnm3d/rediseconomy/config/Settings.java
index 2856051..7a091f9 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/config/Settings.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/config/Settings.java
@@ -39,11 +39,12 @@ public class Settings {
@Comment("Minimum amount of money that can be paid")
public double minPayAmount = 0.01;
@Comment({"Currencies", "payTax is the tax on payments, 0.1 = 10% tax"})
- public List currencies = List.of(new CurrencySettings("vault", "euro", "euros", "#.##", "en-US", 0, 0, true, false), new CurrencySettings("dollar", "$", "$", "#.##", "en-US", 0, 0, false, false));
+ public List currencies = List.of(new CurrencySettings("vault", "euro", "euros", "#.##", "en-US", 0, Double.POSITIVE_INFINITY, 0, true, true, false), new CurrencySettings("dollar", "$", "$", "#.##", "en-US", 0, Double.POSITIVE_INFINITY, 0, false, false, false));
public record CurrencySettings(String currencyName, String currencySingle, String currencyPlural,
String decimalFormat, String languageTag,
- double startingBalance, double payTax, boolean bankEnabled, boolean taxOnlyPay) {
+ double startingBalance, double maxBalance, double payTax,
+ boolean saveTransactions, boolean bankEnabled, boolean taxOnlyPay) {
}
public record RedisSettings(String host, int port, String user, String password, int database, int timeout,
diff --git a/src/main/java/dev/unnm3d/rediseconomy/currency/CurrenciesManager.java b/src/main/java/dev/unnm3d/rediseconomy/currency/CurrenciesManager.java
index 18640a0..3e78fc1 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/currency/CurrenciesManager.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/currency/CurrenciesManager.java
@@ -70,7 +70,7 @@ public CurrenciesManager(RedisManager redisManager, RedisEconomyPlugin plugin, C
currencies.put(currencySettings.currencyName(), currency);
});
if (currencies.get(configManager.getSettings().defaultCurrencyName) == null) {
- currencies.put(configManager.getSettings().defaultCurrencyName, new Currency(this, new Settings.CurrencySettings(configManager.getSettings().defaultCurrencyName, "€", "€", "#.##", "en-US", 0.0, 0.0, true, false)));
+ currencies.put(configManager.getSettings().defaultCurrencyName, new Currency(this, new Settings.CurrencySettings(configManager.getSettings().defaultCurrencyName, "€", "€", "#.##", "en-US", 0.0, Double.POSITIVE_INFINITY,0.0, true,true, false)));
}
registerPayMsgChannel();
registerBlockAccountChannel();
diff --git a/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java b/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java
index 1170a00..ca7b3a9 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java
@@ -32,6 +32,7 @@ public class Currency implements Economy {
@Getter
protected final String currencyName;
private final ConcurrentHashMap accounts;
+
private boolean enabled;
@Getter
private String currencySingular;
@@ -40,7 +41,10 @@ public class Currency implements Economy {
@Getter
private final DecimalFormat decimalFormat;
@Getter
- private double startingBalance;
+ private final double startingBalance;
+ @Getter
+ private final double maxBalance;
+ private boolean saveTransactions;
@Getter
private double transactionTax;
@Getter
@@ -63,6 +67,8 @@ public Currency(CurrenciesManager currenciesManager, Settings.CurrencySettings c
this.currencySingular = currencySettings.currencySingle();
this.currencyPlural = currencySettings.currencyPlural();
this.startingBalance = currencySettings.startingBalance();
+ this.maxBalance = currencySettings.maxBalance() == 0.0d ? Double.POSITIVE_INFINITY : currencySettings.maxBalance();
+ this.saveTransactions = currencySettings.saveTransactions();
this.transactionTax = currencySettings.payTax();
this.taxOnlyPay = currencySettings.taxOnlyPay();
this.accounts = new ConcurrentHashMap<>();
@@ -73,7 +79,7 @@ public Currency(CurrenciesManager currenciesManager, Settings.CurrencySettings c
getOrderedAccounts(-1).thenApply(result -> {
result.forEach(t ->
accounts.put(UUID.fromString(t.getValue()), t.getScore()));
- if (RedisEconomyPlugin.getInstance().settings().debug && accounts.size() > 0) {
+ if (RedisEconomyPlugin.getInstance().settings().debug && !accounts.isEmpty()) {
Bukkit.getLogger().info("start1 Loaded " + accounts.size() + " accounts for currency " + currencyName);
}
return result;
@@ -114,6 +120,14 @@ public boolean isEnabled() {
return enabled;
}
+ public boolean shouldSaveTransactions() {
+ return saveTransactions;
+ }
+
+ public void setShouldSaveTransactions(boolean saveTransactions) {
+ this.saveTransactions = saveTransactions;
+ }
+
@Override
public String getName() {
return "RedisEconomy";
@@ -337,7 +351,7 @@ public boolean createPlayerAccount(@NotNull UUID playerUUID, @Nullable String pl
if (hasAccount(playerUUID))
return false;
updateAccount(playerUUID, playerName, startingBalance);
- currenciesManager.getExchange().saveTransaction(new AccountID(playerUUID), new AccountID(), startingBalance, currencyName, "Account creation");
+ currenciesManager.getExchange().saveTransaction(new AccountID(playerUUID), new AccountID(), startingBalance, this, "Account creation");
return true;
}
@@ -370,7 +384,7 @@ public EconomyResponse withdrawPlayer(@NotNull UUID playerUUID, @Nullable String
return new EconomyResponse(amountToWithdraw, getBalance(playerUUID), EconomyResponse.ResponseType.FAILURE, "Insufficient funds");
updateAccount(playerUUID, playerName, getBalance(playerUUID) - amountToWithdraw);
- currenciesManager.getExchange().saveTransaction(new AccountID(playerUUID), new AccountID(), -amountToWithdraw, currencyName, reason == null ? "Withdraw" : reason);
+ currenciesManager.getExchange().saveTransaction(new AccountID(playerUUID), new AccountID(), -amountToWithdraw, this, reason == null ? "Withdraw" : reason);
return new EconomyResponse(amount, getBalance(playerUUID), EconomyResponse.ResponseType.SUCCESS, null);
}
@@ -391,10 +405,13 @@ public EconomyResponse payPlayer(@NotNull UUID sender, @NotNull UUID receiver, d
if (!has(sender, amountToWithdraw))
return new EconomyResponse(0, getBalance(sender), EconomyResponse.ResponseType.FAILURE, "Insufficient funds");
+ if (getBalance(receiver) + amount > maxBalance)
+ return new EconomyResponse(0, getBalance(receiver), EconomyResponse.ResponseType.FAILURE, "The receiver has reached the maximum balance");
+
updateAccount(sender, senderName, getBalance(sender) - amountToWithdraw);
- currenciesManager.getExchange().saveTransaction(new AccountID(sender), new AccountID(receiver), -amountToWithdraw, currencyName, reason == null ? "Payment" : reason);
+ currenciesManager.getExchange().saveTransaction(new AccountID(sender), new AccountID(receiver), -amountToWithdraw, this, reason == null ? "Payment" : reason);
updateAccount(sender, receiverName, getBalance(receiver) + amount);
- currenciesManager.getExchange().saveTransaction(new AccountID(receiver), new AccountID(sender), amount, currencyName, reason == null ? "Payment" : reason);
+ currenciesManager.getExchange().saveTransaction(new AccountID(receiver), new AccountID(sender), amount, this, reason == null ? "Payment" : reason);
return new EconomyResponse(amount, getBalance(sender), EconomyResponse.ResponseType.SUCCESS, null);
}
@@ -414,7 +431,10 @@ public EconomyResponse payPlayer(@NotNull String senderName, @NotNull String rec
return new EconomyResponse(0, 0, EconomyResponse.ResponseType.FAILURE, "Invalid decimal amount format");
if (!has(senderName, amountToWithdraw))
- return new EconomyResponse(0, getBalance(senderName), EconomyResponse.ResponseType.FAILURE, "Insufficient funds");
+ return new EconomyResponse(0, getBalance(sender), EconomyResponse.ResponseType.FAILURE, "Insufficient funds");
+
+ if (getBalance(receiver) + amount > maxBalance)
+ return new EconomyResponse(0, getBalance(receiver), EconomyResponse.ResponseType.FAILURE, "The receiver has reached the maximum balance");
updateAccount(sender, senderName, getBalance(sender) - amountToWithdraw);
updateAccount(receiver, receiverName, getBalance(receiver) + amount);
@@ -445,8 +465,8 @@ public EconomyResponse setPlayerBalance(@NotNull UUID playerUUID, @Nullable Stri
if (amount == Double.POSITIVE_INFINITY || amount == Double.NEGATIVE_INFINITY || Double.isNaN(amount))
return new EconomyResponse(0, 0, EconomyResponse.ResponseType.FAILURE, "Invalid decimal amount format");
updateAccount(playerUUID, playerName, amount);
- currenciesManager.getExchange().saveTransaction(new AccountID(playerUUID), new AccountID(), -getBalance(playerUUID), currencyName, "Reset balance");
- currenciesManager.getExchange().saveTransaction(new AccountID(playerUUID), new AccountID(), amount, currencyName, "Set balance");
+ currenciesManager.getExchange().saveTransaction(new AccountID(playerUUID), new AccountID(), -getBalance(playerUUID), this, "Reset balance");
+ currenciesManager.getExchange().saveTransaction(new AccountID(playerUUID), new AccountID(), amount, this, "Set balance");
return new EconomyResponse(amount, getBalance(playerUUID), EconomyResponse.ResponseType.SUCCESS, null);
}
@@ -467,7 +487,7 @@ public CompletionStage revertTransaction(int transactionId, @NotNull Tr
if (RedisEconomyPlugin.getInstance().settings().debug) {
Bukkit.getLogger().info("revert01a reverted on account " + transaction.getAccountIdentifier() + " amount " + transaction.getAmount());
}
- return currenciesManager.getExchange().saveTransaction(transaction.getAccountIdentifier(), transaction.getActor(), -transaction.getAmount(), currencyName, "Revert #" + transactionId + ": " + transaction.getReason());
+ return currenciesManager.getExchange().saveTransaction(transaction.getAccountIdentifier(), transaction.getActor(), -transaction.getAmount(), this, "Revert #" + transactionId + ": " + transaction.getReason());
}
/**
@@ -498,8 +518,11 @@ public EconomyResponse depositPlayer(@NotNull UUID playerUUID, @Nullable String
if (amount == Double.POSITIVE_INFINITY || amount == Double.NEGATIVE_INFINITY || Double.isNaN(amount))
return new EconomyResponse(0, 0, EconomyResponse.ResponseType.FAILURE, "Invalid decimal amount format");
+ if (getBalance(playerUUID) + amount > maxBalance)
+ return new EconomyResponse(0, getBalance(playerUUID), EconomyResponse.ResponseType.FAILURE, "The player has reached the maximum balance");
+
updateAccount(playerUUID, playerName, getBalance(playerUUID) + amount);
- currenciesManager.getExchange().saveTransaction(new AccountID(playerUUID), new AccountID(), amount, currencyName, reason == null ? "Deposit" : reason);
+ currenciesManager.getExchange().saveTransaction(new AccountID(playerUUID), new AccountID(), amount, this, reason == null ? "Deposit" : reason);
return new EconomyResponse(amount, getBalance(playerUUID), EconomyResponse.ResponseType.SUCCESS, null);
}
@@ -512,7 +535,6 @@ void updateAccountLocal(@NotNull UUID uuid, @Nullable String playerName, double
protected void updateAccount(@NotNull UUID uuid, @Nullable String playerName, double balance) {
updateAccountCloudCache(uuid, playerName, balance, 0);
updateAccountLocal(uuid, playerName, balance);
-
}
private synchronized void updateAccountCloudCache(@NotNull UUID uuid, @Nullable String playerName, double balance, int tries) {
@@ -595,4 +617,6 @@ public CompletionStage getAccountRedis(UUID uuid) {
public final Map getAccounts() {
return Collections.unmodifiableMap(accounts);
}
+
+
}
diff --git a/src/main/java/dev/unnm3d/rediseconomy/currency/CurrencyWithBanks.java b/src/main/java/dev/unnm3d/rediseconomy/currency/CurrencyWithBanks.java
index 3dfaf99..214643f 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/currency/CurrencyWithBanks.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/currency/CurrencyWithBanks.java
@@ -123,7 +123,7 @@ public EconomyResponse createBank(@NotNull String accountId, UUID playerOwner, S
return new EconomyResponse(0, 0, EconomyResponse.ResponseType.FAILURE, "Bank account already exists");
setOwner(accountId, playerOwner);
updateBankAccount(accountId, 0);
- currenciesManager.getExchange().saveTransaction(new AccountID(accountId), new AccountID(playerOwner), 0, currencyName, reason);
+ currenciesManager.getExchange().saveTransaction(new AccountID(accountId), new AccountID(playerOwner), 0, this, reason);
return new EconomyResponse(0, 0, EconomyResponse.ResponseType.SUCCESS, null);
}
@@ -146,7 +146,7 @@ public EconomyResponse deleteBank(@NotNull String accountId) {
if (RedisEconomyPlugin.getInstance().settings().debug) {
Bukkit.getLogger().info("Deleted bank account " + accountId + " with result " + result);
}
- currenciesManager.getExchange().saveTransaction(new AccountID(accountId), new AccountID(), 0, currencyName, "Bank account deletion");
+ currenciesManager.getExchange().saveTransaction(new AccountID(accountId), new AccountID(), 0, this, "Bank account deletion");
});
return new EconomyResponse(0, 0, EconomyResponse.ResponseType.SUCCESS, null);
}
@@ -184,7 +184,7 @@ public EconomyResponse bankWithdraw(@NotNull String accountId, double amount, St
return hasAmountResponse;
}
updateBankAccount(accountId, hasAmountResponse.balance);//Balance is the new balance with subtracted amount
- currenciesManager.getExchange().saveTransaction(new AccountID(accountId), new AccountID(), -amount, currencyName, reason);
+ currenciesManager.getExchange().saveTransaction(new AccountID(accountId), new AccountID(), -amount, this, reason);
return new EconomyResponse(amount, hasAmountResponse.balance, EconomyResponse.ResponseType.SUCCESS, null);
}
@@ -208,7 +208,7 @@ public EconomyResponse bankDeposit(@NotNull String accountId, double amount, Str
}
EconomyResponse balanceResponse = bankBalance(accountId);
updateBankAccount(accountId, balanceResponse.balance + amount);//Balance is the new balance with subtracted amount
- currenciesManager.getExchange().saveTransaction(new AccountID(accountId), new AccountID(), amount, currencyName, reason);
+ currenciesManager.getExchange().saveTransaction(new AccountID(accountId), new AccountID(), amount, this, reason);
return new EconomyResponse(amount, balanceResponse.balance + amount, EconomyResponse.ResponseType.SUCCESS, null);
}
@@ -263,7 +263,7 @@ public CompletionStage revertTransaction(int transactionId, @NotNull Tr
if (RedisEconomyPlugin.getInstance().settings().debug) {
Bukkit.getLogger().info("revert01a reverted on account " + transaction.getAccountIdentifier() + " amount " + transaction.getAmount());
}
- return currenciesManager.getExchange().saveTransaction(transaction.getAccountIdentifier(), transaction.getActor(), -transaction.getAmount(), currencyName, "Revert #" + transactionId + ": " + transaction.getReason());
+ return currenciesManager.getExchange().saveTransaction(transaction.getAccountIdentifier(), transaction.getActor(), -transaction.getAmount(), this, "Revert #" + transactionId + ": " + transaction.getReason());
}
private void setOwner(@NotNull String accountId, UUID ownerUUID) {
diff --git a/src/main/java/dev/unnm3d/rediseconomy/transaction/EconomyExchange.java b/src/main/java/dev/unnm3d/rediseconomy/transaction/EconomyExchange.java
index 1d16be1..e249caf 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/transaction/EconomyExchange.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/transaction/EconomyExchange.java
@@ -88,6 +88,8 @@ public CompletionStage getTransaction(AccountID accountId, int id)
* @return List of ids: the first one is the id of the transaction on the sender side, the second one is the id of the transaction on the target side
*/
public CompletionStage> savePaymentTransaction(@NotNull UUID sender, @NotNull UUID target, double amount, @NotNull Currency currency, @NotNull String reason) {
+ if (!currency.shouldSaveTransactions()) return CompletableFuture.completedStage(List.of(-1, -1));
+
final CompletableFuture> future = new CompletableFuture<>();
long init = System.currentTimeMillis();
@@ -145,11 +147,12 @@ public CompletionStage> savePaymentTransaction(@NotNull UUID sende
* @param accountOwner The id of the account, could be a UUID or a bank id (string)
* @param target The id of the target account, could be a UUID or a bank id (string)
* @param amount The amount of money transferred
- * @param currencyName The name of the currency
+ * @param currency The currency of the transaction
* @param reason The reason of the transaction
* @return The transaction id
*/
- public CompletionStage saveTransaction(@NotNull AccountID accountOwner, @NotNull AccountID target, double amount, @NotNull String currencyName, @NotNull String reason) {
+ public CompletionStage saveTransaction(@NotNull AccountID accountOwner, @NotNull AccountID target, double amount, @NotNull Currency currency, @NotNull String reason) {
+ if (!currency.shouldSaveTransactions()) return CompletableFuture.completedStage(-1);
final CompletableFuture future = new CompletableFuture<>();
long init = System.currentTimeMillis();
@@ -158,9 +161,9 @@ public CompletionStage saveTransaction(@NotNull AccountID accountOwner,
accountOwner,
System.currentTimeMillis(),
target, //If target is null, it has been sent from the server
- amount, currencyName, reason + getCallerPluginString(), null));
+ amount, currency.getCurrencyName(), reason + getCallerPluginString(), null));
plugin.getScheduler().runTask(() -> plugin.getServer().getPluginManager().callEvent(transactionEvent));
- Long longResult=plugin.getCurrenciesManager().getRedisManager().getConnectionSync(commands -> commands.eval(
+ Long longResult = plugin.getCurrenciesManager().getRedisManager().getConnectionSync(commands -> commands.eval(
"local currentId=redis.call('hlen', KEYS[1]);" + //Get the current size of the hash
"redis.call('hset', KEYS[1], currentId, ARGV[1]);" + //Add the new transaction
"return currentId;", //Return the id of the new transaction
From 7130be9c950e030cbba1832542c386647d0a75dd Mon Sep 17 00:00:00 2001
From: Emibergo02 <36164338+Emibergo02@users.noreply.github.com>
Date: Wed, 3 Apr 2024 11:37:56 +0200
Subject: [PATCH 07/25] 4.3.11 serverId retrieval from Bungeecord Placeholder
renovated
---
pom.xml | 2 +-
.../rediseconomy/config/ConfigManager.java | 61 +-------------
.../unnm3d/rediseconomy/config/Settings.java | 2 +-
.../utils/PlaceholderAPIHook.java | 82 +++++++++++--------
4 files changed, 54 insertions(+), 93 deletions(-)
diff --git a/pom.xml b/pom.xml
index b80d6ef..69f5c72 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
dev.unnm3d
RedisEconomy
- 4.3.10-SNAPSHOT
+ 4.3.11-SNAPSHOT
jar
RedisEconomy
diff --git a/src/main/java/dev/unnm3d/rediseconomy/config/ConfigManager.java b/src/main/java/dev/unnm3d/rediseconomy/config/ConfigManager.java
index e5dadd0..2e20c41 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/config/ConfigManager.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/config/ConfigManager.java
@@ -1,21 +1,13 @@
package dev.unnm3d.rediseconomy.config;
-import com.google.common.io.ByteArrayDataInput;
-import com.google.common.io.ByteArrayDataOutput;
-import com.google.common.io.ByteStreams;
import de.exlll.configlib.YamlConfigurationProperties;
import de.exlll.configlib.YamlConfigurations;
import dev.unnm3d.rediseconomy.RedisEconomyPlugin;
import lombok.Getter;
-import org.bukkit.entity.Player;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.HandlerList;
-import org.bukkit.event.Listener;
-import org.bukkit.plugin.messaging.ChannelNotRegisteredException;
import java.io.File;
import java.nio.charset.StandardCharsets;
-import java.util.concurrent.CompletableFuture;
+import java.util.UUID;
public class ConfigManager {
private final RedisEconomyPlugin plugin;
@@ -44,10 +36,10 @@ public ConfigManager(RedisEconomyPlugin plugin) {
public void postStartupLoad() {
loadLangs();
- getServerId().thenAccept(s -> {
- settings.serverId = s;
+ if (settings.serverId == null || settings.serverId.isEmpty()) {
+ settings.serverId = String.valueOf(UUID.randomUUID());
saveConfigs();
- });
+ }
}
public void loadSettingsConfig() {
@@ -77,49 +69,4 @@ public void loadLangs() {
);
}
- @SuppressWarnings("UnstableApiUsage")
- public CompletableFuture getServerId() {
- CompletableFuture future = new CompletableFuture<>();
- plugin.getServer().getMessenger().registerOutgoingPluginChannel(plugin, "BungeeCord");
- plugin.getServer().getMessenger().registerIncomingPluginChannel(plugin, "BungeeCord", (channel, player, message) -> {
- if (future.isDone()) return;
- ByteArrayDataInput in = ByteStreams.newDataInput(message);
- String subchannel = in.readUTF();
- if (subchannel.equals("GetServer")) {
- future.complete(in.readUTF());//Receive server name
- }
- });
- Listener listener = new Listener() {
- @EventHandler
- public void onJoin(org.bukkit.event.player.PlayerJoinEvent event) {
- if (future.isDone()) {
- return;
- }
- plugin.getScheduler().runTaskLaterAsynchronously(() -> sendServerIdRequest(event.getPlayer()), 20L);
- }
- };
- if (!plugin.getServer().getOnlinePlayers().isEmpty()) {
- try {
- sendServerIdRequest(plugin.getServer().getOnlinePlayers().iterator().next());
- } catch (ChannelNotRegisteredException ignored) {
- }
- } else {
- plugin.getServer().getPluginManager().registerEvents(listener, plugin);
- }
- return future.thenApply(s -> {
- //Remove listener and channel listeners
- HandlerList.unregisterAll(listener);
- plugin.getServer().getMessenger().unregisterIncomingPluginChannel(plugin, "BungeeCord");
- plugin.getServer().getMessenger().unregisterOutgoingPluginChannel(plugin, "BungeeCord");
- return s;
- });
- }
-
- @SuppressWarnings("UnstableApiUsage")
- private void sendServerIdRequest(Player p) throws ChannelNotRegisteredException {
- ByteArrayDataOutput out = ByteStreams.newDataOutput();
- out.writeUTF("GetServer");
- p.sendPluginMessage(plugin, "BungeeCord", out.toByteArray());//Request server name
- }
-
}
diff --git a/src/main/java/dev/unnm3d/rediseconomy/config/Settings.java b/src/main/java/dev/unnm3d/rediseconomy/config/Settings.java
index 7a091f9..bef8cbc 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/config/Settings.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/config/Settings.java
@@ -10,7 +10,7 @@
@Configuration
public class Settings {
@Comment({"This is automatically generated on server startup",
- "Change it only if you have disabled plugin messages on the proxy"})
+ "You need to have a different serverId for each server!!!"})
public String serverId = String.valueOf(UUID.randomUUID());
@Comment("Language file")
public String lang = "en-US";
diff --git a/src/main/java/dev/unnm3d/rediseconomy/utils/PlaceholderAPIHook.java b/src/main/java/dev/unnm3d/rediseconomy/utils/PlaceholderAPIHook.java
index e12ce45..01744d2 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/utils/PlaceholderAPIHook.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/utils/PlaceholderAPIHook.java
@@ -10,6 +10,7 @@
import org.bukkit.plugin.RegisteredServiceProvider;
import org.jetbrains.annotations.NotNull;
+import java.text.DecimalFormat;
import java.util.*;
@@ -109,43 +110,47 @@ public String onRequest(OfflinePlayer player, String params) {
updatePlaceholdersCache();
- if (splitted.get(0).equals("totsupply")) {
-
- return parseParams(totalSupplyCache.get(currency), splitted, currency);
- } else if (splitted.get(0).equals("top")) {
-
+ switch (splitted.get(0)) {
+ case "totsupply" -> {
+ return parseParams(totalSupplyCache.get(currency), splitted, currency);
+ }
+ case "maxbal" -> {
+ return String.valueOf(currency.getMaxBalance());
+ }
+ case "top" -> {
- if (splitted.size() < 3) return null; //Insufficient parameters
+ if (splitted.size() < 3) return null; //Insufficient parameters
- List user_balance_strings = baltopCache.get(currency);
- if (user_balance_strings == null) return null;
+ List user_balance_strings = baltopCache.get(currency);
+ if (user_balance_strings == null) return null;
- if (splitted.get(1).equals("position")) {//rediseco_top_position_
- for (int i = 0; i < user_balance_strings.size(); i++) {
- if (user_balance_strings.get(i)[2].equals(player.getName())) {
- return String.valueOf(i + 1);
+ if (splitted.get(1).equals("position")) {//rediseco_top_position_
+ for (int i = 0; i < user_balance_strings.size(); i++) {
+ if (user_balance_strings.get(i)[2].equals(player.getName())) {
+ return String.valueOf(i + 1);
+ }
}
+ return "10+";
}
- return "10+";
- }
- int position = Integer.parseInt(splitted.get(1));
- if (position < 1 || position > 10) return "N/A"; //Invalid positions
- if (user_balance_strings.size() < position) return "N/A";
+ int position = Integer.parseInt(splitted.get(1));
+ if (position < 1 || position > 10) return "N/A"; //Invalid positions
+ if (user_balance_strings.size() < position) return "N/A";
- switch (splitted.get(2)) {
- case "playerprefix" -> {
- return user_balance_strings.get(position - 1)[0];
- }
- case "playersuffix" -> {
- return user_balance_strings.get(position - 1)[1];
- }
- case "name" -> {
- return user_balance_strings.get(position - 1)[2];
- }
- case "bal" -> {
- double balance = Double.parseDouble(user_balance_strings.get(position - 1)[3]);
- return parseParams(balance, splitted, currency);
+ switch (splitted.get(2)) {
+ case "playerprefix" -> {
+ return user_balance_strings.get(position - 1)[0];
+ }
+ case "playersuffix" -> {
+ return user_balance_strings.get(position - 1)[1];
+ }
+ case "name" -> {
+ return user_balance_strings.get(position - 1)[2];
+ }
+ case "bal" -> {
+ double balance = Double.parseDouble(user_balance_strings.get(position - 1)[3]);
+ return parseParams(balance, splitted, currency);
+ }
}
}
}
@@ -158,15 +163,24 @@ private String parseParams(double amount, List splitted, Currency curren
if (splitted.contains("short")) {
if (amount >= 1000000000000.0) {
- formattedNumber = currency.format(amount / 1000000000000.0) + langs.unitSymbols.trillion();
+ formattedNumber = currency.getDecimalFormat().format(amount / 1000000000000.0) + langs.unitSymbols.trillion();
} else if (amount >= 1000000000.0) {
- formattedNumber = currency.format(amount / 1000000000.0) + langs.unitSymbols.billion();
+ formattedNumber = currency.getDecimalFormat().format(amount / 1000000000.0) + langs.unitSymbols.billion();
} else if (amount >= 1000000.0) {
- formattedNumber = currency.format(amount / 1000000.0) + langs.unitSymbols.million();
+ formattedNumber = currency.getDecimalFormat().format(amount / 1000000.0) + langs.unitSymbols.million();
} else if (amount >= 1000.0) {
- formattedNumber = currency.format(amount / 1000.0) + langs.unitSymbols.thousand();
+ formattedNumber = currency.getDecimalFormat().format(amount / 1000.0) + langs.unitSymbols.thousand();
}
}
+
+ formattedNumber = splitted.stream()
+ .filter(s -> s.startsWith("decformat"))
+ .findFirst()
+ .map(s -> s.split("decformat"))
+ .filter(splittedFormat -> splittedFormat.length > 1)
+ .map(splittedFormat -> new DecimalFormat(splittedFormat[1]).format(amount))
+ .orElse(formattedNumber);
+
if (splitted.contains("formatted")) {
if (amount == 1)
formattedNumber += currency.getCurrencySingular();
From 3ac6bb904971b4fcf755e82b9fe64801dcc45329 Mon Sep 17 00:00:00 2001
From: Emibergo02 <36164338+Emibergo02@users.noreply.github.com>
Date: Sun, 5 May 2024 12:42:51 +0200
Subject: [PATCH 08/25] 4.3.12 New german language file New command /pay *
to send money to all players on your server (you need
rediseconomy.payall)
---
pom.xml | 4 +-
.../rediseconomy/command/PayCommand.java | 60 +++++++++++++++--
.../BrowseTransactionsCommand.java | 2 -
.../rediseconomy/config/ConfigManager.java | 3 +-
.../rediseconomy/currency/Currency.java | 7 +-
src/main/resources/de-DE.yml | 66 +++++++++++++++++++
src/main/resources/plugin.yml | 9 ++-
7 files changed, 137 insertions(+), 14 deletions(-)
create mode 100644 src/main/resources/de-DE.yml
diff --git a/pom.xml b/pom.xml
index 69f5c72..0278103 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
dev.unnm3d
RedisEconomy
- 4.3.11-SNAPSHOT
+ 4.3.12
jar
RedisEconomy
@@ -131,7 +131,7 @@
org.projectlombok
lombok
- 1.18.30
+ 1.18.32
provided
diff --git a/src/main/java/dev/unnm3d/rediseconomy/command/PayCommand.java b/src/main/java/dev/unnm3d/rediseconomy/command/PayCommand.java
index 5bbbe48..e8094d0 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/command/PayCommand.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/command/PayCommand.java
@@ -78,6 +78,13 @@ private void payCurrency(Player sender, Currency currency, String[] args) {
if (target.equalsIgnoreCase(sender.getName())) {
plugin.langs().send(sender, plugin.langs().paySelf);
return;
+ } else if (target.equals("*")) {
+ if (sender.hasPermission("rediseconomy.payall")) {
+ payCurrencyAll(sender, currency, amount);
+ } else {
+ plugin.langs().send(sender, plugin.langs().noPermission);
+ }
+ return;
}
if (!currency.hasAccount(target)) {
plugin.langs().send(sender, plugin.langs().playerNotFound);
@@ -121,7 +128,48 @@ private void payCurrency(Player sender, Currency currency, String[] args) {
}
return currenciesManager.getExchange().savePaymentTransaction(sender.getUniqueId(), targetUUID, amount, currency, reason);
});
+ }
+ /**
+ * Pay to all online players
+ *
+ * @param sender Player who sends the payment
+ * @param currency Currency to pay
+ * @param amount Amount to pay
+ */
+ private void payCurrencyAll(Player sender, Currency currency, double amount) {
+ for (Player onlinePlayer : plugin.getServer().getOnlinePlayers()) {
+ if (onlinePlayer.getName().equals(sender.getName())) continue;
+
+ if (currenciesManager.isAccountLocked(onlinePlayer.getUniqueId(), sender.getUniqueId())) {
+ plugin.langs().send(sender, plugin.langs().blockedPayment.replace("%player%", onlinePlayer.getName()));
+ continue;
+ }
+
+ final EconomyResponse response = currency.payPlayer(sender.getName(), onlinePlayer.getName(), amount);
+ if (!response.transactionSuccess()) {
+ if (response.errorMessage.equals("Insufficient funds")) {
+ plugin.langs().send(sender, plugin.langs().insufficientFunds);
+ } else {
+ plugin.langs().send(sender, plugin.langs().payFail);
+ }
+ return;
+ }
+ //Send msg to sender
+ plugin.langs().send(sender,
+ plugin.langs().paySuccess
+ .replace("%amount%", currency.format(amount))
+ .replace("%player%", onlinePlayer.getName())
+ .replace("%tax_percentage%", (currency.getTransactionTax() * 100) + "%")
+ .replace("%tax_applied%", currency.format(currency.getTransactionTax() * amount))
+ );
+ //Send msg to target
+ currenciesManager.getRedisManager().getConnectionAsync(commands -> {
+ commands.publish(MSG_CHANNEL.toString(), sender.getName() + ";;" + onlinePlayer.getName() + ";;" + currency.format(amount));
+ //Register transaction
+ return currenciesManager.getExchange().savePaymentTransaction(sender.getUniqueId(), onlinePlayer.getUniqueId(), amount, currency, "Payment to all online players");
+ });
+ }
}
@Override
@@ -129,12 +177,14 @@ private void payCurrency(Player sender, Currency currency, String[] args) {
if (args.length == 1) {
if (args[0].length() < plugin.settings().tab_complete_chars)
return List.of();
- return currenciesManager.getNameUniqueIds().keySet().stream().filter(name -> name.toUpperCase().startsWith(args[0].toUpperCase())).toList();
- } else if (args.length == 2)
- return List.of("69");
- else if (args.length == 3)
+ return currenciesManager.getNameUniqueIds().keySet().stream()
+ .filter(name -> name.toUpperCase().startsWith(args[0].toUpperCase()))
+ .toList();
+ } else if (args.length == 2) {
+ return List.of("1");
+ } else if (args.length == 3) {
return currenciesManager.getCurrencies().stream().map(Currency::getCurrencyName).filter(name -> name.startsWith(args[2]) && sender.hasPermission("rediseconomy.pay." + args[2])).toList();
-
+ }
return List.of();
}
diff --git a/src/main/java/dev/unnm3d/rediseconomy/command/transaction/BrowseTransactionsCommand.java b/src/main/java/dev/unnm3d/rediseconomy/command/transaction/BrowseTransactionsCommand.java
index f4ed64d..6dd22f5 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/command/transaction/BrowseTransactionsCommand.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/command/transaction/BrowseTransactionsCommand.java
@@ -63,8 +63,6 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command
sendTransaction(sender, i, transactions.get(i), afterDateString + " " + beforeDateString);
- if (plugin.settings().debug)
- sender.sendMessage("Time: " + (System.currentTimeMillis() - init));
}
plugin.langs().send(sender, plugin.langs().transactionsEnd
diff --git a/src/main/java/dev/unnm3d/rediseconomy/config/ConfigManager.java b/src/main/java/dev/unnm3d/rediseconomy/config/ConfigManager.java
index 2e20c41..6877b3e 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/config/ConfigManager.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/config/ConfigManager.java
@@ -60,7 +60,8 @@ public void saveConfigs() {
public void loadLangs() {
File settingsFile = new File(plugin.getDataFolder(), settings.lang + ".yml");
if (!settingsFile.exists()) {
- plugin.saveResource("it-IT.yml", false);//save default lang
+ plugin.saveResource("it-IT.yml", false);
+ plugin.saveResource("de-DE.yml", false);
}
langs = YamlConfigurations.update(
settingsFile.toPath(),
diff --git a/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java b/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java
index ca7b3a9..a7b9310 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java
@@ -421,8 +421,11 @@ public EconomyResponse payPlayer(@NotNull String senderName, @NotNull String rec
return new EconomyResponse(amount, getBalance(senderName), EconomyResponse.ResponseType.FAILURE, "Account not found");
if (!hasAccount(receiverName))
return new EconomyResponse(amount, getBalance(receiverName), EconomyResponse.ResponseType.FAILURE, "Account not found");
- UUID sender = currenciesManager.getUUIDFromUsernameCache(senderName);
- UUID receiver = currenciesManager.getUUIDFromUsernameCache(receiverName);
+
+ final UUID sender = currenciesManager.getUUIDFromUsernameCache(senderName);
+ final UUID receiver = currenciesManager.getUUIDFromUsernameCache(receiverName);
+
+ //Calculate the amount to withdraw with the transaction tax
double amountToWithdraw = amount + (amount * transactionTax);
if (sender == null || receiver == null)
return new EconomyResponse(amount, getBalance(senderName), EconomyResponse.ResponseType.FAILURE, "Account not found");
diff --git a/src/main/resources/de-DE.yml b/src/main/resources/de-DE.yml
new file mode 100644
index 0000000..3173812
--- /dev/null
+++ b/src/main/resources/de-DE.yml
@@ -0,0 +1,66 @@
+noConsole: Der Befehl muss inGame eingegeben werden!
+noPermission: Du hast keine berechtigung, den Befehl zu nutzen!
+missingArguments: Zu wenig! Argumente
+playerNotFound: Spieler nicht gefunden!
+invalidAmount: Ungültiger Betrag!
+tooSmallAmount: Der Betrag ist zu klein!
+payCooldown: Deine vorherige Zahlung ist noch in Bearbeitung! Bitte warten
+invalidCurrency: Ungültige Währung!
+insufficientFunds: Du hast nicht genügend Geld!
+balance: Du hast %balance%!
+balanceSet: Du hast das Geld von %player% auf %balance% gesetzt!
+balanceOther: %player% hat %balance% !
+balanceTop: Die reichsten Spieler:
%prevpage% %page% %nextpage%
+blockedAccounts: Gesperrte Accounts:
%list%
+blockedAccountSuccess: Account %player% ist gesperrt!
+unblockedAccountSuccess: Account %player% wurde entsperrt!
+blockedPayment: Deine Zahlung an %player% wurde gesperrt!
+balanceTopFormat: %pos% - %player% %balance%
+paySelf: Du kannst nichts an dich selbst zahlen!
+# Use %tax_percentage% for tax percentage and %tax_applied% for tax applied to the transaction.
+paySuccess: Du hast %player% %amount% gezahlt
+payFail: Zahlung fehlgeschlagen!
+payReceived: Du hast %amount% from %player%!
+purgeUserSuccess: %player% wurde gelöscht!
+purgeBalanceSuccess: Die Währung von %player% wurde auf %currency% zurückgesetzt!
+switchCurrencySuccess: %currency% zu %switch-currency%. gewechselt
Bitte
+ starten Sie jeden Server mit
installiertem RedisEconomy neu, um ein Überschreiben
+ zu vermeiden!
+noTransactionFound: Keine Transaktion von %player% gefunden!
+incorrectDate: Falsches Datumsformat !
+transactionsStart: Transactionen von Spieler %player% von %after% bis %before%!
+transactionsEnd: Die Prüfung von %player%'s Transactionen dauerte %time%
+ ms
+transactionsArchiveCompleted: Archiviere %size% Transactiosdaten nach %file%
+transactionsArchiveProgress: 'Archivierungsstatus: %progress%% '
+editMessageError: Dieser Config-Eintrag ist keine Zeichenfolge oder existiert
+ nicht!
+editMessageClickHere: Klicke hier um die Nachricht zu bearbeiten
+ %field%!
+editMessageSuccess: Erfolgreich gespeichert %field%!
+transactionItem:
+ outgoingFunds: '#%id% Click
+ to copy:
%timestamp%">[Timestamp⌛]
+ [←Revert]
%account-owner%
+ > %amount%%symbol% > %other-account%
Reason:
+ %reason%'
+ incomingFunds: '#%id% Click
+ to copy:
%timestamp%">[Timestamp⌛]
+ [←Revert]
%other-account% > %amount%%symbol%
+ > %account-owner%
Reason:
+ %reason%'
+unitSymbols:
+ thousand: k
+ million: m
+ billion: b
+ trillion: t
+ quadrillion: q
+backupRestoreFinished: Backup/restore der Datei %file% beendet!
+invalidPath: Ungültiger Pfad!
+
+# Authors: Unnm3d
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index a31a8c1..89d0239 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -73,6 +73,9 @@ permissions:
rediseconomy.pay:
description: Allows to use /pay
default: true
+ rediseconomy.payall:
+ description: Allows to use /pay *
+ default: false
rediseconomy.toggle-payments:
description: Allows to use /toggle-payments
default: true
@@ -107,8 +110,10 @@ permissions:
description: Allows to use /transaction
default: false
rediseconomy.pay.*:
- description: Allows to use /pay all currencies
- default: op
+ description: Allows to use /pay all currencies
+ default: op
+ children:
+ rediseconomy.payall: true
rediseconomy.balance.*:
description: Allows to use /balance with other currencies
default: op
From 86dc411c98009259890bc40bafdb6bfc0cd2b4cb Mon Sep 17 00:00:00 2001
From: Emibergo02 <36164338+Emibergo02@users.noreply.github.com>
Date: Wed, 8 May 2024 00:30:16 +0200
Subject: [PATCH 09/25] 4.3.13 Percentage payments are now possible everywhere!
with /pay username 10% you will pay 'username' 10% of your balance. (This
feature is optional, check config.yml)
---
pom.xml | 2 +-
.../rediseconomy/command/PayCommand.java | 2 +-
.../command/balance/BalanceCommand.java | 4 +--
.../dev/unnm3d/rediseconomy/config/Langs.java | 32 ++++++++-----------
.../unnm3d/rediseconomy/config/Settings.java | 2 ++
.../currency/CurrenciesManager.java | 31 +++++++++++++++++-
6 files changed, 49 insertions(+), 24 deletions(-)
diff --git a/pom.xml b/pom.xml
index 0278103..10b8a50 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
dev.unnm3d
RedisEconomy
- 4.3.12
+ 4.3.13
jar
RedisEconomy
diff --git a/src/main/java/dev/unnm3d/rediseconomy/command/PayCommand.java b/src/main/java/dev/unnm3d/rediseconomy/command/PayCommand.java
index e8094d0..e8ac73a 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/command/PayCommand.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/command/PayCommand.java
@@ -66,7 +66,7 @@ private void payCurrency(Player sender, Currency currency, String[] args) {
}
long init = System.currentTimeMillis();
final String target = args[0];
- final double amount = plugin.langs().formatAmountString(args[1]);
+ final double amount = currenciesManager.formatAmountString(sender.getName(), currency, args[1]);
if (amount <= 0) {
plugin.langs().send(sender, plugin.langs().invalidAmount);
return;
diff --git a/src/main/java/dev/unnm3d/rediseconomy/command/balance/BalanceCommand.java b/src/main/java/dev/unnm3d/rediseconomy/command/balance/BalanceCommand.java
index 796438b..9ff8773 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/command/balance/BalanceCommand.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/command/balance/BalanceCommand.java
@@ -36,7 +36,7 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command
selfBalancePlayer(sender, defaultCurrency);
return true;
}
- String target = economy.getCaseSensitiveName(args[0]);
+ final String target = economy.getCaseSensitiveName(args[0]);
if (args.length == 1) {
balancePlayer(sender, defaultCurrency, target);
} else if (args.length == 2) {
@@ -62,7 +62,7 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command
plugin.langs().send(sender, plugin.langs().invalidCurrency);
return true;
}
- double amount = plugin.langs().formatAmountString(args[3]);
+ double amount = plugin.getCurrenciesManager().formatAmountString(target, currency, args[3]);
if (amount < 0) {
plugin.langs().send(sender, plugin.langs().invalidAmount);
return true;
diff --git a/src/main/java/dev/unnm3d/rediseconomy/config/Langs.java b/src/main/java/dev/unnm3d/rediseconomy/config/Langs.java
index c314284..e054bdc 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/config/Langs.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/config/Langs.java
@@ -9,6 +9,8 @@
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Field;
+import java.util.NavigableMap;
+import java.util.TreeMap;
@Configuration
public final class Langs {
@@ -75,27 +77,19 @@ public record UnitSymbols(
) {
}
- public void send(CommandSender sender, String text) {
- audiences.sender(sender).sendMessage(MiniMessage.miniMessage().deserialize(text));
+ public NavigableMap getSuffixes() {
+ return new TreeMap<>() {{
+ put(unitSymbols.thousand(), 1_000L);
+ put(unitSymbols.million(), 1_000_000L);
+ put(unitSymbols.billion(), 1_000_000_000L);
+ put(unitSymbols.trillion(), 1_000_000_000_000L);
+ put(unitSymbols.quadrillion(), 1_000_000_000_000_000L);
+ }};
+
}
- public double formatAmountString(String amount) {
- try {
- if (amount.endsWith(unitSymbols.quadrillion())) {
- return Double.parseDouble(amount.substring(0, amount.length() - unitSymbols.quadrillion().length())) * 1_000_000_000_000_000D;
- } else if (amount.endsWith(unitSymbols.trillion())) {
- return Double.parseDouble(amount.substring(0, amount.length() - unitSymbols.trillion().length())) * 1_000_000_000_000D;
- } else if (amount.endsWith(unitSymbols.billion())) {
- return Double.parseDouble(amount.substring(0, amount.length() - unitSymbols.billion().length())) * 1_000_000_000D;
- } else if (amount.endsWith(unitSymbols.million())) {
- return Double.parseDouble(amount.substring(0, amount.length() - unitSymbols.million().length())) * 1_000_000D;
- } else if (amount.endsWith(unitSymbols.thousand())) {
- return Double.parseDouble(amount.substring(0, amount.length() - unitSymbols.thousand().length())) * 1_000D;
- }
- return Double.parseDouble(amount);
- } catch (NumberFormatException e) {
- return -1;
- }
+ public void send(CommandSender sender, String text) {
+ audiences.sender(sender).sendMessage(MiniMessage.miniMessage().deserialize(text));
}
public @Nullable Field getStringField(String name) throws NoSuchFieldException {
diff --git a/src/main/java/dev/unnm3d/rediseconomy/config/Settings.java b/src/main/java/dev/unnm3d/rediseconomy/config/Settings.java
index bef8cbc..f94c7c1 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/config/Settings.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/config/Settings.java
@@ -23,6 +23,8 @@ public class Settings {
@Comment({"if true, migrates the bukkit offline uuids accounts to the default RedisEconomy currency",
"During the migration, the plugin will be disabled. Restart all RedisEconomy instances after the migration."})
public boolean migrationEnabled = false;
+ @Comment("Allow paying with percentage (ex: /pay player 10% sends 'player' 10% of the sender balance)")
+ public boolean allowPercentagePayments = true;
@Comment({"Leave password or user empty if you don't have a password or user",
"Don't use the default credentials in production!! Generate new credentials on RedisLabs -> https://github.com/Emibergo02/RedisEconomy/wiki/Install-redis",
"Default credentials lead to a non-persistent redis server, only for testing!!",
diff --git a/src/main/java/dev/unnm3d/rediseconomy/currency/CurrenciesManager.java b/src/main/java/dev/unnm3d/rediseconomy/currency/CurrenciesManager.java
index 3e78fc1..1354d8a 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/currency/CurrenciesManager.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/currency/CurrenciesManager.java
@@ -70,7 +70,7 @@ public CurrenciesManager(RedisManager redisManager, RedisEconomyPlugin plugin, C
currencies.put(currencySettings.currencyName(), currency);
});
if (currencies.get(configManager.getSettings().defaultCurrencyName) == null) {
- currencies.put(configManager.getSettings().defaultCurrencyName, new Currency(this, new Settings.CurrencySettings(configManager.getSettings().defaultCurrencyName, "€", "€", "#.##", "en-US", 0.0, Double.POSITIVE_INFINITY,0.0, true,true, false)));
+ currencies.put(configManager.getSettings().defaultCurrencyName, new Currency(this, new Settings.CurrencySettings(configManager.getSettings().defaultCurrencyName, "€", "€", "#.##", "en-US", 0.0, Double.POSITIVE_INFINITY, 0.0, true, true, false)));
}
registerPayMsgChannel();
registerBlockAccountChannel();
@@ -415,6 +415,35 @@ public boolean isAccountLocked(UUID uuid, UUID target) {
getLockedAccounts(uuid).contains(RedisKeys.getAllAccountUUID());
}
+ /**
+ * Formats the amount string to a double
+ * Parses suffixes (10k, 10M for 10 thousand and 10 million)
+ * Parses percentages ("10%" for 10% of the accountOwner balance)
+ *
+ * @param targetName The account that has to be modified
+ * @param currency the currency to format the amount
+ * @param amount the amount to format
+ * @return the formatted amount
+ */
+ public double formatAmountString(String targetName, Currency currency, String amount) {
+ try {
+ //Check if last char of amount is number
+ if (Character.isDigit(amount.charAt(amount.length() - 1))) {
+ return Double.parseDouble(amount);
+ }
+ double parsedAmount = Double.parseDouble(amount.substring(0, amount.length() - 1));
+ return amount.endsWith("%") && plugin.settings().allowPercentagePayments ?
+ //Percentage 20%
+ parsedAmount / 100 * currency.getBalance(targetName) :
+ //Parse suffixes from map
+ parsedAmount * plugin.langs().getSuffixes()
+ .getOrDefault(amount.substring(amount.length() - 1), -1L);
+ } catch (NumberFormatException e) {
+ plugin.langs().send(Bukkit.getConsoleSender(), plugin.langs().invalidAmount);
+ }
+ return -1;
+ }
+
public List getLockedAccounts(UUID uuid) {
return lockedAccounts.getOrDefault(uuid, new ArrayList<>());
}
From f7ae0e03de06622135f7ab5618be2bd00b110133 Mon Sep 17 00:00:00 2001
From: Emibergo02 <36164338+Emibergo02@users.noreply.github.com>
Date: Thu, 9 May 2024 18:43:05 +0200
Subject: [PATCH 10/25] 4.3.14 Got rid of the serverId UUID. Now it is randomly
generated and NOT configurable. Placeholder update time changed to 5 seconds
---
.../dev/unnm3d/rediseconomy/RedisEconomyPlugin.java | 7 ++++++-
.../dev/unnm3d/rediseconomy/command/MainCommand.java | 6 ++----
.../unnm3d/rediseconomy/config/ConfigManager.java | 10 ----------
.../dev/unnm3d/rediseconomy/currency/Currency.java | 4 ++--
.../rediseconomy/currency/CurrencyWithBanks.java | 12 ++++++------
.../rediseconomy/utils/PlaceholderAPIHook.java | 2 +-
6 files changed, 17 insertions(+), 24 deletions(-)
diff --git a/src/main/java/dev/unnm3d/rediseconomy/RedisEconomyPlugin.java b/src/main/java/dev/unnm3d/rediseconomy/RedisEconomyPlugin.java
index 69a2225..f03a77e 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/RedisEconomyPlugin.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/RedisEconomyPlugin.java
@@ -30,6 +30,7 @@
import org.bukkit.plugin.java.JavaPlugin;
import java.time.Duration;
+import java.util.UUID;
import java.util.concurrent.TimeUnit;
public final class RedisEconomyPlugin extends JavaPlugin {
@@ -45,6 +46,8 @@ public final class RedisEconomyPlugin extends JavaPlugin {
private TaskScheduler scheduler;
@Getter
private Plugin vaultPlugin;
+ @Getter
+ private static UUID instanceUUID;
public Settings settings() {
@@ -58,6 +61,8 @@ public Langs langs() {
@Override
public void onLoad() {
instance = this;
+ //Generate a unique instance id to not send redis updates to itself
+ instanceUUID = UUID.randomUUID();
this.configManager = new ConfigManager(this);
@@ -75,7 +80,7 @@ public void onEnable() {
if (redisManager == null) return;
this.scheduler = UniversalScheduler.getScheduler(this);
- this.configManager.postStartupLoad();
+ this.configManager.loadLangs();
this.vaultPlugin = getServer().getPluginManager().getPlugin("Vault");
if (this.vaultPlugin == null) { //creates currenciesManager and exchange
this.getLogger().severe("Disabled due to no Vault dependency found!");
diff --git a/src/main/java/dev/unnm3d/rediseconomy/command/MainCommand.java b/src/main/java/dev/unnm3d/rediseconomy/command/MainCommand.java
index 2e143ba..359c155 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/command/MainCommand.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/command/MainCommand.java
@@ -27,13 +27,11 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command
} else if (args.length == 1) {
if (!args[0].equalsIgnoreCase("reload")) return true;
if (!sender.hasPermission("rediseconomy.admin")) return true;
- String serverId = plugin.getConfigManager().getSettings().serverId; //Keep serverId
plugin.getConfigManager().loadSettingsConfig();//Reload configs
- plugin.getConfigManager().loadLangs();
- plugin.getConfigManager().getSettings().serverId = serverId; //Restore serverId
+ plugin.getConfigManager().loadLangs(); //Reload langs
plugin.getConfigManager().saveConfigs(); //Save configs
this.adventureWebuiEditorAPI = new AdventureWebuiEditorAPI(plugin.getConfigManager().getSettings().webEditorUrl);
- sender.sendMessage("§aReloaded successfully " + plugin.getConfigManager().getSettings().serverId + "!");
+ sender.sendMessage("§aReloaded successfully!");
return true;
}
String langField = args[1];
diff --git a/src/main/java/dev/unnm3d/rediseconomy/config/ConfigManager.java b/src/main/java/dev/unnm3d/rediseconomy/config/ConfigManager.java
index 6877b3e..4f0e256 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/config/ConfigManager.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/config/ConfigManager.java
@@ -7,7 +7,6 @@
import java.io.File;
import java.nio.charset.StandardCharsets;
-import java.util.UUID;
public class ConfigManager {
private final RedisEconomyPlugin plugin;
@@ -34,16 +33,7 @@ public ConfigManager(RedisEconomyPlugin plugin) {
loadSettingsConfig();
}
- public void postStartupLoad() {
- loadLangs();
- if (settings.serverId == null || settings.serverId.isEmpty()) {
- settings.serverId = String.valueOf(UUID.randomUUID());
- saveConfigs();
- }
- }
-
public void loadSettingsConfig() {
-
File settingsFile = new File(plugin.getDataFolder(), "config.yml");
settings = YamlConfigurations.update(
settingsFile.toPath(),
diff --git a/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java b/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java
index a7b9310..705b00e 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java
@@ -99,7 +99,7 @@ public void message(String channel, String message) {
Bukkit.getLogger().severe("Invalid message received from RedisEco channel, consider updating RedisEconomy");
return;
}
- if (split[0].equals(RedisEconomyPlugin.getInstance().settings().serverId)) return;
+ if (split[0].equals(RedisEconomyPlugin.getInstanceUUID().toString())) return;
UUID uuid = UUID.fromString(split[1]);
String playerName = split[2];
double balance = Double.parseDouble(split[3]);
@@ -547,7 +547,7 @@ private synchronized void updateAccountCloudCache(@NotNull UUID uuid, @Nullable
if (playerName != null)
reactiveCommands.hset(NAME_UUID.toString(), playerName, uuid.toString());
reactiveCommands.publish(UPDATE_PLAYER_CHANNEL_PREFIX + currencyName,
- RedisEconomyPlugin.getInstance().settings().serverId + ";;" + uuid + ";;" + playerName + ";;" + balance);
+ RedisEconomyPlugin.getInstanceUUID().toString() + ";;" + uuid + ";;" + playerName + ";;" + balance);
}).ifPresentOrElse(result -> {
if (RedisEconomyPlugin.getInstance().settings().debug) {
diff --git a/src/main/java/dev/unnm3d/rediseconomy/currency/CurrencyWithBanks.java b/src/main/java/dev/unnm3d/rediseconomy/currency/CurrencyWithBanks.java
index 214643f..445e4ca 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/currency/CurrencyWithBanks.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/currency/CurrencyWithBanks.java
@@ -34,14 +34,14 @@ public CurrencyWithBanks(CurrenciesManager currenciesManager, Settings.CurrencyS
for (ScoredValue scoredValue : list) {
bankAccounts.put(scoredValue.getValue(), scoredValue.getScore());
}
- if (RedisEconomyPlugin.getInstance().settings().debug && bankAccounts.size() > 0) {
+ if (RedisEconomyPlugin.getInstance().settings().debug && !bankAccounts.isEmpty()) {
Bukkit.getLogger().info("start1bank Loaded " + bankAccounts.size() + " accounts for currency " + currencyName);
}
return list;
}).toCompletableFuture().join();
getRedisBankOwners().thenApply(map -> {
map.forEach((k, v) -> bankOwners.put(k, UUID.fromString(v)));
- if (RedisEconomyPlugin.getInstance().settings().debug && bankOwners.size() > 0) {
+ if (RedisEconomyPlugin.getInstance().settings().debug && !bankOwners.isEmpty()) {
Bukkit.getLogger().info("start1bankb Loaded " + bankOwners.size() + " accounts owners for currency " + currencyName);
}
return map;
@@ -60,7 +60,7 @@ public void message(String channel, String message) {
Bukkit.getLogger().severe("Invalid message received from RedisEco channel, consider updating RedisEconomy");
return;
}
- if (split[0].equals(RedisEconomyPlugin.getInstance().settings().serverId)) return;
+ if (split[0].equals(RedisEconomyPlugin.getInstanceUUID().toString())) return;
String accountId = split[1];
UUID owner = UUID.fromString(split[2]);
bankOwners.put(accountId, owner);
@@ -85,7 +85,7 @@ public void message(String channel, String message) {
Bukkit.getLogger().severe("Invalid message received from RedisEco channel, consider updating RedisEconomy");
return;
}
- if (split[0].equals(RedisEconomyPlugin.getInstance().settings().serverId)) return;
+ if (split[0].equals(RedisEconomyPlugin.getInstanceUUID().toString())) return;
String accountId = split[1];
double balance = Double.parseDouble(split[2]);
updateBankAccountLocal(accountId, balance);
@@ -269,7 +269,7 @@ public CompletionStage revertTransaction(int transactionId, @NotNull Tr
private void setOwner(@NotNull String accountId, UUID ownerUUID) {
currenciesManager.getRedisManager().getConnectionPipeline(connection -> {
connection.hset(BANK_OWNERS.toString(), accountId, ownerUUID.toString());
- return connection.publish(UPDATE_BANK_OWNER_CHANNEL_PREFIX + currencyName, RedisEconomyPlugin.getInstance().settings().serverId + ";;" + accountId + ";;" + ownerUUID);
+ return connection.publish(UPDATE_BANK_OWNER_CHANNEL_PREFIX + currencyName, RedisEconomyPlugin.getInstanceUUID().toString() + ";;" + accountId + ";;" + ownerUUID);
}).thenAccept((result) -> {
if (RedisEconomyPlugin.getInstance().settings().debug) {
Bukkit.getLogger().info("Set owner of bank " + accountId + " to " + ownerUUID + " with result " + result);
@@ -291,7 +291,7 @@ private synchronized void updateBankAccountCloudCache(@NotNull String accountId,
updateExecutor.submit(() -> {
currenciesManager.getRedisManager().executeTransaction(reactiveCommands -> {
reactiveCommands.zadd(BALANCE_BANK_PREFIX + currencyName, balance, accountId);
- reactiveCommands.publish(UPDATE_BANK_CHANNEL_PREFIX + currencyName, RedisEconomyPlugin.getInstance().settings().serverId + ";;" + accountId + ";;" + balance);
+ reactiveCommands.publish(UPDATE_BANK_CHANNEL_PREFIX + currencyName, RedisEconomyPlugin.getInstanceUUID().toString() + ";;" + accountId + ";;" + balance);
}).ifPresentOrElse(result -> {
if (RedisEconomyPlugin.getInstance().settings().debug) {
Bukkit.getLogger().info("01 Sent bank update accoun " + accountId + " to " + balance);
diff --git a/src/main/java/dev/unnm3d/rediseconomy/utils/PlaceholderAPIHook.java b/src/main/java/dev/unnm3d/rediseconomy/utils/PlaceholderAPIHook.java
index 01744d2..ae0eb44 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/utils/PlaceholderAPIHook.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/utils/PlaceholderAPIHook.java
@@ -30,7 +30,7 @@ public PlaceholderAPIHook(RedisEconomyPlugin redisEconomyPlugin) {
this.langs = redisEconomyPlugin.langs();
this.totalSupplyCache = new HashMap<>();
this.baltopCache = new HashMap<>();
- this.updateCachePeriod = 1000 * 20; // 1 minute
+ this.updateCachePeriod = 1000 * 5; // 5 secs
this.lastUpdateTimestamp = 0;
this.plugin = redisEconomyPlugin;
this.prefixProvider = redisEconomyPlugin.getServer().getServicesManager().getRegistration(net.milkbowl.vault.chat.Chat.class);
From 3338e61c6cf473a1e63d5525b0494580bf487c14 Mon Sep 17 00:00:00 2001
From: Emibergo02 <36164338+Emibergo02@users.noreply.github.com>
Date: Sat, 18 May 2024 12:05:15 +0200
Subject: [PATCH 11/25] Bump version
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 10b8a50..226588d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
dev.unnm3d
RedisEconomy
- 4.3.13
+ 4.3.14
jar
RedisEconomy
From 583d39bd7291c068ebf1f0f2994e3e0ef9f4095d Mon Sep 17 00:00:00 2001
From: Emibergo02 <36164338+Emibergo02@users.noreply.github.com>
Date: Fri, 7 Jun 2024 12:48:58 +0200
Subject: [PATCH 12/25] Update README.md
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index ffa50cd..4556ac0 100644
--- a/README.md
+++ b/README.md
@@ -38,7 +38,7 @@ dependencies {
}
```
## API usage
-
+YOU PROBABLY DON'T NEED TO USE REDISECONOMY API: USE VAULT API https://github.com/MilkBowl/VaultAPI
```java
// Access Point
RedisEconomyAPI api = RedisEconomyAPI.getAPI();
@@ -53,7 +53,7 @@ api.getCurrencyBySymbol("€");//Gets the currency by symbol
//Currency is a Vault Economy https://github.com/MilkBowl/VaultAPI/blob/master/src/main/java/net/milkbowl/vault/economy/Economy.java,
//same methods and everything
currency.getBalance(offlinePlayer);
-currency.withdrawPlayer(offlinePlayer, 100);
+currency.withdrawPlayer(offlinePlayer, 100, "Reason of withdrawal");
//Modify a player balance (default currency)
api.getDefaultCurrency().setPlayerBalance(player.getUniqueId(), 1000);
From c692ee0f338848d5bd3baa93fbce22742b551761 Mon Sep 17 00:00:00 2001
From: Emibergo02 <36164338+Emibergo02@users.noreply.github.com>
Date: Sun, 1 Sep 2024 22:19:19 +0200
Subject: [PATCH 13/25] Better timeout handling in updateAccountCloudCache
Added configurable poolSize in config Added expandpool command to adjust the
redis pool size at runtime
---
pom.xml | 15 ++--
.../rediseconomy/RedisEconomyPlugin.java | 2 +-
.../rediseconomy/command/MainCommand.java | 18 ++++-
.../unnm3d/rediseconomy/config/Settings.java | 4 +-
.../rediseconomy/currency/Currency.java | 69 ++++++++++++-------
.../currency/CurrencyWithBanks.java | 55 ++++++++++-----
.../rediseconomy/redis/RedisManager.java | 13 +++-
.../redis/RoundRobinConnectionPool.java | 15 ++++
src/main/resources/plugin.yml | 6 +-
9 files changed, 143 insertions(+), 54 deletions(-)
diff --git a/pom.xml b/pom.xml
index 226588d..8e5ac5c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
dev.unnm3d
RedisEconomy
- 4.3.14
+ 4.3.15
jar
RedisEconomy
@@ -113,6 +113,11 @@
placeholderapi
https://repo.extendedclip.com/content/repositories/placeholderapi/
+
+ maven_central
+ Maven Central
+ https://repo.maven.apache.org/maven2/
+
@@ -131,18 +136,18 @@
org.projectlombok
lombok
- 1.18.32
+ 1.18.34
provided
net.kyori
adventure-text-minimessage
- 4.16.0
+ 4.17.0
net.kyori
adventure-platform-bukkit
- 4.3.2
+ 4.3.3
me.clip
@@ -153,7 +158,7 @@
io.lettuce
lettuce-core
- 6.3.2.RELEASE
+ 6.4.0.RELEASE
provided
diff --git a/src/main/java/dev/unnm3d/rediseconomy/RedisEconomyPlugin.java b/src/main/java/dev/unnm3d/rediseconomy/RedisEconomyPlugin.java
index f03a77e..897e028 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/RedisEconomyPlugin.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/RedisEconomyPlugin.java
@@ -159,7 +159,7 @@ private boolean setupRedis() {
redisURIBuilder.withAuthentication(configManager.getSettings().redis.user(), configManager.getSettings().redis.password());
getLogger().info("Connecting to redis server " + redisURIBuilder.build().toString() + "...");
- this.redisManager = new RedisManager(RedisClient.create(redisURIBuilder.build()));
+ this.redisManager = new RedisManager(RedisClient.create(redisURIBuilder.build()), configManager.getSettings().redis.poolSize());
redisManager.isConnected().get(1, java.util.concurrent.TimeUnit.SECONDS);
if (!configManager.getSettings().clusterId.isEmpty())
RedisKeys.setClusterId(configManager.getSettings().clusterId);
diff --git a/src/main/java/dev/unnm3d/rediseconomy/command/MainCommand.java b/src/main/java/dev/unnm3d/rediseconomy/command/MainCommand.java
index 359c155..d54b7f1 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/command/MainCommand.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/command/MainCommand.java
@@ -36,6 +36,20 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command
}
String langField = args[1];
+ if (args[0].equalsIgnoreCase("expandpool")) {
+ if (!sender.hasPermission("rediseconomy.admin.expandpool")) {
+ plugin.getConfigManager().getLangs().send(sender, plugin.getConfigManager().getLangs().noPermission);
+ return true;
+ }
+ try {
+ plugin.getCurrenciesManager().getRedisManager().expandPool(Integer.parseInt(args[1]));
+ plugin.getConfigManager().getLangs().send(sender, "§aPool expanded successfully!");
+ } catch (Exception e) {
+ plugin.getConfigManager().getLangs().send(sender, "§cError expanding pool: " + e.getMessage());
+ }
+ return true;
+ }
+
if (!sender.hasPermission("rediseconomy.admin.editmessage")) {
plugin.getConfigManager().getLangs().send(sender, plugin.getConfigManager().getLangs().noPermission);
return true;
@@ -81,7 +95,9 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command
@Override
public @NotNull List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
if (args.length == 1) {
- return List.of("reload", "editmessage");
+ return List.of("reload", "editmessage", "expandpool");
+ } else if (args.length == 2 && args[0].equalsIgnoreCase("expandpool")) {
+ return List.of("1", "2", "3", "4", "5");
} else if (args.length == 2 && sender.hasPermission("rediseconomy.admin.editmessage")) {
return Arrays.stream(plugin.getConfigManager().getLangs().getClass().getFields()).filter(field -> field.getType().equals(String.class)).map(Field::getName).toList();
}
diff --git a/src/main/java/dev/unnm3d/rediseconomy/config/Settings.java b/src/main/java/dev/unnm3d/rediseconomy/config/Settings.java
index f94c7c1..f531f58 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/config/Settings.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/config/Settings.java
@@ -29,7 +29,7 @@ public class Settings {
"Don't use the default credentials in production!! Generate new credentials on RedisLabs -> https://github.com/Emibergo02/RedisEconomy/wiki/Install-redis",
"Default credentials lead to a non-persistent redis server, only for testing!!",
})
- public RedisSettings redis = new RedisSettings("localhost", 6379, "", "", 0, 2000, "RedisEconomy");
+ public RedisSettings redis = new RedisSettings("localhost", 6379, "", "", 0, 300, "RedisEconomy", 5, 3);
@Comment({"All RedisEconomy instances with the same cluster id will share the same data"})
public String clusterId = "";
@Comment({"How many chars are needed for a command autocompletion", "Increase if you have a lot of players to list"})
@@ -50,6 +50,6 @@ public record CurrencySettings(String currencyName, String currencySingle, Strin
}
public record RedisSettings(String host, int port, String user, String password, int database, int timeout,
- String clientName) {
+ String clientName, int poolSize, int tryAgainCount) {
}
}
diff --git a/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java b/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java
index 705b00e..db10882 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java
@@ -18,10 +18,7 @@
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.*;
-import java.util.concurrent.CompletionStage;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
+import java.util.concurrent.*;
import static dev.unnm3d.rediseconomy.redis.RedisKeys.*;
@@ -541,30 +538,52 @@ protected void updateAccount(@NotNull UUID uuid, @Nullable String playerName, do
}
private synchronized void updateAccountCloudCache(@NotNull UUID uuid, @Nullable String playerName, double balance, int tries) {
- updateExecutor.submit(() -> {
- currenciesManager.getRedisManager().executeTransaction(reactiveCommands -> {
- reactiveCommands.zadd(BALANCE_PREFIX + currencyName, balance, uuid.toString());
- if (playerName != null)
- reactiveCommands.hset(NAME_UUID.toString(), playerName, uuid.toString());
- reactiveCommands.publish(UPDATE_PLAYER_CHANNEL_PREFIX + currencyName,
- RedisEconomyPlugin.getInstanceUUID().toString() + ";;" + uuid + ";;" + playerName + ";;" + balance);
- }).ifPresentOrElse(result -> {
-
- if (RedisEconomyPlugin.getInstance().settings().debug) {
- Bukkit.getLogger().info("01 Sent update account " + playerName + " to " + balance + " currency " + currencyName);
- }
- }, () -> {
- if (tries < 3) {
- Bukkit.getLogger().severe("Player accounts are desynchronized");
- updateAccountCloudCache(uuid, playerName, balance, tries + 1);
- } else {
- Bukkit.getLogger().severe("Failed to update account " + playerName + " after 3 tries");
- throw new RuntimeException("Player accounts are desynchronized");
+ final RedisEconomyPlugin plugin = RedisEconomyPlugin.getInstance();
+ try {
+ updateExecutor.submit(() -> {
+ try {
+ if (plugin.settings().debug) {
+ Bukkit.getLogger().info("01a Starting update account " + playerName + " to " + balance + " currency " + currencyName);
+ }
+ currenciesManager.getRedisManager().executeTransaction(reactiveCommands -> {
+ reactiveCommands.zadd(BALANCE_PREFIX + currencyName, balance, uuid.toString());
+ if (playerName != null)
+ reactiveCommands.hset(NAME_UUID.toString(), playerName, uuid.toString());
+ reactiveCommands.publish(UPDATE_PLAYER_CHANNEL_PREFIX + currencyName,
+ RedisEconomyPlugin.getInstanceUUID().toString() + ";;" + uuid + ";;" + playerName + ";;" + balance);
+ if (plugin.settings().debug) {
+ plugin.getLogger().info("01b Publishing update account " + playerName + " to " + balance + " currency " + currencyName);
+ }
+ }).ifPresentOrElse(result -> {
+ if (RedisEconomyPlugin.getInstance().settings().debug) {
+ plugin.getLogger().info("01c Sent update account successfully " + playerName + " to " + balance + " currency " + currencyName);
+ }
+ }, () -> handleException(uuid, playerName, balance, tries, null));
+ } catch (Exception e) {
+ handleException(uuid, playerName, balance, tries, e);
}
- });
- });
+ }).get(plugin.settings().redis.timeout(), TimeUnit.MILLISECONDS);
+ } catch (InterruptedException | TimeoutException | ExecutionException e) {
+ handleException(uuid, playerName, balance, tries, e);
+ }
}
+ private void handleException(@NotNull UUID uuid, @Nullable String playerName, double balance, int tries, @Nullable Exception e) {
+ final RedisEconomyPlugin plugin = RedisEconomyPlugin.getInstance();
+ if (tries < plugin.settings().redis.tryAgainCount()) {
+ plugin.getLogger().warning("Player accounts are desynchronized. try: " + tries);
+ if (e != null)
+ plugin.getLogger().warning(e.getMessage());
+ updateAccountCloudCache(uuid, playerName, balance, tries + 1);
+ } else {
+ plugin.getLogger().severe("Failed to update account " + playerName + " after " + tries + " tries");
+ currenciesManager.getRedisManager().printPool();
+ if (e != null)
+ throw new RuntimeException(e);
+ }
+ }
+
+
/**
* Update the balances of all players and their nameuuids
* Do not use this method unless you know what you are doing
diff --git a/src/main/java/dev/unnm3d/rediseconomy/currency/CurrencyWithBanks.java b/src/main/java/dev/unnm3d/rediseconomy/currency/CurrencyWithBanks.java
index 445e4ca..14d33b1 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/currency/CurrencyWithBanks.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/currency/CurrencyWithBanks.java
@@ -10,12 +10,12 @@
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Map;
import java.util.UUID;
-import java.util.concurrent.CompletionStage;
-import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.*;
import static dev.unnm3d.rediseconomy.redis.RedisKeys.*;
@@ -288,24 +288,45 @@ private void updateBankAccount(@NotNull String accountId, double balance) {
}
private synchronized void updateBankAccountCloudCache(@NotNull String accountId, double balance, int tries) {
- updateExecutor.submit(() -> {
- currenciesManager.getRedisManager().executeTransaction(reactiveCommands -> {
- reactiveCommands.zadd(BALANCE_BANK_PREFIX + currencyName, balance, accountId);
- reactiveCommands.publish(UPDATE_BANK_CHANNEL_PREFIX + currencyName, RedisEconomyPlugin.getInstanceUUID().toString() + ";;" + accountId + ";;" + balance);
- }).ifPresentOrElse(result -> {
+ try {
+ updateExecutor.submit(() -> {
if (RedisEconomyPlugin.getInstance().settings().debug) {
- Bukkit.getLogger().info("01 Sent bank update accoun " + accountId + " to " + balance);
+ Bukkit.getLogger().info("01a Starting update bank account " + accountId + " to " + balance + " currency " + currencyName);
}
- }, () -> {
- if (tries < 3) {
- Bukkit.getLogger().severe("Player accounts are desynchronized");
- updateBankAccountCloudCache(accountId, balance, tries + 1);
- } else {
- Bukkit.getLogger().severe("Failed to update account " + accountId + " after 3 tries");
- throw new RuntimeException("Bank accounts are desynchronized");
+ try {
+ currenciesManager.getRedisManager().executeTransaction(reactiveCommands -> {
+ reactiveCommands.zadd(BALANCE_BANK_PREFIX + currencyName, balance, accountId);
+ reactiveCommands.publish(UPDATE_BANK_CHANNEL_PREFIX + currencyName, RedisEconomyPlugin.getInstanceUUID().toString() + ";;" + accountId + ";;" + balance);
+ if (RedisEconomyPlugin.getInstance().settings().debug) {
+ RedisEconomyPlugin.getInstance().getLogger().info("01b Publishing update bank account " + accountId + " to " + balance + " currency " + currencyName);
+ }
+ }).ifPresentOrElse(result -> {
+ if (RedisEconomyPlugin.getInstance().settings().debug) {
+ Bukkit.getLogger().info("01c Sent bank update account " + accountId + " to " + balance);
+ }
+ }, () -> handleException(accountId, balance, tries, null));
+ } catch (Exception e) {
+ handleException(accountId, balance, tries, e);
}
- });
- });
+ }).get(RedisEconomyPlugin.getInstance().settings().redis.timeout(), TimeUnit.MILLISECONDS);
+ } catch (InterruptedException | TimeoutException | ExecutionException e) {
+ handleException(accountId, balance, tries, e);
+ }
+ }
+
+ private void handleException(@NotNull String accountId, double balance, int tries, @Nullable Exception e) {
+ final RedisEconomyPlugin plugin = RedisEconomyPlugin.getInstance();
+ if (tries < plugin.settings().redis.tryAgainCount()) {
+ plugin.getLogger().warning("Player accounts are desynchronized. try: " + tries);
+ if (e != null)
+ plugin.getLogger().warning(e.getMessage());
+ updateBankAccountCloudCache(accountId, balance, tries + 1);
+ } else {
+ plugin.getLogger().severe("Failed to update bank account " + accountId + " after " + tries + " tries");
+ currenciesManager.getRedisManager().printPool();
+ if (e != null)
+ throw new RuntimeException(e);
+ }
}
/**
diff --git a/src/main/java/dev/unnm3d/rediseconomy/redis/RedisManager.java b/src/main/java/dev/unnm3d/rediseconomy/redis/RedisManager.java
index 6939cb9..1da0f61 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/redis/RedisManager.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/redis/RedisManager.java
@@ -1,5 +1,6 @@
package dev.unnm3d.rediseconomy.redis;
+import dev.unnm3d.rediseconomy.RedisEconomyPlugin;
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisFuture;
import io.lettuce.core.TransactionResult;
@@ -25,9 +26,9 @@ public class RedisManager {
private final List> pubSubConnections;
protected RedisClient lettuceRedisClient;
- public RedisManager(RedisClient lettuceRedisClient) {
+ public RedisManager(RedisClient lettuceRedisClient, int poolSize) {
this.lettuceRedisClient = lettuceRedisClient;
- this.roundRobinConnectionPool = new RoundRobinConnectionPool<>(lettuceRedisClient::connect, 5);
+ this.roundRobinConnectionPool = new RoundRobinConnectionPool<>(lettuceRedisClient::connect, poolSize);
pubSubConnections = new CopyOnWriteArrayList<>();
}
@@ -61,6 +62,14 @@ public StatefulRedisPubSubConnection getPubSubConnection() {
return pubSubConnection;
}
+ public void expandPool(int expandBy) {
+ roundRobinConnectionPool.expandPool(expandBy);
+ }
+
+ public void printPool() {
+ RedisEconomyPlugin.getInstance().getLogger().warning(roundRobinConnectionPool.printPool());
+ }
+
public void close() {
pubSubConnections.forEach(StatefulRedisPubSubConnection::close);
lettuceRedisClient.shutdown(Duration.ofSeconds(1), Duration.ofSeconds(1));
diff --git a/src/main/java/dev/unnm3d/rediseconomy/redis/RoundRobinConnectionPool.java b/src/main/java/dev/unnm3d/rediseconomy/redis/RoundRobinConnectionPool.java
index 6dd131e..ea81571 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/redis/RoundRobinConnectionPool.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/redis/RoundRobinConnectionPool.java
@@ -41,6 +41,21 @@ public StatefulRedisConnection get() {
return connection;
}
+ public String printPool() {
+ StringBuilder sb = new StringBuilder();
+ for (StatefulRedisConnection element : elements) {
+ sb.append("Open: ")
+ .append(element.isOpen())
+ .append(", multi: ")
+ .append(element.isMulti())
+ .append(", hash")
+ .append(element.hashCode())
+ .append("\n");
+ }
+ return sb.toString();
+ }
+
+
public void close() {
for (StatefulRedisConnection element : elements) {
element.closeAsync();
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 89d0239..4e7f1fd 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -6,7 +6,7 @@ load: STARTUP
depend:
- Vault
libraries:
- - io.lettuce:lettuce-core:6.3.2.RELEASE
+ - io.lettuce:lettuce-core:6.4.0.RELEASE
- de.exlll:configlib-yaml:4.5.0
softdepend:
- PlaceholderAPI
@@ -109,6 +109,9 @@ permissions:
rediseconomy.admin.transaction:
description: Allows to use /transaction
default: false
+ rediseconomy.admin.expandpool:
+ description: Allows to expand the pool
+ default: false
rediseconomy.pay.*:
description: Allows to use /pay all currencies
default: op
@@ -128,3 +131,4 @@ permissions:
rediseconomy.admin.editmessage: true
rediseconomy.admin.backup-restore: true
rediseconomy.admin.archive-transactions: true
+ rediseconomy.admin.expandpool: true
From 392daf8c2e87c1178bda575db001c0b59e4c53bf Mon Sep 17 00:00:00 2001
From: Emibergo02 <36164338+Emibergo02@users.noreply.github.com>
Date: Sun, 1 Sep 2024 22:19:19 +0200
Subject: [PATCH 14/25] Better timeout handling in updateAccountCloudCache
Added configurable poolSize in config Added expandpool command to adjust the
redis pool size at runtime
---
.../java/dev/unnm3d/rediseconomy/config/ConfigManager.java | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/main/java/dev/unnm3d/rediseconomy/config/ConfigManager.java b/src/main/java/dev/unnm3d/rediseconomy/config/ConfigManager.java
index 4f0e256..ba966dc 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/config/ConfigManager.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/config/ConfigManager.java
@@ -22,7 +22,7 @@ public class ConfigManager {
┃ RedisEconomy Config ┃
┃ Developed by Unnm3d ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
- """
+ """
)
.footer("Authors: Unnm3d")
.charset(StandardCharsets.UTF_8)
@@ -40,6 +40,8 @@ public void loadSettingsConfig() {
Settings.class,
PROPERTIES
);
+ if (settings.redis.tryAgainCount() < 2 || settings.redis.poolSize() < 2)
+ plugin.getLogger().severe("Please regenerate the redis configuration section. New settings have been added.");
}
public void saveConfigs() {
From b24c8b23f6d9215cb47860b1b67d42259645e442 Mon Sep 17 00:00:00 2001
From: Emibergo02 <36164338+Emibergo02@users.noreply.github.com>
Date: Mon, 16 Sep 2024 23:05:25 +0200
Subject: [PATCH 15/25] Better timeout handling in updateAccountCloudCache
Added configurable poolSize in config Added expandpool command to adjust the
redis pool size at runtime
---
pom.xml | 2 +-
.../unnm3d/rediseconomy/config/Settings.java | 2 +
.../rediseconomy/currency/Currency.java | 65 ++++++++++---------
3 files changed, 37 insertions(+), 32 deletions(-)
diff --git a/pom.xml b/pom.xml
index 8e5ac5c..972e9d3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
dev.unnm3d
RedisEconomy
- 4.3.15
+ 4.3.16
jar
RedisEconomy
diff --git a/src/main/java/dev/unnm3d/rediseconomy/config/Settings.java b/src/main/java/dev/unnm3d/rediseconomy/config/Settings.java
index f531f58..d38960a 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/config/Settings.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/config/Settings.java
@@ -18,6 +18,8 @@ public class Settings {
public String webEditorUrl = "https://webui.advntr.dev/";
@Comment("Activate this before reporting an issue")
public boolean debug = false;
+ @Comment("A specific debug for cache update")
+ public boolean debugUpdateCache = false;
@Comment("If true, the plugin registers who's calling it's methods inside transactions")
public boolean registerCalls = false;
@Comment({"if true, migrates the bukkit offline uuids accounts to the default RedisEconomy currency",
diff --git a/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java b/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java
index db10882..6f2504c 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java
@@ -18,7 +18,10 @@
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.*;
-import java.util.concurrent.*;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
import static dev.unnm3d.rediseconomy.redis.RedisKeys.*;
@@ -539,43 +542,43 @@ protected void updateAccount(@NotNull UUID uuid, @Nullable String playerName, do
private synchronized void updateAccountCloudCache(@NotNull UUID uuid, @Nullable String playerName, double balance, int tries) {
final RedisEconomyPlugin plugin = RedisEconomyPlugin.getInstance();
- try {
- updateExecutor.submit(() -> {
- try {
- if (plugin.settings().debug) {
- Bukkit.getLogger().info("01a Starting update account " + playerName + " to " + balance + " currency " + currencyName);
- }
- currenciesManager.getRedisManager().executeTransaction(reactiveCommands -> {
- reactiveCommands.zadd(BALANCE_PREFIX + currencyName, balance, uuid.toString());
- if (playerName != null)
- reactiveCommands.hset(NAME_UUID.toString(), playerName, uuid.toString());
- reactiveCommands.publish(UPDATE_PLAYER_CHANNEL_PREFIX + currencyName,
- RedisEconomyPlugin.getInstanceUUID().toString() + ";;" + uuid + ";;" + playerName + ";;" + balance);
- if (plugin.settings().debug) {
- plugin.getLogger().info("01b Publishing update account " + playerName + " to " + balance + " currency " + currencyName);
- }
- }).ifPresentOrElse(result -> {
- if (RedisEconomyPlugin.getInstance().settings().debug) {
- plugin.getLogger().info("01c Sent update account successfully " + playerName + " to " + balance + " currency " + currencyName);
- }
- }, () -> handleException(uuid, playerName, balance, tries, null));
- } catch (Exception e) {
- handleException(uuid, playerName, balance, tries, e);
+ updateExecutor.submit(() -> {
+ try {
+ if (plugin.settings().debugUpdateCache) {
+ Bukkit.getLogger().info("01a Starting update account " + playerName + " to " + balance + " currency " + currencyName);
}
- }).get(plugin.settings().redis.timeout(), TimeUnit.MILLISECONDS);
- } catch (InterruptedException | TimeoutException | ExecutionException e) {
- handleException(uuid, playerName, balance, tries, e);
- }
+ currenciesManager.getRedisManager().executeTransaction(reactiveCommands -> {
+ reactiveCommands.zadd(BALANCE_PREFIX + currencyName, balance, uuid.toString());
+ if (playerName != null)
+ reactiveCommands.hset(NAME_UUID.toString(), playerName, uuid.toString());
+ reactiveCommands.publish(UPDATE_PLAYER_CHANNEL_PREFIX + currencyName,
+ RedisEconomyPlugin.getInstanceUUID().toString() + ";;" + uuid + ";;" + playerName + ";;" + balance);
+ if (plugin.settings().debugUpdateCache) {
+ plugin.getLogger().info("01b Publishing update account " + playerName + " to " + balance + " currency " + currencyName);
+ }
+ }).ifPresentOrElse(result -> {
+ if (RedisEconomyPlugin.getInstance().settings().debugUpdateCache) {
+ plugin.getLogger().info("01c Sent update account successfully " + playerName + " to " + balance + " currency " + currencyName);
+ }
+ }, () -> handleException(uuid, playerName, balance, tries, null));
+ } catch (Exception e) {
+ handleException(uuid, playerName, balance, tries, e);
+ }
+ });
}
private void handleException(@NotNull UUID uuid, @Nullable String playerName, double balance, int tries, @Nullable Exception e) {
final RedisEconomyPlugin plugin = RedisEconomyPlugin.getInstance();
if (tries < plugin.settings().redis.tryAgainCount()) {
- plugin.getLogger().warning("Player accounts are desynchronized. try: " + tries);
- if (e != null)
- plugin.getLogger().warning(e.getMessage());
+ if (plugin.settings().debugUpdateCache) {
+ plugin.getLogger().warning("Player accounts are desynchronized. try: " + tries);
+ if (e != null)
+ plugin.getLogger().warning(e.getMessage());
+ }
updateAccountCloudCache(uuid, playerName, balance, tries + 1);
- } else {
+ return;
+ }
+ if (plugin.settings().debugUpdateCache) {
plugin.getLogger().severe("Failed to update account " + playerName + " after " + tries + " tries");
currenciesManager.getRedisManager().printPool();
if (e != null)
From b08fff5ed227ae523b23b1e21ffe2236cb3060a4 Mon Sep 17 00:00:00 2001
From: Emibergo02 <36164338+Emibergo02@users.noreply.github.com>
Date: Sat, 21 Sep 2024 15:48:40 +0200
Subject: [PATCH 16/25] Added per-player max balance Configurable with /balance
username currencyName set-max (It is a cross-server feature of
course) Avoid error when upgrading RedisEconomy from ancient versions by
checking 0 values
---
pom.xml | 2 +-
.../rediseconomy/RedisEconomyPlugin.java | 2 +-
.../command/balance/BalanceCommand.java | 7 +-
.../command/balance/BalanceSubCommands.java | 14 +++
.../dev/unnm3d/rediseconomy/config/Langs.java | 1 +
.../unnm3d/rediseconomy/config/Settings.java | 8 ++
.../rediseconomy/currency/Currency.java | 95 +++++++++++++++----
.../currency/CurrencyWithBanks.java | 2 +-
.../unnm3d/rediseconomy/redis/RedisKeys.java | 2 +
.../utils/PlaceholderAPIHook.java | 2 +-
10 files changed, 111 insertions(+), 24 deletions(-)
diff --git a/pom.xml b/pom.xml
index 972e9d3..6764ecd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
dev.unnm3d
RedisEconomy
- 4.3.16
+ 4.3.17
jar
RedisEconomy
diff --git a/src/main/java/dev/unnm3d/rediseconomy/RedisEconomyPlugin.java b/src/main/java/dev/unnm3d/rediseconomy/RedisEconomyPlugin.java
index 897e028..7beff76 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/RedisEconomyPlugin.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/RedisEconomyPlugin.java
@@ -159,7 +159,7 @@ private boolean setupRedis() {
redisURIBuilder.withAuthentication(configManager.getSettings().redis.user(), configManager.getSettings().redis.password());
getLogger().info("Connecting to redis server " + redisURIBuilder.build().toString() + "...");
- this.redisManager = new RedisManager(RedisClient.create(redisURIBuilder.build()), configManager.getSettings().redis.poolSize());
+ this.redisManager = new RedisManager(RedisClient.create(redisURIBuilder.build()), configManager.getSettings().redis.getPoolSize());
redisManager.isConnected().get(1, java.util.concurrent.TimeUnit.SECONDS);
if (!configManager.getSettings().clusterId.isEmpty())
RedisKeys.setClusterId(configManager.getSettings().clusterId);
diff --git a/src/main/java/dev/unnm3d/rediseconomy/command/balance/BalanceCommand.java b/src/main/java/dev/unnm3d/rediseconomy/command/balance/BalanceCommand.java
index 9ff8773..dc0207f 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/command/balance/BalanceCommand.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/command/balance/BalanceCommand.java
@@ -84,6 +84,9 @@ else if (reasonOrCommand.startsWith("/")) {
} else if (args[2].equalsIgnoreCase("set")) {
setPlayer(sender, currency, amount, target);
+
+ } else if (args[2].equalsIgnoreCase("set-max")) {
+ setPlayerMaxBalance(sender, currency, amount, target);
}
}
if (plugin.settings().debug)
@@ -105,6 +108,8 @@ else if (reasonOrCommand.startsWith("/")) {
protected abstract void setPlayer(CommandSender sender, Currency currency, double amount, String target);
+ protected abstract void setPlayerMaxBalance(CommandSender sender, Currency currency, double amount, String target);
+
@Override
public @NotNull List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if (args.length == 1) {
@@ -118,7 +123,7 @@ else if (reasonOrCommand.startsWith("/")) {
} else if (args.length == 2)
return economy.getCurrencies().stream().map(Currency::getCurrencyName).filter(name -> name.startsWith(args[1]) && sender.hasPermission("rediseconomy.balance." + args[1])).toList();
else if (args.length == 3)
- return List.of("give", "take", "set");
+ return List.of("give", "take", "set", "set-max");
else if (args.length == 4)
return List.of("69");
return List.of();
diff --git a/src/main/java/dev/unnm3d/rediseconomy/command/balance/BalanceSubCommands.java b/src/main/java/dev/unnm3d/rediseconomy/command/balance/BalanceSubCommands.java
index c09f54d..2625cb0 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/command/balance/BalanceSubCommands.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/command/balance/BalanceSubCommands.java
@@ -7,6 +7,8 @@
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
+import java.util.UUID;
+
public class BalanceSubCommands extends BalanceCommand {
public BalanceSubCommands(CurrenciesManager economy, RedisEconomyPlugin plugin) {
@@ -72,4 +74,16 @@ protected void setPlayer(CommandSender sender, Currency currency, double amount,
plugin.langs().send(sender, plugin.langs().balanceSet.replace("%balance%", currency.format(er.balance)).replace("%player%", target));
else sender.sendMessage(er.errorMessage);
}
+
+ @Override
+ protected void setPlayerMaxBalance(CommandSender sender, Currency currency, double amount, String target) {
+ final UUID targetUUID = plugin.getCurrenciesManager().getUUIDFromUsernameCache(target);
+ if (targetUUID == null) {
+ plugin.langs().send(sender, plugin.langs().playerNotFound);
+ return;
+ }
+ currency.setPlayerMaxBalance(targetUUID, amount);
+ plugin.langs().send(sender, plugin.langs().maxBalanceSet.replace("%player%", target).replace("%amount%", currency.format(amount)));
+ }
+
}
diff --git a/src/main/java/dev/unnm3d/rediseconomy/config/Langs.java b/src/main/java/dev/unnm3d/rediseconomy/config/Langs.java
index e054bdc..b68e860 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/config/Langs.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/config/Langs.java
@@ -26,6 +26,7 @@ public final class Langs {
public String insufficientFunds = "You do not have enough money!";
public String balance = "You have %balance%!";
public String balanceSet = "You set %player% account to %balance% !";
+ public String maxBalanceSet = "You set %player% max balance to %amount% !";
public String balanceOther = "%player% has %balance% !";
public String balanceTop = "Top richest players:
%prevpage% %page% %nextpage%";
public String blockedAccounts = "Blocked accounts:
%list%";
diff --git a/src/main/java/dev/unnm3d/rediseconomy/config/Settings.java b/src/main/java/dev/unnm3d/rediseconomy/config/Settings.java
index d38960a..911c8ee 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/config/Settings.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/config/Settings.java
@@ -53,5 +53,13 @@ public record CurrencySettings(String currencyName, String currencySingle, Strin
public record RedisSettings(String host, int port, String user, String password, int database, int timeout,
String clientName, int poolSize, int tryAgainCount) {
+ //Those checks are for new config files, if the user doesn't have the new settings
+ public int getPoolSize() {
+ return poolSize == 0 ? 5 : poolSize;
+ }
+
+ public int getTryAgainCount() {
+ return tryAgainCount == 0 ? 3 : tryAgainCount;
+ }
}
}
diff --git a/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java b/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java
index 6f2504c..24c25b1 100644
--- a/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java
+++ b/src/main/java/dev/unnm3d/rediseconomy/currency/Currency.java
@@ -32,6 +32,7 @@ public class Currency implements Economy {
@Getter
protected final String currencyName;
private final ConcurrentHashMap accounts;
+ private final ConcurrentHashMap maxPlayerBalances;
private boolean enabled;
@Getter
@@ -72,19 +73,29 @@ public Currency(CurrenciesManager currenciesManager, Settings.CurrencySettings c
this.transactionTax = currencySettings.payTax();
this.taxOnlyPay = currencySettings.taxOnlyPay();
this.accounts = new ConcurrentHashMap<>();
+ this.maxPlayerBalances = new ConcurrentHashMap<>();
this.decimalFormat = new DecimalFormat(
currencySettings.decimalFormat() != null ? currencySettings.decimalFormat() : "#.##",
new DecimalFormatSymbols(Locale.forLanguageTag(currencySettings.languageTag() != null ? currencySettings.languageTag() : "en-US"))
);
+
getOrderedAccounts(-1).thenApply(result -> {
- result.forEach(t ->
- accounts.put(UUID.fromString(t.getValue()), t.getScore()));
- if (RedisEconomyPlugin.getInstance().settings().debug && !accounts.isEmpty()) {
- Bukkit.getLogger().info("start1 Loaded " + accounts.size() + " accounts for currency " + currencyName);
- }
- return result;
- }
- ).toCompletableFuture().join(); //Wait to avoid API calls before accounts are loaded
+ result.forEach(t ->
+ accounts.put(UUID.fromString(t.getValue()), t.getScore()));
+ if (RedisEconomyPlugin.getInstance().settings().debug && !accounts.isEmpty()) {
+ Bukkit.getLogger().info("start1 Loaded " + accounts.size() + " accounts for currency " + currencyName);
+ }
+ return result;
+ }).toCompletableFuture().join(); //Wait to avoid API calls before accounts are loaded
+
+ getPlayerMaxBalances().thenApply(result -> {
+ maxPlayerBalances.putAll(result);
+ if (RedisEconomyPlugin.getInstance().settings().debug && !maxPlayerBalances.isEmpty()) {
+ Bukkit.getLogger().info("start1 Loaded " + maxPlayerBalances.size() + " max balances for currency " + currencyName);
+ }
+ return result;
+ }); //Not as critical as accounts, so we don't wait
+
registerUpdateListener();
}
@@ -95,21 +106,33 @@ private void registerUpdateListener() {
@Override
public void message(String channel, String message) {
String[] split = message.split(";;");
- if (split.length != 4) {
+ if (split.length != 3) {
Bukkit.getLogger().severe("Invalid message received from RedisEco channel, consider updating RedisEconomy");
return;
}
if (split[0].equals(RedisEconomyPlugin.getInstanceUUID().toString())) return;
+
UUID uuid = UUID.fromString(split[1]);
- String playerName = split[2];
- double balance = Double.parseDouble(split[3]);
- updateAccountLocal(uuid, playerName, balance);
- if (RedisEconomyPlugin.getInstance().settings().debug) {
- Bukkit.getLogger().info("01b Received balance update " + playerName + " to " + balance);
+ double balance = Double.parseDouble(split[2]);
+ if (channel.equals(UPDATE_PLAYER_CHANNEL_PREFIX + currencyName)) {
+ String playerName = currenciesManager.getUsernameFromUUIDCache(uuid);
+ if (playerName == null) {
+ Bukkit.getLogger().severe("Player name not found for UUID " + uuid);
+ return;
+ }
+ updateAccountLocal(uuid, playerName, balance);
+ if (RedisEconomyPlugin.getInstance().settings().debug) {
+ Bukkit.getLogger().info("01b Received balance update " + playerName + " to " + balance);
+ }
+ } else if (channel.equals(UPDATE_MAX_BAL_PREFIX + currencyName)) {
+ setPlayerMaxBalanceLocal(uuid, maxBalance);
+ if (RedisEconomyPlugin.getInstance().settings().debug) {
+ Bukkit.getLogger().info("01b Received max balance update " + uuid + " to " + maxBalance);
+ }
}
}
});
- connection.async().subscribe(UPDATE_PLAYER_CHANNEL_PREFIX + currencyName);
+ connection.async().subscribe(UPDATE_PLAYER_CHANNEL_PREFIX + currencyName, UPDATE_MAX_BAL_PREFIX + currencyName);
if (RedisEconomyPlugin.getInstance().settings().debug) {
Bukkit.getLogger().info("start1b Listening to RedisEco channel " + UPDATE_PLAYER_CHANNEL_PREFIX + currencyName);
}
@@ -405,7 +428,7 @@ public EconomyResponse payPlayer(@NotNull UUID sender, @NotNull UUID receiver, d
if (!has(sender, amountToWithdraw))
return new EconomyResponse(0, getBalance(sender), EconomyResponse.ResponseType.FAILURE, "Insufficient funds");
- if (getBalance(receiver) + amount > maxBalance)
+ if (getBalance(receiver) + amount > getPlayerMaxBalance(receiver))
return new EconomyResponse(0, getBalance(receiver), EconomyResponse.ResponseType.FAILURE, "The receiver has reached the maximum balance");
updateAccount(sender, senderName, getBalance(sender) - amountToWithdraw);
@@ -436,7 +459,7 @@ public EconomyResponse payPlayer(@NotNull String senderName, @NotNull String rec
if (!has(senderName, amountToWithdraw))
return new EconomyResponse(0, getBalance(sender), EconomyResponse.ResponseType.FAILURE, "Insufficient funds");
- if (getBalance(receiver) + amount > maxBalance)
+ if (getBalance(receiver) + amount > getPlayerMaxBalance(receiver))
return new EconomyResponse(0, getBalance(receiver), EconomyResponse.ResponseType.FAILURE, "The receiver has reached the maximum balance");
updateAccount(sender, senderName, getBalance(sender) - amountToWithdraw);
@@ -521,7 +544,7 @@ public EconomyResponse depositPlayer(@NotNull UUID playerUUID, @Nullable String
if (amount == Double.POSITIVE_INFINITY || amount == Double.NEGATIVE_INFINITY || Double.isNaN(amount))
return new EconomyResponse(0, 0, EconomyResponse.ResponseType.FAILURE, "Invalid decimal amount format");
- if (getBalance(playerUUID) + amount > maxBalance)
+ if (getBalance(playerUUID) + amount > getPlayerMaxBalance(playerUUID))
return new EconomyResponse(0, getBalance(playerUUID), EconomyResponse.ResponseType.FAILURE, "The player has reached the maximum balance");
updateAccount(playerUUID, playerName, getBalance(playerUUID) + amount);
@@ -569,7 +592,7 @@ private synchronized void updateAccountCloudCache(@NotNull UUID uuid, @Nullable
private void handleException(@NotNull UUID uuid, @Nullable String playerName, double balance, int tries, @Nullable Exception e) {
final RedisEconomyPlugin plugin = RedisEconomyPlugin.getInstance();
- if (tries < plugin.settings().redis.tryAgainCount()) {
+ if (tries < plugin.settings().redis.getTryAgainCount()) {
if (plugin.settings().debugUpdateCache) {
plugin.getLogger().warning("Player accounts are desynchronized. try: " + tries);
if (e != null)
@@ -623,6 +646,40 @@ public CompletionStage>> getOrderedAccounts(int limit)
}
+ public double getPlayerMaxBalance(UUID uuid) {
+ return maxPlayerBalances.getOrDefault(uuid, maxBalance);
+ }
+
+ public void setPlayerMaxBalance(UUID uuid, double amount) {
+ setPlayerMaxBalanceCloud(uuid, amount);
+ setPlayerMaxBalanceLocal(uuid, amount);
+ }
+
+ public void setPlayerMaxBalanceLocal(UUID uuid, double amount) {
+ maxPlayerBalances.put(uuid, amount);
+ }
+
+ public void setPlayerMaxBalanceCloud(UUID uuid, double amount) {
+ currenciesManager.getRedisManager().getConnectionPipeline(asyncCommands -> {
+ if(amount == maxBalance) {
+ asyncCommands.hdel(MAX_PLAYER_BALANCES + currencyName, uuid.toString());
+ } else {
+ asyncCommands.hset(MAX_PLAYER_BALANCES + currencyName, uuid.toString(), String.valueOf(amount));
+ }
+ return asyncCommands.publish(UPDATE_MAX_BAL_PREFIX + currencyName, RedisEconomyPlugin.getInstanceUUID().toString() + ";;" + uuid + ";;" + amount);
+ });
+ }
+
+ public CompletionStage