Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions src/main/java/pro/cloudnode/smp/bankaccounts/BankAccounts.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -162,6 +164,12 @@ 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();
}

/**
Expand Down Expand Up @@ -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;
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/pro/cloudnode/smp/bankaccounts/BankConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,16 @@ public int invoicePerPage() {
public @NotNull Pattern disallowedRegex() {
return Pattern.compile(Objects.requireNonNull(config.getString("disallowed-regex")));
}

// 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) {
Expand Down Expand Up @@ -1379,6 +1389,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("<unpaid>", String.valueOf(unpaid)),
Formatter.choice("unpaid-choice", unpaid)
));
}

// messages.update-available
public @NotNull Component messagesUpdateAvailable(final @NotNull String version) {
return MiniMessage.miniMessage().deserialize(
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/pro/cloudnode/smp/bankaccounts/Invoice.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public final class Permissions {
public static final @NotNull String INVOICE_CREATE_OTHER = "bank.invoice.create.other";
public static final @NotNull String INVOICE_VIEW = "bank.invoice.view";
public static final @NotNull String INVOICE_VIEW_OTHER = "bank.invoice.view.other";
public static final @NotNull String INVOICE_NOTIFY = "bank.invoice.notify";
public static final @NotNull String INVOICE_PAY_OTHER = "bank.invoice.pay.other";
public static final @NotNull String INVOICE_PAY_ACCOUNT_OTHER = "bank.invoice.pay.account-other";
public static final @NotNull String INVOICE_SEND = "bank.invoice.send";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
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;
import org.bukkit.event.player.PlayerJoinEvent;
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;
Expand Down Expand Up @@ -35,5 +37,11 @@ else if (BankAccounts.getInstance().config().integrationsVaultEnabled()) {
player.sendMessage(BankAccounts.getInstance().config().messagesUpdateAvailable(latestVersion))
), 20L);
}
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);
}, 20L);
}
}
}
17 changes: 17 additions & 0 deletions src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,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

# Advanced: do not edit unless you have good understanding of RegEx
# Regular expression for disallowed characters user-provided text inputs
# e.g. account name, transaction description, POS description, invoice description
Expand Down Expand Up @@ -602,6 +611,14 @@ messages:
# Same placeholders as details
footer: "<hover:show_text:'Click to see the previous page'><click:run_command:<cmd-prev>><green>← Previous</green></click></hover> <gray>Page <page></gray> <hover:show_text:'Click to see the next page'><click:run_command:<cmd-next>><green>Next →</green></click></hover>"

# You have unpaid invoices
# Sent periodically and on login (as configured in invoice.notify)
# Set to empty string to disable
# Placeholders:
# <unpaid> - number of unpaid invoices></yellow>."
# <unpaid-choice> - choice placeholder for unpaid invoices; see https://docs.advntr.dev/minimessage/dynamic-replacements.html#insert-a-choice
notify: "<click:run_command:/invoice list><hover:show_text:'Click to view unpaid invoices'><yellow>(!) You have <gray><unpaid></gray> unpaid invoice<unpaid-choice:'1#|1<s'>. <gray>Click to view.</gray></yellow></hover></click>"

# New version available
# Placeholders:
# <version> - New version
Expand Down