From e9e2ac3222990e41e47de211aae897a7afff0871 Mon Sep 17 00:00:00 2001 From: Zefir Kirilov Date: Fri, 26 Jan 2024 11:19:18 +0200 Subject: [PATCH 01/10] make join event async --- .../smp/bankaccounts/events/Join.java | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/main/java/pro/cloudnode/smp/bankaccounts/events/Join.java b/src/main/java/pro/cloudnode/smp/bankaccounts/events/Join.java index e3fc1ec0..5e8dc753 100644 --- a/src/main/java/pro/cloudnode/smp/bankaccounts/events/Join.java +++ b/src/main/java/pro/cloudnode/smp/bankaccounts/events/Join.java @@ -15,20 +15,22 @@ public final class Join implements Listener { @EventHandler public void onPlayerJoin(final @NotNull PlayerJoinEvent event) { - final Player player = event.getPlayer(); - final @NotNull Optional<@NotNull Double> startingBalance = BankAccounts.getInstance().config() - .startingBalance(); - startingBalance.ifPresent(aDouble -> BankAccounts.getInstance().getServer().getScheduler() - .runTaskAsynchronously(BankAccounts.getInstance(), () -> { - final @NotNull Account[] accounts = Account.get(player, Account.Type.PERSONAL); - if (accounts.length == 0) { - new Account(player, Account.Type.PERSONAL, null, BigDecimal.valueOf(aDouble), false).insert(); - } - })); - if (player.hasPermission(Permissions.NOTIFY_UPDATE)) { - BankAccounts.getInstance().getServer().getScheduler().runTaskLater(BankAccounts.getInstance(), () -> BankAccounts.checkForUpdates().ifPresent(latestVersion -> { - player.sendMessage(BankAccounts.getInstance().config().messagesUpdateAvailable(latestVersion)); - }), 20L); - } + BankAccounts.getInstance().getServer().getScheduler().runTaskAsynchronously(BankAccounts.getInstance(), () -> { + final Player player = event.getPlayer(); + final @NotNull Optional<@NotNull Double> startingBalance = BankAccounts.getInstance().config() + .startingBalance(); + startingBalance.ifPresent(aDouble -> BankAccounts.getInstance().getServer().getScheduler() + .runTaskAsynchronously(BankAccounts.getInstance(), () -> { + final @NotNull Account[] accounts = Account.get(player, Account.Type.PERSONAL); + if (accounts.length == 0) { + new Account(player, Account.Type.PERSONAL, null, BigDecimal.valueOf(aDouble), false).insert(); + } + })); + if (player.hasPermission(Permissions.NOTIFY_UPDATE)) { + BankAccounts.getInstance().getServer().getScheduler().runTaskLater(BankAccounts.getInstance(), () -> BankAccounts.checkForUpdates().ifPresent(latestVersion -> { + player.sendMessage(BankAccounts.getInstance().config().messagesUpdateAvailable(latestVersion)); + }), 20L); + } + }); } } From 8a618573821057a49f8fcdac19df407bb53f5ba4 Mon Sep 17 00:00:00 2001 From: Zefir Kirilov Date: Fri, 26 Jan 2024 11:24:32 +0200 Subject: [PATCH 02/10] count unpaid invoices --- .../pro/cloudnode/smp/bankaccounts/Invoice.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/java/pro/cloudnode/smp/bankaccounts/Invoice.java b/src/main/java/pro/cloudnode/smp/bankaccounts/Invoice.java index 5b5bfd95..bd8e6906 100644 --- a/src/main/java/pro/cloudnode/smp/bankaccounts/Invoice.java +++ b/src/main/java/pro/cloudnode/smp/bankaccounts/Invoice.java @@ -234,4 +234,19 @@ public void update() { return new @NotNull Invoice[0]; } } + + public static int countUnpaid(final @NotNull OfflinePlayer player) { + try (final @NotNull Connection conn = BankAccounts.getInstance().getDb().getConnection(); + final @NotNull PreparedStatement stmt = conn.prepareStatement("SELECT COUNT(`id`) as `count` FROM `bank_invoices` WHERE `buyer` = ? AND `transaction` IS NULL")) { + stmt.setString(1, player.getUniqueId().toString()); + + final @NotNull ResultSet rs = stmt.executeQuery(); + if (rs.next()) return rs.getInt("count"); + return 0; + } + catch (final @NotNull SQLException e) { + BankAccounts.getInstance().getLogger().log(Level.SEVERE, "Could not count unpaid invoices for player: " + player.getUniqueId(), e); + return 0; + } + } } From 5068b21b04b87b8850f66ffc5635e2d47d73da33 Mon Sep 17 00:00:00 2001 From: Zefir Kirilov Date: Fri, 26 Jan 2024 11:30:23 +0200 Subject: [PATCH 03/10] invoice notify permission --- src/main/java/pro/cloudnode/smp/bankaccounts/Permissions.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/pro/cloudnode/smp/bankaccounts/Permissions.java b/src/main/java/pro/cloudnode/smp/bankaccounts/Permissions.java index 12978506..bb5eb364 100644 --- a/src/main/java/pro/cloudnode/smp/bankaccounts/Permissions.java +++ b/src/main/java/pro/cloudnode/smp/bankaccounts/Permissions.java @@ -20,6 +20,7 @@ public final class Permissions { public static @NotNull String INVOICE_CREATE = "bank.invoice.create"; public static @NotNull String INVOICE_CREATE_OTHER = "bank.invoice.create.other"; public static @NotNull String INVOICE_VIEW = "bank.invoice.view"; + public static @NotNull String INVOICE_NOTIFY = "bank.invoice.notify"; public static @NotNull String INVOICE_VIEW_OTHER = "bank.invoice.view.other"; public static @NotNull String INVOICE_PAY_OTHER = "bank.invoice.pay.other"; public static @NotNull String INVOICE_PAY_ACCOUNT_OTHER = "bank.invoice.pay.account-other"; From b12bc3365349f673940375a8b3f46dcd21e633b5 Mon Sep 17 00:00:00 2001 From: Zefir Kirilov Date: Fri, 26 Jan 2024 11:30:53 +0200 Subject: [PATCH 04/10] invoice notifications config --- .../smp/bankaccounts/BankConfig.java | 21 +++++++++++++++++++ src/main/resources/config.yml | 17 +++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/main/java/pro/cloudnode/smp/bankaccounts/BankConfig.java b/src/main/java/pro/cloudnode/smp/bankaccounts/BankConfig.java index c95c1163..77cfa362 100644 --- a/src/main/java/pro/cloudnode/smp/bankaccounts/BankConfig.java +++ b/src/main/java/pro/cloudnode/smp/bankaccounts/BankConfig.java @@ -421,6 +421,16 @@ public int invoicePerPage() { return config.getInt("invoice.per-page"); } + // invoice.notify.join + public boolean invoiceNotifyJoin() { + return config.getBoolean("invoice.notify.join"); + } + + // invoice.notify.interval + public int invoiceNotifyInterval() { + return config.getInt("invoice.notify.interval"); + } + // messages.command-usage public @NotNull Component messagesCommandUsage(final @NotNull String command, final @NotNull String arguments) { return MiniMessage.miniMessage().deserialize( @@ -1358,6 +1368,17 @@ public int invoicePerPage() { ); } + // messages.invoice.notify + public @NotNull Optional<@NotNull Component> messagesInvoiceNotify(final int unpaid) { + final @NotNull String message = Objects.requireNonNull(config.getString("messages.invoice.notify")); + if (message.isBlank()) return Optional.empty(); + return Optional.of(MiniMessage.miniMessage().deserialize( + message + .replace("", String.valueOf(unpaid)), + Formatter.choice("unpaid-choice", unpaid) + )); + } + // messages.update-available public @NotNull Component messagesUpdateAvailable(final @NotNull String version) { return MiniMessage.miniMessage().deserialize( diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 245a25ad..a3fd097b 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -259,6 +259,15 @@ invoice: # Number of invoices to return per page per-page: 10 + # Notifications for unpaid invoices (see messages.invoice.notify) + notify: + # Send message when a player joins + join: true + # Periodically send message while player is online + # Interval between messages in seconds + # Set to 0 or negative to disable + interval: 300 + # Messages messages: # Command usage message @@ -583,6 +592,14 @@ messages: # Same placeholders as details footer: ">← Previous Page >Next →" + # You have unpaid invoices + # Sent periodically and on login (as configured in invoice.notify) + # Set to empty string to disable + # Placeholders: + # - number of unpaid invoices>." + # - choice placeholder for unpaid invoices; see https://docs.advntr.dev/minimessage/dynamic-replacements.html#insert-a-choice + notify: "(!) You have unpaid invoice. Click to view." + # New version available # Placeholders: # - New version From 2d60eef6c11645adf569070033cfa87fb8f16f99 Mon Sep 17 00:00:00 2001 From: Zefir Kirilov Date: Fri, 26 Jan 2024 11:31:05 +0200 Subject: [PATCH 05/10] send unpaid invoices notification on join --- .../java/pro/cloudnode/smp/bankaccounts/events/Join.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/pro/cloudnode/smp/bankaccounts/events/Join.java b/src/main/java/pro/cloudnode/smp/bankaccounts/events/Join.java index 5e8dc753..14d0608c 100644 --- a/src/main/java/pro/cloudnode/smp/bankaccounts/events/Join.java +++ b/src/main/java/pro/cloudnode/smp/bankaccounts/events/Join.java @@ -1,5 +1,6 @@ package pro.cloudnode.smp.bankaccounts.events; +import net.kyori.adventure.text.Component; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -7,6 +8,7 @@ import org.jetbrains.annotations.NotNull; import pro.cloudnode.smp.bankaccounts.Account; import pro.cloudnode.smp.bankaccounts.BankAccounts; +import pro.cloudnode.smp.bankaccounts.Invoice; import pro.cloudnode.smp.bankaccounts.Permissions; import java.math.BigDecimal; @@ -31,6 +33,13 @@ public void onPlayerJoin(final @NotNull PlayerJoinEvent event) { player.sendMessage(BankAccounts.getInstance().config().messagesUpdateAvailable(latestVersion)); }), 20L); } + + if (player.hasPermission(Permissions.INVOICE_NOTIFY) && BankAccounts.getInstance().config().invoiceNotifyJoin()) { + BankAccounts.getInstance().getServer().getScheduler().runTaskLater(BankAccounts.getInstance(), () -> { + final @NotNull Optional<@NotNull Component> message = BankAccounts.getInstance().config().messagesInvoiceNotify(Invoice.countUnpaid(player)); + message.ifPresent(player::sendMessage); + }, 20L); + } }); } } From bb9284613402d946f92b50816ed99f0106d1a586 Mon Sep 17 00:00:00 2001 From: Zefir Kirilov Date: Sun, 15 Sep 2024 17:47:42 +0300 Subject: [PATCH 06/10] check if there are unpaid invoices before sending notification on join --- src/main/java/pro/cloudnode/smp/bankaccounts/events/Join.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/pro/cloudnode/smp/bankaccounts/events/Join.java b/src/main/java/pro/cloudnode/smp/bankaccounts/events/Join.java index c2ce677a..453d3c55 100644 --- a/src/main/java/pro/cloudnode/smp/bankaccounts/events/Join.java +++ b/src/main/java/pro/cloudnode/smp/bankaccounts/events/Join.java @@ -37,7 +37,7 @@ else if (BankAccounts.getInstance().config().integrationsVaultEnabled()) { player.sendMessage(BankAccounts.getInstance().config().messagesUpdateAvailable(latestVersion)) ), 20L); } - if (player.hasPermission(Permissions.INVOICE_NOTIFY) && BankAccounts.getInstance().config().invoiceNotifyJoin()) { + if (player.hasPermission(Permissions.INVOICE_NOTIFY) && BankAccounts.getInstance().config().invoiceNotifyJoin() && Invoice.countUnpaid(player) > 0) { BankAccounts.getInstance().getServer().getScheduler().runTaskLater(BankAccounts.getInstance(), () -> { final @NotNull Optional<@NotNull Component> message = BankAccounts.getInstance().config().messagesInvoiceNotify(Invoice.countUnpaid(player)); message.ifPresent(player::sendMessage); From 750d34f423147594fefbf39f1f45b4810a6898a5 Mon Sep 17 00:00:00 2001 From: Zefir Kirilov Date: Sun, 15 Sep 2024 17:50:13 +0300 Subject: [PATCH 07/10] send periodic notifications for unpaid invoices --- .../smp/bankaccounts/BankAccounts.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/main/java/pro/cloudnode/smp/bankaccounts/BankAccounts.java b/src/main/java/pro/cloudnode/smp/bankaccounts/BankAccounts.java index de8c6d88..4836ebed 100644 --- a/src/main/java/pro/cloudnode/smp/bankaccounts/BankAccounts.java +++ b/src/main/java/pro/cloudnode/smp/bankaccounts/BankAccounts.java @@ -4,11 +4,13 @@ import com.google.gson.JsonParser; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; +import net.kyori.adventure.text.Component; import org.bukkit.NamespacedKey; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.command.PluginCommand; +import org.bukkit.entity.Player; import org.bukkit.event.Listener; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitTask; @@ -105,6 +107,11 @@ public void onEnable() { @Override public void onDisable() { dbSource.close(); + if (this.invoiceNotificationTask != null) { + final int taskId = this.invoiceNotificationTask.getTaskId(); + getServer().getScheduler().cancelTask(taskId); + this.invoiceNotificationTask = null; + } } /** @@ -162,6 +169,7 @@ public static void reload() { getInstance().getLogger().warning("Update details: https://modrinth.com/plugin/bankaccounts/version/" + latestVersion); })); getInstance().startInterestTimer(); + getInstance().setupInvoiceNotificationTimer(); } /** @@ -247,6 +255,20 @@ private void startInterestTimer() { }, 0L, 20L*60); } + private @Nullable BukkitTask invoiceNotificationTask = null; + + private void setupInvoiceNotificationTimer() { + if (config().invoiceNotifyInterval() <= 0) return; + this.invoiceNotificationTask = getServer().getScheduler().runTaskTimerAsynchronously(this, () -> { + for (final @NotNull Player player : getServer().getOnlinePlayers()) { + final @NotNull Optional<@NotNull Component> message = BankAccounts.getInstance().config().messagesInvoiceNotify(Invoice.countUnpaid(player)); + if (message.isEmpty()) continue; + if (player.hasPermission(Permissions.INVOICE_NOTIFY) && Invoice.countUnpaid(player) > 0) + player.sendMessage(message.get()); + } + }, config().invoiceNotifyInterval() * 20L, config().invoiceNotifyInterval() * 20L); + } + private void interestPayment(final @NotNull Account account, final @NotNull BigDecimal amount, final double rate, final @NotNull Account serverAccount) { if (account.balance == null) return; if (account.id.equals(serverAccount.id)) return; From 6ae6258c6cf02dcd94839e4831d4dc75e0893a10 Mon Sep 17 00:00:00 2001 From: Zefir Kirilov Date: Sun, 15 Sep 2024 17:54:11 +0300 Subject: [PATCH 08/10] move invoice notification task cancellation to reload --- .../pro/cloudnode/smp/bankaccounts/BankAccounts.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/pro/cloudnode/smp/bankaccounts/BankAccounts.java b/src/main/java/pro/cloudnode/smp/bankaccounts/BankAccounts.java index 4836ebed..bf83a4a7 100644 --- a/src/main/java/pro/cloudnode/smp/bankaccounts/BankAccounts.java +++ b/src/main/java/pro/cloudnode/smp/bankaccounts/BankAccounts.java @@ -107,11 +107,6 @@ public void onEnable() { @Override public void onDisable() { dbSource.close(); - if (this.invoiceNotificationTask != null) { - final int taskId = this.invoiceNotificationTask.getTaskId(); - getServer().getScheduler().cancelTask(taskId); - this.invoiceNotificationTask = null; - } } /** @@ -169,6 +164,11 @@ public static void reload() { getInstance().getLogger().warning("Update details: https://modrinth.com/plugin/bankaccounts/version/" + latestVersion); })); getInstance().startInterestTimer(); + if (getInstance().invoiceNotificationTask != null) { + final int taskId = getInstance().invoiceNotificationTask.getTaskId(); + getInstance().getServer().getScheduler().cancelTask(taskId); + getInstance().invoiceNotificationTask = null; + } getInstance().setupInvoiceNotificationTimer(); } From bc0327f21bb0bdb19011b8a5d5b17348a9e877a9 Mon Sep 17 00:00:00 2001 From: Zefir Kirilov Date: Mon, 16 Sep 2024 13:24:05 +0300 Subject: [PATCH 09/10] send correct message to invoice recipient --- .../pro/cloudnode/smp/bankaccounts/commands/InvoiceCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/pro/cloudnode/smp/bankaccounts/commands/InvoiceCommand.java b/src/main/java/pro/cloudnode/smp/bankaccounts/commands/InvoiceCommand.java index ef68f82a..c6b220fd 100644 --- a/src/main/java/pro/cloudnode/smp/bankaccounts/commands/InvoiceCommand.java +++ b/src/main/java/pro/cloudnode/smp/bankaccounts/commands/InvoiceCommand.java @@ -199,7 +199,7 @@ public static boolean create(final @NotNull CommandSender sender, @NotNull Strin invoice.insert(); final @NotNull Optional<@NotNull Player> onlineRecipient = invoice.buyer().isPresent() ? Optional.ofNullable(invoice.buyer().get().getPlayer()) : Optional.empty(); - onlineRecipient.ifPresent(player -> sendMessage(player, BankAccounts.getInstance().config().messagesInvoiceCreated(invoice))); + onlineRecipient.ifPresent(player -> sendMessage(player, BankAccounts.getInstance().config().messagesInvoiceReceived(invoice))); return sendMessage(sender, BankAccounts.getInstance().config().messagesInvoiceCreated(invoice)); } From 3a032a9b0b6e8a45cf270613aa4aebe2ecb092f8 Mon Sep 17 00:00:00 2001 From: Zefir Kirilov Date: Mon, 16 Sep 2024 13:32:40 +0300 Subject: [PATCH 10/10] fix "1 unpaid invoices" in notification message ^ here --- src/main/resources/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 4717f733..b68118af 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -617,7 +617,7 @@ messages: # Placeholders: # - number of unpaid invoices>." # - choice placeholder for unpaid invoices; see https://docs.advntr.dev/minimessage/dynamic-replacements.html#insert-a-choice - notify: "(!) You have unpaid invoice. Click to view." + notify: "(!) You have unpaid invoice. Click to view." # New version available # Placeholders: