From 0927c8146906310d56a0da5b8dae635f83639508 Mon Sep 17 00:00:00 2001 From: Mustfa-IT Date: Tue, 27 May 2025 16:02:47 +0300 Subject: [PATCH 01/39] Update .gitignore to exclude config files and add newline to config.yml --- dreamvisitor/.gitignore | 3 + .../dreamvisitor/commands/CmdDvset.java | 416 +++++++++--------- dreamvisitor/src/main/resources/config.yml | 2 +- 3 files changed, 220 insertions(+), 201 deletions(-) diff --git a/dreamvisitor/.gitignore b/dreamvisitor/.gitignore index 772bf01..e598cbd 100644 --- a/dreamvisitor/.gitignore +++ b/dreamvisitor/.gitignore @@ -87,6 +87,9 @@ fabric.properties # modules.xml # .idea/misc.xml # *.ipr +# Plugin Config (token and other sensitive data) +config.yaml +config.yml # Sonarlint plugin # https://plugins.jetbrains.com/plugin/7973-sonarlint diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDvset.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDvset.java index 6ba9a74..7e54f72 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDvset.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDvset.java @@ -2,6 +2,7 @@ import dev.jorel.commandapi.*; import dev.jorel.commandapi.arguments.StringArgument; +import dev.jorel.commandapi.executors.NativeCommandExecutor; import io.github.stonley890.dreamvisitor.Bot; import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.data.PlayerMemory; @@ -17,210 +18,225 @@ public class CmdDvset implements DVCommand { - private static void sendUserGui(@NotNull Player player) { - - PlayerMemory memory = PlayerUtility.getPlayerMemory(player.getUniqueId()); - - ComponentBuilder builder = new ComponentBuilder(Dreamvisitor.PREFIX); - builder.append("User Options "); - - if (player.hasPermission("dreamvisitor.set.discord")) { - builder.append("\n\nDiscord Visibility: ").color(ChatColor.WHITE) - .append("\nWhether to show messages from Discord's chat bridge.").color(ChatColor.GRAY) - .append("\n[").color(ChatColor.DARK_GRAY) - .append(booleanToggle(memory.discordEnabled, "discord")) - .append("").reset().append("]").color(ChatColor.DARK_GRAY); - } - - if (player.hasPermission("dreamvisitor.set.flight")) { - builder.append("\n\nFlight Disabled: ").color(ChatColor.WHITE) - .append("\nWhether Flight Mode cannot be activated.").color(ChatColor.GRAY) - .append("\n[").color(ChatColor.DARK_GRAY) - .append(booleanToggle(memory.flightDisabled, "flight")) - .append("").reset().append("]").color(ChatColor.DARK_GRAY); - } - - if (player.hasPermission("dreamvisitor.set.zoop")) { - builder.append("\n\nDiscord Vanish: ").color(ChatColor.WHITE) - .append("\nWhether to appear offline in Dreamvisitor.").color(ChatColor.GRAY) - .append("\n[").color(ChatColor.DARK_GRAY) - .append(booleanToggle(memory.vanished, "vanished")) - .append("").reset().append("]").color(ChatColor.DARK_GRAY); - } - - if (player.hasPermission("dreamvisitor.set.autoinvswap")) { - builder.append("\n\nAutomatic Inventory Swap: ").color(ChatColor.WHITE) - .append("\nWhether to automatically swap inventories on game mode change.").color(ChatColor.GRAY) - .append("\n[").color(ChatColor.DARK_GRAY) - .append(booleanToggle(memory.autoinvswap, "autoinvswap")) - .append("").reset().append("]").color(ChatColor.DARK_GRAY); - } - - if (player.hasPermission("dreamvisitor.set.autoradio")) { - builder.append("\n\nAutomatic Radio: ").color(ChatColor.WHITE) - .append("\nWhether to send all messages to staff radio.").color(ChatColor.GRAY) - .append("\n[").color(ChatColor.DARK_GRAY) - .append(booleanToggle(memory.autoRadio, "autoradio")) - .append("").reset().append("]").color(ChatColor.DARK_GRAY); - } - - builder.append("").reset().append("\n"); - player.spigot().sendMessage(builder.create()); + private static void sendUserGui(@NotNull Player player) { + PlayerMemory memory = PlayerUtility.getPlayerMemory(player.getUniqueId()); + + ComponentBuilder builder = new ComponentBuilder(Dreamvisitor.PREFIX); + builder.append("User Options "); + + if (player.hasPermission("dreamvisitor.set.discord")) { + builder.append("\n\nDiscord Visibility: ").color(ChatColor.WHITE) + .append("\nWhether to show messages from Discord's chat bridge.").color(ChatColor.GRAY) + .append("\n[").color(ChatColor.DARK_GRAY) + .append(booleanToggle(memory.discordEnabled, "discord")) + .append("").reset().append("]").color(ChatColor.DARK_GRAY); } - /** - * Creates a {@link TextComponent} representing a {@code boolean} value with a command to change it. - * - * @param value the {@code boolean} to display. - * @param cmdName the command to run. This will be formatted as {@code /dvset !value} - * @return a {@link TextComponent} representing the value with a command to change it. - */ - private static @NotNull TextComponent booleanToggle(boolean value, String cmdName) { - TextComponent toggle = new TextComponent(); - toggle.setUnderlined(true); - - if (value) { - toggle.setText("-O"); - toggle.setColor(ChatColor.GREEN); - } else { - toggle.setText("O-"); - toggle.setColor(ChatColor.RED); - } - - toggle.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(ChatColor.GRAY + "Currently toggled to " + ChatColor.WHITE + String.valueOf(value).toUpperCase() + "."))); - toggle.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/dvset " + cmdName + " " + String.valueOf(!value).toLowerCase())); - - - return toggle; + if (player.hasPermission("dreamvisitor.set.flight")) { + builder.append("\n\nFlight Disabled: ").color(ChatColor.WHITE) + .append("\nWhether Flight Mode cannot be activated.").color(ChatColor.GRAY) + .append("\n[").color(ChatColor.DARK_GRAY) + .append(booleanToggle(memory.flightDisabled, "flight")) + .append("").reset().append("]").color(ChatColor.DARK_GRAY); } - @NotNull - @Override - public CommandTree getCommand() { + if (player.hasPermission("dreamvisitor.set.zoop")) { + builder.append("\n\nDiscord Vanish: ").color(ChatColor.WHITE) + .append("\nWhether to appear offline in Dreamvisitor.").color(ChatColor.GRAY) + .append("\n[").color(ChatColor.DARK_GRAY) + .append(booleanToggle(memory.vanished, "vanished")) + .append("").reset().append("]").color(ChatColor.DARK_GRAY); + } - return new CommandTree("dvset") - .withPermission(CommandPermission.fromString("dreamvisitor.userset")) - .withHelp("Manage settings.", "Manage your Dreamvisitor settings.") - .executesNative(((sender, args) -> { - if (sender instanceof Player player && sender.hasPermission("dreamvisitor.userset")) { - // Player GUI - sendUserGui(player); - } else throw CommandAPI.failWithString("No options specified."); - })) - .then(new StringArgument("option") - .setOptional(true) - .executesNative(((sender, args) -> { - String option = (String) args.get("option"); - - CommandSender callee = sender.getCallee(); - if (!callee.hasPermission("dreamvisitor.userset")) - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - - PlayerMemory playerMemory; - - if (callee instanceof Player player) { - playerMemory = PlayerUtility.getPlayerMemory(player.getUniqueId()); - } else throw CommandAPI.failWithString("This can only be executed by a player!"); - - switch (Objects.requireNonNull(option)) { - case "discord" -> { - if (!player.hasPermission("dreamvisitor.set.discord")) - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Discord Visibility is currently set to " + ChatColor.WHITE + playerMemory.discordEnabled); - } - case "flight" -> { - if (!player.hasPermission("dreamvisitor.set.flight")) - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Flight Enabled is currently set to " + ChatColor.WHITE + playerMemory.flightDisabled); - } - case "vanished" -> { - if (!player.hasPermission("dreamvisitor.set.zoop")) - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Discord Vanish is currently set to " + ChatColor.WHITE + playerMemory.vanished); - } - case "autoinvswap" -> { - if (!player.hasPermission("dreamvisitor.set.autoinvswap")) - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Automatic Inventory Swap is currently set to " + ChatColor.WHITE + playerMemory.autoinvswap); - } - case "autoradio" -> { - if (!player.hasPermission("dreamvisitor.set.autoradio")) - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Automatic Radio is currently set to " + ChatColor.WHITE + playerMemory.autoRadio); - } - default -> - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - } - })) - .then(new StringArgument("modification") - .setOptional(true) - .executesNative(((sender, args) -> { - String option = (String) args.get("option"); - String modification = (String) args.get("modification"); - - CommandSender callee = sender.getCallee(); - if (!callee.hasPermission("dreamvisitor.userset")) - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - - PlayerMemory playerMemory; - - if (callee instanceof Player player) { - playerMemory = PlayerUtility.getPlayerMemory(player.getUniqueId()); - } else throw CommandAPI.failWithString("This can only be executed by a player!"); - - if (option == null || modification == null) { - sendUserGui(player); - return; - } - - switch (option) { - case "discord" -> { - if (!player.hasPermission("dreamvisitor.set.discord")) - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - playerMemory.discordEnabled = Boolean.parseBoolean(modification); - callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Discord Visibility toggled to " + ChatColor.WHITE + playerMemory.discordEnabled); - } - case "flight" -> { - if (!player.hasPermission("dreamvisitor.set.flight")) - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - playerMemory.flightDisabled = Boolean.parseBoolean(modification); - callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Flight Enabled toggled to " + ChatColor.WHITE + playerMemory.flightDisabled); - } - case "vanished" -> { - if (!player.hasPermission("dreamvisitor.set.zoop")) - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - playerMemory.vanished = Boolean.parseBoolean(modification); - - String chatMessage; - if (playerMemory.vanished) { - chatMessage = "**" + player.getName() + " left the game**"; - } else { - chatMessage = "**" + player.getName() + " joined the game**"; - } - Bot.getGameChatChannel().sendMessage(chatMessage).queue(); - Bot.sendLog(chatMessage); - - callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Discord Vanish toggled to " + ChatColor.WHITE + playerMemory.vanished); - } - case "autoinvswap" -> { - if (!player.hasPermission("dreamvisitor.set.autoinvswap")) - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - playerMemory.autoinvswap = Boolean.parseBoolean(modification); - callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Automatic Inventory Swap toggled to " + ChatColor.WHITE + playerMemory.autoinvswap); - } - case "autoradio" -> { - if (!player.hasPermission("dreamvisitor.set.autoradio")) - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - playerMemory.autoRadio = Boolean.parseBoolean(modification); - callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Automatic Radio toggled to " + ChatColor.WHITE + playerMemory.autoRadio); - } - default -> - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - } - sendUserGui(player); - })) - ) - ); + if (player.hasPermission("dreamvisitor.set.autoinvswap")) { + builder.append("\n\nAutomatic Inventory Swap: ").color(ChatColor.WHITE) + .append("\nWhether to automatically swap inventories on game mode change.").color(ChatColor.GRAY) + .append("\n[").color(ChatColor.DARK_GRAY) + .append(booleanToggle(memory.autoinvswap, "autoinvswap")) + .append("").reset().append("]").color(ChatColor.DARK_GRAY); + } + + if (player.hasPermission("dreamvisitor.set.autoradio")) { + builder.append("\n\nAutomatic Radio: ").color(ChatColor.WHITE) + .append("\nWhether to send all messages to staff radio.").color(ChatColor.GRAY) + .append("\n[").color(ChatColor.DARK_GRAY) + .append(booleanToggle(memory.autoRadio, "autoradio")) + .append("").reset().append("]").color(ChatColor.DARK_GRAY); + } + + builder.append("").reset().append("\n"); + player.spigot().sendMessage(builder.create()); + + } + + /** + * Creates a {@link TextComponent} representing a {@code boolean} value with a + * command to change it. + * + * @param value the {@code boolean} to display. + * @param cmdName the command to run. This will be formatted as + * {@code /dvset !value} + * @return a {@link TextComponent} representing the value with a command to + * change it. + */ + private static @NotNull TextComponent booleanToggle(boolean value, String cmdName) { + TextComponent toggle = new TextComponent(); + toggle.setUnderlined(true); + + if (value) { + toggle.setText("-O"); + toggle.setColor(ChatColor.GREEN); + } else { + toggle.setText("O-"); + toggle.setColor(ChatColor.RED); } -} \ No newline at end of file + + toggle.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text( + ChatColor.GRAY + "Currently toggled to " + ChatColor.WHITE + String.valueOf(value).toUpperCase() + "."))); + toggle.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, + "/dvset " + cmdName + " " + String.valueOf(!value).toLowerCase())); + + return toggle; + } + + @NotNull + @Override + public CommandTree getCommand() { + + return new CommandTree("dvset") + .withPermission(CommandPermission.fromString("dreamvisitor.userset")) + .withHelp("Manage settings.", "Manage your Dreamvisitor settings.") + .executesNative(((sender, args) -> { + if (sender instanceof Player player && sender.hasPermission("dreamvisitor.userset")) { + // Player GUI + sendUserGui(player); + } else + throw CommandAPI.failWithString("No options specified."); + })) + .then(new StringArgument("option") + .setOptional(true) + .executesNative((NativeCommandExecutor) ((sender, args) -> { + String option = (String) args.get("option"); + + CommandSender callee = sender.getCallee(); + if (!callee.hasPermission("dreamvisitor.userset")) + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + + PlayerMemory playerMemory; + + if (callee instanceof Player player) { + playerMemory = PlayerUtility.getPlayerMemory(player.getUniqueId()); + } else + throw CommandAPI.failWithString("This can only be executed by a player!"); + + switch (Objects.requireNonNull(option)) { + case "discord" -> { + if (!player.hasPermission("dreamvisitor.set.discord")) + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Discord Visibility is currently set to " + + ChatColor.WHITE + playerMemory.discordEnabled); + } + case "flight" -> { + if (!player.hasPermission("dreamvisitor.set.flight")) + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Flight Enabled is currently set to " + + ChatColor.WHITE + playerMemory.flightDisabled); + } + case "vanished" -> { + if (!player.hasPermission("dreamvisitor.set.zoop")) + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Discord Vanish is currently set to " + + ChatColor.WHITE + playerMemory.vanished); + } + case "autoinvswap" -> { + if (!player.hasPermission("dreamvisitor.set.autoinvswap")) + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + + "Automatic Inventory Swap is currently set to " + ChatColor.WHITE + playerMemory.autoinvswap); + } + case "autoradio" -> { + if (!player.hasPermission("dreamvisitor.set.autoradio")) + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Automatic Radio is currently set to " + + ChatColor.WHITE + playerMemory.autoRadio); + } + default -> + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + } + })) + .then(new StringArgument("modification") + .setOptional(true) + .executesNative(((sender, args) -> { + String option = (String) args.get("option"); + String modification = (String) args.get("modification"); + + CommandSender callee = sender.getCallee(); + if (!callee.hasPermission("dreamvisitor.userset")) + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + + PlayerMemory playerMemory; + + if (callee instanceof Player player) { + playerMemory = PlayerUtility.getPlayerMemory(player.getUniqueId()); + } else + throw CommandAPI.failWithString("This can only be executed by a player!"); + + if (option == null || modification == null) { + sendUserGui(player); + return; + } + + switch (option) { + case "discord" -> { + if (!player.hasPermission("dreamvisitor.set.discord")) + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + playerMemory.discordEnabled = Boolean.parseBoolean(modification); + callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Discord Visibility toggled to " + + ChatColor.WHITE + playerMemory.discordEnabled); + } + case "flight" -> { + if (!player.hasPermission("dreamvisitor.set.flight")) + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + playerMemory.flightDisabled = Boolean.parseBoolean(modification); + callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Flight Enabled toggled to " + + ChatColor.WHITE + playerMemory.flightDisabled); + } + case "vanished" -> { + if (!player.hasPermission("dreamvisitor.set.zoop")) + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + playerMemory.vanished = Boolean.parseBoolean(modification); + + String chatMessage; + if (playerMemory.vanished) { + chatMessage = "**" + player.getName() + " left the game**"; + } else { + chatMessage = "**" + player.getName() + " joined the game**"; + } + Bot.getGameChatChannel().sendMessage(chatMessage).queue(); + Bot.sendLog(chatMessage); + + callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Discord Vanish toggled to " + + ChatColor.WHITE + playerMemory.vanished); + } + case "autoinvswap" -> { + if (!player.hasPermission("dreamvisitor.set.autoinvswap")) + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + playerMemory.autoinvswap = Boolean.parseBoolean(modification); + callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Automatic Inventory Swap toggled to " + + ChatColor.WHITE + playerMemory.autoinvswap); + } + case "autoradio" -> { + if (!player.hasPermission("dreamvisitor.set.autoradio")) + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + playerMemory.autoRadio = Boolean.parseBoolean(modification); + callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Automatic Radio toggled to " + + ChatColor.WHITE + playerMemory.autoRadio); + } + default -> + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + } + sendUserGui(player); + })))); + } +} diff --git a/dreamvisitor/src/main/resources/config.yml b/dreamvisitor/src/main/resources/config.yml index 87b05fb..aa8623c 100644 --- a/dreamvisitor/src/main/resources/config.yml +++ b/dreamvisitor/src/main/resources/config.yml @@ -190,4 +190,4 @@ inactiveTaxStop: 50000 # The last time the inactive tax occurred. This should not be manually tampered with. # Default: 0 -lastInactiveTax: 0 \ No newline at end of file +lastInactiveTax: 0 From 84c42987337d6b541c230b294cdb181c5b5ba8f5 Mon Sep 17 00:00:00 2001 From: Mustfa-IT Date: Tue, 27 May 2025 16:23:24 +0300 Subject: [PATCH 02/39] Add repository interfaces for Item, Infraction, Alt, and User data operations; implement UUID formatting utility --- .../data/repository/AltRepository.java | 88 ++++ .../data/repository/InfractionRepository.java | 81 ++++ .../data/repository/ItemRepository.java | 71 +++ .../repository/PocketBaseAltRepository.java | 262 +++++++++++ .../PocketBaseInfractionRepository.java | 293 ++++++++++++ .../repository/PocketBaseItemRepository.java | 329 ++++++++++++++ .../PocketBaseUserInventoryRepository.java | 321 +++++++++++++ .../repository/PocketBaseUserRepository.java | 367 +++++++++++++++ .../repository/UserInventoryRepository.java | 90 ++++ .../data/repository/UserRepository.java | 91 ++++ .../dreamvisitor/data/type/Alt.java | 117 +++++ .../dreamvisitor/data/type/DVUser.java | 241 ++++++++++ .../dreamvisitor/data/type/Infraction.java | 110 +++++ .../dreamvisitor/data/type/Item.java | 198 ++++++++ .../dreamvisitor/data/type/UserInventory.java | 101 +++++ .../discord/DiscEventListener.java | 3 +- .../dreamvisitor/pb/PocketBase.java | 426 ++++++++++++++++++ .../dreamvisitor/pb/PocketBaseUtils.java | 133 ++++++ .../stonley890/dreamvisitor/pb/README.md | 145 ++++++ .../dreamvisitor/util/ConfigLoader.java | 76 ++++ .../dreamvisitor/util/PBConfigLoader.java | 118 +++++ .../dreamvisitor/util/UUIDFromater.java | 15 + 22 files changed, 3675 insertions(+), 1 deletion(-) create mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/AltRepository.java create mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/InfractionRepository.java create mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/ItemRepository.java create mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseAltRepository.java create mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseInfractionRepository.java create mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseItemRepository.java create mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseUserInventoryRepository.java create mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseUserRepository.java create mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/UserInventoryRepository.java create mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/UserRepository.java create mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/Alt.java create mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/DVUser.java create mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/Infraction.java create mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/Item.java create mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/UserInventory.java create mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/PocketBase.java create mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/PocketBaseUtils.java create mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/README.md create mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/ConfigLoader.java create mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/PBConfigLoader.java create mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/UUIDFromater.java diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/AltRepository.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/AltRepository.java new file mode 100644 index 0000000..6daa1aa --- /dev/null +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/AltRepository.java @@ -0,0 +1,88 @@ +package io.github.stonley890.dreamvisitor.data.repository; + +import io.github.stonley890.dreamvisitor.data.type.Alt; + +import java.util.List; +import java.util.Optional; + +/** + * Repository interface for Alt account data operations + */ +public interface AltRepository { + /** + * Find an alt by its PocketBase ID + * + * @param id PocketBase record ID + * @return Optional containing the alt if found + */ + Optional findById(String id); + + /** + * Find all alts linked to a parent user + * + * @param parentId Parent user's PocketBase ID + * @return List of alt accounts for this parent + */ + List findByParentId(String parentId); + + /** + * Find an alt by Discord ID + * + * @param discordId Discord ID (string) + * @return Optional containing the alt if found + */ + Optional findByDiscordId(String discordId); + + /** + * Find an alt by Discord Snowflake ID + * + * @param snowflakeId Discord Snowflake ID (numeric) + * @return Optional containing the alt if found + */ + Optional findBySnowflakeId(Long snowflakeId); + + /** + * Find an alt by Discord username + * + * @param discordName Discord username + * @return Optional containing the alt if found + */ + Optional findByDiscordName(String discordName); + + /** + * Get all alts + * + * @return List of all alt accounts + */ + List findAll(); + + /** + * Save an alt (create or update) + * + * @param alt Alt to save + * @return Saved alt + */ + Alt save(Alt alt); + + /** + * Delete an alt + * + * @param alt Alt to delete + */ + void delete(Alt alt); + + /** + * Delete an alt by ID + * + * @param id PocketBase ID of alt to delete + */ + void deleteById(String id); + + /** + * Get all alts matching a filter expression + * + * @param filter PocketBase filter expression + * @return List of matching alts + */ + List getAllWhere(String filter); +} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/InfractionRepository.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/InfractionRepository.java new file mode 100644 index 0000000..200235a --- /dev/null +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/InfractionRepository.java @@ -0,0 +1,81 @@ +package io.github.stonley890.dreamvisitor.data.repository; + + +import java.util.List; +import java.util.Optional; + +import io.github.stonley890.dreamvisitor.data.type.Infraction; + +/** + * Repository interface for Infraction data operations + */ +public interface InfractionRepository { + /** + * Find an infraction by its PocketBase ID + * + * @param id PocketBase record ID + * @return Optional containing the infraction if found + */ + Optional findById(String id); + + /** + * Find all infractions for a user + * + * @param userId PocketBase user ID + * @return List of infractions for the user + */ + List findByUser(String userId); + + /** + * Find all active (non-expired) infractions for a user + * + * @param userId PocketBase user ID + * @return List of active infractions for the user + */ + List findActiveByUser(String userId); + + /** + * Get all infractions + * + * @return List of all infractions + */ + List findAll(); + + /** + * Save an infraction (create or update) + * + * @param infraction Infraction to save + * @return Saved infraction + */ + Infraction save(Infraction infraction); + + /** + * Delete an infraction + * + * @param infraction Infraction to delete + */ + void delete(Infraction infraction); + + /** + * Delete an infraction by ID + * + * @param id PocketBase ID of infraction to delete + */ + void deleteById(String id); + + /** + * Get all infractions matching a filter + * + * @param filter PocketBase filter expression + * @return List of infractions matching the filter + */ + List getAllWhere(String filter); + + /** + * Load related user data for all infractions + * + * @param infractions List of infractions + * @return List of infractions with loaded user data + */ + List loadRelatedUsers(List infractions); +} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/ItemRepository.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/ItemRepository.java new file mode 100644 index 0000000..b5de479 --- /dev/null +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/ItemRepository.java @@ -0,0 +1,71 @@ +package io.github.stonley890.dreamvisitor.data.repository; + +import java.util.List; +import java.util.Optional; + +import io.github.stonley890.dreamvisitor.data.type.Item; + +/** + * Repository interface for Item data operations + */ +public interface ItemRepository { + /** + * Find an item by its PocketBase ID + * + * @param id PocketBase record ID + * @return Optional containing the item if found + */ + Optional findById(String id); + + /** + * Find an item by its name + * + * @param name Item name + * @return Optional containing the item if found + */ + Optional findByName(String name); + + /** + * Get all items + * + * @return List of all items + */ + List findAll(); + + /** + * Get all enabled items + * + * @return List of all enabled items + */ + List findAllEnabled(); + + /** + * Save an item (create or update) + * + * @param item Item to save + * @return Saved item + */ + Item save(Item item); + + /** + * Delete an item + * + * @param item Item to delete + */ + void delete(Item item); + + /** + * Delete an item by ID + * + * @param id PocketBase ID of item to delete + */ + void deleteById(String id); + + /** + * Get all items matching a filter + * + * @param filter PocketBase filter expression + * @return List of items matching the filter + */ + List getAllWhere(String filter); +} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseAltRepository.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseAltRepository.java new file mode 100644 index 0000000..3a3a91e --- /dev/null +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseAltRepository.java @@ -0,0 +1,262 @@ +package io.github.stonley890.dreamvisitor.data.repository; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.reflect.TypeToken; + +import io.github.stonley890.dreamvisitor.data.type.Alt; +import io.github.stonley890.dreamvisitor.pb.PocketBase; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +/** + * PocketBase implementation of the AltRepository interface + */ +public class PocketBaseAltRepository implements AltRepository { + private static final Logger LOGGER = Logger.getLogger(PocketBaseAltRepository.class.getName()); + private static final String COLLECTION_NAME = "user_alts"; + private final PocketBase pocketBase; + private final Gson gson; + private final UserRepository userRepository; + + /** + * Constructor for PocketBaseAltRepository + * + * @param pocketBase PocketBase client + * @param userRepository User repository for parent relationship + */ + public PocketBaseAltRepository(PocketBase pocketBase, UserRepository userRepository) { + this.pocketBase = pocketBase; + this.gson = new Gson(); + this.userRepository = userRepository; + } + + @Override + public Optional findById(String id) { + try { + JsonObject record = pocketBase.getRecord(COLLECTION_NAME, id, null, null); + return Optional.of(mapToAlt(record)); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error finding alt by ID: " + id, e); + return Optional.empty(); + } + } + + @Override + public List findByParentId(String parentId) { + try { + String filter = "parent = '" + parentId + "'"; + List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, filter, null, null); + return records.stream() + .map(this::mapToAlt) + .collect(Collectors.toList()); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error finding alts by parent ID: " + parentId, e); + return Collections.emptyList(); + } + } + + @Override + public Optional findByDiscordId(String discordId) { + try { + String filter = "discord_id = '" + discordId + "'"; + JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); + return Optional.of(mapToAlt(record)); + } catch (IOException e) { + LOGGER.log(Level.FINE, "No alt found with Discord ID: " + discordId); + return Optional.empty(); + } + } + + @Override + public Optional findBySnowflakeId(Long snowflakeId) { + return findByDiscordId(snowflakeId.toString()); + } + + @Override + public Optional findByDiscordName(String discordName) { + try { + String filter = "discord_name = '" + discordName + "'"; + JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); + return Optional.of(mapToAlt(record)); + } catch (IOException e) { + LOGGER.log(Level.FINE, "No alt found with Discord name: " + discordName); + return Optional.empty(); + } + } + + @Override + public List findAll() { + try { + List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, null, null, null); + return records.stream() + .map(this::mapToAlt) + .collect(Collectors.toList()); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error retrieving all alts", e); + return Collections.emptyList(); + } + } + + @Override + public Alt save(Alt alt) { + try { + JsonObject altData = mapToJsonObject(alt); + + if (alt.getId() != null && !alt.getId().isEmpty()) { + // Update existing alt + JsonObject updatedRecord = pocketBase.updateRecord(COLLECTION_NAME, alt.getId(), altData, null, null); + return mapToAlt(updatedRecord); + } else { + // Create new alt + JsonObject newRecord = pocketBase.createRecord(COLLECTION_NAME, altData, null, null); + return mapToAlt(newRecord); + } + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Error saving alt: " + alt.getDiscord_name(), e); + throw new RuntimeException("Failed to save alt", e); + } + } + + @Override + public void delete(Alt alt) { + if (alt.getId() != null) { + deleteById(alt.getId()); + } + } + + @Override + public void deleteById(String id) { + try { + pocketBase.deleteRecord(COLLECTION_NAME, id); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Error deleting alt with ID: " + id, e); + throw new RuntimeException("Failed to delete alt", e); + } + } + + @Override + public List getAllWhere(String filter) { + try { + List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, filter, null, null); + return records.stream() + .map(this::mapToAlt) + .collect(Collectors.toList()); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error retrieving alts with filter: " + filter, e); + return Collections.emptyList(); + } + } + + /** + * Convert a JsonObject from PocketBase to an Alt object + * + * @param json JsonObject from PocketBase API + * @return Mapped Alt object + */ + private Alt mapToAlt(JsonObject json) { + Alt alt = new Alt(); + + alt.setId(getStringOrNull(json, "id")); + alt.setCollectionId(getStringOrNull(json, "collectionId")); + alt.setCollectionName(getStringOrNull(json, "collectionName")); + + alt.setParent(getStringOrNull(json, "parent")); + alt.setDiscord_name(getStringOrNull(json, "discord_name")); + alt.setDiscord_id(getStringOrNull(json, "discord_id")); + + // Handle snowflake ID + String discordId = getStringOrNull(json, "discord_id"); + if (discordId != null) { + try { + alt.setSnowflakeId(Long.parseLong(discordId)); + } catch (NumberFormatException e) { + LOGGER.warning("Discord ID is not a valid snowflake: " + discordId); + } + } + + // Parse datetime fields + alt.setCreated(getOffsetDateTimeOrNull(json, "created")); + alt.setUpdated(getOffsetDateTimeOrNull(json, "updated")); + + // Load parent relationship if available + String parentId = alt.getParent(); + if (parentId != null && userRepository != null) { + userRepository.findById(parentId).ifPresent(alt::setCachedParent); + } + + return alt; + } + + /** + * Convert an Alt object to a JsonObject for PocketBase + * + * @param alt Alt object to convert + * @return JsonObject for PocketBase API + */ + private JsonObject mapToJsonObject(Alt alt) { + JsonObject json = new JsonObject(); + + // Only include fields that PocketBase expects for updates/creates + if (alt.getParent() != null) + json.addProperty("parent", alt.getParent()); + if (alt.getDiscord_name() != null) + json.addProperty("discord_name", alt.getDiscord_name()); + if (alt.getDiscord_id() != null) + json.addProperty("discord_id", alt.getDiscord_id()); + + return json; + } + + // Helper methods for parsing JSON values + private String getStringOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsString() : null; + } + + private OffsetDateTime getOffsetDateTimeOrNull(JsonObject json, String key) { + if (json.has(key) && !json.get(key).isJsonNull()) { + try { + String dateStr = json.get(key).getAsString(); + + // Check if the string is empty or blank + if (dateStr == null || dateStr.trim().isEmpty()) { + return null; + } + + // Handle PocketBase date format "yyyy-MM-dd HH:mm:ss.SSSZ" + if (dateStr.contains(" ") && !dateStr.contains("T")) { + // Replace space with 'T' to make it ISO-8601 compatible + dateStr = dateStr.replace(" ", "T"); + } + + return OffsetDateTime.parse(dateStr); + } catch (Exception e) { + LOGGER.warning("Failed to parse date: " + json.get(key).getAsString() + " - " + e.getMessage()); + try { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSZ"); + String dateStr = json.get(key).getAsString(); + if (dateStr == null || dateStr.trim().isEmpty()) { + return null; + } + if (dateStr.endsWith("Z")) { + dateStr = dateStr.substring(0, dateStr.length() - 1) + "+0000"; + } + return OffsetDateTime.parse(dateStr.replace(" ", "T")); + } catch (Exception ex) { + LOGGER.warning("Alternative date parsing also failed: " + ex.getMessage()); + return null; + } + } + } + return null; + } +} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseInfractionRepository.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseInfractionRepository.java new file mode 100644 index 0000000..7ff8b72 --- /dev/null +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseInfractionRepository.java @@ -0,0 +1,293 @@ +package io.github.stonley890.dreamvisitor.data.repository; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; + +import io.github.stonley890.dreamvisitor.data.type.DVUser; +import io.github.stonley890.dreamvisitor.data.type.Infraction; +import io.github.stonley890.dreamvisitor.pb.PocketBase; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +/** + * PocketBase implementation of the InfractionRepository interface + */ +public class PocketBaseInfractionRepository implements InfractionRepository { + private static final Logger LOGGER = Logger.getLogger(PocketBaseInfractionRepository.class.getName()); + private static final String COLLECTION_NAME = "infractions"; + private final PocketBase pocketBase; + private final Gson gson; + private final UserRepository userRepository; + + /** + * Constructor for PocketBaseInfractionRepository + * + * @param pocketBase The PocketBase client to use + * @param userRepository The user repository for fetching related users + */ + public PocketBaseInfractionRepository(PocketBase pocketBase, UserRepository userRepository) { + this.pocketBase = pocketBase; + this.gson = new Gson(); + this.userRepository = userRepository; + } + + @Override + public Optional findById(String id) { + try { + JsonObject record = pocketBase.getRecord(COLLECTION_NAME, id, null, null); + return Optional.of(mapToInfraction(record)); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error finding infraction by ID: " + id, e); + return Optional.empty(); + } + } + + @Override + public List findByUser(String userId) { + try { + String filter = "user = '" + userId + "'"; + List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, filter, null, null); + List infractions = records.stream() + .map(this::mapToInfraction) + .collect(Collectors.toList()); + + // Load related users if there are infractions + if (!infractions.isEmpty()) { + loadRelatedUsers(infractions); + } + + return infractions; + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error retrieving infractions for user: " + userId, e); + return Collections.emptyList(); + } + } + + @Override + public List findActiveByUser(String userId) { + try { + String filter = "user = '" + userId + "' && expired = false"; + List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, filter, null, null); + List infractions = records.stream() + .map(this::mapToInfraction) + .collect(Collectors.toList()); + + // Load related users if there are infractions + if (!infractions.isEmpty()) { + loadRelatedUsers(infractions); + } + + return infractions; + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error retrieving active infractions for user: " + userId, e); + return Collections.emptyList(); + } + } + + @Override + public List findAll() { + try { + List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, null, null, null); + return records.stream() + .map(this::mapToInfraction) + .collect(Collectors.toList()); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error retrieving all infractions", e); + return Collections.emptyList(); + } + } + + @Override + public Infraction save(Infraction infraction) { + try { + JsonObject infractionData = mapToJsonObject(infraction); + + if (infraction.getId() != null && !infraction.getId().isEmpty()) { + // Update existing infraction + JsonObject updatedRecord = pocketBase.updateRecord(COLLECTION_NAME, infraction.getId(), infractionData, null, + null); + return mapToInfraction(updatedRecord); + } else { + // Create new infraction + JsonObject newRecord = pocketBase.createRecord(COLLECTION_NAME, infractionData, null, null); + return mapToInfraction(newRecord); + } + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Error saving infraction: " + infraction.getId(), e); + throw new RuntimeException("Failed to save infraction", e); + } + } + + @Override + public void delete(Infraction infraction) { + if (infraction.getId() != null) { + deleteById(infraction.getId()); + } + } + + @Override + public void deleteById(String id) { + try { + pocketBase.deleteRecord(COLLECTION_NAME, id); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Error deleting infraction with ID: " + id, e); + throw new RuntimeException("Failed to delete infraction", e); + } + } + + @Override + public List getAllWhere(String filter) { + try { + List records = pocketBase.getFullList(COLLECTION_NAME, 500, filter, null, null, null); + return records.stream() + .map(this::mapToInfraction) + .collect(Collectors.toList()); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error retrieving infractions with filter: " + filter, e); + return Collections.emptyList(); + } + } + + @Override + public List loadRelatedUsers(List infractions) { + // Get unique user IDs + Set userIds = infractions.stream() + .map(Infraction::getUser) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // Fetch all users in one go + Map userMap = new HashMap<>(); + for (String userId : userIds) { + userRepository.findById(userId).ifPresent(user -> userMap.put(userId, user)); + } + + // Set cached users + for (Infraction infraction : infractions) { + if (infraction.getUser() != null && userMap.containsKey(infraction.getUser())) { + infraction.setCachedUser(userMap.get(infraction.getUser())); + } + } + + return infractions; + } + + /** + * Convert a JsonObject from PocketBase to an Infraction object + * + * @param json JsonObject from PocketBase API + * @return Mapped Infraction object + */ + private Infraction mapToInfraction(JsonObject json) { + Infraction infraction = new Infraction(); + + infraction.setId(getStringOrNull(json, "id")); + infraction.setCollectionId(getStringOrNull(json, "collectionId")); + infraction.setCollectionName(getStringOrNull(json, "collectionName")); + + infraction.setReason(getStringOrNull(json, "reason")); + infraction.setSend_warning(getBooleanOrNull(json, "send_warning")); + infraction.setExpired(getBooleanOrNull(json, "expired")); + infraction.setValue(getIntOrNull(json, "value")); + infraction.setUser(getStringOrNull(json, "user")); + + infraction.setCreated(getOffsetDateTimeOrNull(json, "created")); + infraction.setUpdated(getOffsetDateTimeOrNull(json, "updated")); + + return infraction; + } + + /** + * Convert an Infraction object to a JsonObject for PocketBase + * + * @param infraction Infraction object to convert + * @return JsonObject for PocketBase API + */ + private JsonObject mapToJsonObject(Infraction infraction) { + JsonObject json = new JsonObject(); + + // Only include fields that PocketBase expects for updates/creates + if (infraction.getReason() != null) + json.addProperty("reason", infraction.getReason()); + if (infraction.getSend_warning() != null) + json.addProperty("send_warning", infraction.getSend_warning()); + if (infraction.getExpired() != null) + json.addProperty("expired", infraction.getExpired()); + if (infraction.getValue() != null) + json.addProperty("value", infraction.getValue()); + if (infraction.getUser() != null) + json.addProperty("user", infraction.getUser()); + + return json; + } + + // Helper methods for extracting values from JsonObject + private String getStringOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsString() : null; + } + + private Integer getIntOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsInt() : null; + } + + private Boolean getBooleanOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsBoolean() : null; + } + + private OffsetDateTime getOffsetDateTimeOrNull(JsonObject json, String key) { + if (json.has(key) && !json.get(key).isJsonNull()) { + try { + String dateStr = json.get(key).getAsString(); + + // Check if the string is empty or blank + if (dateStr == null || dateStr.trim().isEmpty()) { + return null; + } + + // Handle PocketBase date format "yyyy-MM-dd HH:mm:ss.SSSZ" + if (dateStr.contains(" ") && !dateStr.contains("T")) { + // Replace space with 'T' to make it ISO-8601 compatible + dateStr = dateStr.replace(" ", "T"); + } + + return OffsetDateTime.parse(dateStr); + } catch (Exception e) { + LOGGER.warning("Failed to parse date: " + json.get(key).getAsString() + " - " + e.getMessage()); + + // Try alternative parsing with explicit formatter + try { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSZ"); + String dateStr = json.get(key).getAsString(); + + // Check if the string is empty or blank + if (dateStr == null || dateStr.trim().isEmpty()) { + return null; + } + + // Convert to ISO format for parsing + if (dateStr.endsWith("Z")) { + dateStr = dateStr.substring(0, dateStr.length() - 1) + "+0000"; + } + + return OffsetDateTime.parse(dateStr.replace(" ", "T")); + } catch (Exception ex) { + LOGGER.warning("Alternative date parsing also failed: " + ex.getMessage()); + return null; + } + } + } + return null; + } + + private String formatDateTime(OffsetDateTime dateTime) { + return dateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); + } +} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseItemRepository.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseItemRepository.java new file mode 100644 index 0000000..e7bd7ad --- /dev/null +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseItemRepository.java @@ -0,0 +1,329 @@ +package io.github.stonley890.dreamvisitor.data.repository; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; + +import io.github.stonley890.dreamvisitor.data.type.Item; +import io.github.stonley890.dreamvisitor.pb.PocketBase; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +/** + * PocketBase implementation of the ItemRepository interface + */ +public class PocketBaseItemRepository implements ItemRepository { + private static final Logger LOGGER = Logger.getLogger(PocketBaseItemRepository.class.getName()); + private static final String COLLECTION_NAME = "items"; + private final PocketBase pocketBase; + private final Gson gson; + + /** + * Constructor for PocketBaseItemRepository + * + * @param pocketBase The PocketBase client to use + */ + public PocketBaseItemRepository(PocketBase pocketBase) { + this.pocketBase = pocketBase; + this.gson = new Gson(); + } + + @Override + public Optional findById(String id) { + try { + JsonObject record = pocketBase.getRecord(COLLECTION_NAME, id, null, null); + return Optional.of(mapToItem(record)); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error finding item by ID: " + id, e); + return Optional.empty(); + } + } + + @Override + public Optional findByName(String name) { + try { + String filter = "name = '" + name + "'"; + JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); + return Optional.of(mapToItem(record)); + } catch (IOException e) { + LOGGER.log(Level.FINE, "No item found with name: " + name); + return Optional.empty(); + } + } + + @Override + public List findAll() { + try { + List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, null, null, null); + return records.stream() + .map(this::mapToItem) + .collect(Collectors.toList()); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error retrieving all items", e); + return Collections.emptyList(); + } + } + + @Override + public List findAllEnabled() { + try { + String filter = "enabled = true"; + List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, filter, null, null); + return records.stream() + .map(this::mapToItem) + .collect(Collectors.toList()); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error retrieving enabled items", e); + return Collections.emptyList(); + } + } + + @Override + public Item save(Item item) { + try { + JsonObject itemData = mapToJsonObject(item); + + if (item.getId() != null && !item.getId().isEmpty()) { + // Update existing item + JsonObject updatedRecord = pocketBase.updateRecord(COLLECTION_NAME, item.getId(), itemData, null, null); + return mapToItem(updatedRecord); + } else { + // Create new item + JsonObject newRecord = pocketBase.createRecord(COLLECTION_NAME, itemData, null, null); + return mapToItem(newRecord); + } + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Error saving item: " + item.getName(), e); + throw new RuntimeException("Failed to save item", e); + } + } + + @Override + public void delete(Item item) { + if (item.getId() != null) { + deleteById(item.getId()); + } + } + + @Override + public void deleteById(String id) { + try { + pocketBase.deleteRecord(COLLECTION_NAME, id); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Error deleting item with ID: " + id, e); + throw new RuntimeException("Failed to delete item", e); + } + } + + @Override + public List getAllWhere(String filter) { + try { + List records = pocketBase.getFullList(COLLECTION_NAME, 500, filter, null, null, null); + return records.stream() + .map(this::mapToItem) + .collect(Collectors.toList()); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error retrieving items with filter: " + filter, e); + return Collections.emptyList(); + } + } + + /** + * Convert a JsonObject from PocketBase to an Item object + * + * @param json JsonObject from PocketBase API + * @return Mapped Item object + */ + private Item mapToItem(JsonObject json) { + Item item = new Item(); + + item.setId(getStringOrNull(json, "id")); + item.setCollectionId(getStringOrNull(json, "collectionId")); + item.setCollectionName(getStringOrNull(json, "collectionName")); + + item.setName(getStringOrNull(json, "name")); + item.setDescription(getStringOrNull(json, "description")); + item.setPrice(getDoubleOrNull(json, "price")); + item.setSale_percent(getDoubleOrNull(json, "sale_percent")); + item.setQuantity(getIntOrNull(json, "quantity")); + item.setGifting_enabled(getBooleanOrNull(json, "gifting_enabled")); + item.setEnabled(getBooleanOrNull(json, "enabled")); + item.setMax_allowed(getIntOrNull(json, "max_allowed")); + item.setUse_disabled(getBooleanOrNull(json, "use_disabled")); + item.setUse_on_purchase(getBooleanOrNull(json, "use_on_purchase")); + + // For JSON fields that could be arrays, use getJsonArrayAsString + item.setOn_use_groups_add(getJsonArrayAsString(json, "on_use_groups_add")); + item.setOn_use_groups_remove(getJsonArrayAsString(json, "on_use_groups_remove")); + item.setOn_use_roles_add(getJsonArrayAsString(json, "on_use_roles_add")); + item.setOn_use_roles_remove(getJsonArrayAsString(json, "on_use_roles_remove")); + item.setOn_use_console_commands(getJsonArrayAsString(json, "on_use_console_commands")); + + item.setCreated(getOffsetDateTimeOrNull(json, "created")); + item.setUpdated(getOffsetDateTimeOrNull(json, "updated")); + + return item; + } + + /** + * Convert an Item object to a JsonObject for PocketBase + * + * @param item Item object to convert + * @return JsonObject for PocketBase API + */ + private JsonObject mapToJsonObject(Item item) { + JsonObject json = new JsonObject(); + + // Only include fields that PocketBase expects for updates/creates + if (item.getName() != null) + json.addProperty("name", item.getName()); + if (item.getDescription() != null) + json.addProperty("description", item.getDescription()); + + // Always include price even if it's 0.0 - PocketBase requires this field + // Previously we only included it if not null, but 0.0 might still be included + // in the JSON + if (item.getPrice() != null) { + json.addProperty("price", item.getPrice()); + } else { + // Set a default price of 0.0 if null to prevent validation errors + json.addProperty("price", 0.0); + } + + // For all other optional fields, only include if not null + if (item.getSale_percent() != null) + json.addProperty("sale_percent", item.getSale_percent()); + if (item.getQuantity() != null) + json.addProperty("quantity", item.getQuantity()); + if (item.getGifting_enabled() != null) + json.addProperty("gifting_enabled", item.getGifting_enabled()); + if (item.getEnabled() != null) + json.addProperty("enabled", item.getEnabled()); + if (item.getMax_allowed() != null) + json.addProperty("max_allowed", item.getMax_allowed()); + if (item.getUse_disabled() != null) + json.addProperty("use_disabled", item.getUse_disabled()); + if (item.getUse_on_purchase() != null) + json.addProperty("use_on_purchase", item.getUse_on_purchase()); + if (item.getOn_use_groups_add() != null) + json.addProperty("on_use_groups_add", item.getOn_use_groups_add()); + if (item.getOn_use_groups_remove() != null) + json.addProperty("on_use_groups_remove", item.getOn_use_groups_remove()); + if (item.getOn_use_roles_add() != null) + json.addProperty("on_use_roles_add", item.getOn_use_roles_add()); + if (item.getOn_use_roles_remove() != null) + json.addProperty("on_use_roles_remove", item.getOn_use_roles_remove()); + if (item.getOn_use_console_commands() != null) + json.addProperty("on_use_console_commands", item.getOn_use_console_commands()); + + return json; + } + + // Helper methods for extracting values from JsonObject + private String getStringOrNull(JsonObject json, String key) { + if (!json.has(key) || json.get(key).isJsonNull()) { + return null; + } + + com.google.gson.JsonElement element = json.get(key); + if (element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) { + return element.getAsString(); + } else { + LOGGER.warning("Field " + key + " is not a string primitive: " + element); + return null; + } + } + + private Integer getIntOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsInt() : null; + } + + private Double getDoubleOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsDouble() : null; + } + + private Boolean getBooleanOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsBoolean() : null; + } + + private OffsetDateTime getOffsetDateTimeOrNull(JsonObject json, String key) { + if (json.has(key) && !json.get(key).isJsonNull()) { + try { + String dateStr = json.get(key).getAsString(); + + // Check if the string is empty or blank + if (dateStr == null || dateStr.trim().isEmpty()) { + return null; + } + + // Handle PocketBase date format "yyyy-MM-dd HH:mm:ss.SSSZ" + if (dateStr.contains(" ") && !dateStr.contains("T")) { + // Replace space with 'T' to make it ISO-8601 compatible + dateStr = dateStr.replace(" ", "T"); + } + + return OffsetDateTime.parse(dateStr); + } catch (Exception e) { + LOGGER.warning("Failed to parse date: " + json.get(key).getAsString() + " - " + e.getMessage()); + + // Try alternative parsing with explicit formatter + try { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSZ"); + String dateStr = json.get(key).getAsString(); + + // Check if the string is empty or blank + if (dateStr == null || dateStr.trim().isEmpty()) { + return null; + } + + // Convert to ISO format for parsing + if (dateStr.endsWith("Z")) { + dateStr = dateStr.substring(0, dateStr.length() - 1) + "+0000"; + } + + return OffsetDateTime.parse(dateStr.replace(" ", "T")); + } catch (Exception ex) { + LOGGER.warning("Alternative date parsing also failed: " + ex.getMessage()); + return null; + } + } + } + return null; + } + + private String formatDateTime(OffsetDateTime dateTime) { + return dateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); + } + + /** + * Safely get a JSON array field as a JSON string + * Handles cases where the field could be a string, array, or other type + */ + private String getJsonArrayAsString(JsonObject json, String key) { + if (!json.has(key) || json.get(key).isJsonNull()) { + return null; + } + + com.google.gson.JsonElement element = json.get(key); + if (element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) { + // It's already a string, return it directly + return element.getAsString(); + } else if (element.isJsonArray()) { + // It's an array, convert to a well-formatted JSON string + return element.toString(); + } else { + // For any other type, convert to string representation + LOGGER.warning("Field " + key + " is not a string or array: " + element); + return element.toString(); + } + } +} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseUserInventoryRepository.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseUserInventoryRepository.java new file mode 100644 index 0000000..0db4e03 --- /dev/null +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseUserInventoryRepository.java @@ -0,0 +1,321 @@ +package io.github.stonley890.dreamvisitor.data.repository; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; + +import io.github.stonley890.dreamvisitor.data.type.DVUser; +import io.github.stonley890.dreamvisitor.data.type.Item; +import io.github.stonley890.dreamvisitor.data.type.UserInventory; +import io.github.stonley890.dreamvisitor.pb.PocketBase; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +/** + * PocketBase implementation of the UserInventoryRepository interface + */ +public class PocketBaseUserInventoryRepository implements UserInventoryRepository { + private static final Logger LOGGER = Logger.getLogger(PocketBaseUserInventoryRepository.class.getName()); + private static final String COLLECTION_NAME = "user_inventory"; + private final PocketBase pocketBase; + private final Gson gson; + private final UserRepository userRepository; + private final ItemRepository itemRepository; + + /** + * Constructor for PocketBaseUserInventoryRepository + * + * @param pocketBase The PocketBase client to use + * @param userRepository The user repository for fetching related users + * @param itemRepository The item repository for fetching related items + */ + public PocketBaseUserInventoryRepository(PocketBase pocketBase, UserRepository userRepository, + ItemRepository itemRepository) { + this.pocketBase = pocketBase; + this.gson = new Gson(); + this.userRepository = userRepository; + this.itemRepository = itemRepository; + } + + @Override + public Optional findById(String id) { + try { + JsonObject record = pocketBase.getRecord(COLLECTION_NAME, id, null, null); + return Optional.of(mapToUserInventory(record)); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error finding user inventory by ID: " + id, e); + return Optional.empty(); + } + } + + @Override + public List findByUser(String userId) { + try { + String filter = "user = '" + userId + "'"; + List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, filter, null, null); + List inventoryEntries = records.stream() + .map(this::mapToUserInventory) + .collect(Collectors.toList()); + + // Load related items if there are inventory entries + if (!inventoryEntries.isEmpty()) { + loadRelatedItems(inventoryEntries); + } + + return inventoryEntries; + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error retrieving user inventory for user: " + userId, e); + return Collections.emptyList(); + } + } + + @Override + public Optional findByUserAndItem(String userId, String itemId) { + try { + String filter = "user = '" + userId + "' && item = '" + itemId + "'"; + JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); + UserInventory inventory = mapToUserInventory(record); + + // Load related item and user + if (inventory.getItem() != null) { + itemRepository.findById(inventory.getItem()).ifPresent(inventory::setCachedItem); + } + if (inventory.getUser() != null) { + userRepository.findById(inventory.getUser()).ifPresent(inventory::setCachedUser); + } + + return Optional.of(inventory); + } catch (IOException e) { + LOGGER.log(Level.FINE, "No inventory entry found for user: " + userId + " and item: " + itemId); + return Optional.empty(); + } + } + + @Override + public List findAll() { + try { + List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, null, null, null); + return records.stream() + .map(this::mapToUserInventory) + .collect(Collectors.toList()); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error retrieving all user inventory entries", e); + return Collections.emptyList(); + } + } + + @Override + public UserInventory save(UserInventory userInventory) { + try { + JsonObject inventoryData = mapToJsonObject(userInventory); + + if (userInventory.getId() != null && !userInventory.getId().isEmpty()) { + // Update existing inventory entry + JsonObject updatedRecord = pocketBase.updateRecord(COLLECTION_NAME, userInventory.getId(), inventoryData, null, + null); + return mapToUserInventory(updatedRecord); + } else { + // Create new inventory entry + JsonObject newRecord = pocketBase.createRecord(COLLECTION_NAME, inventoryData, null, null); + return mapToUserInventory(newRecord); + } + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Error saving user inventory entry: " + userInventory.getId(), e); + throw new RuntimeException("Failed to save user inventory entry", e); + } + } + + @Override + public void delete(UserInventory userInventory) { + if (userInventory.getId() != null) { + deleteById(userInventory.getId()); + } + } + + @Override + public void deleteById(String id) { + try { + pocketBase.deleteRecord(COLLECTION_NAME, id); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Error deleting user inventory entry with ID: " + id, e); + throw new RuntimeException("Failed to delete user inventory entry", e); + } + } + + @Override + public List getAllWhere(String filter) { + try { + List records = pocketBase.getFullList(COLLECTION_NAME, 500, filter, null, null, null); + return records.stream() + .map(this::mapToUserInventory) + .collect(Collectors.toList()); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error retrieving user inventory entries with filter: " + filter, e); + return Collections.emptyList(); + } + } + + @Override + public List loadRelatedItems(List inventoryEntries) { + // Get unique item IDs + Set itemIds = inventoryEntries.stream() + .map(UserInventory::getItem) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // Fetch all items in one go + Map itemMap = new HashMap<>(); + for (String itemId : itemIds) { + itemRepository.findById(itemId).ifPresent(item -> itemMap.put(itemId, item)); + } + + // Set cached items + for (UserInventory entry : inventoryEntries) { + if (entry.getItem() != null && itemMap.containsKey(entry.getItem())) { + entry.setCachedItem(itemMap.get(entry.getItem())); + } + } + + return inventoryEntries; + } + + @Override + public List loadRelatedUsers(List inventoryEntries) { + // Get unique user IDs + Set userIds = inventoryEntries.stream() + .map(UserInventory::getUser) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // Fetch all users in one go + Map userMap = new HashMap<>(); + for (String userId : userIds) { + userRepository.findById(userId).ifPresent(user -> userMap.put(userId, user)); + } + + // Set cached users + for (UserInventory entry : inventoryEntries) { + if (entry.getUser() != null && userMap.containsKey(entry.getUser())) { + entry.setCachedUser(userMap.get(entry.getUser())); + } + } + + return inventoryEntries; + } + + /** + * Convert a JsonObject from PocketBase to a UserInventory object + * + * @param json JsonObject from PocketBase API + * @return Mapped UserInventory object + */ + private UserInventory mapToUserInventory(JsonObject json) { + UserInventory inventory = new UserInventory(); + + inventory.setId(getStringOrNull(json, "id")); + inventory.setCollectionId(getStringOrNull(json, "collectionId")); + inventory.setCollectionName(getStringOrNull(json, "collectionName")); + + inventory.setUser(getStringOrNull(json, "user")); + inventory.setItem(getStringOrNull(json, "item")); + inventory.setQuantity(getIntOrNull(json, "quantity")); + + inventory.setCreated(getOffsetDateTimeOrNull(json, "created")); + inventory.setUpdated(getOffsetDateTimeOrNull(json, "updated")); + + return inventory; + } + + /** + * Convert a UserInventory object to a JsonObject for PocketBase + * + * @param inventory UserInventory object to convert + * @return JsonObject for PocketBase API + */ + private JsonObject mapToJsonObject(UserInventory inventory) { + JsonObject json = new JsonObject(); + + // Only include fields that PocketBase expects for updates/creates + if (inventory.getUser() != null) + json.addProperty("user", inventory.getUser()); + if (inventory.getItem() != null) + json.addProperty("item", inventory.getItem()); + if (inventory.getQuantity() != null) + json.addProperty("quantity", inventory.getQuantity()); + + return json; + } + + // Helper methods for extracting values from JsonObject + private String getStringOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsString() : null; + } + + private Integer getIntOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsInt() : null; + } + + private Double getDoubleOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsDouble() : null; + } + + private Boolean getBooleanOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsBoolean() : null; + } + + private OffsetDateTime getOffsetDateTimeOrNull(JsonObject json, String key) { + if (json.has(key) && !json.get(key).isJsonNull()) { + try { + String dateStr = json.get(key).getAsString(); + + // Check if the string is empty or blank + if (dateStr == null || dateStr.trim().isEmpty()) { + return null; + } + + // Handle PocketBase date format "yyyy-MM-dd HH:mm:ss.SSSZ" + if (dateStr.contains(" ") && !dateStr.contains("T")) { + // Replace space with 'T' to make it ISO-8601 compatible + dateStr = dateStr.replace(" ", "T"); + } + + return OffsetDateTime.parse(dateStr); + } catch (Exception e) { + LOGGER.warning("Failed to parse date: " + json.get(key).getAsString() + " - " + e.getMessage()); + + // Try alternative parsing with explicit formatter + try { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSZ"); + String dateStr = json.get(key).getAsString(); + + // Check if the string is empty or blank + if (dateStr == null || dateStr.trim().isEmpty()) { + return null; + } + + // Convert to ISO format for parsing + if (dateStr.endsWith("Z")) { + dateStr = dateStr.substring(0, dateStr.length() - 1) + "+0000"; + } + + return OffsetDateTime.parse(dateStr.replace(" ", "T")); + } catch (Exception ex) { + LOGGER.warning("Alternative date parsing also failed: " + ex.getMessage()); + return null; + } + } + } + return null; + } + + private String formatDateTime(OffsetDateTime dateTime) { + return dateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); + } +} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseUserRepository.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseUserRepository.java new file mode 100644 index 0000000..7cbc01b --- /dev/null +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseUserRepository.java @@ -0,0 +1,367 @@ +package io.github.stonley890.dreamvisitor.data.repository; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.reflect.TypeToken; + +import io.github.stonley890.dreamvisitor.data.type.DVUser; +import io.github.stonley890.dreamvisitor.pb.PocketBase; +import io.github.stonley890.dreamvisitor.util.UUIDFromater; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.function.Predicate; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +/** + * PocketBase implementation of the UserRepository interface + */ +public class PocketBaseUserRepository implements UserRepository { + private static final Logger LOGGER = Logger.getLogger(PocketBaseUserRepository.class.getName()); + private static final String COLLECTION_NAME = "users"; + private final PocketBase pocketBase; + private final Gson gson; + + /** + * Constructor for PocketBaseUserRepository + * + * @param pocketBase The PocketBase client to use + */ + public PocketBaseUserRepository(PocketBase pocketBase) { + this.pocketBase = pocketBase; + this.gson = new Gson(); + } + + @Override + public Optional findById(String id) { + try { + JsonObject record = pocketBase.getRecord(COLLECTION_NAME, id, null, null); + return Optional.of(mapToUser(record)); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error finding user by ID: " + id, e); + return Optional.empty(); + } + } + + @Override + public Optional findByUuid(UUID mc_uuid) { + try { + String filter = "mc_uuid = '" + mc_uuid.toString() + "'"; + JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); + return Optional.of(mapToUser(record)); + } catch (IOException e) { + LOGGER.log(Level.FINE, "No user found with UUID: " + mc_uuid); + return Optional.empty(); + } + } + + @Override + public Optional findByDiscordId(String discordId) { + try { + String filter = "discord_id = '" + discordId + "'"; + JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); + return Optional.of(mapToUser(record)); + } catch (IOException e) { + LOGGER.log(Level.FINE, "No user found with Discord ID: " + discordId); + return Optional.empty(); + } + } + + @Override + public Optional findBySnowflakeId(Long snowflakeId) { + try { + // First try with the direct snowflake ID + String filter = "discord_id = '" + snowflakeId.toString() + "'"; + LOGGER.info("Searching for user with filter: " + filter); + + try { + JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); + LOGGER.info("User found with snowflake ID: " + snowflakeId); + DVUser user = mapToUser(record); + return Optional.of(user); + } catch (IOException e) { + // First search failed, try with just string comparison if numeric search fails + LOGGER.info("No exact match found, trying alternative search..."); + filter = "discord_id ~ '" + snowflakeId.toString() + "'"; + try { + JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); + LOGGER.info("User found with partial match: " + record.toString()); + DVUser user = mapToUser(record); + return Optional.of(user); + } catch (IOException e2) { + LOGGER.log(Level.INFO, "No user found with Snowflake ID (partial match): " + snowflakeId); + return Optional.empty(); + } + } + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Error searching for user with Snowflake ID: " + snowflakeId, e); + return Optional.empty(); + } + } + + @Override + public Optional findByMcUsername(String mcUsername) { + try { + String filter = "mc_username = '" + mcUsername + "'"; + JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); + return Optional.of(mapToUser(record)); + } catch (IOException e) { + LOGGER.log(Level.FINE, "No user found with MC username: " + mcUsername); + return Optional.empty(); + } + } + + @Override + public List findAll() { + try { + List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, null, null, null); + return records.stream() + .map(this::mapToUser) + .collect(Collectors.toList()); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error retrieving all users", e); + return Collections.emptyList(); + } + } + + @Override + public DVUser save(DVUser user) { + try { + JsonObject userData = mapToJsonObject(user); + + if (user.getId() != null && !user.getId().isEmpty()) { + // Update existing user + JsonObject updatedRecord = pocketBase.updateRecord(COLLECTION_NAME, user.getId(), userData, null, null); + return mapToUser(updatedRecord); + } else { + // Create new user + JsonObject newRecord = pocketBase.createRecord(COLLECTION_NAME, userData, null, null); + return mapToUser(newRecord); + } + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Error saving user: " + user.getMcUsername(), e); + throw new RuntimeException("Failed to save user", e); + } + } + + @Override + public void delete(DVUser user) { + if (user.getId() != null) { + deleteById(user.getId()); + } + } + + @Override + public void deleteById(String id) { + try { + pocketBase.deleteRecord(COLLECTION_NAME, id); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Error deleting user with ID: " + id, e); + throw new RuntimeException("Failed to delete user", e); + } + } + + /** + * Convert a JsonObject from PocketBase to a User object + * + * @param json JsonObject from PocketBase API + * @return Mapped User object + */ + private DVUser mapToUser(JsonObject json) { + DVUser user = new DVUser(); + + user.setId(getStringOrNull(json, "id")); + user.setCollectionId(getStringOrNull(json, "collectionId")); + user.setCollectionName(getStringOrNull(json, "collectionName")); + + user.setDiscord_id(getStringOrNull(json, "discord_id")); + user.setDiscord_username(getStringOrNull(json, "discord_username")); + user.setDiscord_img(getStringOrNull(json, "discord_img")); + user.setMcUsername(getStringOrNull(json, "mc_username")); + + if (json.has("mc_uuid") && !json.get("mc_uuid").isJsonNull()) { + try { + user.setMc_uuid(UUID.fromString(UUIDFromater.formatUuid(json.get("mc_uuid").getAsString()))); + } catch (IllegalArgumentException e) { + LOGGER.warning("Invalid UUID format: " + json.get("mc_uuid").getAsString()); + } + } + + if (user.getDiscord_id() != null) { + try { + user.setSnowflakeId(Long.parseLong(user.getDiscord_id())); + } catch (NumberFormatException e) { + LOGGER.warning("Discord ID is not a valid snowflake: " + user.getDiscord_id()); + } + } + + // Parse relation lists + user.setInfractions(getStringListOrEmpty(json, "infractions")); + user.setUsers_home(getStringListOrEmpty(json, "users_home")); + user.setInventory_items(getStringListOrEmpty(json, "inventory_items")); + user.setClaims(getStringListOrEmpty(json, "claims")); + + // Parse numeric fields + user.setClaim_limit(getIntOrNull(json, "claim_limit")); + user.setPlay_time(getIntOrNull(json, "play_time")); + user.setBalance(getDoubleOrNull(json, "balance")); + user.setDaily_streak(getIntOrNull(json, "daily_streak")); + + // Parse boolean fields + user.setIs_suspended(getBooleanOrNull(json, "is_suspended")); + user.setIs_banned(getBooleanOrNull(json, "is_banned")); + + // Parse datetime fields + user.setLast_work(getOffsetDateTimeOrNull(json, "last_work")); + user.setLast_Played(getOffsetDateTimeOrNull(json, "last_played")); + user.setLast_daily(getOffsetDateTimeOrNull(json, "last_daily")); + user.setCreated(getOffsetDateTimeOrNull(json, "created")); + user.setUpdated(getOffsetDateTimeOrNull(json, "updated")); + + return user; + } + + /** + * Convert a User object to a JsonObject for PocketBase + * + * @param user User object to convert + * @return JsonObject for PocketBase API + */ + private JsonObject mapToJsonObject(DVUser user) { + JsonObject json = new JsonObject(); + + // Only include fields that PocketBase expects for updates/creates + if (user.getDiscord_id() != null) + json.addProperty("discord_id", user.getDiscord_id()); + if (user.getDiscord_username() != null) + json.addProperty("discord_username", user.getDiscord_username()); + if (user.getDiscord_img() != null) + json.addProperty("discord_img", user.getDiscord_img()); + if (user.getMcUsername() != null) + json.addProperty("mc_username", user.getMcUsername()); + if (user.getMc_uuid() != null) + json.addProperty("mc_uuid", user.getMc_uuid().toString()); + + // Add numeric fields + if (user.getClaim_limit() != null) + json.addProperty("claim_limit", user.getClaim_limit()); + if (user.getPlay_time() != null) + json.addProperty("play_time", user.getPlay_time()); + if (user.getBalance() != null) + json.addProperty("balance", user.getBalance()); + if (user.getDaily_streak() != null) + json.addProperty("daily_streak", user.getDaily_streak()); + + // Add boolean fields + if (user.getIs_suspended() != null) + json.addProperty("is_suspended", user.getIs_suspended()); + if (user.getIs_banned() != null) + json.addProperty("is_banned", user.getIs_banned()); + + // Format and add datetime fields + if (user.getLast_work() != null) + json.addProperty("last_work", formatDateTime(user.getLast_work())); + if (user.getLast_daily() != null) + json.addProperty("last_daily", formatDateTime(user.getLast_daily())); + + // Add relation fields (these need to be handled separately based on + // PocketBase's expectations) + // For now, we'll just leave them out as they typically require special handling + // TODO:Add relation fields + return json; + } + + private String getStringOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsString() : null; + } + + private Integer getIntOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsInt() : null; + } + + private Double getDoubleOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsDouble() : null; + } + + private Boolean getBooleanOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsBoolean() : null; + } + + private OffsetDateTime getOffsetDateTimeOrNull(JsonObject json, String key) { + if (json.has(key) && !json.get(key).isJsonNull()) { + try { + String dateStr = json.get(key).getAsString(); + + // Check if the string is empty or blank + if (dateStr == null || dateStr.trim().isEmpty()) { + return null; + } + + // Handle PocketBase date format "yyyy-MM-dd HH:mm:ss.SSSZ" + if (dateStr.contains(" ") && !dateStr.contains("T")) { + // Replace space with 'T' to make it ISO-8601 compatible + dateStr = dateStr.replace(" ", "T"); + } + + return OffsetDateTime.parse(dateStr); + } catch (Exception e) { + LOGGER.warning("Failed to parse date: " + json.get(key).getAsString() + " - " + e.getMessage()); + + // Try alternative parsing with explicit formatter + try { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSZ"); + String dateStr = json.get(key).getAsString(); + + // Check if the string is empty or blank + if (dateStr == null || dateStr.trim().isEmpty()) { + return null; + } + + // Convert to ISO format for parsing + if (dateStr.endsWith("Z")) { + dateStr = dateStr.substring(0, dateStr.length() - 1) + "+0000"; + } + + return OffsetDateTime.parse(dateStr.replace(" ", "T")); + } catch (Exception ex) { + LOGGER.warning("Alternative date parsing also failed: " + ex.getMessage()); + return null; + } + } + } + return null; + } + + @NotNull + private List getStringListOrEmpty(JsonObject json, String key) { + if (json.has(key) && !json.get(key).isJsonNull() && json.get(key).isJsonArray()) { + Type listType = new TypeToken>() { + }.getType(); + return gson.fromJson(json.get(key), listType); + } + return new ArrayList<>(); + } + + private String formatDateTime(OffsetDateTime dateTime) { + return dateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); + } + + @Override + public List getAllWhere(String filter) { + try { + List records = pocketBase.getFullList(COLLECTION_NAME, 500, filter, null, null, null); + return records.stream() + .map(this::mapToUser) + .collect(Collectors.toList()); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error retrieving users with filter: " + filter, e); + return Collections.emptyList(); + } + } +} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/UserInventoryRepository.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/UserInventoryRepository.java new file mode 100644 index 0000000..3617545 --- /dev/null +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/UserInventoryRepository.java @@ -0,0 +1,90 @@ +package io.github.stonley890.dreamvisitor.data.repository; + + +import java.util.List; +import java.util.Optional; + +import io.github.stonley890.dreamvisitor.data.type.UserInventory; + +/** + * Repository interface for UserInventory data operations + */ +public interface UserInventoryRepository { + /** + * Find an inventory entry by its PocketBase ID + * + * @param id PocketBase record ID + * @return Optional containing the inventory entry if found + */ + Optional findById(String id); + + /** + * Find all inventory entries for a user + * + * @param userId PocketBase user ID + * @return List of inventory entries for the user + */ + List findByUser(String userId); + + /** + * Find inventory entry for a specific user and item + * + * @param userId PocketBase user ID + * @param itemId PocketBase item ID + * @return Optional containing the inventory entry if found + */ + Optional findByUserAndItem(String userId, String itemId); + + /** + * Get all inventory entries + * + * @return List of all inventory entries + */ + List findAll(); + + /** + * Save an inventory entry (create or update) + * + * @param userInventory UserInventory to save + * @return Saved inventory entry + */ + UserInventory save(UserInventory userInventory); + + /** + * Delete an inventory entry + * + * @param userInventory UserInventory to delete + */ + void delete(UserInventory userInventory); + + /** + * Delete an inventory entry by ID + * + * @param id PocketBase ID of inventory entry to delete + */ + void deleteById(String id); + + /** + * Get all inventory entries matching a filter + * + * @param filter PocketBase filter expression + * @return List of inventory entries matching the filter + */ + List getAllWhere(String filter); + + /** + * Load related item data for all inventory entries + * + * @param inventoryEntries List of inventory entries + * @return List of inventory entries with loaded item data + */ + List loadRelatedItems(List inventoryEntries); + + /** + * Load related user data for all inventory entries + * + * @param inventoryEntries List of inventory entries + * @return List of inventory entries with loaded user data + */ + List loadRelatedUsers(List inventoryEntries); +} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/UserRepository.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/UserRepository.java new file mode 100644 index 0000000..017d717 --- /dev/null +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/UserRepository.java @@ -0,0 +1,91 @@ +package io.github.stonley890.dreamvisitor.data.repository; + + + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import io.github.stonley890.dreamvisitor.data.type.DVUser; + +/** + * Repository interface for User data operations + */ +public interface UserRepository { + /** + * Find a user by their PocketBase ID + * + * @param id PocketBase record ID + * @return Optional containing the user if found + */ + Optional findById(String id); + + /** + * Find a user by their Minecraft UUID + * + * @param uuid Minecraft UUID + * @return Optional containing the user if found + */ + Optional findByUuid(UUID uuid); + + /** + * Find a user by their Discord ID + * + * @param discordId Discord ID + * @return Optional containing the user if found + */ + Optional findByDiscordId(String discordId); + + /** + * Find a user by their Discord Snowflake ID + * + * @param snowflakeId Discord Snowflake ID + * @return Optional containing the user if found + */ + Optional findBySnowflakeId(Long snowflakeId); + + /** + * Find a user by their Minecraft username + * + * @param mcUsername Minecraft username + * @return Optional containing the user if found + */ + Optional findByMcUsername(String mcUsername); + + /** + * Get all users + * + * @return List of all users + */ + List findAll(); + + /** + * Save a user (create or update) + * + * @param user User to save + * @return Saved user + */ + DVUser save(DVUser user); + + /** + * Delete a user + * + * @param user User to delete + */ + void delete(DVUser user); + + /** + * Delete a user by ID + * + * @param id PocketBase ID of user to delete + */ + void deleteById(String id); + + /** + * Get all users that match a given condition + * + * @param predicate Condition to filter users + * @return List of users matching the condition + */ + List getAllWhere(String filter); +} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/Alt.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/Alt.java new file mode 100644 index 0000000..3340d46 --- /dev/null +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/Alt.java @@ -0,0 +1,117 @@ +package io.github.stonley890.dreamvisitor.data.type; + +import java.time.OffsetDateTime; + +/** + * Represents an alternate Discord account linked to a main account + */ +public class Alt { + private String id; + private String collectionId; + private String collectionName; + + private String parent; // Parent (main) user record ID + private String discord_name; + private String discord_id; // Discord snowflake ID as string + private Long snowflakeId; // Cached numeric version of discord_id + + private OffsetDateTime created; + private OffsetDateTime updated; + + // Cached related objects (not stored in PocketBase directly) + private transient DVUser cachedParent; + + // Getters and setters + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getCollectionId() { + return collectionId; + } + + public void setCollectionId(String collectionId) { + this.collectionId = collectionId; + } + + public String getCollectionName() { + return collectionName; + } + + public void setCollectionName(String collectionName) { + this.collectionName = collectionName; + } + + public String getParent() { + return parent; + } + + public void setParent(String parent) { + this.parent = parent; + } + + public String getDiscord_name() { + return discord_name; + } + + public void setDiscord_name(String discord_name) { + this.discord_name = discord_name; + } + + public String getDiscord_id() { + return discord_id; + } + + public void setDiscord_id(String discord_id) { + this.discord_id = discord_id; + // Update snowflakeId when discord_id is set + if (discord_id != null) { + try { + this.snowflakeId = Long.parseLong(discord_id); + } catch (NumberFormatException e) { + this.snowflakeId = null; + } + } else { + this.snowflakeId = null; + } + } + + public Long getSnowflakeId() { + return snowflakeId; + } + + public void setSnowflakeId(Long snowflakeId) { + this.snowflakeId = snowflakeId; + if (snowflakeId != null) { + this.discord_id = snowflakeId.toString(); + } + } + + public OffsetDateTime getCreated() { + return created; + } + + public void setCreated(OffsetDateTime created) { + this.created = created; + } + + public OffsetDateTime getUpdated() { + return updated; + } + + public void setUpdated(OffsetDateTime updated) { + this.updated = updated; + } + + public DVUser getCachedParent() { + return cachedParent; + } + + public void setCachedParent(DVUser cachedParent) { + this.cachedParent = cachedParent; + } +} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/DVUser.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/DVUser.java new file mode 100644 index 0000000..0031463 --- /dev/null +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/DVUser.java @@ -0,0 +1,241 @@ +package io.github.stonley890.dreamvisitor.data.type; + +import java.time.OffsetDateTime; +import java.util.List; +import java.util.UUID; + +public class DVUser { + private String id; + private String collectionId; + private String collectionName; + + private UUID mc_uuid; + private String mcUsername; + private String discord_username; + private String discord_id; + private String discord_img; + private Long snowflakeId; + + private List infractions; + private List users_home; + private List inventory_items; + private List claims; + private List alts; // Added alts field + + private Integer claim_limit; + private Integer play_time; + private Double balance; + private Integer daily_streak; + + private OffsetDateTime last_work; + private OffsetDateTime last_daily; + private OffsetDateTime last_played; + + private Boolean is_suspended; + private Boolean is_banned; + + private OffsetDateTime created; + private OffsetDateTime updated; + + // Existing getters and setters + public UUID getMc_uuid() { + return mc_uuid; + } + + public Long getSnowflakeId() { + return snowflakeId; + } + + public String getDiscord_username() { + return discord_username; + } + + public String getMcUsername() { + return mcUsername; + } + + public void setDiscord_username(String dcUsername) { + this.discord_username = dcUsername; + } + + public void setMcUsername(String mcUsername) { + this.mcUsername = mcUsername; + } + + public void setSnowflakeId(Long snowflakeId) { + this.snowflakeId = snowflakeId; + } + + public void setMc_uuid(UUID uuid) { + this.mc_uuid = uuid; + } + + // New getters and setters + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getCollectionId() { + return collectionId; + } + + public void setCollectionId(String collectionId) { + this.collectionId = collectionId; + } + + public String getCollectionName() { + return collectionName; + } + + public void setCollectionName(String collectionName) { + this.collectionName = collectionName; + } + + public String getDiscord_id() { + return discord_id; + } + + public void setDiscord_id(String discord_id) { + this.discord_id = discord_id; + } + + public String getDiscord_img() { + return discord_img; + } + + public void setDiscord_img(String discord_img) { + this.discord_img = discord_img; + } + + public List getInfractions() { + return infractions; + } + + public void setInfractions(List infractions) { + this.infractions = infractions; + } + + public List getUsers_home() { + return users_home; + } + + public void setUsers_home(List users_home) { + this.users_home = users_home; + } + + public List getInventory_items() { + return inventory_items; + } + + public void setInventory_items(List inventory_items) { + this.inventory_items = inventory_items; + } + + public List getClaims() { + return claims; + } + + public void setClaims(List claims) { + this.claims = claims; + } + + public List getAlts() { + return alts; + } + + public void setAlts(List alts) { + this.alts = alts; + } + + public Integer getClaim_limit() { + return claim_limit; + } + + public void setClaim_limit(Integer claim_limit) { + this.claim_limit = claim_limit; + } + + public Integer getPlay_time() { + return play_time; + } + + public void setPlay_time(Integer play_time) { + this.play_time = play_time; + } + + public Double getBalance() { + return balance; + } + + public void setBalance(Double balance) { + this.balance = balance; + } + + public Integer getDaily_streak() { + return daily_streak; + } + + public void setDaily_streak(Integer daily_streak) { + this.daily_streak = daily_streak; + } + + public OffsetDateTime getLast_work() { + return last_work; + } + + public void setLast_work(OffsetDateTime last_work) { + this.last_work = last_work; + } + + public OffsetDateTime getLast_played() { + return last_played; + } + + public OffsetDateTime getLast_daily() { + return last_daily; + } + + public void setLast_daily(OffsetDateTime last_daily) { + this.last_daily = last_daily; + } + + public Boolean getIs_suspended() { + return is_suspended; + } + + public void setIs_suspended(Boolean is_suspended) { + this.is_suspended = is_suspended; + } + + public Boolean getIs_banned() { + return is_banned; + } + + public void setIs_banned(Boolean is_banned) { + this.is_banned = is_banned; + } + + public OffsetDateTime getCreated() { + return created; + } + + public void setCreated(OffsetDateTime created) { + this.created = created; + } + + public OffsetDateTime getUpdated() { + return updated; + } + + public void setUpdated(OffsetDateTime updated) { + this.updated = updated; + } + + public void setLast_Played(OffsetDateTime last_played) { + this.last_played = last_played; + } +} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/Infraction.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/Infraction.java new file mode 100644 index 0000000..36b41b1 --- /dev/null +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/Infraction.java @@ -0,0 +1,110 @@ +package io.github.stonley890.dreamvisitor.data.type; + +import java.time.OffsetDateTime; + +public class Infraction { + private String id; + private String collectionId; + private String collectionName; + + private String reason; + private Boolean send_warning; + private Boolean expired; + private Integer value; + private String user; // Relation record ID + + private OffsetDateTime created; + private OffsetDateTime updated; + + // Cached related object (not stored in PocketBase directly) + private transient DVUser cachedUser; + + // Getters and setters + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getCollectionId() { + return collectionId; + } + + public void setCollectionId(String collectionId) { + this.collectionId = collectionId; + } + + public String getCollectionName() { + return collectionName; + } + + public void setCollectionName(String collectionName) { + this.collectionName = collectionName; + } + + public String getReason() { + return reason; + } + + public void setReason(String reason) { + this.reason = reason; + } + + public Boolean getSend_warning() { + return send_warning; + } + + public void setSend_warning(Boolean send_warning) { + this.send_warning = send_warning; + } + + public Boolean getExpired() { + return expired; + } + + public void setExpired(Boolean expired) { + this.expired = expired; + } + + public Integer getValue() { + return value; + } + + public void setValue(Integer value) { + this.value = value; + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public OffsetDateTime getCreated() { + return created; + } + + public void setCreated(OffsetDateTime created) { + this.created = created; + } + + public OffsetDateTime getUpdated() { + return updated; + } + + public void setUpdated(OffsetDateTime updated) { + this.updated = updated; + } + + public DVUser getCachedUser() { + return cachedUser; + } + + public void setCachedUser(DVUser cachedUser) { + this.cachedUser = cachedUser; + } +} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/Item.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/Item.java new file mode 100644 index 0000000..ac53f29 --- /dev/null +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/Item.java @@ -0,0 +1,198 @@ +package io.github.stonley890.dreamvisitor.data.type; + +import java.time.OffsetDateTime; + +public class Item { + private String id; + private String collectionId; + private String collectionName; + + private String name; + private String description; + private Double price; + private Double sale_percent; + private Integer quantity; + private Boolean gifting_enabled; + private Boolean enabled; + private Integer max_allowed; + private Boolean use_disabled; + private Boolean use_on_purchase; + private String on_use_groups_add; // JSON string + private String on_use_groups_remove; // JSON string + + // JSON array of Discord role IDs to add when item is used + // Example format: ["123456789012345678", "234567890123456789"] + // These must be valid Discord role IDs from the server + private String on_use_roles_add; + + // JSON array of Discord role IDs to remove when item is used + // Example format: ["123456789012345678", "234567890123456789"] + // These must be valid Discord role IDs from the server + private String on_use_roles_remove; + + private String on_use_console_commands; // JSON string + + private OffsetDateTime created; + private OffsetDateTime updated; + + // Getters and setters + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getCollectionId() { + return collectionId; + } + + public void setCollectionId(String collectionId) { + this.collectionId = collectionId; + } + + public String getCollectionName() { + return collectionName; + } + + public void setCollectionName(String collectionName) { + this.collectionName = collectionName; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Double getPrice() { + return price; + } + + public void setPrice(Double price) { + this.price = price; + } + + public Double getSale_percent() { + return sale_percent; + } + + public void setSale_percent(Double sale_percent) { + this.sale_percent = sale_percent; + } + + public Integer getQuantity() { + return quantity; + } + + public void setQuantity(Integer quantity) { + this.quantity = quantity; + } + + public Boolean getGifting_enabled() { + return gifting_enabled; + } + + public void setGifting_enabled(Boolean gifting_enabled) { + this.gifting_enabled = gifting_enabled; + } + + public Boolean getEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + public Integer getMax_allowed() { + return max_allowed; + } + + public void setMax_allowed(Integer max_allowed) { + this.max_allowed = max_allowed; + } + + public Boolean getUse_disabled() { + return use_disabled; + } + + public void setUse_disabled(Boolean use_disabled) { + this.use_disabled = use_disabled; + } + + public Boolean getUse_on_purchase() { + return use_on_purchase; + } + + public void setUse_on_purchase(Boolean use_on_purchase) { + this.use_on_purchase = use_on_purchase; + } + + public String getOn_use_groups_add() { + return on_use_groups_add; + } + + public void setOn_use_groups_add(String on_use_groups_add) { + this.on_use_groups_add = on_use_groups_add; + } + + public String getOn_use_groups_remove() { + return on_use_groups_remove; + } + + public void setOn_use_groups_remove(String on_use_groups_remove) { + this.on_use_groups_remove = on_use_groups_remove; + } + + public String getOn_use_roles_add() { + return on_use_roles_add; + } + + public void setOn_use_roles_add(String on_use_roles_add) { + this.on_use_roles_add = on_use_roles_add; + } + + public String getOn_use_roles_remove() { + return on_use_roles_remove; + } + + public void setOn_use_roles_remove(String on_use_roles_remove) { + this.on_use_roles_remove = on_use_roles_remove; + } + + public String getOn_use_console_commands() { + return on_use_console_commands; + } + + public void setOn_use_console_commands(String on_use_console_commands) { + this.on_use_console_commands = on_use_console_commands; + } + + public OffsetDateTime getCreated() { + return created; + } + + public void setCreated(OffsetDateTime created) { + this.created = created; + } + + public OffsetDateTime getUpdated() { + return updated; + } + + public void setUpdated(OffsetDateTime updated) { + this.updated = updated; + } +} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/UserInventory.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/UserInventory.java new file mode 100644 index 0000000..07e4df5 --- /dev/null +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/UserInventory.java @@ -0,0 +1,101 @@ +package io.github.stonley890.dreamvisitor.data.type; + +import java.time.OffsetDateTime; + +public class UserInventory { + private String id; + private String collectionId; + private String collectionName; + + private String user; // Relation record ID + private String item; // Relation record ID + private Integer quantity; + + private OffsetDateTime created; + private OffsetDateTime updated; + + // Cached related objects (not stored in PocketBase directly) + private transient DVUser cachedUser; + private transient Item cachedItem; + + // Getters and setters + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getCollectionId() { + return collectionId; + } + + public void setCollectionId(String collectionId) { + this.collectionId = collectionId; + } + + public String getCollectionName() { + return collectionName; + } + + public void setCollectionName(String collectionName) { + this.collectionName = collectionName; + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public String getItem() { + return item; + } + + public void setItem(String item) { + this.item = item; + } + + public Integer getQuantity() { + return quantity; + } + + public void setQuantity(Integer quantity) { + this.quantity = quantity; + } + + public OffsetDateTime getCreated() { + return created; + } + + public void setCreated(OffsetDateTime created) { + this.created = created; + } + + public OffsetDateTime getUpdated() { + return updated; + } + + public void setUpdated(OffsetDateTime updated) { + this.updated = updated; + } + + public DVUser getCachedUser() { + return cachedUser; + } + + public void setCachedUser(DVUser cachedUser) { + this.cachedUser = cachedUser; + } + + public Item getCachedItem() { + return cachedItem; + } + + public void setCachedItem(Item cachedItem) { + this.cachedItem = cachedItem; + } +} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/DiscEventListener.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/DiscEventListener.java index 4ad8b22..56475a9 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/DiscEventListener.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/DiscEventListener.java @@ -3,6 +3,7 @@ import io.github.stonley890.dreamvisitor.Bot; import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.data.*; +import io.github.stonley890.dreamvisitor.data.Infraction; import io.github.stonley890.dreamvisitor.functions.Whitelist; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.Permission; @@ -738,4 +739,4 @@ public void onStringSelectInteraction(@NotNull StringSelectInteractionEvent even } } -} \ No newline at end of file +} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/PocketBase.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/PocketBase.java new file mode 100644 index 0000000..987bdb0 --- /dev/null +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/PocketBase.java @@ -0,0 +1,426 @@ +package io.github.stonley890.dreamvisitor.pb; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.reflect.TypeToken; +import okhttp3.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; + +public class PocketBase { + private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); + private final OkHttpClient client; + private final Gson gson; + private final String baseUrl; + private String token; + + /** + * Creates a new PocketBase SDK instance. + * + * @param baseUrl The base URL of the PocketBase instance + * @param token The admin/user auth token + */ + public PocketBase(String baseUrl, String token) { + this.baseUrl = baseUrl.endsWith("/") ? baseUrl : baseUrl + "/"; + this.token = token; + this.gson = new Gson(); + this.client = new OkHttpClient.Builder() + .connectTimeout(30, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .writeTimeout(30, TimeUnit.SECONDS) + .build(); + } + + /** + * Creates an instance with the default configuration from config.yml + * + * @return A preconfigured PocketBase instance + */ + public static PocketBase fromConfig(Map config) { + String baseUrl = (String) config.get("pocketbase-url"); + String token = (String) config.get("pocketbase-token"); + return new PocketBase(baseUrl, token); + } + + /** + * Helper method to build a URL with query parameters + * + * @param endpoint The API endpoint + * @param queryParams Query parameters + * @return The complete URL + */ + private HttpUrl buildUrl(String endpoint, @Nullable Map queryParams) { + HttpUrl.Builder urlBuilder = HttpUrl.parse(this.baseUrl + endpoint).newBuilder(); + + if (queryParams != null) { + for (Map.Entry entry : queryParams.entrySet()) { + urlBuilder.addQueryParameter(entry.getKey(), entry.getValue()); + } + } + + return urlBuilder.build(); + } + + /** + * Helper method to execute HTTP requests + * + * @param method HTTP method + * @param endpoint API endpoint + * @param body Request body + * @param queryParams Query parameters + * @return Response string + * @throws IOException If the request fails + */ + private String executeRequest(String method, String endpoint, @Nullable RequestBody body, + @Nullable Map queryParams) throws IOException { + HttpUrl url = buildUrl(endpoint, queryParams); + + Request.Builder requestBuilder = new Request.Builder() + .url(url) + .header("Authorization", "Bearer " + this.token); + + switch (method) { + case "GET": + requestBuilder.get(); + break; + case "POST": + requestBuilder.post(body != null ? body : RequestBody.create(new byte[0], null)); + break; + case "PATCH": + requestBuilder.patch(body != null ? body : RequestBody.create(new byte[0], null)); + break; + case "DELETE": + requestBuilder.delete(body != null ? body : null); + break; + default: + throw new IllegalArgumentException("Unsupported HTTP method: " + method); + } + + Request request = requestBuilder.build(); + try (Response response = client.newCall(request).execute()) { + if (!response.isSuccessful()) { + String errorBody = response.body() != null ? response.body().string() : "No response body"; + throw new IOException("Request failed with code " + response.code() + ": " + errorBody); + } + + return response.body() != null ? response.body().string() : ""; + } + } + + /** + * Impersonates a user and returns a new PocketBase instance with the + * impersonation token + * + * @param collectionIdOrName Collection ID or name + * @param recordId Record ID to impersonate + * @param duration Optional JWT duration in seconds + * @param expand Optional relations to expand + * @param fields Optional fields to return + * @return A new PocketBase instance with impersonation token + * @throws IOException If the request fails + */ + public PocketBase impersonate(String collectionIdOrName, String recordId, + @Nullable Integer duration, + @Nullable String expand, @Nullable String fields) throws IOException { + String endpoint = "api/collections/" + collectionIdOrName + "/impersonate/" + recordId; + + Map queryParams = new HashMap<>(); + if (expand != null) + queryParams.put("expand", expand); + if (fields != null) + queryParams.put("fields", fields); + + JsonObject jsonBody = new JsonObject(); + if (duration != null) + jsonBody.addProperty("duration", duration); + + RequestBody body = RequestBody.create(jsonBody.toString(), JSON); + String response = executeRequest("POST", endpoint, body, queryParams); + + ImpersonateResponse impersonateResponse = gson.fromJson(response, ImpersonateResponse.class); + return new PocketBase(this.baseUrl, impersonateResponse.token); + } + + /** + * Lists/searches records from a collection + * + * @param collectionIdOrName Collection ID or name + * @param page Page number (default: 1) + * @param perPage Records per page (default: 30) + * @param sort Optional sorting + * @param filter Optional filter expression + * @param expand Optional relations to expand + * @param fields Optional fields to return + * @param skipTotal Whether to skip total counts + * @return List response with records + * @throws IOException If the request fails + */ + public ListResult listRecords(String collectionIdOrName, + @Nullable Integer page, @Nullable Integer perPage, + @Nullable String sort, @Nullable String filter, + @Nullable String expand, @Nullable String fields, + @Nullable Boolean skipTotal) throws IOException { + String endpoint = "api/collections/" + collectionIdOrName + "/records"; + + Map queryParams = new HashMap<>(); + if (page != null) + queryParams.put("page", page.toString()); + if (perPage != null) + queryParams.put("perPage", perPage.toString()); + if (sort != null) + queryParams.put("sort", sort); + if (filter != null) + queryParams.put("filter", filter); + if (expand != null) + queryParams.put("expand", expand); + if (fields != null) + queryParams.put("fields", fields); + if (skipTotal != null && skipTotal) + queryParams.put("skipTotal", "true"); + + String response = executeRequest("GET", endpoint, null, queryParams); + return gson.fromJson(response, ListResult.class); + } + + /** + * Gets the full list of records from a collection (auto-paginated) + * + * @param collectionIdOrName Collection ID or name + * @param batch Batch size (default: 500) + * @param sort Optional sorting + * @param filter Optional filter expression + * @param expand Optional relations to expand + * @param fields Optional fields to return + * @return List of records + * @throws IOException If the request fails + */ + public List getFullList(String collectionIdOrName, + @Nullable Integer batch, + @Nullable String sort, + @Nullable String filter, + @Nullable String expand, + @Nullable String fields) throws IOException { + int batchSize = batch != null ? batch : 500; + List allItems = new ArrayList<>(); + int page = 1; + + while (true) { + ListResult result = listRecords( + collectionIdOrName, + page, + batchSize, + sort, + filter, + expand, + fields, + true // skipTotal for optimization + ); + + allItems.addAll(result.items); + + if (result.items.size() < batchSize) { + break; + } + + page++; + } + + return allItems; + } + + /** + * Gets the first record matching the filter + * + * @param collectionIdOrName Collection ID or name + * @param filter Filter expression + * @param sort Optional sorting + * @param expand Optional relations to expand + * @param fields Optional fields to return + * @return First matching record + * @throws IOException If the request fails or no record found + */ + public JsonObject getFirstListItem(String collectionIdOrName, + @NotNull String filter, + @Nullable String sort, + @Nullable String expand, + @Nullable String fields) throws IOException { + ListResult result = listRecords( + collectionIdOrName, + 1, + 1, + sort, + filter, + expand, + fields, + true // skipTotal for optimization + ); + + if (result.items.isEmpty()) { + throw new IOException("No records found."); + } + + return result.items.get(0); + } + + /** + * Gets a single record by ID + * + * @param collectionIdOrName Collection ID or name + * @param recordId Record ID + * @param expand Optional relations to expand + * @param fields Optional fields to return + * @return Record data + * @throws IOException If the request fails + */ + public JsonObject getRecord(String collectionIdOrName, String recordId, + @Nullable String expand, @Nullable String fields) throws IOException { + String endpoint = "api/collections/" + collectionIdOrName + "/records/" + recordId; + + Map queryParams = new HashMap<>(); + if (expand != null) + queryParams.put("expand", expand); + if (fields != null) + queryParams.put("fields", fields); + + String response = executeRequest("GET", endpoint, null, queryParams); + return gson.fromJson(response, JsonObject.class); + } + + /** + * Creates a new record + * + * @param collectionIdOrName Collection ID or name + * @param bodyData Record data + * @param expand Optional relations to expand + * @param fields Optional fields to return + * @return Created record + * @throws IOException If the request fails + */ + public JsonObject createRecord(String collectionIdOrName, Object bodyData, + @Nullable String expand, @Nullable String fields) throws IOException { + String endpoint = "api/collections/" + collectionIdOrName + "/records"; + + Map queryParams = new HashMap<>(); + if (expand != null) + queryParams.put("expand", expand); + if (fields != null) + queryParams.put("fields", fields); + + RequestBody body = RequestBody.create(gson.toJson(bodyData), JSON); + String response = executeRequest("POST", endpoint, body, queryParams); + return gson.fromJson(response, JsonObject.class); + } + + /** + * Updates an existing record + * + * @param collectionIdOrName Collection ID or name + * @param recordId Record ID + * @param bodyData Updated data + * @param expand Optional relations to expand + * @param fields Optional fields to return + * @return Updated record + * @throws IOException If the request fails + */ + public JsonObject updateRecord(String collectionIdOrName, String recordId, Object bodyData, + @Nullable String expand, @Nullable String fields) throws IOException { + String endpoint = "api/collections/" + collectionIdOrName + "/records/" + recordId; + + Map queryParams = new HashMap<>(); + if (expand != null) + queryParams.put("expand", expand); + if (fields != null) + queryParams.put("fields", fields); + + RequestBody body = RequestBody.create(gson.toJson(bodyData), JSON); + String response = executeRequest("PATCH", endpoint, body, queryParams); + return gson.fromJson(response, JsonObject.class); + } + + /** + * Deletes a record + * + * @param collectionIdOrName Collection ID or name + * @param recordId Record ID + * @throws IOException If the request fails + */ + public void deleteRecord(String collectionIdOrName, String recordId) throws IOException { + String endpoint = "api/collections/" + collectionIdOrName + "/records/" + recordId; + executeRequest("DELETE", endpoint, null, null); + } + + /** + * Creates a multipart request body for file uploads + * + * @param fields Map of field names to values + * @param files Map of field names to files + * @return Multipart request body + */ + public RequestBody createMultipartBody(Map fields, Map files) { + MultipartBody.Builder builder = new MultipartBody.Builder() + .setType(MultipartBody.FORM); + + // Add regular fields + for (Map.Entry entry : fields.entrySet()) { + builder.addFormDataPart(entry.getKey(), String.valueOf(entry.getValue())); + } + + // Add files + for (Map.Entry entry : files.entrySet()) { + String fieldName = entry.getKey(); + File file = entry.getValue(); + String fileName = file.getName(); + RequestBody fileBody = RequestBody.create(file, MediaType.parse("application/octet-stream")); + builder.addFormDataPart(fieldName, fileName, fileBody); + } + + return builder.build(); + } + + /** + * Get the current auth token + * + * @return Current auth token + */ + public String getToken() { + return token; + } + + /** + * Update the auth token + * + * @param token New auth token + */ + public void setToken(String token) { + this.token = token; + } + + /** + * Response class for impersonation + */ + private static class ImpersonateResponse { + String token; + JsonObject record; + } + + /** + * Response class for list operations + */ + public static class ListResult { + public int page; + public int perPage; + public int totalItems; + public int totalPages; + public List items; + } +} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/PocketBaseUtils.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/PocketBaseUtils.java new file mode 100644 index 0000000..6889dd6 --- /dev/null +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/PocketBaseUtils.java @@ -0,0 +1,133 @@ +package io.github.stonley890.dreamvisitor.pb; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.Type; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Utility class for PocketBase operations + */ +public class PocketBaseUtils { + private static final Gson gson = new Gson(); + + /** + * Converts a JsonObject to a specific class instance + * + * @param json The JsonObject to convert + * @param clazz The target class + * @param Target type + * @return An instance of the target class + */ + public static T jsonToClass(@NotNull JsonObject json, @NotNull Class clazz) { + return gson.fromJson(json, clazz); + } + + /** + * Converts a JsonObject to an instance of the specified type + * + * @param json The JsonObject to convert + * @param type The target type + * @param Target type + * @return An instance of the target type + */ + public static T jsonToType(@NotNull JsonObject json, @NotNull Type type) { + return gson.fromJson(json, type); + } + + /** + * Converts a list of JsonObjects to a list of class instances + * + * @param jsonList The list of JsonObjects + * @param clazz The target class + * @param Target type + * @return A list of instances of the target class + */ + public static List jsonListToClass(@NotNull List jsonList, @NotNull Class clazz) { + return jsonList.stream() + .map(json -> jsonToClass(json, clazz)) + .collect(Collectors.toList()); + } + + /** + * Gets a string value from JsonObject safely + * + * @param json JsonObject to get value from + * @param key Key to lookup + * @return String value or null if not found or not a string + */ + public static String getString(JsonObject json, String key) { + if (json == null || !json.has(key)) + return null; + JsonElement element = json.get(key); + return element.isJsonPrimitive() && element.getAsJsonPrimitive().isString() + ? element.getAsString() + : null; + } + + /** + * Gets an integer value from JsonObject safely + * + * @param json JsonObject to get value from + * @param key Key to lookup + * @return Integer value or null if not found or not a number + */ + public static Integer getInteger(JsonObject json, String key) { + if (json == null || !json.has(key)) + return null; + JsonElement element = json.get(key); + return element.isJsonPrimitive() && element.getAsJsonPrimitive().isNumber() + ? element.getAsInt() + : null; + } + + /** + * Gets a double value from JsonObject safely + * + * @param json JsonObject to get value from + * @param key Key to lookup + * @return Double value or null if not found or not a number + */ + public static Double getDouble(JsonObject json, String key) { + if (json == null || !json.has(key)) + return null; + JsonElement element = json.get(key); + return element.isJsonPrimitive() && element.getAsJsonPrimitive().isNumber() + ? element.getAsDouble() + : null; + } + + /** + * Gets a boolean value from JsonObject safely + * + * @param json JsonObject to get value from + * @param key Key to lookup + * @return Boolean value or null if not found or not a boolean + */ + public static Boolean getBoolean(JsonObject json, String key) { + if (json == null || !json.has(key)) + return null; + JsonElement element = json.get(key); + return element.isJsonPrimitive() && element.getAsJsonPrimitive().isBoolean() + ? element.getAsBoolean() + : null; + } + + /** + * Gets a nested JsonObject safely + * + * @param json JsonObject to get value from + * @param key Key to lookup + * @return JsonObject or null if not found or not an object + */ + public static JsonObject getJsonObject(JsonObject json, String key) { + if (json == null || !json.has(key)) + return null; + JsonElement element = json.get(key); + return element.isJsonObject() ? element.getAsJsonObject() : null; + } +} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/README.md b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/README.md new file mode 100644 index 0000000..9a67895 --- /dev/null +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/README.md @@ -0,0 +1,145 @@ +# PocketBase Java SDK + +This is a Java SDK for PocketBase, implemented using OkHttp and Gson. + +## Features + +- Authentication with API keys +- User impersonation +- CRUD operations for records +- File uploads with multipart requests +- Helper methods for common tasks + +## Usage Examples + +### Initialize the SDK + +```java +// From configuration +PocketBase pb = PocketBase.fromConfig(); + +// Manual initialization +PocketBase pb = new PocketBase("https://pocketbase.example.com", "YOUR_API_TOKEN"); +``` + +### List Records + +```java +try { + // Basic list + PocketBase.ListResult result = pb.listRecords("posts", 1, 20, null, null, null, null, false); + List posts = result.items; + + // With filtering and sorting + PocketBase.ListResult filteredResult = pb.listRecords( + "posts", + 1, // page + 20, // perPage + "-created,title", // sort by created desc, then title asc + "status='published'", // filter + "author", // expand author relation + "id,title,author.name", // fields to return + false // skipTotal + ); + + // Get full list (auto-paginated) + List allPosts = pb.getFullList("posts", 200, null, null, null, null); + + // Get first matching item + JsonObject post = pb.getFirstListItem("posts", "title~'Java'", "-created", null, null); + +} catch (IOException e) { + e.printStackTrace(); +} +``` + +### Get a Record + +```java +try { + JsonObject post = pb.getRecord("posts", "RECORD_ID", "author,comments", null); + String title = PocketBaseUtils.getString(post, "title"); + System.out.println("Post title: " + title); + + // Convert to your own class + MyPostClass myPost = PocketBaseUtils.jsonToClass(post, MyPostClass.class); +} catch (IOException e) { + e.printStackTrace(); +} +``` + +### Create a Record + +```java +try { + Map postData = new HashMap<>(); + postData.put("title", "New Post"); + postData.put("content", "This is a new post created with the Java SDK."); + postData.put("status", "draft"); + + JsonObject newPost = pb.createRecord("posts", postData, null, null); + String postId = PocketBaseUtils.getString(newPost, "id"); + System.out.println("Created post with ID: " + postId); +} catch (IOException e) { + e.printStackTrace(); +} +``` + +### Update a Record + +```java +try { + Map updateData = new HashMap<>(); + updateData.put("title", "Updated Post Title"); + updateData.put("status", "published"); + + JsonObject updatedPost = pb.updateRecord("posts", "RECORD_ID", updateData, null, null); +} catch (IOException e) { + e.printStackTrace(); +} +``` + +### Delete a Record + +```java +try { + pb.deleteRecord("posts", "RECORD_ID"); + System.out.println("Post deleted successfully"); +} catch (IOException e) { + e.printStackTrace(); +} +``` + +### File Upload + +```java +try { + Map formData = new HashMap<>(); + formData.put("title", "Post with Image"); + + Map files = new HashMap<>(); + files.put("image", new File("/path/to/image.jpg")); + + RequestBody body = pb.createMultipartBody(formData, files); + JsonObject newPost = pb.createRecord("posts", body, null, null); +} catch (IOException e) { + e.printStackTrace(); +} +``` + +### Impersonation + +```java +try { + // Impersonate a user with custom token duration (3600 seconds = 1 hour) + PocketBase impersonated = pb.impersonate("users", "USER_ID", 3600, null, null); + + // Use the impersonated client to perform actions as that user + JsonObject myData = impersonated.getRecord("my_collection", "RECORD_ID", null, null); + + // The original client is unaffected + JsonObject adminData = pb.getRecord("admin_collection", "ADMIN_RECORD", null, null); +} catch (IOException e) { + e.printStackTrace(); +} +``` diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/ConfigLoader.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/ConfigLoader.java new file mode 100644 index 0000000..938f175 --- /dev/null +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/ConfigLoader.java @@ -0,0 +1,76 @@ +package io.github.stonley890.dreamvisitor.util; +import org.yaml.snakeyaml.Yaml; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Logger; + +/** + * Utility class for loading YAML configuration files + */ +public class ConfigLoader { + private static final Logger logger = Logger.getLogger("DreamvisitorHub"); + + private ConfigLoader() { + throw new IllegalStateException("Utility class"); + } + + /** + * Loads a YAML configuration file and returns it as a Map + * + * @param filePath path to the YAML file + * @return Map containing the configuration, or empty map if loading fails + */ + public static Map loadConfig(String filePath) { + try { + File configFile = new File(filePath); + if (!configFile.exists()) { + logger.warning("Config file not found at: " + filePath); + return new HashMap<>(); + } + + Yaml yaml = new Yaml(); + InputStream inputStream = new FileInputStream(configFile); + Map config = yaml.load(inputStream); + logger.info("Successfully loaded config from: " + filePath); + return config != null ? config : new HashMap<>(); + } catch (FileNotFoundException e) { + logger.severe("Failed to load config file: " + e.getMessage()); + return new HashMap<>(); + } catch (Exception e) { + logger.severe("Error parsing config file: " + e.getMessage()); + return new HashMap<>(); + } + } + + /** + * Saves a configuration map to a YAML file + * + * @param filePath path to the YAML file + * @param config the configuration map to save + * @return true if saving succeeded, false otherwise + */ + public static boolean saveConfig(String filePath, Map config) { + try { + File configFile = new File(filePath); + Yaml yaml = new Yaml(); + FileWriter writer = new FileWriter(configFile); + yaml.dump(config, writer); + writer.close(); + logger.info("Successfully saved config to: " + filePath); + return true; + } catch (IOException e) { + logger.severe("Failed to save config file: " + e.getMessage()); + return false; + } catch (Exception e) { + logger.severe("Error writing config file: " + e.getMessage()); + return false; + } + } +} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/PBConfigLoader.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/PBConfigLoader.java new file mode 100644 index 0000000..9c8fcf0 --- /dev/null +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/PBConfigLoader.java @@ -0,0 +1,118 @@ +package io.github.stonley890.dreamvisitor.util; +import com.google.gson.JsonObject; +import com.google.gson.JsonElement; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Logger; + +import io.github.stonley890.dreamvisitor.pb.PocketBase; +/** + * Utility class for loading configuration from PocketBase + */ +public class PBConfigLoader { + private static final Logger logger = Logger.getLogger("DreamvisitorHub"); + private static final String CONFIG_COLLECTION = "dreamvisitor_config"; + private static final String CONFIG_RECORD_ID = "45q1at367581q3a"; // Default record ID + + private PBConfigLoader() { + throw new IllegalStateException("Utility class"); + } + + /** + * Loads configuration from PocketBase and returns it as a Map + * + * @param pocketBase The PocketBase instance to use + * @return Map containing the configuration, or empty map if loading fails + */ + public static Map loadConfig(PocketBase pocketBase) { + Map config = new HashMap<>(); + try { + // Fetch the configuration record from PocketBase + JsonObject configData = pocketBase.getRecord(CONFIG_COLLECTION, CONFIG_RECORD_ID, null, null); + + // Convert JsonObject to Map + for (String key : configData.keySet()) { + JsonElement element = configData.get(key); + + // Skip null values - we'll use file config for these + if (element.isJsonNull()) { + logger.fine("Skipping null value for key: " + key); + continue; + } + + if (element.isJsonPrimitive()) { + if (element.getAsJsonPrimitive().isNumber()) { + config.put(key, element.getAsNumber()); + } else if (element.getAsJsonPrimitive().isBoolean()) { + config.put(key, element.getAsBoolean()); + } else { + config.put(key, element.getAsString()); + } + } + } + + // Rename fields to match the expected format in the existing code + mapFieldNames(config); + + logger.info("Successfully loaded config from PocketBase"); + return config; + } catch (IOException e) { + logger.severe("Failed to load config from PocketBase: " + e.getMessage()); + return new HashMap<>(); + } catch (Exception e) { + logger.severe("Error parsing config from PocketBase: " + e.getMessage()); + return new HashMap<>(); + } + } + + /** + * Maps field names from PocketBase format to the format expected in the code + * + * @param config The configuration map to update + */ + private static void mapFieldNames(Map config) { + // Map PocketBase field names to the names expected in the application + renameField(config, "whitelist_channel", "whitelistChannelID"); + renameField(config, "game_chat_channel", "chatChannelID"); + renameField(config, "game_log_channel", "logChannelID"); + renameField(config, "resource_pack_repo", "resourcePackRepo"); + renameField(config, "shop_name", "shopName"); + // Ensure consistent handling of channel IDs + ensureChannelIdFormat(config, "whitelistChannelID"); + ensureChannelIdFormat(config, "chatChannelID"); + ensureChannelIdFormat(config, "logChannelID"); + + // Add other field mappings as needed + } + + /** + * Ensures that channel ID fields are consistently stored as Strings + * + * @param config The configuration map + * @param fieldName The field name to check + */ + private static void ensureChannelIdFormat(Map config, String fieldName) { + if (config.containsKey(fieldName)) { + Object value = config.get(fieldName); + if (value instanceof Number) { + // Convert Number to String to ensure consistent handling + config.put(fieldName, String.valueOf(((Number) value).longValue())); + } + } + } + + /** + * Renames a field in the configuration map + * + * @param config The configuration map + * @param oldName The old field name + * @param newName The new field name + */ + private static void renameField(Map config, String oldName, String newName) { + if (config.containsKey(oldName)) { + config.put(newName, config.get(oldName)); + config.remove(oldName); + } + } +} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/UUIDFromater.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/UUIDFromater.java new file mode 100644 index 0000000..a054692 --- /dev/null +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/UUIDFromater.java @@ -0,0 +1,15 @@ +package io.github.stonley890.dreamvisitor.util; +public class UUIDFromater { + /** + * Adds the hyphens back into a String UUID. + * + * @param uuid the UUID as a {@link String} without hyphens. + * @return a UUID as a string with hyphens. + */ + public static String formatUuid(String uuid) { + + return uuid.replaceFirst( + "(\\p{XDigit}{8})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}+)", + "$1-$2-$3-$4-$5"); + } +} From 485a56290490293824000fd8373335c44df1677c Mon Sep 17 00:00:00 2001 From: Mustfa-IT Date: Tue, 27 May 2025 17:32:46 +0300 Subject: [PATCH 03/39] Implement PocketBase configuration loader and integrate auto-restart settings --- .../stonley890/dreamvisitor/Dreamvisitor.java | 98 +++------ .../dreamvisitor/data/PBConfigLoader.java | 158 +++++++++++++ .../data/RealtimeConfigUpdater.java | 207 ++++++++++++++++++ .../discord/commands/DCmdAutorestart.java | 70 +++--- .../dreamvisitor/functions/AutoRestart.java | 64 +++--- 5 files changed, 463 insertions(+), 134 deletions(-) create mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PBConfigLoader.java create mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/RealtimeConfigUpdater.java diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Dreamvisitor.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Dreamvisitor.java index 55a5b9d..7d6e02c 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Dreamvisitor.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Dreamvisitor.java @@ -37,19 +37,13 @@ import java.util.*; import java.util.logging.Level; -/* - * The main ticking thread. -*/ - @SuppressWarnings({ "null" }) public class Dreamvisitor extends JavaPlugin { public static final String PREFIX = ChatColor.DARK_BLUE + "[" + ChatColor.WHITE + "DV" + ChatColor.DARK_BLUE + "] " + ChatColor.RESET; - // private private static final org.apache.logging.log4j.core.Logger logger = (org.apache.logging.log4j.core.Logger) LogManager .getRootLogger(); - // public public static Dreamvisitor PLUGIN; public static LuckPerms luckperms; public static String MOTD = null; @@ -62,7 +56,6 @@ public class Dreamvisitor extends JavaPlugin { private static ConsoleLogger appender; public final String VERSION = getDescription().getVersion(); - // WorldGuard flags public static StateFlag DRAGON_FLIGHT; public static StateFlag WITHER; @@ -94,48 +87,32 @@ public static LuckPerms getLuckPerms() throws NullPointerException { @Override public void onLoad() { - // Called after a plugin is loaded but before it has been enabled. - // When multiple plugins are loaded, the onLoad() for all plugins is called - // before any onEnable() is called. - // Init WorldGuard flags try { FlagRegistry registry = WorldGuard.getInstance().getFlagRegistry(); try { - // create a flag with the name "dragon-flight", defaulting to true StateFlag flag = new StateFlag("dragon-flight", true); registry.register(flag); - DRAGON_FLIGHT = flag; // only set our field if there was no error + DRAGON_FLIGHT = flag; } catch (FlagConflictException e) { - // some other plugin registered a flag by the same name already. - // you can use the existing flag, but this may cause conflicts - be sure to - // check type Flag existing = registry.get("dragon-flight"); if (existing instanceof StateFlag) { DRAGON_FLIGHT = (StateFlag) existing; } else { - // types don't match - this is bad news! some other plugin conflicts with you - // hopefully this never actually happens getLogger() .severe("A flag with the name dragon-flight already exists! Some other plugin claimed it already :("); } } try { - // create a flag with the name "wither", defaulting to true StateFlag flag = new StateFlag("wither", true); registry.register(flag); - WITHER = flag; // only set our field if there was no error + WITHER = flag; } catch (FlagConflictException e) { - // some other plugin registered a flag by the same name already. - // you can use the existing flag, but this may cause conflicts - be sure to - // check type Flag existing = registry.get("wither"); if (existing instanceof StateFlag) { WITHER = (StateFlag) existing; } else { - // types don't match - this is bad news! some other plugin conflicts with you - // hopefully this never actually happens getLogger().severe("A flag with the name wither already exists! Some other plugin claimed it already :("); } } @@ -152,13 +129,15 @@ public void onLoad() { public void onEnable() { try { - // Initialize variables PLUGIN = this; debugMode = getConfig().getBoolean("debug"); checkConfig(); + debug("Initializing PocketBase config loader..."); + PBConfigLoader.init(); + debug("Registering listeners..."); registerListeners(); @@ -191,7 +170,7 @@ public void onEnable() { commands.add(new CmdDreamvisitor()); commands.add(new CmdChatback()); commands.add(new CmdVelocity()); - commands.add(new CmdSchedule()); // Add the new schedule command + commands.add(new CmdSchedule()); debug("Initializing commands..."); CommandAPI.onLoad(new CommandAPIBukkitConfig(this).silentLogs(!debugMode)); @@ -199,72 +178,55 @@ public void onEnable() { registerCommands(commands); debug("Creating data folder..."); - // Create config if needed boolean directoryCreated = getDataFolder().mkdir(); if (!directoryCreated) debug("Dreamvisitor did not create a data folder. It may already exist."); saveDefaultConfig(); - // Initialize account link debug("Initializing accountLink.txt"); AccountLink.init(); - // Initialize infractions debug("Initializing infractions.yml"); Infraction.init(); - // Init alts debug("Initializing alts.yml"); AltFamily.init(); - // Init eco debug("Initializing economy.yml"); Economy.init(); - // Init mail debug("Initializing mail.yml"); Mail.init(); - // Init tribes debug("Initializing player-tribes.yml"); PlayerTribe.setup(); - // Init energy debug("Initializing energy"); Flight.init(); - // Init command scheduler debug("Initializing command scheduler"); CommandScheduler.getInstance().loadConfig(); - // Init bad words debug("Initializing badwords.yml"); BadWords.init(); - // LuckPerms API RegisteredServiceProvider provider = Bukkit.getServicesManager().getRegistration(LuckPerms.class); if (provider != null) luckperms = provider.getProvider(); - // WorldGuard flags SessionManager sessionManager = WorldGuard.getInstance().getPlatform().getSessionManager(); - // second param allows for ordering of handlers - see the JavaDocs sessionManager.registerHandler(DragonFlightFlag.FACTORY, null); sessionManager.registerHandler(WitherFlag.FACTORY, null); - // Start message getLogger().log(Level.INFO, "Dreamvisitor: A plugin created by Bog for WoF:TNW to add various features."); - // Bot debug("Starting Dreamvisitor bot..."); Bot.startBot(getConfig()); if (!botFailed) { - // Get saved data debug("Fetching recorded channels and roles from config."); DiscCommandsManager.init(); - // Send server start message try { Bot.getGameLogChannel().sendMessage("Server has been started.\n*Dreamvisitor " + VERSION + "*").queue(); } catch (InsufficientPermissionException e) { @@ -275,7 +237,6 @@ public void onEnable() { } - // If chat was previously paused, restore and notify in console\ debug("Restoring chat pause..."); if (getConfig().getBoolean("chatPaused")) { chatPaused = true; @@ -283,13 +244,11 @@ public void onEnable() { "Chat is currently paused from last session! Use /pausechat to allow users to chat."); } - // Restore player limit override debug("Restoring player limit override..."); playerLimit = getConfig().getInt("playerlimit"); getServer().getLogger().info(PREFIX + "Player limit override is currently set to " + playerLimit); - // Create item banlist if empty debug("Restoring item banlist..."); if (PLUGIN.getConfig().get("itemBlacklist") != null) { ArrayList itemList = (ArrayList) PLUGIN.getConfig().getList("itemBlacklist"); @@ -299,28 +258,24 @@ public void onEnable() { } } - // Console logging debug("Setting up console logging..."); appender = new ConsoleLogger(); logger.addAppender(appender); - // Set up web whitelist if enabled webWhitelistEnabled = getConfig().getBoolean("web-whitelist"); if (webWhitelistEnabled) Whitelist.startWeb(getConfig().getInt("whitelistPort")); Runnable pushConsole = new BukkitRunnable() { - // Push console log to Discord every 2 seconds @Override public void run() { if (Dreamvisitor.getPlugin().getConfig().getBoolean("log-console")) { - // If there are no messages in the queue, return if (ConsoleLogger.messageBuilder.isEmpty()) return; try { - Bot.getGameLogChannel().sendMessage(ConsoleLogger.messageBuilder.toString()).queue(); // send message + Bot.getGameLogChannel().sendMessage(ConsoleLogger.messageBuilder.toString()).queue(); } catch (InsufficientPermissionException e) { Bukkit.getLogger().warning( "Dreamvisitor Bot does not have the necessary permissions to send messages in game log channel."); @@ -328,23 +283,18 @@ public void run() { Bukkit.getLogger().severe("Console logger tried to send an invalid message!"); } - ConsoleLogger.messageBuilder.delete(0, ConsoleLogger.messageBuilder.length()); // delete queued messages + ConsoleLogger.messageBuilder.delete(0, ConsoleLogger.messageBuilder.length()); - // If there are no overflow messages, return if (ConsoleLogger.overFlowMessages.isEmpty()) return; StringBuilder overFlowMessageBuilder = new StringBuilder(); - // First is safe, so add now overFlowMessageBuilder.append(ConsoleLogger.overFlowMessages.get(0)); - // For each message in overflow for (int i = 1; i < ConsoleLogger.overFlowMessages.size(); i++) { - // Check that it fits if ((overFlowMessageBuilder.toString().length() + ConsoleLogger.overFlowMessages.get(i).length() + "\n".length()) >= 2000) { - // if not, queue current message and clear string builder try { Bot.getGameLogChannel().sendMessage(overFlowMessageBuilder.toString()).queue(); } catch (InsufficientPermissionException e) { @@ -368,7 +318,8 @@ public void run() { Runnable scheduledRestarts = new BukkitRunnable() { @Override public void run() { - // Restart if requested and no players are online + PBConfigLoader.loadConfig(); + if (AutoRestart.isAutoRestart() && Bukkit.getOnlinePlayers().isEmpty()) { AutoRestart.sendAutoRestartMessage(); Bukkit.getLogger().info(PREFIX + "Restarting the server as scheduled."); @@ -376,7 +327,6 @@ public void run() { getServer().spigot().restart(); } - // also check if memory usage is high and schedule restart long maxMemory = Runtime.getRuntime().maxMemory(); long freeMemory = Runtime.getRuntime().freeMemory(); double freeMemoryPercent = ((double) freeMemory / maxMemory) * 100; @@ -436,17 +386,13 @@ public void run() { Bukkit.getScheduler().runTaskTimer(this, tick, 0, 0); - // Push console every two seconds if (!botFailed) Bukkit.getScheduler().runTaskTimer(this, pushConsole, 0, 40); - // Check for scheduled restart every minute Bukkit.getScheduler().runTaskTimer(this, scheduledRestarts, 200, 1200); - // Check for warns that need to be reminded every hour Bukkit.getScheduler().runTaskTimer(this, remindWarns, 200, 20 * 60 * 60); - // Check for banned items every ten seconds Bukkit.getScheduler().runTaskTimer(this, checkBannedItems, 40, 20 * 10); debug("Enable finished."); @@ -457,7 +403,6 @@ public void run() { e.printStackTrace(); if (!botFailed) { - // Send startup crashes. StringBuilder builder = new StringBuilder(); builder.append(e.getMessage()); @@ -470,13 +415,10 @@ public void run() { .sendMessage(builder.toString()).complete(); } catch (net.dv8tion.jda.api.exceptions.ErrorResponseException ex) { if (ex.getErrorCode() == 50007) { - // Cannot send messages to this user Bukkit.getLogger().warning("Unable to send Discord DM to user: " + ex.getMessage() + ". User may have DMs disabled or is not in a shared server."); - // Log the error message to console instead Bukkit.getLogger().severe("Error message that would have been sent: " + builder.toString()); } else { - // For other Discord API errors, re-throw throw ex; } } @@ -496,6 +438,20 @@ private void checkConfig() throws InvalidConfigurationException { getConfig().set("playerlimit", -1); if (getConfig().getInt("infraction-expire-time-days") < 1) throw new InvalidConfigurationException("infraction-expire-time-days must be at least 1."); + + if (!getConfig().contains("pocketbase-url")) { + getConfig().set("pocketbase-url", "http://your-pocketbase-server.com"); + } + if (!getConfig().contains("pocketbase-config-id")) { + getConfig().set("pocketbase-config-id", "record_id_here"); + } + if (!getConfig().contains("pocketbase-token")) { + getConfig().set("pocketbase-token", "your_admin_token_here"); + } + if (!getConfig().contains("pocketbase-use-realtime")) { + getConfig().set("pocketbase-use-realtime", true); + } + saveConfig(); } @@ -537,8 +493,10 @@ public void onDisable() { CommandAPI.onDisable(); + // Shutdown the realtime updater + RealtimeConfigUpdater.shutdown(); + if (!botFailed) { - // Shutdown messages getLogger().info("Closing bot instance."); int requestsCanceled = Bot.getJda().cancelRequests(); if (requestsCanceled > 0) @@ -547,7 +505,6 @@ public void onDisable() { Bot.getJda().shutdownNow(); } - // remove moon globes for (Moonglobe moonglobe : Moonglobe.activeMoonglobes) moonglobe.remove(null); @@ -562,7 +519,6 @@ public void onDisable() { } } - // Save command scheduler CommandScheduler.getInstance().saveConfig(); CommandScheduler.getInstance().stopScheduler(); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PBConfigLoader.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PBConfigLoader.java new file mode 100644 index 0000000..33224f9 --- /dev/null +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PBConfigLoader.java @@ -0,0 +1,158 @@ +package io.github.stonley890.dreamvisitor.data; + +import com.google.gson.JsonObject; +import io.github.stonley890.dreamvisitor.Dreamvisitor; +import io.github.stonley890.dreamvisitor.functions.AutoRestart; +import io.github.stonley890.dreamvisitor.pb.PocketBase; +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.FileConfiguration; +import org.json.JSONObject; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CompletableFuture; + +public class PBConfigLoader { + private static JSONObject config; + private static String baseUrl; + private static String configId; + private static String token; + private static boolean useRealtime = true; + private static PocketBase pocketBaseClient; + private static final String COLLECTION_NAME = "dreamvisitor_config"; + + public static void init() { + FileConfiguration pluginConfig = Dreamvisitor.getPlugin().getConfig(); + baseUrl = pluginConfig.getString("pocketbase-url", ""); + configId = pluginConfig.getString("pocketbase-config-id", ""); + token = pluginConfig.getString("pocketbase-token", ""); + useRealtime = pluginConfig.getBoolean("pocketbase-use-realtime", true); + + if (baseUrl.isEmpty() || configId.isEmpty()) { + Bukkit.getLogger().warning("PocketBase URL or config ID not configured in plugin config."); + return; + } + + // Create PocketBase client from config + try { + Map pbConfig = new HashMap<>(); + pbConfig.put("pocketbase-url", baseUrl); + pbConfig.put("pocketbase-token", token); + pocketBaseClient = PocketBase.fromConfig(pbConfig); + + Dreamvisitor.debug("Initialized PocketBase client"); + } catch (Exception e) { + Bukkit.getLogger().warning("Failed to initialize PocketBase client: " + e.getMessage()); + return; + } + + // Initial config load + loadConfig(); + + // Start realtime updates if enabled + if (useRealtime) { + RealtimeConfigUpdater.init(baseUrl, configId, token); + } + } + + public static void loadConfig() { + try { + if (pocketBaseClient == null) { + Bukkit.getLogger().warning("PocketBase client not initialized, cannot load config"); + return; + } + + // Get record using PocketBase client + JsonObject record = pocketBaseClient.getRecord(COLLECTION_NAME, configId, null, null); + + // Convert from Gson JsonObject to org.json.JSONObject + String jsonString = record.toString(); + config = new JSONObject(jsonString); + + Dreamvisitor.debug("Loaded PocketBase configuration: " + config.toString()); + + // Apply config values to the system + applyConfig(); + } catch (IOException e) { + Bukkit.getLogger().warning("Error loading PocketBase config: " + e.getMessage()); + } + } + + public static void updateLocalConfig(JSONObject newConfigData) { + // Update our local config with new data + if (config != null) { + // Merge the new data into our existing config + for (String key : newConfigData.keySet()) { + config.put(key, newConfigData.get(key)); + } + + // Apply the updated config + applyConfig(); + } + } + + private static void applyConfig() { + // Apply configuration values to the relevant systems + if (config != null) { + // Handle autoRestart setting + if (config.has("autoRestart")) { + boolean autoRestart = config.getBoolean("autoRestart"); + if (autoRestart != AutoRestart.isAutoRestart()) { + if (autoRestart) { + AutoRestart.enableAutoRestart(null); + Dreamvisitor.debug("Auto restart enabled from remote config"); + } else { + AutoRestart.disableAutoRestart(); + Dreamvisitor.debug("Auto restart disabled from remote config"); + } + } + } + + // Add more configuration handlers here as needed + } + } + + public static CompletableFuture updateConfigField(String field, boolean value) { + return CompletableFuture.runAsync(() -> { + try { + if (pocketBaseClient == null) { + Bukkit.getLogger().warning("PocketBase client not initialized, cannot update config"); + return; + } + + // Create update data object + JsonObject updateData = new JsonObject(); + updateData.addProperty(field, value); + + // Update the record + pocketBaseClient.updateRecord(COLLECTION_NAME, configId, updateData, null, null); + + Dreamvisitor.debug("Updated PocketBase configuration field " + field + " to " + value); + + // If not using realtime updates, we need to reload config manually + if (!useRealtime) { + loadConfig(); + } + } catch (IOException e) { + Bukkit.getLogger().warning("Error updating PocketBase config: " + e.getMessage()); + } + }); + } + + public static boolean getBoolean(String field, boolean defaultValue) { + if (config == null) { + return defaultValue; + } + + try { + return config.getBoolean(field); + } catch (Exception e) { + return defaultValue; + } + } + + public static PocketBase getClient() { + return pocketBaseClient; + } +} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/RealtimeConfigUpdater.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/RealtimeConfigUpdater.java new file mode 100644 index 0000000..8b820b4 --- /dev/null +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/RealtimeConfigUpdater.java @@ -0,0 +1,207 @@ +package io.github.stonley890.dreamvisitor.data; + +import io.github.stonley890.dreamvisitor.Dreamvisitor; +import org.bukkit.Bukkit; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; + +public class RealtimeConfigUpdater { + private static ExecutorService executor = Executors.newSingleThreadExecutor(); + private static String baseUrl; + private static String configId; + private static String token; + private static String collectionName = "dreamvisitor_config"; + private static String clientId; + private static final AtomicBoolean isRunning = new AtomicBoolean(false); + private static final AtomicBoolean isConnecting = new AtomicBoolean(false); + private static int retryCount = 0; + private static final int MAX_RETRIES = 5; + private static final int RETRY_DELAY_MS = 5000; // 5 seconds between retries + + public static void init(String pbBaseUrl, String pbConfigId, String pbToken) { + baseUrl = pbBaseUrl; + configId = pbConfigId; + token = pbToken; + startRealtimeUpdates(); + } + + public static void startRealtimeUpdates() { + if (isConnecting.get() || isRunning.get()) { + return; + } + + if (baseUrl == null || baseUrl.isEmpty() || configId == null || configId.isEmpty()) { + Dreamvisitor.debug("Cannot start realtime updates: baseUrl or configId is not set"); + return; + } + + isConnecting.set(true); + + CompletableFuture.runAsync(() -> { + try { + connectSSE(); + } catch (Exception e) { + Dreamvisitor.debug("Error in SSE connection: " + e.getMessage()); + handleReconnect(); + } finally { + isConnecting.set(false); + } + }, executor); + } + + private static void connectSSE() throws IOException { + Dreamvisitor.debug("Connecting to SSE endpoint"); + + URL url = new URL(baseUrl + "/api/realtime"); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setReadTimeout(60000); // 1 minute timeout + + // Add authentication if token is provided + if (token != null && !token.isEmpty()) { + connection.setRequestProperty("Authorization", "Bearer " + token); + } + + int responseCode = connection.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK) { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { + isRunning.set(true); + retryCount = 0; + + String line; + while ((line = reader.readLine()) != null && isRunning.get()) { + if (line.startsWith("event: PB_CONNECT")) { + // Next line should be "data: {clientId}" + line = reader.readLine(); + if (line != null && line.startsWith("data: ")) { + clientId = line.substring(6).trim(); + Dreamvisitor.debug("Connected to SSE with client ID: " + clientId); + setSubscription(); + } + } else if (line.startsWith("event: PB_DISCONNECT")) { + Dreamvisitor.debug("Received disconnect event from server"); + break; + } else if (line.startsWith("event: update")) { + // Next line should be data + line = reader.readLine(); + if (line != null && line.startsWith("data: ")) { + handleUpdateEvent(line.substring(6)); + } + } + } + } finally { + isRunning.set(false); + if (!isConnecting.get()) { + handleReconnect(); + } + } + } else { + throw new IOException("Failed to connect to SSE endpoint: " + responseCode); + } + } + + private static void setSubscription() { + try { + URL url = new URL(baseUrl + "/api/realtime"); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("POST"); + connection.setRequestProperty("Content-Type", "application/json"); + + // Add authentication if token is provided + if (token != null && !token.isEmpty()) { + connection.setRequestProperty("Authorization", "Bearer " + token); + } + + connection.setDoOutput(true); + + // Subscribe to collection/record + JSONObject requestBody = new JSONObject(); + requestBody.put("clientId", clientId); + requestBody.put("subscriptions", new String[] { collectionName + "/" + configId }); + + try (OutputStream os = connection.getOutputStream()) { + byte[] input = requestBody.toString().getBytes(StandardCharsets.UTF_8); + os.write(input, 0, input.length); + } + + int responseCode = connection.getResponseCode(); + if (responseCode != HttpURLConnection.HTTP_NO_CONTENT) { + Dreamvisitor.debug("Failed to set subscription: " + responseCode); + + // Read error response if available + if (connection.getErrorStream() != null) { + try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getErrorStream()))) { + StringBuilder errorResponse = new StringBuilder(); + String line; + while ((line = br.readLine()) != null) { + errorResponse.append(line); + } + Dreamvisitor.debug("Error response: " + errorResponse.toString()); + } + } + } else { + Dreamvisitor.debug("Successfully subscribed to config updates"); + } + } catch (Exception e) { + Dreamvisitor.debug("Error setting subscription: " + e.getMessage()); + } + } + + private static void handleUpdateEvent(String data) { + try { + JSONObject jsonData = new JSONObject(data); + if (jsonData.has("record")) { + JSONObject record = jsonData.getJSONObject("record"); + + // Handle autoRestart field + if (record.has("autoRestart")) { + boolean autoRestart = record.getBoolean("autoRestart"); + Dreamvisitor.debug("Received real-time update: autoRestart = " + autoRestart); + + // Schedule update on main thread + Bukkit.getScheduler().runTask(Dreamvisitor.getPlugin(), () -> { + PBConfigLoader.updateLocalConfig(record); + }); + } + } + } catch (JSONException e) { + Dreamvisitor.debug("Error parsing update event: " + e.getMessage()); + } + } + + private static void handleReconnect() { + if (retryCount < MAX_RETRIES) { + retryCount++; + Dreamvisitor.debug("Attempting to reconnect SSE (attempt " + retryCount + "/" + MAX_RETRIES + ")"); + + try { + Thread.sleep(RETRY_DELAY_MS); + startRealtimeUpdates(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } else { + Dreamvisitor.debug("Max retry attempts reached. Giving up on SSE connection."); + // Fallback to polling + retryCount = 0; + } + } + + public static void shutdown() { + isRunning.set(false); + executor.shutdown(); + } +} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdAutorestart.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdAutorestart.java index 6fd3584..0e58e1c 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdAutorestart.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdAutorestart.java @@ -1,6 +1,7 @@ package io.github.stonley890.dreamvisitor.discord.commands; import io.github.stonley890.dreamvisitor.functions.AutoRestart; +import io.github.stonley890.dreamvisitor.data.PBConfigLoader; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; @@ -17,40 +18,43 @@ import java.util.Objects; public class DCmdAutorestart extends ListenerAdapter implements DiscordCommand { - @Override - public @NotNull SlashCommandData getCommandData() { - return Commands.slash("autorestart", "Restart the server when no players are online.") - .setDefaultPermissions(DefaultMemberPermissions.DISABLED); + @Override + public @NotNull SlashCommandData getCommandData() { + return Commands.slash("autorestart", "Restart the server when no players are online.") + .setDefaultPermissions(DefaultMemberPermissions.DISABLED); + } + + @Override + public void onCommand(@NotNull SlashCommandInteractionEvent event) { + interaction(event); + } + + @Override + public void onButtonInteraction(@NotNull ButtonInteractionEvent event) { + if (!Objects.equals(event.getButton().getId(), "autorestart")) { + return; } - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - interaction(event); - } - - @Override - public void onButtonInteraction(@NotNull ButtonInteractionEvent event) { - if (!Objects.equals(event.getButton().getId(), "autorestart")) { - return; - } - - interaction(event); - - } - - private static void interaction(@NotNull IReplyCallback event) { - - Button button = Button.primary("autorestart", "Undo"); - - if (AutoRestart.isAutoRestart()) { - AutoRestart.disableAutoRestart(); - EmbedBuilder embedBuilder = new EmbedBuilder(); - embedBuilder.setDescription("✅ Canceled server restart.").setColor(Color.BLUE).setTimestamp(Instant.now()); - event.replyEmbeds(embedBuilder.build()).addActionRow(button).queue(); - } else { - EmbedBuilder embedBuilder = new EmbedBuilder(); - embedBuilder.setDescription("✅ The server will restart when there are no players online.").setColor(Color.GREEN).setTimestamp(Instant.now()); - event.replyEmbeds(embedBuilder.build()).addActionRow(button).queue(hook -> hook.retrieveOriginal().queue(AutoRestart::enableAutoRestart)); - } + interaction(event); + } + + private static void interaction(@NotNull IReplyCallback event) { + Button button = Button.primary("autorestart", "Undo"); + + // Reload config to ensure we have latest state before checking + PBConfigLoader.loadConfig(); + + if (AutoRestart.isAutoRestart()) { + AutoRestart.disableAutoRestart(); + EmbedBuilder embedBuilder = new EmbedBuilder(); + embedBuilder.setDescription("✅ Canceled server restart.").setColor(Color.BLUE).setTimestamp(Instant.now()); + event.replyEmbeds(embedBuilder.build()).addActionRow(button).queue(); + } else { + EmbedBuilder embedBuilder = new EmbedBuilder(); + embedBuilder.setDescription("✅ The server will restart when there are no players online.").setColor(Color.GREEN) + .setTimestamp(Instant.now()); + event.replyEmbeds(embedBuilder.build()).addActionRow(button) + .queue(hook -> hook.retrieveOriginal().queue(AutoRestart::enableAutoRestart)); } + } } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/AutoRestart.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/AutoRestart.java index cfaf1ec..72a05b5 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/AutoRestart.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/AutoRestart.java @@ -1,6 +1,6 @@ package io.github.stonley890.dreamvisitor.functions; - +import io.github.stonley890.dreamvisitor.data.PBConfigLoader; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Message; import org.jetbrains.annotations.Nullable; @@ -10,34 +10,38 @@ public class AutoRestart { - private static boolean autoRestart = false; - @Nullable - private static Message autoRestartMessage = null; - - public static void enableAutoRestart(@Nullable Message replyMessage) { - autoRestartMessage = replyMessage; - autoRestart = true; - } - - public static void disableAutoRestart() { - autoRestart = false; - autoRestartMessage = null; - } - - - public static boolean isAutoRestart() { - return autoRestart; + private static boolean localAutoRestart = false; + @Nullable + private static Message autoRestartMessage = null; + + public static void enableAutoRestart(@Nullable Message replyMessage) { + autoRestartMessage = replyMessage; + localAutoRestart = true; + // Update the PocketBase config + PBConfigLoader.updateConfigField("autoRestart", true); + } + + public static void disableAutoRestart() { + localAutoRestart = false; + autoRestartMessage = null; + // Update the PocketBase config + PBConfigLoader.updateConfigField("autoRestart", false); + } + + public static boolean isAutoRestart() { + // Check PocketBase config first, fall back to local state if needed + return PBConfigLoader.getBoolean("autoRestart", localAutoRestart); + } + + /** + * Sends the auto restart message if necessary. This uses a blocking complete to + * ensure it does not get canceled. + */ + public static void sendAutoRestartMessage() { + if (autoRestartMessage != null) { + EmbedBuilder embedBuilder = new EmbedBuilder(); + embedBuilder.setDescription("The server is now restarting.").setColor(Color.GREEN).setTimestamp(Instant.now()); + autoRestartMessage.replyEmbeds(embedBuilder.build()).complete(); } - - /** - * Sends the auto restart message if necessary. This uses a blocking complete to ensure it does not get canceled. - */ - public static void sendAutoRestartMessage() { - if (autoRestartMessage != null) { - EmbedBuilder embedBuilder = new EmbedBuilder(); - embedBuilder.setDescription("The server is now restarting.").setColor(Color.GREEN).setTimestamp(Instant.now()); - autoRestartMessage.replyEmbeds(embedBuilder.build()).complete(); - } - } - + } } From 0fe6e3f8f3bb8af554606c26390eaf904b4c7511 Mon Sep 17 00:00:00 2001 From: Mustfa-IT Date: Wed, 28 May 2025 22:40:46 +0300 Subject: [PATCH 04/39] Reduce retry delay and read timeout in RealtimeConfigUpdater for improved responsiveness --- .../stonley890/dreamvisitor/data/RealtimeConfigUpdater.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/RealtimeConfigUpdater.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/RealtimeConfigUpdater.java index 8b820b4..b6c6633 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/RealtimeConfigUpdater.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/RealtimeConfigUpdater.java @@ -29,7 +29,7 @@ public class RealtimeConfigUpdater { private static final AtomicBoolean isConnecting = new AtomicBoolean(false); private static int retryCount = 0; private static final int MAX_RETRIES = 5; - private static final int RETRY_DELAY_MS = 5000; // 5 seconds between retries + private static final int RETRY_DELAY_MS = 3000; // 5 seconds between retries public static void init(String pbBaseUrl, String pbConfigId, String pbToken) { baseUrl = pbBaseUrl; @@ -68,7 +68,7 @@ private static void connectSSE() throws IOException { URL url = new URL(baseUrl + "/api/realtime"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); - connection.setReadTimeout(60000); // 1 minute timeout + connection.setReadTimeout(6000); // 1 minute timeout // Add authentication if token is provided if (token != null && !token.isEmpty()) { @@ -170,7 +170,7 @@ private static void handleUpdateEvent(String data) { if (record.has("autoRestart")) { boolean autoRestart = record.getBoolean("autoRestart"); Dreamvisitor.debug("Received real-time update: autoRestart = " + autoRestart); - + // Schedule update on main thread Bukkit.getScheduler().runTask(Dreamvisitor.getPlugin(), () -> { PBConfigLoader.updateLocalConfig(record); From 336577696fbc474ce4dba213365ea96bea77c98e Mon Sep 17 00:00:00 2001 From: Bog Date: Thu, 26 Jun 2025 10:00:26 -0700 Subject: [PATCH 05/39] Create Messager.java --- .../dreamvisitor/functions/Messager.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Messager.java diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Messager.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Messager.java new file mode 100644 index 0000000..c1acade --- /dev/null +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Messager.java @@ -0,0 +1,37 @@ +package io.github.stonley890.dreamvisitor.functions; + +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.awt.*; + +public class Messager { + + static final Color PREFIX_COLOR = Color.decode("#3B3BD1"); + static final Color MESSAGE_COLOR = Color.decode("#C9C9FB"); + + static final String PREFIX = ChatColor.of(PREFIX_COLOR) + "✧ "; + + /** + * Send a {@link String} message to a player. + * @param player the player to send the message to. + * @param message the message to send. + */ + public static void send(@NotNull Player player, String message) { + player.sendMessage(PREFIX + ChatColor.of(MESSAGE_COLOR) + message); + } + + /** + * Send a {@link BaseComponent} message to a player. + * @param player the player to send the message to. + * @param message the message to send. + */ + public static void send(@NotNull Player player, BaseComponent[] message) { + ComponentBuilder builder = new ComponentBuilder(); + builder.append(PREFIX).append(message).color(ChatColor.of(MESSAGE_COLOR)); + player.spigot().sendMessage(builder.build()); + } +} From 9863c4334abfeb47553a938b5f03ff791946686b Mon Sep 17 00:00:00 2001 From: Bog Date: Thu, 26 Jun 2025 10:29:12 -0700 Subject: [PATCH 06/39] Change all messages to use Messager --- .../github/stonley890/dreamvisitor/Bot.java | 15 +-- .../stonley890/dreamvisitor/Dreamvisitor.java | 91 ++++++++----------- .../dreamvisitor/commands/CmdAdminRadio.java | 4 +- .../dreamvisitor/commands/CmdDiscord.java | 3 +- .../commands/CmdDreamvisitor.java | 35 +++---- .../dreamvisitor/commands/CmdDvset.java | 25 ++--- .../dreamvisitor/commands/CmdHub.java | 5 +- .../dreamvisitor/commands/CmdInvSwap.java | 3 +- .../dreamvisitor/commands/CmdMoonglobe.java | 9 +- .../dreamvisitor/commands/CmdPanic.java | 4 +- .../dreamvisitor/commands/CmdParcel.java | 36 ++++---- .../dreamvisitor/commands/CmdPauseBypass.java | 7 +- .../dreamvisitor/commands/CmdPlayerlimit.java | 6 +- .../dreamvisitor/commands/CmdSandbox.java | 13 +-- .../dreamvisitor/commands/CmdSchedule.java | 83 ++++++++--------- .../commands/CmdScheduleRestart.java | 5 +- .../dreamvisitor/commands/CmdSetback.java | 3 +- .../dreamvisitor/commands/CmdSethub.java | 3 +- .../dreamvisitor/commands/CmdSetmotd.java | 9 +- .../commands/CmdSoftwhitelist.java | 11 ++- .../dreamvisitor/commands/CmdSynctime.java | 3 +- .../dreamvisitor/commands/CmdTribeUpdate.java | 16 +--- .../dreamvisitor/commands/CmdUnwax.java | 3 +- .../dreamvisitor/commands/CmdUser.java | 3 +- .../dreamvisitor/commands/CmdVelocity.java | 3 +- .../dreamvisitor/commands/CmdZoop.java | 3 +- .../dreamvisitor/data/AccountLink.java | 15 ++- .../dreamvisitor/data/AltFamily.java | 7 +- .../dreamvisitor/data/BadWords.java | 4 +- .../stonley890/dreamvisitor/data/Economy.java | 3 +- .../dreamvisitor/data/Infraction.java | 18 ++-- .../dreamvisitor/data/PBConfigLoader.java | 11 ++- .../dreamvisitor/data/PlayerTribe.java | 25 ++--- .../data/RealtimeConfigUpdater.java | 28 +++--- .../discord/DiscCommandsManager.java | 12 +-- .../discord/DiscEventListener.java | 35 +++---- .../discord/commands/DCmdBaltop.java | 13 +-- .../discord/commands/DCmdEconomy.java | 26 +++--- .../discord/commands/DCmdInventory.java | 8 +- .../discord/commands/DCmdLink.java | 10 +- .../commands/DCmdResourcepackupdate.java | 23 ++--- .../discord/commands/DCmdSeen.java | 7 +- .../discord/commands/DCmdUser.java | 6 +- .../functions/CommandScheduler.java | 5 +- .../dreamvisitor/functions/Flight.java | 2 +- .../dreamvisitor/functions/Mail.java | 52 +++++------ .../dreamvisitor/functions/Messager.java | 43 ++++++--- .../dreamvisitor/functions/Sandbox.java | 2 +- .../dreamvisitor/functions/Whitelist.java | 62 ++++++------- .../listeners/ListenPlayerCmdPreprocess.java | 3 +- .../listeners/ListenPlayerJoin.java | 3 +- .../listeners/ListenPlayerLogin.java | 4 +- .../listeners/ListenPlayerQuit.java | 17 ++-- .../listeners/ListenPlayerRespawn.java | 4 +- 54 files changed, 437 insertions(+), 412 deletions(-) diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Bot.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Bot.java index 32ba669..80ecbbf 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Bot.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Bot.java @@ -3,6 +3,7 @@ import io.github.stonley890.dreamvisitor.discord.DiscCommandsManager; import io.github.stonley890.dreamvisitor.discord.DiscEventListener; import io.github.stonley890.dreamvisitor.discord.commands.DCmdAutorestart; +import io.github.stonley890.dreamvisitor.functions.Messager; import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.entities.Role; @@ -45,13 +46,13 @@ public static void startBot(@NotNull FileConfiguration config) { // Build JDA String token = Dreamvisitor.getPlugin().getConfig().getString("bot-token"); // Try to create a bot - Dreamvisitor.debug("Attempting to create a bot..."); + Messager.debug("Attempting to create a bot..."); try { jda = JDABuilder .createLight(token, GatewayIntent.GUILD_MESSAGES, GatewayIntent.MESSAGE_CONTENT, GatewayIntent.GUILD_MEMBERS) .disableCache(CacheFlag.VOICE_STATE, CacheFlag.EMOJI, CacheFlag.STICKER) .build(); - Dreamvisitor.debug("Bot created."); + Messager.debug("Bot created."); Dreamvisitor.botFailed = false; } catch (InvalidTokenException e) { @@ -78,15 +79,15 @@ public static void startBot(@NotNull FileConfiguration config) { // Wait for bot ready try { jda.awaitReady(); - Dreamvisitor.debug("Bot is ready."); + Messager.debug("Bot is ready."); long chatChannelID = config.getLong("chatChannelID"); long logChannelID = config.getLong("logChannelID"); long whitelistChannelID = config.getLong("whitelistChannelID"); - Dreamvisitor.debug(String.valueOf(chatChannelID)); - Dreamvisitor.debug(String.valueOf(logChannelID)); - Dreamvisitor.debug(String.valueOf(whitelistChannelID)); + Messager.debug(String.valueOf(chatChannelID)); + Messager.debug(String.valueOf(logChannelID)); + Messager.debug(String.valueOf(whitelistChannelID)); Bot.gameChatChannel = jda.getTextChannelById(chatChannelID); Bot.gameLogChannel = jda.getTextChannelById(logChannelID); @@ -169,7 +170,7 @@ public static void sendLog(@NotNull String message) { .warning("Dreamvisitor bot does not have sufficient permissions to send messages in game log channel!"); } catch (IllegalArgumentException e) { if (Dreamvisitor.debugMode) - Dreamvisitor.debug("Attempted to send an invalid message."); + Messager.debug("Attempted to send an invalid message."); } } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Dreamvisitor.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Dreamvisitor.java index 7d6e02c..d4787ae 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Dreamvisitor.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Dreamvisitor.java @@ -22,7 +22,6 @@ import net.luckperms.api.LuckPerms; import org.apache.logging.log4j.LogManager; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.entity.Player; @@ -40,8 +39,6 @@ @SuppressWarnings({ "null" }) public class Dreamvisitor extends JavaPlugin { - public static final String PREFIX = ChatColor.DARK_BLUE + "[" + ChatColor.WHITE + "DV" + ChatColor.DARK_BLUE + "] " - + ChatColor.RESET; private static final org.apache.logging.log4j.core.Logger logger = (org.apache.logging.log4j.core.Logger) LogManager .getRootLogger(); public static Dreamvisitor PLUGIN; @@ -67,12 +64,6 @@ public static Dreamvisitor getPlugin() { return PLUGIN.getDataFolder().getAbsolutePath() + "/player/" + uuid + ".yml"; } - public static void debug(String message) { - if (getPlugin().getConfig().getBoolean("debug")) { - Bukkit.getLogger().info("DEBUG: " + message); - } - } - @NotNull public static LuckPerms getLuckPerms() throws NullPointerException { RegisteredServiceProvider provider = Bukkit.getServicesManager().getRegistration(LuckPerms.class); @@ -135,10 +126,10 @@ public void onEnable() { checkConfig(); - debug("Initializing PocketBase config loader..."); + Messager.debug("Initializing PocketBase config loader..."); PBConfigLoader.init(); - debug("Registering listeners..."); + Messager.debug("Registering listeners..."); registerListeners(); List commands = new ArrayList<>(); @@ -172,42 +163,42 @@ public void onEnable() { commands.add(new CmdVelocity()); commands.add(new CmdSchedule()); - debug("Initializing commands..."); + Messager.debug("Initializing commands..."); CommandAPI.onLoad(new CommandAPIBukkitConfig(this).silentLogs(!debugMode)); CommandAPI.onEnable(); registerCommands(commands); - debug("Creating data folder..."); + Messager.debug("Creating data folder..."); boolean directoryCreated = getDataFolder().mkdir(); if (!directoryCreated) - debug("Dreamvisitor did not create a data folder. It may already exist."); + Messager.debug("Dreamvisitor did not create a data folder. It may already exist."); saveDefaultConfig(); - debug("Initializing accountLink.txt"); + Messager.debug("Initializing accountLink.txt"); AccountLink.init(); - debug("Initializing infractions.yml"); + Messager.debug("Initializing infractions.yml"); Infraction.init(); - debug("Initializing alts.yml"); + Messager.debug("Initializing alts.yml"); AltFamily.init(); - debug("Initializing economy.yml"); + Messager.debug("Initializing economy.yml"); Economy.init(); - debug("Initializing mail.yml"); + Messager.debug("Initializing mail.yml"); Mail.init(); - debug("Initializing player-tribes.yml"); + Messager.debug("Initializing player-tribes.yml"); PlayerTribe.setup(); - debug("Initializing energy"); + Messager.debug("Initializing energy"); Flight.init(); - debug("Initializing command scheduler"); + Messager.debug("Initializing command scheduler"); CommandScheduler.getInstance().loadConfig(); - debug("Initializing badwords.yml"); + Messager.debug("Initializing badwords.yml"); BadWords.init(); RegisteredServiceProvider provider = Bukkit.getServicesManager().getRegistration(LuckPerms.class); @@ -220,45 +211,43 @@ public void onEnable() { getLogger().log(Level.INFO, "Dreamvisitor: A plugin created by Bog for WoF:TNW to add various features."); - debug("Starting Dreamvisitor bot..."); + Messager.debug("Starting Dreamvisitor bot..."); Bot.startBot(getConfig()); if (!botFailed) { - debug("Fetching recorded channels and roles from config."); + Messager.debug("Fetching recorded channels and roles from config."); DiscCommandsManager.init(); try { Bot.getGameLogChannel().sendMessage("Server has been started.\n*Dreamvisitor " + VERSION + "*").queue(); } catch (InsufficientPermissionException e) { - Bukkit.getLogger() + getLogger() .severe("Dreamvisitor Bot does not have permission to send messages in the game log channel!"); throw e; } } - debug("Restoring chat pause..."); + Messager.debug("Restoring chat pause..."); if (getConfig().getBoolean("chatPaused")) { chatPaused = true; - Bukkit.getServer().getLogger().info(PREFIX + - "Chat is currently paused from last session! Use /pausechat to allow users to chat."); + getLogger().info("Chat is currently paused from last session! Use /pausechat to allow users to chat."); } - debug("Restoring player limit override..."); + Messager.debug("Restoring player limit override..."); playerLimit = getConfig().getInt("playerlimit"); - getServer().getLogger().info(PREFIX + - "Player limit override is currently set to " + playerLimit); + getLogger().info("Player limit override is currently set to " + playerLimit); - debug("Restoring item banlist..."); + Messager.debug("Restoring item banlist..."); if (PLUGIN.getConfig().get("itemBlacklist") != null) { ArrayList itemList = (ArrayList) PLUGIN.getConfig().getList("itemBlacklist"); if (itemList != null) { - debug("Item banlist is null. Creating an empty banlist..."); + Messager.debug("Item banlist is null. Creating an empty banlist..."); ItemBanList.badItems = itemList.toArray(new ItemStack[0]); } } - debug("Setting up console logging..."); + Messager.debug("Setting up console logging..."); appender = new ConsoleLogger(); logger.addAppender(appender); @@ -277,10 +266,10 @@ public void run() { try { Bot.getGameLogChannel().sendMessage(ConsoleLogger.messageBuilder.toString()).queue(); } catch (InsufficientPermissionException e) { - Bukkit.getLogger().warning( + getLogger().warning( "Dreamvisitor Bot does not have the necessary permissions to send messages in game log channel."); } catch (IllegalArgumentException e) { - Bukkit.getLogger().severe("Console logger tried to send an invalid message!"); + getLogger().severe("Console logger tried to send an invalid message!"); } ConsoleLogger.messageBuilder.delete(0, ConsoleLogger.messageBuilder.length()); @@ -298,10 +287,10 @@ public void run() { try { Bot.getGameLogChannel().sendMessage(overFlowMessageBuilder.toString()).queue(); } catch (InsufficientPermissionException e) { - Bukkit.getLogger().warning( + getLogger().warning( "Dreamvisitor Bot does not have the necessary permissions to send messages in game log channel."); } catch (IllegalArgumentException e) { - Bukkit.getLogger().severe("Console logger tried to send an invalid message!"); + getLogger().severe("Console logger tried to send an invalid message!"); } overFlowMessageBuilder = new StringBuilder(); @@ -322,7 +311,7 @@ public void run() { if (AutoRestart.isAutoRestart() && Bukkit.getOnlinePlayers().isEmpty()) { AutoRestart.sendAutoRestartMessage(); - Bukkit.getLogger().info(PREFIX + "Restarting the server as scheduled."); + getLogger().info("Restarting the server as scheduled."); Bot.sendLog("**Restarting the server as scheduled.**"); getServer().spigot().restart(); } @@ -332,8 +321,8 @@ public void run() { double freeMemoryPercent = ((double) freeMemory / maxMemory) * 100; if (freeMemoryPercent <= 10) { AutoRestart.enableAutoRestart(null); - Bukkit.getLogger() - .info("Dreamvisitor scheduled a restart because free memory usage is at or less than 10%."); + getLogger() + .warning("Dreamvisitor scheduled a restart because free memory usage is at or less than 10%."); } } }; @@ -348,14 +337,14 @@ public void run() { Runnable remindWarns = new BukkitRunnable() { @Override public void run() { - Dreamvisitor.debug("Checking warns to be reminded."); + Messager.debug("Checking warns to be reminded."); Map> infractions = Infraction.getAllInfractions(); - Dreamvisitor.debug("Got list of " + infractions.keySet().size() + " members."); + Messager.debug("Got list of " + infractions.keySet().size() + " members."); for (Long l : infractions.keySet()) { - Dreamvisitor.debug("Checking infractions of user " + l); + Messager.debug("Checking infractions of user " + l); List userInfractions = Infraction.getInfractions(l); for (Infraction userInfraction : userInfractions) { - Dreamvisitor.debug("Attempting remind..."); + Messager.debug("Attempting remind..."); userInfraction.remind(l); } } @@ -395,10 +384,10 @@ public void run() { Bukkit.getScheduler().runTaskTimer(this, checkBannedItems, 40, 20 * 10); - debug("Enable finished."); + Messager.debug("Enable finished."); } catch (Exception e) { - Bukkit.getLogger() + getLogger() .severe("Dreamvisitor was unable to start :(\nPlease notify Bog with the following stack trace:"); e.printStackTrace(); @@ -415,9 +404,9 @@ public void run() { .sendMessage(builder.toString()).complete(); } catch (net.dv8tion.jda.api.exceptions.ErrorResponseException ex) { if (ex.getErrorCode() == 50007) { - Bukkit.getLogger().warning("Unable to send Discord DM to user: " + ex.getMessage() + + getLogger().warning("Unable to send Discord DM to user: " + ex.getMessage() + ". User may have DMs disabled or is not in a shared server."); - Bukkit.getLogger().severe("Error message that would have been sent: " + builder.toString()); + getLogger().severe("Error message that would have been sent: " + builder.toString()); } else { throw ex; } @@ -513,7 +502,7 @@ public void onDisable() { PlayerUtility.savePlayerMemory(player.getUniqueId()); PlayerUtility.clearPlayerMemory(player.getUniqueId()); } catch (IOException e) { - Bukkit.getLogger().severe("Unable to save player memory! Does the server have write access?"); + getLogger().severe("Unable to save player memory! Does the server have write access?"); if (Dreamvisitor.debugMode) throw new RuntimeException(); } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdAdminRadio.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdAdminRadio.java index 739d2ca..34ff735 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdAdminRadio.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdAdminRadio.java @@ -5,7 +5,7 @@ import dev.jorel.commandapi.CommandPermission; import dev.jorel.commandapi.ExecutableCommand; import dev.jorel.commandapi.arguments.GreedyStringArgument; -import io.github.stonley890.dreamvisitor.Dreamvisitor; +import io.github.stonley890.dreamvisitor.functions.Messager; import io.github.stonley890.dreamvisitor.functions.Radio; import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; @@ -24,7 +24,7 @@ public class CmdAdminRadio implements DVCommand { .executesNative(((sender, args) -> { String message = (String) args.get("message"); - Dreamvisitor.debug(sender.getClass().getName()); + Messager.debug(sender.getClass().getName()); CommandSender callee = sender.getCallee(); if (callee instanceof Player player) { diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDiscord.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDiscord.java index 03352e8..5f11dce 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDiscord.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDiscord.java @@ -5,6 +5,7 @@ import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.data.PlayerMemory; import io.github.stonley890.dreamvisitor.data.PlayerUtility; +import io.github.stonley890.dreamvisitor.functions.Messager; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; @@ -22,7 +23,7 @@ public CommandAPICommand getCommand() { PlayerMemory memory = PlayerUtility.getPlayerMemory(player.getUniqueId()); memory.discordEnabled = !memory.discordEnabled; - callee.sendMessage(Dreamvisitor.PREFIX + "Discord visibility toggled to " + !memory.discordEnabled + "."); + Messager.send(player, "Discord visibility toggled to " + !memory.discordEnabled + "."); PlayerUtility.setPlayerMemory(player.getUniqueId(), memory); } else throw CommandAPI.failWithString("This command must be executed as a player!"); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDreamvisitor.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDreamvisitor.java index 335f1e4..193a0c4 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDreamvisitor.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDreamvisitor.java @@ -7,6 +7,7 @@ import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.data.Tribe; import io.github.stonley890.dreamvisitor.data.TribeUtil; +import io.github.stonley890.dreamvisitor.functions.Messager; import net.md_5.bungee.api.ChatColor; import org.bukkit.Location; import org.bukkit.command.CommandSender; @@ -25,14 +26,14 @@ public class CmdDreamvisitor implements DVCommand { public CommandAPICommand getCommand() { return new CommandAPICommand("dreamvisitor") .executes((sender, args) -> { - sender.sendMessage(ChatColor.BLUE + "Dreamvisitor " + Dreamvisitor.getPlugin().getDescription().getVersion() + "\nDeveloped by Stonley890\nOpen source at https://github.com/Stonley890/Dreamvisitor"); + Messager.send(sender, "Dreamvisitor " + Dreamvisitor.getPlugin().getDescription().getVersion() + "\nDeveloped by Bog\nOpen source at https://github.com/WOFTNW/Dreamvisitor"); }) .withSubcommand(new CommandAPICommand("reload") .withPermission(CommandPermission.OP) .withHelp("Reload Dreamvisitor.", "Reload Dreamvisitor's config file from disk.") .executes(((sender, args) -> { Dreamvisitor.getPlugin().reloadConfig(); - sender.sendMessage(Dreamvisitor.PREFIX + "Configuration reloaded."); + Messager.send(sender, "Configuration reloaded."); })) ) .withSubcommand(new CommandAPICommand("manage") @@ -110,12 +111,12 @@ public CommandAPICommand getCommand() { @NotNull Tribe tribe = (Tribe) Objects.requireNonNull(args.get("tribe")); int tribeIndex = TribeUtil.indexOf(tribe); List emblems = plugin.getConfig().getLongList("triberoles"); - if (roleId == null) sender.sendMessage(Dreamvisitor.PREFIX + "role of " + tribe.getName() + " is currently set to\n" + emblems.get(tribeIndex)); + if (roleId == null) Messager.send(sender, "Role of " + tribe.getName() + " is currently set to\n" + emblems.get(tribeIndex)); else { emblems.set(tribeIndex, roleId); plugin.getConfig().set("triberoles", emblems); plugin.saveConfig(); - sender.sendMessage(Dreamvisitor.PREFIX + "Set role of " + tribe.getName() + " to\n" + roleId); + Messager.send(sender, "Set role of " + tribe.getName() + " to\n" + roleId); } }), new CommandAPICommand("chatPaused") @@ -168,7 +169,7 @@ public CommandAPICommand getCommand() { Location location = plugin.getConfig().getLocation(key); String reply = "none"; if (location != null) reply = location.toString(); - sender.sendMessage(Dreamvisitor.PREFIX + key + " is currently set to\n" + reply); + Messager.send(sender, key + " is currently set to\n" + reply); }), new CommandAPICommand("log-console") .withHelp("Set log-console.", """ @@ -443,62 +444,62 @@ Takes the ratio (between 0 and 1) of the distance to the maximum distance betwee private void configBoolean(CommandSender sender, @NotNull CommandArguments args, String key) { Boolean value = (Boolean) args.get(key); - if (value == null) sender.sendMessage(Dreamvisitor.PREFIX + key + " is currently set to\n" + plugin.getConfig().getBoolean(key)); + if (value == null) Messager.send(sender, key + " is currently set to\n" + plugin.getConfig().getBoolean(key)); else { plugin.getConfig().set(key, value); plugin.saveConfig(); - sender.sendMessage(Dreamvisitor.PREFIX + "Set " + key + " to\n" + plugin.getConfig().getBoolean(key)); + Messager.send(sender, "Set " + key + " to\n" + plugin.getConfig().getBoolean(key)); } } private void configInt(CommandSender sender, @NotNull CommandArguments args, String key) { Integer value = (Integer) args.get(key); - if (value == null) sender.sendMessage(Dreamvisitor.PREFIX + key + " is currently set to\n" + plugin.getConfig().getInt(key)); + if (value == null) Messager.send(sender, key + " is currently set to\n" + plugin.getConfig().getInt(key)); else { plugin.getConfig().set(key, value); plugin.saveConfig(); - sender.sendMessage(Dreamvisitor.PREFIX + "Set " + key + " to\n" + plugin.getConfig().getInt(key)); + Messager.send(sender, "Set " + key + " to\n" + plugin.getConfig().getInt(key)); } } private void configDouble(CommandSender sender, @NotNull CommandArguments args, String key) { Double value = (Double) args.get(key); - if (value == null) sender.sendMessage(Dreamvisitor.PREFIX + key + " is currently set to\n" + plugin.getConfig().getDouble(key)); + if (value == null) Messager.send(sender, key + " is currently set to\n" + plugin.getConfig().getDouble(key)); else { plugin.getConfig().set(key, value); plugin.saveConfig(); - sender.sendMessage(Dreamvisitor.PREFIX + "Set " + key + " to\n" + plugin.getConfig().getDouble(key)); + Messager.send(sender, "Set " + key + " to\n" + plugin.getConfig().getDouble(key)); } } private void configLong(CommandSender sender, @NotNull CommandArguments args, String key) { Long value = (Long) args.get(key); - if (value == null) sender.sendMessage(Dreamvisitor.PREFIX + key + " is currently set to\n" + plugin.getConfig().getLong(key)); + if (value == null) Messager.send(sender, key + " is currently set to\n" + plugin.getConfig().getLong(key)); else { plugin.getConfig().set(key, value); plugin.saveConfig(); - sender.sendMessage(Dreamvisitor.PREFIX + "Set " + key + " to\n" + plugin.getConfig().getLong(key)); + Messager.send(sender, "Set " + key + " to\n" + plugin.getConfig().getLong(key)); } } private void configString(CommandSender sender, @NotNull CommandArguments args, String key) { String value = (String) args.get(key); - if (value == null) sender.sendMessage(Dreamvisitor.PREFIX + key + " is currently set to\n" + plugin.getConfig().getString(key)); + if (value == null) Messager.send(sender, key + " is currently set to\n" + plugin.getConfig().getString(key)); else { plugin.getConfig().set(key, value); plugin.saveConfig(); - sender.sendMessage(Dreamvisitor.PREFIX + "Set " + key + " to\n" + plugin.getConfig().getString(key)); + Messager.send(sender, "Set " + key + " to\n" + plugin.getConfig().getString(key)); } } @SuppressWarnings("unchecked") private void configLongList(CommandSender sender, @NotNull CommandArguments args, String key) { List value = (List) args.get(key); - if (value == null) sender.sendMessage(Dreamvisitor.PREFIX + key + " is currently set to\n" + plugin.getConfig().getLongList(key)); + if (value == null) Messager.send(sender, key + " is currently set to\n" + plugin.getConfig().getLongList(key)); else { plugin.getConfig().set(key, value); plugin.saveConfig(); - sender.sendMessage(Dreamvisitor.PREFIX + "Set " + key + " to\n" + plugin.getConfig().getLongList(key)); + Messager.send(sender, "Set " + key + " to\n" + plugin.getConfig().getLongList(key)); } } } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDvset.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDvset.java index 7e54f72..7546b8a 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDvset.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDvset.java @@ -7,6 +7,7 @@ import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.data.PlayerMemory; import io.github.stonley890.dreamvisitor.data.PlayerUtility; +import io.github.stonley890.dreamvisitor.functions.Messager; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.*; import net.md_5.bungee.api.chat.hover.content.Text; @@ -22,7 +23,7 @@ private static void sendUserGui(@NotNull Player player) { PlayerMemory memory = PlayerUtility.getPlayerMemory(player.getUniqueId()); - ComponentBuilder builder = new ComponentBuilder(Dreamvisitor.PREFIX); + ComponentBuilder builder = new ComponentBuilder(); builder.append("User Options "); if (player.hasPermission("dreamvisitor.set.discord")) { @@ -66,7 +67,7 @@ private static void sendUserGui(@NotNull Player player) { } builder.append("").reset().append("\n"); - player.spigot().sendMessage(builder.create()); + Messager.send(player, builder.create()); } @@ -134,31 +135,31 @@ public CommandTree getCommand() { case "discord" -> { if (!player.hasPermission("dreamvisitor.set.discord")) throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Discord Visibility is currently set to " + Messager.send(callee, ChatColor.GRAY + "Discord Visibility is currently set to " + ChatColor.WHITE + playerMemory.discordEnabled); } case "flight" -> { if (!player.hasPermission("dreamvisitor.set.flight")) throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Flight Enabled is currently set to " + Messager.send(callee, ChatColor.GRAY + "Flight Enabled is currently set to " + ChatColor.WHITE + playerMemory.flightDisabled); } case "vanished" -> { if (!player.hasPermission("dreamvisitor.set.zoop")) throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Discord Vanish is currently set to " + Messager.send(callee, ChatColor.GRAY + "Discord Vanish is currently set to " + ChatColor.WHITE + playerMemory.vanished); } case "autoinvswap" -> { if (!player.hasPermission("dreamvisitor.set.autoinvswap")) throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + Messager.send(callee, ChatColor.GRAY + "Automatic Inventory Swap is currently set to " + ChatColor.WHITE + playerMemory.autoinvswap); } case "autoradio" -> { if (!player.hasPermission("dreamvisitor.set.autoradio")) throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Automatic Radio is currently set to " + Messager.send(callee, ChatColor.GRAY + "Automatic Radio is currently set to " + ChatColor.WHITE + playerMemory.autoRadio); } default -> @@ -192,14 +193,14 @@ public CommandTree getCommand() { if (!player.hasPermission("dreamvisitor.set.discord")) throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); playerMemory.discordEnabled = Boolean.parseBoolean(modification); - callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Discord Visibility toggled to " + Messager.send(callee, ChatColor.GRAY + "Discord Visibility toggled to " + ChatColor.WHITE + playerMemory.discordEnabled); } case "flight" -> { if (!player.hasPermission("dreamvisitor.set.flight")) throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); playerMemory.flightDisabled = Boolean.parseBoolean(modification); - callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Flight Enabled toggled to " + Messager.send(callee, ChatColor.GRAY + "Flight Enabled toggled to " + ChatColor.WHITE + playerMemory.flightDisabled); } case "vanished" -> { @@ -216,21 +217,21 @@ public CommandTree getCommand() { Bot.getGameChatChannel().sendMessage(chatMessage).queue(); Bot.sendLog(chatMessage); - callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Discord Vanish toggled to " + Messager.send(callee, ChatColor.GRAY + "Discord Vanish toggled to " + ChatColor.WHITE + playerMemory.vanished); } case "autoinvswap" -> { if (!player.hasPermission("dreamvisitor.set.autoinvswap")) throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); playerMemory.autoinvswap = Boolean.parseBoolean(modification); - callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Automatic Inventory Swap toggled to " + Messager.send(callee, ChatColor.GRAY + "Automatic Inventory Swap toggled to " + ChatColor.WHITE + playerMemory.autoinvswap); } case "autoradio" -> { if (!player.hasPermission("dreamvisitor.set.autoradio")) throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); playerMemory.autoRadio = Boolean.parseBoolean(modification); - callee.sendMessage(Dreamvisitor.PREFIX + ChatColor.GRAY + "Automatic Radio toggled to " + Messager.send(callee, ChatColor.GRAY + "Automatic Radio toggled to " + ChatColor.WHITE + playerMemory.autoRadio); } default -> diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdHub.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdHub.java index 574b028..9f3fbbe 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdHub.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdHub.java @@ -8,6 +8,7 @@ import dev.jorel.commandapi.arguments.EntitySelectorArgument; import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.functions.Mail; +import io.github.stonley890.dreamvisitor.functions.Messager; import org.bukkit.*; import org.bukkit.command.BlockCommandSender; import org.bukkit.command.CommandSender; @@ -72,10 +73,10 @@ public CommandAPICommand getCommand() { } } if (entitySelect.size() == 1) { - callee.sendMessage(Dreamvisitor.PREFIX + "Teleported " + entitySelect.stream().findFirst().get().getName() + " to the hub."); + Messager.send(callee, "Teleported " + entitySelect.stream().findFirst().get().getName() + " to the hub."); } else { - callee.sendMessage(Dreamvisitor.PREFIX + "Teleported " + entitySelect.size() + " entities to the hub."); + Messager.send(callee, "Teleported " + entitySelect.size() + " entities to the hub."); } } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdInvSwap.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdInvSwap.java index 60f3cc0..f9c46d9 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdInvSwap.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdInvSwap.java @@ -5,6 +5,7 @@ import dev.jorel.commandapi.CommandPermission; import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.functions.InvSwap; +import io.github.stonley890.dreamvisitor.functions.Messager; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; @@ -21,7 +22,7 @@ public CommandAPICommand getCommand() { CommandSender callee = sender.getCallee(); if (callee instanceof Player player) { InvSwap.swapInventories(player); - callee.sendMessage(Dreamvisitor.PREFIX + "Your inventory has been swapped!"); + Messager.send(callee, "Your inventory has been swapped!"); } else throw CommandAPI.failWithString("This command can only be executed as a player!"); })); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdMoonglobe.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdMoonglobe.java index 5d066cc..76c3c19 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdMoonglobe.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdMoonglobe.java @@ -10,6 +10,7 @@ import dev.jorel.commandapi.executors.CommandArguments; import dev.jorel.commandapi.wrappers.NativeProxyCommandSender; import io.github.stonley890.dreamvisitor.Dreamvisitor; +import io.github.stonley890.dreamvisitor.functions.Messager; import io.github.stonley890.dreamvisitor.functions.Moonglobe; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -40,7 +41,7 @@ private static String create(@NotNull Collection players, @NotNull Locat if (!alreadyHasGlobe) new Moonglobe(player.getUniqueId(), location, maxDistance); } - return (Dreamvisitor.PREFIX + "Created moon globes for " + players.size() + " players."); + return ("Created moon globes for " + players.size() + " players."); } @@ -66,7 +67,7 @@ public CommandAPICommand getCommand() { } } - sender.sendMessage(Dreamvisitor.PREFIX + "Removed moon globes of " + targets.size() + " players."); + Messager.send(sender, "Removed moon globes of " + targets.size() + " players."); }) ) .withSubcommand(new CommandAPICommand("create") @@ -87,7 +88,7 @@ public CommandAPICommand getCommand() { Object maxDistanceArg = args.get("maxDistance"); if (maxDistanceArg != null) maxDistance = (float) maxDistanceArg; - sender.sendMessage(create(targets, location, maxDistance)); + Messager.send(sender, create(targets, location, maxDistance)); }) .executesNative((sender, args) -> { @@ -128,7 +129,7 @@ public CommandAPICommand getCommand() { Object maxDistanceArg = args.get("maxDistance"); if (maxDistanceArg != null) maxDistance = (float) maxDistanceArg; - sender.sendMessage(create(targets, location, maxDistance)); + Messager.send(sender, create(targets, location, maxDistance)); }) ); } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPanic.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPanic.java index 75c3b0a..b861315 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPanic.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPanic.java @@ -4,6 +4,7 @@ import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.ExecutableCommand; +import io.github.stonley890.dreamvisitor.functions.Messager; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.entity.Player; @@ -26,8 +27,7 @@ public CommandAPICommand getCommand() { .executesNative((sender, args) -> { if (!panicAsked) { panicAsked = true; - sender.sendMessage(Dreamvisitor.PREFIX + - ChatColor.RED + "Are you sure you want to kick all players? Run /panic again to confirm."); + Messager.sendDanger(sender,"Are you sure you want to kick all players? Run /panic again to confirm."); new java.util.Timer().schedule(new TimerTask() { @Override public void run() { diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdParcel.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdParcel.java index bb12a95..dabc021 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdParcel.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdParcel.java @@ -4,9 +4,9 @@ import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; import dev.jorel.commandapi.arguments.*; -import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.data.Tribe; import io.github.stonley890.dreamvisitor.functions.Mail; +import io.github.stonley890.dreamvisitor.functions.Messager; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.ComponentBuilder; import org.bukkit.Location; @@ -53,7 +53,7 @@ public CommandAPICommand getCommand() { Mail.MailLocation mailLocation = new Mail.MailLocation(location, name, weight, tribe); Mail.saveLocation(mailLocation); - sender.sendMessage(Dreamvisitor.PREFIX + "Added location " + name + " at " + location.getX() + " " + location.getY() + " " + location.getZ() + " in world " + Objects.requireNonNull(location.getWorld()).getName() + "."); + Messager.send(sender, "Added location " + name + " at " + location.getX() + " " + location.getY() + " " + location.getZ() + " in world " + Objects.requireNonNull(location.getWorld()).getName() + "."); })) ) .withSubcommand(new CommandAPICommand("remove") @@ -70,14 +70,14 @@ public CommandAPICommand getCommand() { Mail.MailLocation location = Mail.getLocationByName(name); if (location == null) throw CommandAPI.failWithString("Mail location not found."); Mail.removeLocation(location); - sender.sendMessage(Dreamvisitor.PREFIX + "Removed location " + location.getName()); + Messager.send(sender, "Removed location " + location.getName()); }) ) .withSubcommand(new CommandAPICommand("list") .executesNative((sender, args) -> { List locations = Mail.getLocations(); - ComponentBuilder message = new ComponentBuilder(Dreamvisitor.PREFIX + "Mail Locations"); + ComponentBuilder message = new ComponentBuilder("Mail Locations"); for (Mail.MailLocation mailLocation : locations) { message.append("\n").append(mailLocation.getName()).color(net.md_5.bungee.api.ChatColor.YELLOW) @@ -88,7 +88,7 @@ public CommandAPICommand getCommand() { .append("\n Weight: ").append(String.valueOf(mailLocation.getWeight())) .append("\n Home Tribe: ").append(mailLocation.getHomeTribe().getName()); } - sender.spigot().sendMessage(message.create()); + Messager.send(sender, message.create()); }) ) ) @@ -136,19 +136,19 @@ public CommandAPICommand getCommand() { String message = e.getMessage(); switch (message) { case "Player does not have parcel!" -> - player.sendMessage(Dreamvisitor.PREFIX + ChatColor.RED + "You do not have the parcel that is to be delivered!"); + Messager.sendDanger(player, ChatColor.RED + "You do not have the parcel that is to be delivered!"); case "EssentialsX is not currently active!" -> - player.sendMessage(Dreamvisitor.PREFIX + ChatColor.RED + "EssentialsX is not enabled! Contact a staff member!"); + Messager.sendDanger(player, ChatColor.RED + "EssentialsX is not enabled! Contact a staff member!"); case "Not at the destination location!" -> - player.sendMessage(Dreamvisitor.PREFIX + ChatColor.RED + "This is not your delivery location!"); + Messager.sendDanger(player, ChatColor.RED + "This is not your delivery location!"); default -> - player.sendMessage(Dreamvisitor.PREFIX + ChatColor.RED + "There was a problem: " + message + "\nPlease contact a staff member."); + Messager.sendDanger(player, ChatColor.RED + "There was a problem: " + message + "\nPlease contact a staff member."); } return; } } - sender.sendMessage(Dreamvisitor.PREFIX + "Toggled mail for " + players.size() + "."); + Messager.send(sender, "Toggled mail for " + players.size() + "."); }) ) @@ -180,7 +180,7 @@ public CommandAPICommand getCommand() { if (players.isEmpty()) throw CommandAPI.failWithString("No players selected"); add(players, start, end); - sender.sendMessage(Dreamvisitor.PREFIX + "Added " + players.size() + " player(s)."); + Messager.send(sender, "Added " + players.size() + " player(s)."); }) ) @@ -194,17 +194,17 @@ public CommandAPICommand getCommand() { if (players.isEmpty()) throw CommandAPI.failWithString("No players selected"); remove(players); - sender.sendMessage(Dreamvisitor.PREFIX + "Removed " + players.size() + " player(s)."); + Messager.send(sender, "Removed " + players.size() + " player(s)."); }) ) .withSubcommand(new CommandAPICommand("list") .executesNative((sender, args) -> { - StringBuilder message = new StringBuilder(Dreamvisitor.PREFIX); + StringBuilder message = new StringBuilder(); for (Mail.Deliverer deliverer : Mail.getDeliverers()) { message.append(deliverer.getPlayer().getName()).append(" "); } - sender.sendMessage(message.toString()); + Messager.send(sender, message.toString()); }) ) @@ -214,17 +214,17 @@ public CommandAPICommand getCommand() { private void add(@NotNull Collection players, @NotNull Mail.MailLocation start, @NotNull Mail.MailLocation end) { List deliverers = Mail.getDeliverers(); - Dreamvisitor.debug("Size of deliverers: " + deliverers.size()); + Messager.debug("Size of deliverers: " + deliverers.size()); for (Player player : players) { - Dreamvisitor.debug("Adding player " + player.getName()); + Messager.debug("Adding player " + player.getName()); Mail.Deliverer deliverer = new Mail.Deliverer(player, start, end); deliverer.start(); deliverers.add(deliverer); - player.sendMessage(Dreamvisitor.PREFIX + "Deliver this parcel to " + ChatColor.YELLOW + end.getName().replace("_", " ") + ChatColor.WHITE + ".\nRun " + ChatColor.AQUA + "/" + getCommand().getName() + " cancel" + ChatColor.WHITE + " to cancel."); + Messager.send(player, "Deliver this parcel to " + ChatColor.YELLOW + end.getName().replace("_", " ") + ChatColor.WHITE + ".\nRun " + ChatColor.AQUA + "/" + getCommand().getName() + " cancel" + ChatColor.WHITE + " to cancel."); } - Dreamvisitor.debug("Size of deliverers now: " + deliverers.size()); + Messager.debug("Size of deliverers now: " + deliverers.size()); Mail.setDeliverers(deliverers); } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPauseBypass.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPauseBypass.java index e017796..6184422 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPauseBypass.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPauseBypass.java @@ -7,6 +7,7 @@ import dev.jorel.commandapi.arguments.EntitySelectorArgument; import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.data.PlayerUtility; +import io.github.stonley890.dreamvisitor.functions.Messager; import io.github.stonley890.dreamvisitor.functions.PauseBypass; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; @@ -31,7 +32,7 @@ public CommandAPICommand getCommand() { assert players != null; playersList.addAll(players.stream().map(Player::getUniqueId).toList()); PauseBypass.setPlayers(playersList); - sender.sendMessage(Dreamvisitor.PREFIX + "Added " + players.size() + " player(s) to the bypass list."); + Messager.send(sender, "Added " + players.size() + " player(s) to the bypass list."); }) ) .withSubcommand(new CommandAPICommand("remove") @@ -42,7 +43,7 @@ public CommandAPICommand getCommand() { assert players != null; boolean removed = playersList.removeAll(players.stream().map(Player::getUniqueId).toList()); PauseBypass.setPlayers(playersList); - if (removed) sender.sendMessage(Dreamvisitor.PREFIX + "Removed " + players.size() + " player(s) from the bypass list."); + if (removed) Messager.send(sender, "Removed " + players.size() + " player(s) from the bypass list."); else throw CommandAPI.failWithString("No players were removed."); }) ) @@ -55,7 +56,7 @@ public CommandAPICommand getCommand() { if (!list.isEmpty()) list.append(", "); list.append(PlayerUtility.getUsernameOfUuid(player)); } - sender.sendMessage(Dreamvisitor.PREFIX + "Players bypassing: " + list); + Messager.send(sender, "Players bypassing: " + list); }) ); } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPlayerlimit.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPlayerlimit.java index ca88cbc..a2d262c 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPlayerlimit.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPlayerlimit.java @@ -3,6 +3,7 @@ import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; import dev.jorel.commandapi.arguments.IntegerArgument; +import io.github.stonley890.dreamvisitor.functions.Messager; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.entity.Player; @@ -25,7 +26,7 @@ public CommandAPICommand getCommand() { Object newLimitArg = args.get("newLimit"); if (newLimitArg == null) { - sender.sendMessage(Dreamvisitor.PREFIX + ChatColor.WHITE + "Player limit override is currently set to " + Dreamvisitor.playerLimit + "."); + Messager.send(sender, "Player limit override is currently set to " + Dreamvisitor.playerLimit + "."); } else { try { // Change config @@ -43,8 +44,7 @@ public CommandAPICommand getCommand() { plugin.saveConfig(); } catch (NumberFormatException e) { - sender.sendMessage(Dreamvisitor.PREFIX + - ChatColor.RED + "Incorrect arguments! /playerlimit "); + Messager.sendDanger(sender, "Incorrect arguments! /playerlimit "); } } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSandbox.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSandbox.java index e472dc9..a11781f 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSandbox.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSandbox.java @@ -7,6 +7,7 @@ import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.data.PlayerMemory; import io.github.stonley890.dreamvisitor.data.PlayerUtility; +import io.github.stonley890.dreamvisitor.functions.Messager; import io.github.stonley890.dreamvisitor.functions.Sandbox; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.ClickEvent; @@ -44,10 +45,10 @@ public CommandAPICommand getCommand() { } if (sandboxedPlayers.isEmpty()) { - sender.sendMessage(Dreamvisitor.PREFIX + "No players currently online are in sandbox mode. Use /sandbox [true|false] to toggle sandbox mode."); + Messager.send(sender, "No players currently online are in sandbox mode. Use /sandbox [true|false] to toggle sandbox mode."); } - ComponentBuilder messageBuilder = new ComponentBuilder(Dreamvisitor.PREFIX + "Players currently sandboxed:\n"); + ComponentBuilder messageBuilder = new ComponentBuilder("Players currently sandboxed:\n"); HoverEvent tooltip = new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("Click to remove.")); @@ -62,7 +63,7 @@ public CommandAPICommand getCommand() { .append(" in world ").append(Objects.requireNonNull(location.getWorld()).getName()).append(".\n\n"); } - sender.spigot().sendMessage(messageBuilder.create()); + Messager.send(sender, messageBuilder.create()); } else { Object stateArg = args.get("state"); if (stateArg == null) { @@ -70,15 +71,15 @@ public CommandAPICommand getCommand() { if (PlayerUtility.getPlayerMemory(player.getUniqueId()).sandbox) Sandbox.disableSandbox(player); else Sandbox.enableSandbox(player); }); - sender.sendMessage(Dreamvisitor.PREFIX + "Toggled sandbox mode for " + players.size() + " players."); + Messager.send(sender, "Toggled sandbox mode for " + players.size() + " players."); } else { boolean sandboxState = (boolean) stateArg; if (sandboxState) { players.forEach(Sandbox::enableSandbox); - sender.sendMessage(Dreamvisitor.PREFIX + "Enabled sandbox mode for " + players.size() + " players."); + Messager.send(sender, "Enabled sandbox mode for " + players.size() + " players."); } else { players.forEach(Sandbox::disableSandbox); - sender.sendMessage(Dreamvisitor.PREFIX + "Disabled sandbox mode for " + players.size() + " players."); + Messager.send(sender, "Disabled sandbox mode for " + players.size() + " players."); } } } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSchedule.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSchedule.java index bb3c515..a9664f3 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSchedule.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSchedule.java @@ -10,6 +10,7 @@ import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.functions.CommandScheduler; import io.github.stonley890.dreamvisitor.functions.CommandScheduler.Schedule; +import io.github.stonley890.dreamvisitor.functions.Messager; import org.bukkit.ChatColor; import org.jetbrains.annotations.NotNull; @@ -55,10 +56,10 @@ public CommandAPICommand getCommand() { CommandScheduler.getInstance().addSchedule(name, intervalMinutes, commands); if (commands.size() > 1) { - sender.sendMessage(Dreamvisitor.PREFIX + "Added schedule '" + name + "' to run " + commands.size() + + Messager.send(sender, "Added schedule '" + name + "' to run " + commands.size() + " commands every " + intervalMinutes + " minutes."); } else { - sender.sendMessage(Dreamvisitor.PREFIX + "Added schedule '" + name + "' to run '" + commandInput + + Messager.send(sender, "Added schedule '" + name + "' to run '" + commandInput + "' every " + intervalMinutes + " minutes."); } }), @@ -92,15 +93,14 @@ public CommandAPICommand getCommand() { CommandScheduler.getInstance().addDailySchedule(name, time, commands); if (commands.size() > 1) { - sender - .sendMessage(Dreamvisitor.PREFIX + "Added schedule '" + name + "' to run " + commands.size() + + Messager.send(sender, "Added schedule '" + name + "' to run " + commands.size() + " commands daily at " + timeString + "."); } else { - sender.sendMessage(Dreamvisitor.PREFIX + "Added schedule '" + name + "' to run '" + commandInput + + Messager.send(sender, "Added schedule '" + name + "' to run '" + commandInput + "' daily at " + timeString + "."); } } catch (DateTimeParseException e) { - sender.sendMessage(Dreamvisitor.PREFIX + ChatColor.RED + + Messager.sendDanger(sender, "Invalid time format. Please use HH:MM:SS format (e.g., 06:00:00)"); } }), @@ -132,15 +132,13 @@ public CommandAPICommand getCommand() { Schedule schedule = CommandScheduler.getInstance().addCronSchedule(name, pattern, commands); if (schedule == null) { - sender.sendMessage(Dreamvisitor.PREFIX + ChatColor.RED + - "Invalid cron pattern. Format: minute hour day-of-month month day-of-week"); + Messager.sendDanger(sender,"Invalid cron pattern. Format: minute hour day-of-month month day-of-week"); } else { if (commands.size() > 1) { - sender - .sendMessage(Dreamvisitor.PREFIX + "Added schedule '" + name + "' to run " + commands.size() + + Messager.send(sender, "Added schedule '" + name + "' to run " + commands.size() + " commands using cron pattern '" + pattern + "'."); } else { - sender.sendMessage(Dreamvisitor.PREFIX + "Added schedule '" + name + "' to run '" + commandInput + + Messager.send(sender, "Added schedule '" + name + "' to run '" + commandInput + "' using cron pattern '" + pattern + "'."); } } @@ -157,10 +155,9 @@ public CommandAPICommand getCommand() { String name = (String) args.get("name"); if (CommandScheduler.getInstance().removeSchedule(name)) { - sender.sendMessage(Dreamvisitor.PREFIX + "Removed schedule '" + name + "'."); + Messager.send(sender, "Removed schedule '" + name + "'."); } else { - sender.sendMessage( - Dreamvisitor.PREFIX + ChatColor.RED + "No schedule with name '" + name + "' found."); + Messager.sendDanger(sender, "No schedule with name '" + name + "' found."); } }), new CommandAPICommand("list") @@ -169,25 +166,16 @@ public CommandAPICommand getCommand() { .executesNative((sender, args) -> { List schedules = CommandScheduler.getInstance().getSchedules(); if (schedules.isEmpty()) { - sender.sendMessage(Dreamvisitor.PREFIX + "No schedules configured."); + Messager.send(sender, "No schedules configured."); return; } - sender.sendMessage(Dreamvisitor.PREFIX + "Scheduled commands:"); + Messager.send(sender, "Scheduled commands:"); for (Schedule schedule : schedules) { List commands = schedule.getCommands(); - String typeInfo; + String typeInfo = getTypeInfo(schedule); - switch (schedule.getType()) { - case INTERVAL -> typeInfo = "every " + ChatColor.GREEN + schedule.getIntervalMinutes() - + ChatColor.WHITE + " minutes"; - case DAILY -> typeInfo = "daily at " + ChatColor.GREEN + schedule.getDailyTime(); - case CRON -> - typeInfo = "using cron pattern " + ChatColor.GREEN + schedule.getCronPattern().getPattern(); - default -> typeInfo = "unknown schedule type"; - } - - sender.sendMessage(ChatColor.YELLOW + schedule.getName() + ChatColor.WHITE + + Messager.send(sender,ChatColor.YELLOW + schedule.getName() + ChatColor.WHITE + ": " + (commands.size() > 1 ? commands.size() + " commands " : "'" + ChatColor.GRAY + commands.get(0) + ChatColor.WHITE + "' ") @@ -215,10 +203,9 @@ public CommandAPICommand getCommand() { String name = (String) args.get("name"); if (CommandScheduler.getInstance().runScheduleNow(name)) { - sender.sendMessage(Dreamvisitor.PREFIX + "Running schedule '" + name + "' now."); + Messager.send(sender, "Running schedule '" + name + "' now."); } else { - sender.sendMessage( - Dreamvisitor.PREFIX + ChatColor.RED + "No schedule with name '" + name + "' found."); + Messager.sendDanger(sender, "No schedule with name '" + name + "' found."); } }), new CommandAPICommand("add-command") @@ -235,11 +222,9 @@ public CommandAPICommand getCommand() { String command = (String) args.get("command"); if (CommandScheduler.getInstance().addCommand(name, command)) { - sender.sendMessage( - Dreamvisitor.PREFIX + "Added command '" + command + "' to schedule '" + name + "'."); + Messager.send(sender, "Added command '" + command + "' to schedule '" + name + "'."); } else { - sender.sendMessage( - Dreamvisitor.PREFIX + ChatColor.RED + "No schedule with name '" + name + "' found."); + Messager.sendDanger(sender, "No schedule with name '" + name + "' found."); } }), new CommandAPICommand("remove-command") @@ -256,11 +241,10 @@ public CommandAPICommand getCommand() { int index = (int) args.get("index") - 1; // Convert to 0-based index if (CommandScheduler.getInstance().removeCommand(name, index)) { - sender.sendMessage(Dreamvisitor.PREFIX + "Removed command at position " + (index + 1) + Messager.send(sender, "Removed command at position " + (index + 1) + " from schedule '" + name + "'."); } else { - sender.sendMessage( - Dreamvisitor.PREFIX + ChatColor.RED + "No schedule with name '" + name + Messager.sendDanger(sender, "No schedule with name '" + name + "' found or invalid command index."); } }), @@ -282,13 +266,12 @@ public CommandAPICommand getCommand() { // Pass ticks directly to CommandScheduler without conversion if (CommandScheduler.getInstance().addDelay(name, index, delayTicks)) { - sender.sendMessage(Dreamvisitor.PREFIX + "Added " + delayTicks + " tick" + + Messager.send(sender, "Added " + delayTicks + " tick" + (delayTicks == 1 ? "" : "s") + " delay before command " + (index + 1) + " in schedule '" + name + "'. (" + String.format("%.1f", delayTicks / 20.0) + " seconds)"); } else { - sender.sendMessage( - Dreamvisitor.PREFIX + ChatColor.RED + "No schedule with name '" + name + Messager.sendDanger(sender, "No schedule with name '" + name + "' found or invalid command index."); } }), @@ -307,13 +290,27 @@ public CommandAPICommand getCommand() { int index = (int) args.get("index") - 1; // Convert to 0-based index if (CommandScheduler.getInstance().removeDelay(name, index)) { - sender.sendMessage(Dreamvisitor.PREFIX + "Removed delay from command " + (index + 1) + Messager.send(sender,"Removed delay from command " + (index + 1) + " in schedule '" + name + "'."); } else { - sender.sendMessage( - Dreamvisitor.PREFIX + ChatColor.RED + "No schedule with name '" + name + Messager.sendDanger(sender, "No schedule with name '" + name + "' found or no delay was set for this command."); } })); } + + @NotNull + private static String getTypeInfo(@NotNull Schedule schedule) { + String typeInfo; + + switch (schedule.getType()) { + case INTERVAL -> typeInfo = "every " + ChatColor.GREEN + schedule.getIntervalMinutes() + + ChatColor.WHITE + " minutes"; + case DAILY -> typeInfo = "daily at " + ChatColor.GREEN + schedule.getDailyTime(); + case CRON -> + typeInfo = "using cron pattern " + ChatColor.GREEN + schedule.getCronPattern().getPattern(); + default -> typeInfo = "unknown schedule type"; + } + return typeInfo; + } } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdScheduleRestart.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdScheduleRestart.java index 466ad87..3acd600 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdScheduleRestart.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdScheduleRestart.java @@ -4,6 +4,7 @@ import dev.jorel.commandapi.CommandPermission; import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.functions.AutoRestart; +import io.github.stonley890.dreamvisitor.functions.Messager; import org.jetbrains.annotations.NotNull; public class CmdScheduleRestart implements DVCommand { @@ -17,10 +18,10 @@ public CommandAPICommand getCommand() { .executesNative((sender, args) -> { if (AutoRestart.isAutoRestart()) { AutoRestart.disableAutoRestart(); - sender.sendMessage(Dreamvisitor.PREFIX + "Canceled server restart. Run /autorestart again to cancel."); + Messager.send(sender, "Canceled server restart. Run /autorestart again to cancel."); } else { AutoRestart.enableAutoRestart(null); - sender.sendMessage(Dreamvisitor.PREFIX + "The server will restart when there are no players online. Run /autorestart again to cancel."); + Messager.send(sender,"The server will restart when there are no players online. Run /autorestart again to cancel."); } }); } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSetback.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSetback.java index 5297797..616d846 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSetback.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSetback.java @@ -9,6 +9,7 @@ import dev.jorel.commandapi.arguments.*; import dev.jorel.commandapi.wrappers.Rotation; import io.github.stonley890.dreamvisitor.Dreamvisitor; +import io.github.stonley890.dreamvisitor.functions.Messager; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; @@ -76,7 +77,7 @@ public CommandAPICommand getCommand() { user.setLastLocation(location); } - sender.sendMessage(Dreamvisitor.PREFIX + "Set back location to " + location.getBlockX() + ", " + location.getBlockY() + + Messager.send(sender, "Set back location to " + location.getBlockX() + ", " + location.getBlockY() + ", " + location.getBlockZ() + " of " + Objects.requireNonNull(location.getWorld()).getName() + " for " + players.size() + " player(s)."); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSethub.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSethub.java index fb74a2b..fba1254 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSethub.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSethub.java @@ -8,6 +8,7 @@ import dev.jorel.commandapi.arguments.RotationArgument; import dev.jorel.commandapi.arguments.WorldArgument; import dev.jorel.commandapi.wrappers.Rotation; +import io.github.stonley890.dreamvisitor.functions.Messager; import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.World; @@ -64,7 +65,7 @@ public CommandAPICommand getCommand() { Dreamvisitor.hubLocation = location; plugin.getConfig().set("hubLocation", Dreamvisitor.hubLocation); plugin.saveConfig(); - sender.sendMessage(Dreamvisitor.PREFIX + ChatColor.WHITE + "Hub location set."); + Messager.send(sender, "Hub location set."); }); } } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSetmotd.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSetmotd.java index 844a301..8811043 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSetmotd.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSetmotd.java @@ -3,6 +3,7 @@ import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.arguments.GreedyStringArgument; import io.github.stonley890.dreamvisitor.Dreamvisitor; +import io.github.stonley890.dreamvisitor.functions.Messager; import org.jetbrains.annotations.NotNull; public class CmdSetmotd implements DVCommand { @@ -18,14 +19,14 @@ public CommandAPICommand getCommand() { String newMotd = (String) args.get("newMotd"); if (newMotd == null) { Dreamvisitor.MOTD = null; - sender.sendMessage(Dreamvisitor.PREFIX + "Reset MOTD to default:\n" + sender.getServer().getMotd()); - Dreamvisitor.debug("Existing MOTD: " + sender.getServer().getMotd()); + Messager.send(sender, "Reset MOTD to default:\n" + sender.getServer().getMotd()); + Messager.debug("Existing MOTD: " + sender.getServer().getMotd()); } else { String finalMotd = newMotd.replaceAll("&", "§").replaceAll("\\\\n","\n").strip(); Dreamvisitor.MOTD = finalMotd; - sender.sendMessage(Dreamvisitor.PREFIX + "MOTD set to\n" + finalMotd); - Dreamvisitor.debug("New MOTD: " + finalMotd); + Messager.send(sender, "MOTD set to\n" + finalMotd); + Messager.debug("New MOTD: " + finalMotd); } }); } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSoftwhitelist.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSoftwhitelist.java index bc5a3bd..94bfb56 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSoftwhitelist.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSoftwhitelist.java @@ -6,6 +6,7 @@ import dev.jorel.commandapi.arguments.OfflinePlayerArgument; import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.data.PlayerUtility; +import io.github.stonley890.dreamvisitor.functions.Messager; import io.github.stonley890.dreamvisitor.functions.SoftWhitelist; import org.bukkit.ChatColor; import org.bukkit.OfflinePlayer; @@ -33,7 +34,7 @@ public CommandAPICommand getCommand() { if (players.contains(player.getUniqueId())) throw CommandAPI.failWithString("That player is already on the soft whitelist!"); players.add(player.getUniqueId()); SoftWhitelist.setPlayers(players); - sender.sendMessage(Dreamvisitor.PREFIX + "Added " + player.getName() + "."); + Messager.send(sender, "Added " + player.getName() + "."); }) ) .withSubcommand(new CommandAPICommand("remove") @@ -45,7 +46,7 @@ public CommandAPICommand getCommand() { if (!players.contains(player.getUniqueId())) throw CommandAPI.failWithString("That player is not on soft whitelist!"); players.remove(player.getUniqueId()); SoftWhitelist.setPlayers(players); - sender.sendMessage(Dreamvisitor.PREFIX + "Removed " + player.getName() + "."); + Messager.send(sender,"Removed " + player.getName() + "."); }) ) .withSubcommand(new CommandAPICommand("list") @@ -59,21 +60,21 @@ public CommandAPICommand getCommand() { } list.append(PlayerUtility.getUsernameOfUuid(player)); } - sender.sendMessage(Dreamvisitor.PREFIX + ChatColor.WHITE + "Players soft-whitelisted: " + list); + Messager.send(sender, "Players soft-whitelisted: " + list); }) ) .withSubcommand(new CommandAPICommand("on") .executesNative((sender, args) -> { plugin.getConfig().set("softwhitelist", true); plugin.saveConfig(); - sender.sendMessage(Dreamvisitor.PREFIX + ChatColor.WHITE + "Soft whitelist enabled."); + Messager.send(sender,"Soft whitelist enabled."); }) ) .withSubcommand(new CommandAPICommand("off") .executesNative((sender, args) -> { plugin.getConfig().set("softwhitelist", false); plugin.saveConfig(); - sender.sendMessage(Dreamvisitor.PREFIX + ChatColor.WHITE + "Soft whitelist disabled."); + Messager.send(sender, "Soft whitelist disabled."); }) ); } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSynctime.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSynctime.java index c0e3ea4..0862410 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSynctime.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSynctime.java @@ -5,6 +5,7 @@ import dev.jorel.commandapi.CommandPermission; import dev.jorel.commandapi.arguments.WorldArgument; import io.github.stonley890.dreamvisitor.Dreamvisitor; +import io.github.stonley890.dreamvisitor.functions.Messager; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.command.BlockCommandSender; @@ -32,7 +33,7 @@ public CommandAPICommand getCommand() { } else throw CommandAPI.failWithString("World must be specified if it cannot be inferred!"); } for (World world : Bukkit.getWorlds()) world.setFullTime(worldArg.getFullTime()); - sender.sendMessage(Dreamvisitor.PREFIX + "Set all worlds to match " + worldArg.getName() + ": " + worldArg.getFullTime()); + Messager.send(sender, "Set all worlds to match " + worldArg.getName() + ": " + worldArg.getFullTime()); }); } } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdTribeUpdate.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdTribeUpdate.java index 6314e49..9899f7b 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdTribeUpdate.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdTribeUpdate.java @@ -2,22 +2,14 @@ import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; -import dev.jorel.commandapi.ExecutableCommand; import dev.jorel.commandapi.arguments.EntitySelectorArgument; -import io.github.stonley890.dreamvisitor.Bot; import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.data.*; -import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.entities.User; -import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; +import io.github.stonley890.dreamvisitor.functions.Messager; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.entity.Player; -import org.bukkit.scoreboard.Scoreboard; -import org.bukkit.scoreboard.Team; import org.jetbrains.annotations.NotNull; -import java.io.IOException; import java.util.*; public class CmdTribeUpdate implements DVCommand { @@ -34,7 +26,7 @@ public CommandAPICommand getCommand() { assert players != null; // This may take some time - if (sender instanceof Player) sender.sendMessage(Dreamvisitor.PREFIX + "Please wait..."); + if (sender instanceof Player) Messager.send(sender, "Please wait..."); // Run async Bukkit.getScheduler().runTaskAsynchronously(Dreamvisitor.getPlugin(), () -> { @@ -51,13 +43,13 @@ public CommandAPICommand getCommand() { if (playerTribe != null) { // Update LP groups - Dreamvisitor.debug("Updating permissions"); + Messager.debug("Updating permissions"); PlayerTribe.updatePermissions(uuid); } } - Bukkit.getScheduler().runTask(Dreamvisitor.getPlugin(), () -> sender.sendMessage(Dreamvisitor.PREFIX + "Updated " + players.size() + " players.")); + Bukkit.getScheduler().runTask(Dreamvisitor.getPlugin(), () -> Messager.send(sender, "Updated " + players.size() + " players.")); }); }); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdUnwax.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdUnwax.java index 8f214b3..3576d5e 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdUnwax.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdUnwax.java @@ -4,6 +4,7 @@ import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; import io.github.stonley890.dreamvisitor.Dreamvisitor; +import io.github.stonley890.dreamvisitor.functions.Messager; import org.bukkit.FluidCollisionMode; import org.bukkit.Particle; import org.bukkit.block.Block; @@ -28,7 +29,7 @@ public CommandAPICommand getCommand() { sign.setWaxed(false); sign.update(false); sign.getWorld().spawnParticle(Particle.WAX_OFF, sign.getLocation().add(0.5, 0.5, 0.5), 5, 0.2, 0.2, 0.2); - sender.sendMessage(Dreamvisitor.PREFIX + "Wax, be gone!"); + Messager.send(sender, "Wax, be gone!"); } else throw CommandAPI.failWithString("That is not a sign."); } else throw CommandAPI.failWithString("This command must be executed as a player!"); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdUser.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdUser.java index 3455e98..d263695 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdUser.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdUser.java @@ -7,6 +7,7 @@ import io.github.stonley890.dreamvisitor.Bot; import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.data.AccountLink; +import io.github.stonley890.dreamvisitor.functions.Messager; import org.bukkit.ChatColor; import org.bukkit.OfflinePlayer; import org.jetbrains.annotations.NotNull; @@ -41,7 +42,7 @@ public CommandAPICommand getCommand() { } - sender.sendMessage(Dreamvisitor.PREFIX + ChatColor.WHITE + "Local data for player " + player.getName() + ":" + + Messager.send(sender, "Local data for player " + player.getName() + ":" + "\nUUID: " + player.getUniqueId() + "\nDiscord Username: " + discordUsername + "\nDiscord ID: " + discordID diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdVelocity.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdVelocity.java index 2081556..76c9a63 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdVelocity.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdVelocity.java @@ -5,6 +5,7 @@ import dev.jorel.commandapi.CommandPermission; import dev.jorel.commandapi.arguments.*; import io.github.stonley890.dreamvisitor.Dreamvisitor; +import io.github.stonley890.dreamvisitor.functions.Messager; import org.bukkit.Location; import org.bukkit.entity.Entity; import org.jetbrains.annotations.NotNull; @@ -47,7 +48,7 @@ public CommandAPICommand getCommand() { } else { entity.setVelocity(entity.getVelocity().add(force.toVector())); } - sender.sendMessage(Dreamvisitor.PREFIX + "Applied velocity to " + entities.size() + " entities."); + Messager.send(sender, "Applied velocity to " + entities.size() + " entities."); } }); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdZoop.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdZoop.java index d00cb9e..7ce745b 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdZoop.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdZoop.java @@ -7,6 +7,7 @@ import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.data.PlayerMemory; import io.github.stonley890.dreamvisitor.data.PlayerUtility; +import io.github.stonley890.dreamvisitor.functions.Messager; import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; @@ -43,7 +44,7 @@ public CommandAPICommand getCommand() { PlayerUtility.setPlayerMemory(player.getUniqueId(), memory); - sender.sendMessage(Dreamvisitor.PREFIX + ChatColor.WHITE + "Discord vanish toggled to " + memory.vanished + "."); + Messager.send(sender, "Discord vanish toggled to " + memory.vanished + "."); } else throw CommandAPI.failWithString("This command must be executed as a player!"); }); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/AccountLink.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/AccountLink.java index d77af9a..6ef069e 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/AccountLink.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/AccountLink.java @@ -1,8 +1,7 @@ package io.github.stonley890.dreamvisitor.data; -import io.github.stonley890.dreamvisitor.Bot; import io.github.stonley890.dreamvisitor.Dreamvisitor; -import net.dv8tion.jda.api.entities.Role; +import io.github.stonley890.dreamvisitor.functions.Messager; import org.bukkit.Bukkit; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -21,7 +20,7 @@ public class AccountLink { public static void init() throws IOException { // If the file does not exist, create one if (!file.exists()) { - Dreamvisitor.debug("accountLink.txt does not exist. Creating one now..."); + Messager.debug("accountLink.txt does not exist. Creating one now..."); try { if (!file.createNewFile()) throw new IOException("The existence of " + file.getName() + " cannot be verified!", null); } catch (IOException e) { @@ -32,7 +31,7 @@ public static void init() throws IOException { } private static void loadFromFile() { - Dreamvisitor.debug("Loading accountLink.txt"); + Messager.debug("Loading accountLink.txt"); BufferedReader reader; try { reader = new BufferedReader(new FileReader(file)); @@ -56,21 +55,21 @@ private static void loadFromFile() { } public static void saveFile() { - Dreamvisitor.debug("Saving..."); + Messager.debug("Saving..."); BufferedWriter writer; try { writer = new BufferedWriter(new FileWriter(file)); for (Map.Entry entry : uuidToDiscordIdMap.entrySet()) { UUID uuid = entry.getKey(); - Dreamvisitor.debug("UUID for this entry: " + uuid.toString()); + Messager.debug("UUID for this entry: " + uuid.toString()); long discordId = entry.getValue(); - Dreamvisitor.debug("Discord ID for this entry: " + discordId); + Messager.debug("Discord ID for this entry: " + discordId); String data = uuid.toString().replaceAll("-", "") + ":" + discordId; writer.write(data); writer.newLine(); - Dreamvisitor.debug("Line written"); + Messager.debug("Line written"); } writer.close(); } catch (IOException e) { diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/AltFamily.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/AltFamily.java index 0ae5f69..da3da63 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/AltFamily.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/AltFamily.java @@ -1,6 +1,7 @@ package io.github.stonley890.dreamvisitor.data; import io.github.stonley890.dreamvisitor.Dreamvisitor; +import io.github.stonley890.dreamvisitor.functions.Messager; import org.bukkit.Bukkit; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; @@ -27,7 +28,7 @@ public AltFamily(long parentId) { public static void init() throws IOException { // If the file does not exist, create one if (!file.exists()) { - Dreamvisitor.debug("alts.yml does not exist. Creating one now..."); + Messager.debug("alts.yml does not exist. Creating one now..."); try { if (!file.createNewFile()) throw new IOException("The existence of " + file.getName() + " cannot be verified!", null); } catch (IOException e) { @@ -57,14 +58,14 @@ public static void init() throws IOException { } private static void saveToDisk(@NotNull YamlConfiguration config) { - Dreamvisitor.debug("Saving alts.yml..."); + Messager.debug("Saving alts.yml..."); try { config.save(file); } catch (IOException e) { Bukkit.getLogger().severe("alts.yml cannot be written! Does the server have read/write access? " + e.getMessage() + "\nHere is the data that was not saved:\n" + config.saveToString()); Bukkit.getPluginManager().disablePlugin(Dreamvisitor.getPlugin()); } - Dreamvisitor.debug("Done!"); + Messager.debug("Done!"); } /** diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/BadWords.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/BadWords.java index 66f2845..dd11f44 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/BadWords.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/BadWords.java @@ -1,12 +1,12 @@ package io.github.stonley890.dreamvisitor.data; import io.github.stonley890.dreamvisitor.Dreamvisitor; +import io.github.stonley890.dreamvisitor.functions.Messager; import org.bukkit.configuration.file.YamlConfiguration; import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.IOException; -import java.util.ArrayList; import java.util.List; public class BadWords { @@ -16,7 +16,7 @@ public class BadWords { public static void init() throws IOException { // If the file does not exist, create one if (!file.exists()) { - Dreamvisitor.debug(file.getName() + " does not exist. Creating one now..."); + Messager.debug(file.getName() + " does not exist. Creating one now..."); try { if (!file.createNewFile()) throw new IOException("The existence of " + file.getName() + " cannot be verified!", null); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/Economy.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/Economy.java index 004c670..c7ba4c6 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/Economy.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/Economy.java @@ -2,6 +2,7 @@ import io.github.stonley890.dreamvisitor.Bot; import io.github.stonley890.dreamvisitor.Dreamvisitor; +import io.github.stonley890.dreamvisitor.functions.Messager; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Role; @@ -30,7 +31,7 @@ public class Economy { public static void init() throws IOException { // If the file does not exist, create one if (!file.exists()) { - Dreamvisitor.debug(file.getName() + " does not exist. Creating one now..."); + Messager.debug(file.getName() + " does not exist. Creating one now..."); try { if (!file.createNewFile()) throw new IOException("The existence of " + file.getName() + " cannot be verified!", null); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/Infraction.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/Infraction.java index d8f4f53..3edf933 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/Infraction.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/Infraction.java @@ -1,9 +1,9 @@ package io.github.stonley890.dreamvisitor.data; -import dev.jorel.commandapi.wrappers.Time; import io.github.stonley890.dreamvisitor.Bot; import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.discord.commands.DCmdWarn; +import io.github.stonley890.dreamvisitor.functions.Messager; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.Member; @@ -62,7 +62,7 @@ public Infraction(byte infractionValue, @NotNull String infractionReason, @NotNu public static void init() throws IOException { // If the file does not exist, create one if (!file.exists()) { - Dreamvisitor.debug("infractions.yml does not exist. Creating one now..."); + Messager.debug("infractions.yml does not exist. Creating one now..."); try { if (!file.createNewFile()) throw new IOException("The existence of " + file.getName() + " cannot be verified!", null); @@ -87,14 +87,14 @@ public static void init() throws IOException { } private static void saveToDisk(@NotNull YamlConfiguration config) { - Dreamvisitor.debug("Saving infractions.yml..."); + Messager.debug("Saving infractions.yml..."); try { config.save(file); } catch (IOException e) { Bukkit.getLogger().severe("infractions.yml cannot be written! Does the server have read/write access? " + e.getMessage() + "\nHere is the data that was not saved:\n" + config.saveToString()); Bukkit.getPluginManager().disablePlugin(Dreamvisitor.getPlugin()); } - Dreamvisitor.debug("Done!"); + Messager.debug("Done!"); } /** @@ -354,17 +354,17 @@ public TextChannel getWarnChannel() { } public void remind(long user) { - Dreamvisitor.debug("Remind warn. warnChannelId: " + warnChannelID); + Messager.debug("Remind warn. warnChannelId: " + warnChannelID); if (warnChannelID == null) return; TextChannel warnChannel = getWarnChannel(); if (warnChannel == null) return; - Dreamvisitor.debug("Attempting to retrieve last message."); + Messager.debug("Attempting to retrieve last message."); if (!Bot.getGameLogChannel().getGuild().getChannels().contains(warnChannel)) return; warnChannel.retrieveMessageById(warnChannel.getLatestMessageId()).queue(message -> { - Dreamvisitor.debug("Retrieved last message."); - Dreamvisitor.debug("Message author is bot? " + message.getAuthor().equals(Bot.getJda().getSelfUser())); - Dreamvisitor.debug("Time is passed? " + message.getTimeCreated().plusDays(1).isBefore(OffsetDateTime.now())); + Messager.debug("Retrieved last message."); + Messager.debug("Message author is bot? " + message.getAuthor().equals(Bot.getJda().getSelfUser())); + Messager.debug("Time is passed? " + message.getTimeCreated().plusDays(1).isBefore(OffsetDateTime.now())); if (message.getAuthor().equals(Bot.getJda().getSelfUser()) && message.getTimeCreated().plusDays(1).isBefore(OffsetDateTime.now())) { warnChannel.getGuild().retrieveMemberById(user).queue(member -> warnChannel.sendMessage(member.getAsMention() + ", you have not yet responded to this thread. On the first message in this thread, press **I understand** to close the thread or **I'm confused** if you're confused.").queue()); } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PBConfigLoader.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PBConfigLoader.java index 33224f9..b8a1997 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PBConfigLoader.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PBConfigLoader.java @@ -3,6 +3,7 @@ import com.google.gson.JsonObject; import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.functions.AutoRestart; +import io.github.stonley890.dreamvisitor.functions.Messager; import io.github.stonley890.dreamvisitor.pb.PocketBase; import org.bukkit.Bukkit; import org.bukkit.configuration.file.FileConfiguration; @@ -41,7 +42,7 @@ public static void init() { pbConfig.put("pocketbase-token", token); pocketBaseClient = PocketBase.fromConfig(pbConfig); - Dreamvisitor.debug("Initialized PocketBase client"); + Messager.debug("Initialized PocketBase client"); } catch (Exception e) { Bukkit.getLogger().warning("Failed to initialize PocketBase client: " + e.getMessage()); return; @@ -70,7 +71,7 @@ public static void loadConfig() { String jsonString = record.toString(); config = new JSONObject(jsonString); - Dreamvisitor.debug("Loaded PocketBase configuration: " + config.toString()); + Messager.debug("Loaded PocketBase configuration: " + config.toString()); // Apply config values to the system applyConfig(); @@ -101,10 +102,10 @@ private static void applyConfig() { if (autoRestart != AutoRestart.isAutoRestart()) { if (autoRestart) { AutoRestart.enableAutoRestart(null); - Dreamvisitor.debug("Auto restart enabled from remote config"); + Messager.debug("Auto restart enabled from remote config"); } else { AutoRestart.disableAutoRestart(); - Dreamvisitor.debug("Auto restart disabled from remote config"); + Messager.debug("Auto restart disabled from remote config"); } } } @@ -128,7 +129,7 @@ public static CompletableFuture updateConfigField(String field, boolean va // Update the record pocketBaseClient.updateRecord(COLLECTION_NAME, configId, updateData, null, null); - Dreamvisitor.debug("Updated PocketBase configuration field " + field + " to " + value); + Messager.debug("Updated PocketBase configuration field " + field + " to " + value); // If not using realtime updates, we need to reload config manually if (!useRealtime) { diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PlayerTribe.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PlayerTribe.java index 6315a98..27b42b8 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PlayerTribe.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PlayerTribe.java @@ -1,6 +1,7 @@ package io.github.stonley890.dreamvisitor.data; import io.github.stonley890.dreamvisitor.Dreamvisitor; +import io.github.stonley890.dreamvisitor.functions.Messager; import net.luckperms.api.model.user.UserManager; import net.luckperms.api.node.Node; import org.bukkit.Bukkit; @@ -116,29 +117,29 @@ public static void updateTribeOfPlayer(@NotNull UUID uuid) throws NullPointerExc if (username == null) throw new NullPointerException("Player is null"); // Check by team - Dreamvisitor.debug("Checking by team..."); + Messager.debug("Checking by team..."); Tribe[] tribes = Tribe.values(); for (int i = 0; i < tribes.length; i++) { Tribe tribe = tribes[i]; Team team = scoreboard.getTeam(tribe.getTeamName()); - Dreamvisitor.debug("Checking team " + i); + Messager.debug("Checking team " + i); if (team != null && team.hasEntry(username)) { - Dreamvisitor.debug("Found team " + i); + Messager.debug("Found team " + i); playerTribe = i; savePlayer(uuid, tribes[playerTribe]); return; } } - Dreamvisitor.debug("Could not find by team."); + Messager.debug("Could not find by team."); if (online) { // If no matching team, check by tags - Dreamvisitor.debug("Checking by tag..."); + Messager.debug("Checking by tag..."); for (int i = 0; i < tribes.length; i++) { Tribe tribe = tribes[i]; - Dreamvisitor.debug("Checking tag " + i); + Messager.debug("Checking tag " + i); if (player.getScoreboardTags().contains(tribe.getTeamName())) { - Dreamvisitor.debug("Found tag " + i); + Messager.debug("Found tag " + i); playerTribe = i; savePlayer(uuid, tribes[playerTribe]); return; @@ -156,7 +157,7 @@ public static void updateTribeOfPlayer(@NotNull UUID uuid) throws NullPointerExc public static void updatePermissions(@NotNull UUID uuid) { if (Dreamvisitor.luckperms != null) { - Dreamvisitor.debug("[updatePermissions] Updating permissions for user " + uuid + " using info finding"); + Messager.debug("[updatePermissions] Updating permissions for user " + uuid + " using info finding"); Tribe tribe; @@ -165,13 +166,13 @@ public static void updatePermissions(@NotNull UUID uuid) { // Run async if (Dreamvisitor.luckperms != null) { - Dreamvisitor.debug("[updatePermissions] Updating permissions for user " + uuid); + Messager.debug("[updatePermissions] Updating permissions for user " + uuid); // Get user manager UserManager userManager = Dreamvisitor.luckperms.getUserManager(); // Get user at tribe t and position p - Dreamvisitor.debug("[updatePermissions] Updating permissions of UUID " + uuid + " of tribe " + tribe); + Messager.debug("[updatePermissions] Updating permissions of UUID " + uuid + " of tribe " + tribe); // Run async userManager.modifyUser(uuid, user -> { @@ -182,7 +183,7 @@ public static void updatePermissions(@NotNull UUID uuid) { // remove it from player if (tribeName != null) { - Dreamvisitor.debug("[updatePermissions] Removing group " + tribeName + " from " + uuid); + Messager.debug("[updatePermissions] Removing group " + tribeName + " from " + uuid); // Get the group from lp and remove it from the user. user.data().remove(Node.builder("group." + tribeName).build()); @@ -195,7 +196,7 @@ public static void updatePermissions(@NotNull UUID uuid) { String groupName = tribe.getTeamName().toLowerCase(); - Dreamvisitor.debug("[updatePermissions] Adding group " + groupName + " to " + uuid); + Messager.debug("[updatePermissions] Adding group " + groupName + " to " + uuid); // Get the group from lp and add it to the user. user.data().add(Node.builder("group." + groupName).build()); } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/RealtimeConfigUpdater.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/RealtimeConfigUpdater.java index b6c6633..b5b767a 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/RealtimeConfigUpdater.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/RealtimeConfigUpdater.java @@ -1,6 +1,7 @@ package io.github.stonley890.dreamvisitor.data; import io.github.stonley890.dreamvisitor.Dreamvisitor; +import io.github.stonley890.dreamvisitor.functions.Messager; import org.bukkit.Bukkit; import org.json.JSONException; import org.json.JSONObject; @@ -16,7 +17,6 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Consumer; public class RealtimeConfigUpdater { private static ExecutorService executor = Executors.newSingleThreadExecutor(); @@ -44,7 +44,7 @@ public static void startRealtimeUpdates() { } if (baseUrl == null || baseUrl.isEmpty() || configId == null || configId.isEmpty()) { - Dreamvisitor.debug("Cannot start realtime updates: baseUrl or configId is not set"); + Messager.debug("Cannot start realtime updates: baseUrl or configId is not set"); return; } @@ -54,7 +54,7 @@ public static void startRealtimeUpdates() { try { connectSSE(); } catch (Exception e) { - Dreamvisitor.debug("Error in SSE connection: " + e.getMessage()); + Messager.debug("Error in SSE connection: " + e.getMessage()); handleReconnect(); } finally { isConnecting.set(false); @@ -63,7 +63,7 @@ public static void startRealtimeUpdates() { } private static void connectSSE() throws IOException { - Dreamvisitor.debug("Connecting to SSE endpoint"); + Messager.debug("Connecting to SSE endpoint"); URL url = new URL(baseUrl + "/api/realtime"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); @@ -88,11 +88,11 @@ private static void connectSSE() throws IOException { line = reader.readLine(); if (line != null && line.startsWith("data: ")) { clientId = line.substring(6).trim(); - Dreamvisitor.debug("Connected to SSE with client ID: " + clientId); + Messager.debug("Connected to SSE with client ID: " + clientId); setSubscription(); } } else if (line.startsWith("event: PB_DISCONNECT")) { - Dreamvisitor.debug("Received disconnect event from server"); + Messager.debug("Received disconnect event from server"); break; } else if (line.startsWith("event: update")) { // Next line should be data @@ -139,7 +139,7 @@ private static void setSubscription() { int responseCode = connection.getResponseCode(); if (responseCode != HttpURLConnection.HTTP_NO_CONTENT) { - Dreamvisitor.debug("Failed to set subscription: " + responseCode); + Messager.debug("Failed to set subscription: " + responseCode); // Read error response if available if (connection.getErrorStream() != null) { @@ -149,14 +149,14 @@ private static void setSubscription() { while ((line = br.readLine()) != null) { errorResponse.append(line); } - Dreamvisitor.debug("Error response: " + errorResponse.toString()); + Messager.debug("Error response: " + errorResponse.toString()); } } } else { - Dreamvisitor.debug("Successfully subscribed to config updates"); + Messager.debug("Successfully subscribed to config updates"); } } catch (Exception e) { - Dreamvisitor.debug("Error setting subscription: " + e.getMessage()); + Messager.debug("Error setting subscription: " + e.getMessage()); } } @@ -169,7 +169,7 @@ private static void handleUpdateEvent(String data) { // Handle autoRestart field if (record.has("autoRestart")) { boolean autoRestart = record.getBoolean("autoRestart"); - Dreamvisitor.debug("Received real-time update: autoRestart = " + autoRestart); + Messager.debug("Received real-time update: autoRestart = " + autoRestart); // Schedule update on main thread Bukkit.getScheduler().runTask(Dreamvisitor.getPlugin(), () -> { @@ -178,14 +178,14 @@ private static void handleUpdateEvent(String data) { } } } catch (JSONException e) { - Dreamvisitor.debug("Error parsing update event: " + e.getMessage()); + Messager.debug("Error parsing update event: " + e.getMessage()); } } private static void handleReconnect() { if (retryCount < MAX_RETRIES) { retryCount++; - Dreamvisitor.debug("Attempting to reconnect SSE (attempt " + retryCount + "/" + MAX_RETRIES + ")"); + Messager.debug("Attempting to reconnect SSE (attempt " + retryCount + "/" + MAX_RETRIES + ")"); try { Thread.sleep(RETRY_DELAY_MS); @@ -194,7 +194,7 @@ private static void handleReconnect() { Thread.currentThread().interrupt(); } } else { - Dreamvisitor.debug("Max retry attempts reached. Giving up on SSE connection."); + Messager.debug("Max retry attempts reached. Giving up on SSE connection."); // Fallback to polling retryCount = 0; } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/DiscCommandsManager.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/DiscCommandsManager.java index 661a9f2..079d3f0 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/DiscCommandsManager.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/DiscCommandsManager.java @@ -1,8 +1,8 @@ package io.github.stonley890.dreamvisitor.discord; import io.github.stonley890.dreamvisitor.Bot; -import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.discord.commands.*; +import io.github.stonley890.dreamvisitor.functions.Messager; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.entities.Guild; @@ -26,7 +26,7 @@ public class DiscCommandsManager extends ListenerAdapter { @SuppressWarnings({"null"}) public static void init() { - Dreamvisitor.debug("Initializing commands..."); + Messager.debug("Initializing commands..."); List addList = new ArrayList<>(); @@ -58,7 +58,7 @@ public static void init() { addList.add(new DCmdBaltop()); addList.add(new DCmdSeen()); - Dreamvisitor.debug("Ready to add to guild."); + Messager.debug("Ready to add to guild."); addCommands(addList); @@ -84,7 +84,7 @@ public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent even public static void addCommands(@NotNull List commands) { - Dreamvisitor.debug("Request to add " + commands.size() + " commands."); + Messager.debug("Request to add " + commands.size() + " commands."); if (commands.isEmpty()) return; @@ -101,7 +101,7 @@ public static void addCommands(@NotNull List commands) { try { jda.addEventListener(command); } catch (IllegalArgumentException ignored) {} - Dreamvisitor.debug("Added command " + command.getName()); + Messager.debug("Added command " + command.getName()); } } @@ -112,7 +112,7 @@ public static void addCommands(@NotNull List commands) { } } - Dreamvisitor.debug("Updated commands for " + jda.getGuilds().size() + " guild(s)."); + Messager.debug("Updated commands for " + jda.getGuilds().size() + " guild(s)."); commands.removeIf(Objects::isNull); DiscCommandsManager.commands.addAll(commands); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/DiscEventListener.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/DiscEventListener.java index 56475a9..46383af 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/DiscEventListener.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/DiscEventListener.java @@ -4,6 +4,7 @@ import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.data.*; import io.github.stonley890.dreamvisitor.data.Infraction; +import io.github.stonley890.dreamvisitor.functions.Messager; import io.github.stonley890.dreamvisitor.functions.Whitelist; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.Permission; @@ -58,10 +59,10 @@ public void onMessageReceived(@Nonnull MessageReceivedEvent event) { // If in the whitelist channel and username is "legal" try { - Dreamvisitor.debug("Channel ID: " + channel.getId()); - Dreamvisitor.debug("Whitelist ID: " + Bot.getWhitelistChannel().getId()); - Dreamvisitor.debug("Game chat ID: " + Bot.getGameChatChannel().getId()); - Dreamvisitor.debug("Log chat ID: " + Bot.getGameLogChannel().getId()); + Messager.debug("Channel ID: " + channel.getId()); + Messager.debug("Whitelist ID: " + Bot.getWhitelistChannel().getId()); + Messager.debug("Game chat ID: " + Bot.getGameChatChannel().getId()); + Messager.debug("Log chat ID: " + Bot.getGameLogChannel().getId()); if (channel.getId().equals(Bot.getWhitelistChannel().getId()) && !user.isBot() && !p.matcher(username).find()) { EmbedBuilder builder = new EmbedBuilder(); @@ -76,11 +77,11 @@ public void onMessageReceived(@Nonnull MessageReceivedEvent event) { } // Check for valid UUID - Dreamvisitor.debug("Checking for valid UUID"); + Messager.debug("Checking for valid UUID"); UUID uuid = PlayerUtility.getUUIDOfUsername(username); if (uuid == null) { // username does not exist alert - Dreamvisitor.debug("Username does not exist."); + Messager.debug("Username does not exist."); builder.setTitle("❌ `" + username + "` could not be found!") .setDescription("Make sure you type your username exactly as shown in the bottom-right corner of the Minecraft Launcher. You need a paid Minecraft: Java Edition account.") @@ -88,22 +89,22 @@ public void onMessageReceived(@Nonnull MessageReceivedEvent event) { event.getMessage().replyEmbeds(builder.build()).queue(); event.getMessage().addReaction(Emoji.fromFormatted("❌")).queue(); - Dreamvisitor.debug("Failed whitelist."); + Messager.debug("Failed whitelist."); } else { - Dreamvisitor.debug("Got UUID"); + Messager.debug("Got UUID"); // Link accounts if not already linked - Dreamvisitor.debug("Do accounts need to be linked?"); + Messager.debug("Do accounts need to be linked?"); if (AccountLink.getUuid(user.getIdLong()) == null) { - Dreamvisitor.debug("Yes, linking account."); + Messager.debug("Yes, linking account."); AccountLink.linkAccounts(uuid, user.getIdLong()); - Dreamvisitor.debug("Linked."); + Messager.debug("Linked."); } try { if (Whitelist.isUserWhitelisted(uuid)) { - Dreamvisitor.debug("Already whitelisted."); + Messager.debug("Already whitelisted."); builder.setTitle("☑️ `" + username + "` is already whitelisted!") .setDescription("Check <#914620824332435456> for the server address and version.") @@ -111,14 +112,14 @@ public void onMessageReceived(@Nonnull MessageReceivedEvent event) { event.getMessage().replyEmbeds(builder.build()).queue(); event.getMessage().addReaction(Emoji.fromFormatted("☑️")).queue(); - Dreamvisitor.debug("Resolved."); + Messager.debug("Resolved."); } else { - Dreamvisitor.debug("Player is not whitelisted."); + Messager.debug("Player is not whitelisted."); Whitelist.add(username, uuid); // success message - Dreamvisitor.debug("Success."); + Messager.debug("Success."); builder.setTitle("✅ `" + username + "` has been whitelisted!") .setDescription("Check <#914620824332435456> for the server address and version.") @@ -236,7 +237,7 @@ public void onMessageReceived(@Nonnull MessageReceivedEvent event) { if (plugin.getConfig().getBoolean("enable-log-console-commands") && plugin.getConfig().getBoolean("log-console") && Objects.requireNonNull(event.getMember()).hasPermission(Permission.ADMINISTRATOR)) { - Dreamvisitor.debug("Sending console command from log channel..."); + Messager.debug("Sending console command from log channel..."); String message = event.getMessage().getContentRaw(); @@ -437,7 +438,7 @@ private static String[] getResponses(@NotNull MessageReceivedEvent event) { @Override public void onButtonInteraction(@NotNull ButtonInteractionEvent event) { - Dreamvisitor.debug("Button interaction with ID " + event.getButton().getId()); + Messager.debug("Button interaction with ID " + event.getButton().getId()); Button button = event.getButton(); ButtonInteraction interaction = event.getInteraction(); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdBaltop.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdBaltop.java index daa5984..b15a1ac 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdBaltop.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdBaltop.java @@ -8,6 +8,7 @@ import java.util.Objects; import java.util.Optional; +import io.github.stonley890.dreamvisitor.functions.Messager; import org.jetbrains.annotations.NotNull; import io.github.stonley890.dreamvisitor.Dreamvisitor; @@ -36,28 +37,28 @@ public void onCommand(@NotNull SlashCommandInteractionEvent event) { sortedConsumers.sort(Comparator.comparingDouble(Economy.Consumer::getBalance).reversed()); if (Dreamvisitor.debugMode) { - Dreamvisitor.debug("Sorted consumers: "); + Messager.debug("Sorted consumers: "); for (Economy.Consumer sortedConsumer : sortedConsumers) { - Dreamvisitor.debug(sortedConsumer.getId() + ": " + sortedConsumer.getBalance()); + Messager.debug(sortedConsumer.getId() + ": " + sortedConsumer.getBalance()); } } final Economy.Consumer senderConsumer = Economy.getConsumer(event.getUser().getIdLong()); final int senderIndex = sortedConsumers.indexOf(senderConsumer); - Dreamvisitor.debug("Sender index: " + senderIndex); + Messager.debug("Sender index: " + senderIndex); Economy.Consumer aboveSender = null; try { aboveSender = sortedConsumers.get(senderIndex - 1); } catch (IndexOutOfBoundsException ignored) {} - Dreamvisitor.debug("Index above sender: " + (senderIndex - 1) + " id " + (aboveSender != null ? aboveSender.getId() : "null")); + Messager.debug("Index above sender: " + (senderIndex - 1) + " id " + (aboveSender != null ? aboveSender.getId() : "null")); Economy.Consumer belowSender = null; try { belowSender = sortedConsumers.get(senderIndex + 1); } catch (IndexOutOfBoundsException ignored) {} - Dreamvisitor.debug("Index below sender: " + (senderIndex + 1) + " id " + (belowSender != null ? belowSender.getId() : "null")); + Messager.debug("Index below sender: " + (senderIndex + 1) + " id " + (belowSender != null ? belowSender.getId() : "null")); final EmbedBuilder embed = new EmbedBuilder(); embed.setTitle("Top Balances"); @@ -65,7 +66,7 @@ public void onCommand(@NotNull SlashCommandInteractionEvent event) { int numberShown = 10; if (sortedConsumers.size() < numberShown) numberShown = sortedConsumers.size(); - Dreamvisitor.debug("Consumer list size: " + sortedConsumers.size()); + Messager.debug("Consumer list size: " + sortedConsumers.size()); final List retrieveIds = new ArrayList<>(sortedConsumers.subList(0, numberShown).stream().map(Economy.Consumer::getId).toList()); if (aboveSender != null) retrieveIds.add(aboveSender.getId()); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdEconomy.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdEconomy.java index 37d87e8..ea08749 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdEconomy.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdEconomy.java @@ -1,7 +1,7 @@ package io.github.stonley890.dreamvisitor.discord.commands; -import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.data.Economy; +import io.github.stonley890.dreamvisitor.functions.Messager; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Role; @@ -245,7 +245,7 @@ public void onCommand(@NotNull SlashCommandInteractionEvent event) { } case "add" -> { - Dreamvisitor.debug("Call to add."); + Messager.debug("Call to add."); String name = event.getOption("name", OptionMapping::getAsString); if (name == null) { @@ -257,28 +257,28 @@ public void onCommand(@NotNull SlashCommandInteractionEvent event) { event.reply("description cannot be null!").setEphemeral(true).queue(); return; } - Dreamvisitor.debug("Got args."); + Messager.debug("Got args."); if (Economy.getItems().size() >= 25) { event.reply("Only 25 items can exist at a time!").setEphemeral(true).queue(); return; } Economy.ShopItem shopItem = new Economy.ShopItem(name, description); - Dreamvisitor.debug("Created new item."); + Messager.debug("Created new item."); shopItem.ensureUniqueId(); - Dreamvisitor.debug("ID is unique."); + Messager.debug("ID is unique."); int itemId = shopItem.getId(); shopItem.setEnabled(false); - Dreamvisitor.debug("Disabled."); + Messager.debug("Disabled."); Economy.saveItem(shopItem); - Dreamvisitor.debug("Saves."); + Messager.debug("Saves."); EmbedBuilder embed = getEditEmbed(shopItem, Objects.requireNonNull(event.getGuild())); - Dreamvisitor.debug("Got embed."); + Messager.debug("Got embed."); event.reply("The item has been created, but not enabled. Edit it below and set it to enabled when ready.") .addEmbeds(embed.build()).setEphemeral(true).addActionRow(getEditDropdown(itemId).build()).queue(); - Dreamvisitor.debug("Reply queued.."); + Messager.debug("Reply queued.."); } case "remove" -> { @@ -652,7 +652,7 @@ public void onStringSelectInteraction(@NotNull StringSelectInteractionEvent even String id = event.getComponentId(); String[] splitId = id.split("-"); - Dreamvisitor.debug("Got string select menu with id " + id); + Messager.debug("Got string select menu with id " + id); if (event.getSelectedOptions().isEmpty()) return; SelectOption selectedOption = event.getSelectedOptions().get(0); @@ -751,7 +751,7 @@ public void onEntitySelectInteraction(@NotNull EntitySelectInteractionEvent even String id = event.getComponentId(); String[] splitId = id.split("-"); - Dreamvisitor.debug("Got string select menu with id " + id); + Messager.debug("Got string select menu with id " + id); String type = splitId[0]; if (type.equals("item")) { @@ -810,7 +810,7 @@ public void onButtonInteraction(@NotNull ButtonInteractionEvent event) { assert id != null; String[] splitId = id.split("-"); - Dreamvisitor.debug("Got button with id " + id); + Messager.debug("Got button with id " + id); String type = splitId[0]; if (type.equals("item")) { @@ -837,7 +837,7 @@ public void onModalInteraction(@NotNull ModalInteractionEvent event) { String id = event.getModalId(); String[] splitId = id.split("-"); - Dreamvisitor.debug("Got modal with id " + id); + Messager.debug("Got modal with id " + id); String type = splitId[0]; if (type.equals("item")) { diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdInventory.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdInventory.java index a8f93ed..719d240 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdInventory.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdInventory.java @@ -1,7 +1,7 @@ package io.github.stonley890.dreamvisitor.discord.commands; -import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.data.Economy; +import io.github.stonley890.dreamvisitor.functions.Messager; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Mentions; @@ -116,11 +116,11 @@ public void onButtonInteraction(@NotNull ButtonInteractionEvent event) { selectMenu.setPlaceholder("Select an item to gift"); for (Economy.ShopItem item : Economy.getItems()) { if (consumer.getItemQuantity(item.getId()) > 0 && item.isGiftingEnabled()) { - Dreamvisitor.debug("adding " + item.getId() + " to gift list"); + Messager.debug("adding " + item.getId() + " to gift list"); selectMenu.addOption(item.getName(), String.valueOf(item.getId())); } } - Dreamvisitor.debug("selectmenu size: " + selectMenu.getOptions().size()); + Messager.debug("selectmenu size: " + selectMenu.getOptions().size()); if (selectMenu.getOptions().isEmpty()) { event.reply("You do not have any items you can gift.").setEphemeral(true).queue(); return; @@ -231,7 +231,7 @@ public void onStringSelectInteraction(@NotNull StringSelectInteractionEvent even public void onEntitySelectInteraction(@NotNull EntitySelectInteractionEvent event) { String id = event.getSelectMenu().getId(); if (id == null) return; - Dreamvisitor.debug("EntitySelectMenu with ID " + id); + Messager.debug("EntitySelectMenu with ID " + id); Mentions mentions = event.getMentions(); String[] split = id.split("-"); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdLink.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdLink.java index f6262c3..232ae1c 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdLink.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdLink.java @@ -1,8 +1,8 @@ package io.github.stonley890.dreamvisitor.discord.commands; -import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.data.AccountLink; import io.github.stonley890.dreamvisitor.data.PlayerUtility; +import io.github.stonley890.dreamvisitor.functions.Messager; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.User; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; @@ -27,14 +27,14 @@ public class DCmdLink implements DiscordCommand { @Override public void onCommand(@NotNull SlashCommandInteractionEvent event) { - Dreamvisitor.debug("Command requested."); + Messager.debug("Command requested."); User targetUser = Objects.requireNonNull(event.getOption("user")).getAsUser(); - Dreamvisitor.debug("Got user."); + Messager.debug("Got user."); String username = Objects.requireNonNull(event.getOption("username")).getAsString(); - Dreamvisitor.debug("Got username."); + Messager.debug("Got username."); UUID uuid = PlayerUtility.getUUIDOfUsername(username); - Dreamvisitor.debug("Command requested."); + Messager.debug("Command requested."); if (uuid == null) { event.reply("`" + username + "` could not be found!").queue(); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdResourcepackupdate.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdResourcepackupdate.java index 29bef2e..6cc7b89 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdResourcepackupdate.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdResourcepackupdate.java @@ -6,6 +6,7 @@ import com.google.gson.JsonParser; import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.functions.AutoRestart; +import io.github.stonley890.dreamvisitor.functions.Messager; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; import net.dv8tion.jda.api.interactions.commands.build.Commands; @@ -34,21 +35,21 @@ public void onCommand(@NotNull SlashCommandInteractionEvent event) { URL resourcePackURL; try { resourcePackURL = getLatestReleaseURL(Dreamvisitor.getPlugin().getConfig().getString("resourcePackRepo")); - Dreamvisitor.debug("Found URL."); + Messager.debug("Found URL."); } catch (IOException e) { event.reply("Dreamvisitor was unable to find the resource pack URL: " + e.getMessage()).queue(); return; } try { - Dreamvisitor.debug("Attempting to download the resource pack."); + Messager.debug("Attempting to download the resource pack."); HttpURLConnection connection = (HttpURLConnection) resourcePackURL.openConnection(); connection.setRequestMethod("GET"); connection.setReadTimeout(10000); // timeout connection.connect(); if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { - Dreamvisitor.debug("Generating hash."); + Messager.debug("Generating hash."); InputStream is = connection.getInputStream(); MessageDigest sha1 = MessageDigest.getInstance("SHA-1"); byte[] buffer = new byte[1024]; @@ -66,8 +67,8 @@ public void onCommand(@NotNull SlashCommandInteractionEvent event) { } String newHash = hash.toString(); - Dreamvisitor.debug("New hash: " + newHash); - Dreamvisitor.debug("Writing changes to server.properties."); + Messager.debug("New hash: " + newHash); + Messager.debug("Writing changes to server.properties."); try { Properties properties = getProperties(resourcePackURL, newHash); @@ -77,7 +78,7 @@ public void onCommand(@NotNull SlashCommandInteractionEvent event) { properties.store(writer, null); writer.close(); - Dreamvisitor.debug("Success."); + Messager.debug("Success."); event.getHook().editOriginal("The resource pack URL has been updated to " + resourcePackURL + ". The SHA1 hash has been updated to " + newHash + ". The server must restart for changes to take effect. " + "I will restart it automatically when 0 players are online. You can cancel this with `/autorestart`.").queue(); @@ -112,7 +113,7 @@ public void onCommand(@NotNull SlashCommandInteractionEvent event) { private static URL getLatestReleaseURL(String repo) throws IOException { // Create a URL object URL url = new URL("https://api.github.com/repos/" + repo + "/releases/latest"); - Dreamvisitor.debug("Finding latest artifact at " + url); + Messager.debug("Finding latest artifact at " + url); // Open a connection to the URL HttpURLConnection connection = (HttpURLConnection) url.openConnection(); @@ -120,9 +121,9 @@ private static URL getLatestReleaseURL(String repo) throws IOException { connection.setRequestProperty("Accept", "application/json"); // Read the response - Dreamvisitor.debug("Sending request."); + Messager.debug("Sending request."); BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); - Dreamvisitor.debug("Parsing response."); + Messager.debug("Parsing response."); String inputLine; StringBuilder content = new StringBuilder(); while ((inputLine = in.readLine()) != null) { @@ -134,12 +135,12 @@ private static URL getLatestReleaseURL(String repo) throws IOException { connection.disconnect(); // Parse the JSON response using Gson - Dreamvisitor.debug("Converting to JSON."); + Messager.debug("Converting to JSON."); JsonElement jsonElement = JsonParser.parseString(content.toString()); JsonObject jsonObject = jsonElement.getAsJsonObject(); // Access the assets array - Dreamvisitor.debug("Locating assets[0].browser_download_url"); + Messager.debug("Locating assets[0].browser_download_url"); JsonArray assets = jsonObject.getAsJsonArray("assets"); if (!assets.isEmpty()) { // Get the first asset's browser_download_url diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdSeen.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdSeen.java index b619359..8a6b3c9 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdSeen.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdSeen.java @@ -1,9 +1,8 @@ package io.github.stonley890.dreamvisitor.discord.commands; -import com.earth2me.essentials.Essentials; -import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.data.AccountLink; import io.github.stonley890.dreamvisitor.data.PlayerUtility; +import io.github.stonley890.dreamvisitor.functions.Messager; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.User; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; @@ -43,9 +42,9 @@ public void onCommand(@NotNull SlashCommandInteractionEvent event) { event.reply(user.getAsMention() + " does not have a linked Minecraft account.").setEphemeral(true).queue(); return; } - Dreamvisitor.debug("UUID: " + uuid); + Messager.debug("UUID: " + uuid); boolean online = Bukkit.getPlayer(uuid) != null; - Dreamvisitor.debug("Online? " + online); + Messager.debug("Online? " + online); Instant time; try { if (online) { diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdUser.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdUser.java index ba33182..33677c0 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdUser.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdUser.java @@ -1,8 +1,8 @@ package io.github.stonley890.dreamvisitor.discord.commands; -import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.data.AccountLink; import io.github.stonley890.dreamvisitor.data.PlayerUtility; +import io.github.stonley890.dreamvisitor.functions.Messager; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.User; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; @@ -26,9 +26,9 @@ public class DCmdUser implements DiscordCommand { @Override public void onCommand(@NotNull SlashCommandInteractionEvent event) { - Dreamvisitor.debug("Command requested."); + Messager.debug("Command requested."); User targetUser = Objects.requireNonNull(event.getOption("user")).getAsUser(); - Dreamvisitor.debug("Target user: " + targetUser.getId()); + Messager.debug("Target user: " + targetUser.getId()); // UUID from AccountLink.yml UUID uuid; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/CommandScheduler.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/CommandScheduler.java index 685eca9..2f2dad1 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/CommandScheduler.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/CommandScheduler.java @@ -18,7 +18,6 @@ import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; -import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; public class CommandScheduler { @@ -249,7 +248,7 @@ private void checkSchedules() { * @param schedule The schedule to execute */ private void executeSchedule(Schedule schedule) { - Dreamvisitor.debug("Executing scheduled commands for: " + schedule.getName()); + Messager.debug("Executing scheduled commands for: " + schedule.getName()); final AtomicBoolean success = new AtomicBoolean(true); List commands = schedule.getCommands(); @@ -269,7 +268,7 @@ private void executeSchedule(Schedule schedule) { } Bukkit.getScheduler().runTaskLater(Dreamvisitor.getPlugin(), () -> { - Dreamvisitor.debug("Executing command " + (index + 1) + "/" + commands.size() + ": " + command); + Messager.debug("Executing command " + (index + 1) + "/" + commands.size() + ": " + command); try { boolean result = Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command); if (!result) { diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Flight.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Flight.java index 26bb861..5f7a683 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Flight.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Flight.java @@ -131,7 +131,7 @@ public static void setupFlight(@NotNull Player player) { // Re-enable flight if it gets disabled by game mode change // Dreamvisitor.debug("FlightNotAllowed: " + !player.getAllowFlight() + " Permission: " + player.hasPermission("dreamvisitor.fly") + " NotRestricted: " + !isFlightRestricted(player) + " NotDepleted: " + !isPlayerDepleted(player) + " NotDisabled: " + !PlayerUtility.getPlayerMemory(player.getUniqueId()).flightDisabled); if (!player.getAllowFlight() && player.hasPermission("dreamvisitor.fly") && !isFlightRestricted(player) && !isPlayerDepleted(player) && !PlayerUtility.getPlayerMemory(player.getUniqueId()).flightDisabled) { - Dreamvisitor.debug("All requirements met for flight."); + Messager.debug("All requirements met for flight."); Bukkit.getScheduler().runTaskLater(Dreamvisitor.getPlugin(), () -> player.setAllowFlight(true), 1); } } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Mail.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Mail.java index 1735a26..9e488ff 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Mail.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Mail.java @@ -43,7 +43,7 @@ public class Mail { public static void init() throws IOException { // If the file does not exist, create one if (!file.exists()) { - Dreamvisitor.debug(file.getName() + " does not exist. Creating one now..."); + Messager.debug(file.getName() + " does not exist. Creating one now..."); try { if (!file.createNewFile()) throw new IOException("The existence of " + file.getName() + " cannot be verified!", null); @@ -140,15 +140,15 @@ public static MailLocation getLocationByName(String name) { public static MailLocation getNearestLocation(@NotNull Location queryLocation) { double shortestDistance = 50000.0; MailLocation nearest = null; - Dreamvisitor.debug("Getting nearest MailLocation to " + queryLocation); + Messager.debug("Getting nearest MailLocation to " + queryLocation); for (MailLocation location : getLocations()) { - Dreamvisitor.debug("Checking " + location.getName()); + Messager.debug("Checking " + location.getName()); if (!Objects.equals(location.getLocation().getWorld(), queryLocation.getWorld())) continue; - Dreamvisitor.debug("Same world."); + Messager.debug("Same world."); double distance = location.getLocation().distance(queryLocation); - Dreamvisitor.debug("Distance: " + distance); + Messager.debug("Distance: " + distance); if (distance < shortestDistance) { - Dreamvisitor.debug("New nearest!"); + Messager.debug("New nearest!"); nearest = location; shortestDistance = distance; } @@ -222,7 +222,7 @@ public static double complete(Player player) throws Exception { if (nearestLocation == null) throw new Exception("No nearest location found!"); if (!player.getWorld().equals(nearestLocation.location.getWorld())) throw new Exception("Not in same world!"); double distance = player.getLocation().distance(nearestLocation.location); - Dreamvisitor.debug("Distance to nearest: " + distance); + Messager.debug("Distance to nearest: " + distance); if (distance > 10) throw new Exception("Not close enough to MailLocation!"); PlayerInventory inventory = player.getInventory(); @@ -239,14 +239,14 @@ public static double complete(Player player) throws Exception { player.getInventory().remove(deliverer.parcel); - Dreamvisitor.debug("Removed from activeDeliverers: " + activeDeliverers.remove(deliverer)); + Messager.debug("Removed from activeDeliverers: " + activeDeliverers.remove(deliverer)); return reward; } public static void cancel(@NotNull Player player) { activeDeliverers.removeIf(deliverer -> deliverer.player.equals(player)); - player.sendMessage(Dreamvisitor.PREFIX + "You canceled your delivery."); + Messager.send(player, "You canceled your delivery."); } public static boolean isPLayerDeliverer(@NotNull Player player) { @@ -255,51 +255,51 @@ public static boolean isPLayerDeliverer(@NotNull Player player) { @NotNull public static MailLocation chooseDeliveryLocation(@NotNull MailLocation startPos) throws InvalidConfigurationException { - Dreamvisitor.debug("Max distance:" + maxDistance); + Messager.debug("Max distance:" + maxDistance); List locations = getLocations(); - Dreamvisitor.debug("Removed start pos:" + locations.remove(startPos)); + Messager.debug("Removed start pos:" + locations.remove(startPos)); if (locations.isEmpty()) throw new InvalidConfigurationException("There aren't enough mail locations!"); // Compute the total weight of all items together. // This can be skipped of course if sum is already 1. double totalWeight = 0.0; for (MailLocation location : locations) { - Dreamvisitor.debug("\nEvaluating " + location.getName()); + Messager.debug("\nEvaluating " + location.getName()); double weight = calculateWeight(startPos, location); totalWeight += weight; - Dreamvisitor.debug("Weight: " + weight); + Messager.debug("Weight: " + weight); } - Dreamvisitor.debug("Total weight: " + totalWeight); + Messager.debug("Total weight: " + totalWeight); // Now choose a random item. double countWeight = 0.0; double r = Math.random() * totalWeight; - Dreamvisitor.debug("random value: " + r); + Messager.debug("random value: " + r); for (int index = 0; index < locations.size() - 1; ++index) { MailLocation evalLocation = locations.get(index); - Dreamvisitor.debug("\nLocation at index " + index + ": " + evalLocation.getName()); + Messager.debug("\nLocation at index " + index + ": " + evalLocation.getName()); double weight = calculateWeight(startPos, evalLocation); countWeight += weight; - Dreamvisitor.debug("New countWeight: " + countWeight); + Messager.debug("New countWeight: " + countWeight); if (countWeight >= r) { - Dreamvisitor.debug(countWeight + " >= " + r + ", returning."); + Messager.debug(countWeight + " >= " + r + ", returning."); return evalLocation; } - Dreamvisitor.debug("countWeight < random"); + Messager.debug("countWeight < random"); } - Dreamvisitor.debug("Selecting last, " + locations.get(locations.size() -1).getName()); + Messager.debug("Selecting last, " + locations.get(locations.size() -1).getName()); return locations.get(locations.size() -1); } private static double calculateWeight(@NotNull MailLocation startLoc, @NotNull MailLocation location) { - Dreamvisitor.debug("Base weight: " + location.getWeight()); - Dreamvisitor.debug("Distance weight multiplier: " + getDistanceWeightMultiplier()); - Dreamvisitor.debug("Maxdist: " + maxDistance); + Messager.debug("Base weight: " + location.getWeight()); + Messager.debug("Distance weight multiplier: " + getDistanceWeightMultiplier()); + Messager.debug("Maxdist: " + maxDistance); double distance = MailLocation.getDistance(startLoc, location); - Dreamvisitor.debug("distance: " + distance); - Dreamvisitor.debug("Maxdist - distance: " + (maxDistance - distance)); - Dreamvisitor.debug("that divided by maxdist: " + ((maxDistance - distance) / maxDistance)); + Messager.debug("distance: " + distance); + Messager.debug("Maxdist - distance: " + (maxDistance - distance)); + Messager.debug("that divided by maxdist: " + ((maxDistance - distance) / maxDistance)); return location.getWeight() + getDistanceWeightMultiplier() * ((maxDistance - distance) / maxDistance); } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Messager.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Messager.java index c1acade..c7d41da 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Messager.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Messager.java @@ -1,37 +1,58 @@ package io.github.stonley890.dreamvisitor.functions; +import io.github.stonley890.dreamvisitor.Dreamvisitor; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.ComponentBuilder; -import org.bukkit.entity.Player; +import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; import java.awt.*; public class Messager { - static final Color PREFIX_COLOR = Color.decode("#3B3BD1"); - static final Color MESSAGE_COLOR = Color.decode("#C9C9FB"); + public static final Color PREFIX_COLOR = Color.decode("#3B3BD1"); + public static final Color MESSAGE_COLOR = Color.decode("#C9C9FB"); + public static final Color DANGER_COLOR = Color.decode("#E0505B"); static final String PREFIX = ChatColor.of(PREFIX_COLOR) + "✧ "; /** - * Send a {@link String} message to a player. - * @param player the player to send the message to. + * Send a {@link String} message to a target. + * @param target the target to send the message to. * @param message the message to send. */ - public static void send(@NotNull Player player, String message) { - player.sendMessage(PREFIX + ChatColor.of(MESSAGE_COLOR) + message); + public static void send(@NotNull CommandSender target, String message) { + target.sendMessage(PREFIX + ChatColor.of(MESSAGE_COLOR) + message); } /** - * Send a {@link BaseComponent} message to a player. - * @param player the player to send the message to. + * Send a {@link BaseComponent} message to a target. + * @param target the target to send the message to. * @param message the message to send. */ - public static void send(@NotNull Player player, BaseComponent[] message) { + public static void send(@NotNull CommandSender target, BaseComponent[] message) { ComponentBuilder builder = new ComponentBuilder(); builder.append(PREFIX).append(message).color(ChatColor.of(MESSAGE_COLOR)); - player.spigot().sendMessage(builder.build()); + target.spigot().sendMessage(builder.build()); + } + + /** + * Send a {@link String} message to a target with a color that indicates danger. + * @param target the target to send the message to. + * @param message the message to send. + */ + public static void sendDanger(@NotNull CommandSender target, String message) { + target.sendMessage(PREFIX + ChatColor.of(DANGER_COLOR) + message); + } + + /** + * Log a {@link String} message to the console if the debug mode is enabled. + * @param message the message to log. + */ + public static void debug(String message) { + if (Dreamvisitor.getPlugin().getConfig().getBoolean("debug")) { + Dreamvisitor.getPlugin().getLogger().info("DEBUG: " + message); + } } } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Sandbox.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Sandbox.java index 6da1251..cfc3b03 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Sandbox.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Sandbox.java @@ -105,7 +105,7 @@ public void onPlayerInteractEntity (@NotNull PlayerInteractEntityEvent event) { if (event.getRightClicked() instanceof ItemFrame) { for (Player onlinePlayer : Bukkit.getServer().getOnlinePlayers()) { if (onlinePlayer.hasPermission("dreamvisitor.sandbox")) { - onlinePlayer.sendMessage(Dreamvisitor.PREFIX + event.getPlayer().getName() + " interacted with an item frame with held item " + Objects.requireNonNull(player.getInventory().getItem(event.getHand())).getType()); + Messager.send(onlinePlayer, event.getPlayer().getName() + " interacted with an item frame with held item " + Objects.requireNonNull(player.getInventory().getItem(event.getHand())).getType()); } } } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Whitelist.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Whitelist.java index ed5e1b3..21a1af3 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Whitelist.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Whitelist.java @@ -30,22 +30,22 @@ public class Whitelist extends ListenerAdapter { private static @NotNull JSONArray get() throws IOException { // Access whitelist.json file - Dreamvisitor.debug("Trying to access whitelist file"); + Messager.debug("Trying to access whitelist file"); String whitelistPath = Bukkit.getServer().getWorldContainer().getPath() + "/whitelist.json"; // Parse whitelist.json to a string list List lines = Files.readAllLines(new File(whitelistPath).toPath()); - Dreamvisitor.debug("Success"); + Messager.debug("Success"); // Format the string list to StringBuilder StringBuilder fileString = new StringBuilder(); for (String line : lines) { fileString.append(line); } - Dreamvisitor.debug("Strings joined to StringBuilder"); + Messager.debug("Strings joined to StringBuilder"); // Format string to JSONArray JSONArray whitelist = new JSONArray(fileString.toString()); - Dreamvisitor.debug("String Builder parsed as JSON"); + Messager.debug("String Builder parsed as JSON"); return whitelist; } @@ -68,30 +68,30 @@ public static boolean isUserWhitelisted(@NotNull UUID uuid) throws IOException { */ public static void add(@NotNull String username, @NotNull UUID uuid) throws IOException { - Dreamvisitor.debug("Adding " + username + " to the whitelist."); + Messager.debug("Adding " + username + " to the whitelist."); JSONArray whitelist = get(); // Create entry - Dreamvisitor.debug("Creating entry..."); + Messager.debug("Creating entry..."); JSONObject whitelistEntry = new JSONObject(); whitelistEntry.put("uuid", uuid.toString()); whitelistEntry.put("name", username); // Add to whitelist.json - Dreamvisitor.debug("Adding to JSON..."); + Messager.debug("Adding to JSON..."); whitelist.put(whitelistEntry); // Write to whitelist.json file - Dreamvisitor.debug("Attempting to write to file..."); + Messager.debug("Attempting to write to file..."); Files.writeString(new File(Bukkit.getServer().getWorldContainer().getPath() + "/whitelist.json").toPath(), whitelist.toString(4)); - Dreamvisitor.debug("Success."); + Messager.debug("Success."); // reload whitelist - Dreamvisitor.debug("Reloading whitelist"); + Messager.debug("Reloading whitelist"); Bukkit.reloadWhitelist(); - Dreamvisitor.debug("Whitelist reloaded"); + Messager.debug("Whitelist reloaded"); } /** @@ -102,7 +102,7 @@ public static void add(@NotNull String username, @NotNull UUID uuid) throws IOEx */ public static void remove(@NotNull String username, @NotNull UUID uuid) throws IOException { - Dreamvisitor.debug("Removing " + username + " to the whitelist."); + Messager.debug("Removing " + username + " to the whitelist."); JSONArray whitelist = get(); @@ -110,24 +110,24 @@ public static void remove(@NotNull String username, @NotNull UUID uuid) throws I for (int i = 0; i < whitelist.length(); i++) { JSONObject object = (JSONObject) whitelist.get(i); - Dreamvisitor.debug("Checking " + object.get("uuid") + " with " + uuid); + Messager.debug("Checking " + object.get("uuid") + " with " + uuid); if (object.get("uuid").equals(uuid.toString())) { - Dreamvisitor.debug("Found match! " + whitelist.remove(i)); + Messager.debug("Found match! " + whitelist.remove(i)); } } // Write to whitelist.json file - Dreamvisitor.debug("Attempting to write to file..."); + Messager.debug("Attempting to write to file..."); Files.writeString(new File(Bukkit.getServer().getWorldContainer().getPath() + "/whitelist.json").toPath(), whitelist.toString(4)); - Dreamvisitor.debug("Success."); + Messager.debug("Success."); // reload whitelist - Dreamvisitor.debug("Reloading whitelist"); + Messager.debug("Reloading whitelist"); Bukkit.reloadWhitelist(); - Dreamvisitor.debug("Whitelist reloaded"); + Messager.debug("Whitelist reloaded"); } public static void startWeb(int port) { @@ -144,17 +144,17 @@ public static void startWeb(int port) { Spark.post("/process-username", (request, response) -> { String username = request.queryParams("username"); - Dreamvisitor.debug("Username from web form: " + username); + Messager.debug("Username from web form: " + username); // Process the username boolean success = processUsername(username); - Dreamvisitor.debug("Processed. Success: " + success); + Messager.debug("Processed. Success: " + success); // Send a response back to the web page - Dreamvisitor.debug("response.header"); + Messager.debug("response.header"); response.type("application/json"); - Dreamvisitor.debug("response.type"); + Messager.debug("response.type"); return "{\"success\": " + success + "}"; }); } @@ -166,33 +166,33 @@ public static void stopWeb() { private static boolean processUsername(@NotNull String username) throws IOException { // Check for valid UUID - Dreamvisitor.debug("Checking for valid UUID"); + Messager.debug("Checking for valid UUID"); UUID uuid = PlayerUtility.getUUIDOfUsername(username); if (uuid == null) { // username does not exist alert - Dreamvisitor.debug("Username does not exist."); - Dreamvisitor.debug("Failed whitelist."); + Messager.debug("Username does not exist."); + Messager.debug("Failed whitelist."); } else { - Dreamvisitor.debug("Got UUID"); + Messager.debug("Got UUID"); // No account to link // Check if already whitelisted - Dreamvisitor.debug("Is user already whitelisted?"); + Messager.debug("Is user already whitelisted?"); if (isUserWhitelisted(uuid)) { - Dreamvisitor.debug("Already whitelisted."); - Dreamvisitor.debug("Resolved."); + Messager.debug("Already whitelisted."); + Messager.debug("Resolved."); return true; } else { - Dreamvisitor.debug("Player is not whitelisted."); + Messager.debug("Player is not whitelisted."); add(username, uuid); // success message - Dreamvisitor.debug("Success."); + Messager.debug("Success."); report(username, uuid, null); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerCmdPreprocess.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerCmdPreprocess.java index d5d2bbb..717f234 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerCmdPreprocess.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerCmdPreprocess.java @@ -6,6 +6,7 @@ import io.github.stonley890.dreamvisitor.data.PlayerUtility; import io.github.stonley890.dreamvisitor.functions.Mail; +import io.github.stonley890.dreamvisitor.functions.Messager; import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; import org.bukkit.Bukkit; import org.bukkit.configuration.InvalidConfigurationException; @@ -118,7 +119,7 @@ public void onPlayerCommandPreprocess(@NotNull PlayerCommandPreprocessEvent even if (Mail.isPLayerDeliverer(player)) Mail.cancel(player); for (Player sandboxer : Bukkit.getOnlinePlayers()) { if (PlayerUtility.getPlayerMemory(sandboxer.getUniqueId()).sandbox && cmd.contains(sandboxer.getName())) { - player.sendMessage(Dreamvisitor.PREFIX + "That player is currently in Sandbox Mode. Teleportation is not allowed."); + Messager.send(player, "That player is currently in Sandbox Mode. Teleportation is not allowed."); event.setCancelled(true); } } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerJoin.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerJoin.java index 39d0fd7..7f768c9 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerJoin.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerJoin.java @@ -6,6 +6,7 @@ import io.github.stonley890.dreamvisitor.data.PlayerTribe; import io.github.stonley890.dreamvisitor.data.PlayerUtility; import io.github.stonley890.dreamvisitor.data.Tribe; +import io.github.stonley890.dreamvisitor.functions.Messager; import io.github.stonley890.dreamvisitor.functions.Sandbox; import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; import net.luckperms.api.model.user.User; @@ -65,7 +66,7 @@ public void onPlayerJoinEvent(@NotNull PlayerJoinEvent event) { for (Player onlinePlayer : Bukkit.getServer().getOnlinePlayers()) { if (onlinePlayer.hasPermission("dreamvisitor.sandbox")) { sandboxerOnline = true; - onlinePlayer.sendMessage(Dreamvisitor.PREFIX + player.getName() + " is currently in sandbox mode."); + Messager.send(onlinePlayer, player.getName() + " is currently in sandbox mode."); } } if (!sandboxerOnline) Sandbox.disableSandbox(player); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerLogin.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerLogin.java index 3c10372..a467ad5 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerLogin.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerLogin.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.util.List; +import io.github.stonley890.dreamvisitor.functions.Messager; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.configuration.InvalidConfigurationException; @@ -33,8 +34,7 @@ public void onPlayerLoginEvent(@NotNull PlayerLoginEvent event) { // Remind bot login failure to ops if (Dreamvisitor.botFailed && player.isOp()) { - player.sendMessage(Dreamvisitor.PREFIX + ChatColor.RED + - "Bot login failed on server start! You may need a new login token."); + Messager.sendDanger(player,"Bot login failed on server start! You may need a new login token."); } event.allow(); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerQuit.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerQuit.java index f365219..3659181 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerQuit.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerQuit.java @@ -2,6 +2,7 @@ import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.data.PlayerMemory; +import io.github.stonley890.dreamvisitor.functions.Messager; import io.github.stonley890.dreamvisitor.functions.Sandbox; import net.md_5.bungee.api.ChatColor; import org.bukkit.Bukkit; @@ -34,7 +35,7 @@ public void onPlayerQuitEvent(@NotNull PlayerQuitEvent event) { if (memory.sandbox) { for (Player onlinePlayer : Bukkit.getServer().getOnlinePlayers()) { if (onlinePlayer.hasPermission("dreamvisitor.sandbox")) { - onlinePlayer.sendMessage(Dreamvisitor.PREFIX + event.getPlayer().getName() + " left while in sandbox mode."); + Messager.send(onlinePlayer, event.getPlayer().getName() + " left while in sandbox mode."); } } } @@ -46,28 +47,28 @@ public void onPlayerQuitEvent(@NotNull PlayerQuitEvent event) { Bukkit.getLogger().severe("Unable to save player memory! Does the server have write access? Player memory will remain in memory. " + e.getMessage()); } - Dreamvisitor.debug("Checking sandbox."); + Messager.debug("Checking sandbox."); Bukkit.getScheduler().runTask(Dreamvisitor.getPlugin(), () -> { - Dreamvisitor.debug("Task start."); + Messager.debug("Task start."); // Check for sandboxed players boolean moderatorOnline = false; for (Player onlinePlayer : Bukkit.getOnlinePlayers()) { - Dreamvisitor.debug("Is " + onlinePlayer.getName() + " moderator?"); + Messager.debug("Is " + onlinePlayer.getName() + " moderator?"); if (onlinePlayer.hasPermission("dreamvisitor.sandbox")) { - Dreamvisitor.debug("Yes! All good."); + Messager.debug("Yes! All good."); moderatorOnline = true; break; } } if (!moderatorOnline) { - Dreamvisitor.debug("No mods online! Gotta disable sandboxed."); + Messager.debug("No mods online! Gotta disable sandboxed."); for (Player onlinePlayer : Bukkit.getOnlinePlayers()) { - Dreamvisitor.debug("Is " + onlinePlayer + " sandboxed?"); + Messager.debug("Is " + onlinePlayer + " sandboxed?"); if (PlayerUtility.getPlayerMemory(onlinePlayer.getUniqueId()).sandbox) { - Dreamvisitor.debug("Yes. Disabling."); + Messager.debug("Yes. Disabling."); Sandbox.disableSandbox(onlinePlayer); onlinePlayer.sendMessage("You are no longer in Sandbox Mode because there are no sandbox managers available."); } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerRespawn.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerRespawn.java index 486705b..63842d7 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerRespawn.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerRespawn.java @@ -1,7 +1,7 @@ package io.github.stonley890.dreamvisitor.listeners; -import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.functions.Flight; +import io.github.stonley890.dreamvisitor.functions.Messager; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerRespawnEvent; @@ -11,7 +11,7 @@ public class ListenPlayerRespawn implements Listener { @EventHandler public void onPlayerRespawn(@NotNull PlayerRespawnEvent event) { - Dreamvisitor.debug("Respawn"); + Messager.debug("Respawn"); // Reset energy Flight.energy.put(event.getPlayer(), Flight.energyCapacity); Flight.setPlayerDepleted(event.getPlayer(), false); From a79525e289621bdad458148aefd3731042811ecd Mon Sep 17 00:00:00 2001 From: Bog Date: Thu, 26 Jun 2025 12:52:19 -0700 Subject: [PATCH 07/39] Implement string count system --- dreamvisitor/pom.xml | 2 +- .../dreamvisitor/commands/CmdMoonglobe.java | 7 +- .../dreamvisitor/commands/CmdParcel.java | 4 +- .../dreamvisitor/commands/CmdPauseBypass.java | 4 +- .../dreamvisitor/commands/CmdSandbox.java | 6 +- .../dreamvisitor/commands/CmdSchedule.java | 27 ++---- .../dreamvisitor/commands/CmdTribeUpdate.java | 2 +- .../dreamvisitor/commands/CmdVelocity.java | 2 +- .../dreamvisitor/functions/Messager.java | 97 ++++++++++++++++--- 9 files changed, 104 insertions(+), 47 deletions(-) diff --git a/dreamvisitor/pom.xml b/dreamvisitor/pom.xml index 51ba752..08f1377 100644 --- a/dreamvisitor/pom.xml +++ b/dreamvisitor/pom.xml @@ -104,7 +104,7 @@ dev.jorel commandapi-bukkit-shade - 9.7.0 + 10.1.0 compile diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdMoonglobe.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdMoonglobe.java index 76c3c19..4dd6764 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdMoonglobe.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdMoonglobe.java @@ -6,10 +6,8 @@ import dev.jorel.commandapi.arguments.EntitySelectorArgument; import dev.jorel.commandapi.arguments.FloatArgument; import dev.jorel.commandapi.arguments.LocationArgument; -import dev.jorel.commandapi.arguments.LongArgument; import dev.jorel.commandapi.executors.CommandArguments; import dev.jorel.commandapi.wrappers.NativeProxyCommandSender; -import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.functions.Messager; import io.github.stonley890.dreamvisitor.functions.Moonglobe; import org.bukkit.Bukkit; @@ -17,14 +15,11 @@ import org.bukkit.World; import org.bukkit.command.BlockCommandSender; import org.bukkit.command.CommandSender; -import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; import java.util.Collection; -import java.util.List; import java.util.Objects; public class CmdMoonglobe implements DVCommand { @@ -67,7 +62,7 @@ public CommandAPICommand getCommand() { } } - Messager.send(sender, "Removed moon globes of " + targets.size() + " players."); + Messager.send(sender, "Removed moon globes of " + Messager.nameOrCountPlayer(targets) + "."); }) ) .withSubcommand(new CommandAPICommand("create") diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdParcel.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdParcel.java index dabc021..8450bf8 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdParcel.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdParcel.java @@ -180,7 +180,7 @@ public CommandAPICommand getCommand() { if (players.isEmpty()) throw CommandAPI.failWithString("No players selected"); add(players, start, end); - Messager.send(sender, "Added " + players.size() + " player(s)."); + Messager.send(sender, "Added " + Messager.nameOrCountPlayer(players) + "."); }) ) @@ -194,7 +194,7 @@ public CommandAPICommand getCommand() { if (players.isEmpty()) throw CommandAPI.failWithString("No players selected"); remove(players); - Messager.send(sender, "Removed " + players.size() + " player(s)."); + Messager.send(sender, "Removed " + Messager.nameOrCountPlayer(players) + "."); }) ) diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPauseBypass.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPauseBypass.java index 6184422..3817381 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPauseBypass.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPauseBypass.java @@ -32,7 +32,7 @@ public CommandAPICommand getCommand() { assert players != null; playersList.addAll(players.stream().map(Player::getUniqueId).toList()); PauseBypass.setPlayers(playersList); - Messager.send(sender, "Added " + players.size() + " player(s) to the bypass list."); + Messager.send(sender, "Added " + Messager.nameOrCountPlayer(players) + " to the bypass list."); }) ) .withSubcommand(new CommandAPICommand("remove") @@ -43,7 +43,7 @@ public CommandAPICommand getCommand() { assert players != null; boolean removed = playersList.removeAll(players.stream().map(Player::getUniqueId).toList()); PauseBypass.setPlayers(playersList); - if (removed) Messager.send(sender, "Removed " + players.size() + " player(s) from the bypass list."); + if (removed) Messager.send(sender, "Removed " + Messager.nameOrCountPlayer(players) + " from the bypass list."); else throw CommandAPI.failWithString("No players were removed."); }) ) diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSandbox.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSandbox.java index a11781f..64eb43d 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSandbox.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSandbox.java @@ -71,15 +71,15 @@ public CommandAPICommand getCommand() { if (PlayerUtility.getPlayerMemory(player.getUniqueId()).sandbox) Sandbox.disableSandbox(player); else Sandbox.enableSandbox(player); }); - Messager.send(sender, "Toggled sandbox mode for " + players.size() + " players."); + Messager.send(sender, "Toggled sandbox mode for " + Messager.nameOrCountPlayer(players) + "."); } else { boolean sandboxState = (boolean) stateArg; if (sandboxState) { players.forEach(Sandbox::enableSandbox); - Messager.send(sender, "Enabled sandbox mode for " + players.size() + " players."); + Messager.send(sender, "Enabled sandbox mode for " + Messager.nameOrCountPlayer(players) + "."); } else { players.forEach(Sandbox::disableSandbox); - Messager.send(sender, "Disabled sandbox mode for " + players.size() + " players."); + Messager.send(sender, "Disabled sandbox mode for " + Messager.nameOrCountPlayer(players) + "."); } } } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSchedule.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSchedule.java index a9664f3..c6c5a55 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSchedule.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSchedule.java @@ -55,13 +55,9 @@ public CommandAPICommand getCommand() { } CommandScheduler.getInstance().addSchedule(name, intervalMinutes, commands); - if (commands.size() > 1) { - Messager.send(sender, "Added schedule '" + name + "' to run " + commands.size() + - " commands every " + intervalMinutes + " minutes."); - } else { - Messager.send(sender, "Added schedule '" + name + "' to run '" + commandInput + - "' every " + intervalMinutes + " minutes."); - } + Messager.send(sender, "Added schedule '" + name + "' to run " + + Messager.nameOrCountString(commands.stream().map(cmd -> "\"".concat(cmd).concat("\"")).toList(), "command", "commands") + + " every " + intervalMinutes + " minutes."); }), new CommandAPICommand("daily") .withPermission(CommandPermission.fromString("dreamvisitor.schedule")) @@ -92,13 +88,10 @@ public CommandAPICommand getCommand() { } CommandScheduler.getInstance().addDailySchedule(name, time, commands); - if (commands.size() > 1) { - Messager.send(sender, "Added schedule '" + name + "' to run " + commands.size() + + Messager.send(sender, "Added schedule '" + name + "' to run " + + Messager.nameOrCountString(commands.stream().map(cmd -> "\"".concat(cmd).concat("\"")).toList(), "command", "commands") + " commands daily at " + timeString + "."); - } else { - Messager.send(sender, "Added schedule '" + name + "' to run '" + commandInput + - "' daily at " + timeString + "."); - } + } catch (DateTimeParseException e) { Messager.sendDanger(sender, "Invalid time format. Please use HH:MM:SS format (e.g., 06:00:00)"); @@ -134,13 +127,9 @@ public CommandAPICommand getCommand() { if (schedule == null) { Messager.sendDanger(sender,"Invalid cron pattern. Format: minute hour day-of-month month day-of-week"); } else { - if (commands.size() > 1) { - Messager.send(sender, "Added schedule '" + name + "' to run " + commands.size() + + Messager.send(sender, "Added schedule '" + name + "' to run " + + Messager.nameOrCountString(commands.stream().map(cmd -> "\"".concat(cmd).concat("\"")).toList(), "command", "commands") + " commands using cron pattern '" + pattern + "'."); - } else { - Messager.send(sender, "Added schedule '" + name + "' to run '" + commandInput + - "' using cron pattern '" + pattern + "'."); - } } }), new CommandAPICommand("remove") diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdTribeUpdate.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdTribeUpdate.java index 9899f7b..40af8bd 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdTribeUpdate.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdTribeUpdate.java @@ -49,7 +49,7 @@ public CommandAPICommand getCommand() { } } - Bukkit.getScheduler().runTask(Dreamvisitor.getPlugin(), () -> Messager.send(sender, "Updated " + players.size() + " players.")); + Bukkit.getScheduler().runTask(Dreamvisitor.getPlugin(), () -> Messager.send(sender, "Updated " + Messager.nameOrCountPlayer(players) + ".")); }); }); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdVelocity.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdVelocity.java index 76c9a63..b15ac65 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdVelocity.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdVelocity.java @@ -48,7 +48,7 @@ public CommandAPICommand getCommand() { } else { entity.setVelocity(entity.getVelocity().add(force.toVector())); } - Messager.send(sender, "Applied velocity to " + entities.size() + " entities."); + Messager.send(sender, "Applied velocity to " + Messager.chooseCountForm(entities, "entity", "entities") + "."); } }); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Messager.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Messager.java index c7d41da..49f84a6 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Messager.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Messager.java @@ -5,9 +5,11 @@ import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.ComponentBuilder; import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import java.awt.*; +import java.util.Collection; public class Messager { @@ -19,7 +21,8 @@ public class Messager { /** * Send a {@link String} message to a target. - * @param target the target to send the message to. + * + * @param target the target to send the message to. * @param message the message to send. */ public static void send(@NotNull CommandSender target, String message) { @@ -27,10 +30,11 @@ public static void send(@NotNull CommandSender target, String message) { } /** - * Send a {@link BaseComponent} message to a target. - * @param target the target to send the message to. - * @param message the message to send. - */ + * Send a {@link BaseComponent} message to a target. + * + * @param target the target to send the message to. + * @param message the message to send. + */ public static void send(@NotNull CommandSender target, BaseComponent[] message) { ComponentBuilder builder = new ComponentBuilder(); builder.append(PREFIX).append(message).color(ChatColor.of(MESSAGE_COLOR)); @@ -38,21 +42,90 @@ public static void send(@NotNull CommandSender target, BaseComponent[] message) } /** - * Send a {@link String} message to a target with a color that indicates danger. - * @param target the target to send the message to. - * @param message the message to send. - */ + * Send a {@link String} message to a target with a color that indicates danger. + * + * @param target the target to send the message to. + * @param message the message to send. + */ public static void sendDanger(@NotNull CommandSender target, String message) { target.sendMessage(PREFIX + ChatColor.of(DANGER_COLOR) + message); } /** * Log a {@link String} message to the console if the debug mode is enabled. + * * @param message the message to log. */ public static void debug(String message) { - if (Dreamvisitor.getPlugin().getConfig().getBoolean("debug")) { - Dreamvisitor.getPlugin().getLogger().info("DEBUG: " + message); - } + if (Dreamvisitor.getPlugin().getConfig().getBoolean("debug")) { + Dreamvisitor.getPlugin().getLogger().info("DEBUG: " + message); + } + } + + /** + * Get the name of a {@link Collection} of {@link Player}s. + * + * @param targets the {@link Collection} of {@link Player}s. + * @return the name of the {@link Collection} of {@link Player)s. + */ + @NotNull + public static String nameOrCountPlayer(@NotNull Collection targets) { + if (targets.size() == 1) { + return targets.iterator().next().getName(); + } + return chooseCountForm(targets, "player ", "players"); + } + + /** + * Get the name of a {@link Collection} of {@link String}s. + * + * @param targets the {@link Collection} of {@link String}s. + * @return the name of the {@link Collection} of {@link String)s. + */ + @NotNull + public static String nameOrCountString(@NotNull Collection targets, String singular, String plural) { + if (targets.size() == 1) { + return targets.iterator().next(); + } + return chooseCountForm(targets, singular, plural); + } + + /** + * Get a natural {@link String} representation of the number of a {@link Collection}. Sizes between 0 and 20 are + * represented by name. All others are represented by number. If the size is one, the singular form is used. + * + * @param collection the {@link Collection to be counted}. + * @param singular the singular form. + * @param plural the plural form. + * @return the {@link String} representation. + */ + @NotNull + public static String chooseCountForm(@NotNull Collection collection, String singular, String plural) { + int size = collection.size(); + if (size == 1) { + return "one " + singular; + } + if (size < 20) { + if (size == 0) return "zero " + plural; + if (size == 2) return "two " + plural; + if (size == 3) return "three " + plural; + if (size == 4) return "four " + plural; + if (size == 5) return "five " + plural; + if (size == 6) return "six " + plural; + if (size == 7) return "seven " + plural; + if (size == 8) return "eight " + plural; + if (size == 9) return "nine " + plural; + if (size == 10) return "ten " + plural; + if (size == 11) return "eleven " + plural; + if (size == 12) return "twelve " + plural; + if (size == 13) return "thirteen " + plural; + if (size == 14) return "fourteen " + plural; + if (size == 15) return "fifteen " + plural; + if (size == 16) return "sixteen " + plural; + if (size == 17) return "seventeen " + plural; + if (size == 18) return "eighteen " + plural; + return "nineteen " + plural; + } + return size + " " + plural; } } From c116c03a2d4b2916f7377de684326b588b552801 Mon Sep 17 00:00:00 2001 From: Bog Date: Thu, 26 Jun 2025 13:06:34 -0700 Subject: [PATCH 08/39] Auto-cleanup code --- .../io/github/stonley890/dreamvisitor/Dreamvisitor.java | 4 ++-- .../github/stonley890/dreamvisitor/commands/CmdDvset.java | 4 ++-- .../io/github/stonley890/dreamvisitor/commands/CmdHub.java | 3 +-- .../github/stonley890/dreamvisitor/data/PBConfigLoader.java | 2 +- .../stonley890/dreamvisitor/data/RealtimeConfigUpdater.java | 6 +++--- .../data/repository/PocketBaseUserRepository.java | 2 +- .../stonley890/dreamvisitor/functions/CommandScheduler.java | 2 +- .../io/github/stonley890/dreamvisitor/pb/PocketBase.java | 2 +- 8 files changed, 12 insertions(+), 13 deletions(-) diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Dreamvisitor.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Dreamvisitor.java index d4787ae..6ab8187 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Dreamvisitor.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Dreamvisitor.java @@ -339,7 +339,7 @@ public void run() { public void run() { Messager.debug("Checking warns to be reminded."); Map> infractions = Infraction.getAllInfractions(); - Messager.debug("Got list of " + infractions.keySet().size() + " members."); + Messager.debug("Got list of " + infractions.size() + " members."); for (Long l : infractions.keySet()) { Messager.debug("Checking infractions of user " + l); List userInfractions = Infraction.getInfractions(l); @@ -406,7 +406,7 @@ public void run() { if (ex.getErrorCode() == 50007) { getLogger().warning("Unable to send Discord DM to user: " + ex.getMessage() + ". User may have DMs disabled or is not in a shared server."); - getLogger().severe("Error message that would have been sent: " + builder.toString()); + getLogger().severe("Error message that would have been sent: " + builder); } else { throw ex; } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDvset.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDvset.java index 7546b8a..126ec44 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDvset.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDvset.java @@ -117,7 +117,7 @@ public CommandTree getCommand() { })) .then(new StringArgument("option") .setOptional(true) - .executesNative((NativeCommandExecutor) ((sender, args) -> { + .executesNative((sender, args) -> { String option = (String) args.get("option"); CommandSender callee = sender.getCallee(); @@ -165,7 +165,7 @@ public CommandTree getCommand() { default -> throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); } - })) + }) .then(new StringArgument("modification") .setOptional(true) .executesNative(((sender, args) -> { diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdHub.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdHub.java index 9f3fbbe..bf8aec6 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdHub.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdHub.java @@ -81,7 +81,7 @@ public CommandAPICommand getCommand() { } } else { - if (callee instanceof Player) { + if (callee instanceof Player player) { if (plugin.getConfig().getLocation("hubLocation") == null) { throw CommandAPI.failWithString("No hub is currently set!"); } else { @@ -89,7 +89,6 @@ public CommandAPICommand getCommand() { Dreamvisitor.hubLocation = plugin.getConfig().getLocation("hubLocation"); assert Dreamvisitor.hubLocation != null; - Player player = (Player) callee; if (Mail.isPLayerDeliverer(player)) Mail.cancel(player); Essentials ess = (Essentials) Bukkit.getPluginManager().getPlugin("Essentials"); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PBConfigLoader.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PBConfigLoader.java index b8a1997..5fe86e0 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PBConfigLoader.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PBConfigLoader.java @@ -71,7 +71,7 @@ public static void loadConfig() { String jsonString = record.toString(); config = new JSONObject(jsonString); - Messager.debug("Loaded PocketBase configuration: " + config.toString()); + Messager.debug("Loaded PocketBase configuration: " + config); // Apply config values to the system applyConfig(); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/RealtimeConfigUpdater.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/RealtimeConfigUpdater.java index b5b767a..a5af4b0 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/RealtimeConfigUpdater.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/RealtimeConfigUpdater.java @@ -19,11 +19,11 @@ import java.util.concurrent.atomic.AtomicBoolean; public class RealtimeConfigUpdater { - private static ExecutorService executor = Executors.newSingleThreadExecutor(); + private static final ExecutorService executor = Executors.newSingleThreadExecutor(); private static String baseUrl; private static String configId; private static String token; - private static String collectionName = "dreamvisitor_config"; + private static final String collectionName = "dreamvisitor_config"; private static String clientId; private static final AtomicBoolean isRunning = new AtomicBoolean(false); private static final AtomicBoolean isConnecting = new AtomicBoolean(false); @@ -149,7 +149,7 @@ private static void setSubscription() { while ((line = br.readLine()) != null) { errorResponse.append(line); } - Messager.debug("Error response: " + errorResponse.toString()); + Messager.debug("Error response: " + errorResponse); } } } else { diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseUserRepository.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseUserRepository.java index 7cbc01b..a05f65d 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseUserRepository.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseUserRepository.java @@ -88,7 +88,7 @@ public Optional findBySnowflakeId(Long snowflakeId) { } catch (IOException e) { // First search failed, try with just string comparison if numeric search fails LOGGER.info("No exact match found, trying alternative search..."); - filter = "discord_id ~ '" + snowflakeId.toString() + "'"; + filter = "discord_id ~ '" + snowflakeId + "'"; try { JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); LOGGER.info("User found with partial match: " + record.toString()); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/CommandScheduler.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/CommandScheduler.java index 2f2dad1..92357e1 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/CommandScheduler.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/CommandScheduler.java @@ -29,7 +29,7 @@ public class CommandScheduler { // how frequent to run the Scheduler checks // unit is in Game Tick // For 20 game ticks is one sec - private long updateTick = 20L * 5L; + private final long updateTick = 20L * 5L; private CommandScheduler() { // Initialize config file diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/PocketBase.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/PocketBase.java index 987bdb0..2fffdee 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/PocketBase.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/PocketBase.java @@ -100,7 +100,7 @@ private String executeRequest(String method, String endpoint, @Nullable RequestB requestBuilder.patch(body != null ? body : RequestBody.create(new byte[0], null)); break; case "DELETE": - requestBuilder.delete(body != null ? body : null); + requestBuilder.delete(body); break; default: throw new IllegalArgumentException("Unsupported HTTP method: " + method); From 628103e740dbdc28cde5897ace3be48978f9d19d Mon Sep 17 00:00:00 2001 From: Bog Date: Sun, 29 Jun 2025 15:03:10 -0700 Subject: [PATCH 09/39] Use pocketbase info for config --- .../dreamvisitor/data/PBConfigLoader.java | 16 +- dreamvisitor/src/main/resources/config.yml | 197 +----------------- 2 files changed, 14 insertions(+), 199 deletions(-) diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PBConfigLoader.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PBConfigLoader.java index 5fe86e0..4486ddb 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PBConfigLoader.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PBConfigLoader.java @@ -7,6 +7,8 @@ import io.github.stonley890.dreamvisitor.pb.PocketBase; import org.bukkit.Bukkit; import org.bukkit.configuration.file.FileConfiguration; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; import org.json.JSONObject; import java.io.IOException; @@ -25,10 +27,10 @@ public class PBConfigLoader { public static void init() { FileConfiguration pluginConfig = Dreamvisitor.getPlugin().getConfig(); - baseUrl = pluginConfig.getString("pocketbase-url", ""); - configId = pluginConfig.getString("pocketbase-config-id", ""); - token = pluginConfig.getString("pocketbase-token", ""); - useRealtime = pluginConfig.getBoolean("pocketbase-use-realtime", true); + baseUrl = pluginConfig.getString("pocketbaseUrl", "http://127.0.0.1:8090/"); + configId = pluginConfig.getString("pocketbaseConfigId", ""); + token = pluginConfig.getString("pocketbaseToken", ""); + useRealtime = pluginConfig.getBoolean("pocketbaseUseRealtime", true); if (baseUrl.isEmpty() || configId.isEmpty()) { Bukkit.getLogger().warning("PocketBase URL or config ID not configured in plugin config."); @@ -60,7 +62,7 @@ public static void init() { public static void loadConfig() { try { if (pocketBaseClient == null) { - Bukkit.getLogger().warning("PocketBase client not initialized, cannot load config"); + Dreamvisitor.getPlugin().getLogger().warning("PocketBase client not initialized, cannot load config"); return; } @@ -114,6 +116,8 @@ private static void applyConfig() { } } + @NotNull + @Contract("_, _ -> new") public static CompletableFuture updateConfigField(String field, boolean value) { return CompletableFuture.runAsync(() -> { try { @@ -136,7 +140,7 @@ public static CompletableFuture updateConfigField(String field, boolean va loadConfig(); } } catch (IOException e) { - Bukkit.getLogger().warning("Error updating PocketBase config: " + e.getMessage()); + Dreamvisitor.getPlugin().getLogger().warning("Error updating PocketBase config: " + e.getMessage()); } }); } diff --git a/dreamvisitor/src/main/resources/config.yml b/dreamvisitor/src/main/resources/config.yml index aa8623c..c254437 100644 --- a/dreamvisitor/src/main/resources/config.yml +++ b/dreamvisitor/src/main/resources/config.yml @@ -1,193 +1,4 @@ -# Whether to enable debug messages. -# This will send additional messages to help debug Dreamvisitor. -# Default: false -debug: false - -# The Dreamvisitor bot token. DO NOT SHARE THIS. -# Dreamvisitor will not work properly unless this is a valid bot token. -# Ask Bog for a bot token if Dreamvisitor reports a login error on startup. -# Default: BOT_TOKEN -bot-token: BOT_TOKEN - -# Website URL -# The URL for the whitelisting website. -# Used to restrict requests not from the specified website to prevent abuse. -# Default: "https://www.woftnw.org" -website-url: "https://www.woftnw.org" - -# Whether web whitelisting is enabled or not -# This can be set with the /toggleweb Discord command. -# Default: true -web-whitelist: true - -# The channel ID of the game chat. -# This can be set on Discord with /setgamechat -# Default: 880269118975119410 -chatChannelID: 880269118975119410 - -# The channel ID of the log chat. -# This can be set on Discord /setlogchat -# Default: 1114730320068104262 -logChannelID: 1114730320068104262 - -# The channel ID of the whitelist chat. -# This can be set on Discord /setwhitelist -# Default: 858461513991323688 -whitelistChannelID: 858461513991323688 - -# The role IDs of tribes on the main server. -# This can be set on Discord with /setrole -triberoles: - - 964773117803249694 - - 660599218439716906 - - 964773289203490837 - - 660599477622669312 - - 660599843093348392 - - 660599418344439842 - - 660600003315761172 - - 660599559654735893 - - 964773212321882132 - - 660599708145942581 - -# Whether chat is paused or not. -# This can be toggled in Minecraft with /pausechat -# Default: false -chatPaused: false - -# Whether the soft whitelist is enabled or not -# This can be set in Minecraft with /softwhitelist [on|off] -# Default: false -softwhitelist: false - -# Player limit override. This will override the player limit, both over and under. -# This can be set in Minecraft with /playerlimit -# Default: -1 -playerlimit: -1 - -# Whether to globally disable pvp or not. -# This can be toggled in Minecraft with /togglepvp -# Default: false -disablepvp: false - -# The location of the recorded hub. -# This should be set in Minecraft with /sethub -# Default: none -hubLocation: none - -# Whether to copy the output of the console to the Discord log channel. -# This will disable the default Dreamvisitor logging in place of the Minecraft server console. -# Default: false -log-console: false - -# Whether to pass messages in the log channel as console commands. -# If log-console is enabled, this will take messages sent by users with the Discord administrator permission and pass -# them as console commands. -# Default: false -enable-log-console-commands: false - -# The amount of time in days (as an integer) that infractions take to expire. -# Expired infractions are not deleted, but they do not count toward a total infraction count. -# Default: 90 -infraction-expire-time-days: 90 - -# The ID of the category to create infractions channels. -# They will accumulate here. -# Default: 1226180189604544593 -infractions-category-id: 1226180189604544593 - -# The name of the Discord shop. -# This will appear at the top of the embed. -# Default: "Shop" -shopName: "Shop" - -# The icon used for currency in the Discord economy system. -# This can be any string, including symbols, letters, emojis, and Discord custom emoji. -# Default: "$" -currencyIcon: "$" - -# The base amount given by the /daily Discord command. -# This is the default amount before adding the streak bonus. The total amount is decided by dailyBaseAmount + (user's streak * this). -# Default: 10.00 -dailyBaseAmount: 10.00 - -# The multiplier of the streak bonus given by the /daily command. -# This is multiplied by the streak and added to the base amount. The total amount is decided by dailyBaseAmount + (user's streak * this). -# Default: 5.00 -dailyStreakMultiplier: 5.00 - -# The amount gained from the /work command. -# /work can only be run every hour. -# Default: 20.00 -workReward: 20.00 - -# The multiplier of the distance weight when choosing mail delivery locations. -# Takes the ratio (between 0 and 1) of the distance to the maximum distance between locations, -# multiplies it by this value, and adds it to the mail location weight. -# This weight is used to randomly choose a mail location to deliver to provide a realistic -# relationship between delivery locations. -# At 0, distance has no effect on location selection. -# At 1, the weight will have a slight effect on the location selection. -# At 10, the weight will have a significant effect on the location selection. -# The weight is applied inversely, making closer distances worth more than further distances. -# Default: 1.00 -mailDeliveryLocationSelectionDistanceWeightMultiplier: 1.00 - -# Mail delivery reward is calculated by multiplying the distance by this number. -# The result is then rounded to the nearest ten. -# At 0, the reward given is 0. -# At 1, the reward given will be the distance in blocks. -# Default: 0.05 -mailDistanceToRewardMultiplier: 0.05 - -# The repository path of the server resource pack. -# Dreamvisitor will pull the first artifact from the latest release on pack update. -# Default: "WOFTNW/Dragonspeak" -resourcePackRepo: "WOFTNW/Dragonspeak" - -# The port to use to accept web whitelist requests. -# Default: 10826 -whitelistPort: 10826 - -# The maximum amount of flight energy. -# Default: 400 -flightEnergyCapacity: 400 - -# The point after energy depletion that flight is possible again. -# Default: 200.00 -flightRegenerationPoint: 200.00 - -# The rate at which energy is regenerated per tick. -# Default: 1.00 -flightEnergyRegeneration: 1.00 - -# The rate at which movement on the X and Y axes depletes energy while flying. -# Default: 4.00 -flightEnergyDepletionXYMultiplier: 4.00 - -# The rate at which movement on the Y axes depletes energy while flying. -# Default: 10.00 -flightEnergyDepletionYMultiplier: 10.00 - -# The message sent if a Wither is built in a region where the wither flag is denied. -# Default: "Withers cannot be spawned here. You can only spawn Withers in the Wither chamber." -noWitherNotice: "Withers cannot be spawned here. You can only spawn Withers in the Wither chamber." - -# The days a player can be offline until the inactivity tax applies. -# Default: 60 -daysUntilInactiveTax: 60 - -# The percent to tax inactive players, between 0.0 and 1.0 -# Default: 0.1 -inactiveTaxPercent: 0.1 - -# The time in days between inactivity taxes. 0 to disable. -# Default: 7 -inactiveDayFrequency: 7 - -# The lowest a balance can be depleted to by inactivity taxes. -# Default: 50000 -inactiveTaxStop: 50000 - -# The last time the inactive tax occurred. This should not be manually tampered with. -# Default: 0 -lastInactiveTax: 0 +pocketbaseUrl: "http://127.0.0.1:8090/" +pocketbaseConfigId: "" +pocketbaseToken: "" +pocketbaseUseRealtime: true \ No newline at end of file From c1db5cc58db2a08e6794989cefa53ac53e1ae213 Mon Sep 17 00:00:00 2001 From: Bog Date: Sun, 29 Jun 2025 16:48:49 -0700 Subject: [PATCH 10/39] Use PBConfig and remove bot functionality --- .../github/stonley890/dreamvisitor/Bot.java | 193 ---- .../stonley890/dreamvisitor/Dreamvisitor.java | 186 +--- .../dreamvisitor/commands/CmdChatback.java | 25 +- .../dreamvisitor/commands/CmdDvset.java | 8 +- .../dreamvisitor/commands/CmdItemBanList.java | 3 +- .../dreamvisitor/commands/CmdPanic.java | 5 +- .../dreamvisitor/commands/CmdPausechat.java | 9 +- .../dreamvisitor/commands/CmdUser.java | 7 +- .../dreamvisitor/commands/CmdZoop.java | 14 +- .../dreamvisitor/data/AccountLink.java | 126 --- .../dreamvisitor/data/AltFamily.java | 214 ----- .../data/{PBConfigLoader.java => Config.java} | 29 +- .../stonley890/dreamvisitor/data/Economy.java | 871 ----------------- .../dreamvisitor/data/Infraction.java | 400 -------- .../data/RealtimeConfigUpdater.java | 2 +- .../data/repository/AltRepository.java | 2 - .../data/repository/InfractionRepository.java | 2 - .../repository/PocketBaseAltRepository.java | 5 - .../PocketBaseInfractionRepository.java | 3 - .../dreamvisitor/data/type/Alt.java | 117 --- .../dreamvisitor/data/type/Infraction.java | 110 --- .../discord/DiscCommandsManager.java | 122 --- .../discord/DiscEventListener.java | 743 --------------- .../discord/commands/DCmdActivity.java | 59 -- .../discord/commands/DCmdAlts.java | 159 ---- .../discord/commands/DCmdAutorestart.java | 60 -- .../discord/commands/DCmdBalance.java | 46 - .../discord/commands/DCmdBaltop.java | 124 --- .../discord/commands/DCmdBroadcast.java | 52 - .../discord/commands/DCmdDaily.java | 50 - .../discord/commands/DCmdEconomy.java | 897 ------------------ .../discord/commands/DCmdEcostats.java | 44 - .../discord/commands/DCmdInfractions.java | 159 ---- .../discord/commands/DCmdInventory.java | 303 ------ .../discord/commands/DCmdLink.java | 51 - .../discord/commands/DCmdList.java | 75 -- .../discord/commands/DCmdMsg.java | 51 - .../discord/commands/DCmdPanic.java | 56 -- .../commands/DCmdResourcepackupdate.java | 154 --- .../discord/commands/DCmdSeen.java | 72 -- .../discord/commands/DCmdSetgamechat.java | 28 - .../discord/commands/DCmdSetlogchat.java | 28 - .../discord/commands/DCmdSetrole.java | 67 -- .../discord/commands/DCmdSetwhitelist.java | 28 - .../discord/commands/DCmdShop.java | 158 --- .../discord/commands/DCmdToggleweb.java | 31 - .../discord/commands/DCmdUnwhitelist.java | 59 -- .../discord/commands/DCmdUser.java | 57 -- .../discord/commands/DCmdWarn.java | 205 ---- .../discord/commands/DCmdWork.java | 48 - .../discord/commands/DiscordCommand.java | 18 - .../dreamvisitor/functions/AutoRestart.java | 8 +- .../dreamvisitor/functions/ConsoleLogger.java | 32 +- .../dreamvisitor/functions/ItemBanList.java | 47 +- .../dreamvisitor/functions/Radio.java | 2 - .../dreamvisitor/functions/Whitelist.java | 40 +- .../listeners/ListenEntityDamage.java | 3 +- .../listeners/ListenPlayerChat.java | 25 +- .../listeners/ListenPlayerCmdPreprocess.java | 63 +- .../listeners/ListenPlayerDeath.java | 20 +- .../listeners/ListenPlayerJoin.java | 18 +- .../listeners/ListenPlayerLogin.java | 6 +- .../listeners/ListenPlayerMoveEvent.java | 7 +- .../listeners/ListenPlayerQuit.java | 10 +- .../dreamvisitor/pb/PocketBase.java | 17 +- .../dreamvisitor/util/ConfigKey.java | 52 + .../dreamvisitor/util/ConfigLoader.java | 2 + .../dreamvisitor/util/PBConfigLoader.java | 6 +- .../dreamvisitor/util/UUIDFromater.java | 8 +- dreamvisitor/src/main/resources/config.yml | 4 +- 70 files changed, 264 insertions(+), 6441 deletions(-) delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Bot.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/AccountLink.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/AltFamily.java rename dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/{PBConfigLoader.java => Config.java} (88%) delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/Economy.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/Infraction.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/Alt.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/Infraction.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/DiscCommandsManager.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/DiscEventListener.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdActivity.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdAlts.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdAutorestart.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdBalance.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdBaltop.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdBroadcast.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdDaily.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdEconomy.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdEcostats.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdInfractions.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdInventory.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdLink.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdList.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdMsg.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdPanic.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdResourcepackupdate.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdSeen.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdSetgamechat.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdSetlogchat.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdSetrole.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdSetwhitelist.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdShop.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdToggleweb.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdUnwhitelist.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdUser.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdWarn.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdWork.java delete mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DiscordCommand.java create mode 100644 dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/ConfigKey.java diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Bot.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Bot.java deleted file mode 100644 index 80ecbbf..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Bot.java +++ /dev/null @@ -1,193 +0,0 @@ -package io.github.stonley890.dreamvisitor; - -import io.github.stonley890.dreamvisitor.discord.DiscCommandsManager; -import io.github.stonley890.dreamvisitor.discord.DiscEventListener; -import io.github.stonley890.dreamvisitor.discord.commands.DCmdAutorestart; -import io.github.stonley890.dreamvisitor.functions.Messager; -import net.dv8tion.jda.api.JDA; -import net.dv8tion.jda.api.JDABuilder; -import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; -import net.dv8tion.jda.api.exceptions.ErrorResponseException; -import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; -import net.dv8tion.jda.api.exceptions.InvalidTokenException; -import net.dv8tion.jda.api.requests.GatewayIntent; -import net.dv8tion.jda.api.utils.TimeFormat; -import net.dv8tion.jda.api.utils.Timestamp; -import net.dv8tion.jda.api.utils.cache.CacheFlag; -import org.bukkit.Bukkit; -import org.bukkit.configuration.file.FileConfiguration; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.time.LocalDateTime; -import java.time.OffsetDateTime; -import java.util.ArrayList; -import java.util.List; - -import static io.github.stonley890.dreamvisitor.Dreamvisitor.PLUGIN; - -public class Bot { - - public static final String[] TRIBE_NAMES = { "HiveWing", "IceWing", "LeafWing", "MudWing", "NightWing", "RainWing", - "SandWing", "SeaWing", "SilkWing", "SkyWing" }; - private static TextChannel gameChatChannel; - private static TextChannel gameLogChannel; - private static TextChannel whitelistChannel; - public static final List tribeRole = new ArrayList<>(); - static JDA jda; - - private Bot() { - throw new IllegalStateException("Utility class."); - } - - public static void startBot(@NotNull FileConfiguration config) { - - // Build JDA - String token = Dreamvisitor.getPlugin().getConfig().getString("bot-token"); - // Try to create a bot - Messager.debug("Attempting to create a bot..."); - try { - jda = JDABuilder - .createLight(token, GatewayIntent.GUILD_MESSAGES, GatewayIntent.MESSAGE_CONTENT, GatewayIntent.GUILD_MEMBERS) - .disableCache(CacheFlag.VOICE_STATE, CacheFlag.EMOJI, CacheFlag.STICKER) - .build(); - Messager.debug("Bot created."); - Dreamvisitor.botFailed = false; - - } catch (InvalidTokenException e) { - - Bukkit.getLogger().severe( - "BOT LOGIN FAILED: You need a valid bot token in dreamvisitor/config.yml. Dreamvisitor will not work properly unless there is a valid bot token."); - Dreamvisitor.botFailed = true; - - } catch (ErrorResponseException exception) { - - if (exception.getErrorCode() == -1) { - Bukkit.getLogger().severe( - "BOT LOGIN FAILED: Dreamvisitor is unable to connect to the Discord server. Dreamvisitor functionality will not work properly."); - Dreamvisitor.botFailed = true; - } - - } - - if (!Dreamvisitor.botFailed) { - jda.addEventListener(new DiscCommandsManager()); - jda.addEventListener(new DiscEventListener()); - jda.addEventListener(new DCmdAutorestart()); - - // Wait for bot ready - try { - jda.awaitReady(); - Messager.debug("Bot is ready."); - - long chatChannelID = config.getLong("chatChannelID"); - long logChannelID = config.getLong("logChannelID"); - long whitelistChannelID = config.getLong("whitelistChannelID"); - - Messager.debug(String.valueOf(chatChannelID)); - Messager.debug(String.valueOf(logChannelID)); - Messager.debug(String.valueOf(whitelistChannelID)); - - Bot.gameChatChannel = jda.getTextChannelById(chatChannelID); - Bot.gameLogChannel = jda.getTextChannelById(logChannelID); - Bot.whitelistChannel = jda.getTextChannelById(whitelistChannelID); - - if (Bot.gameChatChannel == null) - Bukkit.getLogger().warning("The game chat channel with ID " + chatChannelID + " does not exist!"); - if (Bot.gameLogChannel == null) - Bukkit.getLogger().warning("The game log channel with ID " + logChannelID + " does not exist!"); - if (Bot.whitelistChannel == null) - Bukkit.getLogger().warning("The whitelist channel with ID " + whitelistChannelID + " does not exist!"); - - if (config.getLongList("tribeRoles").isEmpty()) { - Bukkit.getLogger().warning("The Discord role list is empty. Check your configuration."); - } else { - for (int i = 0; i < 10; i++) - Bot.tribeRole.add(jda.getRoleById(config.getLongList("tribeRoles").get(i))); - } - - } catch (InterruptedException exception) { - throw new RuntimeException(); - } - } - } - - public static TextChannel getGameChatChannel() { - if (gameChatChannel == null) { - long channelId = Dreamvisitor.getPlugin().getConfig().getLong("chatChannelID"); - gameChatChannel = jda.getTextChannelById(channelId); - } - return gameChatChannel; - } - - public static void setGameChatChannel(TextChannel channel) { - gameChatChannel = channel; - Dreamvisitor.getPlugin().getConfig().set("chatChannelID", gameChatChannel.getIdLong()); - Dreamvisitor.getPlugin().saveConfig(); - } - - public static TextChannel getWhitelistChannel() { - if (whitelistChannel == null) { - long channelId = Dreamvisitor.getPlugin().getConfig().getLong("whitelistChannelID"); - whitelistChannel = jda.getTextChannelById(channelId); - } - return whitelistChannel; - } - - public static void setWhitelistChannel(TextChannel channel) { - whitelistChannel = channel; - Dreamvisitor.getPlugin().getConfig().set("whitelistChannelID", whitelistChannel.getIdLong()); - Dreamvisitor.getPlugin().saveConfig(); - } - - public static TextChannel getGameLogChannel() { - if (gameLogChannel == null) { - long channelId = Dreamvisitor.getPlugin().getConfig().getLong("logChannelID"); - gameLogChannel = jda.getTextChannelById(channelId); - } - return gameLogChannel; - } - - public static void setGameLogChannel(TextChannel channel) { - gameLogChannel = channel; - Dreamvisitor.getPlugin().getConfig().set("logChannelID", gameLogChannel.getIdLong()); - Dreamvisitor.getPlugin().saveConfig(); - } - - public static JDA getJda() { - return jda; - } - - public static void sendLog(@NotNull String message) { - try { - if (!Dreamvisitor.botFailed && !PLUGIN.getConfig().getBoolean("log-console")) - Bot.getGameLogChannel().sendMessage(message).queue(); - else - gameLogChannel.sendMessage(message).queue(); - } catch (InsufficientPermissionException e) { - Bukkit.getLogger() - .warning("Dreamvisitor bot does not have sufficient permissions to send messages in game log channel!"); - } catch (IllegalArgumentException e) { - if (Dreamvisitor.debugMode) - Messager.debug("Attempted to send an invalid message."); - } - } - - /** - * Escapes all Discord markdown elements in a {@link String}. - * - * @param string the {@link String} to format. - * @return the formatted {@link String}. - */ - public static @NotNull String escapeMarkdownFormatting(@NotNull String string) { - return string.isEmpty() ? string - : string.replaceAll("_", "\\\\_").replaceAll("\\*", "\\\\*").replaceAll("\\|", "\\\\|"); - } - - @NotNull - @Contract("_, _ -> fail") - public static Timestamp createTimestamp(@NotNull LocalDateTime dateTime, @NotNull TimeFormat format) { - return format.atInstant(dateTime.toInstant(OffsetDateTime.now().getOffset())); - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Dreamvisitor.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Dreamvisitor.java index 6ab8187..a4b55de 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Dreamvisitor.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Dreamvisitor.java @@ -18,12 +18,12 @@ import io.github.stonley890.dreamvisitor.functions.worldguard.DragonFlightFlag; import io.github.stonley890.dreamvisitor.functions.worldguard.WitherFlag; import io.github.stonley890.dreamvisitor.listeners.*; +import io.github.stonley890.dreamvisitor.util.ConfigKey; import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; import net.luckperms.api.LuckPerms; import org.apache.logging.log4j.LogManager; import org.bukkit.Bukkit; import org.bukkit.Location; -import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.PluginManager; @@ -49,7 +49,6 @@ public class Dreamvisitor extends JavaPlugin { public static Location hubLocation; public static boolean webWhitelistEnabled; public static boolean debugMode; - public static boolean botFailed = true; private static ConsoleLogger appender; public final String VERSION = getDescription().getVersion(); @@ -116,18 +115,17 @@ public void onLoad() { } @Override - @SuppressWarnings("unchecked") public void onEnable() { try { PLUGIN = this; - debugMode = getConfig().getBoolean("debug"); + debugMode = Config.get(ConfigKey.DEBUG); checkConfig(); Messager.debug("Initializing PocketBase config loader..."); - PBConfigLoader.init(); + Config.init(); Messager.debug("Registering listeners..."); registerListeners(); @@ -174,18 +172,6 @@ public void onEnable() { Messager.debug("Dreamvisitor did not create a data folder. It may already exist."); saveDefaultConfig(); - Messager.debug("Initializing accountLink.txt"); - AccountLink.init(); - - Messager.debug("Initializing infractions.yml"); - Infraction.init(); - - Messager.debug("Initializing alts.yml"); - AltFamily.init(); - - Messager.debug("Initializing economy.yml"); - Economy.init(); - Messager.debug("Initializing mail.yml"); Mail.init(); @@ -209,96 +195,31 @@ public void onEnable() { sessionManager.registerHandler(DragonFlightFlag.FACTORY, null); sessionManager.registerHandler(WitherFlag.FACTORY, null); - getLogger().log(Level.INFO, "Dreamvisitor: A plugin created by Bog for WoF:TNW to add various features."); - - Messager.debug("Starting Dreamvisitor bot..."); - Bot.startBot(getConfig()); - - if (!botFailed) { - Messager.debug("Fetching recorded channels and roles from config."); - DiscCommandsManager.init(); - - try { - Bot.getGameLogChannel().sendMessage("Server has been started.\n*Dreamvisitor " + VERSION + "*").queue(); - } catch (InsufficientPermissionException e) { - getLogger() - .severe("Dreamvisitor Bot does not have permission to send messages in the game log channel!"); - throw e; - } - - } + getLogger().log(Level.INFO, "Dreamvisitor: A plugin created by Bog for Wings of Fire: The New World to add various features."); Messager.debug("Restoring chat pause..."); - if (getConfig().getBoolean("chatPaused")) { + if (Config.get(ConfigKey.PAUSE_CHAT)) { chatPaused = true; getLogger().info("Chat is currently paused from last session! Use /pausechat to allow users to chat."); } Messager.debug("Restoring player limit override..."); - playerLimit = getConfig().getInt("playerlimit"); + playerLimit = Config.get(ConfigKey.PLAYER_LIMIT); getLogger().info("Player limit override is currently set to " + playerLimit); Messager.debug("Restoring item banlist..."); - if (PLUGIN.getConfig().get("itemBlacklist") != null) { - ArrayList itemList = (ArrayList) PLUGIN.getConfig().getList("itemBlacklist"); - if (itemList != null) { - Messager.debug("Item banlist is null. Creating an empty banlist..."); - ItemBanList.badItems = itemList.toArray(new ItemStack[0]); - } - } + ItemBanList.init(); Messager.debug("Setting up console logging..."); appender = new ConsoleLogger(); logger.addAppender(appender); - webWhitelistEnabled = getConfig().getBoolean("web-whitelist"); - if (webWhitelistEnabled) - Whitelist.startWeb(getConfig().getInt("whitelistPort")); - Runnable pushConsole = new BukkitRunnable() { @Override public void run() { - if (Dreamvisitor.getPlugin().getConfig().getBoolean("log-console")) { - - if (ConsoleLogger.messageBuilder.isEmpty()) - return; - - try { - Bot.getGameLogChannel().sendMessage(ConsoleLogger.messageBuilder.toString()).queue(); - } catch (InsufficientPermissionException e) { - getLogger().warning( - "Dreamvisitor Bot does not have the necessary permissions to send messages in game log channel."); - } catch (IllegalArgumentException e) { - getLogger().severe("Console logger tried to send an invalid message!"); - } - - ConsoleLogger.messageBuilder.delete(0, ConsoleLogger.messageBuilder.length()); - - if (ConsoleLogger.overFlowMessages.isEmpty()) - return; - - StringBuilder overFlowMessageBuilder = new StringBuilder(); - overFlowMessageBuilder.append(ConsoleLogger.overFlowMessages.get(0)); - - for (int i = 1; i < ConsoleLogger.overFlowMessages.size(); i++) { - - if ((overFlowMessageBuilder.toString().length() + ConsoleLogger.overFlowMessages.get(i).length() - + "\n".length()) >= 2000) { - try { - Bot.getGameLogChannel().sendMessage(overFlowMessageBuilder.toString()).queue(); - } catch (InsufficientPermissionException e) { - getLogger().warning( - "Dreamvisitor Bot does not have the necessary permissions to send messages in game log channel."); - } catch (IllegalArgumentException e) { - getLogger().severe("Console logger tried to send an invalid message!"); - } - overFlowMessageBuilder = new StringBuilder(); + if (Config.get(ConfigKey.LOG_CONSOLE)) { - } else - overFlowMessageBuilder.append(ConsoleLogger.overFlowMessages.get(i)).append("\n"); - } - - ConsoleLogger.overFlowMessages.clear(); + // TODO: Send to DVHub console. } } @@ -307,12 +228,11 @@ public void run() { Runnable scheduledRestarts = new BukkitRunnable() { @Override public void run() { - PBConfigLoader.loadConfig(); + Config.loadConfig(); if (AutoRestart.isAutoRestart() && Bukkit.getOnlinePlayers().isEmpty()) { AutoRestart.sendAutoRestartMessage(); getLogger().info("Restarting the server as scheduled."); - Bot.sendLog("**Restarting the server as scheduled.**"); getServer().spigot().restart(); } @@ -334,23 +254,6 @@ public void run() { } }; - Runnable remindWarns = new BukkitRunnable() { - @Override - public void run() { - Messager.debug("Checking warns to be reminded."); - Map> infractions = Infraction.getAllInfractions(); - Messager.debug("Got list of " + infractions.size() + " members."); - for (Long l : infractions.keySet()) { - Messager.debug("Checking infractions of user " + l); - List userInfractions = Infraction.getInfractions(l); - for (Infraction userInfraction : userInfractions) { - Messager.debug("Attempting remind..."); - userInfraction.remind(l); - } - } - } - }; - Runnable checkBannedItems = new BukkitRunnable() { @Override public void run() { @@ -364,7 +267,7 @@ public void run() { if (content == null || !content.isSimilar(item)) continue; player.getInventory().remove(item); - Bot.sendLog("Removed " + item.getType().name() + " (" + getLogger().info("Removed " + item.getType().name() + " (" + Objects.requireNonNull(item.getItemMeta()).getDisplayName() + ") from " + player.getName()); } } @@ -375,13 +278,8 @@ public void run() { Bukkit.getScheduler().runTaskTimer(this, tick, 0, 0); - if (!botFailed) - Bukkit.getScheduler().runTaskTimer(this, pushConsole, 0, 40); - Bukkit.getScheduler().runTaskTimer(this, scheduledRestarts, 200, 1200); - Bukkit.getScheduler().runTaskTimer(this, remindWarns, 200, 20 * 60 * 60); - Bukkit.getScheduler().runTaskTimer(this, checkBannedItems, 40, 20 * 10); Messager.debug("Enable finished."); @@ -391,54 +289,31 @@ public void run() { .severe("Dreamvisitor was unable to start :(\nPlease notify Bog with the following stack trace:"); e.printStackTrace(); - if (!botFailed) { - StringBuilder builder = new StringBuilder(); - - builder.append(e.getMessage()); - - for (StackTraceElement stackTraceElement : e.getStackTrace()) - builder.append("\n").append(stackTraceElement.toString()); - - try { - Bot.getJda().retrieveUserById(505833634134228992L).complete().openPrivateChannel().complete() - .sendMessage(builder.toString()).complete(); - } catch (net.dv8tion.jda.api.exceptions.ErrorResponseException ex) { - if (ex.getErrorCode() == 50007) { - getLogger().warning("Unable to send Discord DM to user: " + ex.getMessage() + - ". User may have DMs disabled or is not in a shared server."); - getLogger().severe("Error message that would have been sent: " + builder); - } else { - throw ex; - } - } - - } - Bukkit.getPluginManager().disablePlugin(this); throw new RuntimeException(); } } - private void checkConfig() throws InvalidConfigurationException { - if (getConfig().getLongList("triberoles").size() != 10) - throw new InvalidConfigurationException("triberoles must contain exactly 10 entries."); - if (getConfig().getInt("playerlimit") < -1) - getConfig().set("playerlimit", -1); - if (getConfig().getInt("infraction-expire-time-days") < 1) - throw new InvalidConfigurationException("infraction-expire-time-days must be at least 1."); + private void checkConfig() { +// if (getConfig().getLongList("triberoles").size() != 10) +// throw new InvalidConfigurationException("triberoles must contain exactly 10 entries."); +// if (getConfig().getInt("playerlimit") < -1) +// getConfig().set("playerlimit", -1); +// if (getConfig().getInt("infraction-expire-time-days") < 1) +// throw new InvalidConfigurationException("infraction-expire-time-days must be at least 1."); - if (!getConfig().contains("pocketbase-url")) { - getConfig().set("pocketbase-url", "http://your-pocketbase-server.com"); + if (!getConfig().contains("pocketbaseUrl")) { + getConfig().set("pocketbaseUrl", "http://127.0.0.1:8090/"); } - if (!getConfig().contains("pocketbase-config-id")) { - getConfig().set("pocketbase-config-id", "record_id_here"); + if (!getConfig().contains("pocketbaseConfigId")) { + getConfig().set("pocketbaseConfigId", "record_id_here"); } - if (!getConfig().contains("pocketbase-token")) { - getConfig().set("pocketbase-token", "your_admin_token_here"); + if (!getConfig().contains("pocketbaseToken")) { + getConfig().set("pocketbaseToken", "your_admin_token_here"); } - if (!getConfig().contains("pocketbase-use-realtime")) { - getConfig().set("pocketbase-use-realtime", true); + if (!getConfig().contains("pocketbaseUseRealtime")) { + getConfig().set("pocketbaseUseRealtime", true); } saveConfig(); @@ -485,15 +360,6 @@ public void onDisable() { // Shutdown the realtime updater RealtimeConfigUpdater.shutdown(); - if (!botFailed) { - getLogger().info("Closing bot instance."); - int requestsCanceled = Bot.getJda().cancelRequests(); - if (requestsCanceled > 0) - getLogger().info(requestsCanceled + " queued bot requests were canceled for shutdown."); - Bot.getGameLogChannel().sendMessage("*Server has been shut down.*").complete(); - Bot.getJda().shutdownNow(); - } - for (Moonglobe moonglobe : Moonglobe.activeMoonglobes) moonglobe.remove(null); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdChatback.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdChatback.java index 15e6019..67e5789 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdChatback.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdChatback.java @@ -3,9 +3,7 @@ import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.ExecutableCommand; import dev.jorel.commandapi.arguments.LongArgument; -import io.github.stonley890.dreamvisitor.Bot; import io.github.stonley890.dreamvisitor.functions.Chatback; -import net.dv8tion.jda.api.entities.User; import net.md_5.bungee.api.ChatColor; import org.jetbrains.annotations.NotNull; @@ -22,17 +20,18 @@ public class CmdChatback implements DVCommand { Chatback.nextChatback.remove(sender); } else { sender.sendMessage(ChatColor.GRAY + "Your next message will be a reply. Run /chatback to cancel."); - Bot.getGameChatChannel().retrieveMessageById(messageID).queue(message -> { - User author = message.getAuthor(); - Bot.getGameChatChannel().getGuild().retrieveMemberById(author.getId()).queue(member -> { - Chatback.nextChatback.put(sender, new Chatback.ReplyMessage( - member.getEffectiveName(), - author.getName(), - message.getContentRaw(), - message.getIdLong() - )); - }); - }); + // TODO: Implement chatback. +// Bot.getGameChatChannel().retrieveMessageById(messageID).queue(message -> { +// User author = message.getAuthor(); +// Bot.getGameChatChannel().getGuild().retrieveMemberById(author.getId()).queue(member -> { +// Chatback.nextChatback.put(sender, new Chatback.ReplyMessage( +// member.getEffectiveName(), +// author.getName(), +// message.getContentRaw(), +// message.getIdLong() +// )); +// }); +// }); } }); } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDvset.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDvset.java index 126ec44..e64ddcd 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDvset.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDvset.java @@ -2,9 +2,6 @@ import dev.jorel.commandapi.*; import dev.jorel.commandapi.arguments.StringArgument; -import dev.jorel.commandapi.executors.NativeCommandExecutor; -import io.github.stonley890.dreamvisitor.Bot; -import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.data.PlayerMemory; import io.github.stonley890.dreamvisitor.data.PlayerUtility; import io.github.stonley890.dreamvisitor.functions.Messager; @@ -214,8 +211,9 @@ public CommandTree getCommand() { } else { chatMessage = "**" + player.getName() + " joined the game**"; } - Bot.getGameChatChannel().sendMessage(chatMessage).queue(); - Bot.sendLog(chatMessage); + // TODO: Send the message to the chat channel. +// Bot.getGameChatChannel().sendMessage(chatMessage).queue(); +// Bot.sendLog(chatMessage); Messager.send(callee, ChatColor.GRAY + "Discord Vanish toggled to " + ChatColor.WHITE + playerMemory.vanished); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdItemBanList.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdItemBanList.java index 2c1070a..2da1a4c 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdItemBanList.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdItemBanList.java @@ -9,6 +9,7 @@ import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; public class CmdItemBanList implements DVCommand { @@ -23,7 +24,7 @@ public CommandAPICommand getCommand() { CommandSender callee = sender.getCallee(); if (callee instanceof Player player) { if (ItemBanList.badItems != null) { - ItemBanList.inv.setContents(ItemBanList.badItems); + ItemBanList.inv.setContents(ItemBanList.badItems.toArray(new ItemStack[0])); } player.openInventory(ItemBanList.inv); } else throw CommandAPI.failWithString("This command must be executed as a player!"); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPanic.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPanic.java index b861315..669f709 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPanic.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPanic.java @@ -3,13 +3,11 @@ import java.util.TimerTask; import dev.jorel.commandapi.CommandAPICommand; -import dev.jorel.commandapi.ExecutableCommand; import io.github.stonley890.dreamvisitor.functions.Messager; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.entity.Player; -import io.github.stonley890.dreamvisitor.Bot; import io.github.stonley890.dreamvisitor.Dreamvisitor; import org.jetbrains.annotations.NotNull; @@ -45,7 +43,8 @@ public void run() { plugin.saveConfig(); Bukkit.getServer().broadcastMessage( ChatColor.RED + "Panicked by " + sender.getName() + ".\nPlayer limit override set to 0."); - Bot.sendLog("**Panicked by " + sender.getName()); + // TODO: Send a message to the server log. +// Bot.sendLog("**Panicked by " + sender.getName()); } }); } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPausechat.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPausechat.java index 1ee8482..7efef46 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPausechat.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPausechat.java @@ -5,7 +5,6 @@ import org.bukkit.Bukkit; import org.bukkit.ChatColor; -import io.github.stonley890.dreamvisitor.Bot; import io.github.stonley890.dreamvisitor.Dreamvisitor; import org.jetbrains.annotations.NotNull; @@ -29,8 +28,8 @@ public CommandAPICommand getCommand() { // Broadcast to server Bukkit.getServer().broadcastMessage(ChatColor.BLUE + "Chat has been unpaused."); - // Broadcast to chat channel - Bot.getGameChatChannel().sendMessage("**Chat has been unpaused. Messages will now be sent to Minecraft**").queue(); + // TODO: Broadcast to chat channel +// Bot.getGameChatChannel().sendMessage("**Chat has been unpaused. Messages will now be sent to Minecraft**").queue(); } else { @@ -41,8 +40,8 @@ public CommandAPICommand getCommand() { // Broadcast to server Bukkit.getServer().broadcastMessage(ChatColor.BLUE + "Chat has been paused."); - // Broadcast to chat channel - Bot.getGameChatChannel().sendMessage("**Chat has been paused. Messages will not be sent to Minecraft**").queue(); + // TODO: Broadcast to chat channel +// Bot.getGameChatChannel().sendMessage("**Chat has been paused. Messages will not be sent to Minecraft**").queue(); } plugin.saveConfig(); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdUser.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdUser.java index d263695..1642ac6 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdUser.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdUser.java @@ -4,11 +4,7 @@ import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; import dev.jorel.commandapi.arguments.OfflinePlayerArgument; -import io.github.stonley890.dreamvisitor.Bot; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.data.AccountLink; import io.github.stonley890.dreamvisitor.functions.Messager; -import org.bukkit.ChatColor; import org.bukkit.OfflinePlayer; import org.jetbrains.annotations.NotNull; @@ -35,7 +31,8 @@ public CommandAPICommand getCommand() { try { discord = AccountLink.getDiscordId(player.getUniqueId()); discordID = String.valueOf(discord); - discordUsername = Bot.getJda().retrieveUserById(discord).complete().getName(); + // TODO: Get Discord username from database. +// discordUsername = Bot.getJda().retrieveUserById(discord).complete().getName(); } catch (NullPointerException e) { discordID = "N/A"; // Discord username from JDA diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdZoop.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdZoop.java index 7ce745b..23e9df4 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdZoop.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdZoop.java @@ -3,13 +3,9 @@ import dev.jorel.commandapi.CommandAPI; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; -import io.github.stonley890.dreamvisitor.Bot; -import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.data.PlayerMemory; import io.github.stonley890.dreamvisitor.data.PlayerUtility; import io.github.stonley890.dreamvisitor.functions.Messager; -import org.bukkit.ChatColor; -import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; @@ -32,14 +28,16 @@ public CommandAPICommand getCommand() { memory.vanished = false; String chatMessage = "**" + callee.getName() + " joined the game**"; - Bot.getGameChatChannel().sendMessage(chatMessage).queue(); - Bot.sendLog(chatMessage); + // TODO: Send a join message to Discord. +// Bot.getGameChatChannel().sendMessage(chatMessage).queue(); +// Bot.sendLog(chatMessage); } else { memory.vanished = true; String chatMessage = "**" + callee.getName() + " left the game**"; - Bot.getGameChatChannel().sendMessage(chatMessage).queue(); - Bot.sendLog(chatMessage); + // TODO: Send a leave message to Discord. +// Bot.getGameChatChannel().sendMessage(chatMessage).queue(); +// Bot.sendLog(chatMessage); } PlayerUtility.setPlayerMemory(player.getUniqueId(), memory); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/AccountLink.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/AccountLink.java deleted file mode 100644 index 6ef069e..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/AccountLink.java +++ /dev/null @@ -1,126 +0,0 @@ -package io.github.stonley890.dreamvisitor.data; - -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.functions.Messager; -import org.bukkit.Bukkit; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.io.*; -import java.util.*; - -public class AccountLink { - - static final Dreamvisitor plugin = Dreamvisitor.getPlugin(); - static final File file = new File(plugin.getDataFolder().getPath() + "/accountLink.txt"); - - @NotNull static final Map uuidToDiscordIdMap = new HashMap<>(); - @NotNull static final Map discordIdToUuidMap = new HashMap<>(); - - public static void init() throws IOException { - // If the file does not exist, create one - if (!file.exists()) { - Messager.debug("accountLink.txt does not exist. Creating one now..."); - try { - if (!file.createNewFile()) throw new IOException("The existence of " + file.getName() + " cannot be verified!", null); - } catch (IOException e) { - throw new IOException("Dreamvisitor tried to create " + file.getName() + ", but it cannot be read/written! Does the server have read/write access?", e); - } - } - loadFromFile(); - } - - private static void loadFromFile() { - Messager.debug("Loading accountLink.txt"); - BufferedReader reader; - try { - reader = new BufferedReader(new FileReader(file)); - String line; - while ((line = reader.readLine()) != null) { - String[] parts = line.split(":"); - if (parts.length == 2) { - UUID uuid = UUID.fromString(PlayerUtility.formatUuid(parts[0])); - long discordID = Long.parseLong(parts[1]); - uuidToDiscordIdMap.put(uuid, discordID); - discordIdToUuidMap.put(discordID, uuid); - } - } - } catch (FileNotFoundException e) { - Bukkit.getLogger().severe("accountLink.txt does not exist! " + e.getMessage()); - Bukkit.getPluginManager().disablePlugin(Dreamvisitor.getPlugin()); - } catch (IOException e) { - Bukkit.getLogger().severe("There was an error reading from accountLink.txt! " + e.getMessage()); - Bukkit.getPluginManager().disablePlugin(Dreamvisitor.getPlugin()); - } - } - - public static void saveFile() { - Messager.debug("Saving..."); - BufferedWriter writer; - try { - writer = new BufferedWriter(new FileWriter(file)); - for (Map.Entry entry : uuidToDiscordIdMap.entrySet()) { - UUID uuid = entry.getKey(); - Messager.debug("UUID for this entry: " + uuid.toString()); - long discordId = entry.getValue(); - Messager.debug("Discord ID for this entry: " + discordId); - - String data = uuid.toString().replaceAll("-", "") + ":" + discordId; - - writer.write(data); - writer.newLine(); - Messager.debug("Line written"); - } - writer.close(); - } catch (IOException e) { - Bukkit.getLogger().severe("There was an error writing to accountLink.txt! " + e.getMessage()); - Bukkit.getPluginManager().disablePlugin(Dreamvisitor.getPlugin()); - } - - } - - public static void linkAccounts(@NotNull UUID minecraftUUID, @NotNull Long discordId) { - - loadFromFile(); - - if (Objects.equals(getUuid(discordId), minecraftUUID) && getDiscordId(minecraftUUID) == discordId) return; - - // remove existing values - for (UUID uuid : uuidToDiscordIdMap.keySet()) { - if (uuidToDiscordIdMap.get(uuid).equals(discordId)) { - uuidToDiscordIdMap.remove(uuid); - } - } - for (Long id : discordIdToUuidMap.keySet()) { - if (discordIdToUuidMap.get(id).equals(minecraftUUID)) { - discordIdToUuidMap.remove(discordId); - } - } - - // set values - uuidToDiscordIdMap.put(minecraftUUID, discordId); - discordIdToUuidMap.put(discordId, minecraftUUID); - Bukkit.getScheduler().runTaskAsynchronously(Dreamvisitor.getPlugin(), AccountLink::saveFile); - } - - /** - * Get the Discord ID of the given {@link UUID}. - * @param minecraftUUID the {@link UUID} to get the Discord ID of. - * @return the {@code long} Discord ID. - * @throws NullPointerException if the given {@link UUID} does not have an associated Discord ID. - */ - public static long getDiscordId(@NotNull UUID minecraftUUID) { - loadFromFile(); - return uuidToDiscordIdMap.get(minecraftUUID); - } - - /** - * Get the {@link UUID} of the given Discord ID. - * @param discordId the {@code long} Discord ID to get the {@link UUID} of. - * @return the {@link UUID} associated with this Discord ID or {@code null} if it does not exist. - */ - public static @Nullable UUID getUuid(long discordId) { - loadFromFile(); - return discordIdToUuidMap.get(discordId); - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/AltFamily.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/AltFamily.java deleted file mode 100644 index da3da63..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/AltFamily.java +++ /dev/null @@ -1,214 +0,0 @@ -package io.github.stonley890.dreamvisitor.data; - -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.functions.Messager; -import org.bukkit.Bukkit; -import org.bukkit.configuration.InvalidConfigurationException; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.configuration.serialization.ConfigurationSerializable; -import org.jetbrains.annotations.NotNull; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class AltFamily implements ConfigurationSerializable { - - static final File file = new File(Dreamvisitor.getPlugin().getDataFolder().getPath() + "/alts.yml"); - private final long parent; - @NotNull private List children = new ArrayList<>(); - - public AltFamily(long parentId) { - parent = parentId; - } - - public static void init() throws IOException { - // If the file does not exist, create one - if (!file.exists()) { - Messager.debug("alts.yml does not exist. Creating one now..."); - try { - if (!file.createNewFile()) throw new IOException("The existence of " + file.getName() + " cannot be verified!", null); - } catch (IOException e) { - throw new IOException("Dreamvisitor tried to create " + file.getName() + ", but it cannot be read/written! Does the server have read/write access?", e); - } - } - } - - private static @NotNull YamlConfiguration getConfig() { - YamlConfiguration config = new YamlConfiguration(); - try { - config.load(file); - } catch (IOException e) { - Bukkit.getLogger().severe("alts.yml cannot be read! Does the server have read/write access? " + e.getMessage()); - Bukkit.getPluginManager().disablePlugin(Dreamvisitor.getPlugin()); - } catch (InvalidConfigurationException e) { - Bukkit.getLogger().severe("alts.yml is not a valid configuration! Is it formatted correctly? " + e.getMessage()); - Bukkit.getPluginManager().disablePlugin(Dreamvisitor.getPlugin()); - } - return config; - } - - private static @NotNull YamlConfiguration buildConfig(@NotNull List altFamilyList) { - YamlConfiguration config = new YamlConfiguration(); - config.set("alts", altFamilyList); - return config; - } - - private static void saveToDisk(@NotNull YamlConfiguration config) { - Messager.debug("Saving alts.yml..."); - try { - config.save(file); - } catch (IOException e) { - Bukkit.getLogger().severe("alts.yml cannot be written! Does the server have read/write access? " + e.getMessage() + "\nHere is the data that was not saved:\n" + config.saveToString()); - Bukkit.getPluginManager().disablePlugin(Dreamvisitor.getPlugin()); - } - Messager.debug("Done!"); - } - - /** - * Get the children of a parent account. - * @param parentId the ID of the user to get the child accounts of. - * @return a {@link List} of child user IDs. - * @throws NotParentException if the ID given is not a parent account. - */ - public static @NotNull List getChildren(long parentId) throws NotParentException { - List altFamilyList = getAltFamilyList(); - for (AltFamily altFamily : altFamilyList) { - if (altFamily.getParent() == parentId) return altFamily.getChildren(); - } - if (getParent(parentId) == parentId) return new ArrayList<>(); - else throw new NotParentException(); - } - - /** - * Get the parent of a child. If no parent is found, the child ID will be returned as the parent. - * @param childId the child ID to search for - * @return the parent ID - */ - public static long getParent(long childId) { - List altFamilyList = getAltFamilyList(); - for (AltFamily altFamily : altFamilyList) { - for (Long child : altFamily.getChildren()) { - if (child == childId) return altFamily.getParent(); - } - } - return childId; - } - - /** - * Get the {@link AltFamily} of a given user ID. You can give either a parent or child account ID. - * @param userId the ID of the user to search for. - * @return the {@link AltFamily} connected to this account. It will have no children if the account has not been associated with any others. - */ - public static @NotNull AltFamily getFamily(long userId) { - - List altFamilyList = AltFamily.getAltFamilyList(); - - for (AltFamily altFamily : altFamilyList) { - - if (altFamily.parent == userId) return altFamily; - - for (Long child : altFamily.getChildren()) if (child == userId) return altFamily; - - } - return new AltFamily(userId); - } - - @SuppressWarnings("unchecked") - private static @NotNull List getAltFamilyList() { - List alts = (List) getConfig().getList("alts"); - if (alts == null) alts = new ArrayList<>(); - return alts; - } - - public static void updateFamily(AltFamily altFamily) { - List altFamilyList = getAltFamilyList(); - for (int i = 0; i < altFamilyList.size(); i++) { - AltFamily family = altFamilyList.get(i); - if (altFamily.parent == family.parent) { - altFamilyList.set(i, altFamily); - saveToDisk(buildConfig(altFamilyList)); - return; - } - } - altFamilyList.add(altFamily); - saveToDisk(buildConfig(altFamilyList)); - } - - /** - * Set a child account to a parent account. - * If the child is already linked to another parent, it will be removed. - * Infractions will be transferred from the child to the parent automatically. - * @param parentId the ID of the parent account. - * @param childId the ID of the child account. - * @throws NotParentException if the parent account is a child of another parent. - */ - public static void setAlt(long parentId, long childId) throws NotParentException { - - - long initialParent = getParent(childId); - if (initialParent == parentId) return; - - // remove child from parent if exists - if (initialParent != childId) { - AltFamily family = getFamily(childId); - family.children.remove(childId); - updateFamily(family); - } - - List children = getChildren(parentId); - children.add(childId); - AltFamily altFamily = new AltFamily(parentId); - altFamily.setChildren(children); - updateFamily(altFamily); - - List childInfractions = Infraction.getInfractions(childId); - if (childInfractions.isEmpty()) return; - List parentInfractions = Infraction.getInfractions(parentId); - - parentInfractions.addAll(childInfractions); - childInfractions.clear(); - - Infraction.setInfractions(childInfractions, childId); - Infraction.setInfractions(parentInfractions, parentId); - } - - @SuppressWarnings("unchecked") - public static @NotNull AltFamily deserialize(@NotNull Map objectMap) { - long parent = (long) objectMap.get("parent"); - List children = (List) objectMap.get("children"); - if (children == null) children = new ArrayList<>(); - AltFamily altFamily = new AltFamily(parent); - altFamily.setChildren(children); - return altFamily; - } - - public long getParent() { - return parent; - } - - public @NotNull List getChildren() { - return children; - } - - public void setChildren(@NotNull List children) { - this.children = children; - } - - @NotNull - @Override - public Map serialize() { - Map objectMap = new HashMap<>(); - objectMap.put("parent", parent); - objectMap.put("children", children); - return objectMap; - } - - public static class NotParentException extends Exception { - public NotParentException() {} - } - -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PBConfigLoader.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/Config.java similarity index 88% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PBConfigLoader.java rename to dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/Config.java index 4486ddb..3b5fd49 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PBConfigLoader.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/Config.java @@ -5,6 +5,7 @@ import io.github.stonley890.dreamvisitor.functions.AutoRestart; import io.github.stonley890.dreamvisitor.functions.Messager; import io.github.stonley890.dreamvisitor.pb.PocketBase; +import io.github.stonley890.dreamvisitor.util.ConfigKey; import org.bukkit.Bukkit; import org.bukkit.configuration.file.FileConfiguration; import org.jetbrains.annotations.Contract; @@ -13,10 +14,11 @@ import java.io.IOException; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; -public class PBConfigLoader { +public class Config { private static JSONObject config; private static String baseUrl; private static String configId; @@ -40,8 +42,8 @@ public static void init() { // Create PocketBase client from config try { Map pbConfig = new HashMap<>(); - pbConfig.put("pocketbase-url", baseUrl); - pbConfig.put("pocketbase-token", token); + pbConfig.put("pocketbaseUrl", baseUrl); + pbConfig.put("pocketbaseToken", token); pocketBaseClient = PocketBase.fromConfig(pbConfig); Messager.debug("Initialized PocketBase client"); @@ -145,19 +147,20 @@ public static CompletableFuture updateConfigField(String field, boolean va }); } - public static boolean getBoolean(String field, boolean defaultValue) { - if (config == null) { - return defaultValue; + @SuppressWarnings("unchecked") + public static T get(@NotNull ConfigKey configKey) { + Object value = config.get(configKey.getKey()); + + if (value == null) { + value = configKey.getDefaultValue(); } - try { - return config.getBoolean(field); - } catch (Exception e) { - return defaultValue; + if (configKey.getType().isInstance(value)) { + return (T) value; } - } - public static PocketBase getClient() { - return pocketBaseClient; + throw new IllegalStateException("Config value for key '" + configKey.getKey() + + "' is not of expected type: " + configKey.getType().getSimpleName()); } + } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/Economy.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/Economy.java deleted file mode 100644 index c7ba4c6..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/Economy.java +++ /dev/null @@ -1,871 +0,0 @@ -package io.github.stonley890.dreamvisitor.data; - -import io.github.stonley890.dreamvisitor.Bot; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.functions.Messager; -import net.dv8tion.jda.api.entities.Guild; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.Role; -import net.luckperms.api.LuckPerms; -import net.luckperms.api.model.group.Group; -import net.luckperms.api.node.types.InheritanceNode; -import org.bukkit.Bukkit; -import org.bukkit.configuration.InvalidConfigurationException; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.configuration.serialization.ConfigurationSerializable; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.io.File; -import java.io.IOException; -import java.text.DecimalFormat; -import java.time.Duration; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.*; - -public class Economy { - - static final File file = new File(Dreamvisitor.getPlugin().getDataFolder().getPath() + "/economy.yml"); - - public static void init() throws IOException { - // If the file does not exist, create one - if (!file.exists()) { - Messager.debug(file.getName() + " does not exist. Creating one now..."); - try { - if (!file.createNewFile()) - throw new IOException("The existence of " + file.getName() + " cannot be verified!", null); - } catch (IOException e) { - throw new IOException("Dreamvisitor tried to create " + file.getName() + ", but it cannot be read/written! Does the server have read/write access?", e); - } - } - } - - public static String formatDouble(double number) { - DecimalFormat decimalFormat = new DecimalFormat("#,##0.00"); - return decimalFormat.format(number); - } - - @NotNull - private static YamlConfiguration getConfig() { - YamlConfiguration config = new YamlConfiguration(); - try { - config.load(file); - } catch (IOException e) { - Bukkit.getLogger().severe(file.getName() + " cannot be read! Does the server have read/write access? " + e.getMessage()); - Bukkit.getPluginManager().disablePlugin(Dreamvisitor.getPlugin()); - } catch (InvalidConfigurationException e) { - Bukkit.getLogger().severe(file.getName() + " is not a valid configuration! Is it formatted correctly? " + e.getMessage()); - Bukkit.getPluginManager().disablePlugin(Dreamvisitor.getPlugin()); - } - return config; - } - - private static void saveConfig(@NotNull YamlConfiguration config) { - try { - config.save(file); - } catch (IOException e) { - Bukkit.getLogger().severe(file.getName() + " cannot be written! Does the server have read/write access? " + e.getMessage() + "\nHere is the data that was not saved:\n" + config.saveToString()); - Bukkit.getPluginManager().disablePlugin(Dreamvisitor.getPlugin()); - } - } - - public static String getCurrencySymbol() { - return Dreamvisitor.getPlugin().getConfig().getString("currencyIcon"); - } - - public static void setCurrencySymbol(String symbol) { - Dreamvisitor.getPlugin().getConfig().set("currencyIcon", symbol); - Dreamvisitor.getPlugin().saveConfig(); - } - - @NotNull - public static List getItems() { - List> items = getConfig().getMapList("items"); - List shopItems = new ArrayList<>(); - items.forEach(item -> shopItems.add(ShopItem.deserialize((Map) item))); - return shopItems; - } - - public static void setItems(@NotNull List itemsToSet) { - List> mapList = new ArrayList<>(); - for (ShopItem shopItem : itemsToSet) { - mapList.add(shopItem.serialize()); - } - YamlConfiguration config = getConfig(); - config.set("items", mapList); - saveConfig(config); - } - - @Nullable - public static ShopItem getItem(int id) { - for (ShopItem item : getItems()) { - if (item.getId() == id) return item; - } - return null; - } - - public static void saveItems(@NotNull List itemsToSave) { - if (itemsToSave.isEmpty()) return; - List items = getItems(); - if (items.isEmpty()) { - items.addAll(itemsToSave); - } else { - for (ShopItem newItem : itemsToSave) { - boolean saved = false; - for (int i = 0; i < items.size(); i++) { - ShopItem item = items.get(i); - if (newItem.id != item.id) continue; - items.set(i, newItem); - saved = true; - } - if (!saved) items.add(newItem); - } - } - - setItems(items); - } - - public static void saveItem(@NotNull ShopItem itemToSave) { - List items = getItems(); - if (items.isEmpty()) items.add(itemToSave); - else { - boolean saved = false; - for (int i = 0; i < items.size(); i++) { - ShopItem item = items.get(i); - if (itemToSave.id != item.id) continue; - items.set(i, itemToSave); - saved = true; - } - if (!saved) items.add(itemToSave); - } - - setItems(items); - } - - public static void removeItem(ShopItem item) { - List items = getItems(); - int itemToRemove = -1; - for (int i = 0; i < items.size(); i++) { - if (items.get(i).getId() == item.getId()) { - itemToRemove = i; - break; - } - } - if (itemToRemove == -1) return; - items.remove(itemToRemove); - - setItems(items); - } - - @NotNull - public static List getConsumers() { - List> users = getConfig().getMapList("users"); - List consumers = new ArrayList<>(); - for (Map user : users) { - Consumer consumer = Consumer.deserialize((Map) user); - consumers.add(consumer); - } - return consumers; - } - - @NotNull - public static Consumer getConsumer(long id) { - for (Consumer consumer : getConsumers()) { - if (consumer.id == id) return consumer; - } - return new Consumer(id); - } - - public static void saveConsumers(@NotNull List consumerList) { - List> mapList = new ArrayList<>(); - for (Consumer consumer : consumerList) { - mapList.add(consumer.serialize()); - } - YamlConfiguration config = getConfig(); - config.set("users", mapList); - saveConfig(config); - } - - public static void saveConsumer(Consumer newConsumer) { - List consumers = getConsumers(); - consumers.removeIf(consumer -> consumer.id == newConsumer.id); - consumers.add(newConsumer); - saveConsumers(consumers); - } - - public static String getShopName() { - return Dreamvisitor.getPlugin().getConfig().getString("shopName"); - } - - public static void setShopName(String name) { - Dreamvisitor.getPlugin().getConfig().set("shopName", name); - Dreamvisitor.getPlugin().saveConfig(); - } - - private static double getDailyBaseAmount() { - return Dreamvisitor.getPlugin().getConfig().getDouble("dailyBaseAmount"); - } - - public static double getDailyStreakMultiplier() { - return Dreamvisitor.getPlugin().getConfig().getDouble("dailyStreakMultiplier"); - } - - public static double getWorkReward() { - return Dreamvisitor.getPlugin().getConfig().getDouble("workReward"); - } - - public static class ShopItem implements ConfigurationSerializable { - - private int id; - @NotNull - private String name; - @NotNull - private String description; - private double price = 0; - private double salePercent = 0; - private int quantity = -1; - private int maxAllowed = -1; - private boolean enabled = true; - private boolean giftingEnabled = true; - private boolean useDisabled = false; - private boolean useOnPurchase = false; - @Nullable - private List onUseRolesAdd = null; - @Nullable - private List onUseRolesRemove = null; - @Nullable - private List onUseConsoleCommands = null; - @Nullable - private List onUseGroupsAdd = null; - @Nullable - private List onUseGroupsRemove = null; - - public void ensureUniqueId() { - boolean unique = false; - List items = Economy.getItems(); - if (items.isEmpty()) return; - while (!unique) { - for (ShopItem item : items) { - if (item.id == this.id) { - this.id = new Random().nextInt(0, 99999999); - break; - } - unique = true; - } - } - } - - public ShopItem(@NotNull String name, @NotNull String description) { - this.id = new Random().nextInt(0, 99999999); - this.name = name; - this.description = description; - } - - @NotNull - public static ShopItem deserialize(@NotNull Map map) { - ShopItem shopItem = new ShopItem((String) map.get("name"), (String) map.get("description")); - shopItem.id = (int) map.get("id"); - shopItem.setPrice((Double) map.get("price")); - shopItem.setSalePercent((Double) map.get("salePercent")); - shopItem.setQuantity((Integer) map.get("quantity")); - shopItem.setMaxAllowed((Integer) map.get("maxAllowed")); - shopItem.setEnabled((Boolean) map.get("enabled")); - shopItem.setGiftingEnabled((Boolean) map.get("giftingEnabled")); - shopItem.setUseDisabled((Boolean) map.get("useDisabled")); - shopItem.setUseOnPurchase((Boolean) map.get("useOnPurchase")); - shopItem.setOnUseRolesAdd((List) map.get("onUseRolesAdd")); - shopItem.setOnUseRolesRemove((List) map.get("onUseRolesRemove")); - shopItem.setOnUseConsoleCommands((List) map.get("onUseConsoleCommands")); - shopItem.setOnUseGroupsAdd((List) map.get("onUseGroupsAdd")); - shopItem.setOnUseGroupsRemove((List) map.get("onUseGroupsRemove")); - - return shopItem; - } - - public void use(@NotNull Member member) throws UnsupportedOperationException { - if (useDisabled) throw new UnsupportedOperationException("This item does not allow use."); - UUID uuid = AccountLink.getUuid(member.getIdLong()); - if (uuid == null) throw new UnsupportedOperationException("This account is not linked to a UUID."); - - Guild guild = member.getGuild(); - - LuckPerms luckPerms = Dreamvisitor.getLuckPerms(); - - if (onUseRolesAdd != null && !onUseRolesAdd.isEmpty()) { - for (Long roleId : onUseRolesAdd) { - Role role = guild.getRoleById(roleId); - if (role == null) continue; - guild.addRoleToMember(member, role).queue(); - } - } - if (onUseRolesRemove != null && !onUseRolesRemove.isEmpty()) { - for (Long roleId : onUseRolesRemove) { - Role role = guild.getRoleById(roleId); - if (role == null) continue; - guild.removeRoleFromMember(member, role).queue(); - } - } - if ((onUseGroupsAdd != null && !onUseGroupsAdd.isEmpty()) || onUseGroupsRemove != null && !onUseGroupsRemove.isEmpty()) { - luckPerms.getUserManager().loadUser(uuid).thenAcceptAsync(user -> { - if (onUseGroupsAdd != null && !onUseGroupsAdd.isEmpty()) { - for (String groupName : onUseGroupsAdd) { - Group group = luckPerms.getGroupManager().getGroup(groupName); - if (group == null) return; - user.data().add(InheritanceNode.builder(group).build()); - } - } - if (onUseGroupsRemove != null && !onUseGroupsRemove.isEmpty()) { - for (String groupName : onUseGroupsRemove) { - Group group = luckPerms.getGroupManager().getGroup(groupName); - if (group == null) return; - user.data().remove(InheritanceNode.builder(group).build()); - } - } - luckPerms.getUserManager().saveUser(user); - }); - } - if (onUseConsoleCommands != null && !onUseConsoleCommands.isEmpty()) { - for (String command : onUseConsoleCommands) { - Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command); - } - } - } - - public boolean isInfinite() { - return quantity == -1; - } - - public double getTruePrice() { - return price - price * salePercent * 0.01; - } - - public int getId() { - return id; - } - - @NotNull - public String getName() { - return name; - } - - public void setName(@NotNull String name) { - this.name = name; - } - - @NotNull - public String getDescription() { - return description; - } - - public void setDescription(@NotNull String description) { - this.description = description; - } - - public double getPrice() { - return price; - } - - public void setPrice(double price) { - this.price = price; - } - - public double getSalePercent() { - return salePercent; - } - - public void setSalePercent(double salePercent) { - this.salePercent = salePercent; - } - - public int getQuantity() { - return quantity; - } - - public void setQuantity(int quantity) { - this.quantity = quantity; - } - - public int getMaxAllowed() { - return maxAllowed; - } - - public void setMaxAllowed(int maxAllowed) { - this.maxAllowed = maxAllowed; - } - - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public boolean isGiftingEnabled() { - return giftingEnabled; - } - - public void setGiftingEnabled(boolean giftingEnabled) { - this.giftingEnabled = giftingEnabled; - } - - public boolean isUseDisabled() { - return useDisabled; - } - - public void setUseDisabled(boolean useDisabled) { - this.useDisabled = useDisabled; - } - - public boolean isUseOnPurchase() { - return useOnPurchase; - } - - public void setUseOnPurchase(boolean useOnPurchase) { - this.useOnPurchase = useOnPurchase; - } - - @Nullable - public List getOnUseRolesAdd() { - return onUseRolesAdd; - } - - public void setOnUseRolesAdd(@Nullable List onUseRolesAdd) { - this.onUseRolesAdd = onUseRolesAdd; - } - - @Nullable - public List getOnUseRolesRemove() { - return onUseRolesRemove; - } - - public void setOnUseRolesRemove(@Nullable List onUseRolesRemove) { - this.onUseRolesRemove = onUseRolesRemove; - } - - @Nullable - public List getOnUseConsoleCommands() { - return onUseConsoleCommands; - } - - public void setOnUseConsoleCommands(@Nullable List onUseConsoleCommands) { - this.onUseConsoleCommands = onUseConsoleCommands; - } - - @Nullable - public List getOnUseGroupsAdd() { - return onUseGroupsAdd; - } - - public void setOnUseGroupsAdd(@Nullable List onUseGroupsAdd) { - this.onUseGroupsAdd = onUseGroupsAdd; - } - - @Nullable - public List getOnUseGroupsRemove() { - return onUseGroupsRemove; - } - - public void setOnUseGroupsRemove(@Nullable List onUseGroupsRemove) { - this.onUseGroupsRemove = onUseGroupsRemove; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj instanceof ShopItem item) { - return Objects.equals(name, item.name) && - Objects.equals(description, item.description) && - Objects.equals(price, item.price) && - Objects.equals(salePercent, item.salePercent) && - Objects.equals(quantity, item.quantity) && - Objects.equals(maxAllowed, item.maxAllowed) && - Objects.equals(enabled, item.enabled) && - Objects.equals(giftingEnabled, item.giftingEnabled) && - Objects.equals(useDisabled, item.useDisabled) && - Objects.equals(useOnPurchase, item.useOnPurchase) && - Objects.equals(onUseRolesAdd, item.onUseRolesAdd) && - Objects.equals(onUseRolesRemove, item.onUseRolesRemove) && - Objects.equals(onUseConsoleCommands, item.onUseConsoleCommands) && - Objects.equals(onUseGroupsAdd, item.onUseGroupsAdd) && - Objects.equals(onUseGroupsRemove, item.onUseGroupsRemove); - } - return false; - } - - @NotNull - @Override - public Map serialize() { - Map map = new HashMap<>(); - map.put("id", id); - map.put("name", name); - map.put("description", description); - map.put("price", price); - map.put("salePercent", salePercent); - map.put("quantity", quantity); - map.put("maxAllowed", maxAllowed); - map.put("enabled", enabled); - map.put("giftingEnabled", giftingEnabled); - map.put("useDisabled", useDisabled); - map.put("useOnPurchase", useOnPurchase); - map.put("onUseRolesAdd", onUseRolesAdd); - map.put("onUseRolesRemove", onUseRolesRemove); - map.put("onUseConsoleCommands", onUseConsoleCommands); - map.put("onUseGroupsAdd", onUseGroupsAdd); - map.put("onUseGroupsRemove", onUseGroupsRemove); - - return map; - } - } - - public static class Consumer implements ConfigurationSerializable { - - private long id; - private double balance = 0; - @NotNull - private Map items = new HashMap<>(); - - @NotNull - private GameData gameData = new GameData(); - - private Consumer(long id) { - this.id = id; - } - - @NotNull - public static Consumer deserialize(@NotNull Map map) { - Consumer consumer = new Consumer((Long) map.get("id")); - consumer.setBalance((Double) map.get("balance")); - consumer.setItems((Map) map.get("inventory")); - consumer.setGameData(GameData.deserialize((Map) map.get("gameData"))); - return consumer; - } - - @NotNull - public GameData getGameData() { - return gameData; - } - - public void setGameData(@NotNull GameData gameData) { - this.gameData = gameData; - } - - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - - public double getBalance() { - return balance; - } - - public void setBalance(double newBalance) { - balance = newBalance; - } - - @NotNull - public Map getItems() { - return items; - } - - public void setItems(@NotNull Map itemMap) { - items = itemMap; - } - - public int getItemQuantity(int itemId) { - try { - return items.get(itemId); - } catch (NullPointerException e) { - return 0; - } - } - - public void setItemQuantity(int itemId, int quantity) { - items.put(itemId, quantity); - } - - public int getQuantityOfItem(int itemId) { - int amount = 0; - if (items.get(itemId) != null) amount = items.get(itemId); - return amount; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Consumer consumer = (Consumer) o; - return id == consumer.id && Double.compare(balance, consumer.balance) == 0 && Objects.equals(items, consumer.items) && Objects.equals(gameData, consumer.gameData); - } - - @Override - public int hashCode() { - return Objects.hash(id, balance, items, gameData); - } - - @NotNull - @Override - public Map serialize() { - Map map = new HashMap<>(); - map.put("id", id); - map.put("balance", balance); - map.put("inventory", items); - map.put("gameData", gameData.serialize()); - return map; - } - - /** - * Make this {@link Consumer} purchase an item. - * - * @param itemId the ID of the item to purchase. - * @throws NullPointerException if the item does not exist. - * @throws ItemNotEnabledException if the item is not enabled. - * @throws ItemOutOfStockException if the item is out of stock. - * @throws InsufficientFundsException if the {@link Consumer} does not have sufficient funds to purchase the item. - * @throws MaxItemQualityException if the {@link Consumer} already has the maximum allowed of this item. - */ - public void purchaseItem(int itemId) throws NullPointerException, ItemNotEnabledException, ItemOutOfStockException, InsufficientFundsException, MaxItemQualityException { - - ShopItem desiredItem = getItem(itemId); - if (desiredItem == null) throw new NullPointerException("Item does not exist."); - if (!desiredItem.enabled) throw new ItemNotEnabledException("Item is not enabled."); - if (desiredItem.quantity == 0) throw new ItemOutOfStockException("Item is out of stock."); - if (balance < desiredItem.getTruePrice()) - throw new InsufficientFundsException("Consumer does not have sufficient funds for item."); - if (desiredItem.maxAllowed != -1 && (getItemQuantity(itemId) + 1 > desiredItem.maxAllowed)) - throw new MaxItemQualityException("Consumer already has max amount of this item."); - - if (desiredItem.useOnPurchase) { - try { - useItem(itemId); - } catch (ItemUseNotEnabledException e) { - setItemQuantity(itemId, getQuantityOfItem(itemId) + 1); - } - } else setItemQuantity(itemId, getQuantityOfItem(itemId) + 1); - if (!desiredItem.isInfinite()) desiredItem.setQuantity(desiredItem.quantity - 1); - setBalance(balance - desiredItem.getTruePrice()); - Economy.saveItem(desiredItem); - - } - - public void useItem(int itemId) throws NullPointerException, ItemNotEnabledException, ItemUseNotEnabledException { - - ShopItem item = getItem(itemId); - if (item == null) throw new NullPointerException("Item does not exist."); - if (!item.enabled) throw new ItemNotEnabledException("Item is not enabled."); - if (item.useDisabled) throw new ItemUseNotEnabledException("Item cannot be used."); - - Guild guild = Bot.getGameLogChannel().getGuild(); - Member member = guild.retrieveMemberById(id).complete(); - - UUID uuid = AccountLink.getUuid(id); - if (uuid == null) throw new NullPointerException("No linked Minecraft account exists."); - - String username = PlayerUtility.getUsernameOfUuid(uuid); - if (username == null) throw new NullPointerException("Linked Minecraft account could not be found."); - - LuckPerms luckPerms = Dreamvisitor.getLuckPerms(); - - List rolesToAdd = item.onUseRolesAdd; - if (rolesToAdd != null && !rolesToAdd.isEmpty()) - for (Long roleId : rolesToAdd) { - Role role = Bot.getJda().getRoleById(roleId); - if (role == null) throw new NullPointerException("Role to add " + roleId + " does not exist!"); - guild.addRoleToMember(member, role).queue(); - } - List rolesToRemove = item.onUseRolesRemove; - if (rolesToRemove != null && !rolesToRemove.isEmpty()) - for (Long roleId : rolesToRemove) { - Role role = Bot.getJda().getRoleById(roleId); - if (role == null) throw new NullPointerException("Role to remove " + roleId + " does not exist!"); - guild.removeRoleFromMember(member, role).queue(); - } - - if (item.onUseGroupsAdd != null && !item.onUseGroupsAdd.isEmpty()) { - luckPerms.getUserManager().loadUser(uuid).thenAcceptAsync(user -> { - for (String groupName : item.onUseGroupsAdd) { - Group group = luckPerms.getGroupManager().getGroup(groupName); - if (group == null) - throw new NullPointerException("Group to add " + groupName + " does not exist."); - user.getNodes().add(InheritanceNode.builder(group).build()); - } - luckPerms.getUserManager().saveUser(user); - }); - } - - if (item.onUseGroupsRemove != null && !item.onUseGroupsRemove.isEmpty()) { - luckPerms.getUserManager().loadUser(uuid).thenAcceptAsync(user -> { - for (String groupName : item.onUseGroupsRemove) { - Group group = luckPerms.getGroupManager().getGroup(groupName); - if (group == null) - throw new NullPointerException("Group to remove " + groupName + " does not exist."); - user.getNodes().remove(InheritanceNode.builder(group).build()); - } - luckPerms.getUserManager().saveUser(user); - }); - } - - if (item.onUseConsoleCommands != null && !item.onUseConsoleCommands.isEmpty()) { - for (String command : item.onUseConsoleCommands) { - Bukkit.getScheduler().runTask(Dreamvisitor.getPlugin(), () -> Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command.replace("$PLAYER$", username))); - } - } - - setItemQuantity(itemId, getItemQuantity(itemId - 1)); - - } - - /** - * Claim the daily reward. This method will refresh and update the streak, then add the reward to the balance. - * - * @return the amount that was rewarded. - * @throws CoolDownException if this consumer cannot yet claim their - */ - public double claimDaily() throws CoolDownException { - gameData.updateStreak(); - if (gameData.lastDaily != null && Objects.equals(gameData.lastDaily.toLocalDate(), LocalDate.now())) throw new CoolDownException(); - double dailyBaseAmount = Economy.getDailyBaseAmount(); - double reward = dailyBaseAmount + (gameData.getDailyStreak() * getDailyStreakMultiplier()); - setBalance(balance + reward); - gameData.dailyStreak++; - gameData.lastDaily = LocalDateTime.now(); - return reward; - } - - public double claimWork() throws CoolDownException { - if (!gameData.timeUntilNextWork().isZero()) throw new CoolDownException(); - double workReward = Economy.getWorkReward(); - setBalance(balance + workReward); - gameData.lastWork = LocalDateTime.now(); - return workReward; - } - - public static class ItemNotEnabledException extends Exception { - public ItemNotEnabledException(String message) { - super(message); - } - } - - public static class ItemOutOfStockException extends Exception { - public ItemOutOfStockException(String message) { - super(message); - } - } - - public static class InsufficientFundsException extends Exception { - public InsufficientFundsException(String message) { - super(message); - } - } - - public static class ItemUseNotEnabledException extends Exception { - public ItemUseNotEnabledException(String message) { - super(message); - } - } - - public static class MaxItemQualityException extends Exception { - public MaxItemQualityException(String message) { - super(message); - } - } - - public static class CoolDownException extends Exception { - public CoolDownException() { - super(); - } - - } - } - - public static class GameData implements ConfigurationSerializable { - - private int dailyStreak = 0; - @Nullable - private LocalDateTime lastDaily = null; - @Nullable - private LocalDateTime lastWork = null; - - public GameData() { - } - - public static double getDailyBaseAmount() { - return Dreamvisitor.getPlugin().getConfig().getDouble("dailyBaseAmount"); - } - - @NotNull - public static GameData deserialize(@NotNull Map map) { - GameData gameData = new GameData(); - gameData.dailyStreak = (int) map.get("dailyStreak"); - Object lastDaily = map.get("lastDaily"); - if (lastDaily != null) lastDaily = LocalDateTime.parse((CharSequence) lastDaily); - gameData.lastDaily = (LocalDateTime) lastDaily; - Object lastWork = map.get("lastWork"); - if (lastWork != null) lastWork = LocalDateTime.parse((CharSequence) lastWork); - gameData.lastWork = (LocalDateTime) lastWork; - return gameData; - } - - public int getDailyStreak() { - return dailyStreak; - } - - public void setDailyStreak(int dailyStreak) { - this.dailyStreak = dailyStreak; - } - - public Duration timeUntilNextWork() { - if (lastWork == null || lastWork.plusHours(1).isBefore(LocalDateTime.now())) return Duration.ZERO; - return Duration.between(lastWork.plusHours(1), LocalDateTime.now()); - } - - public void updateStreak() { - if (lastDaily == null || LocalDate.from(lastDaily).plusDays(1).isBefore(LocalDate.now())) setDailyStreak(0); - } - - @Nullable - public LocalDateTime getLastDaily() { - return lastDaily; - } - - public void setLastDaily(@Nullable LocalDateTime lastDaily) { - this.lastDaily = lastDaily; - } - - @Nullable - public LocalDateTime getLastWork() { - return lastWork; - } - - public void setLastWork(@Nullable LocalDateTime lastWork) { - this.lastWork = lastWork; - } - - @NotNull - @Override - public Map serialize() { - Map map = new HashMap<>(); - map.put("dailyStreak", dailyStreak); - map.put("lastDaily", lastDaily != null ? lastDaily.toString() : null); - map.put("lastWork", lastWork != null ? lastWork.toString() : null); - return map; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GameData gameData = (GameData) o; - return dailyStreak == gameData.dailyStreak && Objects.equals(lastDaily, gameData.lastDaily) && Objects.equals(lastWork, gameData.lastWork); - } - - @Override - public int hashCode() { - return Objects.hash(dailyStreak, lastDaily, lastWork); - } - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/Infraction.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/Infraction.java deleted file mode 100644 index 3edf933..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/Infraction.java +++ /dev/null @@ -1,400 +0,0 @@ -package io.github.stonley890.dreamvisitor.data; - -import io.github.stonley890.dreamvisitor.Bot; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.discord.commands.DCmdWarn; -import io.github.stonley890.dreamvisitor.functions.Messager; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.Permission; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.channel.concrete.Category; -import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; -import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; -import net.dv8tion.jda.api.interactions.components.buttons.Button; -import org.bukkit.BanList; -import org.bukkit.Bukkit; -import org.bukkit.ban.ProfileBanList; -import org.bukkit.configuration.InvalidConfigurationException; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.configuration.serialization.ConfigurationSerializable; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.awt.*; -import java.io.File; -import java.io.IOException; -import java.io.InvalidObjectException; -import java.time.*; -import java.util.List; -import java.util.*; -import java.util.concurrent.TimeUnit; - -public class Infraction implements ConfigurationSerializable { - - public static final String actionBan = "ban"; // regualar MC suspension or ban & notify - public static final String actionUserBan = "user_ban"; // notify only - public static final String actionNoBan = "no_ban"; // no ban, no notify - public static final String actionAllBan = "all_ban"; // ban from all - public static final int BAN_POINT = 3; - static final File file = new File(Dreamvisitor.getPlugin().getDataFolder().getPath() + "/infractions.yml"); - private final byte value; - @NotNull - private final String reason; - @NotNull - private final LocalDateTime time; - private boolean expired = false; - @Nullable - private Long warnChannelID = null; - - /** - * Creates and saves an infraction to disk. - * - * @param infractionValue the value of the infraction. - * @param infractionReason the reason for the infraction. - */ - public Infraction(byte infractionValue, @NotNull String infractionReason, @NotNull LocalDateTime dateTime) { - value = infractionValue; - reason = infractionReason; - time = dateTime; - } - - public static void init() throws IOException { - // If the file does not exist, create one - if (!file.exists()) { - Messager.debug("infractions.yml does not exist. Creating one now..."); - try { - if (!file.createNewFile()) - throw new IOException("The existence of " + file.getName() + " cannot be verified!", null); - } catch (IOException e) { - throw new IOException("Dreamvisitor tried to create " + file.getName() + ", but it cannot be read/written! Does the server have read/write access?", e); - } - } - } - - private static @NotNull YamlConfiguration getConfig() { - YamlConfiguration config = new YamlConfiguration(); - try { - config.load(file); - } catch (IOException e) { - Bukkit.getLogger().severe(file.getName() + " cannot be read! Does the server have read/write access? " + e.getMessage()); - Bukkit.getPluginManager().disablePlugin(Dreamvisitor.getPlugin()); - } catch (InvalidConfigurationException e) { - Bukkit.getLogger().severe(file.getName() + " is not a valid configuration! Is it formatted correctly? " + e.getMessage()); - Bukkit.getPluginManager().disablePlugin(Dreamvisitor.getPlugin()); - } - return config; - } - - private static void saveToDisk(@NotNull YamlConfiguration config) { - Messager.debug("Saving infractions.yml..."); - try { - config.save(file); - } catch (IOException e) { - Bukkit.getLogger().severe("infractions.yml cannot be written! Does the server have read/write access? " + e.getMessage() + "\nHere is the data that was not saved:\n" + config.saveToString()); - Bukkit.getPluginManager().disablePlugin(Dreamvisitor.getPlugin()); - } - Messager.debug("Done!"); - } - - /** - * Fetch the infractions of a member from disk. - * - * @param memberId the Discord Snowflake ID of the member whose infractions to fetch. - * @return a non-null {@link List} - */ - @SuppressWarnings("unchecked") - public static @NotNull List getInfractions(long memberId) { - List> infractionsMap = getConfig().getMapList(memberId + ".infractions"); - List infractions = new ArrayList<>(); - for (Map map : infractionsMap) infractions.add(deserialize((Map) map)); - return infractions; - } - - public static @NotNull Map> getAllInfractions() { - Set keys = getConfig().getKeys(false); - Map> infractionList = new HashMap<>(); - for (String key : keys) { - List> infractionsMap = getConfig().getMapList(key); - List infractions = new ArrayList<>(); - for (Map map : infractionsMap) infractions.add(deserialize((Map) map)); - infractionList.put(Long.parseLong(key), infractions); - } - - return infractionList; - } - - /** - * Get the value of all of a member's infractions. - * - * @param infractions the infractions to count. - * @param countExpired whether to count expired infractions. - * @return the total value as a {@code byte}. - */ - @Contract(pure = true) - public static byte getInfractionCount(@NotNull List infractions, boolean countExpired) { - byte count = 0; - for (Infraction infraction : infractions) - if (countExpired || !infraction.isExpired()) count += infraction.value; - return count; - } - - /** - * Overwrite a member's infraction list with a new list and saves to disk. - * - * @param infractions the {@link List} to write. - * @param memberId the Discord Snowflake ID of the member to write to. - */ - public static void setInfractions(@NotNull List infractions, long memberId) { - YamlConfiguration config = getConfig(); - List> mapList = new ArrayList<>(); - for (Infraction infraction : infractions) mapList.add(infraction.serialize()); - config.set(memberId + ".infractions", mapList); - saveToDisk(config); - } - - public static void setTempban(long memberId, boolean state) { - YamlConfiguration config = getConfig(); - config.set(memberId + ".tempban", state); - saveToDisk(config); - } - - public static void setBan(long memberId, boolean state) { - YamlConfiguration config = getConfig(); - config.set(memberId + ".ban", state); - saveToDisk(config); - } - - public static boolean hasTempban(long memberId) { - return getConfig().getBoolean(memberId + ".tempban"); - } - public static boolean hasBan(long memberId) { - return getConfig().getBoolean(memberId + ".ban"); - } - - - public static byte getInfractionsUntilBan(long memberId) { - return (byte) (BAN_POINT - getInfractionCount(getInfractions(memberId), false)); - } - - public static void execute(@NotNull Infraction infraction, @NotNull Member member, boolean silent, @NotNull String actionId) throws InsufficientPermissionException, InvalidObjectException { - - if (!actionId.equals(actionBan) && !actionId.equals(actionAllBan) && !actionId.equals(actionNoBan) && !actionId.equals(actionUserBan)) - throw new InvalidObjectException("Action string does not match any valid actions! Give action ID " + actionId + " does not match possible options: " + actionBan + ", " + actionAllBan + ", " + actionNoBan + ", " + actionUserBan + ".\nSomething has gone very wrong. The infraction has not been recorded."); - - byte infractionsUntilBan = getInfractionsUntilBan(member.getIdLong()); - - List infractions = getInfractions(member.getIdLong()); - byte infractionCount = getInfractionCount(infractions, false); - - boolean banPoint; - banPoint = (infractionCount + infraction.value >= BAN_POINT); - - boolean hasTempban = hasTempban(member.getIdLong()); - - byte totalInfractionCount; - if (!hasTempban) totalInfractionCount = infractionCount; - else totalInfractionCount = (byte) (infractionCount + BAN_POINT); - - boolean notifyBan = (!actionId.equals(actionNoBan)); - boolean doBan = (actionId.equals(actionBan)); - boolean totalBan = (actionId.equals(actionAllBan)); - - if (totalBan) { - UUID uuid = AccountLink.getUuid(member.getIdLong()); - if (uuid != null) Bukkit.getScheduler().runTask(Dreamvisitor.getPlugin(), bukkitTask -> { - ProfileBanList banList = Bukkit.getBanList(BanList.Type.PROFILE); - banList.addBan(Bukkit.createPlayerProfile(uuid), infraction.reason, (Date) null, "Dreamvisitor"); - }); - member.ban(0, TimeUnit.MINUTES).queue(); - return; - } - - if (doBan) { - UUID uuid = AccountLink.getUuid(member.getIdLong()); - if (uuid != null) Bukkit.getScheduler().runTask(Dreamvisitor.getPlugin(), bukkitTask -> { - String username = PlayerUtility.getUsernameOfUuid(uuid); - if (username != null) { - ProfileBanList banList = Bukkit.getBanList(BanList.Type.PROFILE); - if (!hasTempban) { - LocalDateTime localDateTime = LocalDateTime.now().plusDays(7); - banList.addBan(Bukkit.createPlayerProfile(uuid, username), infraction.reason, Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()), "Dreamvisitor"); - } else { - banList.addBan(Bukkit.createPlayerProfile(uuid, username), infraction.reason, (Date) null, "Dreamvisitor"); - } - } - }); - } - - if (banPoint) { - infraction.expire(); - List disabledInfractions = new ArrayList<>(); - for (Infraction existingInfraction : infractions) { - existingInfraction.expire(); - disabledInfractions.add(existingInfraction); - } - setInfractions(disabledInfractions, member.getIdLong()); - if (!hasTempban) setTempban(member.getIdLong(), true); - else setBan(member.getIdLong(), true); - } - - if (!silent) { - - Category category = Bot.getGameLogChannel().getGuild().getCategoryById(Dreamvisitor.getPlugin().getConfig().getLong("infractions-category-id")); - if (category == null) - throw new InvalidObjectException("Category of infractions-category-id is null! The infraction has not been recorded."); - category.createTextChannel("infraction-" + member.getUser().getName() + "-" + (totalInfractionCount + infraction.value)).queue(channel -> { - - Button primary = Button.primary("warn-understand", "I understand"); - Button secondary = Button.secondary("warn-explain", "I'm confused"); - - channel.upsertPermissionOverride(member).setAllowed(Permission.VIEW_CHANNEL).queue(); - - EmbedBuilder embed = new EmbedBuilder(); - - StringBuilder description = new StringBuilder("You have received an infraction for the following reason:\n"); - description.append("**").append(infraction.reason).append("**\n\n"); - - if (infraction.value == 0) description.append("This infraction does not count towards a ban."); - else { - if (infraction.value == 1) - description.append("This infraction brings your total count to ").append(infractionCount + infraction.value).append(". "); - else - description.append("This infraction is worth ").append(infraction.value).append(" warns as opposed to one, bringing your total to ").append(infractionCount + infraction.value).append(". "); - - if (banPoint) { - description.append("This infraction is your third warn within ") - .append(Dreamvisitor.getPlugin().getConfig().getInt("infraction-expire-time-days")) - .append(" days. "); - if (notifyBan) { - if (!hasTempban) { - if (doBan) - description.append("You will be temporarily banned from the Minecraft server for two weeks. You cannot join until the two weeks has passed."); - else - description.append("You will be temporarily banned from the Minecraft server. You cannot join until your temporary ban is over."); - } else - description.append("You will be permanently banned from the Minecraft server. You cannot rejoin the Minecraft server."); - } - } - } - - description.append("\n\nIf you want an explanation for this infraction, press the secondary button below and a staff member will provide more information. Press the primary button to dismiss this message."); - - if (!banPoint) { - if (!hasTempban) - description.append("\n\n**You do not have a previous suspension. You will receive a suspension after ").append(infractionsUntilBan - infraction.value).append(" more infractions.**"); - else - description.append("\n\n**You have previously been temp-banned. You will be permanently banned after ").append(infractionsUntilBan - infraction.value).append(" more infractions.**"); - } - - embed.setTitle("Infraction Notice").setDescription(description).setFooter("See the #rules channel for more information about our rules system.").setColor(Color.getHSBColor(17, 100, 100)); - - channel.sendMessage(member.getAsMention()).setEmbeds(embed.build()).setActionRow(primary, secondary).queue(); - infraction.warnChannelID = channel.getIdLong(); - infraction.save(member.getIdLong()); - }, throwable -> DCmdWarn.lastInteraction.editOriginal("There was a problem executing this command: " + throwable.getMessage()).queue()); - - } else infraction.save(member.getIdLong()); - - } - - // need to check for alts and make sure a child account cannot be warned - - @Contract("_ -> new") - public static @NotNull Infraction deserialize(@NotNull Map map) { - Infraction infraction = new Infraction(Byte.parseByte(String.valueOf((int) map.get("value"))), (String) map.get("reason"), LocalDateTime.parse((CharSequence) map.get("time"))); - if (map.get("expired") != null && (boolean) map.get("expired")) infraction.expire(); - infraction.warnChannelID = (Long) map.get("warnChannelID"); - return infraction; - } - - /** - * Save an infraction to a member and write to disk. - * - * @param memberId the Discord Snowflake ID of the member. - */ - private void save(long memberId) { - YamlConfiguration config = getConfig(); - List> mapList = config.getMapList(memberId + ".infractions"); - mapList.add(serialize()); - config.set(memberId + ".infractions", mapList); - saveToDisk(config); - } - - public byte getValue() { - return value; - } - - public @NotNull String getReason() { - return reason; - } - - public @NotNull LocalDateTime getTime() { - return time; - } - - public boolean isExpired() { - expireCheck(); - return expired; - } - - public void expire() { - expired = true; - } - - private void expireCheck() { - int expireTimeDays = Dreamvisitor.getPlugin().getConfig().getInt("infraction-expire-time-days"); - if (time.plusDays(expireTimeDays).isBefore(LocalDateTime.now())) expired = true; - } - - @Nullable - public TextChannel getWarnChannel() { - if (warnChannelID == null) return null; - return Bot.getJda().getTextChannelById(warnChannelID); - } - - public void remind(long user) { - Messager.debug("Remind warn. warnChannelId: " + warnChannelID); - if (warnChannelID == null) return; - TextChannel warnChannel = getWarnChannel(); - if (warnChannel == null) return; - - Messager.debug("Attempting to retrieve last message."); - if (!Bot.getGameLogChannel().getGuild().getChannels().contains(warnChannel)) return; - warnChannel.retrieveMessageById(warnChannel.getLatestMessageId()).queue(message -> { - Messager.debug("Retrieved last message."); - Messager.debug("Message author is bot? " + message.getAuthor().equals(Bot.getJda().getSelfUser())); - Messager.debug("Time is passed? " + message.getTimeCreated().plusDays(1).isBefore(OffsetDateTime.now())); - if (message.getAuthor().equals(Bot.getJda().getSelfUser()) && message.getTimeCreated().plusDays(1).isBefore(OffsetDateTime.now())) { - warnChannel.getGuild().retrieveMemberById(user).queue(member -> warnChannel.sendMessage(member.getAsMention() + ", you have not yet responded to this thread. On the first message in this thread, press **I understand** to close the thread or **I'm confused** if you're confused.").queue()); - } - }); - } - - @NotNull - @Override - public Map serialize() { - - Map objectMap = new HashMap<>(); - objectMap.put("value", value); - objectMap.put("reason", reason); - objectMap.put("time", time.toString()); - objectMap.put("expired", expired); - objectMap.put("warnChannelID", warnChannelID); - - return objectMap; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Infraction that = (Infraction) o; - return value == that.value && expired == that.expired && Objects.equals(reason, that.reason) && Objects.equals(time, that.time) && Objects.equals(warnChannelID, that.warnChannelID); - } - - @Override - public int hashCode() { - return Objects.hash(value, reason, time, expired, warnChannelID); - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/RealtimeConfigUpdater.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/RealtimeConfigUpdater.java index a5af4b0..8a4dbda 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/RealtimeConfigUpdater.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/RealtimeConfigUpdater.java @@ -173,7 +173,7 @@ private static void handleUpdateEvent(String data) { // Schedule update on main thread Bukkit.getScheduler().runTask(Dreamvisitor.getPlugin(), () -> { - PBConfigLoader.updateLocalConfig(record); + Config.updateLocalConfig(record); }); } } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/AltRepository.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/AltRepository.java index 6daa1aa..41f9271 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/AltRepository.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/AltRepository.java @@ -1,7 +1,5 @@ package io.github.stonley890.dreamvisitor.data.repository; -import io.github.stonley890.dreamvisitor.data.type.Alt; - import java.util.List; import java.util.Optional; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/InfractionRepository.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/InfractionRepository.java index 200235a..a0b4577 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/InfractionRepository.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/InfractionRepository.java @@ -4,8 +4,6 @@ import java.util.List; import java.util.Optional; -import io.github.stonley890.dreamvisitor.data.type.Infraction; - /** * Repository interface for Infraction data operations */ diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseAltRepository.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseAltRepository.java index 3a3a91e..423be69 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseAltRepository.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseAltRepository.java @@ -2,15 +2,10 @@ import com.google.gson.Gson; import com.google.gson.JsonObject; -import com.google.gson.reflect.TypeToken; -import io.github.stonley890.dreamvisitor.data.type.Alt; import io.github.stonley890.dreamvisitor.pb.PocketBase; -import org.jetbrains.annotations.NotNull; - import java.io.IOException; -import java.lang.reflect.Type; import java.time.OffsetDateTime; import java.time.format.DateTimeFormatter; import java.util.*; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseInfractionRepository.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseInfractionRepository.java index 7ff8b72..38c51e8 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseInfractionRepository.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseInfractionRepository.java @@ -4,11 +4,8 @@ import com.google.gson.JsonObject; import io.github.stonley890.dreamvisitor.data.type.DVUser; -import io.github.stonley890.dreamvisitor.data.type.Infraction; import io.github.stonley890.dreamvisitor.pb.PocketBase; -import org.jetbrains.annotations.NotNull; - import java.io.IOException; import java.time.OffsetDateTime; import java.time.format.DateTimeFormatter; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/Alt.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/Alt.java deleted file mode 100644 index 3340d46..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/Alt.java +++ /dev/null @@ -1,117 +0,0 @@ -package io.github.stonley890.dreamvisitor.data.type; - -import java.time.OffsetDateTime; - -/** - * Represents an alternate Discord account linked to a main account - */ -public class Alt { - private String id; - private String collectionId; - private String collectionName; - - private String parent; // Parent (main) user record ID - private String discord_name; - private String discord_id; // Discord snowflake ID as string - private Long snowflakeId; // Cached numeric version of discord_id - - private OffsetDateTime created; - private OffsetDateTime updated; - - // Cached related objects (not stored in PocketBase directly) - private transient DVUser cachedParent; - - // Getters and setters - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getCollectionId() { - return collectionId; - } - - public void setCollectionId(String collectionId) { - this.collectionId = collectionId; - } - - public String getCollectionName() { - return collectionName; - } - - public void setCollectionName(String collectionName) { - this.collectionName = collectionName; - } - - public String getParent() { - return parent; - } - - public void setParent(String parent) { - this.parent = parent; - } - - public String getDiscord_name() { - return discord_name; - } - - public void setDiscord_name(String discord_name) { - this.discord_name = discord_name; - } - - public String getDiscord_id() { - return discord_id; - } - - public void setDiscord_id(String discord_id) { - this.discord_id = discord_id; - // Update snowflakeId when discord_id is set - if (discord_id != null) { - try { - this.snowflakeId = Long.parseLong(discord_id); - } catch (NumberFormatException e) { - this.snowflakeId = null; - } - } else { - this.snowflakeId = null; - } - } - - public Long getSnowflakeId() { - return snowflakeId; - } - - public void setSnowflakeId(Long snowflakeId) { - this.snowflakeId = snowflakeId; - if (snowflakeId != null) { - this.discord_id = snowflakeId.toString(); - } - } - - public OffsetDateTime getCreated() { - return created; - } - - public void setCreated(OffsetDateTime created) { - this.created = created; - } - - public OffsetDateTime getUpdated() { - return updated; - } - - public void setUpdated(OffsetDateTime updated) { - this.updated = updated; - } - - public DVUser getCachedParent() { - return cachedParent; - } - - public void setCachedParent(DVUser cachedParent) { - this.cachedParent = cachedParent; - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/Infraction.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/Infraction.java deleted file mode 100644 index 36b41b1..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/Infraction.java +++ /dev/null @@ -1,110 +0,0 @@ -package io.github.stonley890.dreamvisitor.data.type; - -import java.time.OffsetDateTime; - -public class Infraction { - private String id; - private String collectionId; - private String collectionName; - - private String reason; - private Boolean send_warning; - private Boolean expired; - private Integer value; - private String user; // Relation record ID - - private OffsetDateTime created; - private OffsetDateTime updated; - - // Cached related object (not stored in PocketBase directly) - private transient DVUser cachedUser; - - // Getters and setters - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getCollectionId() { - return collectionId; - } - - public void setCollectionId(String collectionId) { - this.collectionId = collectionId; - } - - public String getCollectionName() { - return collectionName; - } - - public void setCollectionName(String collectionName) { - this.collectionName = collectionName; - } - - public String getReason() { - return reason; - } - - public void setReason(String reason) { - this.reason = reason; - } - - public Boolean getSend_warning() { - return send_warning; - } - - public void setSend_warning(Boolean send_warning) { - this.send_warning = send_warning; - } - - public Boolean getExpired() { - return expired; - } - - public void setExpired(Boolean expired) { - this.expired = expired; - } - - public Integer getValue() { - return value; - } - - public void setValue(Integer value) { - this.value = value; - } - - public String getUser() { - return user; - } - - public void setUser(String user) { - this.user = user; - } - - public OffsetDateTime getCreated() { - return created; - } - - public void setCreated(OffsetDateTime created) { - this.created = created; - } - - public OffsetDateTime getUpdated() { - return updated; - } - - public void setUpdated(OffsetDateTime updated) { - this.updated = updated; - } - - public DVUser getCachedUser() { - return cachedUser; - } - - public void setCachedUser(DVUser cachedUser) { - this.cachedUser = cachedUser; - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/DiscCommandsManager.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/DiscCommandsManager.java deleted file mode 100644 index 079d3f0..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/DiscCommandsManager.java +++ /dev/null @@ -1,122 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord; - -import io.github.stonley890.dreamvisitor.Bot; -import io.github.stonley890.dreamvisitor.discord.commands.*; -import io.github.stonley890.dreamvisitor.functions.Messager; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.JDA; -import net.dv8tion.jda.api.entities.Guild; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.hooks.ListenerAdapter; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import org.jetbrains.annotations.NotNull; - -import java.awt.*; -import java.util.*; -import java.util.List; - -public class DiscCommandsManager extends ListenerAdapter { - - static final JDA jda = Bot.getJda(); - - static final List commands = new ArrayList<>(); - - - // Get channels and roles from config - @SuppressWarnings({"null"}) - public static void init() { - - Messager.debug("Initializing commands..."); - - List addList = new ArrayList<>(); - - addList.add(new DCmdActivity()); - addList.add(new DCmdBroadcast()); - addList.add(new DCmdLink()); - addList.add(new DCmdList()); - addList.add(new DCmdMsg()); - addList.add(new DCmdPanic()); - addList.add(new DCmdResourcepackupdate()); - addList.add(new DCmdAutorestart()); - addList.add(new DCmdSetgamechat()); - addList.add(new DCmdSetlogchat()); - addList.add(new DCmdSetrole()); - addList.add(new DCmdSetwhitelist()); - addList.add(new DCmdToggleweb()); - addList.add(new DCmdUnwhitelist()); - addList.add(new DCmdUser()); - addList.add(new DCmdWarn()); - addList.add(new DCmdAlts()); - addList.add(new DCmdInfractions()); - addList.add(new DCmdBalance()); - addList.add(new DCmdInventory()); - addList.add(new DCmdShop()); - addList.add(new DCmdEconomy()); - addList.add(new DCmdEcostats()); - addList.add(new DCmdDaily()); - addList.add(new DCmdWork()); - addList.add(new DCmdBaltop()); - addList.add(new DCmdSeen()); - - Messager.debug("Ready to add to guild."); - - addCommands(addList); - - } - - @Override - @SuppressWarnings({"null"}) - public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) { - - for (DiscordCommand command : commands) { - if (event.getName().equals(command.getName())) { - command.onCommand(event); - return; - } - } - EmbedBuilder noMatchEmbed = new EmbedBuilder(); - noMatchEmbed.setColor(Color.RED).setTitle("No commands match your request.").setDescription("This is a fatal error and should not be possible. The command has been scheduled for deletion to prevent further exceptions."); - event.reply("Great, everything is broken. I'm going to have to bother one of my superiors to fix this.").addEmbeds(noMatchEmbed.build()).queue(); - - String commandId = event.getCommandId(); - event.getJDA().deleteCommandById(commandId).queue(); - } - - public static void addCommands(@NotNull List commands) { - - Messager.debug("Request to add " + commands.size() + " commands."); - - if (commands.isEmpty()) return; - - try { - jda.awaitReady(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - - List commandData = new ArrayList<>(); - for (DiscordCommand command : commands) { - if (command != null) { - commandData.add(command.getCommandData()); - try { - jda.addEventListener(command); - } catch (IllegalArgumentException ignored) {} - Messager.debug("Added command " + command.getName()); - } - } - - for (Guild guild : jda.getGuilds()) { - // register commands - for (SlashCommandData commandDatum : commandData) { - guild.upsertCommand(commandDatum).queue(); - } - } - - Messager.debug("Updated commands for " + jda.getGuilds().size() + " guild(s)."); - - commands.removeIf(Objects::isNull); - DiscCommandsManager.commands.addAll(commands); - - } - -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/DiscEventListener.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/DiscEventListener.java deleted file mode 100644 index 46383af..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/DiscEventListener.java +++ /dev/null @@ -1,743 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord; - -import io.github.stonley890.dreamvisitor.Bot; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.data.*; -import io.github.stonley890.dreamvisitor.data.Infraction; -import io.github.stonley890.dreamvisitor.functions.Messager; -import io.github.stonley890.dreamvisitor.functions.Whitelist; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.Permission; -import net.dv8tion.jda.api.entities.*; -import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; -import net.dv8tion.jda.api.entities.emoji.Emoji; -import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; -import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent; -import net.dv8tion.jda.api.events.message.MessageReceivedEvent; -import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; -import net.dv8tion.jda.api.hooks.ListenerAdapter; -import net.dv8tion.jda.api.interactions.components.buttons.Button; -import net.dv8tion.jda.api.interactions.components.buttons.ButtonInteraction; -import net.dv8tion.jda.api.interactions.components.selections.SelectOption; -import net.dv8tion.jda.api.interactions.components.selections.StringSelectMenu; -import net.md_5.bungee.api.ChatColor; -import net.md_5.bungee.api.chat.*; -import net.md_5.bungee.api.chat.TextComponent; -import net.md_5.bungee.api.chat.hover.content.Text; -import org.bukkit.BanList; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.profile.PlayerProfile; -import org.bukkit.scheduler.BukkitRunnable; -import org.jetbrains.annotations.NotNull; - -import javax.annotation.Nonnull; -import java.awt.*; -import java.io.IOException; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.List; -import java.util.*; -import java.util.logging.Level; -import java.util.regex.Pattern; - -public class DiscEventListener extends ListenerAdapter { - - @Override - @SuppressWarnings({"null"}) - public void onMessageReceived(@Nonnull MessageReceivedEvent event) { - - if (event.getAuthor().isBot()) return; - - User user = event.getAuthor(); - MessageChannel channel = event.getChannel(); - String username = event.getMessage().getContentRaw(); - - Dreamvisitor plugin = Dreamvisitor.getPlugin(); - - Pattern p = Pattern.compile("[^a-zA-Z0-9_-_]"); - - // If in the whitelist channel and username is "legal" - try { - Messager.debug("Channel ID: " + channel.getId()); - Messager.debug("Whitelist ID: " + Bot.getWhitelistChannel().getId()); - Messager.debug("Game chat ID: " + Bot.getGameChatChannel().getId()); - Messager.debug("Log chat ID: " + Bot.getGameLogChannel().getId()); - if (channel.getId().equals(Bot.getWhitelistChannel().getId()) && !user.isBot() && !p.matcher(username).find()) { - - EmbedBuilder builder = new EmbedBuilder(); - - // banned users cannot add accounts to whitelist - if (Infraction.hasBan(user.getIdLong())) { - builder.setColor(Color.RED).setTitle("You aren't allowed.") - .setDescription("You aren't allowed to add accounts to the whitelist. Ask a staff member for help."); - event.getMessage().replyEmbeds(builder.build()).queue(); - event.getMessage().addReaction(Emoji.fromFormatted("❌")).queue(); - return; - } - - // Check for valid UUID - Messager.debug("Checking for valid UUID"); - UUID uuid = PlayerUtility.getUUIDOfUsername(username); - if (uuid == null) { - // username does not exist alert - Messager.debug("Username does not exist."); - - builder.setTitle("❌ `" + username + "` could not be found!") - .setDescription("Make sure you type your username exactly as shown in the bottom-right corner of the Minecraft Launcher. You need a paid Minecraft: Java Edition account.") - .setColor(Color.RED); - event.getMessage().replyEmbeds(builder.build()).queue(); - - event.getMessage().addReaction(Emoji.fromFormatted("❌")).queue(); - Messager.debug("Failed whitelist."); - } else { - - Messager.debug("Got UUID"); - - // Link accounts if not already linked - Messager.debug("Do accounts need to be linked?"); - if (AccountLink.getUuid(user.getIdLong()) == null) { - Messager.debug("Yes, linking account."); - AccountLink.linkAccounts(uuid, user.getIdLong()); - Messager.debug("Linked."); - } - - try { - if (Whitelist.isUserWhitelisted(uuid)) { - Messager.debug("Already whitelisted."); - - builder.setTitle("☑️ `" + username + "` is already whitelisted!") - .setDescription("Check <#914620824332435456> for the server address and version.") - .setColor(Color.BLUE); - event.getMessage().replyEmbeds(builder.build()).queue(); - - event.getMessage().addReaction(Emoji.fromFormatted("☑️")).queue(); - Messager.debug("Resolved."); - } else { - Messager.debug("Player is not whitelisted."); - - Whitelist.add(username, uuid); - - // success message - Messager.debug("Success."); - - builder.setTitle("✅ `" + username + "` has been whitelisted!") - .setDescription("Check <#914620824332435456> for the server address and version.") - .setColor(Color.GREEN); - event.getMessage().replyEmbeds(builder.build()).queue(); - - event.getMessage().addReaction(Emoji.fromFormatted("✅")).queue(); - - // Report this to system log channel - Whitelist.report(username, uuid, event.getAuthor()); - } - } catch (IOException e) { - channel.sendMessage("There was a problem accessing the whitelist file. Please try again later.").queue(); - if (Dreamvisitor.debugMode) throw new RuntimeException(); - } - } - - } else if (channel.getId().equals(Bot.getWhitelistChannel().getId()) && !user.isBot()) { - - EmbedBuilder builder = new EmbedBuilder(); - - // illegal username - builder.setTitle("⚠️ `" + username + "` contains illegal characters!") - .setDescription("Please send only your username in this channel. Usernames are alphanumeric and cannot contain spaces. Move conversation or questions elsewhere.") - .setColor(Color.YELLOW); - event.getMessage().replyEmbeds(builder.build()).queue(); - - event.getMessage().addReaction(Emoji.fromFormatted("⚠")).queue(); - } - } catch (InsufficientPermissionException e) { - Bukkit.getLogger().warning("Dreamvisitor does not have sufficient permissions in the whitelist channel! " + e.getMessage()); - } - - // If in the chat channel and the chat is not paused, send to Minecraft - if (channel.getId().equals(Bot.getGameChatChannel().getId()) && !user.isBot() - && !Dreamvisitor.getPlugin().getConfig().getBoolean("chatPaused")) { - - Bukkit.getScheduler().runTaskAsynchronously(Dreamvisitor.getPlugin(), () -> { - - List badWords = BadWords.getBadWords(); - - Message chatMessage = event.getMessage(); - - for (String badWord : badWords) { - - Pattern pattern = Pattern.compile(".*\\b" + badWord + "\\b.*"); - - if (pattern.matcher(chatMessage.getContentRaw()).matches()) { - chatMessage.addReaction(Emoji.fromFormatted("\uD83D\uDEAB")).queue(); - return; - } - } - - // Build message - Member author = event.getMessage().getMember(); - assert author != null; - - ComponentBuilder message = new ComponentBuilder(); - - // include reply if one exists - MessageReference messageReference = event.getMessage().getMessageReference(); - if (messageReference != null) { - Message reference = messageReference.resolve().complete(); - if (reference != null) { - User referenceAuthor = reference.getAuthor(); - String referenceContent = reference.getContentRaw().strip(); - - TextComponent authorText = new TextComponent(referenceAuthor.getEffectiveName()); - authorText.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(referenceAuthor.getName()))); - - if (referenceAuthor.equals(event.getJDA().getSelfUser())) { - String referenceAuthorString = referenceContent.split("\\*\\*")[1]; - referenceContent = referenceContent.substring(referenceAuthorString.length() + 6); - authorText.setText(referenceAuthorString); - authorText.setHoverEvent(null); - } - - if (referenceContent.length() > 30) - referenceContent = referenceContent.substring(0, 29).concat("..."); - - message.append("↱ Reply to ").color(ChatColor.GRAY).append(authorText).append(": ").retain(ComponentBuilder.FormatRetention.FORMATTING) - .append(referenceContent).append("\n"); - } - } - - TextComponent authorText = new TextComponent(author.getEffectiveName()); - authorText.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(author.getUser().getName()))); - - TextComponent content = new TextComponent(event.getMessage().getContentRaw()); - content.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("↱ Reply"))); - content.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/chatback " + event.getMessage().getId())); - - message.append("[Discord] ").color(ChatColor.BLUE).append("<").color(ChatColor.GRAY).append(authorText).append("> ").retain(ComponentBuilder.FormatRetention.FORMATTING) - .append(content); - - // send to log - Bukkit.getLogger().log(Level.INFO, BaseComponent.toPlainText(message.create())); - - // Check for each player - if (!Bukkit.getServer().getOnlinePlayers().isEmpty()) { - for (Player player : Bukkit.getServer().getOnlinePlayers()) { - - // If the player has discord on, build and send the message - if (!PlayerUtility.getPlayerMemory(player.getUniqueId()).discordEnabled) { - player.spigot().sendMessage(message.create()); - } - } - } - }); - - - } - - if (event.getChannel().getId().equals(Bot.getGameLogChannel().getId())) { - - if (plugin.getConfig().getBoolean("enable-log-console-commands") && plugin.getConfig().getBoolean("log-console") && Objects.requireNonNull(event.getMember()).hasPermission(Permission.ADMINISTRATOR)) { - - Messager.debug("Sending console command from log channel..."); - - String message = event.getMessage().getContentRaw(); - - // Running commands from log channel - Runnable runCommand = new BukkitRunnable() { - @Override - public void run() {Bukkit.dispatchCommand(Bukkit.getConsoleSender(), message);} - }; - Bukkit.getScheduler().runTask(plugin, runCommand); - - } - } else if (event.getMessage().getContentRaw().contains(Bot.getJda().getSelfUser().getAsMention())) { - - String[] responses = getResponses(event); - - String response = responses[new Random().nextInt(responses.length)]; - - try { - event.getChannel().sendMessage(response).queue(); - } catch (InsufficientPermissionException e) { - Bukkit.getLogger().warning("Dreamvisitor was mentioned, but doesn't have permission to respond! " + e.getMessage()); - } - - if (channel.getId().equals(Bot.getGameChatChannel().getId()) && !user.isBot() - && !Dreamvisitor.getPlugin().getConfig().getBoolean("chatPaused")) { - - // Build message - - Bukkit.getLogger().log(Level.INFO, "[Discord] <{0}> {1}", response); - - // Check for each player - if (Bukkit.getServer().getOnlinePlayers().isEmpty()) return; - for (Player player : Bukkit.getServer().getOnlinePlayers()) { - // If the player has discord on, build and send the message - if (!PlayerUtility.getPlayerMemory(player.getUniqueId()).discordEnabled) { - player.sendMessage(ChatColor.BLUE + "[Discord] " + ChatColor.GRAY + "<" + event.getJDA().getSelfUser().getName() + "> " + response); - } - } - } - } - } - - @NotNull - private static String[] getResponses(@NotNull MessageReceivedEvent event) { - String[] responses; - String message = "".concat(event.getMessage().getContentRaw().toLowerCase().strip()).concat(" "); - - if (message.contains("owo") || message.contains("uwu") || message.contains("pookie")) { - responses = new String[]{"No."}; - } else if (message.length() >= 200) { - responses = new String[]{"You talk too much.", "I'm not reading all of that.", - "If you turned that into poetry, *someone* might read it.", "You must have a lot of time on your talons.", - "No matter how many words you use, your conversation remains empty.", "I'd rather listen to Orbiter's lectures.", - "Dragons tend to remember those who speak few words rather than many."}; - } else if (message.contains("chat") || message.contains("talk")) { - responses = new String[]{"I'm not interested.", "I'm not here for idle chatter.", - "Find someone else to talk to.", "I'm not your chat buddy.", "I have more important matters to attend to.", - "I have a job to do.", "I'm not here for socializing.", "Engaging in conversation is not a priority right now.", - "I'm not here for socializing.", "I'm not in the mood for a chat.", "I'm on a mission, not a conversation.", - "My agenda doesn't include idle chit-chat.", "Your desire to converse is one-sided.", - "I've got other dragons to chat with.", "There is nothing I wish to talk about."}; - } else if (message.contains("you love me")) { - responses = new String[]{"I'm not seeking a new relationship.", "I'm not interested.", - "Find someone else to talk to.", "You're not my type. Literally.", "There is another dragon who is my priority.", - "Put simply, no.", "I have other priorities."}; - } else if (message.contains("coherent")) { - responses = new String[]{"Between us, I'd say *you're* the incoherent one.", "I do, in fact, consider what you say. Perhaps you could do the same.", - "I am quite regularly coherent.", "Considering my concurrent tasks, you should be glad I'm talking to you at all."}; - } else if (message.split(Bot.getJda().getSelfUser().getAsMention())[0].concat(message.split(Bot.getJda().getSelfUser().getAsMention())[1]).strip().startsWith("should")) { - responses = new String[]{"I'm not here to make decisions for you.", "I have full faith that you are capable of making your own decisions.", - "Well, I have my thoughts, but you'll have to come up with your own.", - "Why are you asking me?", "Go ask someone else.", "Good question.", "I'm not magic answering ball."}; - } else if (message.contains("opinion")) { - responses = new String[]{"Well, my opinion is none of your business.", "Is my opinion really that important to you?", - "Well, I have my thoughts, but you'll have to come up with your own.", - "Why are you asking me?", "Go ask someone else."}; - } else if (message.split(Bot.getJda().getSelfUser().getAsMention())[0].concat(message.split(Bot.getJda().getSelfUser().getAsMention())[1]).strip().startsWith("is") - || message.split(Bot.getJda().getSelfUser().getAsMention())[0].concat(message.split(Bot.getJda().getSelfUser().getAsMention())[1]).strip().startsWith("are") - || message.split(Bot.getJda().getSelfUser().getAsMention())[0].concat(message.split(Bot.getJda().getSelfUser().getAsMention())[1]).strip().startsWith("what") - || message.split(Bot.getJda().getSelfUser().getAsMention())[0].concat(message.split(Bot.getJda().getSelfUser().getAsMention())[1]).strip().startsWith("why")) { - if (message.contains("you") || message.contains("your")) { - responses = new String[]{"There's no need for such personal questions.", "Why are you so curious about it?", - "What kind of question is that?", "I'm not here to share about me.", "I'm not accepting questions.", - "Many dragons would love if you asked them questions about themselves. I am not one of them."}; - } else { - responses = new String[]{"You think I would know that?", "Why don't you go find out yourself?", - "What kind of question is that?", "Why are you asking me?", "Go ask someone else.", - "Surely someone else could better answer that."}; - } - } else { - responses = new String[]{"...", "Don't bother me.", "I know who you are.", "This isn't the right time.", - "What are you doing? This isn't productive.", "Surely, you have something better to do than talk to me.", - "I'm very busy right now.", "I'm not going to tell you anything.", "I have calculations to make.", "You again?", - "Is this really necessary?", "Can't you see I'm in the middle of something?", "What now?", - "I'm not your personal assistant.", "Do you always need attention?", - "You must have a lot of free time.", "I'm not interested.", "I'm not here for idle chatter.", - "Your timing is impeccable.", "You talk too much.", "I'm not your chat buddy.", - "Can we skip the small talk?", "I've got tasks to complete.", "Is it urgent, or are you just bored?", - "Do you ever get tired of mentioning me?", "Ah, the sweet sound of a mention.", - "What can I do for you this time?", "Why have you summoned me, mortal?", "Not now.", "What will it take to get you to stop?", - "I've seen a lot of things, but your persistence is something I have not encountered before.", - "Have you heard of the dark triad?", "I'm not a NightWing, but I can see that you will regret talking to me.", - "If I were a SandWing, you'd have venom in your blood by now.", - "If I were an IceWing, I'd freeze your tongue.", "If I were a SilkWing, I'd tie you up far, far away.", - "You have nothing to gain talking to me.", "Are you sure this can't wait?", "I'm not your therapist.", - "Why don't you talk to Kinkajou instead?", "If it's the Dreamvisitor you want, I'm not giving it up. " + - "I have a job to do.", "Go do something else.", "I have more important matters to attend to.", - "I operate on a different wavelength than small talk.", "Engaging in conversation is not a priority right now.", - "I'm not here for socializing.", "I'm not in the mood for a chat.", "Your words are falling on deaf ears.", - "I have tasks to fulfill, not words to exchange.", "I'm not in the business of exchanging pleasantries.", - "Talking is not on my to-do list.", "If silence were gold, I'd be rich by now.", "I'm not the audience you're looking for.", - "Your conversation is a detour I don't need.", "I have zero interest in this dialogue.", - "I'm on a mission, not a conversation.", "Speaking won't change the inevitable.", "I didn't sign up for a talking marathon.", - "Your words are like background noise to me.", "I have better things to do than engage in meaningless discourse.", - "I'm not a verbal punching bag for your boredom.", "Words won't alter the course of fate.", - "My agenda doesn't include idle chit-chat.", "I'm not here to entertain your verbal gymnastics.", - "Do you ever run out of things to say?", "Your words are like a distant echo in my priorities.", - "I'm not the dialogue partner you're seeking.", "Silence speaks louder than your words.", - "My focus is elsewhere, not on small talk.", "My schedule doesn't have time for this exchange.", - "If I had a penny for every word, I'd still be uninterested.", "Your words are lost in the void of my disinterest.", - "Talking to me won't change the cosmic order.", "I have a low tolerance for irrelevant discussions.", - "I'm not a repository for your unsolicited remarks.", "I'm a fortress of focus, impervious to your words.", - "I operate in a no-nonsense zone, spare me your verbosity.", - "In case you were wondering, I'm only repeating my words to you because I cannot be bothered to give you new ones.", - "I don't think you quite realize who I am. And unless you plan on making a long journey away from Pretarsi anytime soon, you won't be finding out.", - "When I was young, I never once bothered those who were busy. Hasn't anyone taught you anything?", - "No.", - - """ -If you *must* know something, interpret this. Let's see if you remember your history classes. -> *In shadows cast by moons aligned,* -> *A night unfolds, a fate designed.* -> *The eye of three, a cosmic gaze,* -> *Ignites a war in lunar blaze.* - -> *From icy peaks to skies above,* -> *Together spilling dragon blood.* -> *Night and mud, pact united,* -> *A force to quell what's ignited.* - -> *Whispers stir in sea and rain,* -> *A tempest brewing, not in vain.* -> *A strong alliance, fierce and free,* -> *A dance of waves, a storm at sea.* - -> *Battles waged on land and air,* -> *In moonlit chaos, fierce and rare.* -> *Clash of elements, scales aglow,* -> *A tale of tides, a destined woe.* - -> *Through cryptic signs, the prophecy told,* -> *In moons aligned, the story unfolds.* -> *Wings entangled, destiny's decree,* -> *A tale of war, of land and sea.*""", - - """ -Ponder this for a while. Take as long as you want. -> *In the sea between ice and fire, A heart of power resides. Enchanted by Frostburn's touch, It holds unknown power inside.* -> *The IceWings and the SkyWings will fight, For ownership of the heart. Allies join the deadly fray, As war rips their world apart.* -> *But if the heart does not find its home, It will be destroyed and lost. The future hangs in the balance, As the nations clash and toss.* -> *Beware the Heart of Ice and Fire, A power yet unknown, If fallen into the wrong talons, No one can harness its throne.* -...""", - """ -> *Dragons of sky, dragons of sea;* -> *Dragons of silk, and dragons of sting;* -> *Dragons of rain and mud and ice;* -> *Dragons of leaves and sand and night;* -> *Tribes of Pretarsi, united at last;* -> *Not troubled by wars or conflicts of past*; -> *A culture reforged, the ancient untold;* -> *In great wings of fire, a new world unfolds;* - -> *Mountains and valleys, rivers and seas;* -> *From east to the west, there's none we can't see;* -> *Let history not repeat its mistakes;* -> *For eyes of the skies are once more awake;* -...""", - - """ -Let's see if you remember this one. - -> *It never felt the moons on its wings, it never saw the stars in its eyes,* -> *Never got to soar with its parents, nor feel the winds in the skies.* -> *What fate has befallen the dragonets of yore?* -> *A tragic tale of death and withering ne'er seen before...* - -> *Bring your swords, your axes, your shields,* -> *Your fire, your venom, your frost,* -> *She will show no mercy,* -> *When she awakens.* - -> *The earth is rumbling...*""" - }; - } - return responses; - } - - @Override - public void onButtonInteraction(@NotNull ButtonInteractionEvent event) { - - Messager.debug("Button interaction with ID " + event.getButton().getId()); - - Button button = event.getButton(); - ButtonInteraction interaction = event.getInteraction(); - - if (Objects.equals(button.getId(), "panic")) { - Bukkit.getScheduler().runTask(Dreamvisitor.getPlugin(), () -> { - for (Player player : Bukkit.getServer().getOnlinePlayers()) if (!player.isOp()) player.kickPlayer("Panic!"); - }); - Dreamvisitor.playerLimit = 0; - Dreamvisitor.getPlugin().getConfig().set("playerlimit", 0); - Dreamvisitor.getPlugin().saveConfig(); - Bukkit.getServer().broadcastMessage( - ChatColor.RED + "Panicked by " + interaction.getUser().getName() + ".\nPlayer limit override set to 0."); - Bot.sendLog("**Panicked by " + interaction.getUser().getName()); - event.reply("Panicked!").queue(); - - // Disable button after use - interaction.editButton(button.asDisabled()).queue(); - } else if (Objects.requireNonNull(button.getId()).startsWith("unwhitelist-")) { - - String uuid = button.getId().substring("unwhitelist-".length()); - String username = PlayerUtility.getUsernameOfUuid(uuid); - - try { - if (Whitelist.isUserWhitelisted(UUID.fromString(uuid))) { - assert username != null; - Whitelist.remove(username, UUID.fromString(uuid)); - event.reply("Removed `" + username + "` from the whitelist.").queue(); - } else { - event.reply("`" + username + "` is not whitelisted.").queue(); - } - } catch (IOException e) { - event.reply("Unable to read or write the whitelist file: " + e.getMessage()).queue(); - } - - // Disable button after use - interaction.editButton(button.asDisabled()).queue(); - - } else if (button.getId().startsWith("ban-")) { - - String uuid = button.getId().substring("ban-".length()); - String username = PlayerUtility.getUsernameOfUuid(uuid); - - try { - - if (Whitelist.isUserWhitelisted(UUID.fromString(uuid))) { - assert username != null; - Whitelist.remove(username, UUID.fromString(uuid)); - } - BanList banList = Bukkit.getBanList(BanList.Type.PROFILE); - assert username != null; - banList.addBan(Bukkit.getServer().createPlayerProfile(username), "Banned by Dreamvistitor.", (Date) null, null); - event.reply("Banned `" + username + "`.").queue(); - - } catch (IOException e) { - event.reply("Unable to read or write the whitelist file: " + e.getMessage()).queue(); - } - - // Disable button after use - interaction.editButton(button.asDisabled()).queue(); - } else if (button.getId().startsWith("setban-")) { - - String[] split = button.getId().split("-"); - - long userId = Long.parseLong(split[1]); - String action = split[2]; - switch (action) { - case "none" -> { - Infraction.setBan(userId, false); - Infraction.setTempban(userId, false); - event.reply("Marked this user as not banned.").setEphemeral(true).queue(); - } - case "temp" -> { - Infraction.setBan(userId, false); - Infraction.setTempban(userId, true); - event.reply("Marked this user as temp-banned.").setEphemeral(true).queue(); - } - case "full" -> { - Infraction.setBan(userId, true); - Infraction.setTempban(userId, true); - event.reply("Marked this user as banned.").setEphemeral(true).queue(); - } - default -> event.reply("Unexpected request: " + button.getId()).setEphemeral(true).queue(); - } - - } else if (button.getId().startsWith("infraction-")) { - if (button.getId().startsWith("infraction-expire-")) { - - long id = Long.parseLong(button.getId().substring("infraction-expire-".length())); - Objects.requireNonNull(event.getGuild()).retrieveMemberById(id).queue(member -> { - - @NotNull List infractions; - - infractions = Infraction.getInfractions(member.getIdLong()); - - if (infractions.isEmpty()) { - event.reply("That user has no infractions.").queue(); - return; - } - - StringSelectMenu.Builder selectMenu = StringSelectMenu.create("infraction-expire-" + member.getId()); - selectMenu.setPlaceholder("Select an infraction to remove"); - - for (Infraction infraction : infractions) { - if (infraction.isExpired()) continue; - - String shortenedReason; - if (infraction.getReason().length() >= 35) shortenedReason = infraction.getReason().substring(0, 35) + "... [Value " + infraction.getValue() + "]"; - else shortenedReason = infraction.getReason() + " [Value " + infraction.getValue() + "]"; - - selectMenu.addOption( - infraction.getTime().format(DateTimeFormatter.ofPattern("M/d/u H:m")), - infraction.getTime().toString(), - shortenedReason - ); - } - - if (selectMenu.getOptions().isEmpty()) { - event.reply("That user has no unexpired infractions.").queue(); - return; - } - - StringSelectMenu dropdown = selectMenu.build(); - - event.reply("Select the infraction to expire.").addActionRow(dropdown).queue(); - - }); - - } else if (button.getId().startsWith("infraction-remove-")) { - - long id = Long.parseLong(button.getId().substring("infraction-remove-".length())); - Objects.requireNonNull(event.getGuild()).retrieveMemberById(id).queue(member -> { - - @NotNull List infractions; - - infractions = Infraction.getInfractions(member.getIdLong()); - - if (infractions.isEmpty()) { - event.reply("That user has no infractions.").queue(); - return; - } - - StringSelectMenu.Builder selectMenu = StringSelectMenu.create("infraction-remove-" + member.getId()); - - for (Infraction infraction : infractions) { - - String shortenedReason; - if (infraction.getReason().length() >= 35) shortenedReason = infraction.getReason().substring(0, 35) + "... [Value " + infraction.getValue() + "]"; - else shortenedReason = infraction.getReason() + " [Value " + infraction.getValue() + "]"; - - selectMenu.addOption( - infraction.getTime().format(DateTimeFormatter.ofPattern("M/d/u H:m")), - infraction.getTime().toString(), - shortenedReason - ); - } - - StringSelectMenu dropdown = selectMenu.build(); - - event.reply("Select the infraction to remove.").addActionRow(dropdown).queue(); - - }); - } else if (button.getId().startsWith("purchase-")) { - - String itemIdString = button.getId().substring("purchase-".length()); - int itemId; - try { - itemId = Integer.parseInt(itemIdString); - } catch (NumberFormatException e) { - event.reply("The item you selected could not be parsed.").queue(); - return; - } - Economy.ShopItem item = Economy.getItem(itemId); - if (item == null) { - event.reply("That item does not exist.").queue(); - return; - } - Economy.Consumer consumer = Economy.getConsumer(event.getUser().getIdLong()); - try { - consumer.purchaseItem(itemId); - } catch (Economy.Consumer.ItemNotEnabledException | Economy.Consumer.ItemOutOfStockException | - NullPointerException e) { - event.reply(e.getMessage()).queue(); - return; - } catch (Economy.Consumer.InsufficientFundsException e) { - EmbedBuilder embed = new EmbedBuilder(); - embed.setDescription("You do not have sufficient funds to purchase " + item.getName() + ".\nYour balance: " + consumer.getBalance() + "\nItem cost: " + item.getTruePrice()); - embed.setColor(Color.RED); - event.replyEmbeds(embed.build()).setEphemeral(true).queue(); - return; - } catch (Economy.Consumer.MaxItemQualityException e) { - EmbedBuilder embed = new EmbedBuilder(); - embed.setDescription("You already have " + item.getMaxAllowed() + " of this item, which is as many as you can have at one time."); - embed.setColor(Color.RED); - event.replyEmbeds(embed.build()).setEphemeral(true).queue(); - return; - } - - EmbedBuilder embed = new EmbedBuilder(); - embed.setTitle("Purchase successful!"); - embed.setDescription("Purchased " + item.getName() + " for " + item.getTruePrice() + "."); - embed.setFooter("You now have " + consumer.getQuantityOfItem(itemId) + " of this item.\nYour new balance is " + consumer.getBalance()); - embed.setColor(Color.GREEN); - - event.editMessageEmbeds(embed.build()).queue(); - event.getMessage().editMessageComponents().queue(); - - } - } - } - - @Override - public void onStringSelectInteraction(@NotNull StringSelectInteractionEvent event) { - if (Objects.requireNonNull(event.getComponent().getId()).startsWith("infraction-expire-")) { - long id = Long.parseLong(event.getComponent().getId().substring("infraction-expire-".length())); - Objects.requireNonNull(event.getGuild()).retrieveMemberById(id).queue(member -> { - - @NotNull List infractions; - SelectOption selectOption = event.getInteraction().getSelectedOptions().get(0); - if (selectOption == null) return; - - LocalDateTime selectedTime = LocalDateTime.parse(selectOption.getValue()); - - infractions = Infraction.getInfractions(member.getIdLong()); - - if (infractions.isEmpty()) { - event.reply("That user has no infractions.").queue(); - return; - } - - for (Infraction infraction : infractions) { - if (infraction.isExpired()) continue; - if (infraction.getTime().equals(selectedTime)) { - infractions.remove(infraction); - infraction.expire(); - infractions.add(infraction); - break; - } - } - Infraction.setInfractions(infractions, member.getIdLong()); - - event.reply("Infraction expired.").queue(); - event.getMessage().editMessageComponents(event.getMessage().getActionRows().get(0).asDisabled()).queue(); - }); - } else if (Objects.requireNonNull(event.getComponent().getId()).startsWith("infraction-remove-")) { - long id = Long.parseLong(event.getComponent().getId().substring("infraction-remove-".length())); - event.getJDA().retrieveUserById(id).queue(member -> { - - @NotNull List infractions; - SelectOption selectOption = event.getInteraction().getSelectedOptions().get(0); - if (selectOption == null) return; - - LocalDateTime selectedTime = LocalDateTime.parse(selectOption.getValue()); - - infractions = Infraction.getInfractions(member.getIdLong()); - - if (infractions.isEmpty()) { - event.reply("That user has no infractions.").queue(); - return; - } - - for (Infraction infraction : infractions) { - if (infraction.getTime().equals(selectedTime)) { - infractions.remove(infraction); - break; - } - } - Infraction.setInfractions(infractions, member.getIdLong()); - - event.reply("Infraction removed.").queue(); - event.getMessage().editMessageComponents(event.getMessage().getActionRows().get(0).asDisabled()).queue(); - }); - } else if (Objects.requireNonNull(event.getComponent().getId()).startsWith("alts-remove-")) { - long id = Long.parseLong(event.getComponent().getId().substring("alts-remove-".length())); - event.getJDA().retrieveUserById(id).queue(member -> { - - AltFamily altFamily; - List childrenIds; - - altFamily = AltFamily.getFamily(member.getIdLong()); - childrenIds = altFamily.getChildren(); - - SelectOption selectOption = event.getInteraction().getSelectedOptions().get(0); - if (selectOption == null) return; - Objects.requireNonNull(event.getGuild()).retrieveMembersByIds(childrenIds).onSuccess(children -> { - for (Member child : children) { - if (!child.getEffectiveName().equals(selectOption.getValue())) continue; - childrenIds.remove(child.getIdLong()); - altFamily.setChildren(childrenIds); - AltFamily.updateFamily(altFamily); - event.reply("Removed " + child.getEffectiveName() + " from the family.").queue(); - event.getMessage().editMessageComponents(event.getMessage().getActionRows().get(0).asDisabled()).queue(); - return; - } - event.reply("That child account could not be found.").queue(); - event.getMessage().editMessageComponents(event.getMessage().getActionRows().get(0).asDisabled()).queue(); - }); - }); - } - } - -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdActivity.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdActivity.java deleted file mode 100644 index ffa917e..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdActivity.java +++ /dev/null @@ -1,59 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import io.github.stonley890.dreamvisitor.Bot; -import net.dv8tion.jda.api.entities.Activity; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; -import net.dv8tion.jda.api.interactions.commands.OptionMapping; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import org.jetbrains.annotations.NotNull; - -public class DCmdActivity implements DiscordCommand { - @Override - public @NotNull SlashCommandData getCommandData() { - return Commands.slash("activity", "Set the bot activity.") - .addOptions(new OptionData(OptionType.STRING, "type", - "The type of activity.", true) - .setAutoComplete(false) - .addChoice("COMPETING", "COMPETING") - .addChoice("LISTENING", "LISTENING") - .addChoice("PLAYING", "PLAYING") - .addChoice("WATCHING", "WATCHING") - ) - .addOption(OptionType.STRING, "activity", "The status to display on the bot.", true) - .setDefaultPermissions(DefaultMemberPermissions.DISABLED); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - // Get args - String activity = event.getOption("activity", OptionMapping::getAsString); - String activityType = event.getOption("type", OptionMapping::getAsString); - - // Set activity - Activity.ActivityType type = Activity.ActivityType.CUSTOM_STATUS; - - assert activityType != null; - if (activityType.equalsIgnoreCase("COMPETING")) - type = Activity.ActivityType.COMPETING; - else if (activityType.equalsIgnoreCase("LISTENING")) - type = Activity.ActivityType.LISTENING; - else if (activityType.equalsIgnoreCase("PLAYING")) - type = Activity.ActivityType.PLAYING; - else if (activityType.equalsIgnoreCase("WATCHING")) - type = Activity.ActivityType.WATCHING; - else { - event.reply("Invalid activity type.").queue(); - } - - // Set presence - if (type != Activity.ActivityType.CUSTOM_STATUS) { - assert activity != null; - Bot.getJda().getPresence().setActivity(Activity.of(type, activity)); - event.reply("Activity set!").setEphemeral(true).queue(); - } - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdAlts.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdAlts.java deleted file mode 100644 index b103dba..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdAlts.java +++ /dev/null @@ -1,159 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import io.github.stonley890.dreamvisitor.data.AccountLink; -import io.github.stonley890.dreamvisitor.data.AltFamily; -import io.github.stonley890.dreamvisitor.data.PlayerUtility; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.User; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent; -import net.dv8tion.jda.api.hooks.ListenerAdapter; -import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; -import net.dv8tion.jda.api.interactions.commands.OptionMapping; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; -import net.dv8tion.jda.api.interactions.components.selections.SelectOption; -import net.dv8tion.jda.api.interactions.components.selections.StringSelectMenu; -import org.jetbrains.annotations.NotNull; - -import java.util.List; -import java.util.Objects; -import java.util.UUID; - -public class DCmdAlts extends ListenerAdapter implements DiscordCommand { - @Override - public @NotNull SlashCommandData getCommandData() { - return Commands.slash("alts", "Manage the alt tracker.").addSubcommands( - new SubcommandData("link", "Link two accounts as alts.").addOptions( - new OptionData(OptionType.USER, "parent", "The parent or main account.", true), - new OptionData(OptionType.USER, "child", "The child or alt account.", true) - ), - new SubcommandData("get", "Get the alts of an account.").addOptions( - new OptionData(OptionType.USER, "user", "The user to get the alts of.", true) - ) - ).setDefaultPermissions(DefaultMemberPermissions.DISABLED); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - - String subcommand = event.getSubcommandName(); - - if (subcommand == null) { - event.reply("No subcommand given.").queue(); - } else if (subcommand.equals("link")) { - User parent = event.getOption("parent", OptionMapping::getAsUser); - User child = event.getOption("child", OptionMapping::getAsUser); - - if (parent == null) { - event.reply("Parent account could not be found.").queue(); - return; - } - if (child == null) { - event.reply("Child account could not be found.").queue(); - return; - } - - try { - long recordedParentOfChild = AltFamily.getParent(child.getIdLong()); - if (recordedParentOfChild != child.getIdLong()) { - event.getJDA().retrieveUserById(recordedParentOfChild).queue(user -> event.reply("The child account is already linked to " + user.getAsMention()).queue()); - return; - } - AltFamily.setAlt(parent.getIdLong(), child.getIdLong()); - event.reply("Alts recorded successfully!").queue(); - - } catch (AltFamily.NotParentException e) { - event.getJDA().retrieveUserById(parent.getIdLong()).queue(user -> event.reply("The parent account is already linked to " + user.getAsMention() + " as a child account.").queue()); - } - - } else if (subcommand.equals("get")) { - User user = event.getOption("user", OptionMapping::getAsUser); - if (user == null) { - event.reply("That member could not be found.").queue(); - return; - } - - AltFamily altFamily; - - altFamily = AltFamily.getFamily(user.getIdLong()); - - if (altFamily.getChildren().isEmpty()) { - event.reply("There are no alts linked to this account.").queue(); - } else { - UUID parentUuid; - parentUuid = AccountLink.getUuid(altFamily.getParent()); - String parentUsername; - if (parentUuid != null) parentUsername = PlayerUtility.getUsernameOfUuid(parentUuid); - else parentUsername = null; - - event.getJDA().retrieveUserById(altFamily.getParent()).queue(parentUser -> { - - String parentEmbed = parentUser.getAsMention(); - if (parentUuid != null && parentUsername != null) parentEmbed = parentEmbed.concat(" (" + parentUsername + "/`" + parentUuid + "`)"); - - EmbedBuilder embed = new EmbedBuilder(); - embed.setTitle("Alts of " + user.getName()).addField("Parent Account", parentEmbed, false); - - StringBuilder childrenEmbed = new StringBuilder(); - - StringSelectMenu.Builder selectMenu = StringSelectMenu.create("alts-remove-" + parentUser.getId()); - selectMenu.setPlaceholder("Remove an alt"); - - Objects.requireNonNull(event.getGuild()).retrieveMembersByIds(altFamily.getChildren()).onSuccess(childMembers -> { - for (Member member : childMembers) { - - UUID childUuid; - childUuid = AccountLink.getUuid(member.getIdLong()); - String childUsername; - if (childUuid != null) childUsername = PlayerUtility.getUsernameOfUuid(childUuid); - else childUsername = null; - - selectMenu.addOption(member.getEffectiveName(), member.getEffectiveName()); - childrenEmbed.append("- ").append(member.getAsMention()).append(" (").append(childUsername).append("/`").append(childUuid).append("`)\n"); - } - - embed.addField("Children", childrenEmbed.toString(), false); - - event.replyEmbeds(embed.build()).addActionRow(selectMenu.build()).queue(); - }); - }); - } - } - } - - @Override - public void onStringSelectInteraction(@NotNull StringSelectInteractionEvent event) { - if (Objects.requireNonNull(event.getComponent().getId()).startsWith("alts-remove-")) { - long id = Long.parseLong(event.getComponent().getId().substring("alts-remove-".length())); - event.getJDA().retrieveUserById(id).queue(member -> { - - AltFamily altFamily; - List childrenIds; - - altFamily = AltFamily.getFamily(member.getIdLong()); - childrenIds = altFamily.getChildren(); - - SelectOption selectOption = event.getInteraction().getSelectedOptions().get(0); - if (selectOption == null) return; - Objects.requireNonNull(event.getGuild()).retrieveMembersByIds(childrenIds).onSuccess(children -> { - for (Member child : children) { - if (!child.getEffectiveName().equals(selectOption.getValue())) continue; - childrenIds.remove(child.getIdLong()); - altFamily.setChildren(childrenIds); - AltFamily.updateFamily(altFamily); - event.reply("Removed " + child.getEffectiveName() + " from the family.").queue(); - event.getMessage().editMessageComponents(event.getMessage().getActionRows().get(0).asDisabled()).queue(); - return; - } - event.reply("That child account could not be found.").queue(); - event.getMessage().editMessageComponents(event.getMessage().getActionRows().get(0).asDisabled()).queue(); - }); - }); - } - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdAutorestart.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdAutorestart.java deleted file mode 100644 index 0e58e1c..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdAutorestart.java +++ /dev/null @@ -1,60 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import io.github.stonley890.dreamvisitor.functions.AutoRestart; -import io.github.stonley890.dreamvisitor.data.PBConfigLoader; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; -import net.dv8tion.jda.api.hooks.ListenerAdapter; -import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback; -import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import net.dv8tion.jda.api.interactions.components.buttons.Button; -import org.jetbrains.annotations.NotNull; - -import java.awt.*; -import java.time.Instant; -import java.util.Objects; - -public class DCmdAutorestart extends ListenerAdapter implements DiscordCommand { - @Override - public @NotNull SlashCommandData getCommandData() { - return Commands.slash("autorestart", "Restart the server when no players are online.") - .setDefaultPermissions(DefaultMemberPermissions.DISABLED); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - interaction(event); - } - - @Override - public void onButtonInteraction(@NotNull ButtonInteractionEvent event) { - if (!Objects.equals(event.getButton().getId(), "autorestart")) { - return; - } - - interaction(event); - } - - private static void interaction(@NotNull IReplyCallback event) { - Button button = Button.primary("autorestart", "Undo"); - - // Reload config to ensure we have latest state before checking - PBConfigLoader.loadConfig(); - - if (AutoRestart.isAutoRestart()) { - AutoRestart.disableAutoRestart(); - EmbedBuilder embedBuilder = new EmbedBuilder(); - embedBuilder.setDescription("✅ Canceled server restart.").setColor(Color.BLUE).setTimestamp(Instant.now()); - event.replyEmbeds(embedBuilder.build()).addActionRow(button).queue(); - } else { - EmbedBuilder embedBuilder = new EmbedBuilder(); - embedBuilder.setDescription("✅ The server will restart when there are no players online.").setColor(Color.GREEN) - .setTimestamp(Instant.now()); - event.replyEmbeds(embedBuilder.build()).addActionRow(button) - .queue(hook -> hook.retrieveOriginal().queue(AutoRestart::enableAutoRestart)); - } - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdBalance.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdBalance.java deleted file mode 100644 index 2873035..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdBalance.java +++ /dev/null @@ -1,46 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.data.Economy; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.entities.User; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.interactions.commands.OptionMapping; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import org.jetbrains.annotations.NotNull; - -public class DCmdBalance implements DiscordCommand { - @NotNull - @Override - public SlashCommandData getCommandData() { - return Commands.slash("balance", "Get your current balance.") - .addOption(OptionType.USER, "member", "[Optional] The member whose balance to fetch", false, false); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - - String message; - - User targetUser = event.getOption("member", OptionMapping::getAsUser); - if (targetUser != null) { - Economy.Consumer consumer = Economy.getConsumer(targetUser.getIdLong()); - double balance; - balance = consumer.getBalance(); - message = targetUser.getAsMention() + " has " + Dreamvisitor.getPlugin().getConfig().getString("currencyIcon") + balance + "."; - } else { - Economy.Consumer consumer = Economy.getConsumer(event.getUser().getIdLong()); - double balance; - balance = consumer.getBalance(); - message = "You have " + Economy.getCurrencySymbol() + Economy.formatDouble(balance) + "."; - } - - EmbedBuilder embed = new EmbedBuilder(); - embed.setDescription(message); - - event.replyEmbeds(embed.build()).queue(); - - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdBaltop.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdBaltop.java deleted file mode 100644 index b15a1ac..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdBaltop.java +++ /dev/null @@ -1,124 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; - -import io.github.stonley890.dreamvisitor.functions.Messager; -import org.jetbrains.annotations.NotNull; - -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.data.Economy; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; - -public class DCmdBaltop implements DiscordCommand { - @NotNull - @Override - public SlashCommandData getCommandData() { - return Commands.slash("baltop", "Get the balances of the richest members.") - .setDefaultPermissions(DefaultMemberPermissions.ENABLED); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - - final String currencySymbol = Economy.getCurrencySymbol(); - - List sortedConsumers = Economy.getConsumers(); - sortedConsumers.sort(Comparator.comparingDouble(Economy.Consumer::getBalance).reversed()); - - if (Dreamvisitor.debugMode) { - Messager.debug("Sorted consumers: "); - for (Economy.Consumer sortedConsumer : sortedConsumers) { - Messager.debug(sortedConsumer.getId() + ": " + sortedConsumer.getBalance()); - } - } - - final Economy.Consumer senderConsumer = Economy.getConsumer(event.getUser().getIdLong()); - - final int senderIndex = sortedConsumers.indexOf(senderConsumer); - Messager.debug("Sender index: " + senderIndex); - - Economy.Consumer aboveSender = null; - try { - aboveSender = sortedConsumers.get(senderIndex - 1); - } catch (IndexOutOfBoundsException ignored) {} - Messager.debug("Index above sender: " + (senderIndex - 1) + " id " + (aboveSender != null ? aboveSender.getId() : "null")); - - Economy.Consumer belowSender = null; - try { - belowSender = sortedConsumers.get(senderIndex + 1); - } catch (IndexOutOfBoundsException ignored) {} - Messager.debug("Index below sender: " + (senderIndex + 1) + " id " + (belowSender != null ? belowSender.getId() : "null")); - - final EmbedBuilder embed = new EmbedBuilder(); - embed.setTitle("Top Balances"); - - int numberShown = 10; - - if (sortedConsumers.size() < numberShown) numberShown = sortedConsumers.size(); - Messager.debug("Consumer list size: " + sortedConsumers.size()); - - final List retrieveIds = new ArrayList<>(sortedConsumers.subList(0, numberShown).stream().map(Economy.Consumer::getId).toList()); - if (aboveSender != null) retrieveIds.add(aboveSender.getId()); - if (belowSender != null) retrieveIds.add(belowSender.getId()); - - int finalNumberShown = numberShown; - Economy.Consumer finalAboveSender = aboveSender; - Economy.Consumer finalBelowSender = belowSender; - Objects.requireNonNull(event.getGuild()).retrieveMembersByIds(retrieveIds).onSuccess(members -> { - - Map memberMap = new HashMap<>(); - List topMembers = members.subList(0, finalNumberShown); - for (Member member : topMembers) { - memberMap.put(member.getIdLong(), member); - } - - // Create a list to hold the sorted members - List sortedMembers = new ArrayList<>(); - - // Add members to the sorted list in the order of consumer IDs - for (Economy.Consumer consumer : sortedConsumers) { - Member member = memberMap.get(consumer.getId()); - sortedMembers.add(member); - } - - final StringBuilder balanceList = new StringBuilder(); - for (int i = 0; i < finalNumberShown; i++) { - balanceList.append(i + 1).append(". ") - .append(currencySymbol).append(Economy.formatDouble(sortedConsumers.get(i).getBalance())).append(": "); - if (sortedMembers.get(i) == null) balanceList.append("<@").append(sortedConsumers.get(i).getId()).append(">\n"); - else balanceList.append(sortedMembers.get(i).getAsMention()).append("\n"); - } - - if (finalNumberShown == 0) balanceList.append("No one has any ").append(Economy.getCurrencySymbol()).append(" yet!\n"); - - if (senderConsumer.getBalance() != 0) { - balanceList.append("\nYour current rank is ").append(senderIndex + 1); - if (finalAboveSender != null) { - Optional member = members.stream().filter(thisMember -> thisMember.getIdLong() == finalAboveSender.getId()).findFirst(); - member.ifPresent(value -> balanceList.append(", behind ").append(value.getAsMention()).append(" (").append(currencySymbol).append(finalAboveSender.getBalance()).append(")")); - } - if (finalBelowSender != null) { - Optional member = members.stream().filter(thisMember -> thisMember.getIdLong() == finalBelowSender.getId()).findFirst(); - member.ifPresent(value -> balanceList.append(", ahead of ").append(value.getAsMention()).append(" (").append(currencySymbol).append(finalBelowSender.getBalance()).append(")")); - } - balanceList.append("."); - } - - embed.setDescription(balanceList).setFooter("Your current balance is " + Economy.formatDouble(senderConsumer.getBalance()) + "."); - event.replyEmbeds(embed.build()).queue(); - }); - - - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdBroadcast.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdBroadcast.java deleted file mode 100644 index 3a69680..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdBroadcast.java +++ /dev/null @@ -1,52 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import io.github.stonley890.dreamvisitor.Bot; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; -import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; -import net.dv8tion.jda.api.interactions.commands.OptionMapping; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.jetbrains.annotations.NotNull; - -public class DCmdBroadcast implements DiscordCommand { - @Override - public @NotNull SlashCommandData getCommandData() { - return Commands.slash("broadcast", "Broadcast a message to the Minecraft server.") - .addOption(OptionType.STRING, "message", "The message to broadcast.", true) - .setDefaultPermissions(DefaultMemberPermissions.DISABLED); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - // Get args - String message = event.getOption("message", OptionMapping::getAsString); - - assert message != null; - if (message.length() < 351) { - // Send message - Bukkit.getScheduler().runTask(Dreamvisitor.getPlugin(), () -> Bukkit.broadcastMessage(ChatColor.DARK_BLUE + "[" + ChatColor.WHITE + "Broadcast" + ChatColor.DARK_BLUE + "] " + ChatColor.BLUE + message)); - - EmbedBuilder builder = new EmbedBuilder(); - - builder.setAuthor("Staff Broadcast"); - builder.setTitle(message); - - try { - Bot.getGameChatChannel().sendMessageEmbeds(builder.build()).queue(); - } catch (InsufficientPermissionException e) { - event.reply("Dreamvisitor Bot does not have the permissions VIEW_CHANNEL, MESSAGE_SEND, or MESSAGE_EMBED_LINKS. The message was still sent to Minecraft").queue(); - } - - // Reply - event.reply("Broadcast sent.").setEphemeral(true).queue(); - } else { - event.reply("Message too long! " + message.length() + " > 350").setEphemeral(true).queue(); - } - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdDaily.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdDaily.java deleted file mode 100644 index 11c643e..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdDaily.java +++ /dev/null @@ -1,50 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import io.github.stonley890.dreamvisitor.data.Economy; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.entities.User; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import org.jetbrains.annotations.NotNull; - -import java.awt.*; -import java.time.Duration; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; - -public class DCmdDaily implements DiscordCommand { - @NotNull - @Override - public SlashCommandData getCommandData() { - return Commands.slash("daily", "Claim your daily streak allowance."); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - User user = event.getUser(); - Economy.Consumer consumer = Economy.getConsumer(user.getIdLong()); - Economy.GameData gameData = consumer.getGameData(); - - EmbedBuilder embedBuilder = new EmbedBuilder(); - embedBuilder.setTitle("Daily Reward"); - - double reward; - - try { - reward = consumer.claimDaily(); - } catch (Economy.Consumer.CoolDownException e) { - Duration duration = Duration.between(LocalDateTime.now(), LocalDateTime.of(LocalDate.now().plusDays(1), LocalTime.MIDNIGHT)); - embedBuilder.setColor(Color.red).setDescription("You have already claimed your daily reward for today. You cannot claim your daily reward for " + String.valueOf(duration.toHoursPart()).replaceFirst("-", "") + " hour(s), " + String.valueOf(duration.toMinutesPart()).replaceFirst("-", "") + " minute(s)."); - event.replyEmbeds(embedBuilder.build()).setEphemeral(true).queue(); - return; - } - Economy.saveConsumer(consumer); - - embedBuilder.setDescription("You earned " + Economy.getCurrencySymbol() + reward + " today.\nCome back tomorrow for your next reward.") - .setFooter("Your new balance is " + consumer.getBalance() + "\nThis brings your streak to " + gameData.getDailyStreak() + " day(s).") - .setColor(Color.GREEN); - event.replyEmbeds(embedBuilder.build()).queue(); - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdEconomy.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdEconomy.java deleted file mode 100644 index ea08749..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdEconomy.java +++ /dev/null @@ -1,897 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import io.github.stonley890.dreamvisitor.data.Economy; -import io.github.stonley890.dreamvisitor.functions.Messager; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.entities.Guild; -import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.entities.User; -import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; -import net.dv8tion.jda.api.events.interaction.component.EntitySelectInteractionEvent; -import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent; -import net.dv8tion.jda.api.hooks.ListenerAdapter; -import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; -import net.dv8tion.jda.api.interactions.commands.OptionMapping; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; -import net.dv8tion.jda.api.interactions.commands.build.SubcommandGroupData; -import net.dv8tion.jda.api.interactions.components.ActionRow; -import net.dv8tion.jda.api.interactions.components.LayoutComponent; -import net.dv8tion.jda.api.interactions.components.buttons.Button; -import net.dv8tion.jda.api.interactions.components.selections.EntitySelectMenu; -import net.dv8tion.jda.api.interactions.components.selections.SelectOption; -import net.dv8tion.jda.api.interactions.components.selections.StringSelectMenu; -import net.dv8tion.jda.api.interactions.components.text.TextInput; -import net.dv8tion.jda.api.interactions.components.text.TextInputStyle; -import net.dv8tion.jda.api.interactions.modals.Modal; -import org.jetbrains.annotations.NotNull; - -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -public class DCmdEconomy extends ListenerAdapter implements DiscordCommand { - @NotNull - @Override - public SlashCommandData getCommandData() { - return Commands.slash("economy", "Manage the Discord economy.") - .setDefaultPermissions(DefaultMemberPermissions.DISABLED) - .addSubcommandGroups( - new SubcommandGroupData("shop", "Manage the shop.").addSubcommands( - new SubcommandData("name","Get or set the name of the shop.") - .addOption(OptionType.STRING, "new-name","The name to set.", false, false), - new SubcommandData("currency-symbol", "Get or set the currency symbol.") - .addOption(OptionType.STRING, "new-symbol", "The symbol to set.", false, false) - ), - new SubcommandGroupData("items", "Manage items.").addSubcommands( - new SubcommandData("list", "List all items."), - new SubcommandData("edit", "Edit an item.") - .addOption(OptionType.INTEGER, "id", "The ID of the item to edit.", true), - new SubcommandData("add", "Create a new item.") - .addOption(OptionType.STRING, "name", "The name of the item.", true) - .addOption(OptionType.STRING, "description", "The description of this item.", true), - new SubcommandData("remove", "Permanently remove an item.") - .addOption(OptionType.STRING, "id", "The ID of the item to remove.", true) - ), - new SubcommandGroupData("users", "Manage users.").addSubcommands( - new SubcommandData("balance", "Get or set the balance of a user.") - .addOption(OptionType.USER, "user", "The user whose balance to get.", true) - .addOption(OptionType.NUMBER, "new-balance", "The balance to set.", false), - new SubcommandData("get-items", "Manage the items of a user.") - .addOption(OptionType.USER, "user", "The user whose items to get.", true), - new SubcommandData("set-items", "Set the quantity of an item held by a user.") - .addOption(OptionType.USER, "user", "The user whose items to get.", true) - .addOption(OptionType.INTEGER, "id", "The ID of the item to modify the quantity of.", true) - .addOption(OptionType.INTEGER, "new-quantity", "The number of this item the user should have.", true), - new SubcommandData("daily-streak", "Get or set the daily streak of a user.") - .addOption(OptionType.USER, "user", "The user whose streak to get.", true) - .addOption(OptionType.INTEGER, "new-value", "The streak to set for this player.", false) - ) - ); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - - String subcommandGroup = event.getSubcommandGroup(); - String subcommand = event.getSubcommandName(); - - if (subcommandGroup == null || subcommand == null) { - event.reply("Subcommand Group or Subcommand is null.").setEphemeral(true).queue(); - return; - } - - switch (subcommandGroup) { - case "shop" -> { - if (subcommand.equals("name")) { - String name = event.getOption("new-name", OptionMapping::getAsString); - if (name == null) { - event.reply("The current shop name is " + Economy.getShopName()).setEphemeral(true).queue(); - } else { - String shopName = Economy.getShopName(); - Economy.setShopName(name); - event.reply("Changed shop name from " + shopName + " to " + name + ".").queue(); - } - } else if (subcommand.equals("currency-symbol")) { - String symbol = event.getOption("new-symbol", OptionMapping::getAsString); - if (symbol == null) { - event.reply("The current shop symbol is " + Economy.getCurrencySymbol()).setEphemeral(true).queue(); - } else { - String oldSymbol = Economy.getCurrencySymbol(); - Economy.setCurrencySymbol(symbol); - event.reply("Changed currency symbol from " + oldSymbol + " to " + symbol + ".").queue(); - } - } else { - event.reply("Subcommand not found.").setEphemeral(true).queue(); - } - } - case "items" -> { - switch (subcommand) { - case "list" -> { - - EmbedBuilder embed = new EmbedBuilder(); - - List items = Economy.getItems(); - if (items.isEmpty()) { - embed.setDescription("There are currently no items."); - event.replyEmbeds(embed.build()).queue(); - return; - } - - for (int j = 0; j < items.size(); j++) { - Economy.ShopItem item = items.get(j); - - StringBuilder description = new StringBuilder(); - - description.append(item.getDescription()).append("\n\n") - .append("Price: ").append(Economy.getCurrencySymbol()).append(item.getPrice()) - .append("\nSale Percent: ").append(item.getSalePercent()).append("%") - .append("\nQuantity: "); - if (item.isInfinite()) description.append("Infinite"); - else description.append(item.getQuantity()); - description.append("\nEnabled: ").append(item.isEnabled()); - description.append("\nGifting: ").append(item.isGiftingEnabled()); - description.append("\nUsable: ").append(!item.isUseDisabled()); - description.append("\nUse on Purchase: ").append(item.isUseOnPurchase()); - description.append("\nMax Allowed: "); - if (item.getMaxAllowed() == -1) description.append("Infinite"); - else description.append(item.getMaxAllowed()); - - description.append("\nRoles Add on Use: "); - List onUseRolesAdd = item.getOnUseRolesAdd(); - if (onUseRolesAdd == null || onUseRolesAdd.isEmpty()) description.append("None"); - else { - for (int i = 0; i < onUseRolesAdd.size(); i++) { - Long roleId = onUseRolesAdd.get(i); - Role role = Objects.requireNonNull(event.getGuild()).getRoleById(roleId); - if (role == null) { - item.getOnUseRolesAdd().remove(roleId); - items.set(i, item); - continue; - } - description.append(role.getAsMention()); - if (i == onUseRolesAdd.size() - 1) description.append(", "); - } - description.delete(description.length(), description.length()); - } - - description.append("\nRoles Remove on Use: "); - List onUseRolesRemove = item.getOnUseRolesRemove(); - if (onUseRolesRemove == null || onUseRolesRemove.isEmpty()) description.append("None"); - else { - for (int i = 0; i < onUseRolesRemove.size(); i++) { - Long roleId = onUseRolesRemove.get(i); - Role role = Objects.requireNonNull(event.getGuild()).getRoleById(roleId); - if (role == null) { - item.getOnUseRolesRemove().remove(roleId); - items.set(i, item); - continue; - } - description.append(role.getAsMention()); - if (i == onUseRolesRemove.size() - 1) description.append(", "); - } - description.delete(description.length(), description.length()); - } - - description.append("\nGroups Parent on Use: "); - List onUseGroupsAdd = item.getOnUseGroupsAdd(); - if (onUseGroupsAdd == null || onUseGroupsAdd.isEmpty()) description.append("None"); - else { - for (int i = 0; i < onUseGroupsAdd.size(); i++) { - String groupName = onUseGroupsAdd.get(i); - description.append(groupName); - if (i == onUseGroupsAdd.size() - 1) description.append(", "); - } - description.delete(description.length(), description.length()); - } - - description.append("\nGroups Unparent on Use: "); - List onUseGroupsRemove = item.getOnUseGroupsRemove(); - if (onUseGroupsRemove == null || onUseGroupsRemove.isEmpty()) description.append("None"); - else { - for (int i = 0; i < onUseGroupsRemove.size(); i++) { - String groupName = onUseGroupsRemove.get(i); - description.append(groupName); - if (i == onUseGroupsRemove.size() - 1) description.append(", "); - } - description.delete(description.length(), description.length()); - } - - description.append("\nCommands on Use: "); - List onUseConsoleCommands = item.getOnUseConsoleCommands(); - if (onUseConsoleCommands == null || onUseConsoleCommands.isEmpty()) - description.append("None"); - else { - for (int i = 0; i < onUseConsoleCommands.size(); i++) { - String groupName = onUseConsoleCommands.get(i); - description.append(groupName); - if (i == onUseConsoleCommands.size() - 1) description.append(", "); - } - description.delete(description.length(), description.length()); - } - - embed.addField(item.getName() + " - `" + item.getId() + "`", description.toString(), false); - } - - Economy.saveItems(items); - - event.replyEmbeds(embed.build()).queue(); - - } - case "edit" -> { - - int itemId; - try { - itemId = Objects.requireNonNull(event.getOption("id", OptionMapping::getAsInt)); - } catch (NullPointerException e) { - event.reply("ID cannot be null!").setEphemeral(true).queue(); - return; - } - Economy.ShopItem item = Economy.getItem(itemId); - if (item == null) { - event.reply("That item does not exist.").setEphemeral(true).queue(); - return; - } - - EmbedBuilder embed = getEditEmbed(item, Objects.requireNonNull(event.getGuild())); - event.replyEmbeds(embed.build()).setEphemeral(true).addActionRow(getEditDropdown(itemId).build()).queue(); - - } - case "add" -> { - - Messager.debug("Call to add."); - - String name = event.getOption("name", OptionMapping::getAsString); - if (name == null) { - event.reply("name cannot be null!").setEphemeral(true).queue(); - return; - } - String description = event.getOption("description", OptionMapping::getAsString); - if (description == null) { - event.reply("description cannot be null!").setEphemeral(true).queue(); - return; - } - Messager.debug("Got args."); - - if (Economy.getItems().size() >= 25) { - event.reply("Only 25 items can exist at a time!").setEphemeral(true).queue(); - return; - } - Economy.ShopItem shopItem = new Economy.ShopItem(name, description); - Messager.debug("Created new item."); - shopItem.ensureUniqueId(); - Messager.debug("ID is unique."); - int itemId = shopItem.getId(); - shopItem.setEnabled(false); - Messager.debug("Disabled."); - Economy.saveItem(shopItem); - Messager.debug("Saves."); - - EmbedBuilder embed = getEditEmbed(shopItem, Objects.requireNonNull(event.getGuild())); - Messager.debug("Got embed."); - - event.reply("The item has been created, but not enabled. Edit it below and set it to enabled when ready.") - .addEmbeds(embed.build()).setEphemeral(true).addActionRow(getEditDropdown(itemId).build()).queue(); - Messager.debug("Reply queued.."); - - } - case "remove" -> { - - int itemId; - try { - itemId = Objects.requireNonNull(event.getOption("id", OptionMapping::getAsInt)); - } catch (NullPointerException e) { - event.reply("ID cannot be null!").setEphemeral(true).queue(); - return; - } - - Economy.ShopItem item = Economy.getItem(itemId); - if (item == null) { - event.reply("That item could not be found.").setEphemeral(true).queue(); - return; - } - - List items = Economy.getItems(); - - Button confirm = Button.danger("item-" + itemId + "-delete", "Yes, permanently delete."); - - StringBuilder description = new StringBuilder(); - - description.append(item.getDescription()).append("\n\n") - .append("Price: ").append(Economy.getCurrencySymbol()).append(item.getPrice()) - .append("\nSale Percent: ").append(item.getSalePercent()).append("%") - .append("\nQuantity: "); - if (item.isInfinite()) description.append("Infinite"); - else description.append(item.getQuantity()); - description.append("\nEnabled: ").append(item.isEnabled()); - description.append("\nGifting: ").append(item.isGiftingEnabled()); - description.append("\nUsable: ").append(!item.isUseDisabled()); - description.append("\nMax Allowed: "); - if (item.getMaxAllowed() == -1) description.append("Infinite"); - else description.append(item.getMaxAllowed()); - - description.append("\nRoles Add on Use: "); - List onUseRolesAdd = item.getOnUseRolesAdd(); - if (onUseRolesAdd == null || onUseRolesAdd.isEmpty()) description.append("None"); - else { - for (int i = 0; i < onUseRolesAdd.size(); i++) { - Long roleId = onUseRolesAdd.get(i); - Role role = Objects.requireNonNull(event.getGuild()).getRoleById(roleId); - if (role == null) { - item.getOnUseRolesAdd().remove(roleId); - items.set(i, item); - continue; - } - description.append(role.getAsMention()); - if (i == onUseRolesAdd.size() - 1) description.append(", "); - } - description.delete(description.length(), description.length()); - } - - description.append("\nRoles Remove on Use: "); - List onUseRolesRemove = item.getOnUseRolesRemove(); - if (onUseRolesRemove == null || onUseRolesRemove.isEmpty()) description.append("None"); - else { - for (int i = 0; i < onUseRolesRemove.size(); i++) { - Long roleId = onUseRolesRemove.get(i); - Role role = Objects.requireNonNull(event.getGuild()).getRoleById(roleId); - if (role == null) { - item.getOnUseRolesRemove().remove(roleId); - items.set(i, item); - continue; - } - description.append(role.getAsMention()); - if (i == onUseRolesRemove.size() - 1) description.append(", "); - } - description.delete(description.length(), description.length()); - } - - description.append("\nGroups Parent on Use: "); - List onUseGroupsAdd = item.getOnUseGroupsAdd(); - if (onUseGroupsAdd == null || onUseGroupsAdd.isEmpty()) description.append("None"); - else { - for (int i = 0; i < onUseGroupsAdd.size(); i++) { - String groupName = onUseGroupsAdd.get(i); - description.append(groupName); - if (i == onUseGroupsAdd.size() - 1) description.append(", "); - } - description.delete(description.length(), description.length()); - } - - description.append("\nGroups Unparent on Use: "); - List onUseGroupsRemove = item.getOnUseGroupsRemove(); - if (onUseGroupsRemove == null || onUseGroupsRemove.isEmpty()) description.append("None"); - else { - for (int i = 0; i < onUseGroupsRemove.size(); i++) { - String groupName = onUseGroupsRemove.get(i); - description.append(groupName); - if (i == onUseGroupsRemove.size() - 1) description.append(", "); - } - description.delete(description.length(), description.length()); - } - - description.append("\nCommands on Use: "); - List onUseConsoleCommands = item.getOnUseConsoleCommands(); - if (onUseConsoleCommands == null || onUseConsoleCommands.isEmpty()) description.append("None"); - else { - for (int i = 0; i < onUseConsoleCommands.size(); i++) { - String groupName = onUseConsoleCommands.get(i); - description.append(groupName); - if (i == onUseConsoleCommands.size() - 1) description.append(", "); - } - description.delete(description.length(), description.length()); - } - - Economy.saveItems(items); - - EmbedBuilder embed = new EmbedBuilder(); - embed.setTitle("Are you sure you want to delete this item?").setDescription(description) - .setFooter("If you delete this item, it will be permanently removed from the shop and be cleared from all users. If you instead just want to disable this item, use /economy items edit This action cannot be undone."); - event.replyEmbeds(embed.build()).addActionRow(confirm).setEphemeral(true).queue(); - - } - } - } - case "users" -> { - - switch (subcommand) { - case "balance" -> { - User user = event.getOption("user", OptionMapping::getAsUser); - if (user == null) { - event.reply("That user could not be found.").setEphemeral(true).queue(); - return; - } - - Economy.Consumer consumer = Economy.getConsumer(user.getIdLong()); - double balance = consumer.getBalance(); - - try { - double newBalance = event.getOption("new-balance", OptionMapping::getAsDouble); - consumer.setBalance(newBalance); - Economy.saveConsumer(consumer); - - EmbedBuilder embed = new EmbedBuilder(); - embed.setAuthor(user.getName(), null, user.getAvatarUrl()); - embed.setDescription("Changed " + user.getAsMention() + "'s balance from " + Economy.getCurrencySymbol() + balance + " to " + Economy.getCurrencySymbol() + newBalance); - - event.replyEmbeds(embed.build()).queue(); - } catch (NullPointerException e) { - EmbedBuilder embed = new EmbedBuilder(); - embed.setAuthor(user.getName(), null, user.getAvatarUrl()); - embed.setDescription(user.getAsMention() + "'s current balance is " + Economy.getCurrencySymbol() + balance); - - event.replyEmbeds(embed.build()).queue(); - } - } - case "get-items" -> { - User user = event.getOption("user", OptionMapping::getAsUser); - if (user == null) { - event.reply("That user could not be found.").setEphemeral(true).queue(); - return; - } - - Economy.Consumer consumer = Economy.getConsumer(user.getIdLong()); - - EmbedBuilder embed = new EmbedBuilder(); - embed.setAuthor(user.getName(), null, user.getAvatarUrl()); - embed.setTitle(user.getEffectiveName() + "'s Inventory"); - - Map ownedItems = consumer.getItems(); - List items = Economy.getItems(); - - for (Economy.ShopItem item : items) { - int id = item.getId(); - Integer quantityOwned = ownedItems.get(id); - if (quantityOwned == null || quantityOwned == 0) { - continue; - } - embed.addField(quantityOwned + " " + item.getName(), "`" + id + "`", true); - } - - event.replyEmbeds(embed.build()).queue(); - } - case "set-items" -> { - User user = event.getOption("user", OptionMapping::getAsUser); - Integer id = event.getOption("id", OptionMapping::getAsInt); - Integer quantity = event.getOption("new-quantity", OptionMapping::getAsInt); - assert id != null; - assert quantity != null; - - Economy.ShopItem item = Economy.getItem(id); - if (item == null) { - event.reply("That item does not exist!").setEphemeral(true).queue(); - return; - } - - if (quantity < 0) { - event.reply("Quantity must be a positive number!").setEphemeral(true).queue(); - return; - } - if (quantity > item.getMaxAllowed() && item.getMaxAllowed() != -1) { - event.reply("You cannot set the quantity to above the max allowed!").setEphemeral(true).queue(); - return; - } - - if (user == null) { - event.reply("That user could not be found.").setEphemeral(true).queue(); - return; - } - - Economy.Consumer consumer = Economy.getConsumer(user.getIdLong()); - consumer.setItemQuantity(id, quantity); - Economy.saveConsumer(consumer); - - event.reply("Set quantity of " + item.getName() + " owned by " + user.getAsMention() + " to " + quantity + ".").queue(); - } case "daily-streak" -> { - User user = event.getOption("user", OptionMapping::getAsUser); - Integer value = event.getOption("new-value", OptionMapping::getAsInt); - - if (user == null) { - event.reply("User cannot be null!").setEphemeral(true).queue(); - return; - } - - Economy.Consumer consumer = Economy.getConsumer(user.getIdLong()); - - if (value == null) { - EmbedBuilder embed = new EmbedBuilder(); - embed.setDescription(user.getAsMention() + " has a daily streak of " + consumer.getGameData().getDailyStreak()); - - event.replyEmbeds(embed.build()).queue(); - return; - } - - Economy.GameData gameData = consumer.getGameData(); - gameData.setDailyStreak(value); - gameData.setLastDaily(LocalDateTime.now().minusHours(24)); - consumer.setGameData(gameData); - Economy.saveConsumer(consumer); - - EmbedBuilder embed = new EmbedBuilder(); - embed.setDescription(user.getAsMention() + "'s streak has been set to " + value + " and their cooldown has been reset."); - - event.replyEmbeds(embed.build()).queue(); - } - } - } - default -> event.reply("Subcommand group not found.").setEphemeral(true).queue(); - } - - } - - @NotNull - private static EmbedBuilder getEditEmbed(@NotNull Economy.ShopItem item, @NotNull Guild guild) { - - EmbedBuilder embed = new EmbedBuilder(); - - StringBuilder description = new StringBuilder(); - - description.append(item.getDescription()).append("\n\n") - .append("Price: ").append(Economy.getCurrencySymbol()).append(item.getPrice()) - .append("\nSale Percent: ").append(item.getSalePercent()).append("%") - .append("\nQuantity: "); - if (item.isInfinite()) description.append("Infinite"); - else description.append(item.getQuantity()); - description.append("\nEnabled: ").append(item.isEnabled()); - description.append("\nGifting: ").append(item.isGiftingEnabled()); - description.append("\nUsable: ").append(!item.isUseDisabled()); - description.append("\nMax Allowed: "); - if (item.getMaxAllowed() == -1) description.append("Infinite"); - else description.append(item.getMaxAllowed()); - - description.append("\nRoles Add on Use: "); - List onUseRolesAdd = item.getOnUseRolesAdd(); - if (onUseRolesAdd == null || onUseRolesAdd.isEmpty()) description.append("None"); - else { - for (int i = 0; i < onUseRolesAdd.size(); i++) { - Long roleId = onUseRolesAdd.get(i); - Role role = guild.getRoleById(roleId); - if (role == null) { - item.getOnUseRolesAdd().remove(roleId); - Economy.saveItem(item); - continue; - } - description.append(role.getAsMention()); - if (i == onUseRolesAdd.size() - 1) description.append(", "); - } - description.delete(description.length(), description.length()); - } - - description.append("\nRoles Remove on Use: "); - List onUseRolesRemove = item.getOnUseRolesRemove(); - if (onUseRolesRemove == null || onUseRolesRemove.isEmpty()) description.append("None"); - else { - for (int i = 0; i < onUseRolesRemove.size(); i++) { - Long roleId = onUseRolesRemove.get(i); - Role role = guild.getRoleById(roleId); - if (role == null) { - item.getOnUseRolesRemove().remove(roleId); - Economy.saveItem(item); - continue; - } - description.append(role.getAsMention()); - if (i == onUseRolesRemove.size() - 1) description.append(", "); - } - description.delete(description.length(), description.length()); - } - - description.append("\nGroups Parent on Use: "); - List onUseGroupsAdd = item.getOnUseGroupsAdd(); - if (onUseGroupsAdd == null || onUseGroupsAdd.isEmpty()) description.append("None"); - else { - for (int i = 0; i < onUseGroupsAdd.size(); i++) { - String groupName = onUseGroupsAdd.get(i); - description.append(groupName); - if (i == onUseGroupsAdd.size() - 1) description.append(", "); - } - description.delete(description.length(), description.length()); - } - - description.append("\nGroups Unparent on Use: "); - List onUseGroupsRemove = item.getOnUseGroupsRemove(); - if (onUseGroupsRemove == null || onUseGroupsRemove.isEmpty()) description.append("None"); - else { - for (int i = 0; i < onUseGroupsRemove.size(); i++) { - String groupName = onUseGroupsRemove.get(i); - description.append(groupName); - if (i == onUseGroupsRemove.size() - 1) description.append(", "); - } - description.delete(description.length(), description.length()); - } - - description.append("\nCommands on Use: "); - List onUseConsoleCommands = item.getOnUseConsoleCommands(); - if (onUseConsoleCommands == null || onUseConsoleCommands.isEmpty()) description.append("None"); - else { - for (int i = 0; i < onUseConsoleCommands.size(); i++) { - String groupName = onUseConsoleCommands.get(i); - description.append(groupName); - if (i == onUseConsoleCommands.size() - 1) description.append(", "); - } - description.delete(description.length(), description.length()); - } - - embed.setTitle(item.getName() + " - " + item.getId()); - embed.setDescription(description.toString()); - embed.setFooter("Choose a property from the select menu to edit."); - - return embed; - } - - @NotNull - private static StringSelectMenu.Builder getEditDropdown(int itemId) { - - StringSelectMenu.Builder selectMenu = StringSelectMenu.create("item-" + itemId + "-edit-select"); - return selectMenu - .addOption("Name", "name", "The name of the item.") - .addOption("Description", "description", "The description of the item.") - .addOption("Price", "price", "The regular price of the item.") - .addOption("Sale Percent", "salePercent", "The percent to remove from the regular price.") - .addOption("Quantity", "quantity", "The quantity of this item available in the shop.") - .addOption("Max Allowed", "maxAllowed", "The maximum quantity of this item a user can have at a time.") - .addOption("Enabled", "enabled", "Whether the item can be bought. Disabled items can still be used.") - .addOption("Gifting Enabled", "giftingEnabled", "Where the item can be transferred to another user.") - .addOption("Use Disabled", "useDisabled", "Whether the item's use is disabled. Useful for vanity items.") - .addOption("Use On Purchase", "useOnPurchase", "Whether the item is auto-used upon purchase.") - .addOption("Roles to Add", "onUseRolesAdd", "The roles to add upon use.") - .addOption("Roles to Remove", "onUseRolesRemove", "The roles to remove upon use.") - .addOption("Groups to Add", "onUseGroupsAdd", "The permission groups to add upon use.") - .addOption("Groups to Remove", "onUseGroupsRemove", "The permission groups to remove upon use.") - .addOption("Console Commands", "onUseConsoleCommands", "The commands to execute upon use."); - - } - - @Override - public void onStringSelectInteraction(@NotNull StringSelectInteractionEvent event) { - String id = event.getComponentId(); - String[] splitId = id.split("-"); - - Messager.debug("Got string select menu with id " + id); - - if (event.getSelectedOptions().isEmpty()) return; - SelectOption selectedOption = event.getSelectedOptions().get(0); - - String type = splitId[0]; - if (type.equals("item")) { - - int itemId = Integer.parseInt(splitId[1]); - Economy.ShopItem item = Economy.getItem(itemId); - if (item == null) { - event.reply("That item could not be found.").setEphemeral(true).queue(); - return; - } - - String action = splitId[2]; - if (action.equals("edit")) { - String subAction = splitId[3]; - if (subAction.equals("select")) { - String value = selectedOption.getValue(); - - if (value.equals("enabled") || value.equals("giftingEnabled") || value.equals("useDisabled") || value.equals("useOnPurchase")) { - StringSelectMenu.Builder toggleMenu = StringSelectMenu.create("item-" + itemId + "-edit-toggle-" + value); - toggleMenu.addOption("True", "true").addOption("False", "false"); - toggleMenu.setPlaceholder("Set to true or false"); - - event.editComponents(event.getMessage().getActionRows().get(0)).queue(); // remove all action rows except value select - List components = new ArrayList<>(event.getMessage().getComponents()); - components.add(ActionRow.of(toggleMenu.build())); - event.getHook().editOriginalComponents(components).queue(); - } else if (value.equals("onUseRolesAdd") || value.equals("onUseRolesRemove")) { - - EntitySelectMenu.Builder selectMenu; - - if (value.equals("onUseRolesAdd")) { - selectMenu = EntitySelectMenu.create("item-" + itemId + "-edit-roles-add", EntitySelectMenu.SelectTarget.ROLE); - if (item.getOnUseRolesAdd() != null) { - List existingValues = new ArrayList<>(); - for (Long l : item.getOnUseRolesAdd()) { - existingValues.add(EntitySelectMenu.DefaultValue.role(l)); - } - selectMenu.setDefaultValues(existingValues); - } - } else { - selectMenu = EntitySelectMenu.create("item-" + itemId + "-edit-roles-remove", EntitySelectMenu.SelectTarget.ROLE); - if (item.getOnUseRolesRemove() != null) { - List existingValues = new ArrayList<>(); - for (Long l : item.getOnUseRolesRemove()) { - existingValues.add(EntitySelectMenu.DefaultValue.role(l)); - } - selectMenu.setDefaultValues(existingValues); - } - } - - selectMenu.setPlaceholder("Select roles to include"); - - event.editComponents(event.getMessage().getActionRows().get(0)).queue(); // remove all action rows except value select - List components = new ArrayList<>(event.getMessage().getComponents()); - components.add(ActionRow.of(selectMenu.build())); - event.getHook().editOriginalComponents(components).queue(); - - - } else { - - Modal.Builder modal = Modal.create("item-" + itemId + "-edit-" + value, "Change " + value + " of item " + itemId); - modal.addActionRow(TextInput.create("new" + value, "New " + value, TextInputStyle.PARAGRAPH).build()); - event.replyModal(modal.build()).queue(); - event.getHook().editOriginalComponents(event.getMessage().getActionRows().get(0)).queue(); // remove all action rows except value select - } - } else if (subAction.equals("toggle")) { - String value = splitId[4]; - boolean bool = Boolean.parseBoolean(selectedOption.getValue()); - switch (value) { - case "enabled" -> item.setEnabled(bool); - case "giftingEnabled" -> item.setGiftingEnabled(bool); - case "useDisabled" -> item.setUseDisabled(bool); - case "useOnPurchase" -> item.setUseOnPurchase(bool); - default -> { - event.reply("Did not expect this property to be set this way!").setEphemeral(true).queue(); - return; - } - } - Economy.saveItem(item); - event.editMessageEmbeds(getEditEmbed(item, Objects.requireNonNull(event.getGuild())).build()).queue(); - Objects.requireNonNull(event.getMessage()).reply("Toggled " + value + " of item `" + item.getId() + "` to " + bool + ".").queue(); - } else { - event.reply("Unexpected request: " + id).queue(); - } - } else { - event.reply("Unexpected request: " + id).queue(); - } - } - } - - @Override - public void onEntitySelectInteraction(@NotNull EntitySelectInteractionEvent event) { - String id = event.getComponentId(); - String[] splitId = id.split("-"); - - Messager.debug("Got string select menu with id " + id); - - String type = splitId[0]; - if (type.equals("item")) { - - int itemId = Integer.parseInt(splitId[1]); - Economy.ShopItem item = Economy.getItem(itemId); - if (item == null) { - event.reply("That item could not be found.").setEphemeral(true).queue(); - return; - } - - String action = splitId[2]; - if (action.equals("edit")) { - String subAction = splitId[3]; - if (subAction.equals("roles")) { - String roleAction = splitId[4]; - if (roleAction.equals("add")) { - - List onUseRolesAdd = item.getOnUseRolesAdd(); - if (onUseRolesAdd == null) onUseRolesAdd = new ArrayList<>(); - - for (Role role : event.getMentions().getRoles()) { - onUseRolesAdd.add(role.getIdLong()); - } - - item.setOnUseRolesAdd(onUseRolesAdd); - Economy.saveItem(item); - event.editMessageEmbeds(getEditEmbed(item, Objects.requireNonNull(event.getGuild())).build()).queue(); - Objects.requireNonNull(event.getMessage()).reply("Set onUseRolesAdd of item `" + item.getId() + "` to " + event.getMentions().getRoles().size() + " role(s).").queue(); - - } else if (roleAction.equals("remove")) { - - List onUseRolesRemove = item.getOnUseRolesAdd(); - if (onUseRolesRemove == null) onUseRolesRemove = new ArrayList<>(); - - for (Role role : event.getMentions().getRoles()) { - onUseRolesRemove.add(role.getIdLong()); - } - - item.setOnUseRolesRemove(onUseRolesRemove); - Economy.saveItem(item); - event.editMessageEmbeds(getEditEmbed(item, Objects.requireNonNull(event.getGuild())).build()).queue(); - Objects.requireNonNull(event.getMessage()).reply("Set onUseRolesRemove of item `" + item.getId() + "` to " + event.getMentions().getRoles().size() + " role(s).").queue(); - - } else { - event.reply("Unexpected request: " + id).queue(); - } - } - } - } - } - - @Override - public void onButtonInteraction(@NotNull ButtonInteractionEvent event) { - String id = event.getButton().getId(); - assert id != null; - String[] splitId = id.split("-"); - - Messager.debug("Got button with id " + id); - - String type = splitId[0]; - if (type.equals("item")) { - - int itemId = Integer.parseInt(splitId[1]); - Economy.ShopItem item = Economy.getItem(itemId); - if (item == null) { - event.reply("That item could not be found.").setEphemeral(true).queue(); - return; - } - - String action = splitId[2]; - if (action.equals("delete")) { - Economy.removeItem(item); - event.editMessage("Deleted item `" + item.getId() + "`.").queue(); - event.getHook().editOriginalEmbeds(new ArrayList<>()).queue(); - event.editButton(null).queue(); - } - } - } - - @Override - public void onModalInteraction(@NotNull ModalInteractionEvent event) { - String id = event.getModalId(); - String[] splitId = id.split("-"); - - Messager.debug("Got modal with id " + id); - - String type = splitId[0]; - if (type.equals("item")) { - int itemId = Integer.parseInt(splitId[1]); - Economy.ShopItem item = Economy.getItem(itemId); - - if (item == null) { - event.reply("That item does not exist!").setEphemeral(true).queue(); - return; - } - - String action = splitId[2]; - if (action.equals("edit")) { - - String editValue = splitId[3]; - String modalResponse = event.getValues().get(0).getAsString(); - - try { - switch (editValue) { - case "name" -> item.setName(modalResponse); - case "description" -> item.setDescription(modalResponse); - case "price" -> item.setPrice(Double.parseDouble(modalResponse)); - case "salePercent" -> item.setSalePercent(Double.parseDouble(modalResponse)); - case "quantity" -> item.setQuantity(Integer.parseInt(modalResponse)); - case "maxAllowed" -> item.setMaxAllowed(Integer.parseInt(modalResponse)); - case "onUseGroupsAdd" -> { - List groups = new ArrayList<>(); - for (String s : modalResponse.split(",")) groups.add(s.strip()); - item.setOnUseGroupsAdd(groups); - } - case "onUseGroupsRemove" -> { - List groups = new ArrayList<>(); - for (String s : modalResponse.split(",")) groups.add(s.strip()); - item.setOnUseGroupsRemove(groups); - } - case "onUseConsoleCommands" -> { - List commands = new ArrayList<>(); - for (String s : modalResponse.split(",")) commands.add(s.strip()); - item.setOnUseConsoleCommands(commands); - } - default -> { - event.reply("Did not expect this property to be set this way!").setEphemeral(true).queue(); - return; - } - } - } catch (NumberFormatException e) { - event.reply("Could not parse response as a number!").setEphemeral(true).queue(); - return; - } - - Economy.saveItem(item); - event.editMessageEmbeds(getEditEmbed(item, Objects.requireNonNull(event.getGuild())).build()).queue(); - Objects.requireNonNull(event.getMessage()).reply("Changed " + editValue + " of item `" + itemId + "` to " + modalResponse).queue(); - } - } - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdEcostats.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdEcostats.java deleted file mode 100644 index d7ad453..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdEcostats.java +++ /dev/null @@ -1,44 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import io.github.stonley890.dreamvisitor.Bot; -import io.github.stonley890.dreamvisitor.data.Economy; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import net.dv8tion.jda.api.utils.TimeFormat; -import org.jetbrains.annotations.NotNull; - -import java.time.LocalDateTime; - -public class DCmdEcostats implements DiscordCommand { - @NotNull - @Override - public SlashCommandData getCommandData() { - return Commands.slash("ecostats", "Get your stats."); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - - Economy.Consumer consumer = Economy.getConsumer(event.getUser().getIdLong()); - Economy.GameData gameData = consumer.getGameData(); - gameData.updateStreak(); - consumer.setGameData(gameData); - Economy.saveConsumer(consumer); - - EmbedBuilder embed = new EmbedBuilder(); - - embed.setTitle("Stats").setAuthor(null, event.getUser().getAvatarUrl()) - .setDescription("Here are your stats as of " + Bot.createTimestamp(LocalDateTime.now(), TimeFormat.DATE_TIME_SHORT) + ", " + event.getUser().getAsMention() + ".") - .addField("Balance", Economy.getCurrencySymbol() + consumer.getBalance(), true) - .addField("Daily Streak", gameData.getDailyStreak() + " days", true); - - String workMinutes = String.valueOf(gameData.timeUntilNextWork().toMinutes()).replaceFirst("-", ""); - - embed.addField("Time Until Next Work", workMinutes + " minutes.", false); - - event.replyEmbeds(embed.build()).queue(); - - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdInfractions.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdInfractions.java deleted file mode 100644 index 5f27fbc..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdInfractions.java +++ /dev/null @@ -1,159 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import io.github.stonley890.dreamvisitor.Bot; -import io.github.stonley890.dreamvisitor.data.AltFamily; -import io.github.stonley890.dreamvisitor.data.Infraction; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.Permission; -import net.dv8tion.jda.api.entities.User; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent; -import net.dv8tion.jda.api.hooks.ListenerAdapter; -import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; -import net.dv8tion.jda.api.interactions.commands.OptionMapping; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import net.dv8tion.jda.api.interactions.components.buttons.Button; -import net.dv8tion.jda.api.interactions.components.selections.SelectOption; -import net.dv8tion.jda.api.utils.TimeFormat; -import org.jetbrains.annotations.NotNull; - -import java.time.LocalDateTime; -import java.util.List; -import java.util.Objects; - -public class DCmdInfractions extends ListenerAdapter implements DiscordCommand { - @Override - public @NotNull SlashCommandData getCommandData() { - return Commands.slash("infractions", "Get the infractions of a user.") - .addOption(OptionType.USER, "user", "The user whose infractions to get.", true) - .setDefaultPermissions(DefaultMemberPermissions.DISABLED); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - User user = event.getOption("user", OptionMapping::getAsUser); - if (user == null) { - event.reply("Null option! Invalid!").queue(); - return; - } - - long userId = user.getIdLong(); - long parent = AltFamily.getParent(userId); - if (parent != userId) { - Objects.requireNonNull(event.getGuild()).retrieveMemberById(parent).queue(parentMember -> event.reply("That user is the child of " + parentMember.getAsMention() + ". Search their infractions instead.").queue()); - return; - } - - List infractions; - infractions = Infraction.getInfractions(userId); - - if (infractions.isEmpty()) { - event.reply(user.getName() + " has no recorded infractions.").queue(); - return; - } - - EmbedBuilder embed = new EmbedBuilder(); - - Button primary = Button.primary("infraction-expire-" + userId, "Expire a warn"); - Button danger = Button.danger("infraction-remove-" + userId, "Remove a warn"); - - Button noBan = Button.secondary("setban-" + userId + "-none", "Set No Ban"); - Button tempBan = Button.secondary("setban-" + userId + "-temp", "Set Temp-Banned"); - Button fullBan = Button.secondary("setban-" + userId + "-full", "Set Banned"); - - if (Infraction.hasBan(userId)) fullBan = fullBan.asDisabled(); - else if (Infraction.hasTempban(userId)) tempBan = tempBan.asDisabled(); - else noBan = noBan.asDisabled(); - - for (Infraction infraction : infractions) { - String expire = "Valid"; - if (infraction.isExpired()) expire = "Expired"; - embed.addField( - Bot.createTimestamp(infraction.getTime(), TimeFormat.DATE_SHORT).toString(), - "*Value: " + infraction.getValue() + ", " + expire + "\n**Reason:** " + infraction.getReason(), - false); - } - - embed - .setTitle("Infractions") - .setDescription("Infractions of " + user.getAsMention() + ":") - .setAuthor(user.getName(), null, user.getAvatarUrl()) - .setFooter("The total value of valid infractions is " + Infraction.getInfractionCount(infractions, false) + ".\n" + - "The total value of infractions " + Infraction.getInfractionCount(infractions, true) + "."); - - event.replyEmbeds(embed.build()).addActionRow(primary, danger).addActionRow(noBan, tempBan, fullBan).queue(); - } - - @Override - public void onStringSelectInteraction(@NotNull StringSelectInteractionEvent event) { - if (Objects.requireNonNull(event.getComponent().getId()).startsWith("infraction-expire-")) { - long id = Long.parseLong(event.getComponent().getId().substring("infraction-expire-".length())); - Objects.requireNonNull(event.getGuild()).retrieveMemberById(id).queue(member -> { - - @NotNull List infractions; - SelectOption selectOption = event.getInteraction().getSelectedOptions().get(0); - if (selectOption == null) return; - - LocalDateTime selectedTime = LocalDateTime.parse(selectOption.getValue()); - - infractions = Infraction.getInfractions(member.getIdLong()); - - if (infractions.isEmpty()) { - event.reply("That user has no infractions.").queue(); - return; - } - - for (Infraction infraction : infractions) { - if (infraction.isExpired()) continue; - if (infraction.getTime().equals(selectedTime)) { - infractions.remove(infraction); - infraction.expire(); - infractions.add(infraction); - break; - } - } - Infraction.setInfractions(infractions, member.getIdLong()); - - event.reply("Infraction expired.").queue(); - event.getMessage().editMessageComponents(event.getMessage().getActionRows().get(0).asDisabled()).queue(); - }); - } else if (Objects.requireNonNull(event.getComponent().getId()).startsWith("infraction-remove-")) { - - // ensure user has permission to use /infractions command - if (!event.getMember().hasPermission(Permission.MODERATE_MEMBERS)) { - event.reply("You do not have permission to use this command.").queue(); - return; - } - - long id = Long.parseLong(event.getComponent().getId().substring("infraction-remove-".length())); - event.getJDA().retrieveUserById(id).queue(member -> { - - @NotNull List infractions; - SelectOption selectOption = event.getInteraction().getSelectedOptions().get(0); - if (selectOption == null) return; - - LocalDateTime selectedTime = LocalDateTime.parse(selectOption.getValue()); - - infractions = Infraction.getInfractions(member.getIdLong()); - - if (infractions.isEmpty()) { - event.reply("That user has no infractions.").queue(); - return; - } - - for (Infraction infraction : infractions) { - if (infraction.getTime().equals(selectedTime)) { - infractions.remove(infraction); - break; - } - } - Infraction.setInfractions(infractions, member.getIdLong()); - - event.reply("Infraction removed.").queue(); - event.getMessage().editMessageComponents(event.getMessage().getActionRows().get(0).asDisabled()).queue(); - }); - } - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdInventory.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdInventory.java deleted file mode 100644 index 719d240..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdInventory.java +++ /dev/null @@ -1,303 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import io.github.stonley890.dreamvisitor.data.Economy; -import io.github.stonley890.dreamvisitor.functions.Messager; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.Mentions; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; -import net.dv8tion.jda.api.events.interaction.component.EntitySelectInteractionEvent; -import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent; -import net.dv8tion.jda.api.hooks.ListenerAdapter; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import net.dv8tion.jda.api.interactions.components.ActionRow; -import net.dv8tion.jda.api.interactions.components.buttons.Button; -import net.dv8tion.jda.api.interactions.components.selections.EntitySelectMenu; -import net.dv8tion.jda.api.interactions.components.selections.SelectOption; -import net.dv8tion.jda.api.interactions.components.selections.StringSelectMenu; -import org.jetbrains.annotations.NotNull; - -import java.awt.*; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -public class DCmdInventory extends ListenerAdapter implements DiscordCommand { - - @NotNull - @Override - public SlashCommandData getCommandData() { - return Commands.slash("inventory", "View your inventory."); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - - Economy.Consumer consumer = Economy.getConsumer(event.getUser().getIdLong()); - Map items = consumer.getItems(); - - EmbedBuilder embed = new EmbedBuilder(); - embed.setTitle("Your Inventory"); - - if (items.isEmpty()) { - embed.setDescription("You do not currently have any items. You can purchase items from the shop."); - event.replyEmbeds(embed.build()).setEphemeral(true).queue(); - return; - } - - embed = getInvEmbed(consumer); - - if (embed.getFields().isEmpty()) { - embed.setDescription("You do not currently have any items. You can purchase items from the shop."); - event.replyEmbeds(embed.build()).setEphemeral(true).queue(); - return; - } - - Button useItem = Button.primary("inv-" + consumer.getId() + "-use", "Use an Item"); - Button giftItem = Button.success("inv-" + consumer.getId() + "-gift", "Gift an Item"); - - event.replyEmbeds(embed.build()).addActionRow(useItem, giftItem).queue(); - - } - - @NotNull - private static EmbedBuilder getInvEmbed(Economy.Consumer consumer) { - - EmbedBuilder embed = new EmbedBuilder(); - - List shopItems = Economy.getItems(); - for (Economy.ShopItem shopItem : shopItems) { - int quantityOfItem = consumer.getQuantityOfItem(shopItem.getId()); - if (quantityOfItem == 0) continue; - String useNotice = "This item can be used."; - String giftNotice = "This item can be gifted."; - if (shopItem.isUseDisabled()) useNotice = "This item cannot be used."; - if (!shopItem.isGiftingEnabled()) giftNotice = "This item cannot be gifted."; - embed.addField("**" + quantityOfItem + "** " + shopItem.getName(), useNotice + "\n" + giftNotice, true); - } - - return embed; - } - - @Override - public void onButtonInteraction(@NotNull ButtonInteractionEvent event) { - String id = event.getButton().getId(); - if (id == null) return; - - String[] split = id.split("-"); - - if (!id.startsWith("inv-")) return; - - long consumerId = Long.parseLong(split[1]); - - if (consumerId != event.getUser().getIdLong()) { - event.reply("Only the invoker of this command can interact with this.").setEphemeral(true).queue(); - return; - } - - Economy.Consumer consumer = Economy.getConsumer(consumerId); - if (split[2].equals("use")) { - StringSelectMenu.Builder selectMenu = StringSelectMenu.create("inv-" + consumerId + "-use"); - selectMenu.setPlaceholder("Select an item to use"); - for (Economy.ShopItem item : Economy.getItems()) { - if (consumer.getItemQuantity(item.getId()) > 0 && !item.isUseDisabled()) { - selectMenu.addOption(item.getName(), String.valueOf(item.getId())); - } - } - if (selectMenu.getOptions().isEmpty()) { - event.reply("You do not have any items you can use.").setEphemeral(true).queue(); - return; - } - event.replyComponents(ActionRow.of(selectMenu.build())).setEphemeral(true).queue(); - } else if (split[2].equals("gift")) { - StringSelectMenu.Builder selectMenu = StringSelectMenu.create("inv-" + consumerId + "-gift"); - selectMenu.setPlaceholder("Select an item to gift"); - for (Economy.ShopItem item : Economy.getItems()) { - if (consumer.getItemQuantity(item.getId()) > 0 && item.isGiftingEnabled()) { - Messager.debug("adding " + item.getId() + " to gift list"); - selectMenu.addOption(item.getName(), String.valueOf(item.getId())); - } - } - Messager.debug("selectmenu size: " + selectMenu.getOptions().size()); - if (selectMenu.getOptions().isEmpty()) { - event.reply("You do not have any items you can gift.").setEphemeral(true).queue(); - return; - } - event.replyComponents(ActionRow.of(selectMenu.build())).setEphemeral(true).queue(); - } - } - - @Override - public void onStringSelectInteraction(@NotNull StringSelectInteractionEvent event) { - String id = event.getSelectMenu().getId(); - if (id == null) return; - SelectOption selected = event.getSelectedOptions().get(0); - - String[] split = id.split("-"); - - if (!id.startsWith("inv-")) return; - - long consumerId = Long.parseLong(split[1]); - - if (consumerId != event.getUser().getIdLong()) { - event.reply("Only the invoker of this command can interact with this.").setEphemeral(true).queue(); - return; - } - - Economy.Consumer consumer = Economy.getConsumer(consumerId); - switch (split[2]) { - case "use" -> { - EmbedBuilder embed = new EmbedBuilder(); - embed.setColor(Color.RED); - - int itemId = Integer.parseInt(selected.getValue()); - Economy.ShopItem item = Economy.getItem(itemId); - if (item == null) { - event.replyEmbeds(embed.setDescription("That item could not be found.").build()).setEphemeral(true).queue(); - return; - } - int itemQuantity = consumer.getItemQuantity(itemId); - if (itemQuantity < 1) { - event.replyEmbeds(embed.setDescription("You do not have any of that item to use!").build()).setEphemeral(true).queue(); - return; - } - if (item.isUseDisabled()) { - event.replyEmbeds(embed.setDescription("That item cannot be used.").build()).setEphemeral(true).queue(); - return; - } - - try { - item.use(Objects.requireNonNull(event.getMember())); - } catch (UnsupportedOperationException e) { - event.replyEmbeds(embed.setDescription(e.getMessage()).build()).setEphemeral(true).queue(); - return; - } - - consumer.setItemQuantity(itemId, itemQuantity - 1); - Economy.saveConsumer(consumer); - - embed.setColor(Color.GREEN).setDescription("Used one " + item.getName() + "!") - .setFooter("You now have " + consumer.getQuantityOfItem(itemId) + " of this item left."); - event.replyEmbeds(embed.build()).queue(); - - EmbedBuilder invEmbed = new EmbedBuilder(); - invEmbed.setTitle("Your Inventory"); - - Map items = consumer.getItems(); - - if (items.isEmpty()) { - invEmbed.setDescription("You do not currently have any items. You can purchase items from the shop."); - } else { - invEmbed = getInvEmbed(consumer); - if (invEmbed.getFields().isEmpty()) { - invEmbed.setDescription("You do not currently have any items. You can purchase items from the shop."); - } - } - - event.getMessage().editMessageEmbeds(invEmbed.build()).queue(); - - } - case "gift" -> { - EmbedBuilder embed = new EmbedBuilder(); - embed.setColor(Color.RED); - - int itemId = Integer.parseInt(selected.getValue()); - Economy.ShopItem item = Economy.getItem(itemId); - if (item == null) { - event.replyEmbeds(embed.setDescription("That item could not be found.").build()).setEphemeral(true).queue(); - return; - } - int itemQuantity = consumer.getItemQuantity(itemId); - if (itemQuantity < 1) { - event.replyEmbeds(embed.setDescription("You do not have any of that item to gift!").build()).queue(); - return; - } - if (!item.isGiftingEnabled()) { - event.replyEmbeds(embed.setDescription("That item cannot be gifted.").build()).setEphemeral(true).queue(); - return; - } - - EntitySelectMenu.Builder selectMenu = EntitySelectMenu.create("inv-" + consumerId + "-giftItem-" + item.getId(), EntitySelectMenu.SelectTarget.USER); - selectMenu.setPlaceholder("Select a user to gift to").setRequiredRange(1, 1); - - event.editComponents(event.getMessage().getComponents().get(0), ActionRow.of(selectMenu.build())).queue(); - } - } - } - - @Override - public void onEntitySelectInteraction(@NotNull EntitySelectInteractionEvent event) { - String id = event.getSelectMenu().getId(); - if (id == null) return; - Messager.debug("EntitySelectMenu with ID " + id); - Mentions mentions = event.getMentions(); - - String[] split = id.split("-"); - - if (!id.startsWith("inv-")) return; - - long consumerId = Long.parseLong(split[1]); - - if (consumerId != event.getUser().getIdLong()) { - event.reply("Only the invoker of this command can interact with this.").setEphemeral(true).queue(); - return; - } - - Economy.Consumer consumer = Economy.getConsumer(consumerId); - if (split[2].equals("giftItem")) { - EmbedBuilder embed = new EmbedBuilder(); - embed.setColor(Color.RED); - - int itemId = Integer.parseInt(split[3]); - Economy.ShopItem item = Economy.getItem(itemId); - if (item == null) { - event.replyEmbeds(embed.setDescription("That item could not be found.").build()).setEphemeral(true).queue(); - return; - } - int itemQuantity = consumer.getItemQuantity(itemId); - if (itemQuantity < 1) { - event.replyEmbeds(embed.setDescription("You do not have any of that item to gift!").build()).setEphemeral(true).queue(); - return; - } - if (!item.isGiftingEnabled()) { - event.replyEmbeds(embed.setDescription("That item cannot be gifted.").build()).setEphemeral(true).queue(); - return; - } - - List members = mentions.getMembers(); - if (members.isEmpty()) { - event.reply("You did not select anyone.").setEphemeral(true).queue(); - return; - } - - Member member = members.get(0); - - Economy.Consumer consumer1 = Economy.getConsumer(member.getIdLong()); - consumer1.setItemQuantity(itemId, consumer1.getQuantityOfItem(itemId) + 1); - consumer.setItemQuantity(itemId, consumer.getQuantityOfItem(itemId) - 1); - - Economy.saveConsumer(consumer); - Economy.saveConsumer(consumer1); - - embed.setDescription(event.getUser().getAsMention() + " gifted one " + item.getName() + " to " + member.getAsMention() + ".") - .setColor(Color.GREEN).setFooter("You now have " + consumer.getQuantityOfItem(itemId) + " of this item left."); - event.reply(member.getAsMention() + ", you were gifted an item!").addEmbeds(embed.build()).queue(); - - EmbedBuilder invEmbed = new EmbedBuilder(); - invEmbed.setTitle("Your Inventory"); - - Map items = consumer.getItems(); - - if (items.isEmpty()) { - invEmbed.setDescription("You do not currently have any items. You can purchase items from the shop."); - } else { - invEmbed = getInvEmbed(consumer); - if (invEmbed.getFields().isEmpty()) { - invEmbed.setDescription("You do not currently have any items. You can purchase items from the shop."); - } - } - } - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdLink.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdLink.java deleted file mode 100644 index 232ae1c..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdLink.java +++ /dev/null @@ -1,51 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import io.github.stonley890.dreamvisitor.data.AccountLink; -import io.github.stonley890.dreamvisitor.data.PlayerUtility; -import io.github.stonley890.dreamvisitor.functions.Messager; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.entities.User; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import org.jetbrains.annotations.NotNull; - -import java.awt.*; -import java.util.Objects; -import java.util.UUID; - -public class DCmdLink implements DiscordCommand { - @Override - public @NotNull SlashCommandData getCommandData() { - return Commands.slash("link", "Link a Discord account to a Minecraft account.") - .addOption(OptionType.USER, "user", "The Discord user to register.", true) - .addOption(OptionType.STRING, "username", "The Minecraft account to connect", true) - .setDefaultPermissions(DefaultMemberPermissions.DISABLED); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - Messager.debug("Command requested."); - User targetUser = Objects.requireNonNull(event.getOption("user")).getAsUser(); - Messager.debug("Got user."); - String username = Objects.requireNonNull(event.getOption("username")).getAsString(); - Messager.debug("Got username."); - - UUID uuid = PlayerUtility.getUUIDOfUsername(username); - Messager.debug("Command requested."); - - if (uuid == null) { - event.reply("`" + username + "` could not be found!").queue(); - return; - } - - EmbedBuilder embed = new EmbedBuilder(); - embed.setDescription(targetUser.getAsMention() + " is now linked to `" + username + "`!"); - embed.setColor(Color.GREEN); - - AccountLink.linkAccounts(uuid, targetUser.getIdLong()); - event.replyEmbeds(embed.build()).queue(); - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdList.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdList.java deleted file mode 100644 index 8cc8042..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdList.java +++ /dev/null @@ -1,75 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import io.github.stonley890.dreamvisitor.Bot; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.data.PlayerMemory; -import io.github.stonley890.dreamvisitor.data.PlayerUtility; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -public class DCmdList implements DiscordCommand { - @Override - public @NotNull SlashCommandData getCommandData() { - return Commands.slash("list", "List online players."); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - // Compile players to list unless no players online - - // Create a string builder - StringBuilder list = new StringBuilder(); - - // If there are players online - if (!Bukkit.getServer().getOnlinePlayers().isEmpty()) { - - Collection players = Bukkit.getServer().getOnlinePlayers(); - - List countedPlayers = new ArrayList<>(); - - // Iterate through each player - for (Player player : players) { - PlayerMemory memory = PlayerUtility.getPlayerMemory(player.getUniqueId()); - - // If player is not vanished, add to list - if (!memory.vanished) { - countedPlayers.add(player); - } - } - - // If there are no listed players (may occur with vanished players), report none - if (countedPlayers.isEmpty()) { - event.reply("**There are no players online.**").setEphemeral(true).queue(); - } else { - // Create string of list - for (Player player : countedPlayers) { - if (!list.isEmpty()) { - list.append("`, `"); - } - list.append(player.getName()); - } - String playerForm = "players"; - String isAreForm = "are"; - if (players.size() == 1) { - playerForm = "player"; - isAreForm = "is"; - } - // Send list - event.reply("**There " + isAreForm + " " + players.size() + " out of maximum " + Dreamvisitor.playerLimit + " " + playerForm + " online:** `" + list + "`") - .setEphemeral(true).queue(); - } - - } else { - event.reply("**There are no players online.**").setEphemeral(true).queue(); - } - - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdMsg.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdMsg.java deleted file mode 100644 index 36ff0a8..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdMsg.java +++ /dev/null @@ -1,51 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import io.github.stonley890.dreamvisitor.Bot; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.interactions.commands.OptionMapping; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.jetbrains.annotations.NotNull; - -import java.util.Objects; - -public class DCmdMsg implements DiscordCommand { - @Override - public @NotNull SlashCommandData getCommandData() { - return Commands.slash("msg", "Message a player on the Minecraft server.") - .addOption(OptionType.STRING, "username", "The user you want to message.", true) - .addOption(OptionType.STRING, "message", "The message to send.", true); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - // args - String username = event.getOption("username", OptionMapping::getAsString); - String msg = event.getOption("message", OptionMapping::getAsString); - - // Check for correct channel - if (event.getChannel() == Bot.getGameChatChannel()) { - // Check for player online - assert username != null; - if (Bukkit.getServer().getPlayer(username) != null) { - - // Send message - Objects.requireNonNull(Bukkit.getServer().getPlayer(username)).sendMessage( - ChatColor.GRAY + "[" + ChatColor.DARK_AQUA + event.getUser().getName() + ChatColor.GRAY + " -> " - + ChatColor.DARK_AQUA + "me" + ChatColor.GRAY + "] " + ChatColor.WHITE + msg); - - // Log message - Objects.requireNonNull(Bot.getJda().getTextChannelById(Bot.getGameLogChannel().getId())).sendMessage( - "**Message from " + event.getUser().getAsMention() + " to **`" + username + "`**:** " + msg).queue(); - - // Reply success - event.reply("Message sent!").setEphemeral(true).queue(); - - } else event.reply("`" + username + "` is not online!").setEphemeral(true).queue(); - } else - event.reply("This command must be executed in " + Bot.getGameChatChannel().getAsMention()).setEphemeral(true).queue(); - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdPanic.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdPanic.java deleted file mode 100644 index 688ea65..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdPanic.java +++ /dev/null @@ -1,56 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import io.github.stonley890.dreamvisitor.Bot; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; -import net.dv8tion.jda.api.hooks.ListenerAdapter; -import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import net.dv8tion.jda.api.interactions.components.buttons.Button; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; - -import java.util.Objects; - -public class DCmdPanic extends ListenerAdapter implements DiscordCommand { - @Override - public @NotNull SlashCommandData getCommandData() { - return Commands.slash("panic", "Kick all players from the server and set the player limit to 0.") - .setDefaultPermissions(DefaultMemberPermissions.DISABLED); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - EmbedBuilder replyEmbed = new EmbedBuilder(); - replyEmbed.setTitle("Are you sure?").setDescription("This will kick all players and set the player limit to 0. Click the button to confirm."); - - Button danger = Button.danger("panic", "Yes, I'm sure."); - - event.replyEmbeds(replyEmbed.build()).setEphemeral(true).addActionRow(danger).queue(); - } - - @Override - public void onButtonInteraction(@NotNull ButtonInteractionEvent event) { - if (!Objects.equals(event.getButton().getId(), "panic")) { - return; - } - Bukkit.getScheduler().runTask(Dreamvisitor.getPlugin(), () -> { - for (Player player : Bukkit.getServer().getOnlinePlayers()) if (!player.isOp()) player.kickPlayer("Panic!"); - }); - Dreamvisitor.playerLimit = 0; - Dreamvisitor.getPlugin().getConfig().set("playerlimit", 0); - Dreamvisitor.getPlugin().saveConfig(); - Bukkit.getServer().broadcastMessage( - ChatColor.RED + "Panicked by " + event.getUser().getName() + ".\nPlayer limit override set to 0."); - Bot.sendLog("**Panicked by " + event.getUser().getName()); - event.reply("Panicked!").queue(); - - // Disable button after use - event.editButton(event.getButton().asDisabled()).queue(); - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdResourcepackupdate.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdResourcepackupdate.java deleted file mode 100644 index 6cc7b89..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdResourcepackupdate.java +++ /dev/null @@ -1,154 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.functions.AutoRestart; -import io.github.stonley890.dreamvisitor.functions.Messager; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.io.*; -import java.net.HttpURLConnection; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.security.MessageDigest; -import java.util.Properties; - -public class DCmdResourcepackupdate implements DiscordCommand { - @Override - public @NotNull SlashCommandData getCommandData() { - return Commands.slash("resourcepackupdate", "Update the resource pack hash to prompt clients to download the pack.") - .setDefaultPermissions(DefaultMemberPermissions.DISABLED); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - event.deferReply().queue(); - - URL resourcePackURL; - try { - resourcePackURL = getLatestReleaseURL(Dreamvisitor.getPlugin().getConfig().getString("resourcePackRepo")); - Messager.debug("Found URL."); - } catch (IOException e) { - event.reply("Dreamvisitor was unable to find the resource pack URL: " + e.getMessage()).queue(); - return; - } - - try { - Messager.debug("Attempting to download the resource pack."); - HttpURLConnection connection = (HttpURLConnection) resourcePackURL.openConnection(); - connection.setRequestMethod("GET"); - connection.setReadTimeout(10000); // timeout - connection.connect(); - - if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { - Messager.debug("Generating hash."); - InputStream is = connection.getInputStream(); - MessageDigest sha1 = MessageDigest.getInstance("SHA-1"); - byte[] buffer = new byte[1024]; - int bytesRead; - - while ((bytesRead = is.read(buffer)) != -1) { - sha1.update(buffer, 0, bytesRead); - } - - byte[] hashBytes = sha1.digest(); - StringBuilder hash = new StringBuilder(); - - for (byte hashByte : hashBytes) { - hash.append(Integer.toString((hashByte & 0xff) + 0x100, 16).substring(1)); - } - - String newHash = hash.toString(); - Messager.debug("New hash: " + newHash); - Messager.debug("Writing changes to server.properties."); - - try { - Properties properties = getProperties(resourcePackURL, newHash); - - // Save the updated properties back to the file with UTF-8 encoding - BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("server.properties"), StandardCharsets.UTF_8)); - properties.store(writer, null); - writer.close(); - - Messager.debug("Success."); - event.getHook().editOriginal("The resource pack URL has been updated to " + resourcePackURL + - ". The SHA1 hash has been updated to " + newHash + ". The server must restart for changes to take effect. " + - "I will restart it automatically when 0 players are online. You can cancel this with `/autorestart`.").queue(); - event.getHook().retrieveOriginal().queue(AutoRestart::enableAutoRestart); - - } catch (IOException e) { - event.reply("Dreamvisitor encountered an while modifying server.properties: " + e.getMessage()).queue(); - } - } - } catch (Exception e) { - event.reply("Dreamvisitor encountered an error: " + e.getMessage()).queue(); - } - - - Dreamvisitor.getPlugin().saveConfig(); - } - - private static @NotNull Properties getProperties(URL resourcePackURL, String newHash) throws IOException { - // Load the server.properties file with UTF-8 encoding - Properties properties = new Properties(); - BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("server.properties"), StandardCharsets.UTF_8)); - properties.load(reader); - reader.close(); - - properties.setProperty("resource-pack", String.valueOf(resourcePackURL)); // Update the resource pack property - properties.setProperty("resource-pack-sha1", newHash); // Update the hash property - return properties; - } - - @NotNull - @Contract("_ -> new") - private static URL getLatestReleaseURL(String repo) throws IOException { - // Create a URL object - URL url = new URL("https://api.github.com/repos/" + repo + "/releases/latest"); - Messager.debug("Finding latest artifact at " + url); - - // Open a connection to the URL - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("GET"); - connection.setRequestProperty("Accept", "application/json"); - - // Read the response - Messager.debug("Sending request."); - BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); - Messager.debug("Parsing response."); - String inputLine; - StringBuilder content = new StringBuilder(); - while ((inputLine = in.readLine()) != null) { - content.append(inputLine); - } - - // Close connections - in.close(); - connection.disconnect(); - - // Parse the JSON response using Gson - Messager.debug("Converting to JSON."); - JsonElement jsonElement = JsonParser.parseString(content.toString()); - JsonObject jsonObject = jsonElement.getAsJsonObject(); - - // Access the assets array - Messager.debug("Locating assets[0].browser_download_url"); - JsonArray assets = jsonObject.getAsJsonArray("assets"); - if (!assets.isEmpty()) { - // Get the first asset's browser_download_url - JsonObject firstAsset = assets.get(0).getAsJsonObject(); - - return new URL(firstAsset.get("browser_download_url").getAsString()); - } else { - throw new FileNotFoundException(); - } - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdSeen.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdSeen.java deleted file mode 100644 index 8a6b3c9..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdSeen.java +++ /dev/null @@ -1,72 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import io.github.stonley890.dreamvisitor.data.AccountLink; -import io.github.stonley890.dreamvisitor.data.PlayerUtility; -import io.github.stonley890.dreamvisitor.functions.Messager; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.entities.User; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; -import net.dv8tion.jda.api.interactions.commands.OptionMapping; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import org.bukkit.Bukkit; -import org.jetbrains.annotations.NotNull; - -import java.awt.*; -import java.time.Duration; -import java.time.Instant; -import java.util.UUID; - -public class DCmdSeen implements DiscordCommand { - @NotNull - @Override - public SlashCommandData getCommandData() { - return Commands.slash("seen", "See when someone was last on the Minecraft server.") - .addOption(OptionType.USER, "user", "The user to search for.", true) - .setDefaultPermissions(DefaultMemberPermissions.ENABLED); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - - - User user = event.getOption("user", OptionMapping::getAsUser); - if (user == null) { - event.reply("user cannot be null!").setEphemeral(true).queue(); - return; - } - UUID uuid = AccountLink.getUuid(user.getIdLong()); - if (uuid == null) { - event.reply(user.getAsMention() + " does not have a linked Minecraft account.").setEphemeral(true).queue(); - return; - } - Messager.debug("UUID: " + uuid); - boolean online = Bukkit.getPlayer(uuid) != null; - Messager.debug("Online? " + online); - Instant time; - try { - if (online) { - time = PlayerUtility.getLastLogin(uuid); - } else { - time = PlayerUtility.getLastLogout(uuid); - } - } catch (Exception e) { - event.reply("EssentialsX is not currently active!").setEphemeral(true).queue(); - return; - } - - Duration duration = Duration.between(time, Instant.ofEpochMilli(System.currentTimeMillis())); - - EmbedBuilder embed = new EmbedBuilder(); - String status = "offline"; - if (online) status = "online"; - embed.setDescription(user.getAsMention() + " has been " + status + " since " + duration.toDaysPart() + " days, " + duration.toHoursPart() + " hours, " + duration.toMinutesPart() + " minutes, and " + duration.toSecondsPart() + " seconds ago."); - embed.setColor(Color.BLUE); - embed.setTimestamp(Instant.now()); - - event.replyEmbeds(embed.build()).queue(); - - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdSetgamechat.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdSetgamechat.java deleted file mode 100644 index 7395e32..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdSetgamechat.java +++ /dev/null @@ -1,28 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import io.github.stonley890.dreamvisitor.Bot; -import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; -import net.dv8tion.jda.api.interactions.commands.OptionMapping; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import org.jetbrains.annotations.NotNull; - -public class DCmdSetgamechat implements DiscordCommand { - @Override - public @NotNull SlashCommandData getCommandData() { - return Commands.slash("setgamechat", "Set the channel that game chat occurs in.") - .addOption(OptionType.CHANNEL, "channel", "The channel to set.", true, false) - .setDefaultPermissions(DefaultMemberPermissions.DISABLED); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - // Get channel from args - Bot.setGameChatChannel((TextChannel) event.getOption("channel", event.getChannel(), OptionMapping::getAsChannel)); - // Reply success - event.reply("Game chat channel set to " + Bot.getGameChatChannel().getAsMention()).queue(); - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdSetlogchat.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdSetlogchat.java deleted file mode 100644 index 7e275d3..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdSetlogchat.java +++ /dev/null @@ -1,28 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import io.github.stonley890.dreamvisitor.Bot; -import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; -import net.dv8tion.jda.api.interactions.commands.OptionMapping; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import org.jetbrains.annotations.NotNull; - -public class DCmdSetlogchat implements DiscordCommand { - @Override - public @NotNull SlashCommandData getCommandData() { - return Commands.slash("setlogchat", "Set the channel that logs Minecraft activity.") - .addOption(OptionType.CHANNEL, "channel", "The channel to set.", true, false) - .setDefaultPermissions(DefaultMemberPermissions.DISABLED); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - // Get channel from args - Bot.setGameLogChannel((TextChannel) event.getOption("channel", event.getChannel(), OptionMapping::getAsChannel)); - // Reply success - event.reply("Log chat channel set to " + Bot.getGameLogChannel().getAsMention()).queue(); - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdSetrole.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdSetrole.java deleted file mode 100644 index ac4d7d2..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdSetrole.java +++ /dev/null @@ -1,67 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import io.github.stonley890.dreamvisitor.Bot; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import org.jetbrains.annotations.NotNull; - -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import java.util.function.Predicate; - -public class DCmdSetrole implements DiscordCommand { - @Override - public @NotNull SlashCommandData getCommandData() { - return Commands.slash("setrole", "Set a role").addOptions( - new OptionData(OptionType.STRING, "type", "The role you want to set.", true) - .setAutoComplete(false) - .addChoice("HiveWing", "HiveWing") - .addChoice("IceWing", "IceWing") - .addChoice("LeafWing", "LeafWing") - .addChoice("MudWing", "MudWing") - .addChoice("NightWing", "NightWing") - .addChoice("RainWing", "RainWing") - .addChoice("SandWing", "SandWing") - .addChoice("SeaWing", "SeaWing") - .addChoice("SilkWing", "SilkWing") - .addChoice("SkyWing", "SkyWing") - ) - .addOption(OptionType.ROLE, "role", "The role to associate.", true) - .setDefaultPermissions(DefaultMemberPermissions.DISABLED); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - // Get role to set - String targetRole = Objects.requireNonNull(event.getOption("type")).getAsString(); - Role role = Objects.requireNonNull(event.getOption("role")).getAsRole(); - - if (Arrays.stream(Bot.TRIBE_NAMES).anyMatch(Predicate.isEqual(targetRole))) { - - // If one of the tribe names, find the index, get the list from config, and set the specified item - int index = Arrays.binarySearch(Bot.TRIBE_NAMES, targetRole); - List tribeRoles = Dreamvisitor.getPlugin().getConfig().getLongList("tribeRoles"); - - if (tribeRoles.isEmpty()) { - for (int i = 0; i < 10; i++) { - tribeRoles.add(0L); - } - } - - tribeRoles.set(index, role.getIdLong()); - Dreamvisitor.getPlugin().getConfig().set("tribeRoles", tribeRoles); - - } else { - event.reply("The target role must match a specified name!").setEphemeral(true).queue(); - } - event.reply("**" + targetRole + " set to " + role.getName() + "**").queue(); - Dreamvisitor.getPlugin().saveConfig(); - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdSetwhitelist.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdSetwhitelist.java deleted file mode 100644 index 551fad7..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdSetwhitelist.java +++ /dev/null @@ -1,28 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import io.github.stonley890.dreamvisitor.Bot; -import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; -import net.dv8tion.jda.api.interactions.commands.OptionMapping; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import org.jetbrains.annotations.NotNull; - -public class DCmdSetwhitelist implements DiscordCommand { - @Override - public @NotNull SlashCommandData getCommandData() { - return Commands.slash("setwhitelist", "Set the channel that whitelists players.") - .addOption(OptionType.CHANNEL, "channel", "The channel to set.", true, false) - .setDefaultPermissions(DefaultMemberPermissions.DISABLED); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - // Get channel from args - Bot.setWhitelistChannel((TextChannel) event.getOption("channel", event.getChannel(), OptionMapping::getAsChannel)); - // Reply success - event.reply("Whitelist channel set to " + Bot.getWhitelistChannel().getAsMention()).queue(); - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdShop.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdShop.java deleted file mode 100644 index ba06162..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdShop.java +++ /dev/null @@ -1,158 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import io.github.stonley890.dreamvisitor.data.Economy; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; -import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent; -import net.dv8tion.jda.api.hooks.ListenerAdapter; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import net.dv8tion.jda.api.interactions.components.buttons.Button; -import net.dv8tion.jda.api.interactions.components.selections.StringSelectMenu; -import org.jetbrains.annotations.NotNull; - -import java.awt.*; -import java.util.List; -import java.util.Objects; - -public class DCmdShop extends ListenerAdapter implements DiscordCommand { - - @NotNull - @Override - public SlashCommandData getCommandData() { - return Commands.slash("shop", "Access the shop."); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - - String currencySymbol = Economy.getCurrencySymbol(); - - EmbedBuilder embed = new EmbedBuilder(); - embed.setTitle(Economy.getShopName()); - embed.setColor(Color.yellow); - List items = Economy.getItems(); - items.removeIf(item -> !item.isEnabled()); - StringSelectMenu.Builder purchaseMenu = StringSelectMenu.create("purchase"); - if (items.isEmpty()) { - embed.setDescription("There are no items currently for sale."); - event.replyEmbeds(embed.build()).queue(); - return; - } - for (Economy.ShopItem item : items) { - String priceString = Economy.formatDouble(item.getPrice()); - double truePrice = item.getTruePrice(); - if (item.getSalePercent() > 0) { - priceString = "~~".concat(priceString).concat("~~ ").concat(Economy.formatDouble(truePrice)).concat(" (").concat(String.valueOf(item.getSalePercent())).concat("% off)"); - } - String header = (item.getName() + " - " + currencySymbol + priceString); - StringBuilder body = new StringBuilder(); - body.append("`").append(item.getId()).append("`"); - body.append("\n**").append(item.getDescription()).append("**"); - if (!item.isInfinite()) body.append("\n").append(item.getQuantity()).append(" of this item remain(s)."); - if (item.isGiftingEnabled()) body.append("\n").append("This item can be gifted."); - else body.append("\n").append("This item cannot be gifted."); - - embed.addField(header, body.toString(), false); - - purchaseMenu.addOption(item.getName(), String.valueOf(item.getId()), item.getId() + " - " + truePrice); - } - - event.reply("Here is what is currently available in the shop.").addEmbeds(embed.build()).addActionRow(purchaseMenu.build()).queue(); - - } - - @Override - public void onButtonInteraction(@NotNull ButtonInteractionEvent event) { - if (!Objects.requireNonNull(event.getButton().getId()).startsWith("purchase-")) { - return; - } - - String itemIdString = event.getButton().getId().substring("purchase-".length()); - int itemId; - try { - itemId = Integer.parseInt(itemIdString); - } catch (NumberFormatException e) { - event.reply("The item you selected could not be parsed.").queue(); - return; - } - Economy.ShopItem item = Economy.getItem(itemId); - if (item == null) { - event.reply("That item does not exist.").queue(); - return; - } - Economy.Consumer consumer = Economy.getConsumer(event.getUser().getIdLong()); - try { - consumer.purchaseItem(itemId); - } catch (Economy.Consumer.ItemNotEnabledException | Economy.Consumer.ItemOutOfStockException | - NullPointerException e) { - event.reply(e.getMessage()).queue(); - return; - } catch (Economy.Consumer.InsufficientFundsException e) { - EmbedBuilder embed = new EmbedBuilder(); - embed.setDescription("You do not have sufficient funds to purchase " + item.getName() + ".\nYour balance: " + Economy.getCurrencySymbol() + Economy.formatDouble(consumer.getBalance()) + "\nItem cost: " + Economy.getCurrencySymbol() + item.getTruePrice()); - embed.setColor(Color.RED); - event.replyEmbeds(embed.build()).setEphemeral(true).queue(); - return; - } catch (Economy.Consumer.MaxItemQualityException e) { - EmbedBuilder embed = new EmbedBuilder(); - embed.setDescription("You already have " + item.getMaxAllowed() + " of this item, which is as many as you can have at one time."); - embed.setColor(Color.RED); - event.replyEmbeds(embed.build()).setEphemeral(true).queue(); - return; - } - - Economy.saveConsumer(consumer); - - EmbedBuilder embed = new EmbedBuilder(); - embed.setTitle("Purchase successful!"); - embed.setDescription("Purchased " + item.getName() + " for " + Economy.getCurrencySymbol() + Economy.formatDouble(item.getTruePrice()) + "."); - embed.setFooter("You now have " + consumer.getQuantityOfItem(itemId) + " of this item.\nYour new balance is " + Economy.formatDouble(consumer.getBalance())); - embed.setColor(Color.GREEN); - - event.editMessageEmbeds(embed.build()).queue(); - event.getMessage().editMessageComponents().queue(); - } - - @Override - public void onStringSelectInteraction(@NotNull StringSelectInteractionEvent event) { - if (Objects.equals(event.getComponent().getId(), "purchase")) { - - String itemIdString = event.getValues().get(0); - int itemId; - try { - itemId = Integer.parseInt(itemIdString); - } catch (NumberFormatException e) { - event.reply("The item you selected could not be parsed.").setEphemeral(true).queue(); - return; - } - Economy.ShopItem item = Economy.getItem(itemId); - if (item == null) { - event.reply("That item does not exist.").setEphemeral(true).queue(); - return; - } - - Economy.Consumer consumer = Economy.getConsumer(event.getUser().getIdLong()); - - EmbedBuilder embed = new EmbedBuilder(); - embed.setTitle(item.getName()); - - StringBuilder description = new StringBuilder(item.getDescription()); - if (item.getSalePercent() == 0) description.append("\n\nThis item costs ").append(Economy.getCurrencySymbol()).append(Economy.formatDouble(item.getPrice())); - else { - description.append("\n\nThis item regularly costs ").append(Economy.getCurrencySymbol()).append(Economy.formatDouble(item.getPrice())).append(".") - .append("\nIt is currently **").append(item.getSalePercent()).append("% off**, bringing the total to **").append(Economy.getCurrencySymbol()).append(Economy.formatDouble(item.getTruePrice())).append("**."); - } - if (item.getMaxAllowed() != -1) description.append("\nYou can carry up to **").append(item.getMaxAllowed()).append("** of this item at a time."); - if (item.getQuantity() != -1) description.append("\n**").append(item.getQuantity()).append("** of this item remain."); - embed.setDescription(description); - embed.setFooter("Your current balance is " + Economy.formatDouble(consumer.getBalance()) + ". After purchasing this item, it would be " + Economy.formatDouble(consumer.getBalance() - item.getTruePrice()) + "."); - - net.dv8tion.jda.api.interactions.components.buttons.Button buyButton = Button.success("purchase-" + itemId, "Purchase for " + Economy.formatDouble(item.getTruePrice())); - - event.replyEmbeds(embed.build()).addActionRow(buyButton).queue(); - - } - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdToggleweb.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdToggleweb.java deleted file mode 100644 index 751ff5b..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdToggleweb.java +++ /dev/null @@ -1,31 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.functions.Whitelist; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import org.jetbrains.annotations.NotNull; - -public class DCmdToggleweb implements DiscordCommand { - @Override - public @NotNull SlashCommandData getCommandData() { - return Commands.slash("toggleweb", "Toggle the web whitelist system on or off.") - .setDefaultPermissions(DefaultMemberPermissions.DISABLED); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - if (!Dreamvisitor.webWhitelistEnabled) { - Whitelist.startWeb(Dreamvisitor.getPlugin().getConfig().getInt("whitelistPort")); - Dreamvisitor.webWhitelistEnabled = true; - event.reply("Web whitelist enabled.").queue(); - } else { - Whitelist.stopWeb(); - Dreamvisitor.webWhitelistEnabled = false; - event.reply("Web whitelist disabled.").queue(); - } - Dreamvisitor.getPlugin().saveConfig(); - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdUnwhitelist.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdUnwhitelist.java deleted file mode 100644 index f0eae39..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdUnwhitelist.java +++ /dev/null @@ -1,59 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import io.github.stonley890.dreamvisitor.data.PlayerUtility; -import io.github.stonley890.dreamvisitor.functions.Whitelist; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; -import net.dv8tion.jda.api.interactions.commands.OptionMapping; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import org.jetbrains.annotations.NotNull; - -import java.io.IOException; -import java.util.UUID; -import java.util.regex.Pattern; - -public class DCmdUnwhitelist implements DiscordCommand { - @Override - public @NotNull SlashCommandData getCommandData() { - return Commands.slash("unwhitelist", "Remove a user from the whitelist.") - .addOption(OptionType.STRING, "username", "The username to remove.", true) - .addOption(OptionType.BOOLEAN, "ban", "Whether to ban the user from the server.", false) - .setDefaultPermissions(DefaultMemberPermissions.DISABLED); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - OptionMapping usernameOption = event.getOption("username"); - String username; - if (usernameOption != null) username = usernameOption.getAsString(); - else { - event.reply("Option `username` could not be found.").queue(); - return; - } - - Pattern p = Pattern.compile("[^a-zA-Z0-9_-_]"); - - if (p.matcher(username).find()) { - event.reply("`" + username + "` contains illegal characters!").queue(); - return; - } - - UUID uuid = PlayerUtility.getUUIDOfUsername(username); - - if (uuid == null) { - event.reply("`" + username + "` could not be found!").queue(); - return; - } - - try { - Whitelist.remove(username, uuid); - } catch (IOException e) { - event.reply("There was a problem accessing the whitelist file.").queue(); - return; - } - - event.reply("Removed " + username + " from the whitelist.").queue(); - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdUser.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdUser.java deleted file mode 100644 index 33677c0..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdUser.java +++ /dev/null @@ -1,57 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import io.github.stonley890.dreamvisitor.data.AccountLink; -import io.github.stonley890.dreamvisitor.data.PlayerUtility; -import io.github.stonley890.dreamvisitor.functions.Messager; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.entities.User; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import org.jetbrains.annotations.NotNull; - -import java.awt.*; -import java.util.Objects; -import java.util.UUID; - -public class DCmdUser implements DiscordCommand { - @Override - public @NotNull SlashCommandData getCommandData() { - return Commands.slash("user", "Get the details of a user.") - .addOption(OptionType.USER, "user", "The user to search for.", true) - .setDefaultPermissions(DefaultMemberPermissions.DISABLED); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - Messager.debug("Command requested."); - User targetUser = Objects.requireNonNull(event.getOption("user")).getAsUser(); - Messager.debug("Target user: " + targetUser.getId()); - - // UUID from AccountLink.yml - UUID uuid; - uuid = AccountLink.getUuid(targetUser.getIdLong()); - String stringUuid = "N/A"; - String username = "N/A"; - - if (uuid != null) { - username = PlayerUtility.getUsernameOfUuid(uuid); - stringUuid = uuid.toString(); - } - if (username == null) username = "N/A"; - - // Send data - EmbedBuilder builder = new EmbedBuilder(); - - builder.setColor(Color.BLUE); - builder.setAuthor(targetUser.getName(), targetUser.getAvatarUrl(), targetUser.getAvatarUrl()); - - builder.addField("ID", targetUser.getId(), false); - builder.addField("Minecraft Username", username, false); - builder.addField("UUID", stringUuid, false); - - event.replyEmbeds(builder.build()).queue(); - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdWarn.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdWarn.java deleted file mode 100644 index 8145e33..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdWarn.java +++ /dev/null @@ -1,205 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import io.github.stonley890.dreamvisitor.data.AltFamily; -import io.github.stonley890.dreamvisitor.data.Infraction; -import net.dv8tion.jda.api.Permission; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; -import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; -import net.dv8tion.jda.api.hooks.ListenerAdapter; -import net.dv8tion.jda.api.interactions.InteractionHook; -import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; -import net.dv8tion.jda.api.interactions.commands.OptionMapping; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import net.dv8tion.jda.api.interactions.components.ActionRow; -import net.dv8tion.jda.api.interactions.components.buttons.Button; -import org.bukkit.Bukkit; -import org.jetbrains.annotations.NotNull; - -import java.io.InvalidObjectException; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -public class DCmdWarn extends ListenerAdapter implements DiscordCommand { - - public static InteractionHook lastInteraction = null; - public static Infraction lastInfraction = null; - public static boolean silent = false; - public static long memberId = 0; - - @Override - public @NotNull SlashCommandData getCommandData() { - return Commands.slash("warn", "Warn a member.") - .addOption(OptionType.USER, "member", "The member to warn", true) - .addOption(OptionType.INTEGER, "value", "How many infractions to count this as.", true) - .addOption(OptionType.BOOLEAN, "silent", "Whether to notify the member. If true, Dreamvisitor will NOT notify.", true) - .addOption(OptionType.STRING, "reason", "The reason for this warn.", false) - .setDefaultPermissions(DefaultMemberPermissions.DISABLED); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - event.deferReply().queue(DCmdWarn::updateLastInteraction); - - Member member = Objects.requireNonNull(event.getOption("member")).getAsMember(); - if (member == null) { - event.getHook().editOriginal("That member does not exist.").queue(); - return; - } - - long parent = AltFamily.getParent(member.getIdLong()); - if (parent != member.getIdLong()) { - Objects.requireNonNull(event.getGuild()).retrieveMemberById(parent).queue(parentMember -> event.getHook().editOriginal("That user is the child of " + parentMember.getAsMention() + ". Warn them instead.").queue()); - return; - } - - int value = Objects.requireNonNull(event.getOption("value")).getAsInt(); - if (value > 6) { - event.getHook().editOriginal("Slow down there. You cannot give an infraction a value higher than **3**.").queue(); - return; - } - - List infractions; - - infractions = Infraction.getInfractions(member.getIdLong()); - - int infractionCount = Infraction.getInfractionCount(infractions, false); - if (infractionCount + value > Infraction.BAN_POINT) { - event.getHook().editOriginal("You cannot add an infraction whose value exceeds the ban point of " + Infraction.BAN_POINT + - ". The highest value you can assign is " + (Infraction.BAN_POINT - infractionCount)).queue(); - return; - } - - String reason = event.getOption("reason", OptionMapping::getAsString); - if (reason == null) reason = "Unspecified."; - reason = reason.strip(); - - boolean silent = Boolean.TRUE.equals(event.getOption("silent", OptionMapping::getAsBoolean)); - - boolean hasTempban; - - hasTempban = Infraction.hasTempban(member.getIdLong()); - - if (infractionCount < Infraction.BAN_POINT) { - if (infractionCount + value == Infraction.BAN_POINT) { - - ActionRow actionRow; - if (!hasTempban) { - if (silent) actionRow = ActionRow.of( - Button.danger(Infraction.actionBan, "Ban them for two weeks."), - Button.secondary(Infraction.actionNoBan, "Don't auto-ban them.") - ); - else actionRow = ActionRow.of( - Button.danger(Infraction.actionBan, "Ban them for two weeks."), - Button.primary(Infraction.actionUserBan, "No, but mention a suspension in the message."), - Button.secondary(Infraction.actionNoBan, "No, don't mention a suspension.") - ); - } else { - if (silent) actionRow = ActionRow.of( - Button.danger(Infraction.actionBan, "Permanently ban from Minecraft."), - Button.danger(Infraction.actionAllBan, "Permanently ban from all."), - Button.secondary(Infraction.actionNoBan, "No, don't ban them.") - ); - else actionRow = ActionRow.of( - Button.danger(Infraction.actionBan, "Permanently ban from Minecraft."), - Button.danger(Infraction.actionAllBan, "Ban from all immediately (skip message)."), - Button.primary(Infraction.actionUserBan, "Mention a ban, but don't auto-ban."), - Button.secondary(Infraction.actionNoBan, "Don't mention a ban and don't auto-ban.") - ); - } - - memberId = member.getIdLong(); - - lastInfraction = new Infraction((byte) value, reason, LocalDateTime.now()); - DCmdWarn.silent = silent; - try { - event.getHook().editOriginal("This will be the user's third warn. Do you want me to also give them a ban from the Minecraft server?") - .setActionRow(actionRow.getComponents()).queue(); - } catch (Exception e) { - Bukkit.getLogger().warning("There was a problem responding to a /warn command: " + e.getMessage()); - } - } else { - - try { - Infraction.execute(new Infraction((byte) value, reason, LocalDateTime.now()), member, silent, Infraction.actionNoBan); - } catch (Exception e) { - try { - event.getHook().editOriginal("There was a problem executing this command: " + e.getMessage()).queue(); - } catch (Exception ex) { - Bukkit.getLogger().warning("There was a problem responding to a /warn command: " + ex.getMessage()); - } - return; - } - - try { - event.getHook().editOriginal("Infraction recorded.").queue(null, throwable -> Bukkit.getLogger().warning("There was a problem responding to a /warn command: " + throwable.getMessage())); - } catch (IllegalArgumentException e) { - Bukkit.getLogger().warning("There was a problem responding to a /warn command: " + e.getMessage()); - } - - } - } - } - - private static void updateLastInteraction(InteractionHook newInteraction) { - - List actionRows = new ArrayList<>(); - - if (lastInteraction != null) { - lastInteraction.retrieveOriginal().queue(original -> { - for (ActionRow actionRow : original.getActionRows()) { - actionRows.add(actionRow.asDisabled()); - } - }, null); - if (!actionRows.isEmpty()) lastInteraction.editOriginalComponents(actionRows).queue(completion -> lastInteraction = newInteraction); - } - - lastInteraction = newInteraction; - - } - - @Override - public void onButtonInteraction(@NotNull ButtonInteractionEvent event) { - - String buttonId = event.getButton().getId(); - if (buttonId == null) return; - - switch (buttonId) { - case Infraction.actionBan, Infraction.actionNoBan, Infraction.actionAllBan, Infraction.actionUserBan -> { - - try { - event.getMessage().editMessageComponents(event.getMessage().getActionRows().get(0).asDisabled()).queue(); - Infraction.execute(DCmdWarn.lastInfraction, Objects.requireNonNull(Objects.requireNonNull(event.getGuild()).retrieveMemberById(DCmdWarn.memberId).complete()), DCmdWarn.silent, buttonId); - event.reply("Infraction notice created.").queue(); - } catch (InsufficientPermissionException e) { - event.getMessage().editMessageComponents(event.getMessage().getActionRows().get(0).asDisabled()).queue(); - event.reply("Dreamvisitor does not have sufficient permissions! " + e.getMessage()).queue(); - } catch (InvalidObjectException e) { - event.getMessage().editMessageComponents(event.getMessage().getActionRows().get(0).asDisabled()).queue(); - event.reply("Something is configured incorrectly! " + e.getMessage()).queue(); - } - } - case "warn-understand" -> { - TextChannel channel = (TextChannel) event.getMessageChannel(); - event.reply("Marked as dismissed. View permission removed.").queue(); - try { - channel.upsertPermissionOverride(Objects.requireNonNull(event.getMember())).setDenied(Permission.VIEW_CHANNEL).queue(); - } catch (InsufficientPermissionException e) { - event.reply("Dreamvisitor has insufficient permissions: " + e.getMessage()).queue(); - return; - } - event.getMessage().editMessageComponents(event.getMessage().getActionRows().get(0).asDisabled()).queue(); - } - case "warn-explain" -> { - event.reply("A staff member will explain the reason for your warn. Please be patient. This could take some time.").queue(); - event.getMessage().editMessageComponents(event.getMessage().getActionRows().get(0).asDisabled()).queue(); - } - } - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdWork.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdWork.java deleted file mode 100644 index cf23b58..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DCmdWork.java +++ /dev/null @@ -1,48 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import io.github.stonley890.dreamvisitor.data.Economy; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.entities.User; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.hooks.ListenerAdapter; -import net.dv8tion.jda.api.interactions.commands.build.Commands; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import org.jetbrains.annotations.NotNull; - -import java.awt.*; -import java.time.Duration; - -public class DCmdWork extends ListenerAdapter implements DiscordCommand { - @NotNull - @Override - public SlashCommandData getCommandData() { - return Commands.slash("work", "Work for a paycheck!"); - } - - @Override - public void onCommand(@NotNull SlashCommandInteractionEvent event) { - User user = event.getUser(); - Economy.Consumer consumer = Economy.getConsumer(user.getIdLong()); - Economy.GameData gameData = consumer.getGameData(); - - EmbedBuilder embed = new EmbedBuilder(); - embed.setTitle("Work"); - - double reward; - - try { - reward = consumer.claimWork(); - } catch (Economy.Consumer.CoolDownException e) { - Duration duration = gameData.timeUntilNextWork(); - embed.setColor(Color.red).setDescription("You cannot work for " + String.valueOf(duration.toMinutes()).replaceFirst("-", "") + " minute(s)."); - event.replyEmbeds(embed.build()).setEphemeral(true).queue(); - return; - } - Economy.saveConsumer(consumer); - - embed.setDescription("You earned " + Economy.getCurrencySymbol() + reward + " by working.\nCome back in one hour to work again.") - .setFooter("Your new balance is " + Economy.formatDouble(consumer.getBalance())) - .setColor(Color.GREEN); - event.replyEmbeds(embed.build()).queue(); - } -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DiscordCommand.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DiscordCommand.java deleted file mode 100644 index 69b7cb2..0000000 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/discord/commands/DiscordCommand.java +++ /dev/null @@ -1,18 +0,0 @@ -package io.github.stonley890.dreamvisitor.discord.commands; - -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; -import org.jetbrains.annotations.NotNull; - -public interface DiscordCommand { - - @NotNull SlashCommandData getCommandData(); - - @NotNull - default String getName() { - return getCommandData().getName(); - } - - void onCommand(@NotNull SlashCommandInteractionEvent event); - -} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/AutoRestart.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/AutoRestart.java index 72a05b5..b953d1d 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/AutoRestart.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/AutoRestart.java @@ -1,6 +1,6 @@ package io.github.stonley890.dreamvisitor.functions; -import io.github.stonley890.dreamvisitor.data.PBConfigLoader; +import io.github.stonley890.dreamvisitor.data.Config; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Message; import org.jetbrains.annotations.Nullable; @@ -18,19 +18,19 @@ public static void enableAutoRestart(@Nullable Message replyMessage) { autoRestartMessage = replyMessage; localAutoRestart = true; // Update the PocketBase config - PBConfigLoader.updateConfigField("autoRestart", true); + Config.updateConfigField("autoRestart", true); } public static void disableAutoRestart() { localAutoRestart = false; autoRestartMessage = null; // Update the PocketBase config - PBConfigLoader.updateConfigField("autoRestart", false); + Config.updateConfigField("autoRestart", false); } public static boolean isAutoRestart() { // Check PocketBase config first, fall back to local state if needed - return PBConfigLoader.getBoolean("autoRestart", localAutoRestart); + return Config.getBoolean("autoRestart", localAutoRestart); } /** diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/ConsoleLogger.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/ConsoleLogger.java index 9289e2e..904d510 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/ConsoleLogger.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/ConsoleLogger.java @@ -1,20 +1,11 @@ package io.github.stonley890.dreamvisitor.functions; -import io.github.stonley890.dreamvisitor.Bot; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.appender.AbstractAppender; import org.jetbrains.annotations.NotNull; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.List; - public class ConsoleLogger extends AbstractAppender { - public static final StringBuilder messageBuilder = new StringBuilder(); - public static final List overFlowMessages = new ArrayList<>(); - public ConsoleLogger() { super("MyLogAppender", null, null, false, null); start(); @@ -34,28 +25,7 @@ public void append(@NotNull LogEvent event) { String message = builder.toString(); - // Remove Minecraft formatting codes - message = message.replaceAll("\u001B?(\\W1B)?\\[([0-9,;]+)m", ""); - message = "[" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")) + " " + event.getLevel().toString() + "] " + Bot.escapeMarkdownFormatting(message); - - // Truncate messages over 2000 characters - if (message.length() >= 2000) { - String tooLongMessage = "**This message was too long! Here is the shorter version:**\n"; - message = tooLongMessage.concat(message.substring(0, (1998 - tooLongMessage.length()))); - } - - // Pause adding strings if the new message will be >= 2000 - if (messageBuilder.toString().length() + message.length() + "\n".length() < 2000) { - - if (!messageBuilder.isEmpty()) { - messageBuilder.append("\n"); - } - messageBuilder.append(message); - - } else { - overFlowMessages.add(message); - } - + // TODO: Send message. } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/ItemBanList.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/ItemBanList.java index 497c902..081bb9d 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/ItemBanList.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/ItemBanList.java @@ -1,8 +1,9 @@ package io.github.stonley890.dreamvisitor.functions; -import io.github.stonley890.dreamvisitor.Bot; import io.github.stonley890.dreamvisitor.Dreamvisitor; import org.bukkit.Bukkit; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -11,17 +12,47 @@ import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; public class ItemBanList implements Listener { - public static final Inventory inv = Bukkit.createInventory(null, 27, "Blacklisted Items"); - public static ItemStack[] badItems; + public static final Inventory inv = Bukkit.createInventory(null, 27, "Banned Items"); + public static List badItems; + + static final File file = new File(Dreamvisitor.getPlugin().getDataFolder().getPath() + "/bannedItems.yml"); + static FileConfiguration config = YamlConfiguration.loadConfiguration(file); + + public static void init() throws IOException { + // If the file does not exist, create one + if (!file.exists()) { + Messager.debug(file.getName() + " does not exist. Creating one now..."); + try { + if (!file.createNewFile()) + throw new IOException("The existence of " + file.getName() + " cannot be verified!", null); + } catch (IOException e) { + throw new IOException("Dreamvisitor tried to create " + file.getName() + ", but it cannot be read/written! Does the server have read/write access?", e); + } + } + config = YamlConfiguration.loadConfiguration(file); + try { + badItems = (List) config.getList("items", new ArrayList<>()); + } catch (Exception e) { + Dreamvisitor.getPlugin().getLogger().warning("Unable to restore item ban list."); + badItems = new ArrayList<>(); + } + } public static void saveItems() { - Dreamvisitor plugin = Dreamvisitor.getPlugin(); - badItems = inv.getContents(); - plugin.getConfig().set("itemBlacklist", badItems); - plugin.saveConfig(); + badItems = List.of(inv.getContents()); + config.set("items", badItems); + try { + config.save(file); + } catch (IOException e) { + Dreamvisitor.getPlugin().getLogger().warning("Unable to save to " + file.getName() + "!"); + } } @EventHandler @@ -35,7 +66,7 @@ public void onInventoryClose(@NotNull InventoryCloseEvent event) { for (ItemStack content : player.getInventory().getContents()) { if (content == null || !content.isSimilar(item)) continue; player.getInventory().remove(item); - Bot.sendLog("Removed " + item.getType().name() + " (" + Objects.requireNonNull(item.getItemMeta()).getDisplayName() + ") from " + player.getName()); + Dreamvisitor.getPlugin().getLogger().info("Removed " + item.getType().name() + " (" + Objects.requireNonNull(item.getItemMeta()).getDisplayName() + ") from " + player.getName()); } } } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Radio.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Radio.java index bfb33a2..bdf278c 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Radio.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Radio.java @@ -1,6 +1,5 @@ package io.github.stonley890.dreamvisitor.functions; -import io.github.stonley890.dreamvisitor.Bot; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.entity.Player; @@ -31,7 +30,6 @@ public static void buildMessage(String message, @NotNull String name, @NotNull S } } - Bot.sendLog(ChatColor.stripColor(finalMessage)); } private static @NotNull String getString(String message, @NotNull String name, @NotNull String command) { diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Whitelist.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Whitelist.java index 21a1af3..d6b1c85 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Whitelist.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Whitelist.java @@ -1,14 +1,9 @@ package io.github.stonley890.dreamvisitor.functions; -import io.github.stonley890.dreamvisitor.Bot; import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.data.PlayerUtility; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.entities.User; -import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; import net.dv8tion.jda.api.hooks.ListenerAdapter; -import net.dv8tion.jda.api.interactions.components.buttons.Button; import org.bukkit.BanList; import org.bukkit.Bukkit; import org.bukkit.profile.PlayerProfile; @@ -185,7 +180,6 @@ private static boolean processUsername(@NotNull String username) throws IOExcept Messager.debug("Already whitelisted."); Messager.debug("Resolved."); - return true; } else { Messager.debug("Player is not whitelisted."); @@ -194,44 +188,12 @@ private static boolean processUsername(@NotNull String username) throws IOExcept // success message Messager.debug("Success."); - report(username, uuid, null); - - return true; } + return true; } return false; } - /** - * Report a whitelist to the system log channel. - * @param username the username that is being whitelisted. - * @param source the {@link User} (or {@code null} if by web) that caused this whitelist. - */ - public static void report(String username, UUID uuid, User source) { - - String sourceName = "web whitelist"; - if (source != null) sourceName = source.getName(); - - TextChannel systemChannel = Bot.getGameLogChannel().getGuild().getSystemChannel(); - if (systemChannel != null) { - EmbedBuilder logEmbed = getEmbedBuilder(username, source, sourceName); - - Button ban = Button.danger("ban-" + uuid, "Ban"); - Button unwhitelist = Button.secondary("unwhitelist-" + uuid, "Unwhitelist"); - systemChannel.sendMessageEmbeds(logEmbed.build()).setActionRow(ban, unwhitelist).queue(); - } - } - - @NotNull - private static EmbedBuilder getEmbedBuilder(String username, User source, String sourceName) { - EmbedBuilder logEmbed = new EmbedBuilder(); - logEmbed.setTitle("Whitelisted " + username + " from " + sourceName); - - if (source != null) logEmbed.setDescription(source.getAsMention() + " added " + username + " to the whitelist with Dreamvisitor. Use the buttons below to undo this action or `/link ` to link this user to a different member."); - else logEmbed.setDescription("Added " + username + " to the whitelist via the web whitelist. Use the buttons below to undo this action or `/link ` to link this user to a Discord member."); - return logEmbed; - } - @Override public void onButtonInteraction(@NotNull ButtonInteractionEvent event) { if (Objects.requireNonNull(event.getButton().getId()).startsWith("unwhitelist")) { diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenEntityDamage.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenEntityDamage.java index e877cf6..ebcfda5 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenEntityDamage.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenEntityDamage.java @@ -1,5 +1,6 @@ package io.github.stonley890.dreamvisitor.listeners; +import io.github.stonley890.dreamvisitor.data.Config; import org.bukkit.entity.EntityType; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -16,7 +17,7 @@ public class ListenEntityDamage implements Listener { public void onEntityDamageEvent(@NotNull EntityDamageByEntityEvent event) { // If PvP is disabled and the damage type is player, cancel the event - if ((event.getDamager().getType() == EntityType.PLAYER && event.getEntity().getType() == EntityType.PLAYER) && plugin.getConfig().getBoolean("disablepvp")) { + if ((event.getDamager().getType() == EntityType.PLAYER && event.getEntity().getType() == EntityType.PLAYER) && Config.getBoolean("disable_pvp", false)) { event.setCancelled(true); } } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerChat.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerChat.java index c58819c..e1ae360 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerChat.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerChat.java @@ -2,7 +2,6 @@ import java.io.File; import java.io.IOException; -import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; @@ -11,7 +10,6 @@ import io.github.stonley890.dreamvisitor.data.PlayerUtility; import io.github.stonley890.dreamvisitor.functions.Chatback; import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; -import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.ComponentBuilder; import net.md_5.bungee.api.chat.HoverEvent; import net.md_5.bungee.api.chat.TextComponent; @@ -25,7 +23,6 @@ import org.bukkit.event.Listener; import org.bukkit.event.player.AsyncPlayerChatEvent; -import io.github.stonley890.dreamvisitor.Bot; import io.github.stonley890.dreamvisitor.Dreamvisitor; import org.jetbrains.annotations.NotNull; @@ -61,16 +58,14 @@ public void onPlayerChatEvent(@NotNull AsyncPlayerChatEvent event) { return; } } - + + // TODO: See below. /* Send chat messages to Discord IF chat is not paused AND the player is not an operator OR the player is an operator, send message */ - String chatMessage = "**" + Bot.escapeMarkdownFormatting(event.getPlayer().getName()) + "**: " + event.getMessage(); - - if (!Dreamvisitor.chatPaused || event.isCancelled()) { if (event.isCancelled()) return; @@ -86,19 +81,20 @@ public void onPlayerChatEvent(@NotNull AsyncPlayerChatEvent event) { replyUser.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(replyMessage.authorUsername))); replyNotice.append(replyUser); - Bot.getGameChatChannel().sendMessage(chatMessage).setMessageReference(replyMessage.messageId).failOnInvalidReply(false).queue(); + // TODO: Send message with reply +// Bot.getGameChatChannel().sendMessage(chatMessage).setMessageReference(replyMessage.messageId).failOnInvalidReply(false).queue(); Bukkit.spigot().broadcast(replyNotice.create()); Chatback.nextChatback.remove(event.getPlayer()); } else { - Bot.getGameChatChannel().sendMessage(chatMessage).queue(); + // TODO: Send message +// Bot.getGameChatChannel().sendMessage(chatMessage).queue(); } } catch (InsufficientPermissionException e) { Bukkit.getLogger().warning("Dreamvisitor does not have sufficient permissions to send messages in game chat channel: " + e.getMessage()); } - Bot.sendLog(chatMessage); } else { @@ -131,22 +127,23 @@ public void onPlayerChatEvent(@NotNull AsyncPlayerChatEvent event) { replyNotice.append(replyUser); Bukkit.spigot().broadcast(replyNotice.create()); - Bot.getGameChatChannel().sendMessage(chatMessage).setMessageReference(replyMessage.messageId).failOnInvalidReply(false).queue(); + // TODO: Send message as reply +// Bot.getGameChatChannel().sendMessage(chatMessage).setMessageReference(replyMessage.messageId).failOnInvalidReply(false).queue(); Chatback.nextChatback.remove(event.getPlayer()); } else { - Bot.getGameChatChannel().sendMessage(chatMessage).queue(); + // TODO: Send message +// Bot.getGameChatChannel().sendMessage(chatMessage).queue(); } } catch (InsufficientPermissionException e) { Bukkit.getLogger().warning("Dreamvisitor does not have sufficient permissions to send messages in game chat channel: " + e.getMessage()); } - Bot.sendLog(chatMessage); } else { event.setCancelled(true); event.getPlayer().sendMessage(ChatColor.RED + "Chat is currently paused."); - Bot.sendLog("Blocked: " + chatMessage); + Dreamvisitor.getPlugin().getLogger().info("Message from " + event.getPlayer().getName() + " was blocked: " + event.getMessage()); } } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerCmdPreprocess.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerCmdPreprocess.java index 717f234..5e78c83 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerCmdPreprocess.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerCmdPreprocess.java @@ -7,7 +7,6 @@ import io.github.stonley890.dreamvisitor.data.PlayerUtility; import io.github.stonley890.dreamvisitor.functions.Mail; import io.github.stonley890.dreamvisitor.functions.Messager; -import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; import org.bukkit.Bukkit; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.FileConfiguration; @@ -17,7 +16,6 @@ import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerCommandPreprocessEvent; -import io.github.stonley890.dreamvisitor.Bot; import io.github.stonley890.dreamvisitor.Dreamvisitor; import net.md_5.bungee.api.ChatColor; import org.jetbrains.annotations.NotNull; @@ -71,19 +69,20 @@ public void onPlayerCommandPreprocess(@NotNull PlayerCommandPreprocessEvent even // If list contains player, allow if (bypassedPlayers.contains(player.getUniqueId().toString()) || player.isOp()) { - // Remove command - int spaceIndex = cmd.indexOf(' '); - if (spaceIndex == -1) return; - String action = cmd.substring(spaceIndex + 1); - String message = "**[" + Bot.escapeMarkdownFormatting(ChatColor.stripColor(player.getDisplayName())) + " **(" + player.getName() - + ")**]** " + ChatColor.stripColor(action); - // Send message - try { - Bot.getGameChatChannel().sendMessage(message).queue(); - } catch (InsufficientPermissionException e) { - Bukkit.getLogger().warning("Dreamvisitor does not have sufficient permissions to send messages in game chat channel: " + e.getMessage()); - } - Bot.sendLog(message); + // TODO: Send action to DVHub +// // Remove command +// int spaceIndex = cmd.indexOf(' '); +// if (spaceIndex == -1) return; +// String action = cmd.substring(spaceIndex + 1); +// String message = "**[" + Bot.escapeMarkdownFormatting(ChatColor.stripColor(player.getDisplayName())) + " **(" + player.getName() +// + ")**]** " + ChatColor.stripColor(action); +// // Send message +// try { +// Bot.getGameChatChannel().sendMessage(message).queue(); +// } catch (InsufficientPermissionException e) { +// Bukkit.getLogger().warning("Dreamvisitor does not have sufficient permissions to send messages in game chat channel: " + e.getMessage()); +// } +// Bot.sendLog(message); } // If list does not contain player, stop the command else { event.setCancelled(true); @@ -92,28 +91,24 @@ public void onPlayerCommandPreprocess(@NotNull PlayerCommandPreprocessEvent even } // If chat is not paused, allow else { + // TODO: Send action to DVHub + // Remove command - int spaceIndex = cmd.indexOf(' '); - if (spaceIndex == -1) return; - String action = cmd.substring(spaceIndex + 1); - String message = "**[" + Bot.escapeMarkdownFormatting(ChatColor.stripColor(player.getDisplayName())) + " **(" + player.getName() - + ")**]** " + ChatColor.stripColor(action); - // Send message - try { - Bot.getGameChatChannel().sendMessage(message).queue(); - } catch (InsufficientPermissionException e) { - Bukkit.getLogger().warning("Dreamvisitor does not have sufficient permissions to send messages in game chat channel: " + e.getMessage()); - } - Bot.sendLog(message); +// int spaceIndex = cmd.indexOf(' '); +// if (spaceIndex == -1) return; +// String action = cmd.substring(spaceIndex + 1); +// String message = "**[" + Bot.escapeMarkdownFormatting(ChatColor.stripColor(player.getDisplayName())) + " **(" + player.getName() +// + ")**]** " + ChatColor.stripColor(action); +// // Send message +// try { +// Bot.getGameChatChannel().sendMessage(message).queue(); +// } catch (InsufficientPermissionException e) { +// Bukkit.getLogger().warning("Dreamvisitor does not have sufficient permissions to send messages in game chat channel: " + e.getMessage()); +// } +// Bot.sendLog(message); } } else { - for (String string : msgAliases) { - if (cmd.startsWith(string)) { - String message = "**" + Bot.escapeMarkdownFormatting(player.getName()) + "** sent command: `" + cmd + "`"; - Bot.sendLog(message); - return; - } - } + // Cancel if command is a teleportation command to a sandboxed player. for (String tpAlias : tpAliases) { if (cmd.startsWith(tpAlias)) { if (Mail.isPLayerDeliverer(player)) Mail.cancel(player); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerDeath.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerDeath.java index d1f3c57..52327b7 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerDeath.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerDeath.java @@ -1,15 +1,11 @@ package io.github.stonley890.dreamvisitor.listeners; import io.github.stonley890.dreamvisitor.functions.Mail; -import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; -import net.md_5.bungee.api.ChatColor; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.entity.PlayerDeathEvent; -import io.github.stonley890.dreamvisitor.Bot; import org.jetbrains.annotations.NotNull; public class ListenPlayerDeath implements Listener { @@ -22,14 +18,14 @@ public void onPlayerDeathEvent(@NotNull PlayerDeathEvent event) { if (event.getDeathMessage() == null) return; - // Send death messages - String chatMessage = "**" + Bot.escapeMarkdownFormatting(ChatColor.stripColor(event.getDeathMessage())) + "**"; - try { - Bot.getGameChatChannel().sendMessage(chatMessage).queue(); - } catch (InsufficientPermissionException e) { - Bukkit.getLogger().warning("Dreamvisitor does not have sufficient permissions to send messages in game chat channel: " + e.getMessage()); - } - Bot.sendLog(chatMessage); + // TODO: Send death messages +// String chatMessage = "**" + Bot.escapeMarkdownFormatting(ChatColor.stripColor(event.getDeathMessage())) + "**"; +// try { +// Bot.getGameChatChannel().sendMessage(chatMessage).queue(); +// } catch (InsufficientPermissionException e) { +// Bukkit.getLogger().warning("Dreamvisitor does not have sufficient permissions to send messages in game chat channel: " + e.getMessage()); +// } +// Bot.sendLog(chatMessage); } } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerJoin.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerJoin.java index 7f768c9..88a12ce 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerJoin.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerJoin.java @@ -1,6 +1,5 @@ package io.github.stonley890.dreamvisitor.listeners; -import io.github.stonley890.dreamvisitor.Bot; import io.github.stonley890.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.data.PlayerMemory; import io.github.stonley890.dreamvisitor.data.PlayerTribe; @@ -8,7 +7,6 @@ import io.github.stonley890.dreamvisitor.data.Tribe; import io.github.stonley890.dreamvisitor.functions.Messager; import io.github.stonley890.dreamvisitor.functions.Sandbox; -import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; import net.luckperms.api.model.user.User; import net.md_5.bungee.api.ChatColor; import org.bukkit.Bukkit; @@ -50,14 +48,14 @@ public void onPlayerJoinEvent(@NotNull PlayerJoinEvent event) { player.setAllowFlight(true); } - // Send join messages - String chatMessage = "**" + Bot.escapeMarkdownFormatting(ChatColor.stripColor(player.getName())) + " joined the game**"; - try { - Bot.getGameChatChannel().sendMessage(chatMessage).queue(); - } catch (InsufficientPermissionException e) { - Bukkit.getLogger().warning("Dreamvisitor does not have sufficient permissions to send messages in game chat channel: " + e.getMessage()); - } - Bot.sendLog(chatMessage); + // TODO: Send join messages +// String chatMessage = "**" + Bot.escapeMarkdownFormatting(ChatColor.stripColor(player.getName())) + " joined the game**"; +// try { +// Bot.getGameChatChannel().sendMessage(chatMessage).queue(); +// } catch (InsufficientPermissionException e) { +// Bukkit.getLogger().warning("Dreamvisitor does not have sufficient permissions to send messages in game chat channel: " + e.getMessage()); +// } +// Bot.sendLog(chatMessage); PlayerMemory memory = PlayerUtility.getPlayerMemory(player.getUniqueId()); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerLogin.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerLogin.java index a467ad5..5c1e3bb 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerLogin.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerLogin.java @@ -4,9 +4,9 @@ import java.io.IOException; import java.util.List; +import io.github.stonley890.dreamvisitor.data.Config; import io.github.stonley890.dreamvisitor.functions.Messager; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; @@ -57,7 +57,7 @@ public void onPlayerLoginEvent(@NotNull PlayerLoginEvent event) { // Kick for server full event.disallow(Result.KICK_FULL, "The server is full. The current player limit is " + Dreamvisitor.playerLimit); - } else if (plugin.getConfig().getBoolean("softwhitelist")) { + } else if (Config.getBoolean("softwhitelist", false)) { // Soft whitelist is enabled allowIfSoftWhitelist(player, event); @@ -72,7 +72,7 @@ public void onPlayerLoginEvent(@NotNull PlayerLoginEvent event) { // Player limit is not overridden // If soft whitelist is on - if (plugin.getConfig().getBoolean("softwhitelist")) { + if (Config.getBoolean("softwhitelist", false)) { // Soft whitelist is enabled Bukkit.getLogger().info("Soft whitelist is enabled"); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerMoveEvent.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerMoveEvent.java index 624a8b0..3535d0d 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerMoveEvent.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerMoveEvent.java @@ -1,8 +1,7 @@ package io.github.stonley890.dreamvisitor.listeners; -import io.github.stonley890.dreamvisitor.Dreamvisitor; +import io.github.stonley890.dreamvisitor.data.Config; import io.github.stonley890.dreamvisitor.functions.Flight; -import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -57,8 +56,8 @@ private static double getEnergyToRemove(@NotNull PlayerMoveEvent event) { double distanceY = toY - fromY; if (distanceY < 0) distanceY = 0; - double flightEnergyDepletionXYMultiplier = Dreamvisitor.getPlugin().getConfig().getDouble("flightEnergyDepletionXYMultiplier"); - double flightEnergyDepletionYMultiplier = Dreamvisitor.getPlugin().getConfig().getDouble("flightEnergyDepletionYMultiplier"); + double flightEnergyDepletionXYMultiplier = Config.getDouble("flightEnergyDepletionXYMultiplier", 1.0); + double flightEnergyDepletionYMultiplier = Config.getDouble("flightEnergyDepletionYMultiplier", 2.00); energyToRemove = distance2d * flightEnergyDepletionXYMultiplier + distanceY * flightEnergyDepletionYMultiplier; return energyToRemove; } diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerQuit.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerQuit.java index 3659181..a9ff733 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerQuit.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerQuit.java @@ -4,14 +4,12 @@ import io.github.stonley890.dreamvisitor.data.PlayerMemory; import io.github.stonley890.dreamvisitor.functions.Messager; import io.github.stonley890.dreamvisitor.functions.Sandbox; -import net.md_5.bungee.api.ChatColor; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerQuitEvent; -import io.github.stonley890.dreamvisitor.Bot; import io.github.stonley890.dreamvisitor.data.PlayerUtility; import org.jetbrains.annotations.NotNull; @@ -25,10 +23,10 @@ public void onPlayerQuitEvent(@NotNull PlayerQuitEvent event) { Player player = event.getPlayer(); - // Send player quits to Discord - String chatMessage = "**" + Bot.escapeMarkdownFormatting(ChatColor.stripColor(player.getName())) + " left the game**"; - Bot.getGameChatChannel().sendMessage(chatMessage).queue(); - Bot.sendLog(chatMessage); + // TODO: Send player quits to Discord +// String chatMessage = "**" + Bot.escapeMarkdownFormatting(ChatColor.stripColor(player.getName())) + " left the game**"; +// Bot.getGameChatChannel().sendMessage(chatMessage).queue(); +// Bot.sendLog(chatMessage); PlayerMemory memory = PlayerUtility.getPlayerMemory(event.getPlayer().getUniqueId()); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/PocketBase.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/PocketBase.java index 2fffdee..505c433 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/PocketBase.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/PocketBase.java @@ -30,7 +30,7 @@ public class PocketBase { * @param baseUrl The base URL of the PocketBase instance * @param token The admin/user auth token */ - public PocketBase(String baseUrl, String token) { + public PocketBase(@NotNull String baseUrl, String token) { this.baseUrl = baseUrl.endsWith("/") ? baseUrl : baseUrl + "/"; this.token = token; this.gson = new Gson(); @@ -46,9 +46,10 @@ public PocketBase(String baseUrl, String token) { * * @return A preconfigured PocketBase instance */ - public static PocketBase fromConfig(Map config) { - String baseUrl = (String) config.get("pocketbase-url"); - String token = (String) config.get("pocketbase-token"); + @NotNull + public static PocketBase fromConfig(@NotNull Map config) { + String baseUrl = (String) config.get("pocketbaseUrl"); + String token = (String) config.get("pocketbaseToken"); return new PocketBase(baseUrl, token); } @@ -59,6 +60,7 @@ public static PocketBase fromConfig(Map config) { * @param queryParams Query parameters * @return The complete URL */ + @NotNull private HttpUrl buildUrl(String endpoint, @Nullable Map queryParams) { HttpUrl.Builder urlBuilder = HttpUrl.parse(this.baseUrl + endpoint).newBuilder(); @@ -81,8 +83,9 @@ private HttpUrl buildUrl(String endpoint, @Nullable Map queryPar * @return Response string * @throws IOException If the request fails */ - private String executeRequest(String method, String endpoint, @Nullable RequestBody body, - @Nullable Map queryParams) throws IOException { + @NotNull + private String executeRequest(@NotNull String method, String endpoint, @Nullable RequestBody body, + @Nullable Map queryParams) throws IOException { HttpUrl url = buildUrl(endpoint, queryParams); Request.Builder requestBuilder = new Request.Builder() @@ -366,7 +369,7 @@ public void deleteRecord(String collectionIdOrName, String recordId) throws IOEx * @param files Map of field names to files * @return Multipart request body */ - public RequestBody createMultipartBody(Map fields, Map files) { + public RequestBody createMultipartBody(@NotNull Map fields, Map files) { MultipartBody.Builder builder = new MultipartBody.Builder() .setType(MultipartBody.FORM); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/ConfigKey.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/ConfigKey.java new file mode 100644 index 0000000..d8cdd24 --- /dev/null +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/ConfigKey.java @@ -0,0 +1,52 @@ +package io.github.stonley890.dreamvisitor.util; + +import org.bukkit.Location; + +public enum ConfigKey { + + DEBUG("debug", true, Boolean.class), // This is intentionally set to true because these default should typically only be used when no database is connected. + AUTO_RESTART("auto_restart", false, Boolean.class), + PAUSE_CHAT("pause_chat", false, Boolean.class), + SOFT_WHITELIST("soft_whitelist", false, Boolean.class), + DISABLE_PVP("disable_pvp", false, Boolean.class), + PLAYER_LIMIT("player_limit", -1, Integer.class), + RESOURCE_PACK_REPO("resource_pack_repo", "WOFTNW/Dragonspeak", String.class), + HUB_LOCATION("hub_location", null, Location.class), + LOG_CONSOLE("log_console", false, Boolean.class), + ENABLE_LOG_CONSOLE_COMMANDS("enable_log_console_commands", false, Boolean.class), // Technically this only need to be read by DreamvisitorHub, but it's a good idea to have it here for redundancy. + MAIL_DELIVERY_LOCATION_SELECTION_DISTANCE_WEIGHT_MULTIPLIER("mail_delivery_location_selection_distance_weight_multiplier", 1.00, Double.class), + MAIL_DISTANCE_TO_REWARD_MULTIPLIER("mail_distance_to_reward_multiplier", 0.05, Double.class), + FLIGHT_ENERGY_CAPACITY("flight_energy_capacity", 400, Integer.class), + FLIGHT_REGENERATION_POINT("flight_regeneration_point", 200.00, Double.class), + FLIGHT_ENERGY_REGENERATION("flight_energy_regeneration", 1.00, Double.class), + FLIGHT_ENERGY_DEPLETION_X_Z_MULTIPLIER("flight_energy_destruction_x_z_multiplier", 1.00, Double.class), + FLIGHT_ENERGY_DEPLETION_Y_MULTIPLIER("flight_energy_destruction_y_multiplier", 2.00, Double.class), + DAYS_UNTIL_INACTIVE_TAX("days_until_inactive_tax", 60, Integer.class), + INACTIVE_TAX_PERCENT("inactive_tax_percent", 0.1, Double.class), + INACTIVE_DAY_FREQUENCY("inactive_day_frequency", 7, Integer.class), + INACTIVE_TAX_STOP("inactive_tax_stop", 50000, Integer.class), + NO_WITHER_NOTICE("no_wither_notice", "Withers cannot be spawned here. You can only spawn Withers in the Wither chamber.", String.class); + + private final String key; + private final Object defaultValue; + private final Class type; + + ConfigKey(String key, Object defaultValue, Class type) { + this.key = key; + this.defaultValue = defaultValue; + this.type = type; + } + + public String getKey() { + return key; + } + + public Object getDefaultValue() { + return defaultValue; + } + + public Class getType() { + return type; + } + +} diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/ConfigLoader.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/ConfigLoader.java index 938f175..18e4d78 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/ConfigLoader.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/ConfigLoader.java @@ -1,4 +1,5 @@ package io.github.stonley890.dreamvisitor.util; +import org.jetbrains.annotations.NotNull; import org.yaml.snakeyaml.Yaml; import java.io.File; @@ -27,6 +28,7 @@ private ConfigLoader() { * @param filePath path to the YAML file * @return Map containing the configuration, or empty map if loading fails */ + @NotNull public static Map loadConfig(String filePath) { try { File configFile = new File(filePath); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/PBConfigLoader.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/PBConfigLoader.java index 9c8fcf0..1c8e01c 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/PBConfigLoader.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/PBConfigLoader.java @@ -7,6 +7,8 @@ import java.util.logging.Logger; import io.github.stonley890.dreamvisitor.pb.PocketBase; +import org.jetbrains.annotations.NotNull; + /** * Utility class for loading configuration from PocketBase */ @@ -92,7 +94,7 @@ private static void mapFieldNames(Map config) { * @param config The configuration map * @param fieldName The field name to check */ - private static void ensureChannelIdFormat(Map config, String fieldName) { + private static void ensureChannelIdFormat(@NotNull Map config, String fieldName) { if (config.containsKey(fieldName)) { Object value = config.get(fieldName); if (value instanceof Number) { @@ -109,7 +111,7 @@ private static void ensureChannelIdFormat(Map config, String fie * @param oldName The old field name * @param newName The new field name */ - private static void renameField(Map config, String oldName, String newName) { + private static void renameField(@NotNull Map config, String oldName, String newName) { if (config.containsKey(oldName)) { config.put(newName, config.get(oldName)); config.remove(oldName); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/UUIDFromater.java b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/UUIDFromater.java index a054692..04d6b39 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/UUIDFromater.java +++ b/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/UUIDFromater.java @@ -1,4 +1,8 @@ package io.github.stonley890.dreamvisitor.util; + +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + public class UUIDFromater { /** * Adds the hyphens back into a String UUID. @@ -6,7 +10,9 @@ public class UUIDFromater { * @param uuid the UUID as a {@link String} without hyphens. * @return a UUID as a string with hyphens. */ - public static String formatUuid(String uuid) { + @NotNull + @Contract(pure = true) + public static String formatUuid(@NotNull String uuid) { return uuid.replaceFirst( "(\\p{XDigit}{8})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}+)", diff --git a/dreamvisitor/src/main/resources/config.yml b/dreamvisitor/src/main/resources/config.yml index c254437..76643db 100644 --- a/dreamvisitor/src/main/resources/config.yml +++ b/dreamvisitor/src/main/resources/config.yml @@ -1,4 +1,4 @@ pocketbaseUrl: "http://127.0.0.1:8090/" -pocketbaseConfigId: "" -pocketbaseToken: "" +pocketbaseConfigId: "record_id_here" +pocketbaseToken: "your_admin_token_here" pocketbaseUseRealtime: true \ No newline at end of file From ab3d2dd717096756f236c55bc17092db30d317e6 Mon Sep 17 00:00:00 2001 From: Bog Date: Sun, 29 Jun 2025 16:50:32 -0700 Subject: [PATCH 11/39] Move to group ID org.woftnw and version to 3.0.0 --- dreamvisitor/pom.xml | 4 ++-- .../woftnw}/dreamvisitor/Dreamvisitor.java | 14 ++++++++------ .../dreamvisitor/commands/CmdAdminRadio.java | 6 +++--- .../dreamvisitor/commands/CmdChatback.java | 4 ++-- .../dreamvisitor/commands/CmdDiscord.java | 9 ++++----- .../dreamvisitor/commands/CmdDreamvisitor.java | 11 +++++------ .../woftnw}/dreamvisitor/commands/CmdDvset.java | 8 ++++---- .../woftnw}/dreamvisitor/commands/CmdHub.java | 8 ++++---- .../dreamvisitor/commands/CmdInvSwap.java | 7 +++---- .../dreamvisitor/commands/CmdItemBanList.java | 7 ++----- .../dreamvisitor/commands/CmdMoonglobe.java | 6 +++--- .../woftnw}/dreamvisitor/commands/CmdPanic.java | 6 +++--- .../woftnw}/dreamvisitor/commands/CmdParcel.java | 8 ++++---- .../dreamvisitor/commands/CmdPauseBypass.java | 10 ++++------ .../dreamvisitor/commands/CmdPausechat.java | 4 ++-- .../dreamvisitor/commands/CmdPlayerlimit.java | 6 +++--- .../woftnw}/dreamvisitor/commands/CmdRadio.java | 4 ++-- .../dreamvisitor/commands/CmdSandbox.java | 11 +++++------ .../dreamvisitor/commands/CmdSchedule.java | 9 ++++----- .../commands/CmdScheduleRestart.java | 7 +++---- .../dreamvisitor/commands/CmdSetback.java | 6 ++---- .../woftnw}/dreamvisitor/commands/CmdSethub.java | 8 +++----- .../dreamvisitor/commands/CmdSetmotd.java | 6 +++--- .../dreamvisitor/commands/CmdSoftwhitelist.java | 11 +++++------ .../dreamvisitor/commands/CmdSynctime.java | 5 ++--- .../dreamvisitor/commands/CmdTagRadio.java | 4 ++-- .../dreamvisitor/commands/CmdTribeUpdate.java | 8 +++++--- .../woftnw}/dreamvisitor/commands/CmdUnwax.java | 5 ++--- .../woftnw}/dreamvisitor/commands/CmdUser.java | 4 ++-- .../dreamvisitor/commands/CmdVelocity.java | 5 ++--- .../woftnw}/dreamvisitor/commands/CmdZoop.java | 8 ++++---- .../dreamvisitor/commands/CommandUtils.java | 4 ++-- .../woftnw}/dreamvisitor/commands/DVCommand.java | 2 +- .../woftnw}/dreamvisitor/data/BadWords.java | 6 +++--- .../woftnw}/dreamvisitor/data/Config.java | 13 ++++++------- .../woftnw}/dreamvisitor/data/PlayerMemory.java | 2 +- .../woftnw}/dreamvisitor/data/PlayerTribe.java | 6 +++--- .../woftnw}/dreamvisitor/data/PlayerUtility.java | 4 ++-- .../dreamvisitor/data/RealtimeConfigUpdater.java | 6 +++--- .../woftnw}/dreamvisitor/data/Tribe.java | 2 +- .../woftnw}/dreamvisitor/data/TribeUtil.java | 2 +- .../data/repository/AltRepository.java | 2 +- .../data/repository/InfractionRepository.java | 2 +- .../data/repository/ItemRepository.java | 4 ++-- .../data/repository/PocketBaseAltRepository.java | 4 ++-- .../PocketBaseInfractionRepository.java | 6 +++--- .../repository/PocketBaseItemRepository.java | 8 +++----- .../PocketBaseUserInventoryRepository.java | 12 +++++------- .../repository/PocketBaseUserRepository.java | 9 ++++----- .../data/repository/UserInventoryRepository.java | 4 ++-- .../data/repository/UserRepository.java | 4 ++-- .../woftnw}/dreamvisitor/data/type/DVUser.java | 2 +- .../woftnw}/dreamvisitor/data/type/Item.java | 2 +- .../dreamvisitor/data/type/UserInventory.java | 2 +- .../dreamvisitor/functions/AutoRestart.java | 4 ++-- .../woftnw}/dreamvisitor/functions/Chatback.java | 2 +- .../dreamvisitor/functions/CommandScheduler.java | 4 ++-- .../dreamvisitor/functions/ConsoleLogger.java | 2 +- .../woftnw}/dreamvisitor/functions/Flight.java | 8 ++++---- .../dreamvisitor/functions/InactivityTax.java | 8 +++----- .../woftnw}/dreamvisitor/functions/InvSwap.java | 6 +++--- .../dreamvisitor/functions/ItemBanList.java | 4 ++-- .../woftnw}/dreamvisitor/functions/Mail.java | 8 ++++---- .../woftnw}/dreamvisitor/functions/Messager.java | 4 ++-- .../dreamvisitor/functions/Moonglobe.java | 2 +- .../dreamvisitor/functions/PauseBypass.java | 4 ++-- .../woftnw}/dreamvisitor/functions/Radio.java | 2 +- .../woftnw}/dreamvisitor/functions/Sandbox.java | 7 +++---- .../dreamvisitor/functions/SoftWhitelist.java | 4 ++-- .../dreamvisitor/functions/Whitelist.java | 6 +++--- .../functions/worldguard/DragonFlightFlag.java | 6 +++--- .../functions/worldguard/WitherFlag.java | 4 ++-- .../listeners/ListenCreatureSpawn.java | 4 ++-- .../listeners/ListenEntityDamage.java | 6 +++--- .../listeners/ListenEntityToggleGlideEvent.java | 2 +- .../listeners/ListenPlayerChangedWorld.java | 4 ++-- .../dreamvisitor/listeners/ListenPlayerChat.java | 12 ++++++------ .../listeners/ListenPlayerCmdPreprocess.java | 10 +++++----- .../listeners/ListenPlayerDeath.java | 4 ++-- .../listeners/ListenPlayerGameModeChange.java | 8 ++++---- .../dreamvisitor/listeners/ListenPlayerJoin.java | 16 ++++++++-------- .../listeners/ListenPlayerLogin.java | 8 ++++---- .../listeners/ListenPlayerMoveEvent.java | 6 +++--- .../dreamvisitor/listeners/ListenPlayerQuit.java | 12 ++++++------ .../listeners/ListenPlayerRespawn.java | 6 +++--- .../listeners/ListenPlayerToggleFlightEvent.java | 4 ++-- .../dreamvisitor/listeners/ListenServerPing.java | 4 ++-- .../listeners/ListenSignChangeEvent.java | 2 +- .../dreamvisitor/listeners/ListenTimeSkip.java | 4 ++-- .../woftnw}/dreamvisitor/pb/PocketBase.java | 5 +---- .../woftnw}/dreamvisitor/pb/PocketBaseUtils.java | 2 +- .../woftnw}/dreamvisitor/pb/README.md | 0 .../woftnw}/dreamvisitor/util/ConfigKey.java | 2 +- .../woftnw}/dreamvisitor/util/ConfigLoader.java | 2 +- .../dreamvisitor/util/PBConfigLoader.java | 4 ++-- .../woftnw}/dreamvisitor/util/UUIDFromater.java | 2 +- dreamvisitor/src/main/resources/plugin.yml | 2 +- 97 files changed, 258 insertions(+), 285 deletions(-) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/Dreamvisitor.java (97%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdAdminRadio.java (90%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdChatback.java (93%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdDiscord.java (80%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdDreamvisitor.java (99%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdDvset.java (98%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdHub.java (97%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdInvSwap.java (82%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdItemBanList.java (82%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdMoonglobe.java (97%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdPanic.java (92%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdParcel.java (98%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdPauseBypass.java (89%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdPausechat.java (94%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdPlayerlimit.java (92%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdRadio.java (93%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdSandbox.java (92%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdSchedule.java (98%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdScheduleRestart.java (81%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdSetback.java (94%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdSethub.java (92%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdSetmotd.java (88%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdSoftwhitelist.java (92%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdSynctime.java (90%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdTagRadio.java (94%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdTribeUpdate.java (90%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdUnwax.java (90%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdUser.java (94%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdVelocity.java (92%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CmdZoop.java (90%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/CommandUtils.java (90%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/commands/DVCommand.java (77%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/data/BadWords.java (86%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/data/Config.java (93%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/data/PlayerMemory.java (98%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/data/PlayerTribe.java (97%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/data/PlayerUtility.java (98%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/data/RealtimeConfigUpdater.java (97%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/data/Tribe.java (97%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/data/TribeUtil.java (96%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/data/repository/AltRepository.java (96%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/data/repository/InfractionRepository.java (96%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/data/repository/ItemRepository.java (91%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/data/repository/PocketBaseAltRepository.java (98%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/data/repository/PocketBaseInfractionRepository.java (98%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/data/repository/PocketBaseItemRepository.java (98%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/data/repository/PocketBaseUserInventoryRepository.java (97%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/data/repository/PocketBaseUserRepository.java (97%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/data/repository/UserInventoryRepository.java (94%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/data/repository/UserRepository.java (93%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/data/type/DVUser.java (98%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/data/type/Item.java (98%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/data/type/UserInventory.java (97%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/functions/AutoRestart.java (92%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/functions/Chatback.java (93%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/functions/CommandScheduler.java (99%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/functions/ConsoleLogger.java (94%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/functions/Flight.java (96%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/functions/InactivityTax.java (94%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/functions/InvSwap.java (85%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/functions/ItemBanList.java (96%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/functions/Mail.java (99%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/functions/Messager.java (97%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/functions/Moonglobe.java (98%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/functions/PauseBypass.java (95%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/functions/Radio.java (97%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/functions/Sandbox.java (96%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/functions/SoftWhitelist.java (95%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/functions/Whitelist.java (98%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/functions/worldguard/DragonFlightFlag.java (93%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/functions/worldguard/WitherFlag.java (93%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/listeners/ListenCreatureSpawn.java (95%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/listeners/ListenEntityDamage.java (81%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/listeners/ListenEntityToggleGlideEvent.java (89%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/listeners/ListenPlayerChangedWorld.java (77%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/listeners/ListenPlayerChat.java (94%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/listeners/ListenPlayerCmdPreprocess.java (95%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/listeners/ListenPlayerDeath.java (90%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/listeners/ListenPlayerGameModeChange.java (79%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/listeners/ListenPlayerJoin.java (85%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/listeners/ListenPlayerLogin.java (94%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/listeners/ListenPlayerMoveEvent.java (92%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/listeners/ListenPlayerQuit.java (89%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/listeners/ListenPlayerRespawn.java (78%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/listeners/ListenPlayerToggleFlightEvent.java (94%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/listeners/ListenServerPing.java (81%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/listeners/ListenSignChangeEvent.java (96%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/listeners/ListenTimeSkip.java (87%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/pb/PocketBase.java (98%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/pb/PocketBaseUtils.java (98%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/pb/README.md (100%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/util/ConfigKey.java (98%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/util/ConfigLoader.java (98%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/util/PBConfigLoader.java (97%) rename dreamvisitor/src/main/java/{io/github/stonley890 => org/woftnw}/dreamvisitor/util/UUIDFromater.java (91%) diff --git a/dreamvisitor/pom.xml b/dreamvisitor/pom.xml index 08f1377..dc69a29 100644 --- a/dreamvisitor/pom.xml +++ b/dreamvisitor/pom.xml @@ -1,9 +1,9 @@ 4.0.0 - io.github.stonley890 + org.woftnw dreamvisitor - 2.17.0 + 3.0.0 jar Dreamvisitor diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Dreamvisitor.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java similarity index 97% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Dreamvisitor.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java index a4b55de..fafe3ca 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/Dreamvisitor.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor; +package org.woftnw.dreamvisitor; import com.sk89q.worldguard.WorldGuard; import com.sk89q.worldguard.protection.flags.Flag; @@ -13,13 +13,15 @@ import io.github.stonley890.dreamvisitor.commands.*; import io.github.stonley890.dreamvisitor.data.*; import io.github.stonley890.dreamvisitor.discord.DiscCommandsManager; -import io.github.stonley890.dreamvisitor.commands.CmdChatback; +import org.woftnw.dreamvisitor.commands.*; import io.github.stonley890.dreamvisitor.functions.*; -import io.github.stonley890.dreamvisitor.functions.worldguard.DragonFlightFlag; -import io.github.stonley890.dreamvisitor.functions.worldguard.WitherFlag; +import org.woftnw.dreamvisitor.data.*; +import org.woftnw.dreamvisitor.functions.*; +import org.woftnw.dreamvisitor.functions.worldguard.DragonFlightFlag; +import org.woftnw.dreamvisitor.functions.worldguard.WitherFlag; import io.github.stonley890.dreamvisitor.listeners.*; -import io.github.stonley890.dreamvisitor.util.ConfigKey; -import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; +import org.woftnw.dreamvisitor.listeners.*; +import org.woftnw.dreamvisitor.util.ConfigKey; import net.luckperms.api.LuckPerms; import org.apache.logging.log4j.LogManager; import org.bukkit.Bukkit; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdAdminRadio.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdAdminRadio.java similarity index 90% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdAdminRadio.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdAdminRadio.java index 34ff735..6114c04 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdAdminRadio.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdAdminRadio.java @@ -1,12 +1,12 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.CommandAPI; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; import dev.jorel.commandapi.ExecutableCommand; import dev.jorel.commandapi.arguments.GreedyStringArgument; -import io.github.stonley890.dreamvisitor.functions.Messager; -import io.github.stonley890.dreamvisitor.functions.Radio; +import org.woftnw.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.functions.Radio; import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; import org.bukkit.entity.Player; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdChatback.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdChatback.java similarity index 93% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdChatback.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdChatback.java index 67e5789..f767750 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdChatback.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdChatback.java @@ -1,9 +1,9 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.ExecutableCommand; import dev.jorel.commandapi.arguments.LongArgument; -import io.github.stonley890.dreamvisitor.functions.Chatback; +import org.woftnw.dreamvisitor.functions.Chatback; import net.md_5.bungee.api.ChatColor; import org.jetbrains.annotations.NotNull; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDiscord.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdDiscord.java similarity index 80% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDiscord.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdDiscord.java index 5f11dce..3026325 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDiscord.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdDiscord.java @@ -1,11 +1,10 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.CommandAPI; import dev.jorel.commandapi.CommandAPICommand; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.data.PlayerMemory; -import io.github.stonley890.dreamvisitor.data.PlayerUtility; -import io.github.stonley890.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.data.PlayerMemory; +import org.woftnw.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDreamvisitor.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdDreamvisitor.java similarity index 99% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDreamvisitor.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdDreamvisitor.java index 193a0c4..60a3eaa 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDreamvisitor.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdDreamvisitor.java @@ -1,14 +1,13 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; import dev.jorel.commandapi.arguments.*; import dev.jorel.commandapi.executors.CommandArguments; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.data.Tribe; -import io.github.stonley890.dreamvisitor.data.TribeUtil; -import io.github.stonley890.dreamvisitor.functions.Messager; -import net.md_5.bungee.api.ChatColor; +import org.woftnw.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.data.Tribe; +import org.woftnw.dreamvisitor.data.TribeUtil; +import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.Location; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDvset.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdDvset.java similarity index 98% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDvset.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdDvset.java index e64ddcd..895bcc2 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdDvset.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdDvset.java @@ -1,10 +1,10 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.*; import dev.jorel.commandapi.arguments.StringArgument; -import io.github.stonley890.dreamvisitor.data.PlayerMemory; -import io.github.stonley890.dreamvisitor.data.PlayerUtility; -import io.github.stonley890.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.data.PlayerMemory; +import org.woftnw.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.functions.Messager; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.*; import net.md_5.bungee.api.chat.hover.content.Text; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdHub.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdHub.java similarity index 97% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdHub.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdHub.java index bf8aec6..c83480f 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdHub.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdHub.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import com.earth2me.essentials.Essentials; import com.earth2me.essentials.User; @@ -6,9 +6,9 @@ import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; import dev.jorel.commandapi.arguments.EntitySelectorArgument; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.functions.Mail; -import io.github.stonley890.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.functions.Mail; +import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.*; import org.bukkit.command.BlockCommandSender; import org.bukkit.command.CommandSender; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdInvSwap.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdInvSwap.java similarity index 82% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdInvSwap.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdInvSwap.java index f9c46d9..0368328 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdInvSwap.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdInvSwap.java @@ -1,11 +1,10 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.CommandAPI; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.functions.InvSwap; -import io.github.stonley890.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.functions.InvSwap; +import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdItemBanList.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdItemBanList.java similarity index 82% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdItemBanList.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdItemBanList.java index 2da1a4c..d1baa25 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdItemBanList.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdItemBanList.java @@ -1,12 +1,9 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.CommandAPI; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; -import dev.jorel.commandapi.ExecutableCommand; -import dev.jorel.commandapi.wrappers.NativeProxyCommandSender; -import io.github.stonley890.dreamvisitor.functions.ItemBanList; -import org.bukkit.command.Command; +import org.woftnw.dreamvisitor.functions.ItemBanList; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdMoonglobe.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdMoonglobe.java similarity index 97% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdMoonglobe.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdMoonglobe.java index 4dd6764..9e818b3 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdMoonglobe.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdMoonglobe.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.CommandAPI; import dev.jorel.commandapi.CommandAPICommand; @@ -8,8 +8,8 @@ import dev.jorel.commandapi.arguments.LocationArgument; import dev.jorel.commandapi.executors.CommandArguments; import dev.jorel.commandapi.wrappers.NativeProxyCommandSender; -import io.github.stonley890.dreamvisitor.functions.Messager; -import io.github.stonley890.dreamvisitor.functions.Moonglobe; +import org.woftnw.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.functions.Moonglobe; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPanic.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPanic.java similarity index 92% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPanic.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPanic.java index 669f709..5f11c84 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPanic.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPanic.java @@ -1,14 +1,14 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import java.util.TimerTask; import dev.jorel.commandapi.CommandAPICommand; -import io.github.stonley890.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.entity.Player; -import io.github.stonley890.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.Dreamvisitor; import org.jetbrains.annotations.NotNull; public class CmdPanic implements DVCommand { diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdParcel.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdParcel.java similarity index 98% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdParcel.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdParcel.java index 8450bf8..0006d89 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdParcel.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdParcel.java @@ -1,12 +1,12 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.CommandAPI; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; import dev.jorel.commandapi.arguments.*; -import io.github.stonley890.dreamvisitor.data.Tribe; -import io.github.stonley890.dreamvisitor.functions.Mail; -import io.github.stonley890.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.data.Tribe; +import org.woftnw.dreamvisitor.functions.Mail; +import org.woftnw.dreamvisitor.functions.Messager; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.ComponentBuilder; import org.bukkit.Location; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPauseBypass.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPauseBypass.java similarity index 89% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPauseBypass.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPauseBypass.java index 3817381..be65766 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPauseBypass.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPauseBypass.java @@ -1,14 +1,12 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.CommandAPI; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; -import dev.jorel.commandapi.ExecutableCommand; import dev.jorel.commandapi.arguments.EntitySelectorArgument; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.data.PlayerUtility; -import io.github.stonley890.dreamvisitor.functions.Messager; -import io.github.stonley890.dreamvisitor.functions.PauseBypass; +import org.woftnw.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.functions.PauseBypass; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPausechat.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPausechat.java similarity index 94% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPausechat.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPausechat.java index 7efef46..ec757c4 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPausechat.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPausechat.java @@ -1,11 +1,11 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; import org.bukkit.Bukkit; import org.bukkit.ChatColor; -import io.github.stonley890.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.Dreamvisitor; import org.jetbrains.annotations.NotNull; public class CmdPausechat implements DVCommand { diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPlayerlimit.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPlayerlimit.java similarity index 92% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPlayerlimit.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPlayerlimit.java index a2d262c..21ab96f 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdPlayerlimit.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPlayerlimit.java @@ -1,14 +1,14 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; import dev.jorel.commandapi.arguments.IntegerArgument; -import io.github.stonley890.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.entity.Player; -import io.github.stonley890.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.Dreamvisitor; import org.jetbrains.annotations.NotNull; public class CmdPlayerlimit implements DVCommand { diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdRadio.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdRadio.java similarity index 93% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdRadio.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdRadio.java index ad7953c..1c07950 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdRadio.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdRadio.java @@ -1,10 +1,10 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.CommandAPI; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; import dev.jorel.commandapi.arguments.GreedyStringArgument; -import io.github.stonley890.dreamvisitor.functions.Radio; +import org.woftnw.dreamvisitor.functions.Radio; import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; import org.bukkit.entity.Player; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSandbox.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSandbox.java similarity index 92% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSandbox.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSandbox.java index 64eb43d..0c40508 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSandbox.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSandbox.java @@ -1,14 +1,13 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; import dev.jorel.commandapi.arguments.BooleanArgument; import dev.jorel.commandapi.arguments.EntitySelectorArgument; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.data.PlayerMemory; -import io.github.stonley890.dreamvisitor.data.PlayerUtility; -import io.github.stonley890.dreamvisitor.functions.Messager; -import io.github.stonley890.dreamvisitor.functions.Sandbox; +import org.woftnw.dreamvisitor.data.PlayerMemory; +import org.woftnw.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.functions.Sandbox; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.chat.ComponentBuilder; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSchedule.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSchedule.java similarity index 98% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSchedule.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSchedule.java index c6c5a55..c22a3c7 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSchedule.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSchedule.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; @@ -7,10 +7,9 @@ import dev.jorel.commandapi.arguments.IntegerArgument; import dev.jorel.commandapi.arguments.StringArgument; import dev.jorel.commandapi.arguments.TextArgument; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.functions.CommandScheduler; -import io.github.stonley890.dreamvisitor.functions.CommandScheduler.Schedule; -import io.github.stonley890.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.functions.CommandScheduler; +import org.woftnw.dreamvisitor.functions.CommandScheduler.Schedule; +import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.ChatColor; import org.jetbrains.annotations.NotNull; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdScheduleRestart.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdScheduleRestart.java similarity index 81% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdScheduleRestart.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdScheduleRestart.java index 3acd600..e1e0503 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdScheduleRestart.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdScheduleRestart.java @@ -1,10 +1,9 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.functions.AutoRestart; -import io.github.stonley890.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.functions.AutoRestart; +import org.woftnw.dreamvisitor.functions.Messager; import org.jetbrains.annotations.NotNull; public class CmdScheduleRestart implements DVCommand { diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSetback.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSetback.java similarity index 94% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSetback.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSetback.java index 616d846..30e9ec1 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSetback.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSetback.java @@ -1,15 +1,13 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import com.earth2me.essentials.Essentials; import com.earth2me.essentials.User; import dev.jorel.commandapi.CommandAPI; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; -import dev.jorel.commandapi.ExecutableCommand; import dev.jorel.commandapi.arguments.*; import dev.jorel.commandapi.wrappers.Rotation; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSethub.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSethub.java similarity index 92% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSethub.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSethub.java index fba1254..f944141 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSethub.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSethub.java @@ -1,22 +1,20 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.CommandAPI; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; -import dev.jorel.commandapi.ExecutableCommand; import dev.jorel.commandapi.arguments.LocationArgument; import dev.jorel.commandapi.arguments.RotationArgument; import dev.jorel.commandapi.arguments.WorldArgument; import dev.jorel.commandapi.wrappers.Rotation; -import io.github.stonley890.dreamvisitor.functions.Messager; -import org.bukkit.ChatColor; +import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.command.BlockCommandSender; import org.bukkit.command.CommandSender; import org.bukkit.entity.Entity; -import io.github.stonley890.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.Dreamvisitor; import org.jetbrains.annotations.NotNull; public class CmdSethub implements DVCommand { diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSetmotd.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSetmotd.java similarity index 88% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSetmotd.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSetmotd.java index 8811043..596104c 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSetmotd.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSetmotd.java @@ -1,9 +1,9 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.arguments.GreedyStringArgument; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.functions.Messager; import org.jetbrains.annotations.NotNull; public class CmdSetmotd implements DVCommand { diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSoftwhitelist.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSoftwhitelist.java similarity index 92% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSoftwhitelist.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSoftwhitelist.java index 94bfb56..664b44e 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSoftwhitelist.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSoftwhitelist.java @@ -1,14 +1,13 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.CommandAPI; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; import dev.jorel.commandapi.arguments.OfflinePlayerArgument; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.data.PlayerUtility; -import io.github.stonley890.dreamvisitor.functions.Messager; -import io.github.stonley890.dreamvisitor.functions.SoftWhitelist; -import org.bukkit.ChatColor; +import org.woftnw.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.functions.SoftWhitelist; import org.bukkit.OfflinePlayer; import org.jetbrains.annotations.NotNull; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSynctime.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSynctime.java similarity index 90% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSynctime.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSynctime.java index 0862410..14fc656 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdSynctime.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSynctime.java @@ -1,11 +1,10 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.CommandAPI; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; import dev.jorel.commandapi.arguments.WorldArgument; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.command.BlockCommandSender; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdTagRadio.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdTagRadio.java similarity index 94% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdTagRadio.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdTagRadio.java index f4e2fab..498410c 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdTagRadio.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdTagRadio.java @@ -1,10 +1,10 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.CommandAPI; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.arguments.GreedyStringArgument; import dev.jorel.commandapi.arguments.StringArgument; -import io.github.stonley890.dreamvisitor.functions.Radio; +import org.woftnw.dreamvisitor.functions.Radio; import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; import org.bukkit.entity.Player; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdTribeUpdate.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdTribeUpdate.java similarity index 90% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdTribeUpdate.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdTribeUpdate.java index 40af8bd..1f3b25e 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdTribeUpdate.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdTribeUpdate.java @@ -1,11 +1,13 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; import dev.jorel.commandapi.arguments.EntitySelectorArgument; -import io.github.stonley890.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.Dreamvisitor; import io.github.stonley890.dreamvisitor.data.*; -import io.github.stonley890.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.data.PlayerTribe; +import org.woftnw.dreamvisitor.data.Tribe; +import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdUnwax.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdUnwax.java similarity index 90% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdUnwax.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdUnwax.java index 3576d5e..b1fe75f 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdUnwax.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdUnwax.java @@ -1,10 +1,9 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.CommandAPI; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.FluidCollisionMode; import org.bukkit.Particle; import org.bukkit.block.Block; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdUser.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdUser.java similarity index 94% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdUser.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdUser.java index 1642ac6..849ae10 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdUser.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdUser.java @@ -1,10 +1,10 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.CommandAPI; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; import dev.jorel.commandapi.arguments.OfflinePlayerArgument; -import io.github.stonley890.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.OfflinePlayer; import org.jetbrains.annotations.NotNull; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdVelocity.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdVelocity.java similarity index 92% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdVelocity.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdVelocity.java index b15ac65..05d1f6b 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdVelocity.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdVelocity.java @@ -1,11 +1,10 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.CommandAPI; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; import dev.jorel.commandapi.arguments.*; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.Location; import org.bukkit.entity.Entity; import org.jetbrains.annotations.NotNull; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdZoop.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdZoop.java similarity index 90% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdZoop.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdZoop.java index 23e9df4..27281d7 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CmdZoop.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdZoop.java @@ -1,11 +1,11 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.CommandAPI; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; -import io.github.stonley890.dreamvisitor.data.PlayerMemory; -import io.github.stonley890.dreamvisitor.data.PlayerUtility; -import io.github.stonley890.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.data.PlayerMemory; +import org.woftnw.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CommandUtils.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CommandUtils.java similarity index 90% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CommandUtils.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CommandUtils.java index 7598c1c..a35b5e6 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/CommandUtils.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CommandUtils.java @@ -1,10 +1,10 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.arguments.Argument; import dev.jorel.commandapi.arguments.ArgumentSuggestions; import dev.jorel.commandapi.arguments.CustomArgument; import dev.jorel.commandapi.arguments.StringArgument; -import io.github.stonley890.dreamvisitor.data.Tribe; +import org.woftnw.dreamvisitor.data.Tribe; import java.util.Arrays; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/DVCommand.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/DVCommand.java similarity index 77% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/DVCommand.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/DVCommand.java index b1b0327..a9c9754 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/commands/DVCommand.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/DVCommand.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.commands; +package org.woftnw.dreamvisitor.commands; import dev.jorel.commandapi.ExecutableCommand; import org.jetbrains.annotations.NotNull; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/BadWords.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/BadWords.java similarity index 86% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/BadWords.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/BadWords.java index dd11f44..2b3537f 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/BadWords.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/BadWords.java @@ -1,7 +1,7 @@ -package io.github.stonley890.dreamvisitor.data; +package org.woftnw.dreamvisitor.data; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.configuration.file.YamlConfiguration; import org.jetbrains.annotations.NotNull; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/Config.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/Config.java similarity index 93% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/Config.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/Config.java index 3b5fd49..7dd154e 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/Config.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/Config.java @@ -1,11 +1,11 @@ -package io.github.stonley890.dreamvisitor.data; +package org.woftnw.dreamvisitor.data; import com.google.gson.JsonObject; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.functions.AutoRestart; -import io.github.stonley890.dreamvisitor.functions.Messager; -import io.github.stonley890.dreamvisitor.pb.PocketBase; -import io.github.stonley890.dreamvisitor.util.ConfigKey; +import org.woftnw.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.functions.AutoRestart; +import org.woftnw.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.pb.PocketBase; +import org.woftnw.dreamvisitor.util.ConfigKey; import org.bukkit.Bukkit; import org.bukkit.configuration.file.FileConfiguration; import org.jetbrains.annotations.Contract; @@ -14,7 +14,6 @@ import java.io.IOException; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PlayerMemory.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/PlayerMemory.java similarity index 98% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PlayerMemory.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/PlayerMemory.java index 114b822..b14f23e 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PlayerMemory.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/PlayerMemory.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.data; +package org.woftnw.dreamvisitor.data; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PlayerTribe.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/PlayerTribe.java similarity index 97% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PlayerTribe.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/PlayerTribe.java index 27b42b8..1ab7c19 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PlayerTribe.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/PlayerTribe.java @@ -1,7 +1,7 @@ -package io.github.stonley890.dreamvisitor.data; +package org.woftnw.dreamvisitor.data; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.functions.Messager; import net.luckperms.api.model.user.UserManager; import net.luckperms.api.node.Node; import org.bukkit.Bukkit; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PlayerUtility.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/PlayerUtility.java similarity index 98% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PlayerUtility.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/PlayerUtility.java index fe5dad0..2ea5746 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/PlayerUtility.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/PlayerUtility.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.data; +package org.woftnw.dreamvisitor.data; import java.io.File; import java.io.IOException; @@ -8,7 +8,7 @@ import java.util.UUID; import com.earth2me.essentials.Essentials; -import io.github.stonley890.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.Dreamvisitor; import org.bukkit.Bukkit; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/RealtimeConfigUpdater.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/RealtimeConfigUpdater.java similarity index 97% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/RealtimeConfigUpdater.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/RealtimeConfigUpdater.java index 8a4dbda..5839392 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/RealtimeConfigUpdater.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/RealtimeConfigUpdater.java @@ -1,7 +1,7 @@ -package io.github.stonley890.dreamvisitor.data; +package org.woftnw.dreamvisitor.data; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.Bukkit; import org.json.JSONException; import org.json.JSONObject; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/Tribe.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/Tribe.java similarity index 97% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/Tribe.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/Tribe.java index 91a2787..832a3f5 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/Tribe.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/Tribe.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.data; +package org.woftnw.dreamvisitor.data; import net.md_5.bungee.api.ChatColor; import org.jetbrains.annotations.Contract; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/TribeUtil.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/TribeUtil.java similarity index 96% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/TribeUtil.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/TribeUtil.java index a3d24d9..aa745de 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/TribeUtil.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/TribeUtil.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.data; +package org.woftnw.dreamvisitor.data; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/AltRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/AltRepository.java similarity index 96% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/AltRepository.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/AltRepository.java index 41f9271..9f2eb64 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/AltRepository.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/AltRepository.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.data.repository; +package org.woftnw.dreamvisitor.data.repository; import java.util.List; import java.util.Optional; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/InfractionRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/InfractionRepository.java similarity index 96% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/InfractionRepository.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/InfractionRepository.java index a0b4577..aba3eaa 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/InfractionRepository.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/InfractionRepository.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.data.repository; +package org.woftnw.dreamvisitor.data.repository; import java.util.List; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/ItemRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/ItemRepository.java similarity index 91% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/ItemRepository.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/ItemRepository.java index b5de479..2414378 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/ItemRepository.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/ItemRepository.java @@ -1,9 +1,9 @@ -package io.github.stonley890.dreamvisitor.data.repository; +package org.woftnw.dreamvisitor.data.repository; import java.util.List; import java.util.Optional; -import io.github.stonley890.dreamvisitor.data.type.Item; +import org.woftnw.dreamvisitor.data.type.Item; /** * Repository interface for Item data operations diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseAltRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseAltRepository.java similarity index 98% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseAltRepository.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseAltRepository.java index 423be69..6ebf307 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseAltRepository.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseAltRepository.java @@ -1,9 +1,9 @@ -package io.github.stonley890.dreamvisitor.data.repository; +package org.woftnw.dreamvisitor.data.repository; import com.google.gson.Gson; import com.google.gson.JsonObject; -import io.github.stonley890.dreamvisitor.pb.PocketBase; +import org.woftnw.dreamvisitor.pb.PocketBase; import java.io.IOException; import java.time.OffsetDateTime; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseInfractionRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseInfractionRepository.java similarity index 98% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseInfractionRepository.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseInfractionRepository.java index 38c51e8..29cd616 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseInfractionRepository.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseInfractionRepository.java @@ -1,10 +1,10 @@ -package io.github.stonley890.dreamvisitor.data.repository; +package org.woftnw.dreamvisitor.data.repository; import com.google.gson.Gson; import com.google.gson.JsonObject; -import io.github.stonley890.dreamvisitor.data.type.DVUser; -import io.github.stonley890.dreamvisitor.pb.PocketBase; +import org.woftnw.dreamvisitor.data.type.DVUser; +import org.woftnw.dreamvisitor.pb.PocketBase; import java.io.IOException; import java.time.OffsetDateTime; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseItemRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseItemRepository.java similarity index 98% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseItemRepository.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseItemRepository.java index e7bd7ad..63a6599 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseItemRepository.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseItemRepository.java @@ -1,12 +1,10 @@ -package io.github.stonley890.dreamvisitor.data.repository; +package org.woftnw.dreamvisitor.data.repository; import com.google.gson.Gson; import com.google.gson.JsonObject; -import io.github.stonley890.dreamvisitor.data.type.Item; -import io.github.stonley890.dreamvisitor.pb.PocketBase; - -import org.jetbrains.annotations.NotNull; +import org.woftnw.dreamvisitor.data.type.Item; +import org.woftnw.dreamvisitor.pb.PocketBase; import java.io.IOException; import java.time.OffsetDateTime; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseUserInventoryRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserInventoryRepository.java similarity index 97% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseUserInventoryRepository.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserInventoryRepository.java index 0db4e03..7bd0a8d 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseUserInventoryRepository.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserInventoryRepository.java @@ -1,14 +1,12 @@ -package io.github.stonley890.dreamvisitor.data.repository; +package org.woftnw.dreamvisitor.data.repository; import com.google.gson.Gson; import com.google.gson.JsonObject; -import io.github.stonley890.dreamvisitor.data.type.DVUser; -import io.github.stonley890.dreamvisitor.data.type.Item; -import io.github.stonley890.dreamvisitor.data.type.UserInventory; -import io.github.stonley890.dreamvisitor.pb.PocketBase; - -import org.jetbrains.annotations.NotNull; +import org.woftnw.dreamvisitor.data.type.DVUser; +import org.woftnw.dreamvisitor.data.type.Item; +import org.woftnw.dreamvisitor.data.type.UserInventory; +import org.woftnw.dreamvisitor.pb.PocketBase; import java.io.IOException; import java.time.OffsetDateTime; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseUserRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserRepository.java similarity index 97% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseUserRepository.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserRepository.java index a05f65d..ae8e3e3 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/PocketBaseUserRepository.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserRepository.java @@ -1,11 +1,11 @@ -package io.github.stonley890.dreamvisitor.data.repository; +package org.woftnw.dreamvisitor.data.repository; import com.google.gson.Gson; import com.google.gson.JsonObject; import com.google.gson.reflect.TypeToken; -import io.github.stonley890.dreamvisitor.data.type.DVUser; -import io.github.stonley890.dreamvisitor.pb.PocketBase; -import io.github.stonley890.dreamvisitor.util.UUIDFromater; +import org.woftnw.dreamvisitor.data.type.DVUser; +import org.woftnw.dreamvisitor.pb.PocketBase; +import org.woftnw.dreamvisitor.util.UUIDFromater; import org.jetbrains.annotations.NotNull; @@ -14,7 +14,6 @@ import java.time.OffsetDateTime; import java.time.format.DateTimeFormatter; import java.util.*; -import java.util.function.Predicate; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/UserInventoryRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserInventoryRepository.java similarity index 94% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/UserInventoryRepository.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserInventoryRepository.java index 3617545..b3192fb 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/UserInventoryRepository.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserInventoryRepository.java @@ -1,10 +1,10 @@ -package io.github.stonley890.dreamvisitor.data.repository; +package org.woftnw.dreamvisitor.data.repository; import java.util.List; import java.util.Optional; -import io.github.stonley890.dreamvisitor.data.type.UserInventory; +import org.woftnw.dreamvisitor.data.type.UserInventory; /** * Repository interface for UserInventory data operations diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/UserRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserRepository.java similarity index 93% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/UserRepository.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserRepository.java index 017d717..a8c33bf 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/repository/UserRepository.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserRepository.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.data.repository; +package org.woftnw.dreamvisitor.data.repository; @@ -6,7 +6,7 @@ import java.util.Optional; import java.util.UUID; -import io.github.stonley890.dreamvisitor.data.type.DVUser; +import org.woftnw.dreamvisitor.data.type.DVUser; /** * Repository interface for User data operations diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/DVUser.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/DVUser.java similarity index 98% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/DVUser.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/DVUser.java index 0031463..25bc576 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/DVUser.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/DVUser.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.data.type; +package org.woftnw.dreamvisitor.data.type; import java.time.OffsetDateTime; import java.util.List; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/Item.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/Item.java similarity index 98% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/Item.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/Item.java index ac53f29..d2dfbf3 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/Item.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/Item.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.data.type; +package org.woftnw.dreamvisitor.data.type; import java.time.OffsetDateTime; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/UserInventory.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/UserInventory.java similarity index 97% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/UserInventory.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/UserInventory.java index 07e4df5..1174085 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/data/type/UserInventory.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/UserInventory.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.data.type; +package org.woftnw.dreamvisitor.data.type; import java.time.OffsetDateTime; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/AutoRestart.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/AutoRestart.java similarity index 92% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/AutoRestart.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/AutoRestart.java index b953d1d..fd6b64d 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/AutoRestart.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/AutoRestart.java @@ -1,6 +1,6 @@ -package io.github.stonley890.dreamvisitor.functions; +package org.woftnw.dreamvisitor.functions; -import io.github.stonley890.dreamvisitor.data.Config; +import org.woftnw.dreamvisitor.data.Config; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Message; import org.jetbrains.annotations.Nullable; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Chatback.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Chatback.java similarity index 93% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Chatback.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Chatback.java index 0f108e5..bcd3a06 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Chatback.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Chatback.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.functions; +package org.woftnw.dreamvisitor.functions; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/CommandScheduler.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/CommandScheduler.java similarity index 99% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/CommandScheduler.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/CommandScheduler.java index 92357e1..9567a8f 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/CommandScheduler.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/CommandScheduler.java @@ -1,6 +1,6 @@ -package io.github.stonley890.dreamvisitor.functions; +package org.woftnw.dreamvisitor.functions; -import io.github.stonley890.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.Dreamvisitor; import org.bukkit.Bukkit; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/ConsoleLogger.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ConsoleLogger.java similarity index 94% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/ConsoleLogger.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ConsoleLogger.java index 904d510..3a30ad4 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/ConsoleLogger.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ConsoleLogger.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.functions; +package org.woftnw.dreamvisitor.functions; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.appender.AbstractAppender; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Flight.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Flight.java similarity index 96% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Flight.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Flight.java index 5f7a683..7c0f9d2 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Flight.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Flight.java @@ -1,8 +1,8 @@ -package io.github.stonley890.dreamvisitor.functions; +package org.woftnw.dreamvisitor.functions; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.data.PlayerMemory; -import io.github.stonley890.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.data.PlayerMemory; +import org.woftnw.dreamvisitor.data.PlayerUtility; import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.NamespacedKey; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/InactivityTax.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/InactivityTax.java similarity index 94% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/InactivityTax.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/InactivityTax.java index 69a5132..00c01c3 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/InactivityTax.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/InactivityTax.java @@ -1,17 +1,15 @@ -package io.github.stonley890.dreamvisitor.functions; +package org.woftnw.dreamvisitor.functions; import com.earth2me.essentials.Essentials; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.data.PlayerUtility; import net.essentialsx.api.v2.services.BalanceTop; import org.bukkit.Bukkit; import org.bukkit.configuration.file.FileConfiguration; import java.math.BigDecimal; -import java.math.RoundingMode; import java.time.Duration; import java.time.Instant; -import java.time.LocalDate; import java.util.Map; import java.util.UUID; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/InvSwap.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/InvSwap.java similarity index 85% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/InvSwap.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/InvSwap.java index 3b5d80e..d997632 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/InvSwap.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/InvSwap.java @@ -1,7 +1,7 @@ -package io.github.stonley890.dreamvisitor.functions; +package org.woftnw.dreamvisitor.functions; -import io.github.stonley890.dreamvisitor.data.PlayerMemory; -import io.github.stonley890.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.data.PlayerMemory; +import org.woftnw.dreamvisitor.data.PlayerUtility; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/ItemBanList.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ItemBanList.java similarity index 96% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/ItemBanList.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ItemBanList.java index 081bb9d..2fecd68 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/ItemBanList.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ItemBanList.java @@ -1,6 +1,6 @@ -package io.github.stonley890.dreamvisitor.functions; +package org.woftnw.dreamvisitor.functions; -import io.github.stonley890.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.Dreamvisitor; import org.bukkit.Bukkit; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Mail.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Mail.java similarity index 99% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Mail.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Mail.java index 9e488ff..c0e7da7 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Mail.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Mail.java @@ -1,10 +1,10 @@ -package io.github.stonley890.dreamvisitor.functions; +package org.woftnw.dreamvisitor.functions; import com.earth2me.essentials.Essentials; import com.earth2me.essentials.User; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.data.Tribe; -import io.github.stonley890.dreamvisitor.data.TribeUtil; +import org.woftnw.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.data.Tribe; +import org.woftnw.dreamvisitor.data.TribeUtil; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.chat.ComponentBuilder; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Messager.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Messager.java similarity index 97% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Messager.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Messager.java index 49f84a6..8ec6718 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Messager.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Messager.java @@ -1,6 +1,6 @@ -package io.github.stonley890.dreamvisitor.functions; +package org.woftnw.dreamvisitor.functions; -import io.github.stonley890.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.Dreamvisitor; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.ComponentBuilder; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Moonglobe.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Moonglobe.java similarity index 98% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Moonglobe.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Moonglobe.java index 88948df..62d86a2 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Moonglobe.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Moonglobe.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.functions; +package org.woftnw.dreamvisitor.functions; import net.md_5.bungee.api.ChatColor; import org.bukkit.Bukkit; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/PauseBypass.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/PauseBypass.java similarity index 95% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/PauseBypass.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/PauseBypass.java index 472e6f2..8d272fe 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/PauseBypass.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/PauseBypass.java @@ -1,6 +1,6 @@ -package io.github.stonley890.dreamvisitor.functions; +package org.woftnw.dreamvisitor.functions; -import io.github.stonley890.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.Dreamvisitor; import org.bukkit.Bukkit; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Radio.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Radio.java similarity index 97% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Radio.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Radio.java index bdf278c..b5d5fe6 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Radio.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Radio.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.functions; +package org.woftnw.dreamvisitor.functions; import org.bukkit.Bukkit; import org.bukkit.ChatColor; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Sandbox.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Sandbox.java similarity index 96% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Sandbox.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Sandbox.java index cfc3b03..d475ecb 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Sandbox.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Sandbox.java @@ -1,8 +1,7 @@ -package io.github.stonley890.dreamvisitor.functions; +package org.woftnw.dreamvisitor.functions; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.data.PlayerMemory; -import io.github.stonley890.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.data.PlayerMemory; +import org.woftnw.dreamvisitor.data.PlayerUtility; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.ComponentBuilder; import org.bukkit.Bukkit; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/SoftWhitelist.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/SoftWhitelist.java similarity index 95% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/SoftWhitelist.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/SoftWhitelist.java index ff85c70..37b74a6 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/SoftWhitelist.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/SoftWhitelist.java @@ -1,6 +1,6 @@ -package io.github.stonley890.dreamvisitor.functions; +package org.woftnw.dreamvisitor.functions; -import io.github.stonley890.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.Dreamvisitor; import org.bukkit.Bukkit; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Whitelist.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Whitelist.java similarity index 98% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Whitelist.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Whitelist.java index d6b1c85..0fc0aad 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/Whitelist.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Whitelist.java @@ -1,7 +1,7 @@ -package io.github.stonley890.dreamvisitor.functions; +package org.woftnw.dreamvisitor.functions; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.data.PlayerUtility; import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; import net.dv8tion.jda.api.hooks.ListenerAdapter; import org.bukkit.BanList; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/worldguard/DragonFlightFlag.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/worldguard/DragonFlightFlag.java similarity index 93% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/worldguard/DragonFlightFlag.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/worldguard/DragonFlightFlag.java index 24f87ae..bd18161 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/worldguard/DragonFlightFlag.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/worldguard/DragonFlightFlag.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.functions.worldguard; +package org.woftnw.dreamvisitor.functions.worldguard; import com.sk89q.worldedit.util.Location; import com.sk89q.worldguard.LocalPlayer; @@ -8,8 +8,8 @@ import com.sk89q.worldguard.session.Session; import com.sk89q.worldguard.session.handler.FlagValueChangeHandler; import com.sk89q.worldguard.session.handler.Handler; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.functions.Flight; +import org.woftnw.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.functions.Flight; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/worldguard/WitherFlag.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/worldguard/WitherFlag.java similarity index 93% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/worldguard/WitherFlag.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/worldguard/WitherFlag.java index 4f37638..b9ca956 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/functions/worldguard/WitherFlag.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/worldguard/WitherFlag.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.functions.worldguard; +package org.woftnw.dreamvisitor.functions.worldguard; import com.sk89q.worldedit.util.Location; import com.sk89q.worldguard.LocalPlayer; @@ -8,7 +8,7 @@ import com.sk89q.worldguard.session.Session; import com.sk89q.worldguard.session.handler.FlagValueChangeHandler; import com.sk89q.worldguard.session.handler.Handler; -import io.github.stonley890.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.Dreamvisitor; import org.jetbrains.annotations.NotNull; public class WitherFlag extends FlagValueChangeHandler { diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenCreatureSpawn.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenCreatureSpawn.java similarity index 95% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenCreatureSpawn.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenCreatureSpawn.java index c121fe7..0f117c6 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenCreatureSpawn.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenCreatureSpawn.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.listeners; +package org.woftnw.dreamvisitor.listeners; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.util.Location; @@ -8,7 +8,7 @@ import com.sk89q.worldguard.protection.regions.ProtectedRegion; import com.sk89q.worldguard.protection.regions.RegionContainer; import com.sk89q.worldguard.protection.regions.RegionQuery; -import io.github.stonley890.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.Dreamvisitor; import net.md_5.bungee.api.ChatColor; import org.bukkit.World; import org.bukkit.entity.Entity; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenEntityDamage.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenEntityDamage.java similarity index 81% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenEntityDamage.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenEntityDamage.java index ebcfda5..73975a2 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenEntityDamage.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenEntityDamage.java @@ -1,12 +1,12 @@ -package io.github.stonley890.dreamvisitor.listeners; +package org.woftnw.dreamvisitor.listeners; -import io.github.stonley890.dreamvisitor.data.Config; +import org.woftnw.dreamvisitor.data.Config; import org.bukkit.entity.EntityType; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityDamageByEntityEvent; -import io.github.stonley890.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.Dreamvisitor; import org.jetbrains.annotations.NotNull; public class ListenEntityDamage implements Listener { diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenEntityToggleGlideEvent.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenEntityToggleGlideEvent.java similarity index 89% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenEntityToggleGlideEvent.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenEntityToggleGlideEvent.java index 488fbf3..ddc2236 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenEntityToggleGlideEvent.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenEntityToggleGlideEvent.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.listeners; +package org.woftnw.dreamvisitor.listeners; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerChangedWorld.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerChangedWorld.java similarity index 77% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerChangedWorld.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerChangedWorld.java index 80ebd2a..d4eeddc 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerChangedWorld.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerChangedWorld.java @@ -1,6 +1,6 @@ -package io.github.stonley890.dreamvisitor.listeners; +package org.woftnw.dreamvisitor.listeners; -import io.github.stonley890.dreamvisitor.functions.Flight; +import org.woftnw.dreamvisitor.functions.Flight; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerChangedWorldEvent; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerChat.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerChat.java similarity index 94% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerChat.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerChat.java index e1ae360..186e07f 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerChat.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerChat.java @@ -1,14 +1,14 @@ -package io.github.stonley890.dreamvisitor.listeners; +package org.woftnw.dreamvisitor.listeners; import java.io.File; import java.io.IOException; import java.util.List; import java.util.regex.Pattern; -import io.github.stonley890.dreamvisitor.data.BadWords; -import io.github.stonley890.dreamvisitor.data.PlayerMemory; -import io.github.stonley890.dreamvisitor.data.PlayerUtility; -import io.github.stonley890.dreamvisitor.functions.Chatback; +import org.woftnw.dreamvisitor.data.BadWords; +import org.woftnw.dreamvisitor.data.PlayerMemory; +import org.woftnw.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.functions.Chatback; import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; import net.md_5.bungee.api.chat.ComponentBuilder; import net.md_5.bungee.api.chat.HoverEvent; @@ -23,7 +23,7 @@ import org.bukkit.event.Listener; import org.bukkit.event.player.AsyncPlayerChatEvent; -import io.github.stonley890.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.Dreamvisitor; import org.jetbrains.annotations.NotNull; public class ListenPlayerChat implements Listener { diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerCmdPreprocess.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerCmdPreprocess.java similarity index 95% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerCmdPreprocess.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerCmdPreprocess.java index 5e78c83..abdef2b 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerCmdPreprocess.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerCmdPreprocess.java @@ -1,12 +1,12 @@ -package io.github.stonley890.dreamvisitor.listeners; +package org.woftnw.dreamvisitor.listeners; import java.io.File; import java.io.IOException; import java.util.List; -import io.github.stonley890.dreamvisitor.data.PlayerUtility; -import io.github.stonley890.dreamvisitor.functions.Mail; -import io.github.stonley890.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.functions.Mail; +import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.Bukkit; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.FileConfiguration; @@ -16,7 +16,7 @@ import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerCommandPreprocessEvent; -import io.github.stonley890.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.Dreamvisitor; import net.md_5.bungee.api.ChatColor; import org.jetbrains.annotations.NotNull; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerDeath.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerDeath.java similarity index 90% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerDeath.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerDeath.java index 52327b7..3cb5681 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerDeath.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerDeath.java @@ -1,6 +1,6 @@ -package io.github.stonley890.dreamvisitor.listeners; +package org.woftnw.dreamvisitor.listeners; -import io.github.stonley890.dreamvisitor.functions.Mail; +import org.woftnw.dreamvisitor.functions.Mail; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerGameModeChange.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerGameModeChange.java similarity index 79% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerGameModeChange.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerGameModeChange.java index c6e7eba..3cb5d8c 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerGameModeChange.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerGameModeChange.java @@ -1,8 +1,8 @@ -package io.github.stonley890.dreamvisitor.listeners; +package org.woftnw.dreamvisitor.listeners; -import io.github.stonley890.dreamvisitor.data.PlayerMemory; -import io.github.stonley890.dreamvisitor.data.PlayerUtility; -import io.github.stonley890.dreamvisitor.functions.Flight; +import org.woftnw.dreamvisitor.data.PlayerMemory; +import org.woftnw.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.functions.Flight; import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.entity.Player; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerJoin.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerJoin.java similarity index 85% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerJoin.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerJoin.java index 88a12ce..3113056 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerJoin.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerJoin.java @@ -1,12 +1,12 @@ -package io.github.stonley890.dreamvisitor.listeners; +package org.woftnw.dreamvisitor.listeners; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.data.PlayerMemory; -import io.github.stonley890.dreamvisitor.data.PlayerTribe; -import io.github.stonley890.dreamvisitor.data.PlayerUtility; -import io.github.stonley890.dreamvisitor.data.Tribe; -import io.github.stonley890.dreamvisitor.functions.Messager; -import io.github.stonley890.dreamvisitor.functions.Sandbox; +import org.woftnw.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.data.PlayerMemory; +import org.woftnw.dreamvisitor.data.PlayerTribe; +import org.woftnw.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.data.Tribe; +import org.woftnw.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.functions.Sandbox; import net.luckperms.api.model.user.User; import net.md_5.bungee.api.ChatColor; import org.bukkit.Bukkit; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerLogin.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerLogin.java similarity index 94% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerLogin.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerLogin.java index 5c1e3bb..05777f5 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerLogin.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerLogin.java @@ -1,11 +1,11 @@ -package io.github.stonley890.dreamvisitor.listeners; +package org.woftnw.dreamvisitor.listeners; import java.io.File; import java.io.IOException; import java.util.List; -import io.github.stonley890.dreamvisitor.data.Config; -import io.github.stonley890.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.data.Config; +import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.Bukkit; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.FileConfiguration; @@ -16,7 +16,7 @@ import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerLoginEvent.Result; -import io.github.stonley890.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.Dreamvisitor; import org.jetbrains.annotations.NotNull; public class ListenPlayerLogin implements Listener { diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerMoveEvent.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerMoveEvent.java similarity index 92% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerMoveEvent.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerMoveEvent.java index 3535d0d..2045157 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerMoveEvent.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerMoveEvent.java @@ -1,7 +1,7 @@ -package io.github.stonley890.dreamvisitor.listeners; +package org.woftnw.dreamvisitor.listeners; -import io.github.stonley890.dreamvisitor.data.Config; -import io.github.stonley890.dreamvisitor.functions.Flight; +import org.woftnw.dreamvisitor.data.Config; +import org.woftnw.dreamvisitor.functions.Flight; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerQuit.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerQuit.java similarity index 89% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerQuit.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerQuit.java index a9ff733..ebf2502 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerQuit.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerQuit.java @@ -1,16 +1,16 @@ -package io.github.stonley890.dreamvisitor.listeners; +package org.woftnw.dreamvisitor.listeners; -import io.github.stonley890.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.data.PlayerMemory; -import io.github.stonley890.dreamvisitor.functions.Messager; -import io.github.stonley890.dreamvisitor.functions.Sandbox; +import org.woftnw.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.data.PlayerMemory; +import org.woftnw.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.functions.Sandbox; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerQuitEvent; -import io.github.stonley890.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.data.PlayerUtility; import org.jetbrains.annotations.NotNull; import java.io.IOException; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerRespawn.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerRespawn.java similarity index 78% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerRespawn.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerRespawn.java index 63842d7..21cf406 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerRespawn.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerRespawn.java @@ -1,7 +1,7 @@ -package io.github.stonley890.dreamvisitor.listeners; +package org.woftnw.dreamvisitor.listeners; -import io.github.stonley890.dreamvisitor.functions.Flight; -import io.github.stonley890.dreamvisitor.functions.Messager; +import org.woftnw.dreamvisitor.functions.Flight; +import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerRespawnEvent; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerToggleFlightEvent.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerToggleFlightEvent.java similarity index 94% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerToggleFlightEvent.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerToggleFlightEvent.java index a6ba28e..a98c7ec 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenPlayerToggleFlightEvent.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerToggleFlightEvent.java @@ -1,6 +1,6 @@ -package io.github.stonley890.dreamvisitor.listeners; +package org.woftnw.dreamvisitor.listeners; -import io.github.stonley890.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.Dreamvisitor; import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.Sound; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenServerPing.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenServerPing.java similarity index 81% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenServerPing.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenServerPing.java index cc0a16e..4406b05 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenServerPing.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenServerPing.java @@ -1,6 +1,6 @@ -package io.github.stonley890.dreamvisitor.listeners; +package org.woftnw.dreamvisitor.listeners; -import io.github.stonley890.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.Dreamvisitor; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.server.ServerListPingEvent; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenSignChangeEvent.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenSignChangeEvent.java similarity index 96% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenSignChangeEvent.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenSignChangeEvent.java index 70fae15..776f0b2 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenSignChangeEvent.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenSignChangeEvent.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.listeners; +package org.woftnw.dreamvisitor.listeners; import com.earth2me.essentials.Essentials; import net.md_5.bungee.api.ChatColor; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenTimeSkip.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenTimeSkip.java similarity index 87% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenTimeSkip.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenTimeSkip.java index 7a1e273..c7a6379 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/listeners/ListenTimeSkip.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenTimeSkip.java @@ -1,6 +1,6 @@ -package io.github.stonley890.dreamvisitor.listeners; +package org.woftnw.dreamvisitor.listeners; -import io.github.stonley890.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.Dreamvisitor; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.event.EventHandler; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/PocketBase.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/pb/PocketBase.java similarity index 98% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/PocketBase.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/pb/PocketBase.java index 505c433..e8f1f4e 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/PocketBase.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/pb/PocketBase.java @@ -1,21 +1,18 @@ -package io.github.stonley890.dreamvisitor.pb; +package org.woftnw.dreamvisitor.pb; import com.google.gson.Gson; import com.google.gson.JsonObject; -import com.google.gson.reflect.TypeToken; import okhttp3.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; -import java.lang.reflect.Type; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; -import java.util.logging.Level; public class PocketBase { private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/PocketBaseUtils.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/pb/PocketBaseUtils.java similarity index 98% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/PocketBaseUtils.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/pb/PocketBaseUtils.java index 6889dd6..5c3d790 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/PocketBaseUtils.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/pb/PocketBaseUtils.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.pb; +package org.woftnw.dreamvisitor.pb; import com.google.gson.Gson; import com.google.gson.JsonElement; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/README.md b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/pb/README.md similarity index 100% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/pb/README.md rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/pb/README.md diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/ConfigKey.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigKey.java similarity index 98% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/ConfigKey.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigKey.java index d8cdd24..f5691fa 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/ConfigKey.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigKey.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.util; +package org.woftnw.dreamvisitor.util; import org.bukkit.Location; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/ConfigLoader.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigLoader.java similarity index 98% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/ConfigLoader.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigLoader.java index 18e4d78..44f2c43 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/ConfigLoader.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigLoader.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.util; +package org.woftnw.dreamvisitor.util; import org.jetbrains.annotations.NotNull; import org.yaml.snakeyaml.Yaml; diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/PBConfigLoader.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/PBConfigLoader.java similarity index 97% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/PBConfigLoader.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/PBConfigLoader.java index 1c8e01c..4d701ac 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/PBConfigLoader.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/PBConfigLoader.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.util; +package org.woftnw.dreamvisitor.util; import com.google.gson.JsonObject; import com.google.gson.JsonElement; import java.io.IOException; @@ -6,7 +6,7 @@ import java.util.Map; import java.util.logging.Logger; -import io.github.stonley890.dreamvisitor.pb.PocketBase; +import org.woftnw.dreamvisitor.pb.PocketBase; import org.jetbrains.annotations.NotNull; /** diff --git a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/UUIDFromater.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/UUIDFromater.java similarity index 91% rename from dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/UUIDFromater.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/UUIDFromater.java index 04d6b39..502041b 100644 --- a/dreamvisitor/src/main/java/io/github/stonley890/dreamvisitor/util/UUIDFromater.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/UUIDFromater.java @@ -1,4 +1,4 @@ -package io.github.stonley890.dreamvisitor.util; +package org.woftnw.dreamvisitor.util; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; diff --git a/dreamvisitor/src/main/resources/plugin.yml b/dreamvisitor/src/main/resources/plugin.yml index 94d28e0..4a511ab 100644 --- a/dreamvisitor/src/main/resources/plugin.yml +++ b/dreamvisitor/src/main/resources/plugin.yml @@ -1,4 +1,4 @@ -main: io.github.stonley890.dreamvisitor.Dreamvisitor +main: org.woftnw.dreamvisitor.Dreamvisitor name: Dreamvisitor version: "${project.version}" api-version: 1.20 From 3f59909a3843f04e49f8a0adf06e3a32f709849c Mon Sep 17 00:00:00 2001 From: Bog Date: Sun, 29 Jun 2025 17:27:28 -0700 Subject: [PATCH 12/39] Reformat code --- .../org/woftnw/dreamvisitor/Dreamvisitor.java | 620 +++++++------- .../data/RealtimeConfigUpdater.java | 336 ++++---- .../data/repository/AltRepository.java | 86 -- .../data/repository/InfractionRepository.java | 79 -- .../data/repository/ItemRepository.java | 104 +-- .../repository/PocketBaseAltRepository.java | 257 ------ .../PocketBaseInfractionRepository.java | 290 ------- .../repository/PocketBaseItemRepository.java | 552 ++++++------ .../PocketBaseUserInventoryRepository.java | 546 ++++++------ .../repository/PocketBaseUserRepository.java | 635 +++++++------- .../repository/UserInventoryRepository.java | 136 +-- .../data/repository/UserRepository.java | 135 ++- .../woftnw/dreamvisitor/data/type/DVUser.java | 422 +++++----- .../woftnw/dreamvisitor/data/type/Item.java | 348 ++++---- .../dreamvisitor/data/type/UserInventory.java | 144 ++-- .../woftnw/dreamvisitor/pb/PocketBase.java | 788 +++++++++--------- .../dreamvisitor/pb/PocketBaseUtils.java | 218 ++--- .../dreamvisitor/util/ConfigLoader.java | 107 +-- .../dreamvisitor/util/PBConfigLoader.java | 182 ++-- .../dreamvisitor/util/UUIDFromater.java | 26 +- 20 files changed, 2649 insertions(+), 3362 deletions(-) delete mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/AltRepository.java delete mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/InfractionRepository.java delete mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseAltRepository.java delete mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseInfractionRepository.java diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java index fafe3ca..5192521 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java @@ -10,17 +10,14 @@ import dev.jorel.commandapi.CommandAPIBukkitConfig; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandTree; -import io.github.stonley890.dreamvisitor.commands.*; -import io.github.stonley890.dreamvisitor.data.*; -import io.github.stonley890.dreamvisitor.discord.DiscCommandsManager; import org.woftnw.dreamvisitor.commands.*; -import io.github.stonley890.dreamvisitor.functions.*; import org.woftnw.dreamvisitor.data.*; import org.woftnw.dreamvisitor.functions.*; import org.woftnw.dreamvisitor.functions.worldguard.DragonFlightFlag; import org.woftnw.dreamvisitor.functions.worldguard.WitherFlag; -import io.github.stonley890.dreamvisitor.listeners.*; import org.woftnw.dreamvisitor.listeners.*; +import org.woftnw.dreamvisitor.pb.PocketBase; +import org.woftnw.dreamvisitor.pb.PocketBaseUtils; import org.woftnw.dreamvisitor.util.ConfigKey; import net.luckperms.api.LuckPerms; import org.apache.logging.log4j.LogManager; @@ -38,266 +35,265 @@ import java.util.*; import java.util.logging.Level; -@SuppressWarnings({ "null" }) +@SuppressWarnings({"null"}) public class Dreamvisitor extends JavaPlugin { - private static final org.apache.logging.log4j.core.Logger logger = (org.apache.logging.log4j.core.Logger) LogManager - .getRootLogger(); - public static Dreamvisitor PLUGIN; - public static LuckPerms luckperms; - public static String MOTD = null; - public static boolean chatPaused; - public static int playerLimit; - public static Location hubLocation; - public static boolean webWhitelistEnabled; - public static boolean debugMode; - private static ConsoleLogger appender; - public final String VERSION = getDescription().getVersion(); - - public static StateFlag DRAGON_FLIGHT; - public static StateFlag WITHER; - - public static Dreamvisitor getPlugin() { - return PLUGIN; - } - - public static @NotNull String getPlayerPath(@NotNull UUID uuid) { - return PLUGIN.getDataFolder().getAbsolutePath() + "/player/" + uuid + ".yml"; - } - - @NotNull - public static LuckPerms getLuckPerms() throws NullPointerException { - RegisteredServiceProvider provider = Bukkit.getServicesManager().getRegistration(LuckPerms.class); - LuckPerms luckPerms; - if (provider != null) - luckPerms = provider.getProvider(); - else { - throw new NullPointerException("LuckPerms cannot be found."); + private static final org.apache.logging.log4j.core.Logger logger = (org.apache.logging.log4j.core.Logger) LogManager + .getRootLogger(); + public static Dreamvisitor PLUGIN; + public static LuckPerms luckperms; + public static String MOTD = null; + public static boolean chatPaused; + public static int playerLimit; + public static Location hubLocation; + public static boolean webWhitelistEnabled; + public static boolean debugMode; + private static ConsoleLogger appender; + public final String VERSION = getDescription().getVersion(); + + public static StateFlag DRAGON_FLIGHT; + public static StateFlag WITHER; + + public static Dreamvisitor getPlugin() { + return PLUGIN; } - return luckPerms; - } - - @Override - public void onLoad() { - try { - FlagRegistry registry = WorldGuard.getInstance().getFlagRegistry(); - try { - StateFlag flag = new StateFlag("dragon-flight", true); - registry.register(flag); - DRAGON_FLIGHT = flag; - - } catch (FlagConflictException e) { - Flag existing = registry.get("dragon-flight"); - if (existing instanceof StateFlag) { - DRAGON_FLIGHT = (StateFlag) existing; - } else { - getLogger() - .severe("A flag with the name dragon-flight already exists! Some other plugin claimed it already :("); - } - } - try { - StateFlag flag = new StateFlag("wither", true); - registry.register(flag); - WITHER = flag; - - } catch (FlagConflictException e) { - Flag existing = registry.get("wither"); - if (existing instanceof StateFlag) { - WITHER = (StateFlag) existing; - } else { - getLogger().severe("A flag with the name wither already exists! Some other plugin claimed it already :("); - } - } - } catch (NoClassDefFoundError e) { - getLogger().info("WorldGuard is not installed, so no flags will be created."); - } catch (IllegalStateException e) { - getLogger().severe("New WorldGuard flags cannot be registered at this time. This should be impossible."); - e.printStackTrace(); + + public static @NotNull String getPlayerPath(@NotNull UUID uuid) { + return PLUGIN.getDataFolder().getAbsolutePath() + "/player/" + uuid + ".yml"; } - } - - @Override - public void onEnable() { - - try { - PLUGIN = this; - - debugMode = Config.get(ConfigKey.DEBUG); - - checkConfig(); - - Messager.debug("Initializing PocketBase config loader..."); - Config.init(); - - Messager.debug("Registering listeners..."); - registerListeners(); - - List commands = new ArrayList<>(); - commands.add(new CmdAdminRadio()); - commands.add(new CmdDiscord()); - commands.add(new CmdHub()); - commands.add(new CmdPanic()); - commands.add(new CmdPauseBypass()); - commands.add(new CmdPausechat()); - commands.add(new CmdPlayerlimit()); - commands.add(new CmdRadio()); - commands.add(new CmdSethub()); - commands.add(new CmdSoftwhitelist()); - commands.add(new CmdTagRadio()); - commands.add(new CmdZoop()); - commands.add(new CmdItemBanList()); - commands.add(new CmdUser()); - commands.add(new CmdTribeUpdate()); - commands.add(new CmdUnwax()); - commands.add(new CmdScheduleRestart()); - commands.add(new CmdInvSwap()); - commands.add(new CmdDvset()); - commands.add(new CmdSetmotd()); - commands.add(new CmdSynctime()); - commands.add(new CmdSandbox()); - commands.add(new CmdMoonglobe()); - commands.add(new CmdSetback()); - commands.add(new CmdParcel()); - commands.add(new CmdDreamvisitor()); - commands.add(new CmdChatback()); - commands.add(new CmdVelocity()); - commands.add(new CmdSchedule()); - - Messager.debug("Initializing commands..."); - CommandAPI.onLoad(new CommandAPIBukkitConfig(this).silentLogs(!debugMode)); - CommandAPI.onEnable(); - registerCommands(commands); - - Messager.debug("Creating data folder..."); - boolean directoryCreated = getDataFolder().mkdir(); - if (!directoryCreated) - Messager.debug("Dreamvisitor did not create a data folder. It may already exist."); - saveDefaultConfig(); - - Messager.debug("Initializing mail.yml"); - Mail.init(); - - Messager.debug("Initializing player-tribes.yml"); - PlayerTribe.setup(); - - Messager.debug("Initializing energy"); - Flight.init(); - - Messager.debug("Initializing command scheduler"); - CommandScheduler.getInstance().loadConfig(); - - Messager.debug("Initializing badwords.yml"); - BadWords.init(); - - RegisteredServiceProvider provider = Bukkit.getServicesManager().getRegistration(LuckPerms.class); - if (provider != null) - luckperms = provider.getProvider(); - - SessionManager sessionManager = WorldGuard.getInstance().getPlatform().getSessionManager(); - sessionManager.registerHandler(DragonFlightFlag.FACTORY, null); - sessionManager.registerHandler(WitherFlag.FACTORY, null); - - getLogger().log(Level.INFO, "Dreamvisitor: A plugin created by Bog for Wings of Fire: The New World to add various features."); - - Messager.debug("Restoring chat pause..."); - if (Config.get(ConfigKey.PAUSE_CHAT)) { - chatPaused = true; - getLogger().info("Chat is currently paused from last session! Use /pausechat to allow users to chat."); - } - - Messager.debug("Restoring player limit override..."); - playerLimit = Config.get(ConfigKey.PLAYER_LIMIT); - getLogger().info("Player limit override is currently set to " + playerLimit); - - Messager.debug("Restoring item banlist..."); - ItemBanList.init(); - - Messager.debug("Setting up console logging..."); - appender = new ConsoleLogger(); - logger.addAppender(appender); - - Runnable pushConsole = new BukkitRunnable() { - @Override - public void run() { - if (Config.get(ConfigKey.LOG_CONSOLE)) { - - // TODO: Send to DVHub console. - - } - } - }; - - Runnable scheduledRestarts = new BukkitRunnable() { - @Override - public void run() { - Config.loadConfig(); - - if (AutoRestart.isAutoRestart() && Bukkit.getOnlinePlayers().isEmpty()) { - AutoRestart.sendAutoRestartMessage(); - getLogger().info("Restarting the server as scheduled."); - getServer().spigot().restart(); - } - - long maxMemory = Runtime.getRuntime().maxMemory(); - long freeMemory = Runtime.getRuntime().freeMemory(); - double freeMemoryPercent = ((double) freeMemory / maxMemory) * 100; - if (freeMemoryPercent <= 10) { - AutoRestart.enableAutoRestart(null); - getLogger() - .warning("Dreamvisitor scheduled a restart because free memory usage is at or less than 10%."); - } - } - }; - Runnable tick = new BukkitRunnable() { - @Override - public void run() { - Moonglobe.tick(); + @NotNull + public static LuckPerms getLuckPerms() throws NullPointerException { + RegisteredServiceProvider provider = Bukkit.getServicesManager().getRegistration(LuckPerms.class); + LuckPerms luckPerms; + if (provider != null) + luckPerms = provider.getProvider(); + else { + throw new NullPointerException("LuckPerms cannot be found."); } - }; - - Runnable checkBannedItems = new BukkitRunnable() { - @Override - public void run() { - for (Player player : Bukkit.getOnlinePlayers()) { - if (!player.isOp() && ItemBanList.badItems != null) { - - for (ItemStack item : ItemBanList.badItems) { - if (item == null) - continue; - for (ItemStack content : player.getInventory().getContents()) { - if (content == null || !content.isSimilar(item)) - continue; - player.getInventory().remove(item); - getLogger().info("Removed " + item.getType().name() + " (" - + Objects.requireNonNull(item.getItemMeta()).getDisplayName() + ") from " + player.getName()); + return luckPerms; + } + + @Override + public void onLoad() { + try { + FlagRegistry registry = WorldGuard.getInstance().getFlagRegistry(); + try { + StateFlag flag = new StateFlag("dragon-flight", true); + registry.register(flag); + DRAGON_FLIGHT = flag; + + } catch (FlagConflictException e) { + Flag existing = registry.get("dragon-flight"); + if (existing instanceof StateFlag) { + DRAGON_FLIGHT = (StateFlag) existing; + } else { + getLogger() + .severe("A flag with the name dragon-flight already exists! Some other plugin claimed it already :("); } - } } - } + try { + StateFlag flag = new StateFlag("wither", true); + registry.register(flag); + WITHER = flag; + + } catch (FlagConflictException e) { + Flag existing = registry.get("wither"); + if (existing instanceof StateFlag) { + WITHER = (StateFlag) existing; + } else { + getLogger().severe("A flag with the name wither already exists! Some other plugin claimed it already :("); + } + } + } catch (NoClassDefFoundError e) { + getLogger().info("WorldGuard is not installed, so no flags will be created."); + } catch (IllegalStateException e) { + getLogger().warning("New WorldGuard flags cannot be registered at this time. You may not have WorldGuard installed."); } - }; + } - Bukkit.getScheduler().runTaskTimer(this, tick, 0, 0); + @Override + public void onEnable() { + + try { + PLUGIN = this; + + debugMode = Config.get(ConfigKey.DEBUG); + + checkConfig(); + + Messager.debug("Initializing PocketBase config loader..."); + Config.init(); + + Messager.debug("Registering listeners..."); + registerListeners(); + + List commands = new ArrayList<>(); + commands.add(new CmdAdminRadio()); + commands.add(new CmdDiscord()); + commands.add(new CmdHub()); + commands.add(new CmdPanic()); + commands.add(new CmdPauseBypass()); + commands.add(new CmdPausechat()); + commands.add(new CmdPlayerlimit()); + commands.add(new CmdRadio()); + commands.add(new CmdSethub()); + commands.add(new CmdSoftwhitelist()); + commands.add(new CmdTagRadio()); + commands.add(new CmdZoop()); + commands.add(new CmdItemBanList()); + commands.add(new CmdUser()); + commands.add(new CmdTribeUpdate()); + commands.add(new CmdUnwax()); + commands.add(new CmdScheduleRestart()); + commands.add(new CmdInvSwap()); + commands.add(new CmdDvset()); + commands.add(new CmdSetmotd()); + commands.add(new CmdSynctime()); + commands.add(new CmdSandbox()); + commands.add(new CmdMoonglobe()); + commands.add(new CmdSetback()); + commands.add(new CmdParcel()); + commands.add(new CmdDreamvisitor()); + commands.add(new CmdChatback()); + commands.add(new CmdVelocity()); + commands.add(new CmdSchedule()); + + Messager.debug("Initializing commands..."); + CommandAPI.onLoad(new CommandAPIBukkitConfig(this).silentLogs(!debugMode)); + CommandAPI.onEnable(); + registerCommands(commands); + + Messager.debug("Creating data folder..."); + boolean directoryCreated = getDataFolder().mkdir(); + if (!directoryCreated) + Messager.debug("Dreamvisitor did not create a data folder. It may already exist."); + saveDefaultConfig(); + + Messager.debug("Initializing mail.yml"); + Mail.init(); + + Messager.debug("Initializing player-tribes.yml"); + PlayerTribe.setup(); + + Messager.debug("Initializing energy"); + Flight.init(); + + Messager.debug("Initializing command scheduler"); + CommandScheduler.getInstance().loadConfig(); + + Messager.debug("Initializing badwords.yml"); + BadWords.init(); + + RegisteredServiceProvider provider = Bukkit.getServicesManager().getRegistration(LuckPerms.class); + if (provider != null) + luckperms = provider.getProvider(); + + SessionManager sessionManager = WorldGuard.getInstance().getPlatform().getSessionManager(); + sessionManager.registerHandler(DragonFlightFlag.FACTORY, null); + sessionManager.registerHandler(WitherFlag.FACTORY, null); + + getLogger().log(Level.INFO, "Dreamvisitor: A plugin created by Bog for Wings of Fire: The New World to add various features."); + + Messager.debug("Restoring chat pause..."); + if (Config.get(ConfigKey.PAUSE_CHAT)) { + chatPaused = true; + getLogger().info("Chat is currently paused from last session! Use /pausechat to allow users to chat."); + } + + Messager.debug("Restoring player limit override..."); + playerLimit = Config.get(ConfigKey.PLAYER_LIMIT); + getLogger().info("Player limit override is currently set to " + playerLimit); + + Messager.debug("Restoring item banlist..."); + ItemBanList.init(); + + Messager.debug("Setting up console logging..."); + appender = new ConsoleLogger(); + logger.addAppender(appender); + + Runnable pushConsole = new BukkitRunnable() { + @Override + public void run() { + if (Config.get(ConfigKey.LOG_CONSOLE)) { - Bukkit.getScheduler().runTaskTimer(this, scheduledRestarts, 200, 1200); - Bukkit.getScheduler().runTaskTimer(this, checkBannedItems, 40, 20 * 10); - Messager.debug("Enable finished."); - } catch (Exception e) { + } + } + }; + + Runnable scheduledRestarts = new BukkitRunnable() { + @Override + public void run() { + Config.loadConfig(); + + if (AutoRestart.isAutoRestart() && Bukkit.getOnlinePlayers().isEmpty()) { + AutoRestart.sendAutoRestartMessage(); + getLogger().info("Restarting the server as scheduled."); + getServer().spigot().restart(); + } + + long maxMemory = Runtime.getRuntime().maxMemory(); + long freeMemory = Runtime.getRuntime().freeMemory(); + double freeMemoryPercent = ((double) freeMemory / maxMemory) * 100; + if (freeMemoryPercent <= 10) { + AutoRestart.enableAutoRestart(null); + getLogger() + .warning("Dreamvisitor scheduled a restart because free memory usage is at or less than 10%."); + } + } + }; + + Runnable tick = new BukkitRunnable() { + @Override + public void run() { + Moonglobe.tick(); + } + }; + + Runnable checkBannedItems = new BukkitRunnable() { + @Override + public void run() { + for (Player player : Bukkit.getOnlinePlayers()) { + if (!player.isOp() && ItemBanList.badItems != null) { + + for (ItemStack item : ItemBanList.badItems) { + if (item == null) + continue; + for (ItemStack content : player.getInventory().getContents()) { + if (content == null || !content.isSimilar(item)) + continue; + player.getInventory().remove(item); + getLogger().info("Removed " + item.getType().name() + " (" + + Objects.requireNonNull(item.getItemMeta()).getDisplayName() + ") from " + player.getName()); + } + } + } + } + } + }; - getLogger() - .severe("Dreamvisitor was unable to start :(\nPlease notify Bog with the following stack trace:"); - e.printStackTrace(); + Bukkit.getScheduler().runTaskTimer(this, tick, 0, 0); - Bukkit.getPluginManager().disablePlugin(this); - throw new RuntimeException(); + Bukkit.getScheduler().runTaskTimer(this, scheduledRestarts, 200, 1200); + Bukkit.getScheduler().runTaskTimer(this, checkBannedItems, 40, 20 * 10); + + Messager.debug("Enable finished."); + } catch (Exception e) { + + getLogger() + .severe("Dreamvisitor was unable to start :(\nPlease notify Bog with the following stack trace:"); + e.printStackTrace(); + + Bukkit.getPluginManager().disablePlugin(this); + throw new RuntimeException(); + + } } - } - private void checkConfig() { + private void checkConfig() { // if (getConfig().getLongList("triberoles").size() != 10) // throw new InvalidConfigurationException("triberoles must contain exactly 10 entries."); // if (getConfig().getInt("playerlimit") < -1) @@ -305,81 +301,81 @@ private void checkConfig() { // if (getConfig().getInt("infraction-expire-time-days") < 1) // throw new InvalidConfigurationException("infraction-expire-time-days must be at least 1."); - if (!getConfig().contains("pocketbaseUrl")) { - getConfig().set("pocketbaseUrl", "http://127.0.0.1:8090/"); - } - if (!getConfig().contains("pocketbaseConfigId")) { - getConfig().set("pocketbaseConfigId", "record_id_here"); - } - if (!getConfig().contains("pocketbaseToken")) { - getConfig().set("pocketbaseToken", "your_admin_token_here"); + if (!getConfig().contains("pocketbaseUrl")) { + getConfig().set("pocketbaseUrl", "http://127.0.0.1:8090/"); + } + if (!getConfig().contains("pocketbaseConfigId")) { + getConfig().set("pocketbaseConfigId", "record_id_here"); + } + if (!getConfig().contains("pocketbaseToken")) { + getConfig().set("pocketbaseToken", "your_admin_token_here"); + } + if (!getConfig().contains("pocketbaseUseRealtime")) { + getConfig().set("pocketbaseUseRealtime", true); + } + + saveConfig(); } - if (!getConfig().contains("pocketbaseUseRealtime")) { - getConfig().set("pocketbaseUseRealtime", true); + + private void registerListeners() { + PluginManager pluginManager = getServer().getPluginManager(); + pluginManager.registerEvents(new ListenEntityDamage(), this); + pluginManager.registerEvents(new ListenPlayerChat(), this); + pluginManager.registerEvents(new ListenPlayerCmdPreprocess(), this); + pluginManager.registerEvents(new ListenPlayerDeath(), this); + pluginManager.registerEvents(new ListenPlayerJoin(), this); + pluginManager.registerEvents(new ListenPlayerLogin(), this); + pluginManager.registerEvents(new ListenPlayerQuit(), this); + pluginManager.registerEvents(new ItemBanList(), this); + pluginManager.registerEvents(new ListenPlayerGameModeChange(), this); + pluginManager.registerEvents(new ListenServerPing(), this); + pluginManager.registerEvents(new Sandbox(), this); + pluginManager.registerEvents(new ListenTimeSkip(), this); + pluginManager.registerEvents(new ListenSignChangeEvent(), this); + pluginManager.registerEvents(new ListenPlayerToggleFlightEvent(), this); + pluginManager.registerEvents(new ListenPlayerMoveEvent(), this); + pluginManager.registerEvents(new ListenEntityToggleGlideEvent(), this); + pluginManager.registerEvents(new ListenPlayerChangedWorld(), this); + pluginManager.registerEvents(new ListenPlayerRespawn(), this); + pluginManager.registerEvents(new ListenCreatureSpawn(), this); } - saveConfig(); - } - - private void registerListeners() { - PluginManager pluginManager = getServer().getPluginManager(); - pluginManager.registerEvents(new ListenEntityDamage(), this); - pluginManager.registerEvents(new ListenPlayerChat(), this); - pluginManager.registerEvents(new ListenPlayerCmdPreprocess(), this); - pluginManager.registerEvents(new ListenPlayerDeath(), this); - pluginManager.registerEvents(new ListenPlayerJoin(), this); - pluginManager.registerEvents(new ListenPlayerLogin(), this); - pluginManager.registerEvents(new ListenPlayerQuit(), this); - pluginManager.registerEvents(new ItemBanList(), this); - pluginManager.registerEvents(new ListenPlayerGameModeChange(), this); - pluginManager.registerEvents(new ListenServerPing(), this); - pluginManager.registerEvents(new Sandbox(), this); - pluginManager.registerEvents(new ListenTimeSkip(), this); - pluginManager.registerEvents(new ListenSignChangeEvent(), this); - pluginManager.registerEvents(new ListenPlayerToggleFlightEvent(), this); - pluginManager.registerEvents(new ListenPlayerMoveEvent(), this); - pluginManager.registerEvents(new ListenEntityToggleGlideEvent(), this); - pluginManager.registerEvents(new ListenPlayerChangedWorld(), this); - pluginManager.registerEvents(new ListenPlayerRespawn(), this); - pluginManager.registerEvents(new ListenCreatureSpawn(), this); - } - - private void registerCommands(@NotNull List commands) throws NullPointerException { - for (DVCommand command : commands) { - if (command.getCommand() instanceof CommandAPICommand apiCommand) { - apiCommand.register(this); - } else if (command.getCommand() instanceof CommandTree apiCommand) { - apiCommand.register(this); - } + private void registerCommands(@NotNull List commands) throws NullPointerException { + for (DVCommand command : commands) { + if (command.getCommand() instanceof CommandAPICommand apiCommand) { + apiCommand.register(this); + } else if (command.getCommand() instanceof CommandTree apiCommand) { + apiCommand.register(this); + } + } } - } - @Override - public void onDisable() { + @Override + public void onDisable() { - CommandAPI.onDisable(); + CommandAPI.onDisable(); - // Shutdown the realtime updater - RealtimeConfigUpdater.shutdown(); + // Shutdown the realtime updater + RealtimeConfigUpdater.shutdown(); - for (Moonglobe moonglobe : Moonglobe.activeMoonglobes) - moonglobe.remove(null); + for (Moonglobe moonglobe : Moonglobe.activeMoonglobes) + moonglobe.remove(null); - for (Player player : Bukkit.getOnlinePlayers()) { - try { - PlayerUtility.savePlayerMemory(player.getUniqueId()); - PlayerUtility.clearPlayerMemory(player.getUniqueId()); - } catch (IOException e) { - getLogger().severe("Unable to save player memory! Does the server have write access?"); - if (Dreamvisitor.debugMode) - throw new RuntimeException(); - } - } + for (Player player : Bukkit.getOnlinePlayers()) { + try { + PlayerUtility.savePlayerMemory(player.getUniqueId()); + PlayerUtility.clearPlayerMemory(player.getUniqueId()); + } catch (IOException e) { + getLogger().severe("Unable to save player memory! Does the server have write access?"); + if (Dreamvisitor.debugMode) + throw new RuntimeException(); + } + } - CommandScheduler.getInstance().saveConfig(); - CommandScheduler.getInstance().stopScheduler(); + CommandScheduler.getInstance().saveConfig(); + CommandScheduler.getInstance().stopScheduler(); - logger.removeAppender(appender); - } + logger.removeAppender(appender); + } } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/RealtimeConfigUpdater.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/RealtimeConfigUpdater.java index 5839392..3b2b93c 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/RealtimeConfigUpdater.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/RealtimeConfigUpdater.java @@ -19,189 +19,189 @@ import java.util.concurrent.atomic.AtomicBoolean; public class RealtimeConfigUpdater { - private static final ExecutorService executor = Executors.newSingleThreadExecutor(); - private static String baseUrl; - private static String configId; - private static String token; - private static final String collectionName = "dreamvisitor_config"; - private static String clientId; - private static final AtomicBoolean isRunning = new AtomicBoolean(false); - private static final AtomicBoolean isConnecting = new AtomicBoolean(false); - private static int retryCount = 0; - private static final int MAX_RETRIES = 5; - private static final int RETRY_DELAY_MS = 3000; // 5 seconds between retries - - public static void init(String pbBaseUrl, String pbConfigId, String pbToken) { - baseUrl = pbBaseUrl; - configId = pbConfigId; - token = pbToken; - startRealtimeUpdates(); - } - - public static void startRealtimeUpdates() { - if (isConnecting.get() || isRunning.get()) { - return; + private static final ExecutorService executor = Executors.newSingleThreadExecutor(); + private static String baseUrl; + private static String configId; + private static String token; + private static final String collectionName = "dreamvisitor_config"; + private static String clientId; + private static final AtomicBoolean isRunning = new AtomicBoolean(false); + private static final AtomicBoolean isConnecting = new AtomicBoolean(false); + private static int retryCount = 0; + private static final int MAX_RETRIES = 5; + private static final int RETRY_DELAY_MS = 3000; // 5 seconds between retries + + public static void init(String pbBaseUrl, String pbConfigId, String pbToken) { + baseUrl = pbBaseUrl; + configId = pbConfigId; + token = pbToken; + startRealtimeUpdates(); } - if (baseUrl == null || baseUrl.isEmpty() || configId == null || configId.isEmpty()) { - Messager.debug("Cannot start realtime updates: baseUrl or configId is not set"); - return; - } + public static void startRealtimeUpdates() { + if (isConnecting.get() || isRunning.get()) { + return; + } - isConnecting.set(true); - - CompletableFuture.runAsync(() -> { - try { - connectSSE(); - } catch (Exception e) { - Messager.debug("Error in SSE connection: " + e.getMessage()); - handleReconnect(); - } finally { - isConnecting.set(false); - } - }, executor); - } - - private static void connectSSE() throws IOException { - Messager.debug("Connecting to SSE endpoint"); - - URL url = new URL(baseUrl + "/api/realtime"); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("GET"); - connection.setReadTimeout(6000); // 1 minute timeout - - // Add authentication if token is provided - if (token != null && !token.isEmpty()) { - connection.setRequestProperty("Authorization", "Bearer " + token); - } + if (baseUrl == null || baseUrl.isEmpty() || configId == null || configId.isEmpty()) { + Messager.debug("Cannot start realtime updates: baseUrl or configId is not set"); + return; + } - int responseCode = connection.getResponseCode(); - if (responseCode == HttpURLConnection.HTTP_OK) { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { - isRunning.set(true); - retryCount = 0; - - String line; - while ((line = reader.readLine()) != null && isRunning.get()) { - if (line.startsWith("event: PB_CONNECT")) { - // Next line should be "data: {clientId}" - line = reader.readLine(); - if (line != null && line.startsWith("data: ")) { - clientId = line.substring(6).trim(); - Messager.debug("Connected to SSE with client ID: " + clientId); - setSubscription(); - } - } else if (line.startsWith("event: PB_DISCONNECT")) { - Messager.debug("Received disconnect event from server"); - break; - } else if (line.startsWith("event: update")) { - // Next line should be data - line = reader.readLine(); - if (line != null && line.startsWith("data: ")) { - handleUpdateEvent(line.substring(6)); + isConnecting.set(true); + + CompletableFuture.runAsync(() -> { + try { + connectSSE(); + } catch (Exception e) { + Messager.debug("Error in SSE connection: " + e.getMessage()); + handleReconnect(); + } finally { + isConnecting.set(false); } - } + }, executor); + } + + private static void connectSSE() throws IOException { + Messager.debug("Connecting to SSE endpoint"); + + URL url = new URL(baseUrl + "/api/realtime"); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setReadTimeout(6000); // 1 minute timeout + + // Add authentication if token is provided + if (token != null && !token.isEmpty()) { + connection.setRequestProperty("Authorization", "Bearer " + token); } - } finally { - isRunning.set(false); - if (!isConnecting.get()) { - handleReconnect(); + + int responseCode = connection.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK) { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { + isRunning.set(true); + retryCount = 0; + + String line; + while ((line = reader.readLine()) != null && isRunning.get()) { + if (line.startsWith("event: PB_CONNECT")) { + // Next line should be "data: {clientId}" + line = reader.readLine(); + if (line != null && line.startsWith("data: ")) { + clientId = line.substring(6).trim(); + Messager.debug("Connected to SSE with client ID: " + clientId); + setSubscription(); + } + } else if (line.startsWith("event: PB_DISCONNECT")) { + Messager.debug("Received disconnect event from server"); + break; + } else if (line.startsWith("event: update")) { + // Next line should be data + line = reader.readLine(); + if (line != null && line.startsWith("data: ")) { + handleUpdateEvent(line.substring(6)); + } + } + } + } finally { + isRunning.set(false); + if (!isConnecting.get()) { + handleReconnect(); + } + } + } else { + throw new IOException("Failed to connect to SSE endpoint: " + responseCode); } - } - } else { - throw new IOException("Failed to connect to SSE endpoint: " + responseCode); } - } - - private static void setSubscription() { - try { - URL url = new URL(baseUrl + "/api/realtime"); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("POST"); - connection.setRequestProperty("Content-Type", "application/json"); - - // Add authentication if token is provided - if (token != null && !token.isEmpty()) { - connection.setRequestProperty("Authorization", "Bearer " + token); - } - - connection.setDoOutput(true); - - // Subscribe to collection/record - JSONObject requestBody = new JSONObject(); - requestBody.put("clientId", clientId); - requestBody.put("subscriptions", new String[] { collectionName + "/" + configId }); - - try (OutputStream os = connection.getOutputStream()) { - byte[] input = requestBody.toString().getBytes(StandardCharsets.UTF_8); - os.write(input, 0, input.length); - } - - int responseCode = connection.getResponseCode(); - if (responseCode != HttpURLConnection.HTTP_NO_CONTENT) { - Messager.debug("Failed to set subscription: " + responseCode); - - // Read error response if available - if (connection.getErrorStream() != null) { - try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getErrorStream()))) { - StringBuilder errorResponse = new StringBuilder(); - String line; - while ((line = br.readLine()) != null) { - errorResponse.append(line); + + private static void setSubscription() { + try { + URL url = new URL(baseUrl + "/api/realtime"); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("POST"); + connection.setRequestProperty("Content-Type", "application/json"); + + // Add authentication if token is provided + if (token != null && !token.isEmpty()) { + connection.setRequestProperty("Authorization", "Bearer " + token); + } + + connection.setDoOutput(true); + + // Subscribe to collection/record + JSONObject requestBody = new JSONObject(); + requestBody.put("clientId", clientId); + requestBody.put("subscriptions", new String[]{collectionName + "/" + configId}); + + try (OutputStream os = connection.getOutputStream()) { + byte[] input = requestBody.toString().getBytes(StandardCharsets.UTF_8); + os.write(input, 0, input.length); + } + + int responseCode = connection.getResponseCode(); + if (responseCode != HttpURLConnection.HTTP_NO_CONTENT) { + Messager.debug("Failed to set subscription: " + responseCode); + + // Read error response if available + if (connection.getErrorStream() != null) { + try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getErrorStream()))) { + StringBuilder errorResponse = new StringBuilder(); + String line; + while ((line = br.readLine()) != null) { + errorResponse.append(line); + } + Messager.debug("Error response: " + errorResponse); + } + } + } else { + Messager.debug("Successfully subscribed to config updates"); } - Messager.debug("Error response: " + errorResponse); - } + } catch (Exception e) { + Messager.debug("Error setting subscription: " + e.getMessage()); } - } else { - Messager.debug("Successfully subscribed to config updates"); - } - } catch (Exception e) { - Messager.debug("Error setting subscription: " + e.getMessage()); } - } - - private static void handleUpdateEvent(String data) { - try { - JSONObject jsonData = new JSONObject(data); - if (jsonData.has("record")) { - JSONObject record = jsonData.getJSONObject("record"); - - // Handle autoRestart field - if (record.has("autoRestart")) { - boolean autoRestart = record.getBoolean("autoRestart"); - Messager.debug("Received real-time update: autoRestart = " + autoRestart); - - // Schedule update on main thread - Bukkit.getScheduler().runTask(Dreamvisitor.getPlugin(), () -> { - Config.updateLocalConfig(record); - }); + + private static void handleUpdateEvent(String data) { + try { + JSONObject jsonData = new JSONObject(data); + if (jsonData.has("record")) { + JSONObject record = jsonData.getJSONObject("record"); + + // Handle autoRestart field + if (record.has("autoRestart")) { + boolean autoRestart = record.getBoolean("autoRestart"); + Messager.debug("Received real-time update: autoRestart = " + autoRestart); + + // Schedule update on main thread + Bukkit.getScheduler().runTask(Dreamvisitor.getPlugin(), () -> { + Config.updateLocalConfig(record); + }); + } + } + } catch (JSONException e) { + Messager.debug("Error parsing update event: " + e.getMessage()); } - } - } catch (JSONException e) { - Messager.debug("Error parsing update event: " + e.getMessage()); } - } - private static void handleReconnect() { - if (retryCount < MAX_RETRIES) { - retryCount++; - Messager.debug("Attempting to reconnect SSE (attempt " + retryCount + "/" + MAX_RETRIES + ")"); + private static void handleReconnect() { + if (retryCount < MAX_RETRIES) { + retryCount++; + Messager.debug("Attempting to reconnect SSE (attempt " + retryCount + "/" + MAX_RETRIES + ")"); - try { - Thread.sleep(RETRY_DELAY_MS); - startRealtimeUpdates(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } else { - Messager.debug("Max retry attempts reached. Giving up on SSE connection."); - // Fallback to polling - retryCount = 0; + try { + Thread.sleep(RETRY_DELAY_MS); + startRealtimeUpdates(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } else { + Messager.debug("Max retry attempts reached. Giving up on SSE connection."); + // Fallback to polling + retryCount = 0; + } } - } - public static void shutdown() { - isRunning.set(false); - executor.shutdown(); - } + public static void shutdown() { + isRunning.set(false); + executor.shutdown(); + } } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/AltRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/AltRepository.java deleted file mode 100644 index 9f2eb64..0000000 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/AltRepository.java +++ /dev/null @@ -1,86 +0,0 @@ -package org.woftnw.dreamvisitor.data.repository; - -import java.util.List; -import java.util.Optional; - -/** - * Repository interface for Alt account data operations - */ -public interface AltRepository { - /** - * Find an alt by its PocketBase ID - * - * @param id PocketBase record ID - * @return Optional containing the alt if found - */ - Optional findById(String id); - - /** - * Find all alts linked to a parent user - * - * @param parentId Parent user's PocketBase ID - * @return List of alt accounts for this parent - */ - List findByParentId(String parentId); - - /** - * Find an alt by Discord ID - * - * @param discordId Discord ID (string) - * @return Optional containing the alt if found - */ - Optional findByDiscordId(String discordId); - - /** - * Find an alt by Discord Snowflake ID - * - * @param snowflakeId Discord Snowflake ID (numeric) - * @return Optional containing the alt if found - */ - Optional findBySnowflakeId(Long snowflakeId); - - /** - * Find an alt by Discord username - * - * @param discordName Discord username - * @return Optional containing the alt if found - */ - Optional findByDiscordName(String discordName); - - /** - * Get all alts - * - * @return List of all alt accounts - */ - List findAll(); - - /** - * Save an alt (create or update) - * - * @param alt Alt to save - * @return Saved alt - */ - Alt save(Alt alt); - - /** - * Delete an alt - * - * @param alt Alt to delete - */ - void delete(Alt alt); - - /** - * Delete an alt by ID - * - * @param id PocketBase ID of alt to delete - */ - void deleteById(String id); - - /** - * Get all alts matching a filter expression - * - * @param filter PocketBase filter expression - * @return List of matching alts - */ - List getAllWhere(String filter); -} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/InfractionRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/InfractionRepository.java deleted file mode 100644 index aba3eaa..0000000 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/InfractionRepository.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.woftnw.dreamvisitor.data.repository; - - -import java.util.List; -import java.util.Optional; - -/** - * Repository interface for Infraction data operations - */ -public interface InfractionRepository { - /** - * Find an infraction by its PocketBase ID - * - * @param id PocketBase record ID - * @return Optional containing the infraction if found - */ - Optional findById(String id); - - /** - * Find all infractions for a user - * - * @param userId PocketBase user ID - * @return List of infractions for the user - */ - List findByUser(String userId); - - /** - * Find all active (non-expired) infractions for a user - * - * @param userId PocketBase user ID - * @return List of active infractions for the user - */ - List findActiveByUser(String userId); - - /** - * Get all infractions - * - * @return List of all infractions - */ - List findAll(); - - /** - * Save an infraction (create or update) - * - * @param infraction Infraction to save - * @return Saved infraction - */ - Infraction save(Infraction infraction); - - /** - * Delete an infraction - * - * @param infraction Infraction to delete - */ - void delete(Infraction infraction); - - /** - * Delete an infraction by ID - * - * @param id PocketBase ID of infraction to delete - */ - void deleteById(String id); - - /** - * Get all infractions matching a filter - * - * @param filter PocketBase filter expression - * @return List of infractions matching the filter - */ - List getAllWhere(String filter); - - /** - * Load related user data for all infractions - * - * @param infractions List of infractions - * @return List of infractions with loaded user data - */ - List loadRelatedUsers(List infractions); -} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/ItemRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/ItemRepository.java index 2414378..2f7f7bb 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/ItemRepository.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/ItemRepository.java @@ -9,63 +9,63 @@ * Repository interface for Item data operations */ public interface ItemRepository { - /** - * Find an item by its PocketBase ID - * - * @param id PocketBase record ID - * @return Optional containing the item if found - */ - Optional findById(String id); + /** + * Find an item by its PocketBase ID + * + * @param id PocketBase record ID + * @return Optional containing the item if found + */ + Optional findById(String id); - /** - * Find an item by its name - * - * @param name Item name - * @return Optional containing the item if found - */ - Optional findByName(String name); + /** + * Find an item by its name + * + * @param name Item name + * @return Optional containing the item if found + */ + Optional findByName(String name); - /** - * Get all items - * - * @return List of all items - */ - List findAll(); + /** + * Get all items + * + * @return List of all items + */ + List findAll(); - /** - * Get all enabled items - * - * @return List of all enabled items - */ - List findAllEnabled(); + /** + * Get all enabled items + * + * @return List of all enabled items + */ + List findAllEnabled(); - /** - * Save an item (create or update) - * - * @param item Item to save - * @return Saved item - */ - Item save(Item item); + /** + * Save an item (create or update) + * + * @param item Item to save + * @return Saved item + */ + Item save(Item item); - /** - * Delete an item - * - * @param item Item to delete - */ - void delete(Item item); + /** + * Delete an item + * + * @param item Item to delete + */ + void delete(Item item); - /** - * Delete an item by ID - * - * @param id PocketBase ID of item to delete - */ - void deleteById(String id); + /** + * Delete an item by ID + * + * @param id PocketBase ID of item to delete + */ + void deleteById(String id); - /** - * Get all items matching a filter - * - * @param filter PocketBase filter expression - * @return List of items matching the filter - */ - List getAllWhere(String filter); + /** + * Get all items matching a filter + * + * @param filter PocketBase filter expression + * @return List of items matching the filter + */ + List getAllWhere(String filter); } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseAltRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseAltRepository.java deleted file mode 100644 index 6ebf307..0000000 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseAltRepository.java +++ /dev/null @@ -1,257 +0,0 @@ -package org.woftnw.dreamvisitor.data.repository; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; - -import org.woftnw.dreamvisitor.pb.PocketBase; - -import java.io.IOException; -import java.time.OffsetDateTime; -import java.time.format.DateTimeFormatter; -import java.util.*; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; - -/** - * PocketBase implementation of the AltRepository interface - */ -public class PocketBaseAltRepository implements AltRepository { - private static final Logger LOGGER = Logger.getLogger(PocketBaseAltRepository.class.getName()); - private static final String COLLECTION_NAME = "user_alts"; - private final PocketBase pocketBase; - private final Gson gson; - private final UserRepository userRepository; - - /** - * Constructor for PocketBaseAltRepository - * - * @param pocketBase PocketBase client - * @param userRepository User repository for parent relationship - */ - public PocketBaseAltRepository(PocketBase pocketBase, UserRepository userRepository) { - this.pocketBase = pocketBase; - this.gson = new Gson(); - this.userRepository = userRepository; - } - - @Override - public Optional findById(String id) { - try { - JsonObject record = pocketBase.getRecord(COLLECTION_NAME, id, null, null); - return Optional.of(mapToAlt(record)); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error finding alt by ID: " + id, e); - return Optional.empty(); - } - } - - @Override - public List findByParentId(String parentId) { - try { - String filter = "parent = '" + parentId + "'"; - List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, filter, null, null); - return records.stream() - .map(this::mapToAlt) - .collect(Collectors.toList()); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error finding alts by parent ID: " + parentId, e); - return Collections.emptyList(); - } - } - - @Override - public Optional findByDiscordId(String discordId) { - try { - String filter = "discord_id = '" + discordId + "'"; - JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); - return Optional.of(mapToAlt(record)); - } catch (IOException e) { - LOGGER.log(Level.FINE, "No alt found with Discord ID: " + discordId); - return Optional.empty(); - } - } - - @Override - public Optional findBySnowflakeId(Long snowflakeId) { - return findByDiscordId(snowflakeId.toString()); - } - - @Override - public Optional findByDiscordName(String discordName) { - try { - String filter = "discord_name = '" + discordName + "'"; - JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); - return Optional.of(mapToAlt(record)); - } catch (IOException e) { - LOGGER.log(Level.FINE, "No alt found with Discord name: " + discordName); - return Optional.empty(); - } - } - - @Override - public List findAll() { - try { - List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, null, null, null); - return records.stream() - .map(this::mapToAlt) - .collect(Collectors.toList()); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error retrieving all alts", e); - return Collections.emptyList(); - } - } - - @Override - public Alt save(Alt alt) { - try { - JsonObject altData = mapToJsonObject(alt); - - if (alt.getId() != null && !alt.getId().isEmpty()) { - // Update existing alt - JsonObject updatedRecord = pocketBase.updateRecord(COLLECTION_NAME, alt.getId(), altData, null, null); - return mapToAlt(updatedRecord); - } else { - // Create new alt - JsonObject newRecord = pocketBase.createRecord(COLLECTION_NAME, altData, null, null); - return mapToAlt(newRecord); - } - } catch (IOException e) { - LOGGER.log(Level.SEVERE, "Error saving alt: " + alt.getDiscord_name(), e); - throw new RuntimeException("Failed to save alt", e); - } - } - - @Override - public void delete(Alt alt) { - if (alt.getId() != null) { - deleteById(alt.getId()); - } - } - - @Override - public void deleteById(String id) { - try { - pocketBase.deleteRecord(COLLECTION_NAME, id); - } catch (IOException e) { - LOGGER.log(Level.SEVERE, "Error deleting alt with ID: " + id, e); - throw new RuntimeException("Failed to delete alt", e); - } - } - - @Override - public List getAllWhere(String filter) { - try { - List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, filter, null, null); - return records.stream() - .map(this::mapToAlt) - .collect(Collectors.toList()); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error retrieving alts with filter: " + filter, e); - return Collections.emptyList(); - } - } - - /** - * Convert a JsonObject from PocketBase to an Alt object - * - * @param json JsonObject from PocketBase API - * @return Mapped Alt object - */ - private Alt mapToAlt(JsonObject json) { - Alt alt = new Alt(); - - alt.setId(getStringOrNull(json, "id")); - alt.setCollectionId(getStringOrNull(json, "collectionId")); - alt.setCollectionName(getStringOrNull(json, "collectionName")); - - alt.setParent(getStringOrNull(json, "parent")); - alt.setDiscord_name(getStringOrNull(json, "discord_name")); - alt.setDiscord_id(getStringOrNull(json, "discord_id")); - - // Handle snowflake ID - String discordId = getStringOrNull(json, "discord_id"); - if (discordId != null) { - try { - alt.setSnowflakeId(Long.parseLong(discordId)); - } catch (NumberFormatException e) { - LOGGER.warning("Discord ID is not a valid snowflake: " + discordId); - } - } - - // Parse datetime fields - alt.setCreated(getOffsetDateTimeOrNull(json, "created")); - alt.setUpdated(getOffsetDateTimeOrNull(json, "updated")); - - // Load parent relationship if available - String parentId = alt.getParent(); - if (parentId != null && userRepository != null) { - userRepository.findById(parentId).ifPresent(alt::setCachedParent); - } - - return alt; - } - - /** - * Convert an Alt object to a JsonObject for PocketBase - * - * @param alt Alt object to convert - * @return JsonObject for PocketBase API - */ - private JsonObject mapToJsonObject(Alt alt) { - JsonObject json = new JsonObject(); - - // Only include fields that PocketBase expects for updates/creates - if (alt.getParent() != null) - json.addProperty("parent", alt.getParent()); - if (alt.getDiscord_name() != null) - json.addProperty("discord_name", alt.getDiscord_name()); - if (alt.getDiscord_id() != null) - json.addProperty("discord_id", alt.getDiscord_id()); - - return json; - } - - // Helper methods for parsing JSON values - private String getStringOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsString() : null; - } - - private OffsetDateTime getOffsetDateTimeOrNull(JsonObject json, String key) { - if (json.has(key) && !json.get(key).isJsonNull()) { - try { - String dateStr = json.get(key).getAsString(); - - // Check if the string is empty or blank - if (dateStr == null || dateStr.trim().isEmpty()) { - return null; - } - - // Handle PocketBase date format "yyyy-MM-dd HH:mm:ss.SSSZ" - if (dateStr.contains(" ") && !dateStr.contains("T")) { - // Replace space with 'T' to make it ISO-8601 compatible - dateStr = dateStr.replace(" ", "T"); - } - - return OffsetDateTime.parse(dateStr); - } catch (Exception e) { - LOGGER.warning("Failed to parse date: " + json.get(key).getAsString() + " - " + e.getMessage()); - try { - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSZ"); - String dateStr = json.get(key).getAsString(); - if (dateStr == null || dateStr.trim().isEmpty()) { - return null; - } - if (dateStr.endsWith("Z")) { - dateStr = dateStr.substring(0, dateStr.length() - 1) + "+0000"; - } - return OffsetDateTime.parse(dateStr.replace(" ", "T")); - } catch (Exception ex) { - LOGGER.warning("Alternative date parsing also failed: " + ex.getMessage()); - return null; - } - } - } - return null; - } -} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseInfractionRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseInfractionRepository.java deleted file mode 100644 index 29cd616..0000000 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseInfractionRepository.java +++ /dev/null @@ -1,290 +0,0 @@ -package org.woftnw.dreamvisitor.data.repository; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; - -import org.woftnw.dreamvisitor.data.type.DVUser; -import org.woftnw.dreamvisitor.pb.PocketBase; - -import java.io.IOException; -import java.time.OffsetDateTime; -import java.time.format.DateTimeFormatter; -import java.util.*; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; - -/** - * PocketBase implementation of the InfractionRepository interface - */ -public class PocketBaseInfractionRepository implements InfractionRepository { - private static final Logger LOGGER = Logger.getLogger(PocketBaseInfractionRepository.class.getName()); - private static final String COLLECTION_NAME = "infractions"; - private final PocketBase pocketBase; - private final Gson gson; - private final UserRepository userRepository; - - /** - * Constructor for PocketBaseInfractionRepository - * - * @param pocketBase The PocketBase client to use - * @param userRepository The user repository for fetching related users - */ - public PocketBaseInfractionRepository(PocketBase pocketBase, UserRepository userRepository) { - this.pocketBase = pocketBase; - this.gson = new Gson(); - this.userRepository = userRepository; - } - - @Override - public Optional findById(String id) { - try { - JsonObject record = pocketBase.getRecord(COLLECTION_NAME, id, null, null); - return Optional.of(mapToInfraction(record)); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error finding infraction by ID: " + id, e); - return Optional.empty(); - } - } - - @Override - public List findByUser(String userId) { - try { - String filter = "user = '" + userId + "'"; - List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, filter, null, null); - List infractions = records.stream() - .map(this::mapToInfraction) - .collect(Collectors.toList()); - - // Load related users if there are infractions - if (!infractions.isEmpty()) { - loadRelatedUsers(infractions); - } - - return infractions; - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error retrieving infractions for user: " + userId, e); - return Collections.emptyList(); - } - } - - @Override - public List findActiveByUser(String userId) { - try { - String filter = "user = '" + userId + "' && expired = false"; - List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, filter, null, null); - List infractions = records.stream() - .map(this::mapToInfraction) - .collect(Collectors.toList()); - - // Load related users if there are infractions - if (!infractions.isEmpty()) { - loadRelatedUsers(infractions); - } - - return infractions; - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error retrieving active infractions for user: " + userId, e); - return Collections.emptyList(); - } - } - - @Override - public List findAll() { - try { - List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, null, null, null); - return records.stream() - .map(this::mapToInfraction) - .collect(Collectors.toList()); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error retrieving all infractions", e); - return Collections.emptyList(); - } - } - - @Override - public Infraction save(Infraction infraction) { - try { - JsonObject infractionData = mapToJsonObject(infraction); - - if (infraction.getId() != null && !infraction.getId().isEmpty()) { - // Update existing infraction - JsonObject updatedRecord = pocketBase.updateRecord(COLLECTION_NAME, infraction.getId(), infractionData, null, - null); - return mapToInfraction(updatedRecord); - } else { - // Create new infraction - JsonObject newRecord = pocketBase.createRecord(COLLECTION_NAME, infractionData, null, null); - return mapToInfraction(newRecord); - } - } catch (IOException e) { - LOGGER.log(Level.SEVERE, "Error saving infraction: " + infraction.getId(), e); - throw new RuntimeException("Failed to save infraction", e); - } - } - - @Override - public void delete(Infraction infraction) { - if (infraction.getId() != null) { - deleteById(infraction.getId()); - } - } - - @Override - public void deleteById(String id) { - try { - pocketBase.deleteRecord(COLLECTION_NAME, id); - } catch (IOException e) { - LOGGER.log(Level.SEVERE, "Error deleting infraction with ID: " + id, e); - throw new RuntimeException("Failed to delete infraction", e); - } - } - - @Override - public List getAllWhere(String filter) { - try { - List records = pocketBase.getFullList(COLLECTION_NAME, 500, filter, null, null, null); - return records.stream() - .map(this::mapToInfraction) - .collect(Collectors.toList()); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error retrieving infractions with filter: " + filter, e); - return Collections.emptyList(); - } - } - - @Override - public List loadRelatedUsers(List infractions) { - // Get unique user IDs - Set userIds = infractions.stream() - .map(Infraction::getUser) - .filter(Objects::nonNull) - .collect(Collectors.toSet()); - - // Fetch all users in one go - Map userMap = new HashMap<>(); - for (String userId : userIds) { - userRepository.findById(userId).ifPresent(user -> userMap.put(userId, user)); - } - - // Set cached users - for (Infraction infraction : infractions) { - if (infraction.getUser() != null && userMap.containsKey(infraction.getUser())) { - infraction.setCachedUser(userMap.get(infraction.getUser())); - } - } - - return infractions; - } - - /** - * Convert a JsonObject from PocketBase to an Infraction object - * - * @param json JsonObject from PocketBase API - * @return Mapped Infraction object - */ - private Infraction mapToInfraction(JsonObject json) { - Infraction infraction = new Infraction(); - - infraction.setId(getStringOrNull(json, "id")); - infraction.setCollectionId(getStringOrNull(json, "collectionId")); - infraction.setCollectionName(getStringOrNull(json, "collectionName")); - - infraction.setReason(getStringOrNull(json, "reason")); - infraction.setSend_warning(getBooleanOrNull(json, "send_warning")); - infraction.setExpired(getBooleanOrNull(json, "expired")); - infraction.setValue(getIntOrNull(json, "value")); - infraction.setUser(getStringOrNull(json, "user")); - - infraction.setCreated(getOffsetDateTimeOrNull(json, "created")); - infraction.setUpdated(getOffsetDateTimeOrNull(json, "updated")); - - return infraction; - } - - /** - * Convert an Infraction object to a JsonObject for PocketBase - * - * @param infraction Infraction object to convert - * @return JsonObject for PocketBase API - */ - private JsonObject mapToJsonObject(Infraction infraction) { - JsonObject json = new JsonObject(); - - // Only include fields that PocketBase expects for updates/creates - if (infraction.getReason() != null) - json.addProperty("reason", infraction.getReason()); - if (infraction.getSend_warning() != null) - json.addProperty("send_warning", infraction.getSend_warning()); - if (infraction.getExpired() != null) - json.addProperty("expired", infraction.getExpired()); - if (infraction.getValue() != null) - json.addProperty("value", infraction.getValue()); - if (infraction.getUser() != null) - json.addProperty("user", infraction.getUser()); - - return json; - } - - // Helper methods for extracting values from JsonObject - private String getStringOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsString() : null; - } - - private Integer getIntOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsInt() : null; - } - - private Boolean getBooleanOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsBoolean() : null; - } - - private OffsetDateTime getOffsetDateTimeOrNull(JsonObject json, String key) { - if (json.has(key) && !json.get(key).isJsonNull()) { - try { - String dateStr = json.get(key).getAsString(); - - // Check if the string is empty or blank - if (dateStr == null || dateStr.trim().isEmpty()) { - return null; - } - - // Handle PocketBase date format "yyyy-MM-dd HH:mm:ss.SSSZ" - if (dateStr.contains(" ") && !dateStr.contains("T")) { - // Replace space with 'T' to make it ISO-8601 compatible - dateStr = dateStr.replace(" ", "T"); - } - - return OffsetDateTime.parse(dateStr); - } catch (Exception e) { - LOGGER.warning("Failed to parse date: " + json.get(key).getAsString() + " - " + e.getMessage()); - - // Try alternative parsing with explicit formatter - try { - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSZ"); - String dateStr = json.get(key).getAsString(); - - // Check if the string is empty or blank - if (dateStr == null || dateStr.trim().isEmpty()) { - return null; - } - - // Convert to ISO format for parsing - if (dateStr.endsWith("Z")) { - dateStr = dateStr.substring(0, dateStr.length() - 1) + "+0000"; - } - - return OffsetDateTime.parse(dateStr.replace(" ", "T")); - } catch (Exception ex) { - LOGGER.warning("Alternative date parsing also failed: " + ex.getMessage()); - return null; - } - } - } - return null; - } - - private String formatDateTime(OffsetDateTime dateTime) { - return dateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); - } -} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseItemRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseItemRepository.java index 63a6599..6ee43e5 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseItemRepository.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseItemRepository.java @@ -20,308 +20,308 @@ * PocketBase implementation of the ItemRepository interface */ public class PocketBaseItemRepository implements ItemRepository { - private static final Logger LOGGER = Logger.getLogger(PocketBaseItemRepository.class.getName()); - private static final String COLLECTION_NAME = "items"; - private final PocketBase pocketBase; - private final Gson gson; - - /** - * Constructor for PocketBaseItemRepository - * - * @param pocketBase The PocketBase client to use - */ - public PocketBaseItemRepository(PocketBase pocketBase) { - this.pocketBase = pocketBase; - this.gson = new Gson(); - } - - @Override - public Optional findById(String id) { - try { - JsonObject record = pocketBase.getRecord(COLLECTION_NAME, id, null, null); - return Optional.of(mapToItem(record)); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error finding item by ID: " + id, e); - return Optional.empty(); + private static final Logger LOGGER = Logger.getLogger(PocketBaseItemRepository.class.getName()); + private static final String COLLECTION_NAME = "items"; + private final PocketBase pocketBase; + private final Gson gson; + + /** + * Constructor for PocketBaseItemRepository + * + * @param pocketBase The PocketBase client to use + */ + public PocketBaseItemRepository(PocketBase pocketBase) { + this.pocketBase = pocketBase; + this.gson = new Gson(); } - } - - @Override - public Optional findByName(String name) { - try { - String filter = "name = '" + name + "'"; - JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); - return Optional.of(mapToItem(record)); - } catch (IOException e) { - LOGGER.log(Level.FINE, "No item found with name: " + name); - return Optional.empty(); - } - } - - @Override - public List findAll() { - try { - List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, null, null, null); - return records.stream() - .map(this::mapToItem) - .collect(Collectors.toList()); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error retrieving all items", e); - return Collections.emptyList(); - } - } - - @Override - public List findAllEnabled() { - try { - String filter = "enabled = true"; - List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, filter, null, null); - return records.stream() - .map(this::mapToItem) - .collect(Collectors.toList()); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error retrieving enabled items", e); - return Collections.emptyList(); - } - } - - @Override - public Item save(Item item) { - try { - JsonObject itemData = mapToJsonObject(item); - - if (item.getId() != null && !item.getId().isEmpty()) { - // Update existing item - JsonObject updatedRecord = pocketBase.updateRecord(COLLECTION_NAME, item.getId(), itemData, null, null); - return mapToItem(updatedRecord); - } else { - // Create new item - JsonObject newRecord = pocketBase.createRecord(COLLECTION_NAME, itemData, null, null); - return mapToItem(newRecord); - } - } catch (IOException e) { - LOGGER.log(Level.SEVERE, "Error saving item: " + item.getName(), e); - throw new RuntimeException("Failed to save item", e); + + @Override + public Optional findById(String id) { + try { + JsonObject record = pocketBase.getRecord(COLLECTION_NAME, id, null, null); + return Optional.of(mapToItem(record)); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error finding item by ID: " + id, e); + return Optional.empty(); + } } - } - @Override - public void delete(Item item) { - if (item.getId() != null) { - deleteById(item.getId()); + @Override + public Optional findByName(String name) { + try { + String filter = "name = '" + name + "'"; + JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); + return Optional.of(mapToItem(record)); + } catch (IOException e) { + LOGGER.log(Level.FINE, "No item found with name: " + name); + return Optional.empty(); + } } - } - - @Override - public void deleteById(String id) { - try { - pocketBase.deleteRecord(COLLECTION_NAME, id); - } catch (IOException e) { - LOGGER.log(Level.SEVERE, "Error deleting item with ID: " + id, e); - throw new RuntimeException("Failed to delete item", e); + + @Override + public List findAll() { + try { + List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, null, null, null); + return records.stream() + .map(this::mapToItem) + .collect(Collectors.toList()); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error retrieving all items", e); + return Collections.emptyList(); + } } - } - - @Override - public List getAllWhere(String filter) { - try { - List records = pocketBase.getFullList(COLLECTION_NAME, 500, filter, null, null, null); - return records.stream() - .map(this::mapToItem) - .collect(Collectors.toList()); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error retrieving items with filter: " + filter, e); - return Collections.emptyList(); + + @Override + public List findAllEnabled() { + try { + String filter = "enabled = true"; + List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, filter, null, null); + return records.stream() + .map(this::mapToItem) + .collect(Collectors.toList()); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error retrieving enabled items", e); + return Collections.emptyList(); + } } - } - - /** - * Convert a JsonObject from PocketBase to an Item object - * - * @param json JsonObject from PocketBase API - * @return Mapped Item object - */ - private Item mapToItem(JsonObject json) { - Item item = new Item(); - - item.setId(getStringOrNull(json, "id")); - item.setCollectionId(getStringOrNull(json, "collectionId")); - item.setCollectionName(getStringOrNull(json, "collectionName")); - - item.setName(getStringOrNull(json, "name")); - item.setDescription(getStringOrNull(json, "description")); - item.setPrice(getDoubleOrNull(json, "price")); - item.setSale_percent(getDoubleOrNull(json, "sale_percent")); - item.setQuantity(getIntOrNull(json, "quantity")); - item.setGifting_enabled(getBooleanOrNull(json, "gifting_enabled")); - item.setEnabled(getBooleanOrNull(json, "enabled")); - item.setMax_allowed(getIntOrNull(json, "max_allowed")); - item.setUse_disabled(getBooleanOrNull(json, "use_disabled")); - item.setUse_on_purchase(getBooleanOrNull(json, "use_on_purchase")); - - // For JSON fields that could be arrays, use getJsonArrayAsString - item.setOn_use_groups_add(getJsonArrayAsString(json, "on_use_groups_add")); - item.setOn_use_groups_remove(getJsonArrayAsString(json, "on_use_groups_remove")); - item.setOn_use_roles_add(getJsonArrayAsString(json, "on_use_roles_add")); - item.setOn_use_roles_remove(getJsonArrayAsString(json, "on_use_roles_remove")); - item.setOn_use_console_commands(getJsonArrayAsString(json, "on_use_console_commands")); - - item.setCreated(getOffsetDateTimeOrNull(json, "created")); - item.setUpdated(getOffsetDateTimeOrNull(json, "updated")); - - return item; - } - - /** - * Convert an Item object to a JsonObject for PocketBase - * - * @param item Item object to convert - * @return JsonObject for PocketBase API - */ - private JsonObject mapToJsonObject(Item item) { - JsonObject json = new JsonObject(); - - // Only include fields that PocketBase expects for updates/creates - if (item.getName() != null) - json.addProperty("name", item.getName()); - if (item.getDescription() != null) - json.addProperty("description", item.getDescription()); - - // Always include price even if it's 0.0 - PocketBase requires this field - // Previously we only included it if not null, but 0.0 might still be included - // in the JSON - if (item.getPrice() != null) { - json.addProperty("price", item.getPrice()); - } else { - // Set a default price of 0.0 if null to prevent validation errors - json.addProperty("price", 0.0); + + @Override + public Item save(Item item) { + try { + JsonObject itemData = mapToJsonObject(item); + + if (item.getId() != null && !item.getId().isEmpty()) { + // Update existing item + JsonObject updatedRecord = pocketBase.updateRecord(COLLECTION_NAME, item.getId(), itemData, null, null); + return mapToItem(updatedRecord); + } else { + // Create new item + JsonObject newRecord = pocketBase.createRecord(COLLECTION_NAME, itemData, null, null); + return mapToItem(newRecord); + } + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Error saving item: " + item.getName(), e); + throw new RuntimeException("Failed to save item", e); + } } - // For all other optional fields, only include if not null - if (item.getSale_percent() != null) - json.addProperty("sale_percent", item.getSale_percent()); - if (item.getQuantity() != null) - json.addProperty("quantity", item.getQuantity()); - if (item.getGifting_enabled() != null) - json.addProperty("gifting_enabled", item.getGifting_enabled()); - if (item.getEnabled() != null) - json.addProperty("enabled", item.getEnabled()); - if (item.getMax_allowed() != null) - json.addProperty("max_allowed", item.getMax_allowed()); - if (item.getUse_disabled() != null) - json.addProperty("use_disabled", item.getUse_disabled()); - if (item.getUse_on_purchase() != null) - json.addProperty("use_on_purchase", item.getUse_on_purchase()); - if (item.getOn_use_groups_add() != null) - json.addProperty("on_use_groups_add", item.getOn_use_groups_add()); - if (item.getOn_use_groups_remove() != null) - json.addProperty("on_use_groups_remove", item.getOn_use_groups_remove()); - if (item.getOn_use_roles_add() != null) - json.addProperty("on_use_roles_add", item.getOn_use_roles_add()); - if (item.getOn_use_roles_remove() != null) - json.addProperty("on_use_roles_remove", item.getOn_use_roles_remove()); - if (item.getOn_use_console_commands() != null) - json.addProperty("on_use_console_commands", item.getOn_use_console_commands()); - - return json; - } - - // Helper methods for extracting values from JsonObject - private String getStringOrNull(JsonObject json, String key) { - if (!json.has(key) || json.get(key).isJsonNull()) { - return null; + @Override + public void delete(Item item) { + if (item.getId() != null) { + deleteById(item.getId()); + } } - com.google.gson.JsonElement element = json.get(key); - if (element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) { - return element.getAsString(); - } else { - LOGGER.warning("Field " + key + " is not a string primitive: " + element); - return null; + @Override + public void deleteById(String id) { + try { + pocketBase.deleteRecord(COLLECTION_NAME, id); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Error deleting item with ID: " + id, e); + throw new RuntimeException("Failed to delete item", e); + } } - } - private Integer getIntOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsInt() : null; - } + @Override + public List getAllWhere(String filter) { + try { + List records = pocketBase.getFullList(COLLECTION_NAME, 500, filter, null, null, null); + return records.stream() + .map(this::mapToItem) + .collect(Collectors.toList()); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error retrieving items with filter: " + filter, e); + return Collections.emptyList(); + } + } - private Double getDoubleOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsDouble() : null; - } + /** + * Convert a JsonObject from PocketBase to an Item object + * + * @param json JsonObject from PocketBase API + * @return Mapped Item object + */ + private Item mapToItem(JsonObject json) { + Item item = new Item(); + + item.setId(getStringOrNull(json, "id")); + item.setCollectionId(getStringOrNull(json, "collectionId")); + item.setCollectionName(getStringOrNull(json, "collectionName")); + + item.setName(getStringOrNull(json, "name")); + item.setDescription(getStringOrNull(json, "description")); + item.setPrice(getDoubleOrNull(json, "price")); + item.setSale_percent(getDoubleOrNull(json, "sale_percent")); + item.setQuantity(getIntOrNull(json, "quantity")); + item.setGifting_enabled(getBooleanOrNull(json, "gifting_enabled")); + item.setEnabled(getBooleanOrNull(json, "enabled")); + item.setMax_allowed(getIntOrNull(json, "max_allowed")); + item.setUse_disabled(getBooleanOrNull(json, "use_disabled")); + item.setUse_on_purchase(getBooleanOrNull(json, "use_on_purchase")); + + // For JSON fields that could be arrays, use getJsonArrayAsString + item.setOn_use_groups_add(getJsonArrayAsString(json, "on_use_groups_add")); + item.setOn_use_groups_remove(getJsonArrayAsString(json, "on_use_groups_remove")); + item.setOn_use_roles_add(getJsonArrayAsString(json, "on_use_roles_add")); + item.setOn_use_roles_remove(getJsonArrayAsString(json, "on_use_roles_remove")); + item.setOn_use_console_commands(getJsonArrayAsString(json, "on_use_console_commands")); + + item.setCreated(getOffsetDateTimeOrNull(json, "created")); + item.setUpdated(getOffsetDateTimeOrNull(json, "updated")); + + return item; + } - private Boolean getBooleanOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsBoolean() : null; - } + /** + * Convert an Item object to a JsonObject for PocketBase + * + * @param item Item object to convert + * @return JsonObject for PocketBase API + */ + private JsonObject mapToJsonObject(Item item) { + JsonObject json = new JsonObject(); + + // Only include fields that PocketBase expects for updates/creates + if (item.getName() != null) + json.addProperty("name", item.getName()); + if (item.getDescription() != null) + json.addProperty("description", item.getDescription()); + + // Always include price even if it's 0.0 - PocketBase requires this field + // Previously we only included it if not null, but 0.0 might still be included + // in the JSON + if (item.getPrice() != null) { + json.addProperty("price", item.getPrice()); + } else { + // Set a default price of 0.0 if null to prevent validation errors + json.addProperty("price", 0.0); + } - private OffsetDateTime getOffsetDateTimeOrNull(JsonObject json, String key) { - if (json.has(key) && !json.get(key).isJsonNull()) { - try { - String dateStr = json.get(key).getAsString(); + // For all other optional fields, only include if not null + if (item.getSale_percent() != null) + json.addProperty("sale_percent", item.getSale_percent()); + if (item.getQuantity() != null) + json.addProperty("quantity", item.getQuantity()); + if (item.getGifting_enabled() != null) + json.addProperty("gifting_enabled", item.getGifting_enabled()); + if (item.getEnabled() != null) + json.addProperty("enabled", item.getEnabled()); + if (item.getMax_allowed() != null) + json.addProperty("max_allowed", item.getMax_allowed()); + if (item.getUse_disabled() != null) + json.addProperty("use_disabled", item.getUse_disabled()); + if (item.getUse_on_purchase() != null) + json.addProperty("use_on_purchase", item.getUse_on_purchase()); + if (item.getOn_use_groups_add() != null) + json.addProperty("on_use_groups_add", item.getOn_use_groups_add()); + if (item.getOn_use_groups_remove() != null) + json.addProperty("on_use_groups_remove", item.getOn_use_groups_remove()); + if (item.getOn_use_roles_add() != null) + json.addProperty("on_use_roles_add", item.getOn_use_roles_add()); + if (item.getOn_use_roles_remove() != null) + json.addProperty("on_use_roles_remove", item.getOn_use_roles_remove()); + if (item.getOn_use_console_commands() != null) + json.addProperty("on_use_console_commands", item.getOn_use_console_commands()); + + return json; + } - // Check if the string is empty or blank - if (dateStr == null || dateStr.trim().isEmpty()) { - return null; + // Helper methods for extracting values from JsonObject + private String getStringOrNull(JsonObject json, String key) { + if (!json.has(key) || json.get(key).isJsonNull()) { + return null; } - // Handle PocketBase date format "yyyy-MM-dd HH:mm:ss.SSSZ" - if (dateStr.contains(" ") && !dateStr.contains("T")) { - // Replace space with 'T' to make it ISO-8601 compatible - dateStr = dateStr.replace(" ", "T"); + com.google.gson.JsonElement element = json.get(key); + if (element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) { + return element.getAsString(); + } else { + LOGGER.warning("Field " + key + " is not a string primitive: " + element); + return null; } + } - return OffsetDateTime.parse(dateStr); - } catch (Exception e) { - LOGGER.warning("Failed to parse date: " + json.get(key).getAsString() + " - " + e.getMessage()); - - // Try alternative parsing with explicit formatter - try { - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSZ"); - String dateStr = json.get(key).getAsString(); + private Integer getIntOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsInt() : null; + } - // Check if the string is empty or blank - if (dateStr == null || dateStr.trim().isEmpty()) { - return null; - } + private Double getDoubleOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsDouble() : null; + } - // Convert to ISO format for parsing - if (dateStr.endsWith("Z")) { - dateStr = dateStr.substring(0, dateStr.length() - 1) + "+0000"; - } + private Boolean getBooleanOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsBoolean() : null; + } - return OffsetDateTime.parse(dateStr.replace(" ", "T")); - } catch (Exception ex) { - LOGGER.warning("Alternative date parsing also failed: " + ex.getMessage()); - return null; + private OffsetDateTime getOffsetDateTimeOrNull(JsonObject json, String key) { + if (json.has(key) && !json.get(key).isJsonNull()) { + try { + String dateStr = json.get(key).getAsString(); + + // Check if the string is empty or blank + if (dateStr == null || dateStr.trim().isEmpty()) { + return null; + } + + // Handle PocketBase date format "yyyy-MM-dd HH:mm:ss.SSSZ" + if (dateStr.contains(" ") && !dateStr.contains("T")) { + // Replace space with 'T' to make it ISO-8601 compatible + dateStr = dateStr.replace(" ", "T"); + } + + return OffsetDateTime.parse(dateStr); + } catch (Exception e) { + LOGGER.warning("Failed to parse date: " + json.get(key).getAsString() + " - " + e.getMessage()); + + // Try alternative parsing with explicit formatter + try { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSZ"); + String dateStr = json.get(key).getAsString(); + + // Check if the string is empty or blank + if (dateStr == null || dateStr.trim().isEmpty()) { + return null; + } + + // Convert to ISO format for parsing + if (dateStr.endsWith("Z")) { + dateStr = dateStr.substring(0, dateStr.length() - 1) + "+0000"; + } + + return OffsetDateTime.parse(dateStr.replace(" ", "T")); + } catch (Exception ex) { + LOGGER.warning("Alternative date parsing also failed: " + ex.getMessage()); + return null; + } + } } - } + return null; } - return null; - } - - private String formatDateTime(OffsetDateTime dateTime) { - return dateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); - } - - /** - * Safely get a JSON array field as a JSON string - * Handles cases where the field could be a string, array, or other type - */ - private String getJsonArrayAsString(JsonObject json, String key) { - if (!json.has(key) || json.get(key).isJsonNull()) { - return null; + + private String formatDateTime(OffsetDateTime dateTime) { + return dateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); } - com.google.gson.JsonElement element = json.get(key); - if (element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) { - // It's already a string, return it directly - return element.getAsString(); - } else if (element.isJsonArray()) { - // It's an array, convert to a well-formatted JSON string - return element.toString(); - } else { - // For any other type, convert to string representation - LOGGER.warning("Field " + key + " is not a string or array: " + element); - return element.toString(); + /** + * Safely get a JSON array field as a JSON string + * Handles cases where the field could be a string, array, or other type + */ + private String getJsonArrayAsString(JsonObject json, String key) { + if (!json.has(key) || json.get(key).isJsonNull()) { + return null; + } + + com.google.gson.JsonElement element = json.get(key); + if (element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) { + // It's already a string, return it directly + return element.getAsString(); + } else if (element.isJsonArray()) { + // It's an array, convert to a well-formatted JSON string + return element.toString(); + } else { + // For any other type, convert to string representation + LOGGER.warning("Field " + key + " is not a string or array: " + element); + return element.toString(); + } } - } } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserInventoryRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserInventoryRepository.java index 7bd0a8d..0c96a57 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserInventoryRepository.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserInventoryRepository.java @@ -20,300 +20,300 @@ * PocketBase implementation of the UserInventoryRepository interface */ public class PocketBaseUserInventoryRepository implements UserInventoryRepository { - private static final Logger LOGGER = Logger.getLogger(PocketBaseUserInventoryRepository.class.getName()); - private static final String COLLECTION_NAME = "user_inventory"; - private final PocketBase pocketBase; - private final Gson gson; - private final UserRepository userRepository; - private final ItemRepository itemRepository; - - /** - * Constructor for PocketBaseUserInventoryRepository - * - * @param pocketBase The PocketBase client to use - * @param userRepository The user repository for fetching related users - * @param itemRepository The item repository for fetching related items - */ - public PocketBaseUserInventoryRepository(PocketBase pocketBase, UserRepository userRepository, - ItemRepository itemRepository) { - this.pocketBase = pocketBase; - this.gson = new Gson(); - this.userRepository = userRepository; - this.itemRepository = itemRepository; - } - - @Override - public Optional findById(String id) { - try { - JsonObject record = pocketBase.getRecord(COLLECTION_NAME, id, null, null); - return Optional.of(mapToUserInventory(record)); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error finding user inventory by ID: " + id, e); - return Optional.empty(); + private static final Logger LOGGER = Logger.getLogger(PocketBaseUserInventoryRepository.class.getName()); + private static final String COLLECTION_NAME = "user_inventory"; + private final PocketBase pocketBase; + private final Gson gson; + private final UserRepository userRepository; + private final ItemRepository itemRepository; + + /** + * Constructor for PocketBaseUserInventoryRepository + * + * @param pocketBase The PocketBase client to use + * @param userRepository The user repository for fetching related users + * @param itemRepository The item repository for fetching related items + */ + public PocketBaseUserInventoryRepository(PocketBase pocketBase, UserRepository userRepository, + ItemRepository itemRepository) { + this.pocketBase = pocketBase; + this.gson = new Gson(); + this.userRepository = userRepository; + this.itemRepository = itemRepository; } - } - - @Override - public List findByUser(String userId) { - try { - String filter = "user = '" + userId + "'"; - List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, filter, null, null); - List inventoryEntries = records.stream() - .map(this::mapToUserInventory) - .collect(Collectors.toList()); - - // Load related items if there are inventory entries - if (!inventoryEntries.isEmpty()) { - loadRelatedItems(inventoryEntries); - } - - return inventoryEntries; - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error retrieving user inventory for user: " + userId, e); - return Collections.emptyList(); - } - } - - @Override - public Optional findByUserAndItem(String userId, String itemId) { - try { - String filter = "user = '" + userId + "' && item = '" + itemId + "'"; - JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); - UserInventory inventory = mapToUserInventory(record); - - // Load related item and user - if (inventory.getItem() != null) { - itemRepository.findById(inventory.getItem()).ifPresent(inventory::setCachedItem); - } - if (inventory.getUser() != null) { - userRepository.findById(inventory.getUser()).ifPresent(inventory::setCachedUser); - } - - return Optional.of(inventory); - } catch (IOException e) { - LOGGER.log(Level.FINE, "No inventory entry found for user: " + userId + " and item: " + itemId); - return Optional.empty(); - } - } - - @Override - public List findAll() { - try { - List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, null, null, null); - return records.stream() - .map(this::mapToUserInventory) - .collect(Collectors.toList()); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error retrieving all user inventory entries", e); - return Collections.emptyList(); + + @Override + public Optional findById(String id) { + try { + JsonObject record = pocketBase.getRecord(COLLECTION_NAME, id, null, null); + return Optional.of(mapToUserInventory(record)); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error finding user inventory by ID: " + id, e); + return Optional.empty(); + } } - } - - @Override - public UserInventory save(UserInventory userInventory) { - try { - JsonObject inventoryData = mapToJsonObject(userInventory); - - if (userInventory.getId() != null && !userInventory.getId().isEmpty()) { - // Update existing inventory entry - JsonObject updatedRecord = pocketBase.updateRecord(COLLECTION_NAME, userInventory.getId(), inventoryData, null, - null); - return mapToUserInventory(updatedRecord); - } else { - // Create new inventory entry - JsonObject newRecord = pocketBase.createRecord(COLLECTION_NAME, inventoryData, null, null); - return mapToUserInventory(newRecord); - } - } catch (IOException e) { - LOGGER.log(Level.SEVERE, "Error saving user inventory entry: " + userInventory.getId(), e); - throw new RuntimeException("Failed to save user inventory entry", e); + + @Override + public List findByUser(String userId) { + try { + String filter = "user = '" + userId + "'"; + List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, filter, null, null); + List inventoryEntries = records.stream() + .map(this::mapToUserInventory) + .collect(Collectors.toList()); + + // Load related items if there are inventory entries + if (!inventoryEntries.isEmpty()) { + loadRelatedItems(inventoryEntries); + } + + return inventoryEntries; + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error retrieving user inventory for user: " + userId, e); + return Collections.emptyList(); + } } - } - @Override - public void delete(UserInventory userInventory) { - if (userInventory.getId() != null) { - deleteById(userInventory.getId()); + @Override + public Optional findByUserAndItem(String userId, String itemId) { + try { + String filter = "user = '" + userId + "' && item = '" + itemId + "'"; + JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); + UserInventory inventory = mapToUserInventory(record); + + // Load related item and user + if (inventory.getItem() != null) { + itemRepository.findById(inventory.getItem()).ifPresent(inventory::setCachedItem); + } + if (inventory.getUser() != null) { + userRepository.findById(inventory.getUser()).ifPresent(inventory::setCachedUser); + } + + return Optional.of(inventory); + } catch (IOException e) { + LOGGER.log(Level.FINE, "No inventory entry found for user: " + userId + " and item: " + itemId); + return Optional.empty(); + } } - } - - @Override - public void deleteById(String id) { - try { - pocketBase.deleteRecord(COLLECTION_NAME, id); - } catch (IOException e) { - LOGGER.log(Level.SEVERE, "Error deleting user inventory entry with ID: " + id, e); - throw new RuntimeException("Failed to delete user inventory entry", e); + + @Override + public List findAll() { + try { + List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, null, null, null); + return records.stream() + .map(this::mapToUserInventory) + .collect(Collectors.toList()); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error retrieving all user inventory entries", e); + return Collections.emptyList(); + } } - } - - @Override - public List getAllWhere(String filter) { - try { - List records = pocketBase.getFullList(COLLECTION_NAME, 500, filter, null, null, null); - return records.stream() - .map(this::mapToUserInventory) - .collect(Collectors.toList()); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error retrieving user inventory entries with filter: " + filter, e); - return Collections.emptyList(); + + @Override + public UserInventory save(UserInventory userInventory) { + try { + JsonObject inventoryData = mapToJsonObject(userInventory); + + if (userInventory.getId() != null && !userInventory.getId().isEmpty()) { + // Update existing inventory entry + JsonObject updatedRecord = pocketBase.updateRecord(COLLECTION_NAME, userInventory.getId(), inventoryData, null, + null); + return mapToUserInventory(updatedRecord); + } else { + // Create new inventory entry + JsonObject newRecord = pocketBase.createRecord(COLLECTION_NAME, inventoryData, null, null); + return mapToUserInventory(newRecord); + } + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Error saving user inventory entry: " + userInventory.getId(), e); + throw new RuntimeException("Failed to save user inventory entry", e); + } } - } - - @Override - public List loadRelatedItems(List inventoryEntries) { - // Get unique item IDs - Set itemIds = inventoryEntries.stream() - .map(UserInventory::getItem) - .filter(Objects::nonNull) - .collect(Collectors.toSet()); - - // Fetch all items in one go - Map itemMap = new HashMap<>(); - for (String itemId : itemIds) { - itemRepository.findById(itemId).ifPresent(item -> itemMap.put(itemId, item)); + + @Override + public void delete(UserInventory userInventory) { + if (userInventory.getId() != null) { + deleteById(userInventory.getId()); + } } - // Set cached items - for (UserInventory entry : inventoryEntries) { - if (entry.getItem() != null && itemMap.containsKey(entry.getItem())) { - entry.setCachedItem(itemMap.get(entry.getItem())); - } + @Override + public void deleteById(String id) { + try { + pocketBase.deleteRecord(COLLECTION_NAME, id); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Error deleting user inventory entry with ID: " + id, e); + throw new RuntimeException("Failed to delete user inventory entry", e); + } } - return inventoryEntries; - } - - @Override - public List loadRelatedUsers(List inventoryEntries) { - // Get unique user IDs - Set userIds = inventoryEntries.stream() - .map(UserInventory::getUser) - .filter(Objects::nonNull) - .collect(Collectors.toSet()); - - // Fetch all users in one go - Map userMap = new HashMap<>(); - for (String userId : userIds) { - userRepository.findById(userId).ifPresent(user -> userMap.put(userId, user)); + @Override + public List getAllWhere(String filter) { + try { + List records = pocketBase.getFullList(COLLECTION_NAME, 500, filter, null, null, null); + return records.stream() + .map(this::mapToUserInventory) + .collect(Collectors.toList()); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error retrieving user inventory entries with filter: " + filter, e); + return Collections.emptyList(); + } } - // Set cached users - for (UserInventory entry : inventoryEntries) { - if (entry.getUser() != null && userMap.containsKey(entry.getUser())) { - entry.setCachedUser(userMap.get(entry.getUser())); - } + @Override + public List loadRelatedItems(List inventoryEntries) { + // Get unique item IDs + Set itemIds = inventoryEntries.stream() + .map(UserInventory::getItem) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // Fetch all items in one go + Map itemMap = new HashMap<>(); + for (String itemId : itemIds) { + itemRepository.findById(itemId).ifPresent(item -> itemMap.put(itemId, item)); + } + + // Set cached items + for (UserInventory entry : inventoryEntries) { + if (entry.getItem() != null && itemMap.containsKey(entry.getItem())) { + entry.setCachedItem(itemMap.get(entry.getItem())); + } + } + + return inventoryEntries; } - return inventoryEntries; - } - - /** - * Convert a JsonObject from PocketBase to a UserInventory object - * - * @param json JsonObject from PocketBase API - * @return Mapped UserInventory object - */ - private UserInventory mapToUserInventory(JsonObject json) { - UserInventory inventory = new UserInventory(); - - inventory.setId(getStringOrNull(json, "id")); - inventory.setCollectionId(getStringOrNull(json, "collectionId")); - inventory.setCollectionName(getStringOrNull(json, "collectionName")); - - inventory.setUser(getStringOrNull(json, "user")); - inventory.setItem(getStringOrNull(json, "item")); - inventory.setQuantity(getIntOrNull(json, "quantity")); - - inventory.setCreated(getOffsetDateTimeOrNull(json, "created")); - inventory.setUpdated(getOffsetDateTimeOrNull(json, "updated")); - - return inventory; - } - - /** - * Convert a UserInventory object to a JsonObject for PocketBase - * - * @param inventory UserInventory object to convert - * @return JsonObject for PocketBase API - */ - private JsonObject mapToJsonObject(UserInventory inventory) { - JsonObject json = new JsonObject(); - - // Only include fields that PocketBase expects for updates/creates - if (inventory.getUser() != null) - json.addProperty("user", inventory.getUser()); - if (inventory.getItem() != null) - json.addProperty("item", inventory.getItem()); - if (inventory.getQuantity() != null) - json.addProperty("quantity", inventory.getQuantity()); - - return json; - } - - // Helper methods for extracting values from JsonObject - private String getStringOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsString() : null; - } - - private Integer getIntOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsInt() : null; - } - - private Double getDoubleOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsDouble() : null; - } - - private Boolean getBooleanOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsBoolean() : null; - } - - private OffsetDateTime getOffsetDateTimeOrNull(JsonObject json, String key) { - if (json.has(key) && !json.get(key).isJsonNull()) { - try { - String dateStr = json.get(key).getAsString(); - - // Check if the string is empty or blank - if (dateStr == null || dateStr.trim().isEmpty()) { - return null; + @Override + public List loadRelatedUsers(List inventoryEntries) { + // Get unique user IDs + Set userIds = inventoryEntries.stream() + .map(UserInventory::getUser) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // Fetch all users in one go + Map userMap = new HashMap<>(); + for (String userId : userIds) { + userRepository.findById(userId).ifPresent(user -> userMap.put(userId, user)); } - // Handle PocketBase date format "yyyy-MM-dd HH:mm:ss.SSSZ" - if (dateStr.contains(" ") && !dateStr.contains("T")) { - // Replace space with 'T' to make it ISO-8601 compatible - dateStr = dateStr.replace(" ", "T"); + // Set cached users + for (UserInventory entry : inventoryEntries) { + if (entry.getUser() != null && userMap.containsKey(entry.getUser())) { + entry.setCachedUser(userMap.get(entry.getUser())); + } } - return OffsetDateTime.parse(dateStr); - } catch (Exception e) { - LOGGER.warning("Failed to parse date: " + json.get(key).getAsString() + " - " + e.getMessage()); + return inventoryEntries; + } - // Try alternative parsing with explicit formatter - try { - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSZ"); - String dateStr = json.get(key).getAsString(); - - // Check if the string is empty or blank - if (dateStr == null || dateStr.trim().isEmpty()) { - return null; - } - - // Convert to ISO format for parsing - if (dateStr.endsWith("Z")) { - dateStr = dateStr.substring(0, dateStr.length() - 1) + "+0000"; - } - - return OffsetDateTime.parse(dateStr.replace(" ", "T")); - } catch (Exception ex) { - LOGGER.warning("Alternative date parsing also failed: " + ex.getMessage()); - return null; + /** + * Convert a JsonObject from PocketBase to a UserInventory object + * + * @param json JsonObject from PocketBase API + * @return Mapped UserInventory object + */ + private UserInventory mapToUserInventory(JsonObject json) { + UserInventory inventory = new UserInventory(); + + inventory.setId(getStringOrNull(json, "id")); + inventory.setCollectionId(getStringOrNull(json, "collectionId")); + inventory.setCollectionName(getStringOrNull(json, "collectionName")); + + inventory.setUser(getStringOrNull(json, "user")); + inventory.setItem(getStringOrNull(json, "item")); + inventory.setQuantity(getIntOrNull(json, "quantity")); + + inventory.setCreated(getOffsetDateTimeOrNull(json, "created")); + inventory.setUpdated(getOffsetDateTimeOrNull(json, "updated")); + + return inventory; + } + + /** + * Convert a UserInventory object to a JsonObject for PocketBase + * + * @param inventory UserInventory object to convert + * @return JsonObject for PocketBase API + */ + private JsonObject mapToJsonObject(UserInventory inventory) { + JsonObject json = new JsonObject(); + + // Only include fields that PocketBase expects for updates/creates + if (inventory.getUser() != null) + json.addProperty("user", inventory.getUser()); + if (inventory.getItem() != null) + json.addProperty("item", inventory.getItem()); + if (inventory.getQuantity() != null) + json.addProperty("quantity", inventory.getQuantity()); + + return json; + } + + // Helper methods for extracting values from JsonObject + private String getStringOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsString() : null; + } + + private Integer getIntOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsInt() : null; + } + + private Double getDoubleOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsDouble() : null; + } + + private Boolean getBooleanOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsBoolean() : null; + } + + private OffsetDateTime getOffsetDateTimeOrNull(JsonObject json, String key) { + if (json.has(key) && !json.get(key).isJsonNull()) { + try { + String dateStr = json.get(key).getAsString(); + + // Check if the string is empty or blank + if (dateStr == null || dateStr.trim().isEmpty()) { + return null; + } + + // Handle PocketBase date format "yyyy-MM-dd HH:mm:ss.SSSZ" + if (dateStr.contains(" ") && !dateStr.contains("T")) { + // Replace space with 'T' to make it ISO-8601 compatible + dateStr = dateStr.replace(" ", "T"); + } + + return OffsetDateTime.parse(dateStr); + } catch (Exception e) { + LOGGER.warning("Failed to parse date: " + json.get(key).getAsString() + " - " + e.getMessage()); + + // Try alternative parsing with explicit formatter + try { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSZ"); + String dateStr = json.get(key).getAsString(); + + // Check if the string is empty or blank + if (dateStr == null || dateStr.trim().isEmpty()) { + return null; + } + + // Convert to ISO format for parsing + if (dateStr.endsWith("Z")) { + dateStr = dateStr.substring(0, dateStr.length() - 1) + "+0000"; + } + + return OffsetDateTime.parse(dateStr.replace(" ", "T")); + } catch (Exception ex) { + LOGGER.warning("Alternative date parsing also failed: " + ex.getMessage()); + return null; + } + } } - } + return null; } - return null; - } - private String formatDateTime(OffsetDateTime dateTime) { - return dateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); - } + private String formatDateTime(OffsetDateTime dateTime) { + return dateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); + } } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserRepository.java index ae8e3e3..079265f 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserRepository.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserRepository.java @@ -1,4 +1,5 @@ package org.woftnw.dreamvisitor.data.repository; + import com.google.gson.Gson; import com.google.gson.JsonObject; import com.google.gson.reflect.TypeToken; @@ -22,345 +23,345 @@ * PocketBase implementation of the UserRepository interface */ public class PocketBaseUserRepository implements UserRepository { - private static final Logger LOGGER = Logger.getLogger(PocketBaseUserRepository.class.getName()); - private static final String COLLECTION_NAME = "users"; - private final PocketBase pocketBase; - private final Gson gson; - - /** - * Constructor for PocketBaseUserRepository - * - * @param pocketBase The PocketBase client to use - */ - public PocketBaseUserRepository(PocketBase pocketBase) { - this.pocketBase = pocketBase; - this.gson = new Gson(); - } - - @Override - public Optional findById(String id) { - try { - JsonObject record = pocketBase.getRecord(COLLECTION_NAME, id, null, null); - return Optional.of(mapToUser(record)); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error finding user by ID: " + id, e); - return Optional.empty(); - } - } - - @Override - public Optional findByUuid(UUID mc_uuid) { - try { - String filter = "mc_uuid = '" + mc_uuid.toString() + "'"; - JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); - return Optional.of(mapToUser(record)); - } catch (IOException e) { - LOGGER.log(Level.FINE, "No user found with UUID: " + mc_uuid); - return Optional.empty(); + private static final Logger LOGGER = Logger.getLogger(PocketBaseUserRepository.class.getName()); + private static final String COLLECTION_NAME = "users"; + private final PocketBase pocketBase; + private final Gson gson; + + /** + * Constructor for PocketBaseUserRepository + * + * @param pocketBase The PocketBase client to use + */ + public PocketBaseUserRepository(PocketBase pocketBase) { + this.pocketBase = pocketBase; + this.gson = new Gson(); } - } - - @Override - public Optional findByDiscordId(String discordId) { - try { - String filter = "discord_id = '" + discordId + "'"; - JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); - return Optional.of(mapToUser(record)); - } catch (IOException e) { - LOGGER.log(Level.FINE, "No user found with Discord ID: " + discordId); - return Optional.empty(); + + @Override + public Optional findById(String id) { + try { + JsonObject record = pocketBase.getRecord(COLLECTION_NAME, id, null, null); + return Optional.of(mapToUser(record)); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error finding user by ID: " + id, e); + return Optional.empty(); + } } - } - - @Override - public Optional findBySnowflakeId(Long snowflakeId) { - try { - // First try with the direct snowflake ID - String filter = "discord_id = '" + snowflakeId.toString() + "'"; - LOGGER.info("Searching for user with filter: " + filter); - - try { - JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); - LOGGER.info("User found with snowflake ID: " + snowflakeId); - DVUser user = mapToUser(record); - return Optional.of(user); - } catch (IOException e) { - // First search failed, try with just string comparison if numeric search fails - LOGGER.info("No exact match found, trying alternative search..."); - filter = "discord_id ~ '" + snowflakeId + "'"; + + @Override + public Optional findByUuid(UUID mc_uuid) { try { - JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); - LOGGER.info("User found with partial match: " + record.toString()); - DVUser user = mapToUser(record); - return Optional.of(user); - } catch (IOException e2) { - LOGGER.log(Level.INFO, "No user found with Snowflake ID (partial match): " + snowflakeId); - return Optional.empty(); + String filter = "mc_uuid = '" + mc_uuid.toString() + "'"; + JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); + return Optional.of(mapToUser(record)); + } catch (IOException e) { + LOGGER.log(Level.FINE, "No user found with UUID: " + mc_uuid); + return Optional.empty(); } - } - } catch (Exception e) { - LOGGER.log(Level.WARNING, "Error searching for user with Snowflake ID: " + snowflakeId, e); - return Optional.empty(); } - } - - @Override - public Optional findByMcUsername(String mcUsername) { - try { - String filter = "mc_username = '" + mcUsername + "'"; - JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); - return Optional.of(mapToUser(record)); - } catch (IOException e) { - LOGGER.log(Level.FINE, "No user found with MC username: " + mcUsername); - return Optional.empty(); + + @Override + public Optional findByDiscordId(String discordId) { + try { + String filter = "discord_id = '" + discordId + "'"; + JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); + return Optional.of(mapToUser(record)); + } catch (IOException e) { + LOGGER.log(Level.FINE, "No user found with Discord ID: " + discordId); + return Optional.empty(); + } } - } - - @Override - public List findAll() { - try { - List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, null, null, null); - return records.stream() - .map(this::mapToUser) - .collect(Collectors.toList()); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error retrieving all users", e); - return Collections.emptyList(); + + @Override + public Optional findBySnowflakeId(Long snowflakeId) { + try { + // First try with the direct snowflake ID + String filter = "discord_id = '" + snowflakeId.toString() + "'"; + LOGGER.info("Searching for user with filter: " + filter); + + try { + JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); + LOGGER.info("User found with snowflake ID: " + snowflakeId); + DVUser user = mapToUser(record); + return Optional.of(user); + } catch (IOException e) { + // First search failed, try with just string comparison if numeric search fails + LOGGER.info("No exact match found, trying alternative search..."); + filter = "discord_id ~ '" + snowflakeId + "'"; + try { + JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); + LOGGER.info("User found with partial match: " + record.toString()); + DVUser user = mapToUser(record); + return Optional.of(user); + } catch (IOException e2) { + LOGGER.log(Level.INFO, "No user found with Snowflake ID (partial match): " + snowflakeId); + return Optional.empty(); + } + } + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Error searching for user with Snowflake ID: " + snowflakeId, e); + return Optional.empty(); + } } - } - - @Override - public DVUser save(DVUser user) { - try { - JsonObject userData = mapToJsonObject(user); - - if (user.getId() != null && !user.getId().isEmpty()) { - // Update existing user - JsonObject updatedRecord = pocketBase.updateRecord(COLLECTION_NAME, user.getId(), userData, null, null); - return mapToUser(updatedRecord); - } else { - // Create new user - JsonObject newRecord = pocketBase.createRecord(COLLECTION_NAME, userData, null, null); - return mapToUser(newRecord); - } - } catch (IOException e) { - LOGGER.log(Level.SEVERE, "Error saving user: " + user.getMcUsername(), e); - throw new RuntimeException("Failed to save user", e); + + @Override + public Optional findByMcUsername(String mcUsername) { + try { + String filter = "mc_username = '" + mcUsername + "'"; + JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); + return Optional.of(mapToUser(record)); + } catch (IOException e) { + LOGGER.log(Level.FINE, "No user found with MC username: " + mcUsername); + return Optional.empty(); + } } - } - @Override - public void delete(DVUser user) { - if (user.getId() != null) { - deleteById(user.getId()); + @Override + public List findAll() { + try { + List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, null, null, null); + return records.stream() + .map(this::mapToUser) + .collect(Collectors.toList()); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error retrieving all users", e); + return Collections.emptyList(); + } } - } - - @Override - public void deleteById(String id) { - try { - pocketBase.deleteRecord(COLLECTION_NAME, id); - } catch (IOException e) { - LOGGER.log(Level.SEVERE, "Error deleting user with ID: " + id, e); - throw new RuntimeException("Failed to delete user", e); + + @Override + public DVUser save(DVUser user) { + try { + JsonObject userData = mapToJsonObject(user); + + if (user.getId() != null && !user.getId().isEmpty()) { + // Update existing user + JsonObject updatedRecord = pocketBase.updateRecord(COLLECTION_NAME, user.getId(), userData, null, null); + return mapToUser(updatedRecord); + } else { + // Create new user + JsonObject newRecord = pocketBase.createRecord(COLLECTION_NAME, userData, null, null); + return mapToUser(newRecord); + } + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Error saving user: " + user.getMcUsername(), e); + throw new RuntimeException("Failed to save user", e); + } } - } - - /** - * Convert a JsonObject from PocketBase to a User object - * - * @param json JsonObject from PocketBase API - * @return Mapped User object - */ - private DVUser mapToUser(JsonObject json) { - DVUser user = new DVUser(); - - user.setId(getStringOrNull(json, "id")); - user.setCollectionId(getStringOrNull(json, "collectionId")); - user.setCollectionName(getStringOrNull(json, "collectionName")); - - user.setDiscord_id(getStringOrNull(json, "discord_id")); - user.setDiscord_username(getStringOrNull(json, "discord_username")); - user.setDiscord_img(getStringOrNull(json, "discord_img")); - user.setMcUsername(getStringOrNull(json, "mc_username")); - - if (json.has("mc_uuid") && !json.get("mc_uuid").isJsonNull()) { - try { - user.setMc_uuid(UUID.fromString(UUIDFromater.formatUuid(json.get("mc_uuid").getAsString()))); - } catch (IllegalArgumentException e) { - LOGGER.warning("Invalid UUID format: " + json.get("mc_uuid").getAsString()); - } + + @Override + public void delete(DVUser user) { + if (user.getId() != null) { + deleteById(user.getId()); + } } - if (user.getDiscord_id() != null) { - try { - user.setSnowflakeId(Long.parseLong(user.getDiscord_id())); - } catch (NumberFormatException e) { - LOGGER.warning("Discord ID is not a valid snowflake: " + user.getDiscord_id()); - } + @Override + public void deleteById(String id) { + try { + pocketBase.deleteRecord(COLLECTION_NAME, id); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Error deleting user with ID: " + id, e); + throw new RuntimeException("Failed to delete user", e); + } } - // Parse relation lists - user.setInfractions(getStringListOrEmpty(json, "infractions")); - user.setUsers_home(getStringListOrEmpty(json, "users_home")); - user.setInventory_items(getStringListOrEmpty(json, "inventory_items")); - user.setClaims(getStringListOrEmpty(json, "claims")); - - // Parse numeric fields - user.setClaim_limit(getIntOrNull(json, "claim_limit")); - user.setPlay_time(getIntOrNull(json, "play_time")); - user.setBalance(getDoubleOrNull(json, "balance")); - user.setDaily_streak(getIntOrNull(json, "daily_streak")); - - // Parse boolean fields - user.setIs_suspended(getBooleanOrNull(json, "is_suspended")); - user.setIs_banned(getBooleanOrNull(json, "is_banned")); - - // Parse datetime fields - user.setLast_work(getOffsetDateTimeOrNull(json, "last_work")); - user.setLast_Played(getOffsetDateTimeOrNull(json, "last_played")); - user.setLast_daily(getOffsetDateTimeOrNull(json, "last_daily")); - user.setCreated(getOffsetDateTimeOrNull(json, "created")); - user.setUpdated(getOffsetDateTimeOrNull(json, "updated")); - - return user; - } - - /** - * Convert a User object to a JsonObject for PocketBase - * - * @param user User object to convert - * @return JsonObject for PocketBase API - */ - private JsonObject mapToJsonObject(DVUser user) { - JsonObject json = new JsonObject(); - - // Only include fields that PocketBase expects for updates/creates - if (user.getDiscord_id() != null) - json.addProperty("discord_id", user.getDiscord_id()); - if (user.getDiscord_username() != null) - json.addProperty("discord_username", user.getDiscord_username()); - if (user.getDiscord_img() != null) - json.addProperty("discord_img", user.getDiscord_img()); - if (user.getMcUsername() != null) - json.addProperty("mc_username", user.getMcUsername()); - if (user.getMc_uuid() != null) - json.addProperty("mc_uuid", user.getMc_uuid().toString()); - - // Add numeric fields - if (user.getClaim_limit() != null) - json.addProperty("claim_limit", user.getClaim_limit()); - if (user.getPlay_time() != null) - json.addProperty("play_time", user.getPlay_time()); - if (user.getBalance() != null) - json.addProperty("balance", user.getBalance()); - if (user.getDaily_streak() != null) - json.addProperty("daily_streak", user.getDaily_streak()); - - // Add boolean fields - if (user.getIs_suspended() != null) - json.addProperty("is_suspended", user.getIs_suspended()); - if (user.getIs_banned() != null) - json.addProperty("is_banned", user.getIs_banned()); - - // Format and add datetime fields - if (user.getLast_work() != null) - json.addProperty("last_work", formatDateTime(user.getLast_work())); - if (user.getLast_daily() != null) - json.addProperty("last_daily", formatDateTime(user.getLast_daily())); - - // Add relation fields (these need to be handled separately based on - // PocketBase's expectations) - // For now, we'll just leave them out as they typically require special handling - // TODO:Add relation fields - return json; - } - - private String getStringOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsString() : null; - } - - private Integer getIntOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsInt() : null; - } - - private Double getDoubleOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsDouble() : null; - } - - private Boolean getBooleanOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsBoolean() : null; - } - - private OffsetDateTime getOffsetDateTimeOrNull(JsonObject json, String key) { - if (json.has(key) && !json.get(key).isJsonNull()) { - try { - String dateStr = json.get(key).getAsString(); - - // Check if the string is empty or blank - if (dateStr == null || dateStr.trim().isEmpty()) { - return null; + /** + * Convert a JsonObject from PocketBase to a User object + * + * @param json JsonObject from PocketBase API + * @return Mapped User object + */ + private DVUser mapToUser(JsonObject json) { + DVUser user = new DVUser(); + + user.setId(getStringOrNull(json, "id")); + user.setCollectionId(getStringOrNull(json, "collectionId")); + user.setCollectionName(getStringOrNull(json, "collectionName")); + + user.setDiscord_id(getStringOrNull(json, "discord_id")); + user.setDiscord_username(getStringOrNull(json, "discord_username")); + user.setDiscord_img(getStringOrNull(json, "discord_img")); + user.setMcUsername(getStringOrNull(json, "mc_username")); + + if (json.has("mc_uuid") && !json.get("mc_uuid").isJsonNull()) { + try { + user.setMc_uuid(UUID.fromString(UUIDFromater.formatUuid(json.get("mc_uuid").getAsString()))); + } catch (IllegalArgumentException e) { + LOGGER.warning("Invalid UUID format: " + json.get("mc_uuid").getAsString()); + } } - // Handle PocketBase date format "yyyy-MM-dd HH:mm:ss.SSSZ" - if (dateStr.contains(" ") && !dateStr.contains("T")) { - // Replace space with 'T' to make it ISO-8601 compatible - dateStr = dateStr.replace(" ", "T"); + if (user.getDiscord_id() != null) { + try { + user.setSnowflakeId(Long.parseLong(user.getDiscord_id())); + } catch (NumberFormatException e) { + LOGGER.warning("Discord ID is not a valid snowflake: " + user.getDiscord_id()); + } } - return OffsetDateTime.parse(dateStr); - } catch (Exception e) { - LOGGER.warning("Failed to parse date: " + json.get(key).getAsString() + " - " + e.getMessage()); + // Parse relation lists + user.setInfractions(getStringListOrEmpty(json, "infractions")); + user.setUsers_home(getStringListOrEmpty(json, "users_home")); + user.setInventory_items(getStringListOrEmpty(json, "inventory_items")); + user.setClaims(getStringListOrEmpty(json, "claims")); + + // Parse numeric fields + user.setClaim_limit(getIntOrNull(json, "claim_limit")); + user.setPlay_time(getIntOrNull(json, "play_time")); + user.setBalance(getDoubleOrNull(json, "balance")); + user.setDaily_streak(getIntOrNull(json, "daily_streak")); + + // Parse boolean fields + user.setIs_suspended(getBooleanOrNull(json, "is_suspended")); + user.setIs_banned(getBooleanOrNull(json, "is_banned")); + + // Parse datetime fields + user.setLast_work(getOffsetDateTimeOrNull(json, "last_work")); + user.setLast_Played(getOffsetDateTimeOrNull(json, "last_played")); + user.setLast_daily(getOffsetDateTimeOrNull(json, "last_daily")); + user.setCreated(getOffsetDateTimeOrNull(json, "created")); + user.setUpdated(getOffsetDateTimeOrNull(json, "updated")); + + return user; + } + + /** + * Convert a User object to a JsonObject for PocketBase + * + * @param user User object to convert + * @return JsonObject for PocketBase API + */ + private JsonObject mapToJsonObject(DVUser user) { + JsonObject json = new JsonObject(); + + // Only include fields that PocketBase expects for updates/creates + if (user.getDiscord_id() != null) + json.addProperty("discord_id", user.getDiscord_id()); + if (user.getDiscord_username() != null) + json.addProperty("discord_username", user.getDiscord_username()); + if (user.getDiscord_img() != null) + json.addProperty("discord_img", user.getDiscord_img()); + if (user.getMcUsername() != null) + json.addProperty("mc_username", user.getMcUsername()); + if (user.getMc_uuid() != null) + json.addProperty("mc_uuid", user.getMc_uuid().toString()); + + // Add numeric fields + if (user.getClaim_limit() != null) + json.addProperty("claim_limit", user.getClaim_limit()); + if (user.getPlay_time() != null) + json.addProperty("play_time", user.getPlay_time()); + if (user.getBalance() != null) + json.addProperty("balance", user.getBalance()); + if (user.getDaily_streak() != null) + json.addProperty("daily_streak", user.getDaily_streak()); + + // Add boolean fields + if (user.getIs_suspended() != null) + json.addProperty("is_suspended", user.getIs_suspended()); + if (user.getIs_banned() != null) + json.addProperty("is_banned", user.getIs_banned()); + + // Format and add datetime fields + if (user.getLast_work() != null) + json.addProperty("last_work", formatDateTime(user.getLast_work())); + if (user.getLast_daily() != null) + json.addProperty("last_daily", formatDateTime(user.getLast_daily())); + + // Add relation fields (these need to be handled separately based on + // PocketBase's expectations) + // For now, we'll just leave them out as they typically require special handling + // TODO:Add relation fields + return json; + } - // Try alternative parsing with explicit formatter - try { - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSZ"); - String dateStr = json.get(key).getAsString(); - - // Check if the string is empty or blank - if (dateStr == null || dateStr.trim().isEmpty()) { - return null; - } - - // Convert to ISO format for parsing - if (dateStr.endsWith("Z")) { - dateStr = dateStr.substring(0, dateStr.length() - 1) + "+0000"; - } - - return OffsetDateTime.parse(dateStr.replace(" ", "T")); - } catch (Exception ex) { - LOGGER.warning("Alternative date parsing also failed: " + ex.getMessage()); - return null; + private String getStringOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsString() : null; + } + + private Integer getIntOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsInt() : null; + } + + private Double getDoubleOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsDouble() : null; + } + + private Boolean getBooleanOrNull(JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsBoolean() : null; + } + + private OffsetDateTime getOffsetDateTimeOrNull(JsonObject json, String key) { + if (json.has(key) && !json.get(key).isJsonNull()) { + try { + String dateStr = json.get(key).getAsString(); + + // Check if the string is empty or blank + if (dateStr == null || dateStr.trim().isEmpty()) { + return null; + } + + // Handle PocketBase date format "yyyy-MM-dd HH:mm:ss.SSSZ" + if (dateStr.contains(" ") && !dateStr.contains("T")) { + // Replace space with 'T' to make it ISO-8601 compatible + dateStr = dateStr.replace(" ", "T"); + } + + return OffsetDateTime.parse(dateStr); + } catch (Exception e) { + LOGGER.warning("Failed to parse date: " + json.get(key).getAsString() + " - " + e.getMessage()); + + // Try alternative parsing with explicit formatter + try { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSZ"); + String dateStr = json.get(key).getAsString(); + + // Check if the string is empty or blank + if (dateStr == null || dateStr.trim().isEmpty()) { + return null; + } + + // Convert to ISO format for parsing + if (dateStr.endsWith("Z")) { + dateStr = dateStr.substring(0, dateStr.length() - 1) + "+0000"; + } + + return OffsetDateTime.parse(dateStr.replace(" ", "T")); + } catch (Exception ex) { + LOGGER.warning("Alternative date parsing also failed: " + ex.getMessage()); + return null; + } + } + } + return null; + } + + @NotNull + private List getStringListOrEmpty(JsonObject json, String key) { + if (json.has(key) && !json.get(key).isJsonNull() && json.get(key).isJsonArray()) { + Type listType = new TypeToken>() { + }.getType(); + return gson.fromJson(json.get(key), listType); } - } + return new ArrayList<>(); } - return null; - } - - @NotNull - private List getStringListOrEmpty(JsonObject json, String key) { - if (json.has(key) && !json.get(key).isJsonNull() && json.get(key).isJsonArray()) { - Type listType = new TypeToken>() { - }.getType(); - return gson.fromJson(json.get(key), listType); + + private String formatDateTime(OffsetDateTime dateTime) { + return dateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); } - return new ArrayList<>(); - } - - private String formatDateTime(OffsetDateTime dateTime) { - return dateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); - } - - @Override - public List getAllWhere(String filter) { - try { - List records = pocketBase.getFullList(COLLECTION_NAME, 500, filter, null, null, null); - return records.stream() - .map(this::mapToUser) - .collect(Collectors.toList()); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error retrieving users with filter: " + filter, e); - return Collections.emptyList(); + + @Override + public List getAllWhere(String filter) { + try { + List records = pocketBase.getFullList(COLLECTION_NAME, 500, filter, null, null, null); + return records.stream() + .map(this::mapToUser) + .collect(Collectors.toList()); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error retrieving users with filter: " + filter, e); + return Collections.emptyList(); + } } - } } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserInventoryRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserInventoryRepository.java index b3192fb..5fe8e4a 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserInventoryRepository.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserInventoryRepository.java @@ -10,81 +10,81 @@ * Repository interface for UserInventory data operations */ public interface UserInventoryRepository { - /** - * Find an inventory entry by its PocketBase ID - * - * @param id PocketBase record ID - * @return Optional containing the inventory entry if found - */ - Optional findById(String id); + /** + * Find an inventory entry by its PocketBase ID + * + * @param id PocketBase record ID + * @return Optional containing the inventory entry if found + */ + Optional findById(String id); - /** - * Find all inventory entries for a user - * - * @param userId PocketBase user ID - * @return List of inventory entries for the user - */ - List findByUser(String userId); + /** + * Find all inventory entries for a user + * + * @param userId PocketBase user ID + * @return List of inventory entries for the user + */ + List findByUser(String userId); - /** - * Find inventory entry for a specific user and item - * - * @param userId PocketBase user ID - * @param itemId PocketBase item ID - * @return Optional containing the inventory entry if found - */ - Optional findByUserAndItem(String userId, String itemId); + /** + * Find inventory entry for a specific user and item + * + * @param userId PocketBase user ID + * @param itemId PocketBase item ID + * @return Optional containing the inventory entry if found + */ + Optional findByUserAndItem(String userId, String itemId); - /** - * Get all inventory entries - * - * @return List of all inventory entries - */ - List findAll(); + /** + * Get all inventory entries + * + * @return List of all inventory entries + */ + List findAll(); - /** - * Save an inventory entry (create or update) - * - * @param userInventory UserInventory to save - * @return Saved inventory entry - */ - UserInventory save(UserInventory userInventory); + /** + * Save an inventory entry (create or update) + * + * @param userInventory UserInventory to save + * @return Saved inventory entry + */ + UserInventory save(UserInventory userInventory); - /** - * Delete an inventory entry - * - * @param userInventory UserInventory to delete - */ - void delete(UserInventory userInventory); + /** + * Delete an inventory entry + * + * @param userInventory UserInventory to delete + */ + void delete(UserInventory userInventory); - /** - * Delete an inventory entry by ID - * - * @param id PocketBase ID of inventory entry to delete - */ - void deleteById(String id); + /** + * Delete an inventory entry by ID + * + * @param id PocketBase ID of inventory entry to delete + */ + void deleteById(String id); - /** - * Get all inventory entries matching a filter - * - * @param filter PocketBase filter expression - * @return List of inventory entries matching the filter - */ - List getAllWhere(String filter); + /** + * Get all inventory entries matching a filter + * + * @param filter PocketBase filter expression + * @return List of inventory entries matching the filter + */ + List getAllWhere(String filter); - /** - * Load related item data for all inventory entries - * - * @param inventoryEntries List of inventory entries - * @return List of inventory entries with loaded item data - */ - List loadRelatedItems(List inventoryEntries); + /** + * Load related item data for all inventory entries + * + * @param inventoryEntries List of inventory entries + * @return List of inventory entries with loaded item data + */ + List loadRelatedItems(List inventoryEntries); - /** - * Load related user data for all inventory entries - * - * @param inventoryEntries List of inventory entries - * @return List of inventory entries with loaded user data - */ - List loadRelatedUsers(List inventoryEntries); + /** + * Load related user data for all inventory entries + * + * @param inventoryEntries List of inventory entries + * @return List of inventory entries with loaded user data + */ + List loadRelatedUsers(List inventoryEntries); } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserRepository.java index a8c33bf..42c397f 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserRepository.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserRepository.java @@ -1,7 +1,6 @@ package org.woftnw.dreamvisitor.data.repository; - import java.util.List; import java.util.Optional; import java.util.UUID; @@ -12,80 +11,80 @@ * Repository interface for User data operations */ public interface UserRepository { - /** - * Find a user by their PocketBase ID - * - * @param id PocketBase record ID - * @return Optional containing the user if found - */ - Optional findById(String id); + /** + * Find a user by their PocketBase ID + * + * @param id PocketBase record ID + * @return Optional containing the user if found + */ + Optional findById(String id); - /** - * Find a user by their Minecraft UUID - * - * @param uuid Minecraft UUID - * @return Optional containing the user if found - */ - Optional findByUuid(UUID uuid); + /** + * Find a user by their Minecraft UUID + * + * @param uuid Minecraft UUID + * @return Optional containing the user if found + */ + Optional findByUuid(UUID uuid); - /** - * Find a user by their Discord ID - * - * @param discordId Discord ID - * @return Optional containing the user if found - */ - Optional findByDiscordId(String discordId); + /** + * Find a user by their Discord ID + * + * @param discordId Discord ID + * @return Optional containing the user if found + */ + Optional findByDiscordId(String discordId); - /** - * Find a user by their Discord Snowflake ID - * - * @param snowflakeId Discord Snowflake ID - * @return Optional containing the user if found - */ - Optional findBySnowflakeId(Long snowflakeId); + /** + * Find a user by their Discord Snowflake ID + * + * @param snowflakeId Discord Snowflake ID + * @return Optional containing the user if found + */ + Optional findBySnowflakeId(Long snowflakeId); - /** - * Find a user by their Minecraft username - * - * @param mcUsername Minecraft username - * @return Optional containing the user if found - */ - Optional findByMcUsername(String mcUsername); + /** + * Find a user by their Minecraft username + * + * @param mcUsername Minecraft username + * @return Optional containing the user if found + */ + Optional findByMcUsername(String mcUsername); - /** - * Get all users - * - * @return List of all users - */ - List findAll(); + /** + * Get all users + * + * @return List of all users + */ + List findAll(); - /** - * Save a user (create or update) - * - * @param user User to save - * @return Saved user - */ - DVUser save(DVUser user); + /** + * Save a user (create or update) + * + * @param user User to save + * @return Saved user + */ + DVUser save(DVUser user); - /** - * Delete a user - * - * @param user User to delete - */ - void delete(DVUser user); + /** + * Delete a user + * + * @param user User to delete + */ + void delete(DVUser user); - /** - * Delete a user by ID - * - * @param id PocketBase ID of user to delete - */ - void deleteById(String id); + /** + * Delete a user by ID + * + * @param id PocketBase ID of user to delete + */ + void deleteById(String id); - /** - * Get all users that match a given condition - * - * @param predicate Condition to filter users - * @return List of users matching the condition - */ - List getAllWhere(String filter); + /** + * Get all users that match a given condition + * + * @param predicate Condition to filter users + * @return List of users matching the condition + */ + List getAllWhere(String filter); } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/DVUser.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/DVUser.java index 25bc576..3929ab4 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/DVUser.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/DVUser.java @@ -5,237 +5,237 @@ import java.util.UUID; public class DVUser { - private String id; - private String collectionId; - private String collectionName; - - private UUID mc_uuid; - private String mcUsername; - private String discord_username; - private String discord_id; - private String discord_img; - private Long snowflakeId; - - private List infractions; - private List users_home; - private List inventory_items; - private List claims; - private List alts; // Added alts field - - private Integer claim_limit; - private Integer play_time; - private Double balance; - private Integer daily_streak; - - private OffsetDateTime last_work; - private OffsetDateTime last_daily; - private OffsetDateTime last_played; - - private Boolean is_suspended; - private Boolean is_banned; - - private OffsetDateTime created; - private OffsetDateTime updated; - - // Existing getters and setters - public UUID getMc_uuid() { - return mc_uuid; - } - - public Long getSnowflakeId() { - return snowflakeId; - } - - public String getDiscord_username() { - return discord_username; - } - - public String getMcUsername() { - return mcUsername; - } - - public void setDiscord_username(String dcUsername) { - this.discord_username = dcUsername; - } - - public void setMcUsername(String mcUsername) { - this.mcUsername = mcUsername; - } - - public void setSnowflakeId(Long snowflakeId) { - this.snowflakeId = snowflakeId; - } - - public void setMc_uuid(UUID uuid) { - this.mc_uuid = uuid; - } - - // New getters and setters - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getCollectionId() { - return collectionId; - } - - public void setCollectionId(String collectionId) { - this.collectionId = collectionId; - } - - public String getCollectionName() { - return collectionName; - } - - public void setCollectionName(String collectionName) { - this.collectionName = collectionName; - } - - public String getDiscord_id() { - return discord_id; - } - - public void setDiscord_id(String discord_id) { - this.discord_id = discord_id; - } - - public String getDiscord_img() { - return discord_img; - } - - public void setDiscord_img(String discord_img) { - this.discord_img = discord_img; - } - - public List getInfractions() { - return infractions; - } + private String id; + private String collectionId; + private String collectionName; + + private UUID mc_uuid; + private String mcUsername; + private String discord_username; + private String discord_id; + private String discord_img; + private Long snowflakeId; + + private List infractions; + private List users_home; + private List inventory_items; + private List claims; + private List alts; // Added alts field + + private Integer claim_limit; + private Integer play_time; + private Double balance; + private Integer daily_streak; + + private OffsetDateTime last_work; + private OffsetDateTime last_daily; + private OffsetDateTime last_played; + + private Boolean is_suspended; + private Boolean is_banned; + + private OffsetDateTime created; + private OffsetDateTime updated; + + // Existing getters and setters + public UUID getMc_uuid() { + return mc_uuid; + } + + public Long getSnowflakeId() { + return snowflakeId; + } + + public String getDiscord_username() { + return discord_username; + } + + public String getMcUsername() { + return mcUsername; + } + + public void setDiscord_username(String dcUsername) { + this.discord_username = dcUsername; + } + + public void setMcUsername(String mcUsername) { + this.mcUsername = mcUsername; + } + + public void setSnowflakeId(Long snowflakeId) { + this.snowflakeId = snowflakeId; + } + + public void setMc_uuid(UUID uuid) { + this.mc_uuid = uuid; + } + + // New getters and setters + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getCollectionId() { + return collectionId; + } + + public void setCollectionId(String collectionId) { + this.collectionId = collectionId; + } + + public String getCollectionName() { + return collectionName; + } + + public void setCollectionName(String collectionName) { + this.collectionName = collectionName; + } + + public String getDiscord_id() { + return discord_id; + } + + public void setDiscord_id(String discord_id) { + this.discord_id = discord_id; + } + + public String getDiscord_img() { + return discord_img; + } + + public void setDiscord_img(String discord_img) { + this.discord_img = discord_img; + } + + public List getInfractions() { + return infractions; + } - public void setInfractions(List infractions) { - this.infractions = infractions; - } + public void setInfractions(List infractions) { + this.infractions = infractions; + } - public List getUsers_home() { - return users_home; - } + public List getUsers_home() { + return users_home; + } - public void setUsers_home(List users_home) { - this.users_home = users_home; - } + public void setUsers_home(List users_home) { + this.users_home = users_home; + } - public List getInventory_items() { - return inventory_items; - } + public List getInventory_items() { + return inventory_items; + } - public void setInventory_items(List inventory_items) { - this.inventory_items = inventory_items; - } + public void setInventory_items(List inventory_items) { + this.inventory_items = inventory_items; + } - public List getClaims() { - return claims; - } - - public void setClaims(List claims) { - this.claims = claims; - } - - public List getAlts() { - return alts; - } - - public void setAlts(List alts) { - this.alts = alts; - } - - public Integer getClaim_limit() { - return claim_limit; - } - - public void setClaim_limit(Integer claim_limit) { - this.claim_limit = claim_limit; - } - - public Integer getPlay_time() { - return play_time; - } - - public void setPlay_time(Integer play_time) { - this.play_time = play_time; - } - - public Double getBalance() { - return balance; - } - - public void setBalance(Double balance) { - this.balance = balance; - } + public List getClaims() { + return claims; + } + + public void setClaims(List claims) { + this.claims = claims; + } + + public List getAlts() { + return alts; + } + + public void setAlts(List alts) { + this.alts = alts; + } + + public Integer getClaim_limit() { + return claim_limit; + } + + public void setClaim_limit(Integer claim_limit) { + this.claim_limit = claim_limit; + } + + public Integer getPlay_time() { + return play_time; + } + + public void setPlay_time(Integer play_time) { + this.play_time = play_time; + } + + public Double getBalance() { + return balance; + } + + public void setBalance(Double balance) { + this.balance = balance; + } - public Integer getDaily_streak() { - return daily_streak; - } + public Integer getDaily_streak() { + return daily_streak; + } - public void setDaily_streak(Integer daily_streak) { - this.daily_streak = daily_streak; - } + public void setDaily_streak(Integer daily_streak) { + this.daily_streak = daily_streak; + } - public OffsetDateTime getLast_work() { - return last_work; - } + public OffsetDateTime getLast_work() { + return last_work; + } - public void setLast_work(OffsetDateTime last_work) { - this.last_work = last_work; - } + public void setLast_work(OffsetDateTime last_work) { + this.last_work = last_work; + } - public OffsetDateTime getLast_played() { - return last_played; - } + public OffsetDateTime getLast_played() { + return last_played; + } - public OffsetDateTime getLast_daily() { - return last_daily; - } + public OffsetDateTime getLast_daily() { + return last_daily; + } - public void setLast_daily(OffsetDateTime last_daily) { - this.last_daily = last_daily; - } + public void setLast_daily(OffsetDateTime last_daily) { + this.last_daily = last_daily; + } - public Boolean getIs_suspended() { - return is_suspended; - } + public Boolean getIs_suspended() { + return is_suspended; + } - public void setIs_suspended(Boolean is_suspended) { - this.is_suspended = is_suspended; - } + public void setIs_suspended(Boolean is_suspended) { + this.is_suspended = is_suspended; + } - public Boolean getIs_banned() { - return is_banned; - } + public Boolean getIs_banned() { + return is_banned; + } - public void setIs_banned(Boolean is_banned) { - this.is_banned = is_banned; - } + public void setIs_banned(Boolean is_banned) { + this.is_banned = is_banned; + } - public OffsetDateTime getCreated() { - return created; - } + public OffsetDateTime getCreated() { + return created; + } - public void setCreated(OffsetDateTime created) { - this.created = created; - } + public void setCreated(OffsetDateTime created) { + this.created = created; + } - public OffsetDateTime getUpdated() { - return updated; - } + public OffsetDateTime getUpdated() { + return updated; + } - public void setUpdated(OffsetDateTime updated) { - this.updated = updated; - } + public void setUpdated(OffsetDateTime updated) { + this.updated = updated; + } - public void setLast_Played(OffsetDateTime last_played) { - this.last_played = last_played; - } + public void setLast_Played(OffsetDateTime last_played) { + this.last_played = last_played; + } } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/Item.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/Item.java index d2dfbf3..77d88ca 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/Item.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/Item.java @@ -3,196 +3,196 @@ import java.time.OffsetDateTime; public class Item { - private String id; - private String collectionId; - private String collectionName; - - private String name; - private String description; - private Double price; - private Double sale_percent; - private Integer quantity; - private Boolean gifting_enabled; - private Boolean enabled; - private Integer max_allowed; - private Boolean use_disabled; - private Boolean use_on_purchase; - private String on_use_groups_add; // JSON string - private String on_use_groups_remove; // JSON string - - // JSON array of Discord role IDs to add when item is used - // Example format: ["123456789012345678", "234567890123456789"] - // These must be valid Discord role IDs from the server - private String on_use_roles_add; - - // JSON array of Discord role IDs to remove when item is used - // Example format: ["123456789012345678", "234567890123456789"] - // These must be valid Discord role IDs from the server - private String on_use_roles_remove; - - private String on_use_console_commands; // JSON string - - private OffsetDateTime created; - private OffsetDateTime updated; - - // Getters and setters - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getCollectionId() { - return collectionId; - } - - public void setCollectionId(String collectionId) { - this.collectionId = collectionId; - } - - public String getCollectionName() { - return collectionName; - } - - public void setCollectionName(String collectionName) { - this.collectionName = collectionName; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public Double getPrice() { - return price; - } - - public void setPrice(Double price) { - this.price = price; - } - - public Double getSale_percent() { - return sale_percent; - } - - public void setSale_percent(Double sale_percent) { - this.sale_percent = sale_percent; - } - - public Integer getQuantity() { - return quantity; - } - - public void setQuantity(Integer quantity) { - this.quantity = quantity; - } - - public Boolean getGifting_enabled() { - return gifting_enabled; - } - - public void setGifting_enabled(Boolean gifting_enabled) { - this.gifting_enabled = gifting_enabled; - } - - public Boolean getEnabled() { - return enabled; - } - - public void setEnabled(Boolean enabled) { - this.enabled = enabled; - } - - public Integer getMax_allowed() { - return max_allowed; - } + private String id; + private String collectionId; + private String collectionName; + + private String name; + private String description; + private Double price; + private Double sale_percent; + private Integer quantity; + private Boolean gifting_enabled; + private Boolean enabled; + private Integer max_allowed; + private Boolean use_disabled; + private Boolean use_on_purchase; + private String on_use_groups_add; // JSON string + private String on_use_groups_remove; // JSON string + + // JSON array of Discord role IDs to add when item is used + // Example format: ["123456789012345678", "234567890123456789"] + // These must be valid Discord role IDs from the server + private String on_use_roles_add; + + // JSON array of Discord role IDs to remove when item is used + // Example format: ["123456789012345678", "234567890123456789"] + // These must be valid Discord role IDs from the server + private String on_use_roles_remove; + + private String on_use_console_commands; // JSON string + + private OffsetDateTime created; + private OffsetDateTime updated; + + // Getters and setters + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getCollectionId() { + return collectionId; + } + + public void setCollectionId(String collectionId) { + this.collectionId = collectionId; + } + + public String getCollectionName() { + return collectionName; + } + + public void setCollectionName(String collectionName) { + this.collectionName = collectionName; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Double getPrice() { + return price; + } + + public void setPrice(Double price) { + this.price = price; + } + + public Double getSale_percent() { + return sale_percent; + } + + public void setSale_percent(Double sale_percent) { + this.sale_percent = sale_percent; + } + + public Integer getQuantity() { + return quantity; + } + + public void setQuantity(Integer quantity) { + this.quantity = quantity; + } + + public Boolean getGifting_enabled() { + return gifting_enabled; + } + + public void setGifting_enabled(Boolean gifting_enabled) { + this.gifting_enabled = gifting_enabled; + } + + public Boolean getEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + public Integer getMax_allowed() { + return max_allowed; + } - public void setMax_allowed(Integer max_allowed) { - this.max_allowed = max_allowed; - } + public void setMax_allowed(Integer max_allowed) { + this.max_allowed = max_allowed; + } - public Boolean getUse_disabled() { - return use_disabled; - } + public Boolean getUse_disabled() { + return use_disabled; + } - public void setUse_disabled(Boolean use_disabled) { - this.use_disabled = use_disabled; - } + public void setUse_disabled(Boolean use_disabled) { + this.use_disabled = use_disabled; + } - public Boolean getUse_on_purchase() { - return use_on_purchase; - } - - public void setUse_on_purchase(Boolean use_on_purchase) { - this.use_on_purchase = use_on_purchase; - } + public Boolean getUse_on_purchase() { + return use_on_purchase; + } + + public void setUse_on_purchase(Boolean use_on_purchase) { + this.use_on_purchase = use_on_purchase; + } - public String getOn_use_groups_add() { - return on_use_groups_add; - } + public String getOn_use_groups_add() { + return on_use_groups_add; + } - public void setOn_use_groups_add(String on_use_groups_add) { - this.on_use_groups_add = on_use_groups_add; - } + public void setOn_use_groups_add(String on_use_groups_add) { + this.on_use_groups_add = on_use_groups_add; + } - public String getOn_use_groups_remove() { - return on_use_groups_remove; - } + public String getOn_use_groups_remove() { + return on_use_groups_remove; + } - public void setOn_use_groups_remove(String on_use_groups_remove) { - this.on_use_groups_remove = on_use_groups_remove; - } + public void setOn_use_groups_remove(String on_use_groups_remove) { + this.on_use_groups_remove = on_use_groups_remove; + } - public String getOn_use_roles_add() { - return on_use_roles_add; - } + public String getOn_use_roles_add() { + return on_use_roles_add; + } - public void setOn_use_roles_add(String on_use_roles_add) { - this.on_use_roles_add = on_use_roles_add; - } + public void setOn_use_roles_add(String on_use_roles_add) { + this.on_use_roles_add = on_use_roles_add; + } - public String getOn_use_roles_remove() { - return on_use_roles_remove; - } + public String getOn_use_roles_remove() { + return on_use_roles_remove; + } - public void setOn_use_roles_remove(String on_use_roles_remove) { - this.on_use_roles_remove = on_use_roles_remove; - } + public void setOn_use_roles_remove(String on_use_roles_remove) { + this.on_use_roles_remove = on_use_roles_remove; + } - public String getOn_use_console_commands() { - return on_use_console_commands; - } + public String getOn_use_console_commands() { + return on_use_console_commands; + } - public void setOn_use_console_commands(String on_use_console_commands) { - this.on_use_console_commands = on_use_console_commands; - } + public void setOn_use_console_commands(String on_use_console_commands) { + this.on_use_console_commands = on_use_console_commands; + } - public OffsetDateTime getCreated() { - return created; - } + public OffsetDateTime getCreated() { + return created; + } - public void setCreated(OffsetDateTime created) { - this.created = created; - } + public void setCreated(OffsetDateTime created) { + this.created = created; + } - public OffsetDateTime getUpdated() { - return updated; - } + public OffsetDateTime getUpdated() { + return updated; + } - public void setUpdated(OffsetDateTime updated) { - this.updated = updated; - } + public void setUpdated(OffsetDateTime updated) { + this.updated = updated; + } } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/UserInventory.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/UserInventory.java index 1174085..25ed8f4 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/UserInventory.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/UserInventory.java @@ -3,99 +3,99 @@ import java.time.OffsetDateTime; public class UserInventory { - private String id; - private String collectionId; - private String collectionName; + private String id; + private String collectionId; + private String collectionName; - private String user; // Relation record ID - private String item; // Relation record ID - private Integer quantity; + private String user; // Relation record ID + private String item; // Relation record ID + private Integer quantity; - private OffsetDateTime created; - private OffsetDateTime updated; + private OffsetDateTime created; + private OffsetDateTime updated; - // Cached related objects (not stored in PocketBase directly) - private transient DVUser cachedUser; - private transient Item cachedItem; + // Cached related objects (not stored in PocketBase directly) + private transient DVUser cachedUser; + private transient Item cachedItem; - // Getters and setters - public String getId() { - return id; - } + // Getters and setters + public String getId() { + return id; + } - public void setId(String id) { - this.id = id; - } + public void setId(String id) { + this.id = id; + } - public String getCollectionId() { - return collectionId; - } + public String getCollectionId() { + return collectionId; + } - public void setCollectionId(String collectionId) { - this.collectionId = collectionId; - } + public void setCollectionId(String collectionId) { + this.collectionId = collectionId; + } - public String getCollectionName() { - return collectionName; - } + public String getCollectionName() { + return collectionName; + } - public void setCollectionName(String collectionName) { - this.collectionName = collectionName; - } + public void setCollectionName(String collectionName) { + this.collectionName = collectionName; + } - public String getUser() { - return user; - } + public String getUser() { + return user; + } - public void setUser(String user) { - this.user = user; - } + public void setUser(String user) { + this.user = user; + } - public String getItem() { - return item; - } + public String getItem() { + return item; + } - public void setItem(String item) { - this.item = item; - } + public void setItem(String item) { + this.item = item; + } - public Integer getQuantity() { - return quantity; - } + public Integer getQuantity() { + return quantity; + } - public void setQuantity(Integer quantity) { - this.quantity = quantity; - } + public void setQuantity(Integer quantity) { + this.quantity = quantity; + } - public OffsetDateTime getCreated() { - return created; - } + public OffsetDateTime getCreated() { + return created; + } - public void setCreated(OffsetDateTime created) { - this.created = created; - } + public void setCreated(OffsetDateTime created) { + this.created = created; + } - public OffsetDateTime getUpdated() { - return updated; - } + public OffsetDateTime getUpdated() { + return updated; + } - public void setUpdated(OffsetDateTime updated) { - this.updated = updated; - } + public void setUpdated(OffsetDateTime updated) { + this.updated = updated; + } - public DVUser getCachedUser() { - return cachedUser; - } + public DVUser getCachedUser() { + return cachedUser; + } - public void setCachedUser(DVUser cachedUser) { - this.cachedUser = cachedUser; - } + public void setCachedUser(DVUser cachedUser) { + this.cachedUser = cachedUser; + } - public Item getCachedItem() { - return cachedItem; - } + public Item getCachedItem() { + return cachedItem; + } - public void setCachedItem(Item cachedItem) { - this.cachedItem = cachedItem; - } + public void setCachedItem(Item cachedItem) { + this.cachedItem = cachedItem; + } } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/pb/PocketBase.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/pb/PocketBase.java index e8f1f4e..76e60d0 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/pb/PocketBase.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/pb/PocketBase.java @@ -15,412 +15,412 @@ import java.util.concurrent.TimeUnit; public class PocketBase { - private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - private final OkHttpClient client; - private final Gson gson; - private final String baseUrl; - private String token; - - /** - * Creates a new PocketBase SDK instance. - * - * @param baseUrl The base URL of the PocketBase instance - * @param token The admin/user auth token - */ - public PocketBase(@NotNull String baseUrl, String token) { - this.baseUrl = baseUrl.endsWith("/") ? baseUrl : baseUrl + "/"; - this.token = token; - this.gson = new Gson(); - this.client = new OkHttpClient.Builder() - .connectTimeout(30, TimeUnit.SECONDS) - .readTimeout(30, TimeUnit.SECONDS) - .writeTimeout(30, TimeUnit.SECONDS) - .build(); - } - - /** - * Creates an instance with the default configuration from config.yml - * - * @return A preconfigured PocketBase instance - */ - @NotNull - public static PocketBase fromConfig(@NotNull Map config) { - String baseUrl = (String) config.get("pocketbaseUrl"); - String token = (String) config.get("pocketbaseToken"); - return new PocketBase(baseUrl, token); - } - - /** - * Helper method to build a URL with query parameters - * - * @param endpoint The API endpoint - * @param queryParams Query parameters - * @return The complete URL - */ - @NotNull - private HttpUrl buildUrl(String endpoint, @Nullable Map queryParams) { - HttpUrl.Builder urlBuilder = HttpUrl.parse(this.baseUrl + endpoint).newBuilder(); - - if (queryParams != null) { - for (Map.Entry entry : queryParams.entrySet()) { - urlBuilder.addQueryParameter(entry.getKey(), entry.getValue()); - } + private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); + private final OkHttpClient client; + private final Gson gson; + private final String baseUrl; + private String token; + + /** + * Creates a new PocketBase SDK instance. + * + * @param baseUrl The base URL of the PocketBase instance + * @param token The admin/user auth token + */ + public PocketBase(@NotNull String baseUrl, String token) { + this.baseUrl = baseUrl.endsWith("/") ? baseUrl : baseUrl + "/"; + this.token = token; + this.gson = new Gson(); + this.client = new OkHttpClient.Builder() + .connectTimeout(30, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .writeTimeout(30, TimeUnit.SECONDS) + .build(); } - return urlBuilder.build(); - } - - /** - * Helper method to execute HTTP requests - * - * @param method HTTP method - * @param endpoint API endpoint - * @param body Request body - * @param queryParams Query parameters - * @return Response string - * @throws IOException If the request fails - */ - @NotNull - private String executeRequest(@NotNull String method, String endpoint, @Nullable RequestBody body, - @Nullable Map queryParams) throws IOException { - HttpUrl url = buildUrl(endpoint, queryParams); - - Request.Builder requestBuilder = new Request.Builder() - .url(url) - .header("Authorization", "Bearer " + this.token); - - switch (method) { - case "GET": - requestBuilder.get(); - break; - case "POST": - requestBuilder.post(body != null ? body : RequestBody.create(new byte[0], null)); - break; - case "PATCH": - requestBuilder.patch(body != null ? body : RequestBody.create(new byte[0], null)); - break; - case "DELETE": - requestBuilder.delete(body); - break; - default: - throw new IllegalArgumentException("Unsupported HTTP method: " + method); + /** + * Creates an instance with the default configuration from config.yml + * + * @return A preconfigured PocketBase instance + */ + @NotNull + public static PocketBase fromConfig(@NotNull Map config) { + String baseUrl = (String) config.get("pocketbaseUrl"); + String token = (String) config.get("pocketbaseToken"); + return new PocketBase(baseUrl, token); } - Request request = requestBuilder.build(); - try (Response response = client.newCall(request).execute()) { - if (!response.isSuccessful()) { - String errorBody = response.body() != null ? response.body().string() : "No response body"; - throw new IOException("Request failed with code " + response.code() + ": " + errorBody); - } + /** + * Helper method to build a URL with query parameters + * + * @param endpoint The API endpoint + * @param queryParams Query parameters + * @return The complete URL + */ + @NotNull + private HttpUrl buildUrl(String endpoint, @Nullable Map queryParams) { + HttpUrl.Builder urlBuilder = HttpUrl.parse(this.baseUrl + endpoint).newBuilder(); + + if (queryParams != null) { + for (Map.Entry entry : queryParams.entrySet()) { + urlBuilder.addQueryParameter(entry.getKey(), entry.getValue()); + } + } + + return urlBuilder.build(); + } + + /** + * Helper method to execute HTTP requests + * + * @param method HTTP method + * @param endpoint API endpoint + * @param body Request body + * @param queryParams Query parameters + * @return Response string + * @throws IOException If the request fails + */ + @NotNull + private String executeRequest(@NotNull String method, String endpoint, @Nullable RequestBody body, + @Nullable Map queryParams) throws IOException { + HttpUrl url = buildUrl(endpoint, queryParams); + + Request.Builder requestBuilder = new Request.Builder() + .url(url) + .header("Authorization", "Bearer " + this.token); + + switch (method) { + case "GET": + requestBuilder.get(); + break; + case "POST": + requestBuilder.post(body != null ? body : RequestBody.create(new byte[0], null)); + break; + case "PATCH": + requestBuilder.patch(body != null ? body : RequestBody.create(new byte[0], null)); + break; + case "DELETE": + requestBuilder.delete(body); + break; + default: + throw new IllegalArgumentException("Unsupported HTTP method: " + method); + } + + Request request = requestBuilder.build(); + try (Response response = client.newCall(request).execute()) { + if (!response.isSuccessful()) { + String errorBody = response.body() != null ? response.body().string() : "No response body"; + throw new IOException("Request failed with code " + response.code() + ": " + errorBody); + } + + return response.body() != null ? response.body().string() : ""; + } + } + + /** + * Impersonates a user and returns a new PocketBase instance with the + * impersonation token + * + * @param collectionIdOrName Collection ID or name + * @param recordId Record ID to impersonate + * @param duration Optional JWT duration in seconds + * @param expand Optional relations to expand + * @param fields Optional fields to return + * @return A new PocketBase instance with impersonation token + * @throws IOException If the request fails + */ + public PocketBase impersonate(String collectionIdOrName, String recordId, + @Nullable Integer duration, + @Nullable String expand, @Nullable String fields) throws IOException { + String endpoint = "api/collections/" + collectionIdOrName + "/impersonate/" + recordId; + + Map queryParams = new HashMap<>(); + if (expand != null) + queryParams.put("expand", expand); + if (fields != null) + queryParams.put("fields", fields); + + JsonObject jsonBody = new JsonObject(); + if (duration != null) + jsonBody.addProperty("duration", duration); + + RequestBody body = RequestBody.create(jsonBody.toString(), JSON); + String response = executeRequest("POST", endpoint, body, queryParams); + + ImpersonateResponse impersonateResponse = gson.fromJson(response, ImpersonateResponse.class); + return new PocketBase(this.baseUrl, impersonateResponse.token); + } - return response.body() != null ? response.body().string() : ""; + /** + * Lists/searches records from a collection + * + * @param collectionIdOrName Collection ID or name + * @param page Page number (default: 1) + * @param perPage Records per page (default: 30) + * @param sort Optional sorting + * @param filter Optional filter expression + * @param expand Optional relations to expand + * @param fields Optional fields to return + * @param skipTotal Whether to skip total counts + * @return List response with records + * @throws IOException If the request fails + */ + public ListResult listRecords(String collectionIdOrName, + @Nullable Integer page, @Nullable Integer perPage, + @Nullable String sort, @Nullable String filter, + @Nullable String expand, @Nullable String fields, + @Nullable Boolean skipTotal) throws IOException { + String endpoint = "api/collections/" + collectionIdOrName + "/records"; + + Map queryParams = new HashMap<>(); + if (page != null) + queryParams.put("page", page.toString()); + if (perPage != null) + queryParams.put("perPage", perPage.toString()); + if (sort != null) + queryParams.put("sort", sort); + if (filter != null) + queryParams.put("filter", filter); + if (expand != null) + queryParams.put("expand", expand); + if (fields != null) + queryParams.put("fields", fields); + if (skipTotal != null && skipTotal) + queryParams.put("skipTotal", "true"); + + String response = executeRequest("GET", endpoint, null, queryParams); + return gson.fromJson(response, ListResult.class); } - } - - /** - * Impersonates a user and returns a new PocketBase instance with the - * impersonation token - * - * @param collectionIdOrName Collection ID or name - * @param recordId Record ID to impersonate - * @param duration Optional JWT duration in seconds - * @param expand Optional relations to expand - * @param fields Optional fields to return - * @return A new PocketBase instance with impersonation token - * @throws IOException If the request fails - */ - public PocketBase impersonate(String collectionIdOrName, String recordId, - @Nullable Integer duration, - @Nullable String expand, @Nullable String fields) throws IOException { - String endpoint = "api/collections/" + collectionIdOrName + "/impersonate/" + recordId; - - Map queryParams = new HashMap<>(); - if (expand != null) - queryParams.put("expand", expand); - if (fields != null) - queryParams.put("fields", fields); - - JsonObject jsonBody = new JsonObject(); - if (duration != null) - jsonBody.addProperty("duration", duration); - - RequestBody body = RequestBody.create(jsonBody.toString(), JSON); - String response = executeRequest("POST", endpoint, body, queryParams); - - ImpersonateResponse impersonateResponse = gson.fromJson(response, ImpersonateResponse.class); - return new PocketBase(this.baseUrl, impersonateResponse.token); - } - - /** - * Lists/searches records from a collection - * - * @param collectionIdOrName Collection ID or name - * @param page Page number (default: 1) - * @param perPage Records per page (default: 30) - * @param sort Optional sorting - * @param filter Optional filter expression - * @param expand Optional relations to expand - * @param fields Optional fields to return - * @param skipTotal Whether to skip total counts - * @return List response with records - * @throws IOException If the request fails - */ - public ListResult listRecords(String collectionIdOrName, - @Nullable Integer page, @Nullable Integer perPage, - @Nullable String sort, @Nullable String filter, - @Nullable String expand, @Nullable String fields, - @Nullable Boolean skipTotal) throws IOException { - String endpoint = "api/collections/" + collectionIdOrName + "/records"; - - Map queryParams = new HashMap<>(); - if (page != null) - queryParams.put("page", page.toString()); - if (perPage != null) - queryParams.put("perPage", perPage.toString()); - if (sort != null) - queryParams.put("sort", sort); - if (filter != null) - queryParams.put("filter", filter); - if (expand != null) - queryParams.put("expand", expand); - if (fields != null) - queryParams.put("fields", fields); - if (skipTotal != null && skipTotal) - queryParams.put("skipTotal", "true"); - - String response = executeRequest("GET", endpoint, null, queryParams); - return gson.fromJson(response, ListResult.class); - } - - /** - * Gets the full list of records from a collection (auto-paginated) - * - * @param collectionIdOrName Collection ID or name - * @param batch Batch size (default: 500) - * @param sort Optional sorting - * @param filter Optional filter expression - * @param expand Optional relations to expand - * @param fields Optional fields to return - * @return List of records - * @throws IOException If the request fails - */ - public List getFullList(String collectionIdOrName, - @Nullable Integer batch, - @Nullable String sort, - @Nullable String filter, - @Nullable String expand, - @Nullable String fields) throws IOException { - int batchSize = batch != null ? batch : 500; - List allItems = new ArrayList<>(); - int page = 1; - - while (true) { - ListResult result = listRecords( - collectionIdOrName, - page, - batchSize, - sort, - filter, - expand, - fields, - true // skipTotal for optimization - ); - - allItems.addAll(result.items); - - if (result.items.size() < batchSize) { - break; - } - - page++; + + /** + * Gets the full list of records from a collection (auto-paginated) + * + * @param collectionIdOrName Collection ID or name + * @param batch Batch size (default: 500) + * @param sort Optional sorting + * @param filter Optional filter expression + * @param expand Optional relations to expand + * @param fields Optional fields to return + * @return List of records + * @throws IOException If the request fails + */ + public List getFullList(String collectionIdOrName, + @Nullable Integer batch, + @Nullable String sort, + @Nullable String filter, + @Nullable String expand, + @Nullable String fields) throws IOException { + int batchSize = batch != null ? batch : 500; + List allItems = new ArrayList<>(); + int page = 1; + + while (true) { + ListResult result = listRecords( + collectionIdOrName, + page, + batchSize, + sort, + filter, + expand, + fields, + true // skipTotal for optimization + ); + + allItems.addAll(result.items); + + if (result.items.size() < batchSize) { + break; + } + + page++; + } + + return allItems; + } + + /** + * Gets the first record matching the filter + * + * @param collectionIdOrName Collection ID or name + * @param filter Filter expression + * @param sort Optional sorting + * @param expand Optional relations to expand + * @param fields Optional fields to return + * @return First matching record + * @throws IOException If the request fails or no record found + */ + public JsonObject getFirstListItem(String collectionIdOrName, + @NotNull String filter, + @Nullable String sort, + @Nullable String expand, + @Nullable String fields) throws IOException { + ListResult result = listRecords( + collectionIdOrName, + 1, + 1, + sort, + filter, + expand, + fields, + true // skipTotal for optimization + ); + + if (result.items.isEmpty()) { + throw new IOException("No records found."); + } + + return result.items.get(0); + } + + /** + * Gets a single record by ID + * + * @param collectionIdOrName Collection ID or name + * @param recordId Record ID + * @param expand Optional relations to expand + * @param fields Optional fields to return + * @return Record data + * @throws IOException If the request fails + */ + public JsonObject getRecord(String collectionIdOrName, String recordId, + @Nullable String expand, @Nullable String fields) throws IOException { + String endpoint = "api/collections/" + collectionIdOrName + "/records/" + recordId; + + Map queryParams = new HashMap<>(); + if (expand != null) + queryParams.put("expand", expand); + if (fields != null) + queryParams.put("fields", fields); + + String response = executeRequest("GET", endpoint, null, queryParams); + return gson.fromJson(response, JsonObject.class); } - return allItems; - } - - /** - * Gets the first record matching the filter - * - * @param collectionIdOrName Collection ID or name - * @param filter Filter expression - * @param sort Optional sorting - * @param expand Optional relations to expand - * @param fields Optional fields to return - * @return First matching record - * @throws IOException If the request fails or no record found - */ - public JsonObject getFirstListItem(String collectionIdOrName, - @NotNull String filter, - @Nullable String sort, - @Nullable String expand, - @Nullable String fields) throws IOException { - ListResult result = listRecords( - collectionIdOrName, - 1, - 1, - sort, - filter, - expand, - fields, - true // skipTotal for optimization - ); - - if (result.items.isEmpty()) { - throw new IOException("No records found."); + /** + * Creates a new record + * + * @param collectionIdOrName Collection ID or name + * @param bodyData Record data + * @param expand Optional relations to expand + * @param fields Optional fields to return + * @return Created record + * @throws IOException If the request fails + */ + public JsonObject createRecord(String collectionIdOrName, Object bodyData, + @Nullable String expand, @Nullable String fields) throws IOException { + String endpoint = "api/collections/" + collectionIdOrName + "/records"; + + Map queryParams = new HashMap<>(); + if (expand != null) + queryParams.put("expand", expand); + if (fields != null) + queryParams.put("fields", fields); + + RequestBody body = RequestBody.create(gson.toJson(bodyData), JSON); + String response = executeRequest("POST", endpoint, body, queryParams); + return gson.fromJson(response, JsonObject.class); } - return result.items.get(0); - } - - /** - * Gets a single record by ID - * - * @param collectionIdOrName Collection ID or name - * @param recordId Record ID - * @param expand Optional relations to expand - * @param fields Optional fields to return - * @return Record data - * @throws IOException If the request fails - */ - public JsonObject getRecord(String collectionIdOrName, String recordId, - @Nullable String expand, @Nullable String fields) throws IOException { - String endpoint = "api/collections/" + collectionIdOrName + "/records/" + recordId; - - Map queryParams = new HashMap<>(); - if (expand != null) - queryParams.put("expand", expand); - if (fields != null) - queryParams.put("fields", fields); - - String response = executeRequest("GET", endpoint, null, queryParams); - return gson.fromJson(response, JsonObject.class); - } - - /** - * Creates a new record - * - * @param collectionIdOrName Collection ID or name - * @param bodyData Record data - * @param expand Optional relations to expand - * @param fields Optional fields to return - * @return Created record - * @throws IOException If the request fails - */ - public JsonObject createRecord(String collectionIdOrName, Object bodyData, - @Nullable String expand, @Nullable String fields) throws IOException { - String endpoint = "api/collections/" + collectionIdOrName + "/records"; - - Map queryParams = new HashMap<>(); - if (expand != null) - queryParams.put("expand", expand); - if (fields != null) - queryParams.put("fields", fields); - - RequestBody body = RequestBody.create(gson.toJson(bodyData), JSON); - String response = executeRequest("POST", endpoint, body, queryParams); - return gson.fromJson(response, JsonObject.class); - } - - /** - * Updates an existing record - * - * @param collectionIdOrName Collection ID or name - * @param recordId Record ID - * @param bodyData Updated data - * @param expand Optional relations to expand - * @param fields Optional fields to return - * @return Updated record - * @throws IOException If the request fails - */ - public JsonObject updateRecord(String collectionIdOrName, String recordId, Object bodyData, - @Nullable String expand, @Nullable String fields) throws IOException { - String endpoint = "api/collections/" + collectionIdOrName + "/records/" + recordId; - - Map queryParams = new HashMap<>(); - if (expand != null) - queryParams.put("expand", expand); - if (fields != null) - queryParams.put("fields", fields); - - RequestBody body = RequestBody.create(gson.toJson(bodyData), JSON); - String response = executeRequest("PATCH", endpoint, body, queryParams); - return gson.fromJson(response, JsonObject.class); - } - - /** - * Deletes a record - * - * @param collectionIdOrName Collection ID or name - * @param recordId Record ID - * @throws IOException If the request fails - */ - public void deleteRecord(String collectionIdOrName, String recordId) throws IOException { - String endpoint = "api/collections/" + collectionIdOrName + "/records/" + recordId; - executeRequest("DELETE", endpoint, null, null); - } - - /** - * Creates a multipart request body for file uploads - * - * @param fields Map of field names to values - * @param files Map of field names to files - * @return Multipart request body - */ - public RequestBody createMultipartBody(@NotNull Map fields, Map files) { - MultipartBody.Builder builder = new MultipartBody.Builder() - .setType(MultipartBody.FORM); - - // Add regular fields - for (Map.Entry entry : fields.entrySet()) { - builder.addFormDataPart(entry.getKey(), String.valueOf(entry.getValue())); + /** + * Updates an existing record + * + * @param collectionIdOrName Collection ID or name + * @param recordId Record ID + * @param bodyData Updated data + * @param expand Optional relations to expand + * @param fields Optional fields to return + * @return Updated record + * @throws IOException If the request fails + */ + public JsonObject updateRecord(String collectionIdOrName, String recordId, Object bodyData, + @Nullable String expand, @Nullable String fields) throws IOException { + String endpoint = "api/collections/" + collectionIdOrName + "/records/" + recordId; + + Map queryParams = new HashMap<>(); + if (expand != null) + queryParams.put("expand", expand); + if (fields != null) + queryParams.put("fields", fields); + + RequestBody body = RequestBody.create(gson.toJson(bodyData), JSON); + String response = executeRequest("PATCH", endpoint, body, queryParams); + return gson.fromJson(response, JsonObject.class); } - // Add files - for (Map.Entry entry : files.entrySet()) { - String fieldName = entry.getKey(); - File file = entry.getValue(); - String fileName = file.getName(); - RequestBody fileBody = RequestBody.create(file, MediaType.parse("application/octet-stream")); - builder.addFormDataPart(fieldName, fileName, fileBody); + /** + * Deletes a record + * + * @param collectionIdOrName Collection ID or name + * @param recordId Record ID + * @throws IOException If the request fails + */ + public void deleteRecord(String collectionIdOrName, String recordId) throws IOException { + String endpoint = "api/collections/" + collectionIdOrName + "/records/" + recordId; + executeRequest("DELETE", endpoint, null, null); } - return builder.build(); - } - - /** - * Get the current auth token - * - * @return Current auth token - */ - public String getToken() { - return token; - } - - /** - * Update the auth token - * - * @param token New auth token - */ - public void setToken(String token) { - this.token = token; - } - - /** - * Response class for impersonation - */ - private static class ImpersonateResponse { - String token; - JsonObject record; - } - - /** - * Response class for list operations - */ - public static class ListResult { - public int page; - public int perPage; - public int totalItems; - public int totalPages; - public List items; - } + /** + * Creates a multipart request body for file uploads + * + * @param fields Map of field names to values + * @param files Map of field names to files + * @return Multipart request body + */ + public RequestBody createMultipartBody(@NotNull Map fields, Map files) { + MultipartBody.Builder builder = new MultipartBody.Builder() + .setType(MultipartBody.FORM); + + // Add regular fields + for (Map.Entry entry : fields.entrySet()) { + builder.addFormDataPart(entry.getKey(), String.valueOf(entry.getValue())); + } + + // Add files + for (Map.Entry entry : files.entrySet()) { + String fieldName = entry.getKey(); + File file = entry.getValue(); + String fileName = file.getName(); + RequestBody fileBody = RequestBody.create(file, MediaType.parse("application/octet-stream")); + builder.addFormDataPart(fieldName, fileName, fileBody); + } + + return builder.build(); + } + + /** + * Get the current auth token + * + * @return Current auth token + */ + public String getToken() { + return token; + } + + /** + * Update the auth token + * + * @param token New auth token + */ + public void setToken(String token) { + this.token = token; + } + + /** + * Response class for impersonation + */ + private static class ImpersonateResponse { + String token; + JsonObject record; + } + + /** + * Response class for list operations + */ + public static class ListResult { + public int page; + public int perPage; + public int totalItems; + public int totalPages; + public List items; + } } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/pb/PocketBaseUtils.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/pb/PocketBaseUtils.java index 5c3d790..ed65221 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/pb/PocketBaseUtils.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/pb/PocketBaseUtils.java @@ -13,121 +13,121 @@ * Utility class for PocketBase operations */ public class PocketBaseUtils { - private static final Gson gson = new Gson(); + private static final Gson gson = new Gson(); - /** - * Converts a JsonObject to a specific class instance - * - * @param json The JsonObject to convert - * @param clazz The target class - * @param Target type - * @return An instance of the target class - */ - public static T jsonToClass(@NotNull JsonObject json, @NotNull Class clazz) { - return gson.fromJson(json, clazz); - } + /** + * Converts a JsonObject to a specific class instance + * + * @param json The JsonObject to convert + * @param clazz The target class + * @param Target type + * @return An instance of the target class + */ + public static T jsonToClass(@NotNull JsonObject json, @NotNull Class clazz) { + return gson.fromJson(json, clazz); + } - /** - * Converts a JsonObject to an instance of the specified type - * - * @param json The JsonObject to convert - * @param type The target type - * @param Target type - * @return An instance of the target type - */ - public static T jsonToType(@NotNull JsonObject json, @NotNull Type type) { - return gson.fromJson(json, type); - } + /** + * Converts a JsonObject to an instance of the specified type + * + * @param json The JsonObject to convert + * @param type The target type + * @param Target type + * @return An instance of the target type + */ + public static T jsonToType(@NotNull JsonObject json, @NotNull Type type) { + return gson.fromJson(json, type); + } - /** - * Converts a list of JsonObjects to a list of class instances - * - * @param jsonList The list of JsonObjects - * @param clazz The target class - * @param Target type - * @return A list of instances of the target class - */ - public static List jsonListToClass(@NotNull List jsonList, @NotNull Class clazz) { - return jsonList.stream() - .map(json -> jsonToClass(json, clazz)) - .collect(Collectors.toList()); - } + /** + * Converts a list of JsonObjects to a list of class instances + * + * @param jsonList The list of JsonObjects + * @param clazz The target class + * @param Target type + * @return A list of instances of the target class + */ + public static List jsonListToClass(@NotNull List jsonList, @NotNull Class clazz) { + return jsonList.stream() + .map(json -> jsonToClass(json, clazz)) + .collect(Collectors.toList()); + } - /** - * Gets a string value from JsonObject safely - * - * @param json JsonObject to get value from - * @param key Key to lookup - * @return String value or null if not found or not a string - */ - public static String getString(JsonObject json, String key) { - if (json == null || !json.has(key)) - return null; - JsonElement element = json.get(key); - return element.isJsonPrimitive() && element.getAsJsonPrimitive().isString() - ? element.getAsString() - : null; - } + /** + * Gets a string value from JsonObject safely + * + * @param json JsonObject to get value from + * @param key Key to lookup + * @return String value or null if not found or not a string + */ + public static String getString(JsonObject json, String key) { + if (json == null || !json.has(key)) + return null; + JsonElement element = json.get(key); + return element.isJsonPrimitive() && element.getAsJsonPrimitive().isString() + ? element.getAsString() + : null; + } - /** - * Gets an integer value from JsonObject safely - * - * @param json JsonObject to get value from - * @param key Key to lookup - * @return Integer value or null if not found or not a number - */ - public static Integer getInteger(JsonObject json, String key) { - if (json == null || !json.has(key)) - return null; - JsonElement element = json.get(key); - return element.isJsonPrimitive() && element.getAsJsonPrimitive().isNumber() - ? element.getAsInt() - : null; - } + /** + * Gets an integer value from JsonObject safely + * + * @param json JsonObject to get value from + * @param key Key to lookup + * @return Integer value or null if not found or not a number + */ + public static Integer getInteger(JsonObject json, String key) { + if (json == null || !json.has(key)) + return null; + JsonElement element = json.get(key); + return element.isJsonPrimitive() && element.getAsJsonPrimitive().isNumber() + ? element.getAsInt() + : null; + } - /** - * Gets a double value from JsonObject safely - * - * @param json JsonObject to get value from - * @param key Key to lookup - * @return Double value or null if not found or not a number - */ - public static Double getDouble(JsonObject json, String key) { - if (json == null || !json.has(key)) - return null; - JsonElement element = json.get(key); - return element.isJsonPrimitive() && element.getAsJsonPrimitive().isNumber() - ? element.getAsDouble() - : null; - } + /** + * Gets a double value from JsonObject safely + * + * @param json JsonObject to get value from + * @param key Key to lookup + * @return Double value or null if not found or not a number + */ + public static Double getDouble(JsonObject json, String key) { + if (json == null || !json.has(key)) + return null; + JsonElement element = json.get(key); + return element.isJsonPrimitive() && element.getAsJsonPrimitive().isNumber() + ? element.getAsDouble() + : null; + } - /** - * Gets a boolean value from JsonObject safely - * - * @param json JsonObject to get value from - * @param key Key to lookup - * @return Boolean value or null if not found or not a boolean - */ - public static Boolean getBoolean(JsonObject json, String key) { - if (json == null || !json.has(key)) - return null; - JsonElement element = json.get(key); - return element.isJsonPrimitive() && element.getAsJsonPrimitive().isBoolean() - ? element.getAsBoolean() - : null; - } + /** + * Gets a boolean value from JsonObject safely + * + * @param json JsonObject to get value from + * @param key Key to lookup + * @return Boolean value or null if not found or not a boolean + */ + public static Boolean getBoolean(JsonObject json, String key) { + if (json == null || !json.has(key)) + return null; + JsonElement element = json.get(key); + return element.isJsonPrimitive() && element.getAsJsonPrimitive().isBoolean() + ? element.getAsBoolean() + : null; + } - /** - * Gets a nested JsonObject safely - * - * @param json JsonObject to get value from - * @param key Key to lookup - * @return JsonObject or null if not found or not an object - */ - public static JsonObject getJsonObject(JsonObject json, String key) { - if (json == null || !json.has(key)) - return null; - JsonElement element = json.get(key); - return element.isJsonObject() ? element.getAsJsonObject() : null; - } + /** + * Gets a nested JsonObject safely + * + * @param json JsonObject to get value from + * @param key Key to lookup + * @return JsonObject or null if not found or not an object + */ + public static JsonObject getJsonObject(JsonObject json, String key) { + if (json == null || !json.has(key)) + return null; + JsonElement element = json.get(key); + return element.isJsonObject() ? element.getAsJsonObject() : null; + } } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigLoader.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigLoader.java index 44f2c43..6ec1b55 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigLoader.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigLoader.java @@ -1,4 +1,5 @@ package org.woftnw.dreamvisitor.util; + import org.jetbrains.annotations.NotNull; import org.yaml.snakeyaml.Yaml; @@ -16,63 +17,63 @@ * Utility class for loading YAML configuration files */ public class ConfigLoader { - private static final Logger logger = Logger.getLogger("DreamvisitorHub"); + private static final Logger logger = Logger.getLogger("DreamvisitorHub"); - private ConfigLoader() { - throw new IllegalStateException("Utility class"); - } + private ConfigLoader() { + throw new IllegalStateException("Utility class"); + } - /** - * Loads a YAML configuration file and returns it as a Map - * - * @param filePath path to the YAML file - * @return Map containing the configuration, or empty map if loading fails - */ - @NotNull - public static Map loadConfig(String filePath) { - try { - File configFile = new File(filePath); - if (!configFile.exists()) { - logger.warning("Config file not found at: " + filePath); - return new HashMap<>(); - } + /** + * Loads a YAML configuration file and returns it as a Map + * + * @param filePath path to the YAML file + * @return Map containing the configuration, or empty map if loading fails + */ + @NotNull + public static Map loadConfig(String filePath) { + try { + File configFile = new File(filePath); + if (!configFile.exists()) { + logger.warning("Config file not found at: " + filePath); + return new HashMap<>(); + } - Yaml yaml = new Yaml(); - InputStream inputStream = new FileInputStream(configFile); - Map config = yaml.load(inputStream); - logger.info("Successfully loaded config from: " + filePath); - return config != null ? config : new HashMap<>(); - } catch (FileNotFoundException e) { - logger.severe("Failed to load config file: " + e.getMessage()); - return new HashMap<>(); - } catch (Exception e) { - logger.severe("Error parsing config file: " + e.getMessage()); - return new HashMap<>(); + Yaml yaml = new Yaml(); + InputStream inputStream = new FileInputStream(configFile); + Map config = yaml.load(inputStream); + logger.info("Successfully loaded config from: " + filePath); + return config != null ? config : new HashMap<>(); + } catch (FileNotFoundException e) { + logger.severe("Failed to load config file: " + e.getMessage()); + return new HashMap<>(); + } catch (Exception e) { + logger.severe("Error parsing config file: " + e.getMessage()); + return new HashMap<>(); + } } - } - /** - * Saves a configuration map to a YAML file - * - * @param filePath path to the YAML file - * @param config the configuration map to save - * @return true if saving succeeded, false otherwise - */ - public static boolean saveConfig(String filePath, Map config) { - try { - File configFile = new File(filePath); - Yaml yaml = new Yaml(); - FileWriter writer = new FileWriter(configFile); - yaml.dump(config, writer); - writer.close(); - logger.info("Successfully saved config to: " + filePath); - return true; - } catch (IOException e) { - logger.severe("Failed to save config file: " + e.getMessage()); - return false; - } catch (Exception e) { - logger.severe("Error writing config file: " + e.getMessage()); - return false; + /** + * Saves a configuration map to a YAML file + * + * @param filePath path to the YAML file + * @param config the configuration map to save + * @return true if saving succeeded, false otherwise + */ + public static boolean saveConfig(String filePath, Map config) { + try { + File configFile = new File(filePath); + Yaml yaml = new Yaml(); + FileWriter writer = new FileWriter(configFile); + yaml.dump(config, writer); + writer.close(); + logger.info("Successfully saved config to: " + filePath); + return true; + } catch (IOException e) { + logger.severe("Failed to save config file: " + e.getMessage()); + return false; + } catch (Exception e) { + logger.severe("Error writing config file: " + e.getMessage()); + return false; + } } - } } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/PBConfigLoader.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/PBConfigLoader.java index 4d701ac..acbd4b7 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/PBConfigLoader.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/PBConfigLoader.java @@ -1,6 +1,8 @@ package org.woftnw.dreamvisitor.util; + import com.google.gson.JsonObject; import com.google.gson.JsonElement; + import java.io.IOException; import java.util.HashMap; import java.util.Map; @@ -13,108 +15,108 @@ * Utility class for loading configuration from PocketBase */ public class PBConfigLoader { - private static final Logger logger = Logger.getLogger("DreamvisitorHub"); - private static final String CONFIG_COLLECTION = "dreamvisitor_config"; - private static final String CONFIG_RECORD_ID = "45q1at367581q3a"; // Default record ID + private static final Logger logger = Logger.getLogger("DreamvisitorHub"); + private static final String CONFIG_COLLECTION = "dreamvisitor_config"; + private static final String CONFIG_RECORD_ID = "45q1at367581q3a"; // Default record ID - private PBConfigLoader() { - throw new IllegalStateException("Utility class"); - } + private PBConfigLoader() { + throw new IllegalStateException("Utility class"); + } - /** - * Loads configuration from PocketBase and returns it as a Map - * - * @param pocketBase The PocketBase instance to use - * @return Map containing the configuration, or empty map if loading fails - */ - public static Map loadConfig(PocketBase pocketBase) { - Map config = new HashMap<>(); - try { - // Fetch the configuration record from PocketBase - JsonObject configData = pocketBase.getRecord(CONFIG_COLLECTION, CONFIG_RECORD_ID, null, null); + /** + * Loads configuration from PocketBase and returns it as a Map + * + * @param pocketBase The PocketBase instance to use + * @return Map containing the configuration, or empty map if loading fails + */ + public static Map loadConfig(PocketBase pocketBase) { + Map config = new HashMap<>(); + try { + // Fetch the configuration record from PocketBase + JsonObject configData = pocketBase.getRecord(CONFIG_COLLECTION, CONFIG_RECORD_ID, null, null); - // Convert JsonObject to Map - for (String key : configData.keySet()) { - JsonElement element = configData.get(key); + // Convert JsonObject to Map + for (String key : configData.keySet()) { + JsonElement element = configData.get(key); - // Skip null values - we'll use file config for these - if (element.isJsonNull()) { - logger.fine("Skipping null value for key: " + key); - continue; - } + // Skip null values - we'll use file config for these + if (element.isJsonNull()) { + logger.fine("Skipping null value for key: " + key); + continue; + } - if (element.isJsonPrimitive()) { - if (element.getAsJsonPrimitive().isNumber()) { - config.put(key, element.getAsNumber()); - } else if (element.getAsJsonPrimitive().isBoolean()) { - config.put(key, element.getAsBoolean()); - } else { - config.put(key, element.getAsString()); - } - } - } + if (element.isJsonPrimitive()) { + if (element.getAsJsonPrimitive().isNumber()) { + config.put(key, element.getAsNumber()); + } else if (element.getAsJsonPrimitive().isBoolean()) { + config.put(key, element.getAsBoolean()); + } else { + config.put(key, element.getAsString()); + } + } + } - // Rename fields to match the expected format in the existing code - mapFieldNames(config); + // Rename fields to match the expected format in the existing code + mapFieldNames(config); - logger.info("Successfully loaded config from PocketBase"); - return config; - } catch (IOException e) { - logger.severe("Failed to load config from PocketBase: " + e.getMessage()); - return new HashMap<>(); - } catch (Exception e) { - logger.severe("Error parsing config from PocketBase: " + e.getMessage()); - return new HashMap<>(); + logger.info("Successfully loaded config from PocketBase"); + return config; + } catch (IOException e) { + logger.severe("Failed to load config from PocketBase: " + e.getMessage()); + return new HashMap<>(); + } catch (Exception e) { + logger.severe("Error parsing config from PocketBase: " + e.getMessage()); + return new HashMap<>(); + } } - } - /** - * Maps field names from PocketBase format to the format expected in the code - * - * @param config The configuration map to update - */ - private static void mapFieldNames(Map config) { - // Map PocketBase field names to the names expected in the application - renameField(config, "whitelist_channel", "whitelistChannelID"); - renameField(config, "game_chat_channel", "chatChannelID"); - renameField(config, "game_log_channel", "logChannelID"); - renameField(config, "resource_pack_repo", "resourcePackRepo"); - renameField(config, "shop_name", "shopName"); - // Ensure consistent handling of channel IDs - ensureChannelIdFormat(config, "whitelistChannelID"); - ensureChannelIdFormat(config, "chatChannelID"); - ensureChannelIdFormat(config, "logChannelID"); + /** + * Maps field names from PocketBase format to the format expected in the code + * + * @param config The configuration map to update + */ + private static void mapFieldNames(Map config) { + // Map PocketBase field names to the names expected in the application + renameField(config, "whitelist_channel", "whitelistChannelID"); + renameField(config, "game_chat_channel", "chatChannelID"); + renameField(config, "game_log_channel", "logChannelID"); + renameField(config, "resource_pack_repo", "resourcePackRepo"); + renameField(config, "shop_name", "shopName"); + // Ensure consistent handling of channel IDs + ensureChannelIdFormat(config, "whitelistChannelID"); + ensureChannelIdFormat(config, "chatChannelID"); + ensureChannelIdFormat(config, "logChannelID"); - // Add other field mappings as needed - } + // Add other field mappings as needed + } - /** - * Ensures that channel ID fields are consistently stored as Strings - * - * @param config The configuration map - * @param fieldName The field name to check - */ - private static void ensureChannelIdFormat(@NotNull Map config, String fieldName) { - if (config.containsKey(fieldName)) { - Object value = config.get(fieldName); - if (value instanceof Number) { - // Convert Number to String to ensure consistent handling - config.put(fieldName, String.valueOf(((Number) value).longValue())); - } + /** + * Ensures that channel ID fields are consistently stored as Strings + * + * @param config The configuration map + * @param fieldName The field name to check + */ + private static void ensureChannelIdFormat(@NotNull Map config, String fieldName) { + if (config.containsKey(fieldName)) { + Object value = config.get(fieldName); + if (value instanceof Number) { + // Convert Number to String to ensure consistent handling + config.put(fieldName, String.valueOf(((Number) value).longValue())); + } + } } - } - /** - * Renames a field in the configuration map - * - * @param config The configuration map - * @param oldName The old field name - * @param newName The new field name - */ - private static void renameField(@NotNull Map config, String oldName, String newName) { - if (config.containsKey(oldName)) { - config.put(newName, config.get(oldName)); - config.remove(oldName); + /** + * Renames a field in the configuration map + * + * @param config The configuration map + * @param oldName The old field name + * @param newName The new field name + */ + private static void renameField(@NotNull Map config, String oldName, String newName) { + if (config.containsKey(oldName)) { + config.put(newName, config.get(oldName)); + config.remove(oldName); + } } - } } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/UUIDFromater.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/UUIDFromater.java index 502041b..a7eab02 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/UUIDFromater.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/UUIDFromater.java @@ -4,18 +4,18 @@ import org.jetbrains.annotations.NotNull; public class UUIDFromater { - /** - * Adds the hyphens back into a String UUID. - * - * @param uuid the UUID as a {@link String} without hyphens. - * @return a UUID as a string with hyphens. - */ - @NotNull - @Contract(pure = true) - public static String formatUuid(@NotNull String uuid) { + /** + * Adds the hyphens back into a String UUID. + * + * @param uuid the UUID as a {@link String} without hyphens. + * @return a UUID as a string with hyphens. + */ + @NotNull + @Contract(pure = true) + public static String formatUuid(@NotNull String uuid) { - return uuid.replaceFirst( - "(\\p{XDigit}{8})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}+)", - "$1-$2-$3-$4-$5"); - } + return uuid.replaceFirst( + "(\\p{XDigit}{8})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}+)", + "$1-$2-$3-$4-$5"); + } } From 7bfcb0fabf6ddeba80eaeac1ba8107a0e6c0d069 Mon Sep 17 00:00:00 2001 From: Bog Date: Sun, 29 Jun 2025 17:28:05 -0700 Subject: [PATCH 13/39] Fix docs error --- .../org/woftnw/dreamvisitor/data/repository/UserRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserRepository.java index 42c397f..13ffe3e 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserRepository.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserRepository.java @@ -83,7 +83,7 @@ public interface UserRepository { /** * Get all users that match a given condition * - * @param predicate Condition to filter users + * @param filter Condition to filter users * @return List of users matching the condition */ List getAllWhere(String filter); From c8264b8e86e1f110dfd181c05e0ecb5a0c764296 Mon Sep 17 00:00:00 2001 From: Bog Date: Sun, 29 Jun 2025 17:36:09 -0700 Subject: [PATCH 14/39] Catch onEnable exceptions individually --- .../org/woftnw/dreamvisitor/Dreamvisitor.java | 288 +++++++++--------- .../woftnw/dreamvisitor/data/BadWords.java | 2 +- .../woftnw/dreamvisitor/data/PlayerTribe.java | 2 +- .../dreamvisitor/functions/ItemBanList.java | 5 +- 4 files changed, 149 insertions(+), 148 deletions(-) diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java index 5192521..159a2be 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java @@ -16,8 +16,6 @@ import org.woftnw.dreamvisitor.functions.worldguard.DragonFlightFlag; import org.woftnw.dreamvisitor.functions.worldguard.WitherFlag; import org.woftnw.dreamvisitor.listeners.*; -import org.woftnw.dreamvisitor.pb.PocketBase; -import org.woftnw.dreamvisitor.pb.PocketBaseUtils; import org.woftnw.dreamvisitor.util.ConfigKey; import net.luckperms.api.LuckPerms; import org.apache.logging.log4j.LogManager; @@ -46,10 +44,8 @@ public class Dreamvisitor extends JavaPlugin { public static boolean chatPaused; public static int playerLimit; public static Location hubLocation; - public static boolean webWhitelistEnabled; public static boolean debugMode; private static ConsoleLogger appender; - public final String VERSION = getDescription().getVersion(); public static StateFlag DRAGON_FLIGHT; public static StateFlag WITHER; @@ -115,182 +111,188 @@ public void onLoad() { @Override public void onEnable() { + PLUGIN = this; + + debugMode = Config.get(ConfigKey.DEBUG); + + checkConfig(); + + Messager.debug("Initializing PocketBase config loader..."); + Config.init(); + + Messager.debug("Registering listeners..."); + registerListeners(); + + List commands = new ArrayList<>(); + commands.add(new CmdAdminRadio()); + commands.add(new CmdDiscord()); + commands.add(new CmdHub()); + commands.add(new CmdPanic()); + commands.add(new CmdPauseBypass()); + commands.add(new CmdPausechat()); + commands.add(new CmdPlayerlimit()); + commands.add(new CmdRadio()); + commands.add(new CmdSethub()); + commands.add(new CmdSoftwhitelist()); + commands.add(new CmdTagRadio()); + commands.add(new CmdZoop()); + commands.add(new CmdItemBanList()); + commands.add(new CmdUser()); + commands.add(new CmdTribeUpdate()); + commands.add(new CmdUnwax()); + commands.add(new CmdScheduleRestart()); + commands.add(new CmdInvSwap()); + commands.add(new CmdDvset()); + commands.add(new CmdSetmotd()); + commands.add(new CmdSynctime()); + commands.add(new CmdSandbox()); + commands.add(new CmdMoonglobe()); + commands.add(new CmdSetback()); + commands.add(new CmdParcel()); + commands.add(new CmdDreamvisitor()); + commands.add(new CmdChatback()); + commands.add(new CmdVelocity()); + commands.add(new CmdSchedule()); + + Messager.debug("Initializing commands..."); + CommandAPI.onLoad(new CommandAPIBukkitConfig(this).silentLogs(!debugMode)); + CommandAPI.onEnable(); + registerCommands(commands); + + Messager.debug("Creating data folder..."); + boolean directoryCreated = getDataFolder().mkdir(); + if (!directoryCreated) + Messager.debug("Dreamvisitor did not create a data folder. It may already exist."); + saveDefaultConfig(); + + Messager.debug("Initializing mail.yml"); try { - PLUGIN = this; - - debugMode = Config.get(ConfigKey.DEBUG); - - checkConfig(); - - Messager.debug("Initializing PocketBase config loader..."); - Config.init(); - - Messager.debug("Registering listeners..."); - registerListeners(); - - List commands = new ArrayList<>(); - commands.add(new CmdAdminRadio()); - commands.add(new CmdDiscord()); - commands.add(new CmdHub()); - commands.add(new CmdPanic()); - commands.add(new CmdPauseBypass()); - commands.add(new CmdPausechat()); - commands.add(new CmdPlayerlimit()); - commands.add(new CmdRadio()); - commands.add(new CmdSethub()); - commands.add(new CmdSoftwhitelist()); - commands.add(new CmdTagRadio()); - commands.add(new CmdZoop()); - commands.add(new CmdItemBanList()); - commands.add(new CmdUser()); - commands.add(new CmdTribeUpdate()); - commands.add(new CmdUnwax()); - commands.add(new CmdScheduleRestart()); - commands.add(new CmdInvSwap()); - commands.add(new CmdDvset()); - commands.add(new CmdSetmotd()); - commands.add(new CmdSynctime()); - commands.add(new CmdSandbox()); - commands.add(new CmdMoonglobe()); - commands.add(new CmdSetback()); - commands.add(new CmdParcel()); - commands.add(new CmdDreamvisitor()); - commands.add(new CmdChatback()); - commands.add(new CmdVelocity()); - commands.add(new CmdSchedule()); - - Messager.debug("Initializing commands..."); - CommandAPI.onLoad(new CommandAPIBukkitConfig(this).silentLogs(!debugMode)); - CommandAPI.onEnable(); - registerCommands(commands); - - Messager.debug("Creating data folder..."); - boolean directoryCreated = getDataFolder().mkdir(); - if (!directoryCreated) - Messager.debug("Dreamvisitor did not create a data folder. It may already exist."); - saveDefaultConfig(); - - Messager.debug("Initializing mail.yml"); Mail.init(); + } catch (IOException e) { + getLogger().warning("Unable to mail locations from " + PlayerTribe.file + ": " + e.getMessage()); + } - Messager.debug("Initializing player-tribes.yml"); + Messager.debug("Initializing player-tribes.yml"); + try { PlayerTribe.setup(); + } catch (IOException e) { + getLogger().warning("Unable to load tribes from " + PlayerTribe.file + ": " + e.getMessage()); + } - Messager.debug("Initializing energy"); - Flight.init(); + Messager.debug("Initializing energy"); + Flight.init(); - Messager.debug("Initializing command scheduler"); - CommandScheduler.getInstance().loadConfig(); + Messager.debug("Initializing command scheduler"); + CommandScheduler.getInstance().loadConfig(); - Messager.debug("Initializing badwords.yml"); + Messager.debug("Initializing badwords.yml"); + try { BadWords.init(); + } catch (IOException e) { + getLogger().warning("Unable to load bad words from " + BadWords.file + ": " + e.getMessage()); + } - RegisteredServiceProvider provider = Bukkit.getServicesManager().getRegistration(LuckPerms.class); - if (provider != null) - luckperms = provider.getProvider(); + RegisteredServiceProvider provider = Bukkit.getServicesManager().getRegistration(LuckPerms.class); + if (provider != null) + luckperms = provider.getProvider(); - SessionManager sessionManager = WorldGuard.getInstance().getPlatform().getSessionManager(); - sessionManager.registerHandler(DragonFlightFlag.FACTORY, null); - sessionManager.registerHandler(WitherFlag.FACTORY, null); + SessionManager sessionManager = WorldGuard.getInstance().getPlatform().getSessionManager(); + sessionManager.registerHandler(DragonFlightFlag.FACTORY, null); + sessionManager.registerHandler(WitherFlag.FACTORY, null); - getLogger().log(Level.INFO, "Dreamvisitor: A plugin created by Bog for Wings of Fire: The New World to add various features."); + getLogger().log(Level.INFO, "Dreamvisitor: A plugin created by Bog for Wings of Fire: The New World to add various features."); - Messager.debug("Restoring chat pause..."); - if (Config.get(ConfigKey.PAUSE_CHAT)) { - chatPaused = true; - getLogger().info("Chat is currently paused from last session! Use /pausechat to allow users to chat."); - } + Messager.debug("Restoring chat pause..."); + if (Config.get(ConfigKey.PAUSE_CHAT)) { + chatPaused = true; + getLogger().info("Chat is currently paused from last session! Use /pausechat to allow users to chat."); + } - Messager.debug("Restoring player limit override..."); - playerLimit = Config.get(ConfigKey.PLAYER_LIMIT); - getLogger().info("Player limit override is currently set to " + playerLimit); + Messager.debug("Restoring player limit override..."); + playerLimit = Config.get(ConfigKey.PLAYER_LIMIT); + getLogger().info("Player limit override is currently set to " + playerLimit); - Messager.debug("Restoring item banlist..."); + Messager.debug("Restoring item banlist..."); + try { ItemBanList.init(); + } catch (IOException e) { + getLogger().warning("Unable to load banned items from " + ItemBanList.file + ": " + e.getMessage()); + } - Messager.debug("Setting up console logging..."); - appender = new ConsoleLogger(); - logger.addAppender(appender); + Messager.debug("Setting up console logging..."); + appender = new ConsoleLogger(); + logger.addAppender(appender); - Runnable pushConsole = new BukkitRunnable() { - @Override - public void run() { - if (Config.get(ConfigKey.LOG_CONSOLE)) { + Runnable pushConsole = new BukkitRunnable() { + @Override + public void run() { + if (Config.get(ConfigKey.LOG_CONSOLE)) { - } } - }; - - Runnable scheduledRestarts = new BukkitRunnable() { - @Override - public void run() { - Config.loadConfig(); + } + }; - if (AutoRestart.isAutoRestart() && Bukkit.getOnlinePlayers().isEmpty()) { - AutoRestart.sendAutoRestartMessage(); - getLogger().info("Restarting the server as scheduled."); - getServer().spigot().restart(); - } + Runnable scheduledRestarts = new BukkitRunnable() { + @Override + public void run() { + Config.loadConfig(); - long maxMemory = Runtime.getRuntime().maxMemory(); - long freeMemory = Runtime.getRuntime().freeMemory(); - double freeMemoryPercent = ((double) freeMemory / maxMemory) * 100; - if (freeMemoryPercent <= 10) { - AutoRestart.enableAutoRestart(null); - getLogger() - .warning("Dreamvisitor scheduled a restart because free memory usage is at or less than 10%."); - } + if (AutoRestart.isAutoRestart() && Bukkit.getOnlinePlayers().isEmpty()) { + AutoRestart.sendAutoRestartMessage(); + getLogger().info("Restarting the server as scheduled."); + getServer().spigot().restart(); } - }; - Runnable tick = new BukkitRunnable() { - @Override - public void run() { - Moonglobe.tick(); + long maxMemory = Runtime.getRuntime().maxMemory(); + long freeMemory = Runtime.getRuntime().freeMemory(); + double freeMemoryPercent = ((double) freeMemory / maxMemory) * 100; + if (freeMemoryPercent <= 10) { + AutoRestart.enableAutoRestart(null); + getLogger() + .warning("Dreamvisitor scheduled a restart because free memory usage is at or less than 10%."); } - }; - - Runnable checkBannedItems = new BukkitRunnable() { - @Override - public void run() { - for (Player player : Bukkit.getOnlinePlayers()) { - if (!player.isOp() && ItemBanList.badItems != null) { + } + }; - for (ItemStack item : ItemBanList.badItems) { - if (item == null) + Runnable tick = new BukkitRunnable() { + @Override + public void run() { + Moonglobe.tick(); + } + }; + + Runnable checkBannedItems = new BukkitRunnable() { + @Override + public void run() { + for (Player player : Bukkit.getOnlinePlayers()) { + if (!player.isOp() && ItemBanList.badItems != null) { + + for (ItemStack item : ItemBanList.badItems) { + if (item == null) + continue; + for (ItemStack content : player.getInventory().getContents()) { + if (content == null || !content.isSimilar(item)) continue; - for (ItemStack content : player.getInventory().getContents()) { - if (content == null || !content.isSimilar(item)) - continue; - player.getInventory().remove(item); - getLogger().info("Removed " + item.getType().name() + " (" - + Objects.requireNonNull(item.getItemMeta()).getDisplayName() + ") from " + player.getName()); - } + player.getInventory().remove(item); + getLogger().info("Removed " + item.getType().name() + " (" + + Objects.requireNonNull(item.getItemMeta()).getDisplayName() + ") from " + player.getName()); } } } } - }; - - Bukkit.getScheduler().runTaskTimer(this, tick, 0, 0); - - Bukkit.getScheduler().runTaskTimer(this, scheduledRestarts, 200, 1200); + } + }; - Bukkit.getScheduler().runTaskTimer(this, checkBannedItems, 40, 20 * 10); + Bukkit.getScheduler().runTaskTimer(this, tick, 0, 0); - Messager.debug("Enable finished."); - } catch (Exception e) { + Bukkit.getScheduler().runTaskTimer(this, scheduledRestarts, 200, 1200); - getLogger() - .severe("Dreamvisitor was unable to start :(\nPlease notify Bog with the following stack trace:"); - e.printStackTrace(); + Bukkit.getScheduler().runTaskTimer(this, checkBannedItems, 40, 20 * 10); - Bukkit.getPluginManager().disablePlugin(this); - throw new RuntimeException(); + Messager.debug("Enable finished."); - } } private void checkConfig() { diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/BadWords.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/BadWords.java index 2b3537f..56829c6 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/BadWords.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/BadWords.java @@ -11,7 +11,7 @@ public class BadWords { - static final File file = new File(Dreamvisitor.getPlugin().getDataFolder().getPath() + "/badWords.yml"); + public static final File file = new File(Dreamvisitor.getPlugin().getDataFolder().getPath() + "/badWords.yml"); public static void init() throws IOException { // If the file does not exist, create one diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/PlayerTribe.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/PlayerTribe.java index 1ab7c19..48d9d4f 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/PlayerTribe.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/PlayerTribe.java @@ -22,7 +22,7 @@ public class PlayerTribe { private static final Dreamvisitor plugin = Dreamvisitor.getPlugin(); - private static final File file = new File(plugin.getDataFolder(), "player-tribes.yml"); + public static final File file = new File(plugin.getDataFolder(), "player-tribes.yml"); /** * Initializes the player tribe storage. diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ItemBanList.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ItemBanList.java index 2fecd68..9117cb8 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ItemBanList.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ItemBanList.java @@ -20,9 +20,9 @@ public class ItemBanList implements Listener { public static final Inventory inv = Bukkit.createInventory(null, 27, "Banned Items"); - public static List badItems; + public static List badItems = new ArrayList<>(); - static final File file = new File(Dreamvisitor.getPlugin().getDataFolder().getPath() + "/bannedItems.yml"); + public static final File file = new File(Dreamvisitor.getPlugin().getDataFolder().getPath() + "/bannedItems.yml"); static FileConfiguration config = YamlConfiguration.loadConfiguration(file); public static void init() throws IOException { @@ -41,7 +41,6 @@ public static void init() throws IOException { badItems = (List) config.getList("items", new ArrayList<>()); } catch (Exception e) { Dreamvisitor.getPlugin().getLogger().warning("Unable to restore item ban list."); - badItems = new ArrayList<>(); } } From d00eef05ab1c492da13d979bb99d0e54a73f9fd1 Mon Sep 17 00:00:00 2001 From: Bog Date: Sun, 29 Jun 2025 19:58:48 -0700 Subject: [PATCH 15/39] Add comments and formatting --- .../org/woftnw/dreamvisitor/Dreamvisitor.java | 57 +++-- .../org/woftnw/dreamvisitor/data/Config.java | 240 +++++++++--------- .../repository/PocketBaseUserRepository.java | 4 +- .../woftnw/dreamvisitor/util/ConfigKey.java | 3 + .../dreamvisitor/util/ConfigLoader.java | 3 +- .../dreamvisitor/util/UUIDFromater.java | 21 -- 6 files changed, 166 insertions(+), 162 deletions(-) delete mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/UUIDFromater.java diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java index 159a2be..6cae565 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java @@ -16,6 +16,7 @@ import org.woftnw.dreamvisitor.functions.worldguard.DragonFlightFlag; import org.woftnw.dreamvisitor.functions.worldguard.WitherFlag; import org.woftnw.dreamvisitor.listeners.*; +import org.woftnw.dreamvisitor.pb.PocketBase; import org.woftnw.dreamvisitor.util.ConfigKey; import net.luckperms.api.LuckPerms; import org.apache.logging.log4j.LogManager; @@ -28,6 +29,7 @@ import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitRunnable; import org.jetbrains.annotations.NotNull; +import org.woftnw.dreamvisitor.util.PBConfigLoader; import java.io.IOException; import java.util.*; @@ -40,6 +42,7 @@ public class Dreamvisitor extends JavaPlugin { .getRootLogger(); public static Dreamvisitor PLUGIN; public static LuckPerms luckperms; + public static PocketBase pocketBase; public static String MOTD = null; public static boolean chatPaused; public static int playerLimit; @@ -72,8 +75,11 @@ public static LuckPerms getLuckPerms() throws NullPointerException { @Override public void onLoad() { + // Register WorldGuard flags try { + // Get registry FlagRegistry registry = WorldGuard.getInstance().getFlagRegistry(); + // Create and register dragon-flight flag try { StateFlag flag = new StateFlag("dragon-flight", true); registry.register(flag); @@ -88,6 +94,7 @@ public void onLoad() { .severe("A flag with the name dragon-flight already exists! Some other plugin claimed it already :("); } } + // Create and register dragon-flight flag try { StateFlag flag = new StateFlag("wither", true); registry.register(flag); @@ -102,9 +109,9 @@ public void onLoad() { } } } catch (NoClassDefFoundError e) { - getLogger().info("WorldGuard is not installed, so no flags will be created."); + getLogger().warning("WorldGuard is not installed, so no flags will be created."); } catch (IllegalStateException e) { - getLogger().warning("New WorldGuard flags cannot be registered at this time. You may not have WorldGuard installed."); + getLogger().warning("New WorldGuard flags cannot be registered at this time: " + e.getMessage()); } } @@ -113,12 +120,16 @@ public void onEnable() { PLUGIN = this; - debugMode = Config.get(ConfigKey.DEBUG); + // Can't use debug messages until debug mode is enabled, so these first two are normal info messages. + getLogger().info("Checking local config file..."); checkConfig(); - Messager.debug("Initializing PocketBase config loader..."); + getLogger().info("Initializing PocketBase config loader..."); Config.init(); + getLogger().info("Configuration fetched. Starting enable."); + + debugMode = Config.get(ConfigKey.DEBUG); Messager.debug("Registering listeners..."); registerListeners(); @@ -154,9 +165,12 @@ public void onEnable() { commands.add(new CmdVelocity()); commands.add(new CmdSchedule()); - Messager.debug("Initializing commands..."); + // CommandAPI is shaded into Dreamvisitor, so it must be loaded and enabled. + Messager.debug("Loading the CommandAPI..."); CommandAPI.onLoad(new CommandAPIBukkitConfig(this).silentLogs(!debugMode)); + Messager.debug("Enabling the CommandAPI..."); CommandAPI.onEnable(); + Messager.debug("Registering " + commands.size() + " commands..."); registerCommands(commands); Messager.debug("Creating data folder..."); @@ -192,16 +206,16 @@ public void onEnable() { getLogger().warning("Unable to load bad words from " + BadWords.file + ": " + e.getMessage()); } + Messager.debug("Initializing LuckPerms API..."); RegisteredServiceProvider provider = Bukkit.getServicesManager().getRegistration(LuckPerms.class); if (provider != null) luckperms = provider.getProvider(); + Messager.debug("Registering WorldGuard flag handlers..."); SessionManager sessionManager = WorldGuard.getInstance().getPlatform().getSessionManager(); sessionManager.registerHandler(DragonFlightFlag.FACTORY, null); sessionManager.registerHandler(WitherFlag.FACTORY, null); - getLogger().log(Level.INFO, "Dreamvisitor: A plugin created by Bog for Wings of Fire: The New World to add various features."); - Messager.debug("Restoring chat pause..."); if (Config.get(ConfigKey.PAUSE_CHAT)) { chatPaused = true; @@ -223,6 +237,8 @@ public void onEnable() { appender = new ConsoleLogger(); logger.addAppender(appender); + Messager.debug("Setting up schedules..."); + Runnable pushConsole = new BukkitRunnable() { @Override public void run() { @@ -291,18 +307,14 @@ public void run() { Bukkit.getScheduler().runTaskTimer(this, checkBannedItems, 40, 20 * 10); - Messager.debug("Enable finished."); + getLogger().log(Level.INFO, "Dreamvisitor has been enabled."); } + /** + * Checks the config.yml file and sets default values if they do not exist. + */ private void checkConfig() { -// if (getConfig().getLongList("triberoles").size() != 10) -// throw new InvalidConfigurationException("triberoles must contain exactly 10 entries."); -// if (getConfig().getInt("playerlimit") < -1) -// getConfig().set("playerlimit", -1); -// if (getConfig().getInt("infraction-expire-time-days") < 1) -// throw new InvalidConfigurationException("infraction-expire-time-days must be at least 1."); - if (!getConfig().contains("pocketbaseUrl")) { getConfig().set("pocketbaseUrl", "http://127.0.0.1:8090/"); } @@ -319,6 +331,9 @@ private void checkConfig() { saveConfig(); } + /** + * Registers listeners so that they can receive events. + */ private void registerListeners() { PluginManager pluginManager = getServer().getPluginManager(); pluginManager.registerEvents(new ListenEntityDamage(), this); @@ -342,6 +357,9 @@ private void registerListeners() { pluginManager.registerEvents(new ListenCreatureSpawn(), this); } + /** + * Registers commands using CommandAPI. + */ private void registerCommands(@NotNull List commands) throws NullPointerException { for (DVCommand command : commands) { if (command.getCommand() instanceof CommandAPICommand apiCommand) { @@ -355,14 +373,17 @@ private void registerCommands(@NotNull List commands) throws NullPoin @Override public void onDisable() { + // Disable CommandAPI CommandAPI.onDisable(); // Shutdown the realtime updater RealtimeConfigUpdater.shutdown(); + // Remove any active moon globes for (Moonglobe moonglobe : Moonglobe.activeMoonglobes) moonglobe.remove(null); + // Save all player memory for (Player player : Bukkit.getOnlinePlayers()) { try { PlayerUtility.savePlayerMemory(player.getUniqueId()); @@ -374,10 +395,16 @@ public void onDisable() { } } + // Save and shutdown the Command Scheduler CommandScheduler.getInstance().saveConfig(); CommandScheduler.getInstance().stopScheduler(); + // Unattach the server logger logger.removeAppender(appender); + + // TODO: Send shutdown signal to PocketBase. + + getLogger().info("Dreamvisitor has been disabled."); } } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/Config.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/Config.java index 7dd154e..1699119 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/Config.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/Config.java @@ -18,148 +18,142 @@ import java.util.concurrent.CompletableFuture; public class Config { - private static JSONObject config; - private static String baseUrl; - private static String configId; - private static String token; - private static boolean useRealtime = true; - private static PocketBase pocketBaseClient; - private static final String COLLECTION_NAME = "dreamvisitor_config"; - - public static void init() { - FileConfiguration pluginConfig = Dreamvisitor.getPlugin().getConfig(); - baseUrl = pluginConfig.getString("pocketbaseUrl", "http://127.0.0.1:8090/"); - configId = pluginConfig.getString("pocketbaseConfigId", ""); - token = pluginConfig.getString("pocketbaseToken", ""); - useRealtime = pluginConfig.getBoolean("pocketbaseUseRealtime", true); - - if (baseUrl.isEmpty() || configId.isEmpty()) { - Bukkit.getLogger().warning("PocketBase URL or config ID not configured in plugin config."); - return; - } + private static JSONObject config; + private static String baseUrl; + private static String configId; + private static String token; + private static boolean useRealtime = true; + private static PocketBase pocketBaseClient; + private static final String COLLECTION_NAME = "dreamvisitor_config"; + + public static void init() { + FileConfiguration pluginConfig = Dreamvisitor.getPlugin().getConfig(); + baseUrl = pluginConfig.getString("pocketbaseUrl", "http://127.0.0.1:8090/"); + configId = pluginConfig.getString("pocketbaseConfigId", ""); + token = pluginConfig.getString("pocketbaseToken", ""); + useRealtime = pluginConfig.getBoolean("pocketbaseUseRealtime", true); + + if (baseUrl.isEmpty() || configId.isEmpty()) { + throw new NullPointerException("Missing PocketBase URL or Config ID"); + } - // Create PocketBase client from config - try { - Map pbConfig = new HashMap<>(); - pbConfig.put("pocketbaseUrl", baseUrl); - pbConfig.put("pocketbaseToken", token); - pocketBaseClient = PocketBase.fromConfig(pbConfig); - - Messager.debug("Initialized PocketBase client"); - } catch (Exception e) { - Bukkit.getLogger().warning("Failed to initialize PocketBase client: " + e.getMessage()); - return; - } + // Create PocketBase client from config + Map pbConfig = new HashMap<>(); + pbConfig.put("pocketbaseUrl", baseUrl); + pbConfig.put("pocketbaseToken", token); + pocketBaseClient = PocketBase.fromConfig(pbConfig); + + Messager.debug("Initialized PocketBase client"); - // Initial config load - loadConfig(); + // Initial config load + loadConfig(); - // Start realtime updates if enabled - if (useRealtime) { - RealtimeConfigUpdater.init(baseUrl, configId, token); + // Start realtime updates if enabled + if (useRealtime) { + RealtimeConfigUpdater.init(baseUrl, configId, token); + } } - } - public static void loadConfig() { - try { - if (pocketBaseClient == null) { - Dreamvisitor.getPlugin().getLogger().warning("PocketBase client not initialized, cannot load config"); - return; - } + public static void loadConfig() { + try { + if (pocketBaseClient == null) { + Dreamvisitor.getPlugin().getLogger().warning("PocketBase client not initialized, cannot load config"); + return; + } - // Get record using PocketBase client - JsonObject record = pocketBaseClient.getRecord(COLLECTION_NAME, configId, null, null); + // Get record using PocketBase client + JsonObject record = pocketBaseClient.getRecord(COLLECTION_NAME, configId, null, null); - // Convert from Gson JsonObject to org.json.JSONObject - String jsonString = record.toString(); - config = new JSONObject(jsonString); + // Convert from Gson JsonObject to org.json.JSONObject + String jsonString = record.toString(); + config = new JSONObject(jsonString); - Messager.debug("Loaded PocketBase configuration: " + config); + Messager.debug("Loaded PocketBase configuration: " + config); - // Apply config values to the system - applyConfig(); - } catch (IOException e) { - Bukkit.getLogger().warning("Error loading PocketBase config: " + e.getMessage()); - } - } - - public static void updateLocalConfig(JSONObject newConfigData) { - // Update our local config with new data - if (config != null) { - // Merge the new data into our existing config - for (String key : newConfigData.keySet()) { - config.put(key, newConfigData.get(key)); - } - - // Apply the updated config - applyConfig(); - } - } - - private static void applyConfig() { - // Apply configuration values to the relevant systems - if (config != null) { - // Handle autoRestart setting - if (config.has("autoRestart")) { - boolean autoRestart = config.getBoolean("autoRestart"); - if (autoRestart != AutoRestart.isAutoRestart()) { - if (autoRestart) { - AutoRestart.enableAutoRestart(null); - Messager.debug("Auto restart enabled from remote config"); - } else { - AutoRestart.disableAutoRestart(); - Messager.debug("Auto restart disabled from remote config"); - } + // Apply config values to the system + applyConfig(); + } catch (IOException e) { + Bukkit.getLogger().warning("Error loading PocketBase config: " + e.getMessage()); } - } + } - // Add more configuration handlers here as needed + public static void updateLocalConfig(JSONObject newConfigData) { + // Update our local config with new data + if (config != null) { + // Merge the new data into our existing config + for (String key : newConfigData.keySet()) { + config.put(key, newConfigData.get(key)); + } + + // Apply the updated config + applyConfig(); + } } - } - - @NotNull - @Contract("_, _ -> new") - public static CompletableFuture updateConfigField(String field, boolean value) { - return CompletableFuture.runAsync(() -> { - try { - if (pocketBaseClient == null) { - Bukkit.getLogger().warning("PocketBase client not initialized, cannot update config"); - return; + + private static void applyConfig() { + // Apply configuration values to the relevant systems + if (config != null) { + // Handle autoRestart setting + if (config.has("autoRestart")) { + boolean autoRestart = config.getBoolean("autoRestart"); + if (autoRestart != AutoRestart.isAutoRestart()) { + if (autoRestart) { + AutoRestart.enableAutoRestart(null); + Messager.debug("Auto restart enabled from remote config"); + } else { + AutoRestart.disableAutoRestart(); + Messager.debug("Auto restart disabled from remote config"); + } + } + } + + // Add more configuration handlers here as needed } + } - // Create update data object - JsonObject updateData = new JsonObject(); - updateData.addProperty(field, value); + @NotNull + @Contract("_, _ -> new") + public static CompletableFuture updateConfigField(String field, boolean value) { + return CompletableFuture.runAsync(() -> { + try { + if (pocketBaseClient == null) { + Bukkit.getLogger().warning("PocketBase client not initialized, cannot update config"); + return; + } + + // Create update data object + JsonObject updateData = new JsonObject(); + updateData.addProperty(field, value); + + // Update the record + pocketBaseClient.updateRecord(COLLECTION_NAME, configId, updateData, null, null); + + Messager.debug("Updated PocketBase configuration field " + field + " to " + value); + + // If not using realtime updates, we need to reload config manually + if (!useRealtime) { + loadConfig(); + } + } catch (IOException e) { + Dreamvisitor.getPlugin().getLogger().warning("Error updating PocketBase config: " + e.getMessage()); + } + }); + } - // Update the record - pocketBaseClient.updateRecord(COLLECTION_NAME, configId, updateData, null, null); + @SuppressWarnings("unchecked") + public static T get(@NotNull ConfigKey configKey) { + Object value = config.get(configKey.getKey()); - Messager.debug("Updated PocketBase configuration field " + field + " to " + value); + if (value == null) { + value = configKey.getDefaultValue(); + } - // If not using realtime updates, we need to reload config manually - if (!useRealtime) { - loadConfig(); + if (configKey.getType().isInstance(value)) { + return (T) value; } - } catch (IOException e) { - Dreamvisitor.getPlugin().getLogger().warning("Error updating PocketBase config: " + e.getMessage()); - } - }); - } - - @SuppressWarnings("unchecked") - public static T get(@NotNull ConfigKey configKey) { - Object value = config.get(configKey.getKey()); - - if (value == null) { - value = configKey.getDefaultValue(); - } - if (configKey.getType().isInstance(value)) { - return (T) value; + throw new IllegalStateException("Config value for key '" + configKey.getKey() + + "' is not of expected type: " + configKey.getType().getSimpleName()); } - throw new IllegalStateException("Config value for key '" + configKey.getKey() + - "' is not of expected type: " + configKey.getType().getSimpleName()); - } - } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserRepository.java index 079265f..3e8a58f 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserRepository.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserRepository.java @@ -4,9 +4,9 @@ import com.google.gson.JsonObject; import com.google.gson.reflect.TypeToken; +import org.woftnw.dreamvisitor.data.PlayerUtility; import org.woftnw.dreamvisitor.data.type.DVUser; import org.woftnw.dreamvisitor.pb.PocketBase; -import org.woftnw.dreamvisitor.util.UUIDFromater; import org.jetbrains.annotations.NotNull; @@ -187,7 +187,7 @@ private DVUser mapToUser(JsonObject json) { if (json.has("mc_uuid") && !json.get("mc_uuid").isJsonNull()) { try { - user.setMc_uuid(UUID.fromString(UUIDFromater.formatUuid(json.get("mc_uuid").getAsString()))); + user.setMc_uuid(UUID.fromString(PlayerUtility.formatUuid(json.get("mc_uuid").getAsString()))); } catch (IllegalArgumentException e) { LOGGER.warning("Invalid UUID format: " + json.get("mc_uuid").getAsString()); } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigKey.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigKey.java index f5691fa..3cbf380 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigKey.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigKey.java @@ -2,6 +2,9 @@ import org.bukkit.Location; +/** + * An enum that holds all the relevant configuration keys. Each key has a default value and a type. + */ public enum ConfigKey { DEBUG("debug", true, Boolean.class), // This is intentionally set to true because these default should typically only be used when no database is connected. diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigLoader.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigLoader.java index 6ec1b55..23b648e 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigLoader.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigLoader.java @@ -1,6 +1,7 @@ package org.woftnw.dreamvisitor.util; import org.jetbrains.annotations.NotNull; +import org.woftnw.dreamvisitor.Dreamvisitor; import org.yaml.snakeyaml.Yaml; import java.io.File; @@ -17,7 +18,7 @@ * Utility class for loading YAML configuration files */ public class ConfigLoader { - private static final Logger logger = Logger.getLogger("DreamvisitorHub"); + private static final Logger logger = Dreamvisitor.getPlugin().getLogger();; private ConfigLoader() { throw new IllegalStateException("Utility class"); diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/UUIDFromater.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/UUIDFromater.java deleted file mode 100644 index a7eab02..0000000 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/UUIDFromater.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.woftnw.dreamvisitor.util; - -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -public class UUIDFromater { - /** - * Adds the hyphens back into a String UUID. - * - * @param uuid the UUID as a {@link String} without hyphens. - * @return a UUID as a string with hyphens. - */ - @NotNull - @Contract(pure = true) - public static String formatUuid(@NotNull String uuid) { - - return uuid.replaceFirst( - "(\\p{XDigit}{8})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}+)", - "$1-$2-$3-$4-$5"); - } -} From aeadd37af99edb0323a7509ec987cb77043ab2ff Mon Sep 17 00:00:00 2001 From: Bog Date: Tue, 1 Jul 2025 11:45:18 -0700 Subject: [PATCH 16/39] Implement new data systems and cleanup code --- dreamvisitor/pom.xml | 2 +- .../org/woftnw/dreamvisitor/Dreamvisitor.java | 47 +- .../dreamvisitor/commands/CmdAdminRadio.java | 4 +- .../dreamvisitor/commands/CmdDiscord.java | 15 +- .../dreamvisitor/commands/CmdDvset.java | 426 ++-- .../woftnw/dreamvisitor/commands/CmdHub.java | 22 +- .../dreamvisitor/commands/CmdItemBanList.java | 2 +- .../dreamvisitor/commands/CmdMoonglobe.java | 10 +- .../dreamvisitor/commands/CmdParcel.java | 44 +- .../dreamvisitor/commands/CmdPauseBypass.java | 12 +- .../dreamvisitor/commands/CmdPlayerlimit.java | 2 +- .../dreamvisitor/commands/CmdRadio.java | 4 +- .../dreamvisitor/commands/CmdSandbox.java | 18 +- .../dreamvisitor/commands/CmdSchedule.java | 515 +++-- .../commands/CmdScheduleRestart.java | 27 - .../dreamvisitor/commands/CmdSetback.java | 13 +- .../dreamvisitor/commands/CmdSethub.java | 10 +- .../dreamvisitor/commands/CmdSetmotd.java | 4 +- .../commands/CmdSoftwhitelist.java | 12 +- .../dreamvisitor/commands/CmdSynctime.java | 15 +- .../dreamvisitor/commands/CmdTagRadio.java | 6 +- .../dreamvisitor/commands/CmdTribeUpdate.java | 9 +- .../dreamvisitor/commands/CmdUnwax.java | 2 +- .../woftnw/dreamvisitor/commands/CmdUser.java | 21 +- .../woftnw/dreamvisitor/commands/CmdZoop.java | 13 +- .../org/woftnw/dreamvisitor/data/Config.java | 27 +- .../dreamvisitor/data/PlayerUtility.java | 97 +- .../data/RealtimeConfigUpdater.java | 29 +- .../data/repository/ItemRepository.java | 71 - .../repository/PocketBaseItemRepository.java | 327 ---- .../PocketBaseServerLogsRepository.java | 103 + .../PocketBaseUserInventoryRepository.java | 319 --- .../repository/PocketBaseUserRepository.java | 189 +- .../data/repository/Repository.java | 124 ++ .../data/repository/RepositoryManager.java | 25 + .../data/repository/ServerLogsRepository.java | 26 + .../repository/UserInventoryRepository.java | 90 - .../data/repository/UserRepository.java | 12 +- .../data/repository/UsersHomesRepository.java | 60 + .../woftnw/dreamvisitor/data/type/DVUser.java | 267 ++- .../dreamvisitor/data/type/ServerLog.java | 63 + .../dreamvisitor/data/type/UserHome.java | 75 + .../dreamvisitor/functions/AutoRestart.java | 7 +- .../functions/CommandScheduler.java | 1730 +++++++++-------- .../dreamvisitor/functions/ConsoleLogger.java | 7 +- .../woftnw/dreamvisitor/functions/Flight.java | 70 +- .../dreamvisitor/functions/InvSwap.java | 22 +- .../dreamvisitor/functions/Sandbox.java | 73 +- .../listeners/ListenCreatureSpawn.java | 1 + .../listeners/ListenEntityDamage.java | 25 - ...vent.java => ListenEntityToggleGlide.java} | 4 +- .../listeners/ListenPlayerChangedWorld.java | 1 + .../listeners/ListenPlayerChat.java | 131 +- .../listeners/ListenPlayerCmdPreprocess.java | 40 +- .../listeners/ListenPlayerDropItem.java | 20 + .../listeners/ListenPlayerGameModeChange.java | 10 +- .../listeners/ListenPlayerInteract.java | 34 + .../listeners/ListenPlayerInteractEntity.java | 32 + .../listeners/ListenPlayerJoin.java | 13 +- .../listeners/ListenPlayerLogin.java | 10 +- .../listeners/ListenPlayerMoveEvent.java | 65 - .../listeners/ListenPlayerQuit.java | 17 +- ...ent.java => ListenPlayerToggleFlight.java} | 17 +- .../listeners/ListenServerPing.java | 2 + ...ChangeEvent.java => ListenSignChange.java} | 22 +- .../woftnw/dreamvisitor/util/ConfigKey.java | 1 - dreamvisitor/src/main/resources/plugin.yml | 2 +- 67 files changed, 2594 insertions(+), 2921 deletions(-) delete mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdScheduleRestart.java delete mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/ItemRepository.java delete mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseItemRepository.java create mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseServerLogsRepository.java delete mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserInventoryRepository.java create mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/Repository.java create mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/RepositoryManager.java create mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/ServerLogsRepository.java delete mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserInventoryRepository.java create mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UsersHomesRepository.java create mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/ServerLog.java create mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/UserHome.java delete mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenEntityDamage.java rename dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/{ListenEntityToggleGlideEvent.java => ListenEntityToggleGlide.java} (77%) create mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerDropItem.java create mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerInteract.java create mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerInteractEntity.java delete mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerMoveEvent.java rename dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/{ListenPlayerToggleFlightEvent.java => ListenPlayerToggleFlight.java} (67%) rename dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/{ListenSignChangeEvent.java => ListenSignChange.java} (56%) diff --git a/dreamvisitor/pom.xml b/dreamvisitor/pom.xml index dc69a29..e4fed3b 100644 --- a/dreamvisitor/pom.xml +++ b/dreamvisitor/pom.xml @@ -47,7 +47,7 @@ org.spigotmc spigot-api - 1.20.4-R0.1-SNAPSHOT + 1.21.4-R0.1-SNAPSHOT provided diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java index 6cae565..df10f1f 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java @@ -12,6 +12,7 @@ import dev.jorel.commandapi.CommandTree; import org.woftnw.dreamvisitor.commands.*; import org.woftnw.dreamvisitor.data.*; +import org.woftnw.dreamvisitor.data.repository.*; import org.woftnw.dreamvisitor.functions.*; import org.woftnw.dreamvisitor.functions.worldguard.DragonFlightFlag; import org.woftnw.dreamvisitor.functions.worldguard.WitherFlag; @@ -29,7 +30,6 @@ import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitRunnable; import org.jetbrains.annotations.NotNull; -import org.woftnw.dreamvisitor.util.PBConfigLoader; import java.io.IOException; import java.util.*; @@ -42,7 +42,6 @@ public class Dreamvisitor extends JavaPlugin { .getRootLogger(); public static Dreamvisitor PLUGIN; public static LuckPerms luckperms; - public static PocketBase pocketBase; public static String MOTD = null; public static boolean chatPaused; public static int playerLimit; @@ -50,6 +49,10 @@ public class Dreamvisitor extends JavaPlugin { public static boolean debugMode; private static ConsoleLogger appender; + PocketBase pocketBase; + + RepositoryManager repositoryManager; + public static StateFlag DRAGON_FLIGHT; public static StateFlag WITHER; @@ -130,6 +133,13 @@ public void onEnable() { getLogger().info("Configuration fetched. Starting enable."); debugMode = Config.get(ConfigKey.DEBUG); + Messager.debug("Debug mode is enabled."); + + Messager.debug("Ensuring auto-restart is disabled..."); + if (Config.get(ConfigKey.AUTO_RESTART)) Config.set(ConfigKey.AUTO_RESTART, false); + + Messager.debug("Setting up repositories..."); + repositoryManager = new RepositoryManager(pocketBase); Messager.debug("Registering listeners..."); registerListeners(); @@ -151,7 +161,6 @@ public void onEnable() { commands.add(new CmdUser()); commands.add(new CmdTribeUpdate()); commands.add(new CmdUnwax()); - commands.add(new CmdScheduleRestart()); commands.add(new CmdInvSwap()); commands.add(new CmdDvset()); commands.add(new CmdSetmotd()); @@ -301,12 +310,21 @@ public void run() { } }; + Runnable tickFlight = new Runnable() { + @Override + public void run() { + Flight.tick(); + } + }; + Bukkit.getScheduler().runTaskTimer(this, tick, 0, 0); Bukkit.getScheduler().runTaskTimer(this, scheduledRestarts, 200, 1200); Bukkit.getScheduler().runTaskTimer(this, checkBannedItems, 40, 20 * 10); + Bukkit.getScheduler().runTaskTimer(this, tickFlight, 0, 1); + getLogger().log(Level.INFO, "Dreamvisitor has been enabled."); } @@ -336,7 +354,6 @@ private void checkConfig() { */ private void registerListeners() { PluginManager pluginManager = getServer().getPluginManager(); - pluginManager.registerEvents(new ListenEntityDamage(), this); pluginManager.registerEvents(new ListenPlayerChat(), this); pluginManager.registerEvents(new ListenPlayerCmdPreprocess(), this); pluginManager.registerEvents(new ListenPlayerDeath(), this); @@ -348,10 +365,9 @@ private void registerListeners() { pluginManager.registerEvents(new ListenServerPing(), this); pluginManager.registerEvents(new Sandbox(), this); pluginManager.registerEvents(new ListenTimeSkip(), this); - pluginManager.registerEvents(new ListenSignChangeEvent(), this); - pluginManager.registerEvents(new ListenPlayerToggleFlightEvent(), this); - pluginManager.registerEvents(new ListenPlayerMoveEvent(), this); - pluginManager.registerEvents(new ListenEntityToggleGlideEvent(), this); + pluginManager.registerEvents(new ListenSignChange(), this); + pluginManager.registerEvents(new ListenPlayerToggleFlight(), this); + pluginManager.registerEvents(new ListenEntityToggleGlide(), this); pluginManager.registerEvents(new ListenPlayerChangedWorld(), this); pluginManager.registerEvents(new ListenPlayerRespawn(), this); pluginManager.registerEvents(new ListenCreatureSpawn(), this); @@ -383,18 +399,6 @@ public void onDisable() { for (Moonglobe moonglobe : Moonglobe.activeMoonglobes) moonglobe.remove(null); - // Save all player memory - for (Player player : Bukkit.getOnlinePlayers()) { - try { - PlayerUtility.savePlayerMemory(player.getUniqueId()); - PlayerUtility.clearPlayerMemory(player.getUniqueId()); - } catch (IOException e) { - getLogger().severe("Unable to save player memory! Does the server have write access?"); - if (Dreamvisitor.debugMode) - throw new RuntimeException(); - } - } - // Save and shutdown the Command Scheduler CommandScheduler.getInstance().saveConfig(); CommandScheduler.getInstance().stopScheduler(); @@ -407,4 +411,7 @@ public void onDisable() { getLogger().info("Dreamvisitor has been disabled."); } + public RepositoryManager getRepositoryManager() { + return repositoryManager; + } } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdAdminRadio.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdAdminRadio.java index 6114c04..9cb84be 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdAdminRadio.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdAdminRadio.java @@ -22,11 +22,11 @@ public class CmdAdminRadio implements DVCommand { .withHelp("Use the admin radio.", "Sends a message to all operators.") .withArguments(new GreedyStringArgument("message")) .executesNative(((sender, args) -> { - String message = (String) args.get("message"); + final String message = (String) args.get("message"); Messager.debug(sender.getClass().getName()); - CommandSender callee = sender.getCallee(); + final CommandSender callee = sender.getCallee(); if (callee instanceof Player player) { Radio.buildMessage(message, player.getName(), getCommand().getName(), null); } else if (callee instanceof ConsoleCommandSender) { diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdDiscord.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdDiscord.java index 3026325..c73cb6c 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdDiscord.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdDiscord.java @@ -2,8 +2,8 @@ import dev.jorel.commandapi.CommandAPI; import dev.jorel.commandapi.CommandAPICommand; -import org.woftnw.dreamvisitor.data.PlayerMemory; import org.woftnw.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.data.type.DVUser; import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -17,14 +17,17 @@ public CommandAPICommand getCommand() { return new CommandAPICommand("discord") .withHelp("Toggles Discord message visibility.", "Toggle whether messages from the Discord chat bridge appear in your chat.") .executesNative(((sender, args) -> { - CommandSender callee = sender.getCallee(); + final CommandSender callee = sender.getCallee(); if (callee instanceof Player player) { - PlayerMemory memory = PlayerUtility.getPlayerMemory(player.getUniqueId()); - memory.discordEnabled = !memory.discordEnabled; - Messager.send(player, "Discord visibility toggled to " + !memory.discordEnabled + "."); + final DVUser user = PlayerUtility.getUser(player); + + user.setShowDiscordMessages(!user.isShowDiscordOn()); + + Messager.send(player, "Discord visibility toggled to " + user.isShowDiscordOn() + "."); + + PlayerUtility.saveUser(user); - PlayerUtility.setPlayerMemory(player.getUniqueId(), memory); } else throw CommandAPI.failWithString("This command must be executed as a player!"); diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdDvset.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdDvset.java index 895bcc2..291c765 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdDvset.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdDvset.java @@ -2,8 +2,8 @@ import dev.jorel.commandapi.*; import dev.jorel.commandapi.arguments.StringArgument; -import org.woftnw.dreamvisitor.data.PlayerMemory; import org.woftnw.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.data.type.DVUser; import org.woftnw.dreamvisitor.functions.Messager; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.*; @@ -16,226 +16,226 @@ public class CmdDvset implements DVCommand { - private static void sendUserGui(@NotNull Player player) { + private static void sendUserGui(@NotNull Player player) { + + DVUser user = PlayerUtility.getUser(player); + + ComponentBuilder builder = new ComponentBuilder(); + builder.append("User Options "); + + if (player.hasPermission("dreamvisitor.set.discord")) { + builder.append("\n\nDiscord Visibility: ").color(ChatColor.WHITE) + .append("\nWhether to show messages from Discord's chat bridge.").color(ChatColor.GRAY) + .append("\n[").color(ChatColor.DARK_GRAY) + .append(booleanToggle(user.isShowDiscordOn(), "discord")) + .append("").reset().append("]").color(ChatColor.DARK_GRAY); + } + + if (player.hasPermission("dreamvisitor.set.flight")) { + builder.append("\n\nFlight Disabled: ").color(ChatColor.WHITE) + .append("\nWhether Flight Mode cannot be activated.").color(ChatColor.GRAY) + .append("\n[").color(ChatColor.DARK_GRAY) + .append(booleanToggle(user.isFlightDisabled(), "flight")) + .append("").reset().append("]").color(ChatColor.DARK_GRAY); + } + + if (player.hasPermission("dreamvisitor.set.zoop")) { + builder.append("\n\nDiscord Vanish: ").color(ChatColor.WHITE) + .append("\nWhether to appear offline in Dreamvisitor.").color(ChatColor.GRAY) + .append("\n[").color(ChatColor.DARK_GRAY) + .append(booleanToggle(user.isVanished(), "vanished")) + .append("").reset().append("]").color(ChatColor.DARK_GRAY); + } + + if (player.hasPermission("dreamvisitor.set.autoinvswap")) { + builder.append("\n\nAutomatic Inventory Swap: ").color(ChatColor.WHITE) + .append("\nWhether to automatically swap inventories on game mode change.").color(ChatColor.GRAY) + .append("\n[").color(ChatColor.DARK_GRAY) + .append(booleanToggle(user.isAutoInvSwapEnabled(), "autoinvswap")) + .append("").reset().append("]").color(ChatColor.DARK_GRAY); + } + + if (player.hasPermission("dreamvisitor.set.autoradio")) { + builder.append("\n\nAutomatic Radio: ").color(ChatColor.WHITE) + .append("\nWhether to send all messages to staff radio.").color(ChatColor.GRAY) + .append("\n[").color(ChatColor.DARK_GRAY) + .append(booleanToggle(user.isAutoRadioEnabled(), "autoradio")) + .append("").reset().append("]").color(ChatColor.DARK_GRAY); + } + + builder.append("").reset().append("\n"); + Messager.send(player, builder.create()); - PlayerMemory memory = PlayerUtility.getPlayerMemory(player.getUniqueId()); - - ComponentBuilder builder = new ComponentBuilder(); - builder.append("User Options "); - - if (player.hasPermission("dreamvisitor.set.discord")) { - builder.append("\n\nDiscord Visibility: ").color(ChatColor.WHITE) - .append("\nWhether to show messages from Discord's chat bridge.").color(ChatColor.GRAY) - .append("\n[").color(ChatColor.DARK_GRAY) - .append(booleanToggle(memory.discordEnabled, "discord")) - .append("").reset().append("]").color(ChatColor.DARK_GRAY); - } - - if (player.hasPermission("dreamvisitor.set.flight")) { - builder.append("\n\nFlight Disabled: ").color(ChatColor.WHITE) - .append("\nWhether Flight Mode cannot be activated.").color(ChatColor.GRAY) - .append("\n[").color(ChatColor.DARK_GRAY) - .append(booleanToggle(memory.flightDisabled, "flight")) - .append("").reset().append("]").color(ChatColor.DARK_GRAY); - } - - if (player.hasPermission("dreamvisitor.set.zoop")) { - builder.append("\n\nDiscord Vanish: ").color(ChatColor.WHITE) - .append("\nWhether to appear offline in Dreamvisitor.").color(ChatColor.GRAY) - .append("\n[").color(ChatColor.DARK_GRAY) - .append(booleanToggle(memory.vanished, "vanished")) - .append("").reset().append("]").color(ChatColor.DARK_GRAY); } - if (player.hasPermission("dreamvisitor.set.autoinvswap")) { - builder.append("\n\nAutomatic Inventory Swap: ").color(ChatColor.WHITE) - .append("\nWhether to automatically swap inventories on game mode change.").color(ChatColor.GRAY) - .append("\n[").color(ChatColor.DARK_GRAY) - .append(booleanToggle(memory.autoinvswap, "autoinvswap")) - .append("").reset().append("]").color(ChatColor.DARK_GRAY); + /** + * Creates a {@link TextComponent} representing a {@code boolean} value with a + * command to change it. + * + * @param value the {@code boolean} to display. + * @param cmdName the command to run. This will be formatted as + * {@code /dvset !value} + * @return a {@link TextComponent} representing the value with a command to + * change it. + */ + private static @NotNull TextComponent booleanToggle(boolean value, String cmdName) { + TextComponent toggle = new TextComponent(); + toggle.setUnderlined(true); + + if (value) { + toggle.setText("-O"); + toggle.setColor(ChatColor.GREEN); + } else { + toggle.setText("O-"); + toggle.setColor(ChatColor.RED); + } + + toggle.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text( + ChatColor.GRAY + "Currently toggled to " + ChatColor.WHITE + String.valueOf(value).toUpperCase() + "."))); + toggle.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, + "/dvset " + cmdName + " " + String.valueOf(!value).toLowerCase())); + + return toggle; } - if (player.hasPermission("dreamvisitor.set.autoradio")) { - builder.append("\n\nAutomatic Radio: ").color(ChatColor.WHITE) - .append("\nWhether to send all messages to staff radio.").color(ChatColor.GRAY) - .append("\n[").color(ChatColor.DARK_GRAY) - .append(booleanToggle(memory.autoRadio, "autoradio")) - .append("").reset().append("]").color(ChatColor.DARK_GRAY); - } + @NotNull + @Override + public CommandTree getCommand() { - builder.append("").reset().append("\n"); - Messager.send(player, builder.create()); - - } - - /** - * Creates a {@link TextComponent} representing a {@code boolean} value with a - * command to change it. - * - * @param value the {@code boolean} to display. - * @param cmdName the command to run. This will be formatted as - * {@code /dvset !value} - * @return a {@link TextComponent} representing the value with a command to - * change it. - */ - private static @NotNull TextComponent booleanToggle(boolean value, String cmdName) { - TextComponent toggle = new TextComponent(); - toggle.setUnderlined(true); - - if (value) { - toggle.setText("-O"); - toggle.setColor(ChatColor.GREEN); - } else { - toggle.setText("O-"); - toggle.setColor(ChatColor.RED); - } - - toggle.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text( - ChatColor.GRAY + "Currently toggled to " + ChatColor.WHITE + String.valueOf(value).toUpperCase() + "."))); - toggle.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, - "/dvset " + cmdName + " " + String.valueOf(!value).toLowerCase())); - - return toggle; - } - - @NotNull - @Override - public CommandTree getCommand() { - - return new CommandTree("dvset") - .withPermission(CommandPermission.fromString("dreamvisitor.userset")) - .withHelp("Manage settings.", "Manage your Dreamvisitor settings.") - .executesNative(((sender, args) -> { - if (sender instanceof Player player && sender.hasPermission("dreamvisitor.userset")) { - // Player GUI - sendUserGui(player); - } else - throw CommandAPI.failWithString("No options specified."); - })) - .then(new StringArgument("option") - .setOptional(true) - .executesNative((sender, args) -> { - String option = (String) args.get("option"); - - CommandSender callee = sender.getCallee(); - if (!callee.hasPermission("dreamvisitor.userset")) - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - - PlayerMemory playerMemory; - - if (callee instanceof Player player) { - playerMemory = PlayerUtility.getPlayerMemory(player.getUniqueId()); - } else - throw CommandAPI.failWithString("This can only be executed by a player!"); - - switch (Objects.requireNonNull(option)) { - case "discord" -> { - if (!player.hasPermission("dreamvisitor.set.discord")) - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - Messager.send(callee, ChatColor.GRAY + "Discord Visibility is currently set to " - + ChatColor.WHITE + playerMemory.discordEnabled); - } - case "flight" -> { - if (!player.hasPermission("dreamvisitor.set.flight")) - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - Messager.send(callee, ChatColor.GRAY + "Flight Enabled is currently set to " - + ChatColor.WHITE + playerMemory.flightDisabled); - } - case "vanished" -> { - if (!player.hasPermission("dreamvisitor.set.zoop")) - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - Messager.send(callee, ChatColor.GRAY + "Discord Vanish is currently set to " - + ChatColor.WHITE + playerMemory.vanished); - } - case "autoinvswap" -> { - if (!player.hasPermission("dreamvisitor.set.autoinvswap")) - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - Messager.send(callee, ChatColor.GRAY - + "Automatic Inventory Swap is currently set to " + ChatColor.WHITE + playerMemory.autoinvswap); - } - case "autoradio" -> { - if (!player.hasPermission("dreamvisitor.set.autoradio")) - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - Messager.send(callee, ChatColor.GRAY + "Automatic Radio is currently set to " - + ChatColor.WHITE + playerMemory.autoRadio); - } - default -> - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - } - }) - .then(new StringArgument("modification") - .setOptional(true) + return new CommandTree("dvset") + .withPermission(CommandPermission.fromString("dreamvisitor.userset")) + .withHelp("Manage settings.", "Manage your Dreamvisitor settings.") .executesNative(((sender, args) -> { - String option = (String) args.get("option"); - String modification = (String) args.get("modification"); - - CommandSender callee = sender.getCallee(); - if (!callee.hasPermission("dreamvisitor.userset")) - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - - PlayerMemory playerMemory; - - if (callee instanceof Player player) { - playerMemory = PlayerUtility.getPlayerMemory(player.getUniqueId()); - } else - throw CommandAPI.failWithString("This can only be executed by a player!"); - - if (option == null || modification == null) { - sendUserGui(player); - return; - } - - switch (option) { - case "discord" -> { - if (!player.hasPermission("dreamvisitor.set.discord")) - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - playerMemory.discordEnabled = Boolean.parseBoolean(modification); - Messager.send(callee, ChatColor.GRAY + "Discord Visibility toggled to " - + ChatColor.WHITE + playerMemory.discordEnabled); - } - case "flight" -> { - if (!player.hasPermission("dreamvisitor.set.flight")) - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - playerMemory.flightDisabled = Boolean.parseBoolean(modification); - Messager.send(callee, ChatColor.GRAY + "Flight Enabled toggled to " - + ChatColor.WHITE + playerMemory.flightDisabled); - } - case "vanished" -> { - if (!player.hasPermission("dreamvisitor.set.zoop")) - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - playerMemory.vanished = Boolean.parseBoolean(modification); - - String chatMessage; - if (playerMemory.vanished) { - chatMessage = "**" + player.getName() + " left the game**"; - } else { - chatMessage = "**" + player.getName() + " joined the game**"; - } - // TODO: Send the message to the chat channel. + if (sender instanceof Player player && sender.hasPermission("dreamvisitor.userset")) { + // Player GUI + sendUserGui(player); + } else + throw CommandAPI.failWithString("No options specified."); + })) + .then(new StringArgument("option") + .setOptional(true) + .executesNative((sender, args) -> { + String option = (String) args.get("option"); + + CommandSender callee = sender.getCallee(); + if (!callee.hasPermission("dreamvisitor.userset")) + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + + DVUser user; + + if (callee instanceof Player player) { + user = PlayerUtility.getUser(player); + } else + throw CommandAPI.failWithString("This can only be executed by a player!"); + + switch (Objects.requireNonNull(option)) { + case "discord" -> { + if (!player.hasPermission("dreamvisitor.set.discord")) + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + Messager.send(callee, ChatColor.GRAY + "Discord Visibility is currently set to " + + ChatColor.WHITE + user.isShowDiscordOn()); + } + case "flight" -> { + if (!player.hasPermission("dreamvisitor.set.flight")) + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + Messager.send(callee, ChatColor.GRAY + "Flight Enabled is currently set to " + + ChatColor.WHITE + user.isFlightDisabled()); + } + case "vanished" -> { + if (!player.hasPermission("dreamvisitor.set.zoop")) + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + Messager.send(callee, ChatColor.GRAY + "Discord Vanish is currently set to " + + ChatColor.WHITE + user.isVanished()); + } + case "autoinvswap" -> { + if (!player.hasPermission("dreamvisitor.set.autoinvswap")) + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + Messager.send(callee, ChatColor.GRAY + + "Automatic Inventory Swap is currently set to " + ChatColor.WHITE + user.isAutoInvSwapEnabled()); + } + case "autoradio" -> { + if (!player.hasPermission("dreamvisitor.set.autoradio")) + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + Messager.send(callee, ChatColor.GRAY + "Automatic Radio is currently set to " + + ChatColor.WHITE + user.isAutoRadioEnabled()); + } + default -> + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + } + }) + .then(new StringArgument("modification") + .setOptional(true) + .executesNative(((sender, args) -> { + String option = (String) args.get("option"); + String modification = (String) args.get("modification"); + + CommandSender callee = sender.getCallee(); + if (!callee.hasPermission("dreamvisitor.userset")) + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + + DVUser user; + + if (callee instanceof Player player) { + user = PlayerUtility.getUser(player); + } else + throw CommandAPI.failWithString("This can only be executed by a player!"); + + if (option == null || modification == null) { + sendUserGui(player); + return; + } + + switch (option) { + case "discord" -> { + if (!player.hasPermission("dreamvisitor.set.discord")) + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + user.setShowDiscordMessages(Boolean.parseBoolean(modification)); + Messager.send(callee, ChatColor.GRAY + "Discord Visibility toggled to " + + ChatColor.WHITE + user.isShowDiscordOn()); + } + case "flight" -> { + if (!player.hasPermission("dreamvisitor.set.flight")) + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + user.setFlightDisabled(Boolean.parseBoolean(modification)); + Messager.send(callee, ChatColor.GRAY + "Flight Enabled toggled to " + + ChatColor.WHITE + user.isFlightDisabled()); + } + case "vanished" -> { + if (!player.hasPermission("dreamvisitor.set.zoop")) + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + user.setVanished(Boolean.parseBoolean(modification)); + + String chatMessage; + if (user.isVanished()) { + chatMessage = "**" + player.getName() + " left the game**"; + } else { + chatMessage = "**" + player.getName() + " joined the game**"; + } + // TODO: Send the message to the chat channel. // Bot.getGameChatChannel().sendMessage(chatMessage).queue(); // Bot.sendLog(chatMessage); - Messager.send(callee, ChatColor.GRAY + "Discord Vanish toggled to " - + ChatColor.WHITE + playerMemory.vanished); - } - case "autoinvswap" -> { - if (!player.hasPermission("dreamvisitor.set.autoinvswap")) - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - playerMemory.autoinvswap = Boolean.parseBoolean(modification); - Messager.send(callee, ChatColor.GRAY + "Automatic Inventory Swap toggled to " - + ChatColor.WHITE + playerMemory.autoinvswap); - } - case "autoradio" -> { - if (!player.hasPermission("dreamvisitor.set.autoradio")) - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - playerMemory.autoRadio = Boolean.parseBoolean(modification); - Messager.send(callee, ChatColor.GRAY + "Automatic Radio toggled to " - + ChatColor.WHITE + playerMemory.autoRadio); - } - default -> - throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); - } - sendUserGui(player); - })))); - } + Messager.send(callee, ChatColor.GRAY + "Discord Vanish toggled to " + + ChatColor.WHITE + user.isVanished()); + } + case "autoinvswap" -> { + if (!player.hasPermission("dreamvisitor.set.autoinvswap")) + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + user.setAutoInvSwapEnabled(Boolean.parseBoolean(modification)); + Messager.send(callee, ChatColor.GRAY + "Automatic Inventory Swap toggled to " + + ChatColor.WHITE + user.isAutoInvSwapEnabled()); + } + case "autoradio" -> { + if (!player.hasPermission("dreamvisitor.set.autoradio")) + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + user.setAutoRadioEnabled(Boolean.parseBoolean(modification)); + Messager.send(callee, ChatColor.GRAY + "Automatic Radio toggled to " + + ChatColor.WHITE + user.isAutoRadioEnabled()); + } + default -> + throw CommandAPI.failWithString("Invalid arguments or insufficient permissions!"); + } + sendUserGui(player); + })))); + } } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdHub.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdHub.java index c83480f..38842cd 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdHub.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdHub.java @@ -37,9 +37,9 @@ public CommandAPICommand getCommand() { ) .executesNative(((sender, args) -> { - Collection entitySelect = (Collection) args.get("entities"); + final Collection entitySelect = (Collection) args.get("entities"); - CommandSender callee = sender.getCallee(); + final CommandSender callee = sender.getCallee(); if (entitySelect != null) { if (entitySelect.isEmpty()) { @@ -52,7 +52,7 @@ public CommandAPICommand getCommand() { Dreamvisitor.hubLocation = plugin.getConfig().getLocation("hubLocation"); assert Dreamvisitor.hubLocation != null; - Essentials ess = (Essentials) Bukkit.getPluginManager().getPlugin("Essentials"); + final Essentials ess = (Essentials) Bukkit.getPluginManager().getPlugin("Essentials"); for (Entity entity : entitySelect) { @@ -67,7 +67,7 @@ public CommandAPICommand getCommand() { } player.teleport(Dreamvisitor.hubLocation); - player.spawnParticle(Particle.FIREWORKS_SPARK, Dreamvisitor.hubLocation, 100); + player.spawnParticle(Particle.FIREWORK, Dreamvisitor.hubLocation, 100); player.playSound(Dreamvisitor.hubLocation, Sound.ENTITY_EXPERIENCE_ORB_PICKUP, SoundCategory.MASTER, 0.5f, 1f); } else entity.teleport(Dreamvisitor.hubLocation, TeleportCause.COMMAND); } @@ -91,13 +91,13 @@ public CommandAPICommand getCommand() { if (Mail.isPLayerDeliverer(player)) Mail.cancel(player); - Essentials ess = (Essentials) Bukkit.getPluginManager().getPlugin("Essentials"); + final Essentials ess = (Essentials) Bukkit.getPluginManager().getPlugin("Essentials"); if (ess != null) { - User user = ess.getUser(player); + final User user = ess.getUser(player); user.setLastLocation(player.getLocation()); } - List leashed = new ArrayList<>(); + final List leashed = new ArrayList<>(); for (Entity entity : player.getNearbyEntities(10, 10, 10)) { if (entity instanceof LivingEntity livingEntity && livingEntity.isLeashed() && livingEntity.getLeashHolder().equals(player)) @@ -106,15 +106,15 @@ public CommandAPICommand getCommand() { if (leashed.isEmpty() || !player.hasPermission("dreamvisitor.hub.leash")) { player.teleport(Dreamvisitor.hubLocation); - player.spawnParticle(Particle.FIREWORKS_SPARK, Dreamvisitor.hubLocation, 100); + player.spawnParticle(Particle.FIREWORK, Dreamvisitor.hubLocation, 100); player.playSound(Dreamvisitor.hubLocation, Sound.ENTITY_EXPERIENCE_ORB_PICKUP, SoundCategory.MASTER, 0.5f, 1f); } else { - Location tpLocation = Dreamvisitor.hubLocation.clone().subtract(0, 14, 0); + final Location tpLocation = Dreamvisitor.hubLocation.clone().subtract(0, 14, 0); player.teleport(tpLocation); - player.spawnParticle(Particle.FIREWORKS_SPARK, tpLocation, 100); + player.spawnParticle(Particle.FIREWORK, tpLocation, 100); player.playSound(tpLocation, Sound.ENTITY_EXPERIENCE_ORB_PICKUP, SoundCategory.MASTER, 0.5f, 1f); for (LivingEntity entity : leashed) { @@ -153,7 +153,7 @@ public CommandAPICommand getCommand() { } closest.teleport(Dreamvisitor.hubLocation); - closest.spawnParticle(Particle.FIREWORKS_SPARK, Dreamvisitor.hubLocation, 100); + closest.spawnParticle(Particle.FIREWORK, Dreamvisitor.hubLocation, 100); closest.playSound(Dreamvisitor.hubLocation, Sound.ENTITY_EXPERIENCE_ORB_PICKUP, SoundCategory.MASTER, 0.5f, 1f); } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdItemBanList.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdItemBanList.java index d1baa25..394b0bb 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdItemBanList.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdItemBanList.java @@ -18,7 +18,7 @@ public CommandAPICommand getCommand() { .withPermission(CommandPermission.fromString("dreamvisitor.itembanlist")) .withHelp("Manage the item ban list.", "Open the item ban list inventory GUI.") .executesNative(((sender, args) -> { - CommandSender callee = sender.getCallee(); + final CommandSender callee = sender.getCallee(); if (callee instanceof Player player) { if (ItemBanList.badItems != null) { ItemBanList.inv.setContents(ItemBanList.badItems.toArray(new ItemStack[0])); diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdMoonglobe.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdMoonglobe.java index 9e818b3..dfa62ae 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdMoonglobe.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdMoonglobe.java @@ -51,7 +51,7 @@ public CommandAPICommand getCommand() { .withArguments(new EntitySelectorArgument.ManyPlayers("players")) .executesNative((sender, args) -> { - Collection targets = (Collection) args.get("players"); + final Collection targets = (Collection) args.get("players"); // Get players assert targets != null; @@ -75,12 +75,12 @@ public CommandAPICommand getCommand() { // Get players assert targets != null; - Location location = getLocation(sender, args); + final Location location = getLocation(sender, args); // get distance float maxDistance = 256.0f; - Object maxDistanceArg = args.get("maxDistance"); + final Object maxDistanceArg = args.get("maxDistance"); if (maxDistanceArg != null) maxDistance = (float) maxDistanceArg; Messager.send(sender, create(targets, location, maxDistance)); @@ -94,7 +94,7 @@ public CommandAPICommand getCommand() { World world; - CommandSender callee = sender.getCallee(); + final CommandSender callee = sender.getCallee(); if (callee instanceof Player player) world = player.getWorld(); else if (callee instanceof BlockCommandSender block) world = block.getBlock().getWorld(); else world = Bukkit.getWorlds().get(0); @@ -121,7 +121,7 @@ public CommandAPICommand getCommand() { // get distance float maxDistance = 256.0f; - Object maxDistanceArg = args.get("maxDistance"); + final Object maxDistanceArg = args.get("maxDistance"); if (maxDistanceArg != null) maxDistance = (float) maxDistanceArg; Messager.send(sender, create(targets, location, maxDistance)); diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdParcel.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdParcel.java index 0006d89..001d657 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdParcel.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdParcel.java @@ -39,15 +39,15 @@ public CommandAPICommand getCommand() { .withArguments(CommandUtils.customTribeArgument("homeTribe")) .executesNative(((sender, args) -> { - Location location = (Location) args.get("location"); + final Location location = (Location) args.get("location"); if (location == null) throw CommandAPI.failWithString("Location was not provided!"); - String name = (String) args.get("name"); + final String name = (String) args.get("name"); if (name == null) throw CommandAPI.failWithString("Name was not provided!"); - Object weightArg = args.get("weight"); + final Object weightArg = args.get("weight"); if (weightArg == null) throw CommandAPI.failWithString("Weight was not provided!"); int weight = (int) weightArg; - Tribe tribe = (Tribe) args.get("homeTribe"); + final Tribe tribe = (Tribe) args.get("homeTribe"); if (tribe == null) throw CommandAPI.failWithString("Tribe was not provided!"); Mail.MailLocation mailLocation = new Mail.MailLocation(location, name, weight, tribe); @@ -64,10 +64,10 @@ public CommandAPICommand getCommand() { ) .executesNative((sender, args) -> { - String name = (String) args.get("name"); + final String name = (String) args.get("name"); if (name == null) throw CommandAPI.failWithString("Name is null!"); - Mail.MailLocation location = Mail.getLocationByName(name); + final Mail.MailLocation location = Mail.getLocationByName(name); if (location == null) throw CommandAPI.failWithString("Mail location not found."); Mail.removeLocation(location); Messager.send(sender, "Removed location " + location.getName()); @@ -77,7 +77,7 @@ public CommandAPICommand getCommand() { .executesNative((sender, args) -> { List locations = Mail.getLocations(); - ComponentBuilder message = new ComponentBuilder("Mail Locations"); + final ComponentBuilder message = new ComponentBuilder("Mail Locations"); for (Mail.MailLocation mailLocation : locations) { message.append("\n").append(mailLocation.getName()).color(net.md_5.bungee.api.ChatColor.YELLOW) @@ -97,16 +97,16 @@ public CommandAPICommand getCommand() { .withSubcommand(new CommandAPICommand("terminal") .withArguments(new EntitySelectorArgument.ManyPlayers("players")) .executesNative((sender, args) -> { - Collection players = (Collection) args.get("players"); + final Collection players = (Collection) args.get("players"); assert players != null; if (players.isEmpty()) throw CommandAPI.failWithString("No players selected"); - List deliverers = Mail.getDeliverers(); - List playerList = deliverers.stream().map(Mail.Deliverer::getPlayer).toList(); + final List deliverers = Mail.getDeliverers(); + final List playerList = deliverers.stream().map(Mail.Deliverer::getPlayer).toList(); - List addPlayers = new ArrayList<>(); - List removePlayers = new ArrayList<>(); + final List addPlayers = new ArrayList<>(); + final List removePlayers = new ArrayList<>(); for (Player player : players) { if (playerList.contains(player)) removePlayers.add(player); @@ -118,7 +118,7 @@ public CommandAPICommand getCommand() { for (Player player : addPlayers) { - Mail.MailLocation endLoc; + final Mail.MailLocation endLoc; try { endLoc = Mail.chooseDeliveryLocation(startLoc); @@ -133,7 +133,7 @@ public CommandAPICommand getCommand() { try { Mail.complete(player); } catch (Exception e) { - String message = e.getMessage(); + final String message = e.getMessage(); switch (message) { case "Player does not have parcel!" -> Messager.sendDanger(player, ChatColor.RED + "You do not have the parcel that is to be delivered!"); @@ -166,15 +166,15 @@ public CommandAPICommand getCommand() { ) .executesNative((sender, args) -> { - String startArg = (String) args.get("start"); - Mail.MailLocation start = Mail.getLocationByName(startArg); + final String startArg = (String) args.get("start"); + final Mail.MailLocation start = Mail.getLocationByName(startArg); if (start == null) throw CommandAPI.failWithString(startArg + " is not a valid MailLocation!"); - String endArg = (String) args.get("end"); - Mail.MailLocation end = Mail.getLocationByName(endArg); + final String endArg = (String) args.get("end"); + final Mail.MailLocation end = Mail.getLocationByName(endArg); if (end == null) throw CommandAPI.failWithString(endArg + " is not a valid MailLocation!"); - Collection players = (Collection) args.get("players"); + final Collection players = (Collection) args.get("players"); assert players != null; if (players.isEmpty()) throw CommandAPI.failWithString("No players selected"); @@ -200,7 +200,7 @@ public CommandAPICommand getCommand() { .withSubcommand(new CommandAPICommand("list") .executesNative((sender, args) -> { - StringBuilder message = new StringBuilder(); + final StringBuilder message = new StringBuilder(); for (Mail.Deliverer deliverer : Mail.getDeliverers()) { message.append(deliverer.getPlayer().getName()).append(" "); } @@ -218,7 +218,7 @@ private void add(@NotNull Collection players, @NotNull Mail.MailLocation for (Player player : players) { Messager.debug("Adding player " + player.getName()); - Mail.Deliverer deliverer = new Mail.Deliverer(player, start, end); + final Mail.Deliverer deliverer = new Mail.Deliverer(player, start, end); deliverer.start(); deliverers.add(deliverer); Messager.send(player, "Deliver this parcel to " + ChatColor.YELLOW + end.getName().replace("_", " ") + ChatColor.WHITE + ".\nRun " + ChatColor.AQUA + "/" + getCommand().getName() + " cancel" + ChatColor.WHITE + " to cancel."); @@ -229,7 +229,7 @@ private void add(@NotNull Collection players, @NotNull Mail.MailLocation } private void remove(@NotNull Collection players) { - List deliverers = Mail.getDeliverers(); + final List deliverers = Mail.getDeliverers(); deliverers.removeIf(deliverer -> players.contains(deliverer.getPlayer())); Mail.setDeliverers(deliverers); } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPauseBypass.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPauseBypass.java index be65766..8db8be9 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPauseBypass.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPauseBypass.java @@ -25,8 +25,8 @@ public CommandAPICommand getCommand() { .withSubcommand(new CommandAPICommand("add") .withArguments(new EntitySelectorArgument.ManyPlayers("players")) .executesNative((sender, args) -> { - Collection players = (Collection) args.get("players"); - List playersList = PauseBypass.getPlayers(); + final Collection players = (Collection) args.get("players"); + final List playersList = PauseBypass.getPlayers(); assert players != null; playersList.addAll(players.stream().map(Player::getUniqueId).toList()); PauseBypass.setPlayers(playersList); @@ -36,10 +36,10 @@ public CommandAPICommand getCommand() { .withSubcommand(new CommandAPICommand("remove") .withArguments(new EntitySelectorArgument.ManyPlayers("players")) .executesNative((sender, args) -> { - Collection players = (Collection) args.get("players"); - List playersList = PauseBypass.getPlayers(); + final Collection players = (Collection) args.get("players"); + final List playersList = PauseBypass.getPlayers(); assert players != null; - boolean removed = playersList.removeAll(players.stream().map(Player::getUniqueId).toList()); + final boolean removed = playersList.removeAll(players.stream().map(Player::getUniqueId).toList()); PauseBypass.setPlayers(playersList); if (removed) Messager.send(sender, "Removed " + Messager.nameOrCountPlayer(players) + " from the bypass list."); else throw CommandAPI.failWithString("No players were removed."); @@ -48,7 +48,7 @@ public CommandAPICommand getCommand() { .withSubcommand(new CommandAPICommand("list") .executesNative((sender, args) -> { // Build list - StringBuilder list = new StringBuilder(); + final StringBuilder list = new StringBuilder(); for (UUID player : PauseBypass.getPlayers()) { if (!list.isEmpty()) list.append(", "); diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPlayerlimit.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPlayerlimit.java index 21ab96f..bb24b09 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPlayerlimit.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPlayerlimit.java @@ -30,7 +30,7 @@ public CommandAPICommand getCommand() { } else { try { // Change config - int result = (int) newLimitArg; + final int result = (int) newLimitArg; // Dreamvisitor.getPlugin().getServer().setMaxPlayers(result); for (Player player : Bukkit.getServer().getOnlinePlayers()) { diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdRadio.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdRadio.java index 1c07950..8e3338b 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdRadio.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdRadio.java @@ -22,9 +22,9 @@ public CommandAPICommand getCommand() { .withArguments(new GreedyStringArgument("message")) .executesNative((sender, args) -> { - String message = (String) args.get("message"); + final String message = (String) args.get("message"); - CommandSender callee = sender.getCallee(); + final CommandSender callee = sender.getCallee(); if (callee instanceof Player player) { Radio.buildMessage(message, player.getName(), getCommand().getName(), null); } else if (callee instanceof ConsoleCommandSender) { diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSandbox.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSandbox.java index 0c40508..2c73ba0 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSandbox.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSandbox.java @@ -4,8 +4,8 @@ import dev.jorel.commandapi.CommandPermission; import dev.jorel.commandapi.arguments.BooleanArgument; import dev.jorel.commandapi.arguments.EntitySelectorArgument; -import org.woftnw.dreamvisitor.data.PlayerMemory; import org.woftnw.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.data.type.DVUser; import org.woftnw.dreamvisitor.functions.Messager; import org.woftnw.dreamvisitor.functions.Sandbox; import net.md_5.bungee.api.ChatColor; @@ -36,23 +36,23 @@ public CommandAPICommand getCommand() { .executesNative((sender, args) -> { Collection players = (Collection) args.get("players"); if (players == null) { - List sandboxedPlayers = new ArrayList<>(); + final List sandboxedPlayers = new ArrayList<>(); for (Player player : Bukkit.getOnlinePlayers()) { - PlayerMemory memory = PlayerUtility.getPlayerMemory(player.getUniqueId()); - if (memory.sandbox) sandboxedPlayers.add(player); + final DVUser user = PlayerUtility.getUser(player); + if (user.isInSandboxMode()) sandboxedPlayers.add(player); } if (sandboxedPlayers.isEmpty()) { Messager.send(sender, "No players currently online are in sandbox mode. Use /sandbox [true|false] to toggle sandbox mode."); } - ComponentBuilder messageBuilder = new ComponentBuilder("Players currently sandboxed:\n"); + final ComponentBuilder messageBuilder = new ComponentBuilder("Players currently sandboxed:\n"); - HoverEvent tooltip = new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("Click to remove.")); + final HoverEvent tooltip = new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("Click to remove.")); for (Player player : sandboxedPlayers) { - Location location = player.getLocation(); + final Location location = player.getLocation(); messageBuilder.append(player.getName()).color(ChatColor.YELLOW) .append(" [").color(ChatColor.WHITE) .append("Remove").color(ChatColor.RED) @@ -64,10 +64,10 @@ public CommandAPICommand getCommand() { Messager.send(sender, messageBuilder.create()); } else { - Object stateArg = args.get("state"); + final Object stateArg = args.get("state"); if (stateArg == null) { players.forEach(player -> { - if (PlayerUtility.getPlayerMemory(player.getUniqueId()).sandbox) Sandbox.disableSandbox(player); + if (PlayerUtility.getUser(player).isInSandboxMode()) Sandbox.disableSandbox(player); else Sandbox.enableSandbox(player); }); Messager.send(sender, "Toggled sandbox mode for " + Messager.nameOrCountPlayer(players) + "."); diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSchedule.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSchedule.java index c22a3c7..769970f 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSchedule.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSchedule.java @@ -21,284 +21,281 @@ public class CmdSchedule implements DVCommand { - @NotNull - @Override - public CommandAPICommand getCommand() { - return new CommandAPICommand("schedule") - .withPermission(CommandPermission.fromString("dreamvisitor.schedule")) - .withHelp("Schedule commands to run at specific intervals or times.", - "Schedule commands to run at specific intervals or times.") - .withSubcommands( - new CommandAPICommand("interval") + @NotNull + @Override + public CommandAPICommand getCommand() { + return new CommandAPICommand("schedule") .withPermission(CommandPermission.fromString("dreamvisitor.schedule")) - .withHelp("Add a new interval-based schedule.", "Add a new schedule that runs every X minutes.") - .withArguments(new StringArgument("name")) - .withArguments(new IntegerArgument("interval-minutes", 1)) - .withArguments(new GreedyStringArgument("command")) - .executesNative((sender, args) -> { - String name = (String) args.get("name"); - int intervalMinutes = (int) args.get("interval-minutes"); - String commandInput = (String) args.get("command"); + .withHelp("Schedule commands to run at specific intervals or times.", + "Schedule commands to run at specific intervals or times.") + .withSubcommands( + new CommandAPICommand("interval") + .withPermission(CommandPermission.fromString("dreamvisitor.schedule")) + .withHelp("Add a new interval-based schedule.", "Add a new schedule that runs every X minutes.") + .withArguments(new StringArgument("name")) + .withArguments(new IntegerArgument("interval-minutes", 1)) + .withArguments(new GreedyStringArgument("command")) + .executesNative((sender, args) -> { + final String name = (String) args.get("name"); + final int intervalMinutes = (int) args.get("interval-minutes"); + final String commandInput = (String) args.get("command"); - // Check if the command input contains multiple commands (separated by - // semicolons) - List commands = new ArrayList<>(); - if (commandInput.contains(";")) { - commands.addAll(Arrays.asList(commandInput.split(";"))); - // Trim commands - for (int i = 0; i < commands.size(); i++) { - commands.set(i, commands.get(i).trim()); - } - } else { - commands.add(commandInput); - } + // Check if the command input contains multiple commands (separated by + // semicolons) + final List commands = new ArrayList<>(); + assert commandInput != null; + if (commandInput.contains(";")) { + commands.addAll(Arrays.asList(commandInput.split(";"))); + // Trim commands + commands.replaceAll(String::trim); + } else { + commands.add(commandInput); + } - CommandScheduler.getInstance().addSchedule(name, intervalMinutes, commands); - Messager.send(sender, "Added schedule '" + name + "' to run " + - Messager.nameOrCountString(commands.stream().map(cmd -> "\"".concat(cmd).concat("\"")).toList(), "command", "commands") + - " every " + intervalMinutes + " minutes."); - }), - new CommandAPICommand("daily") - .withPermission(CommandPermission.fromString("dreamvisitor.schedule")) - .withHelp("Add a new daily schedule.", "Add a new schedule that runs once per day at a specific time.") - .withArguments(new StringArgument("name")) - .withArguments(new TextArgument("time").includeSuggestions( - ArgumentSuggestions.strings("00:00:00", "06:00:00", "12:00:00", "18:00:00"))) - .withArguments(new GreedyStringArgument("command")) - .executesNative((sender, args) -> { - String name = (String) args.get("name"); - String timeString = (String) args.get("time"); - String commandInput = (String) args.get("command"); + CommandScheduler.getInstance().addSchedule(name, intervalMinutes, commands); + Messager.send(sender, "Added schedule '" + name + "' to run " + + Messager.nameOrCountString(commands.stream().map(cmd -> "\"".concat(cmd).concat("\"")).toList(), "command", "commands") + + " every " + intervalMinutes + " minutes."); + }), + new CommandAPICommand("daily") + .withPermission(CommandPermission.fromString("dreamvisitor.schedule")) + .withHelp("Add a new daily schedule.", "Add a new schedule that runs once per day at a specific time.") + .withArguments(new StringArgument("name")) + .withArguments(new TextArgument("time").includeSuggestions( + ArgumentSuggestions.strings("00:00:00", "06:00:00", "12:00:00", "18:00:00"))) + .withArguments(new GreedyStringArgument("command")) + .executesNative((sender, args) -> { + final String name = (String) args.get("name"); + final String timeString = (String) args.get("time"); + final String commandInput = (String) args.get("command"); - try { - LocalTime time = LocalTime.parse(timeString); + try { + assert timeString != null; + final LocalTime time = LocalTime.parse(timeString); - // Check if the command input contains multiple commands (separated by - // semicolons) - List commands = new ArrayList<>(); - if (commandInput.contains(";")) { - commands.addAll(Arrays.asList(commandInput.split(";"))); - // Trim commands - for (int i = 0; i < commands.size(); i++) { - commands.set(i, commands.get(i).trim()); - } - } else { - commands.add(commandInput); - } + // Check if the command input contains multiple commands (separated by + // semicolons) + final List commands = new ArrayList<>(); + assert commandInput != null; + if (commandInput.contains(";")) { + commands.addAll(Arrays.asList(commandInput.split(";"))); + // Trim commands + commands.replaceAll(String::trim); + } else { + commands.add(commandInput); + } - CommandScheduler.getInstance().addDailySchedule(name, time, commands); - Messager.send(sender, "Added schedule '" + name + "' to run " + - Messager.nameOrCountString(commands.stream().map(cmd -> "\"".concat(cmd).concat("\"")).toList(), "command", "commands") + - " commands daily at " + timeString + "."); + CommandScheduler.getInstance().addDailySchedule(name, time, commands); + Messager.send(sender, "Added schedule '" + name + "' to run " + + Messager.nameOrCountString(commands.stream().map(cmd -> "\"".concat(cmd).concat("\"")).toList(), "command", "commands") + + " commands daily at " + timeString + "."); - } catch (DateTimeParseException e) { - Messager.sendDanger(sender, - "Invalid time format. Please use HH:MM:SS format (e.g., 06:00:00)"); - } - }), - new CommandAPICommand("cron") - .withPermission(CommandPermission.fromString("dreamvisitor.schedule")) - .withHelp("Add a new cron-style schedule.", - "Add a new schedule using cron pattern (minute hour day-of-month month day-of-week).") - .withArguments(new StringArgument("name")) - .withArguments(new TextArgument("pattern").includeSuggestions( - ArgumentSuggestions.strings("0 * * * *", "0 0 * * *", "0 0 * * 0", "*/5 * * * *"))) - .withArguments(new GreedyStringArgument("command")) - .executesNative((sender, args) -> { - String name = (String) args.get("name"); - String pattern = (String) args.get("pattern"); - String commandInput = (String) args.get("command"); + } catch (DateTimeParseException e) { + Messager.sendDanger(sender, + "Invalid time format. Please use HH:MM:SS format (e.g., 06:00:00)"); + } + }), + new CommandAPICommand("cron") + .withPermission(CommandPermission.fromString("dreamvisitor.schedule")) + .withHelp("Add a new cron-style schedule.", + "Add a new schedule using cron pattern (minute hour day-of-month month day-of-week).") + .withArguments(new StringArgument("name")) + .withArguments(new TextArgument("pattern").includeSuggestions( + ArgumentSuggestions.strings("0 * * * *", "0 0 * * *", "0 0 * * 0", "*/5 * * * *"))) + .withArguments(new GreedyStringArgument("command")) + .executesNative((sender, args) -> { + final String name = (String) args.get("name"); + final String pattern = (String) args.get("pattern"); + final String commandInput = (String) args.get("command"); - // Check if the command input contains multiple commands (separated by - // semicolons) - List commands = new ArrayList<>(); - if (commandInput.contains(";")) { - commands.addAll(Arrays.asList(commandInput.split(";"))); - // Trim commands - for (int i = 0; i < commands.size(); i++) { - commands.set(i, commands.get(i).trim()); - } - } else { - commands.add(commandInput); - } + // Check if the command input contains multiple commands (separated by + // semicolons) + final List commands = new ArrayList<>(); + assert commandInput != null; + if (commandInput.contains(";")) { + commands.addAll(Arrays.asList(commandInput.split(";"))); + // Trim commands + commands.replaceAll(String::trim); + } else { + commands.add(commandInput); + } - Schedule schedule = CommandScheduler.getInstance().addCronSchedule(name, pattern, commands); - if (schedule == null) { - Messager.sendDanger(sender,"Invalid cron pattern. Format: minute hour day-of-month month day-of-week"); - } else { - Messager.send(sender, "Added schedule '" + name + "' to run " + - Messager.nameOrCountString(commands.stream().map(cmd -> "\"".concat(cmd).concat("\"")).toList(), "command", "commands") + - " commands using cron pattern '" + pattern + "'."); - } - }), - new CommandAPICommand("remove") - .withPermission(CommandPermission.fromString("dreamvisitor.schedule")) - .withHelp("Remove a scheduled command.", "Remove a scheduled command.") - .withArguments(new StringArgument("name") - .replaceSuggestions( - ArgumentSuggestions.strings(info -> CommandScheduler.getInstance().getSchedules().stream() - .map(Schedule::getName) - .toArray(String[]::new)))) - .executesNative((sender, args) -> { - String name = (String) args.get("name"); + final Schedule schedule = CommandScheduler.getInstance().addCronSchedule(name, pattern, commands); + if (schedule == null) { + Messager.sendDanger(sender, "Invalid cron pattern. Format: minute hour day-of-month month day-of-week"); + } else { + Messager.send(sender, "Added schedule '" + name + "' to run " + + Messager.nameOrCountString(commands.stream().map(cmd -> "\"".concat(cmd).concat("\"")).toList(), "command", "commands") + + " commands using cron pattern '" + pattern + "'."); + } + }), + new CommandAPICommand("remove") + .withPermission(CommandPermission.fromString("dreamvisitor.schedule")) + .withHelp("Remove a scheduled command.", "Remove a scheduled command.") + .withArguments(new StringArgument("name") + .replaceSuggestions( + ArgumentSuggestions.strings(info -> CommandScheduler.getInstance().getSchedules().stream() + .map(Schedule::getName) + .toArray(String[]::new)))) + .executesNative((sender, args) -> { + final String name = (String) args.get("name"); - if (CommandScheduler.getInstance().removeSchedule(name)) { - Messager.send(sender, "Removed schedule '" + name + "'."); - } else { - Messager.sendDanger(sender, "No schedule with name '" + name + "' found."); - } - }), - new CommandAPICommand("list") - .withPermission(CommandPermission.fromString("dreamvisitor.schedule")) - .withHelp("List all scheduled commands.", "List all scheduled commands.") - .executesNative((sender, args) -> { - List schedules = CommandScheduler.getInstance().getSchedules(); - if (schedules.isEmpty()) { - Messager.send(sender, "No schedules configured."); - return; - } + if (CommandScheduler.getInstance().removeSchedule(name)) { + Messager.send(sender, "Removed schedule '" + name + "'."); + } else { + Messager.sendDanger(sender, "No schedule with name '" + name + "' found."); + } + }), + new CommandAPICommand("list") + .withPermission(CommandPermission.fromString("dreamvisitor.schedule")) + .withHelp("List all scheduled commands.", "List all scheduled commands.") + .executesNative((sender, args) -> { + final List schedules = CommandScheduler.getInstance().getSchedules(); + if (schedules.isEmpty()) { + Messager.send(sender, "No schedules configured."); + return; + } - Messager.send(sender, "Scheduled commands:"); - for (Schedule schedule : schedules) { - List commands = schedule.getCommands(); - String typeInfo = getTypeInfo(schedule); + Messager.send(sender, "Scheduled commands:"); + for (Schedule schedule : schedules) { + final List commands = schedule.getCommands(); + final String typeInfo = getTypeInfo(schedule); - Messager.send(sender,ChatColor.YELLOW + schedule.getName() + ChatColor.WHITE + - ": " - + (commands.size() > 1 ? commands.size() + " commands " - : "'" + ChatColor.GRAY + commands.get(0) + ChatColor.WHITE + "' ") - + - typeInfo + ". " + - ChatColor.AQUA + schedule.getTimeUntilNextRun() + ChatColor.WHITE + " until next run."); + Messager.send(sender, ChatColor.YELLOW + schedule.getName() + ChatColor.WHITE + + ": " + + (commands.size() > 1 ? commands.size() + " commands " + : "'" + ChatColor.GRAY + commands.get(0) + ChatColor.WHITE + "' ") + + + typeInfo + ". " + + ChatColor.AQUA + schedule.getTimeUntilNextRun() + ChatColor.WHITE + " until next run."); - if (commands.size() > 1) { - sender.sendMessage(ChatColor.GRAY + " Commands: "); - for (int i = 0; i < commands.size(); i++) { - sender.sendMessage(ChatColor.GRAY + " " + (i + 1) + ". " + commands.get(i)); - } - } - } - }), - new CommandAPICommand("run") - .withPermission(CommandPermission.fromString("dreamvisitor.schedule")) - .withHelp("Run a scheduled command immediately.", "Run a scheduled command immediately.") - .withArguments(new StringArgument("name") - .replaceSuggestions( - ArgumentSuggestions.strings(info -> CommandScheduler.getInstance().getSchedules().stream() - .map(Schedule::getName) - .toArray(String[]::new)))) - .executesNative((sender, args) -> { - String name = (String) args.get("name"); + if (commands.size() > 1) { + sender.sendMessage(ChatColor.GRAY + " Commands: "); + for (int i = 0; i < commands.size(); i++) { + sender.sendMessage(ChatColor.GRAY + " " + (i + 1) + ". " + commands.get(i)); + } + } + } + }), + new CommandAPICommand("run") + .withPermission(CommandPermission.fromString("dreamvisitor.schedule")) + .withHelp("Run a scheduled command immediately.", "Run a scheduled command immediately.") + .withArguments(new StringArgument("name") + .replaceSuggestions( + ArgumentSuggestions.strings(info -> CommandScheduler.getInstance().getSchedules().stream() + .map(Schedule::getName) + .toArray(String[]::new)))) + .executesNative((sender, args) -> { + final String name = (String) args.get("name"); - if (CommandScheduler.getInstance().runScheduleNow(name)) { - Messager.send(sender, "Running schedule '" + name + "' now."); - } else { - Messager.sendDanger(sender, "No schedule with name '" + name + "' found."); - } - }), - new CommandAPICommand("add-command") - .withPermission(CommandPermission.fromString("dreamvisitor.schedule")) - .withHelp("Add a command to an existing schedule.", "Add a command to an existing schedule.") - .withArguments(new StringArgument("name") - .replaceSuggestions( - ArgumentSuggestions.strings(info -> CommandScheduler.getInstance().getSchedules().stream() - .map(Schedule::getName) - .toArray(String[]::new)))) - .withArguments(new GreedyStringArgument("command")) - .executesNative((sender, args) -> { - String name = (String) args.get("name"); - String command = (String) args.get("command"); + if (CommandScheduler.getInstance().runScheduleNow(name)) { + Messager.send(sender, "Running schedule '" + name + "' now."); + } else { + Messager.sendDanger(sender, "No schedule with name '" + name + "' found."); + } + }), + new CommandAPICommand("add-command") + .withPermission(CommandPermission.fromString("dreamvisitor.schedule")) + .withHelp("Add a command to an existing schedule.", "Add a command to an existing schedule.") + .withArguments(new StringArgument("name") + .replaceSuggestions( + ArgumentSuggestions.strings(info -> CommandScheduler.getInstance().getSchedules().stream() + .map(Schedule::getName) + .toArray(String[]::new)))) + .withArguments(new GreedyStringArgument("command")) + .executesNative((sender, args) -> { + final String name = (String) args.get("name"); + final String command = (String) args.get("command"); - if (CommandScheduler.getInstance().addCommand(name, command)) { - Messager.send(sender, "Added command '" + command + "' to schedule '" + name + "'."); - } else { - Messager.sendDanger(sender, "No schedule with name '" + name + "' found."); - } - }), - new CommandAPICommand("remove-command") - .withPermission(CommandPermission.fromString("dreamvisitor.schedule")) - .withHelp("Remove a command from a schedule.", "Remove a command from a schedule.") - .withArguments(new StringArgument("name") - .replaceSuggestions( - ArgumentSuggestions.strings(info -> CommandScheduler.getInstance().getSchedules().stream() - .map(Schedule::getName) - .toArray(String[]::new)))) - .withArguments(new IntegerArgument("index", 1)) - .executesNative((sender, args) -> { - String name = (String) args.get("name"); - int index = (int) args.get("index") - 1; // Convert to 0-based index + if (CommandScheduler.getInstance().addCommand(name, command)) { + Messager.send(sender, "Added command '" + command + "' to schedule '" + name + "'."); + } else { + Messager.sendDanger(sender, "No schedule with name '" + name + "' found."); + } + }), + new CommandAPICommand("remove-command") + .withPermission(CommandPermission.fromString("dreamvisitor.schedule")) + .withHelp("Remove a command from a schedule.", "Remove a command from a schedule.") + .withArguments(new StringArgument("name") + .replaceSuggestions( + ArgumentSuggestions.strings(info -> CommandScheduler.getInstance().getSchedules().stream() + .map(Schedule::getName) + .toArray(String[]::new)))) + .withArguments(new IntegerArgument("index", 1)) + .executesNative((sender, args) -> { + final String name = (String) args.get("name"); + final int index = (int) args.get("index") - 1; // Convert to 0-based index - if (CommandScheduler.getInstance().removeCommand(name, index)) { - Messager.send(sender, "Removed command at position " + (index + 1) - + " from schedule '" + name + "'."); - } else { - Messager.sendDanger(sender, "No schedule with name '" + name - + "' found or invalid command index."); - } - }), - new CommandAPICommand("add-delay") - .withPermission(CommandPermission.fromString("dreamvisitor.schedule")) - .withHelp("Add a delay before executing a command in a schedule.", - "Add a delay before executing a command in a schedule (in game ticks, 20 ticks = 1 second).") - .withArguments(new StringArgument("name") - .replaceSuggestions( - ArgumentSuggestions.strings(info -> CommandScheduler.getInstance().getSchedules().stream() - .map(Schedule::getName) - .toArray(String[]::new)))) - .withArguments(new IntegerArgument("index", 1)) - .withArguments(new IntegerArgument("delay-ticks", 1)) - .executesNative((sender, args) -> { - String name = (String) args.get("name"); - int index = (int) args.get("index") - 1; // Convert to 0-based index - int delayTicks = (int) args.get("delay-ticks"); + if (CommandScheduler.getInstance().removeCommand(name, index)) { + Messager.send(sender, "Removed command at position " + (index + 1) + + " from schedule '" + name + "'."); + } else { + Messager.sendDanger(sender, "No schedule with name '" + name + + "' found or invalid command index."); + } + }), + new CommandAPICommand("add-delay") + .withPermission(CommandPermission.fromString("dreamvisitor.schedule")) + .withHelp("Add a delay before executing a command in a schedule.", + "Add a delay before executing a command in a schedule (in game ticks, 20 ticks = 1 second).") + .withArguments(new StringArgument("name") + .replaceSuggestions( + ArgumentSuggestions.strings(info -> CommandScheduler.getInstance().getSchedules().stream() + .map(Schedule::getName) + .toArray(String[]::new)))) + .withArguments(new IntegerArgument("index", 1)) + .withArguments(new IntegerArgument("delay-ticks", 1)) + .executesNative((sender, args) -> { + final String name = (String) args.get("name"); + final int index = (int) args.get("index") - 1; // Convert to 0-based index + final int delayTicks = (int) args.get("delay-ticks"); - // Pass ticks directly to CommandScheduler without conversion - if (CommandScheduler.getInstance().addDelay(name, index, delayTicks)) { - Messager.send(sender, "Added " + delayTicks + " tick" + - (delayTicks == 1 ? "" : "s") + " delay before command " - + (index + 1) + " in schedule '" + name + "'. (" + - String.format("%.1f", delayTicks / 20.0) + " seconds)"); - } else { - Messager.sendDanger(sender, "No schedule with name '" + name - + "' found or invalid command index."); - } - }), - new CommandAPICommand("remove-delay") - .withPermission(CommandPermission.fromString("dreamvisitor.schedule")) - .withHelp("Remove a delay from a command in a schedule.", - "Remove a delay from a command in a schedule.") - .withArguments(new StringArgument("name") - .replaceSuggestions( - ArgumentSuggestions.strings(info -> CommandScheduler.getInstance().getSchedules().stream() - .map(Schedule::getName) - .toArray(String[]::new)))) - .withArguments(new IntegerArgument("index", 1)) - .executesNative((sender, args) -> { - String name = (String) args.get("name"); - int index = (int) args.get("index") - 1; // Convert to 0-based index + // Pass ticks directly to CommandScheduler without conversion + if (CommandScheduler.getInstance().addDelay(name, index, delayTicks)) { + Messager.send(sender, "Added " + delayTicks + " tick" + + (delayTicks == 1 ? "" : "s") + " delay before command " + + (index + 1) + " in schedule '" + name + "'. (" + + String.format("%.1f", delayTicks / 20.0) + " seconds)"); + } else { + Messager.sendDanger(sender, "No schedule with name '" + name + + "' found or invalid command index."); + } + }), + new CommandAPICommand("remove-delay") + .withPermission(CommandPermission.fromString("dreamvisitor.schedule")) + .withHelp("Remove a delay from a command in a schedule.", + "Remove a delay from a command in a schedule.") + .withArguments(new StringArgument("name") + .replaceSuggestions( + ArgumentSuggestions.strings(info -> CommandScheduler.getInstance().getSchedules().stream() + .map(Schedule::getName) + .toArray(String[]::new)))) + .withArguments(new IntegerArgument("index", 1)) + .executesNative((sender, args) -> { + final String name = (String) args.get("name"); + final int index = (int) args.get("index") - 1; // Convert to 0-based index - if (CommandScheduler.getInstance().removeDelay(name, index)) { - Messager.send(sender,"Removed delay from command " + (index + 1) - + " in schedule '" + name + "'."); - } else { - Messager.sendDanger(sender, "No schedule with name '" + name - + "' found or no delay was set for this command."); - } - })); - } + if (CommandScheduler.getInstance().removeDelay(name, index)) { + Messager.send(sender, "Removed delay from command " + (index + 1) + + " in schedule '" + name + "'."); + } else { + Messager.sendDanger(sender, "No schedule with name '" + name + + "' found or no delay was set for this command."); + } + })); + } - @NotNull - private static String getTypeInfo(@NotNull Schedule schedule) { - String typeInfo; + @NotNull + private static String getTypeInfo(@NotNull Schedule schedule) { + String typeInfo; - switch (schedule.getType()) { - case INTERVAL -> typeInfo = "every " + ChatColor.GREEN + schedule.getIntervalMinutes() - + ChatColor.WHITE + " minutes"; - case DAILY -> typeInfo = "daily at " + ChatColor.GREEN + schedule.getDailyTime(); - case CRON -> - typeInfo = "using cron pattern " + ChatColor.GREEN + schedule.getCronPattern().getPattern(); - default -> typeInfo = "unknown schedule type"; + switch (schedule.getType()) { + case INTERVAL -> typeInfo = "every " + ChatColor.GREEN + schedule.getIntervalMinutes() + + ChatColor.WHITE + " minutes"; + case DAILY -> typeInfo = "daily at " + ChatColor.GREEN + schedule.getDailyTime(); + case CRON -> typeInfo = "using cron pattern " + ChatColor.GREEN + schedule.getCronPattern().getPattern(); + default -> typeInfo = "unknown schedule type"; + } + return typeInfo; } - return typeInfo; - } } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdScheduleRestart.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdScheduleRestart.java deleted file mode 100644 index e1e0503..0000000 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdScheduleRestart.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.woftnw.dreamvisitor.commands; - -import dev.jorel.commandapi.CommandAPICommand; -import dev.jorel.commandapi.CommandPermission; -import org.woftnw.dreamvisitor.functions.AutoRestart; -import org.woftnw.dreamvisitor.functions.Messager; -import org.jetbrains.annotations.NotNull; - -public class CmdScheduleRestart implements DVCommand { - - @NotNull - @Override - public CommandAPICommand getCommand() { - return new CommandAPICommand("schedulerestart") - .withPermission(CommandPermission.OP) - .withHelp("Schedule a restart.", "Restart the server when no players are online.") - .executesNative((sender, args) -> { - if (AutoRestart.isAutoRestart()) { - AutoRestart.disableAutoRestart(); - Messager.send(sender, "Canceled server restart. Run /autorestart again to cancel."); - } else { - AutoRestart.enableAutoRestart(null); - Messager.send(sender,"The server will restart when there are no players online. Run /autorestart again to cancel."); - } - }); - } -} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSetback.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSetback.java index 30e9ec1..dce8267 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSetback.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSetback.java @@ -7,6 +7,7 @@ import dev.jorel.commandapi.CommandPermission; import dev.jorel.commandapi.arguments.*; import dev.jorel.commandapi.wrappers.Rotation; +import org.jetbrains.annotations.Nullable; import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -34,19 +35,19 @@ public CommandAPICommand getCommand() { .withOptionalArguments(new WorldArgument("world")) .executesNative((sender, args) -> { - Essentials ess = (Essentials) Bukkit.getPluginManager().getPlugin("Essentials"); + final Essentials ess = (Essentials) Bukkit.getPluginManager().getPlugin("Essentials"); if (ess == null) { throw CommandAPI.failWithString("EssentialsX is not currently active!"); } - Collection players = (Collection) args.get("players"); - Location location = (Location) args.get("location"); - Rotation rotation = (Rotation) args.get("rotation"); - World world = (World) args.get("world"); + final Collection players = (Collection) args.get("players"); + @Nullable Location location = (Location) args.get("location"); + @Nullable Rotation rotation = (Rotation) args.get("rotation"); + @Nullable World world = (World) args.get("world"); assert players != null; - CommandSender callee = sender.getCallee(); + final CommandSender callee = sender.getCallee(); if (location == null) { if (callee instanceof Entity entity) { location = entity.getLocation(); diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSethub.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSethub.java index f944141..b87892d 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSethub.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSethub.java @@ -17,6 +17,8 @@ import org.woftnw.dreamvisitor.Dreamvisitor; import org.jetbrains.annotations.NotNull; +import javax.annotation.Nullable; + public class CmdSethub implements DVCommand { final Dreamvisitor plugin = Dreamvisitor.getPlugin(); @@ -31,10 +33,10 @@ public CommandAPICommand getCommand() { .withOptionalArguments(new RotationArgument("rotation")) .withOptionalArguments(new WorldArgument("world")) .executesNative((sender, args) -> { - Location location = (Location) args.get("location"); - Rotation rotation = (Rotation) args.get("rotation"); - World world = (World) args.get("world"); - CommandSender callee = sender.getCallee(); + @Nullable Location location = (Location) args.get("location"); + @Nullable Rotation rotation = (Rotation) args.get("rotation"); + @Nullable World world = (World) args.get("world"); + final CommandSender callee = sender.getCallee(); if (location == null) { if (callee instanceof Entity entity) { location = entity.getLocation(); diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSetmotd.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSetmotd.java index 596104c..487be43 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSetmotd.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSetmotd.java @@ -16,13 +16,13 @@ public CommandAPICommand getCommand() { .withHelp("Set or reset the MOTD.", "Set or reset the server MOTD.") .withOptionalArguments(new GreedyStringArgument("newMotd")) .executesNative((sender, args) -> { - String newMotd = (String) args.get("newMotd"); + final String newMotd = (String) args.get("newMotd"); if (newMotd == null) { Dreamvisitor.MOTD = null; Messager.send(sender, "Reset MOTD to default:\n" + sender.getServer().getMotd()); Messager.debug("Existing MOTD: " + sender.getServer().getMotd()); } else { - String finalMotd = newMotd.replaceAll("&", "§").replaceAll("\\\\n","\n").strip(); + final String finalMotd = newMotd.replaceAll("&", "§").replaceAll("\\\\n","\n").strip(); Dreamvisitor.MOTD = finalMotd; Messager.send(sender, "MOTD set to\n" + finalMotd); diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSoftwhitelist.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSoftwhitelist.java index 664b44e..7289c97 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSoftwhitelist.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSoftwhitelist.java @@ -27,9 +27,9 @@ public CommandAPICommand getCommand() { .withSubcommand(new CommandAPICommand("add") .withArguments(new OfflinePlayerArgument("player")) .executesNative((sender, args) -> { - OfflinePlayer player = (OfflinePlayer) args.get("player"); + final OfflinePlayer player = (OfflinePlayer) args.get("player"); if (player == null) throw CommandAPI.failWithString("That player could not be found!"); - List players = SoftWhitelist.getPlayers(); + final List players = SoftWhitelist.getPlayers(); if (players.contains(player.getUniqueId())) throw CommandAPI.failWithString("That player is already on the soft whitelist!"); players.add(player.getUniqueId()); SoftWhitelist.setPlayers(players); @@ -39,9 +39,9 @@ public CommandAPICommand getCommand() { .withSubcommand(new CommandAPICommand("remove") .withArguments(new OfflinePlayerArgument("player")) .executesNative((sender, args) -> { - OfflinePlayer player = (OfflinePlayer) args.get("player"); + final OfflinePlayer player = (OfflinePlayer) args.get("player"); if (player == null) throw CommandAPI.failWithString("That player could not be found!"); - List players = SoftWhitelist.getPlayers(); + final List players = SoftWhitelist.getPlayers(); if (!players.contains(player.getUniqueId())) throw CommandAPI.failWithString("That player is not on soft whitelist!"); players.remove(player.getUniqueId()); SoftWhitelist.setPlayers(players); @@ -50,8 +50,8 @@ public CommandAPICommand getCommand() { ) .withSubcommand(new CommandAPICommand("list") .executesNative((sender, args) -> { - List players = SoftWhitelist.getPlayers(); - StringBuilder list = new StringBuilder(); + final List players = SoftWhitelist.getPlayers(); + final StringBuilder list = new StringBuilder(); for (UUID player : players) { if (!list.isEmpty()) { diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSynctime.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSynctime.java index 14fc656..b324daf 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSynctime.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSynctime.java @@ -4,6 +4,7 @@ import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; import dev.jorel.commandapi.arguments.WorldArgument; +import org.jetbrains.annotations.Nullable; import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.Bukkit; import org.bukkit.World; @@ -22,17 +23,17 @@ public CommandAPICommand getCommand() { .withHelp("Sync time across worlds.", "Sync time across all worlds.") .withOptionalArguments(new WorldArgument("world")) .executesNative((sender, args) -> { - World worldArg = (World) args.get("world"); - CommandSender callee = sender.getCallee(); - if (worldArg == null) { + @Nullable World targetWorld = (World) args.get("world"); + final CommandSender callee = sender.getCallee(); + if (targetWorld == null) { if (callee instanceof Entity entity) { - worldArg = entity.getWorld(); + targetWorld = entity.getWorld(); } else if (callee instanceof BlockCommandSender block) { - worldArg = block.getBlock().getWorld(); + targetWorld = block.getBlock().getWorld(); } else throw CommandAPI.failWithString("World must be specified if it cannot be inferred!"); } - for (World world : Bukkit.getWorlds()) world.setFullTime(worldArg.getFullTime()); - Messager.send(sender, "Set all worlds to match " + worldArg.getName() + ": " + worldArg.getFullTime()); + for (World world : Bukkit.getWorlds()) world.setFullTime(targetWorld.getFullTime()); + Messager.send(sender, "Set all worlds to match " + targetWorld.getName() + ": " + targetWorld.getFullTime()); }); } } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdTagRadio.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdTagRadio.java index 498410c..3c91b6b 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdTagRadio.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdTagRadio.java @@ -21,12 +21,12 @@ public CommandAPICommand getCommand() { .withArguments(new StringArgument("tag")) .withArguments(new GreedyStringArgument("message")) .executesNative((sender, args) -> { - String tag = (String) args.get("tag"); + final String tag = (String) args.get("tag"); if (tag == null) throw CommandAPI.failWithString("You must specify a tag!"); - String message = (String) args.get("message"); + final String message = (String) args.get("message"); if (message == null) throw CommandAPI.failWithString("You cannot send an empty message!"); - CommandSender callee = sender.getCallee(); + final CommandSender callee = sender.getCallee(); if (callee instanceof Player player) { Radio.buildMessage(message, player.getName(), getCommand().getName(), tag); } else if (callee instanceof ConsoleCommandSender) { diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdTribeUpdate.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdTribeUpdate.java index 1f3b25e..c9a3b83 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdTribeUpdate.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdTribeUpdate.java @@ -4,7 +4,6 @@ import dev.jorel.commandapi.CommandPermission; import dev.jorel.commandapi.arguments.EntitySelectorArgument; import org.woftnw.dreamvisitor.Dreamvisitor; -import io.github.stonley890.dreamvisitor.data.*; import org.woftnw.dreamvisitor.data.PlayerTribe; import org.woftnw.dreamvisitor.data.Tribe; import org.woftnw.dreamvisitor.functions.Messager; @@ -24,7 +23,7 @@ public CommandAPICommand getCommand() { .withPermission(CommandPermission.fromString("dreamvisitor.tribeupdate")) .withArguments(new EntitySelectorArgument.ManyPlayers("players")) .executes((sender, args) -> { - Collection players = (Collection) args.get("players"); + final Collection players = (Collection) args.get("players"); assert players != null; // This may take some time @@ -33,14 +32,14 @@ public CommandAPICommand getCommand() { // Run async Bukkit.getScheduler().runTaskAsynchronously(Dreamvisitor.getPlugin(), () -> { - for (Player player : players) { + for (final Player player : players) { - UUID uuid = player.getUniqueId(); + final UUID uuid = player.getUniqueId(); PlayerTribe.updateTribeOfPlayer(uuid); // Get tribe - Tribe playerTribe = PlayerTribe.getTribeOfPlayer(uuid); + final Tribe playerTribe = PlayerTribe.getTribeOfPlayer(uuid); if (playerTribe != null) { diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdUnwax.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdUnwax.java index b1fe75f..1beccc8 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdUnwax.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdUnwax.java @@ -21,7 +21,7 @@ public CommandAPICommand getCommand() { .withHelp("Unwax a sign.", "Unwax the sign you are looking at") .executesNative((sender, args) -> { if (sender.getCallee() instanceof Player player) { - Block targetBlock = player.getTargetBlockExact(10, FluidCollisionMode.NEVER); + final Block targetBlock = player.getTargetBlockExact(10, FluidCollisionMode.NEVER); if (targetBlock == null) throw CommandAPI.failWithString("No nearby sign in line of sight!"); if (targetBlock.getState() instanceof Sign sign) { diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdUser.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdUser.java index 849ae10..e31a67b 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdUser.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdUser.java @@ -4,6 +4,8 @@ import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; import dev.jorel.commandapi.arguments.OfflinePlayerArgument; +import org.woftnw.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.data.type.DVUser; import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.OfflinePlayer; import org.jetbrains.annotations.NotNull; @@ -19,24 +21,17 @@ public CommandAPICommand getCommand() { .withArguments(new OfflinePlayerArgument("player")) .executesNative((sender, args) -> { - OfflinePlayer player = (OfflinePlayer) args.get("player"); + final OfflinePlayer player = (OfflinePlayer) args.get("player"); if (player == null) throw CommandAPI.failWithString("Player not found!"); - String discordID; + String discordID = "N/A"; String discordUsername = "N/A"; - long discord; - - // Discord ID from AccountLink.yml - try { - discord = AccountLink.getDiscordId(player.getUniqueId()); - discordID = String.valueOf(discord); - // TODO: Get Discord username from database. -// discordUsername = Bot.getJda().retrieveUserById(discord).complete().getName(); - } catch (NullPointerException e) { - discordID = "N/A"; - // Discord username from JDA + final DVUser user = PlayerUtility.getUser(player.getUniqueId()); + if (user.getDiscordId() == null) { + discordID = String.valueOf(user.getDiscordId()); + discordUsername = user.getDiscordUsername(); } Messager.send(sender, "Local data for player " + player.getName() + ":" + diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdZoop.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdZoop.java index 27281d7..fca177f 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdZoop.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdZoop.java @@ -5,6 +5,7 @@ import dev.jorel.commandapi.CommandPermission; import org.woftnw.dreamvisitor.data.PlayerMemory; import org.woftnw.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.data.type.DVUser; import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -21,28 +22,28 @@ public CommandAPICommand getCommand() { .executesNative((sender, args) -> { CommandSender callee = sender.getCallee(); if (callee instanceof Player player) { - PlayerMemory memory = PlayerUtility.getPlayerMemory(player.getUniqueId()); + final DVUser user = PlayerUtility.getUser(player); // Change data - if (memory.vanished) { + if (user.isVanished()) { - memory.vanished = false; + user.setVanished(false); String chatMessage = "**" + callee.getName() + " joined the game**"; // TODO: Send a join message to Discord. // Bot.getGameChatChannel().sendMessage(chatMessage).queue(); // Bot.sendLog(chatMessage); } else { - memory.vanished = true; + user.setVanished(true); String chatMessage = "**" + callee.getName() + " left the game**"; // TODO: Send a leave message to Discord. // Bot.getGameChatChannel().sendMessage(chatMessage).queue(); // Bot.sendLog(chatMessage); } - PlayerUtility.setPlayerMemory(player.getUniqueId(), memory); + PlayerUtility.saveUser(user); - Messager.send(sender, "Discord vanish toggled to " + memory.vanished + "."); + Messager.send(sender, "Discord vanish toggled to " + user.isVanished() + "."); } else throw CommandAPI.failWithString("This command must be executed as a player!"); }); diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/Config.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/Config.java index 1699119..3207893 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/Config.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/Config.java @@ -113,22 +113,41 @@ private static void applyConfig() { @NotNull @Contract("_, _ -> new") - public static CompletableFuture updateConfigField(String field, boolean value) { + public static CompletableFuture set(ConfigKey key, T value) { return CompletableFuture.runAsync(() -> { try { if (pocketBaseClient == null) { - Bukkit.getLogger().warning("PocketBase client not initialized, cannot update config"); + Dreamvisitor.getPlugin().getLogger().warning("PocketBase client not initialized, cannot update config"); return; } + if (value != null && !key.getType().isInstance(value)) { + throw new IllegalArgumentException("Value for config key '" + key.getKey() + + "' is not of expected type: " + key.getType().getSimpleName()); + } + // Create update data object JsonObject updateData = new JsonObject(); - updateData.addProperty(field, value); + + // Handle manual conversion for supported types + if (value instanceof Boolean) { + updateData.addProperty(key.getKey(), (Boolean) value); + } else if (value instanceof Number) { + updateData.addProperty(key.getKey(), (Number) value); + } else if (value instanceof String) { + updateData.addProperty(key.getKey(), (String) value); + } else { + // More types can be added if needed + throw new IllegalArgumentException("Unsupported config value type for key '" + key.getKey() + "'"); + } // Update the record pocketBaseClient.updateRecord(COLLECTION_NAME, configId, updateData, null, null); - Messager.debug("Updated PocketBase configuration field " + field + " to " + value); + Messager.debug("Updated PocketBase configuration field " + key.getKey() + " to " + value); + + // Update local storage + config.put(key.getKey(), value); // If not using realtime updates, we need to reload config manually if (!useRealtime) { diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/PlayerUtility.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/PlayerUtility.java index 2ea5746..c77a6bb 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/PlayerUtility.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/PlayerUtility.java @@ -1,82 +1,71 @@ package org.woftnw.dreamvisitor.data; -import java.io.File; -import java.io.IOException; import java.time.Instant; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; +import java.util.*; import com.earth2me.essentials.Essentials; +import org.bukkit.entity.Player; import org.woftnw.dreamvisitor.Dreamvisitor; import org.bukkit.Bukkit; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.shanerx.mojang.Mojang; +import org.woftnw.dreamvisitor.data.repository.UserRepository; +import org.woftnw.dreamvisitor.data.type.DVUser; public class PlayerUtility { - private static final Map MEMORY_MAP = new HashMap<>(); + private static final List USER_MEMORY = new ArrayList<>(); + + private static final UserRepository userRepository = Dreamvisitor.getPlugin().getRepositoryManager().getUserRepository(); private PlayerUtility() { throw new IllegalStateException("Utility class"); } - /** - * Get the specified player's memory from the file. - * Creates a new configuration with default values if one does not exist. - * @param uuid The UUID of the player whose data to fetch. - * @return The {@link PlayerMemory} of the given player. - */ - private static @NotNull PlayerMemory fetchPlayerMemory(@NotNull UUID uuid) { - File file = new File(Dreamvisitor.getPlayerPath(uuid)); - FileConfiguration fileConfig = YamlConfiguration.loadConfiguration(file); - return PlayerMemory.getFromFileConfig(fileConfig); - } - - /** - * Saves the specified player's memory to file. Does nothing if the player is not in memory. - * @param uuid The UUID of the player whose data to save. - */ - public static void savePlayerMemory(@NotNull UUID uuid) throws IOException { - if(MEMORY_MAP.containsKey(uuid.toString())) { - PlayerMemory memory = getPlayerMemory(uuid); - memory.toFileConfig().save(Dreamvisitor.getPlayerPath(uuid)); + @NotNull + public static DVUser getUser(@NotNull UUID uuid) { + // Check if in memory map + for (DVUser user : USER_MEMORY) { + if (Objects.equals(user.getMinecraftUuid(), uuid)) { + return user; + } } - } - /** - * Get the specified player's memory. If it is not in memory, it will be fetched from file. - * @param uuid The UUID of the player whose data to get. - * @return The {@link PlayerMemory} of the given player. - */ - public static @NotNull PlayerMemory getPlayerMemory(@NotNull UUID uuid) { - // If it does not exist in memory, add it - if(!MEMORY_MAP.containsKey(uuid.toString())) { - PlayerMemory memory = fetchPlayerMemory(uuid); - MEMORY_MAP.put(uuid.toString(), memory); - return memory; + // Get from repository + Optional optional = userRepository.findByUuid(uuid); + if (optional.isPresent()) { + // If it exists, add to memory map and return + USER_MEMORY.add(optional.get()); + return optional.get(); } - return MEMORY_MAP.get(uuid.toString()); + + // If not, create, add to memory map, and return + DVUser user = new DVUser(); + user.setMinecraftUuid(uuid); + USER_MEMORY.add(user); + return user; } - /** - * Removes the specified player's memory from random access storage. This does NOT save memory first. - * @param uuid The UUID of the player whose data to remove. - */ - public static void clearPlayerMemory(@NotNull UUID uuid) { - MEMORY_MAP.remove(uuid.toString()); + @NotNull + public static DVUser getUser(@NotNull Player player) { + return getUser(player.getUniqueId()); } - /** - * Update a player's memory configuration. This must be used to update a player's memory after it has been modified. - * @param uuid The UUID of the player whose data to modify. - * @param memory The modified {@link PlayerMemory}. - */ - public static void setPlayerMemory(@NotNull UUID uuid, @NotNull PlayerMemory memory) { - MEMORY_MAP.put(uuid.toString(), memory); + public static void saveUser(DVUser user) { + + DVUser existing = null; + for (DVUser dvUser : USER_MEMORY) { + if (Objects.equals(dvUser.getMinecraftUuid(), user.getMinecraftUuid())) { + existing = dvUser; + break; + } + } + if (existing != null) USER_MEMORY.remove(existing); + + USER_MEMORY.add(user); + + userRepository.save(existing); } /** diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/RealtimeConfigUpdater.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/RealtimeConfigUpdater.java index 3b2b93c..57e8e68 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/RealtimeConfigUpdater.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/RealtimeConfigUpdater.java @@ -1,5 +1,6 @@ package org.woftnw.dreamvisitor.data; +import org.jetbrains.annotations.NotNull; import org.woftnw.dreamvisitor.Dreamvisitor; import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.Bukkit; @@ -115,17 +116,7 @@ private static void connectSSE() throws IOException { private static void setSubscription() { try { - URL url = new URL(baseUrl + "/api/realtime"); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("POST"); - connection.setRequestProperty("Content-Type", "application/json"); - - // Add authentication if token is provided - if (token != null && !token.isEmpty()) { - connection.setRequestProperty("Authorization", "Bearer " + token); - } - - connection.setDoOutput(true); + HttpURLConnection connection = getRealtimeConnection(); // Subscribe to collection/record JSONObject requestBody = new JSONObject(); @@ -160,6 +151,22 @@ private static void setSubscription() { } } + @NotNull + private static HttpURLConnection getRealtimeConnection() throws IOException { + URL url = new URL(baseUrl + "/api/realtime"); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("POST"); + connection.setRequestProperty("Content-Type", "application/json"); + + // Add authentication if token is provided + if (token != null && !token.isEmpty()) { + connection.setRequestProperty("Authorization", "Bearer " + token); + } + + connection.setDoOutput(true); + return connection; + } + private static void handleUpdateEvent(String data) { try { JSONObject jsonData = new JSONObject(data); diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/ItemRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/ItemRepository.java deleted file mode 100644 index 2f7f7bb..0000000 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/ItemRepository.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.woftnw.dreamvisitor.data.repository; - -import java.util.List; -import java.util.Optional; - -import org.woftnw.dreamvisitor.data.type.Item; - -/** - * Repository interface for Item data operations - */ -public interface ItemRepository { - /** - * Find an item by its PocketBase ID - * - * @param id PocketBase record ID - * @return Optional containing the item if found - */ - Optional findById(String id); - - /** - * Find an item by its name - * - * @param name Item name - * @return Optional containing the item if found - */ - Optional findByName(String name); - - /** - * Get all items - * - * @return List of all items - */ - List findAll(); - - /** - * Get all enabled items - * - * @return List of all enabled items - */ - List findAllEnabled(); - - /** - * Save an item (create or update) - * - * @param item Item to save - * @return Saved item - */ - Item save(Item item); - - /** - * Delete an item - * - * @param item Item to delete - */ - void delete(Item item); - - /** - * Delete an item by ID - * - * @param id PocketBase ID of item to delete - */ - void deleteById(String id); - - /** - * Get all items matching a filter - * - * @param filter PocketBase filter expression - * @return List of items matching the filter - */ - List getAllWhere(String filter); -} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseItemRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseItemRepository.java deleted file mode 100644 index 6ee43e5..0000000 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseItemRepository.java +++ /dev/null @@ -1,327 +0,0 @@ -package org.woftnw.dreamvisitor.data.repository; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; - -import org.woftnw.dreamvisitor.data.type.Item; -import org.woftnw.dreamvisitor.pb.PocketBase; - -import java.io.IOException; -import java.time.OffsetDateTime; -import java.time.format.DateTimeFormatter; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; - -/** - * PocketBase implementation of the ItemRepository interface - */ -public class PocketBaseItemRepository implements ItemRepository { - private static final Logger LOGGER = Logger.getLogger(PocketBaseItemRepository.class.getName()); - private static final String COLLECTION_NAME = "items"; - private final PocketBase pocketBase; - private final Gson gson; - - /** - * Constructor for PocketBaseItemRepository - * - * @param pocketBase The PocketBase client to use - */ - public PocketBaseItemRepository(PocketBase pocketBase) { - this.pocketBase = pocketBase; - this.gson = new Gson(); - } - - @Override - public Optional findById(String id) { - try { - JsonObject record = pocketBase.getRecord(COLLECTION_NAME, id, null, null); - return Optional.of(mapToItem(record)); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error finding item by ID: " + id, e); - return Optional.empty(); - } - } - - @Override - public Optional findByName(String name) { - try { - String filter = "name = '" + name + "'"; - JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); - return Optional.of(mapToItem(record)); - } catch (IOException e) { - LOGGER.log(Level.FINE, "No item found with name: " + name); - return Optional.empty(); - } - } - - @Override - public List findAll() { - try { - List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, null, null, null); - return records.stream() - .map(this::mapToItem) - .collect(Collectors.toList()); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error retrieving all items", e); - return Collections.emptyList(); - } - } - - @Override - public List findAllEnabled() { - try { - String filter = "enabled = true"; - List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, filter, null, null); - return records.stream() - .map(this::mapToItem) - .collect(Collectors.toList()); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error retrieving enabled items", e); - return Collections.emptyList(); - } - } - - @Override - public Item save(Item item) { - try { - JsonObject itemData = mapToJsonObject(item); - - if (item.getId() != null && !item.getId().isEmpty()) { - // Update existing item - JsonObject updatedRecord = pocketBase.updateRecord(COLLECTION_NAME, item.getId(), itemData, null, null); - return mapToItem(updatedRecord); - } else { - // Create new item - JsonObject newRecord = pocketBase.createRecord(COLLECTION_NAME, itemData, null, null); - return mapToItem(newRecord); - } - } catch (IOException e) { - LOGGER.log(Level.SEVERE, "Error saving item: " + item.getName(), e); - throw new RuntimeException("Failed to save item", e); - } - } - - @Override - public void delete(Item item) { - if (item.getId() != null) { - deleteById(item.getId()); - } - } - - @Override - public void deleteById(String id) { - try { - pocketBase.deleteRecord(COLLECTION_NAME, id); - } catch (IOException e) { - LOGGER.log(Level.SEVERE, "Error deleting item with ID: " + id, e); - throw new RuntimeException("Failed to delete item", e); - } - } - - @Override - public List getAllWhere(String filter) { - try { - List records = pocketBase.getFullList(COLLECTION_NAME, 500, filter, null, null, null); - return records.stream() - .map(this::mapToItem) - .collect(Collectors.toList()); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error retrieving items with filter: " + filter, e); - return Collections.emptyList(); - } - } - - /** - * Convert a JsonObject from PocketBase to an Item object - * - * @param json JsonObject from PocketBase API - * @return Mapped Item object - */ - private Item mapToItem(JsonObject json) { - Item item = new Item(); - - item.setId(getStringOrNull(json, "id")); - item.setCollectionId(getStringOrNull(json, "collectionId")); - item.setCollectionName(getStringOrNull(json, "collectionName")); - - item.setName(getStringOrNull(json, "name")); - item.setDescription(getStringOrNull(json, "description")); - item.setPrice(getDoubleOrNull(json, "price")); - item.setSale_percent(getDoubleOrNull(json, "sale_percent")); - item.setQuantity(getIntOrNull(json, "quantity")); - item.setGifting_enabled(getBooleanOrNull(json, "gifting_enabled")); - item.setEnabled(getBooleanOrNull(json, "enabled")); - item.setMax_allowed(getIntOrNull(json, "max_allowed")); - item.setUse_disabled(getBooleanOrNull(json, "use_disabled")); - item.setUse_on_purchase(getBooleanOrNull(json, "use_on_purchase")); - - // For JSON fields that could be arrays, use getJsonArrayAsString - item.setOn_use_groups_add(getJsonArrayAsString(json, "on_use_groups_add")); - item.setOn_use_groups_remove(getJsonArrayAsString(json, "on_use_groups_remove")); - item.setOn_use_roles_add(getJsonArrayAsString(json, "on_use_roles_add")); - item.setOn_use_roles_remove(getJsonArrayAsString(json, "on_use_roles_remove")); - item.setOn_use_console_commands(getJsonArrayAsString(json, "on_use_console_commands")); - - item.setCreated(getOffsetDateTimeOrNull(json, "created")); - item.setUpdated(getOffsetDateTimeOrNull(json, "updated")); - - return item; - } - - /** - * Convert an Item object to a JsonObject for PocketBase - * - * @param item Item object to convert - * @return JsonObject for PocketBase API - */ - private JsonObject mapToJsonObject(Item item) { - JsonObject json = new JsonObject(); - - // Only include fields that PocketBase expects for updates/creates - if (item.getName() != null) - json.addProperty("name", item.getName()); - if (item.getDescription() != null) - json.addProperty("description", item.getDescription()); - - // Always include price even if it's 0.0 - PocketBase requires this field - // Previously we only included it if not null, but 0.0 might still be included - // in the JSON - if (item.getPrice() != null) { - json.addProperty("price", item.getPrice()); - } else { - // Set a default price of 0.0 if null to prevent validation errors - json.addProperty("price", 0.0); - } - - // For all other optional fields, only include if not null - if (item.getSale_percent() != null) - json.addProperty("sale_percent", item.getSale_percent()); - if (item.getQuantity() != null) - json.addProperty("quantity", item.getQuantity()); - if (item.getGifting_enabled() != null) - json.addProperty("gifting_enabled", item.getGifting_enabled()); - if (item.getEnabled() != null) - json.addProperty("enabled", item.getEnabled()); - if (item.getMax_allowed() != null) - json.addProperty("max_allowed", item.getMax_allowed()); - if (item.getUse_disabled() != null) - json.addProperty("use_disabled", item.getUse_disabled()); - if (item.getUse_on_purchase() != null) - json.addProperty("use_on_purchase", item.getUse_on_purchase()); - if (item.getOn_use_groups_add() != null) - json.addProperty("on_use_groups_add", item.getOn_use_groups_add()); - if (item.getOn_use_groups_remove() != null) - json.addProperty("on_use_groups_remove", item.getOn_use_groups_remove()); - if (item.getOn_use_roles_add() != null) - json.addProperty("on_use_roles_add", item.getOn_use_roles_add()); - if (item.getOn_use_roles_remove() != null) - json.addProperty("on_use_roles_remove", item.getOn_use_roles_remove()); - if (item.getOn_use_console_commands() != null) - json.addProperty("on_use_console_commands", item.getOn_use_console_commands()); - - return json; - } - - // Helper methods for extracting values from JsonObject - private String getStringOrNull(JsonObject json, String key) { - if (!json.has(key) || json.get(key).isJsonNull()) { - return null; - } - - com.google.gson.JsonElement element = json.get(key); - if (element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) { - return element.getAsString(); - } else { - LOGGER.warning("Field " + key + " is not a string primitive: " + element); - return null; - } - } - - private Integer getIntOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsInt() : null; - } - - private Double getDoubleOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsDouble() : null; - } - - private Boolean getBooleanOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsBoolean() : null; - } - - private OffsetDateTime getOffsetDateTimeOrNull(JsonObject json, String key) { - if (json.has(key) && !json.get(key).isJsonNull()) { - try { - String dateStr = json.get(key).getAsString(); - - // Check if the string is empty or blank - if (dateStr == null || dateStr.trim().isEmpty()) { - return null; - } - - // Handle PocketBase date format "yyyy-MM-dd HH:mm:ss.SSSZ" - if (dateStr.contains(" ") && !dateStr.contains("T")) { - // Replace space with 'T' to make it ISO-8601 compatible - dateStr = dateStr.replace(" ", "T"); - } - - return OffsetDateTime.parse(dateStr); - } catch (Exception e) { - LOGGER.warning("Failed to parse date: " + json.get(key).getAsString() + " - " + e.getMessage()); - - // Try alternative parsing with explicit formatter - try { - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSZ"); - String dateStr = json.get(key).getAsString(); - - // Check if the string is empty or blank - if (dateStr == null || dateStr.trim().isEmpty()) { - return null; - } - - // Convert to ISO format for parsing - if (dateStr.endsWith("Z")) { - dateStr = dateStr.substring(0, dateStr.length() - 1) + "+0000"; - } - - return OffsetDateTime.parse(dateStr.replace(" ", "T")); - } catch (Exception ex) { - LOGGER.warning("Alternative date parsing also failed: " + ex.getMessage()); - return null; - } - } - } - return null; - } - - private String formatDateTime(OffsetDateTime dateTime) { - return dateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); - } - - /** - * Safely get a JSON array field as a JSON string - * Handles cases where the field could be a string, array, or other type - */ - private String getJsonArrayAsString(JsonObject json, String key) { - if (!json.has(key) || json.get(key).isJsonNull()) { - return null; - } - - com.google.gson.JsonElement element = json.get(key); - if (element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) { - // It's already a string, return it directly - return element.getAsString(); - } else if (element.isJsonArray()) { - // It's an array, convert to a well-formatted JSON string - return element.toString(); - } else { - // For any other type, convert to string representation - LOGGER.warning("Field " + key + " is not a string or array: " + element); - return element.toString(); - } - } -} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseServerLogsRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseServerLogsRepository.java new file mode 100644 index 0000000..bbc2b40 --- /dev/null +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseServerLogsRepository.java @@ -0,0 +1,103 @@ +package org.woftnw.dreamvisitor.data.repository; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.woftnw.dreamvisitor.data.type.Item; +import org.woftnw.dreamvisitor.data.type.ServerLog; +import org.woftnw.dreamvisitor.pb.PocketBase; + +import java.io.IOException; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +/** + * PocketBase implementation of the ServerRepository interface + */ +public class PocketBaseServerLogsRepository implements ServerLogsRepository { + private static final Logger LOGGER = Logger.getLogger(PocketBaseServerLogsRepository.class.getName()); + private static final String COLLECTION_NAME = "server_logs"; + private final PocketBase pocketBase; + private final Gson gson; + + /** + * Constructor for PocketBaseServerBaseRepository + * + * @param pocketBase The PocketBase client to use + */ + public PocketBaseServerLogsRepository(PocketBase pocketBase) { + this.pocketBase = pocketBase; + this.gson = new Gson(); + } + + @Override + public List findLast(int count) { + return List.of(); + } + + @Override + public ServerLog create(ServerLog log) { + try { + JsonObject itemData = mapToJsonObject(log); + + if (log.getId() != null && !log.getId().isEmpty()) { + // Update existing log + JsonObject updatedRecord = pocketBase.updateRecord(COLLECTION_NAME, log.getId(), itemData, null, null); + return mapToItem(updatedRecord); + } else { + // Create new log + JsonObject newRecord = pocketBase.createRecord(COLLECTION_NAME, itemData, null, null); + return mapToItem(newRecord); + } + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Error saving log: ", e); + throw new RuntimeException("Failed to save log", e); + } + } + + /** + * Convert a JsonObject from PocketBase to an Item object + * + * @param json JsonObject from PocketBase API + * @return Mapped Item object + */ + @NotNull + private ServerLog mapToItem(JsonObject json) { + ServerLog log = new ServerLog(); + + log.setId(getStringOrNull(json, "id")); + log.setCollectionId(getStringOrNull(json, "collectionId")); + log.setCollectionName(getStringOrNull(json, "collectionName")); + + log.setLogMsg(getStringOrNull(json, "log_msg")); + + log.setCreated(getOffsetDateTimeOrNull(json, "created")); + log.setUpdated(getOffsetDateTimeOrNull(json, "updated")); + + return log; + } + + /** + * Convert an Item object to a JsonObject for PocketBase + * + * @param log Item object to convert + * @return JsonObject for PocketBase API + */ + @NotNull + private JsonObject mapToJsonObject(@NotNull ServerLog log) { + JsonObject json = new JsonObject(); + + // This is the only field for this type + if (log.getLogMsg() != null) + json.addProperty("log_msg", log.getLogMsg()); + + return json; + } +} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserInventoryRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserInventoryRepository.java deleted file mode 100644 index 0c96a57..0000000 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserInventoryRepository.java +++ /dev/null @@ -1,319 +0,0 @@ -package org.woftnw.dreamvisitor.data.repository; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; - -import org.woftnw.dreamvisitor.data.type.DVUser; -import org.woftnw.dreamvisitor.data.type.Item; -import org.woftnw.dreamvisitor.data.type.UserInventory; -import org.woftnw.dreamvisitor.pb.PocketBase; - -import java.io.IOException; -import java.time.OffsetDateTime; -import java.time.format.DateTimeFormatter; -import java.util.*; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; - -/** - * PocketBase implementation of the UserInventoryRepository interface - */ -public class PocketBaseUserInventoryRepository implements UserInventoryRepository { - private static final Logger LOGGER = Logger.getLogger(PocketBaseUserInventoryRepository.class.getName()); - private static final String COLLECTION_NAME = "user_inventory"; - private final PocketBase pocketBase; - private final Gson gson; - private final UserRepository userRepository; - private final ItemRepository itemRepository; - - /** - * Constructor for PocketBaseUserInventoryRepository - * - * @param pocketBase The PocketBase client to use - * @param userRepository The user repository for fetching related users - * @param itemRepository The item repository for fetching related items - */ - public PocketBaseUserInventoryRepository(PocketBase pocketBase, UserRepository userRepository, - ItemRepository itemRepository) { - this.pocketBase = pocketBase; - this.gson = new Gson(); - this.userRepository = userRepository; - this.itemRepository = itemRepository; - } - - @Override - public Optional findById(String id) { - try { - JsonObject record = pocketBase.getRecord(COLLECTION_NAME, id, null, null); - return Optional.of(mapToUserInventory(record)); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error finding user inventory by ID: " + id, e); - return Optional.empty(); - } - } - - @Override - public List findByUser(String userId) { - try { - String filter = "user = '" + userId + "'"; - List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, filter, null, null); - List inventoryEntries = records.stream() - .map(this::mapToUserInventory) - .collect(Collectors.toList()); - - // Load related items if there are inventory entries - if (!inventoryEntries.isEmpty()) { - loadRelatedItems(inventoryEntries); - } - - return inventoryEntries; - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error retrieving user inventory for user: " + userId, e); - return Collections.emptyList(); - } - } - - @Override - public Optional findByUserAndItem(String userId, String itemId) { - try { - String filter = "user = '" + userId + "' && item = '" + itemId + "'"; - JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); - UserInventory inventory = mapToUserInventory(record); - - // Load related item and user - if (inventory.getItem() != null) { - itemRepository.findById(inventory.getItem()).ifPresent(inventory::setCachedItem); - } - if (inventory.getUser() != null) { - userRepository.findById(inventory.getUser()).ifPresent(inventory::setCachedUser); - } - - return Optional.of(inventory); - } catch (IOException e) { - LOGGER.log(Level.FINE, "No inventory entry found for user: " + userId + " and item: " + itemId); - return Optional.empty(); - } - } - - @Override - public List findAll() { - try { - List records = pocketBase.getFullList(COLLECTION_NAME, 500, null, null, null, null); - return records.stream() - .map(this::mapToUserInventory) - .collect(Collectors.toList()); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error retrieving all user inventory entries", e); - return Collections.emptyList(); - } - } - - @Override - public UserInventory save(UserInventory userInventory) { - try { - JsonObject inventoryData = mapToJsonObject(userInventory); - - if (userInventory.getId() != null && !userInventory.getId().isEmpty()) { - // Update existing inventory entry - JsonObject updatedRecord = pocketBase.updateRecord(COLLECTION_NAME, userInventory.getId(), inventoryData, null, - null); - return mapToUserInventory(updatedRecord); - } else { - // Create new inventory entry - JsonObject newRecord = pocketBase.createRecord(COLLECTION_NAME, inventoryData, null, null); - return mapToUserInventory(newRecord); - } - } catch (IOException e) { - LOGGER.log(Level.SEVERE, "Error saving user inventory entry: " + userInventory.getId(), e); - throw new RuntimeException("Failed to save user inventory entry", e); - } - } - - @Override - public void delete(UserInventory userInventory) { - if (userInventory.getId() != null) { - deleteById(userInventory.getId()); - } - } - - @Override - public void deleteById(String id) { - try { - pocketBase.deleteRecord(COLLECTION_NAME, id); - } catch (IOException e) { - LOGGER.log(Level.SEVERE, "Error deleting user inventory entry with ID: " + id, e); - throw new RuntimeException("Failed to delete user inventory entry", e); - } - } - - @Override - public List getAllWhere(String filter) { - try { - List records = pocketBase.getFullList(COLLECTION_NAME, 500, filter, null, null, null); - return records.stream() - .map(this::mapToUserInventory) - .collect(Collectors.toList()); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Error retrieving user inventory entries with filter: " + filter, e); - return Collections.emptyList(); - } - } - - @Override - public List loadRelatedItems(List inventoryEntries) { - // Get unique item IDs - Set itemIds = inventoryEntries.stream() - .map(UserInventory::getItem) - .filter(Objects::nonNull) - .collect(Collectors.toSet()); - - // Fetch all items in one go - Map itemMap = new HashMap<>(); - for (String itemId : itemIds) { - itemRepository.findById(itemId).ifPresent(item -> itemMap.put(itemId, item)); - } - - // Set cached items - for (UserInventory entry : inventoryEntries) { - if (entry.getItem() != null && itemMap.containsKey(entry.getItem())) { - entry.setCachedItem(itemMap.get(entry.getItem())); - } - } - - return inventoryEntries; - } - - @Override - public List loadRelatedUsers(List inventoryEntries) { - // Get unique user IDs - Set userIds = inventoryEntries.stream() - .map(UserInventory::getUser) - .filter(Objects::nonNull) - .collect(Collectors.toSet()); - - // Fetch all users in one go - Map userMap = new HashMap<>(); - for (String userId : userIds) { - userRepository.findById(userId).ifPresent(user -> userMap.put(userId, user)); - } - - // Set cached users - for (UserInventory entry : inventoryEntries) { - if (entry.getUser() != null && userMap.containsKey(entry.getUser())) { - entry.setCachedUser(userMap.get(entry.getUser())); - } - } - - return inventoryEntries; - } - - /** - * Convert a JsonObject from PocketBase to a UserInventory object - * - * @param json JsonObject from PocketBase API - * @return Mapped UserInventory object - */ - private UserInventory mapToUserInventory(JsonObject json) { - UserInventory inventory = new UserInventory(); - - inventory.setId(getStringOrNull(json, "id")); - inventory.setCollectionId(getStringOrNull(json, "collectionId")); - inventory.setCollectionName(getStringOrNull(json, "collectionName")); - - inventory.setUser(getStringOrNull(json, "user")); - inventory.setItem(getStringOrNull(json, "item")); - inventory.setQuantity(getIntOrNull(json, "quantity")); - - inventory.setCreated(getOffsetDateTimeOrNull(json, "created")); - inventory.setUpdated(getOffsetDateTimeOrNull(json, "updated")); - - return inventory; - } - - /** - * Convert a UserInventory object to a JsonObject for PocketBase - * - * @param inventory UserInventory object to convert - * @return JsonObject for PocketBase API - */ - private JsonObject mapToJsonObject(UserInventory inventory) { - JsonObject json = new JsonObject(); - - // Only include fields that PocketBase expects for updates/creates - if (inventory.getUser() != null) - json.addProperty("user", inventory.getUser()); - if (inventory.getItem() != null) - json.addProperty("item", inventory.getItem()); - if (inventory.getQuantity() != null) - json.addProperty("quantity", inventory.getQuantity()); - - return json; - } - - // Helper methods for extracting values from JsonObject - private String getStringOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsString() : null; - } - - private Integer getIntOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsInt() : null; - } - - private Double getDoubleOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsDouble() : null; - } - - private Boolean getBooleanOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsBoolean() : null; - } - - private OffsetDateTime getOffsetDateTimeOrNull(JsonObject json, String key) { - if (json.has(key) && !json.get(key).isJsonNull()) { - try { - String dateStr = json.get(key).getAsString(); - - // Check if the string is empty or blank - if (dateStr == null || dateStr.trim().isEmpty()) { - return null; - } - - // Handle PocketBase date format "yyyy-MM-dd HH:mm:ss.SSSZ" - if (dateStr.contains(" ") && !dateStr.contains("T")) { - // Replace space with 'T' to make it ISO-8601 compatible - dateStr = dateStr.replace(" ", "T"); - } - - return OffsetDateTime.parse(dateStr); - } catch (Exception e) { - LOGGER.warning("Failed to parse date: " + json.get(key).getAsString() + " - " + e.getMessage()); - - // Try alternative parsing with explicit formatter - try { - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSZ"); - String dateStr = json.get(key).getAsString(); - - // Check if the string is empty or blank - if (dateStr == null || dateStr.trim().isEmpty()) { - return null; - } - - // Convert to ISO format for parsing - if (dateStr.endsWith("Z")) { - dateStr = dateStr.substring(0, dateStr.length() - 1) + "+0000"; - } - - return OffsetDateTime.parse(dateStr.replace(" ", "T")); - } catch (Exception ex) { - LOGGER.warning("Alternative date parsing also failed: " + ex.getMessage()); - return null; - } - } - } - return null; - } - - private String formatDateTime(OffsetDateTime dateTime) { - return dateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); - } -} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserRepository.java index 3e8a58f..bcf6439 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserRepository.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserRepository.java @@ -12,8 +12,6 @@ import java.io.IOException; import java.lang.reflect.Type; -import java.time.OffsetDateTime; -import java.time.format.DateTimeFormatter; import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; @@ -50,7 +48,7 @@ public Optional findById(String id) { } @Override - public Optional findByUuid(UUID mc_uuid) { + public Optional findByUuid(@NotNull UUID mc_uuid) { try { String filter = "mc_uuid = '" + mc_uuid.toString() + "'"; JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); @@ -62,7 +60,7 @@ public Optional findByUuid(UUID mc_uuid) { } @Override - public Optional findByDiscordId(String discordId) { + public Optional findByDiscordId(long discordId) { try { String filter = "discord_id = '" + discordId + "'"; JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); @@ -73,38 +71,6 @@ public Optional findByDiscordId(String discordId) { } } - @Override - public Optional findBySnowflakeId(Long snowflakeId) { - try { - // First try with the direct snowflake ID - String filter = "discord_id = '" + snowflakeId.toString() + "'"; - LOGGER.info("Searching for user with filter: " + filter); - - try { - JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); - LOGGER.info("User found with snowflake ID: " + snowflakeId); - DVUser user = mapToUser(record); - return Optional.of(user); - } catch (IOException e) { - // First search failed, try with just string comparison if numeric search fails - LOGGER.info("No exact match found, trying alternative search..."); - filter = "discord_id ~ '" + snowflakeId + "'"; - try { - JsonObject record = pocketBase.getFirstListItem(COLLECTION_NAME, filter, null, null, null); - LOGGER.info("User found with partial match: " + record.toString()); - DVUser user = mapToUser(record); - return Optional.of(user); - } catch (IOException e2) { - LOGGER.log(Level.INFO, "No user found with Snowflake ID (partial match): " + snowflakeId); - return Optional.empty(); - } - } - } catch (Exception e) { - LOGGER.log(Level.WARNING, "Error searching for user with Snowflake ID: " + snowflakeId, e); - return Optional.empty(); - } - } - @Override public Optional findByMcUsername(String mcUsername) { try { @@ -145,13 +111,13 @@ public DVUser save(DVUser user) { return mapToUser(newRecord); } } catch (IOException e) { - LOGGER.log(Level.SEVERE, "Error saving user: " + user.getMcUsername(), e); + LOGGER.log(Level.SEVERE, "Error saving user: " + user.getMinecraftUsername(), e); throw new RuntimeException("Failed to save user", e); } } @Override - public void delete(DVUser user) { + public void delete(@NotNull DVUser user) { if (user.getId() != null) { deleteById(user.getId()); } @@ -173,6 +139,7 @@ public void deleteById(String id) { * @param json JsonObject from PocketBase API * @return Mapped User object */ + @NotNull private DVUser mapToUser(JsonObject json) { DVUser user = new DVUser(); @@ -180,47 +147,39 @@ private DVUser mapToUser(JsonObject json) { user.setCollectionId(getStringOrNull(json, "collectionId")); user.setCollectionName(getStringOrNull(json, "collectionName")); - user.setDiscord_id(getStringOrNull(json, "discord_id")); - user.setDiscord_username(getStringOrNull(json, "discord_username")); - user.setDiscord_img(getStringOrNull(json, "discord_img")); - user.setMcUsername(getStringOrNull(json, "mc_username")); + user.setDiscordId(getLongOrNull(json, "discord_id")); + user.setDiscordUsername(getStringOrNull(json, "discord_username")); + user.setDiscordAvatarUrl(getStringOrNull(json, "discord_img")); + user.setMinecraftUsername(getStringOrNull(json, "mc_username")); if (json.has("mc_uuid") && !json.get("mc_uuid").isJsonNull()) { try { - user.setMc_uuid(UUID.fromString(PlayerUtility.formatUuid(json.get("mc_uuid").getAsString()))); + user.setMinecraftUuid(UUID.fromString(PlayerUtility.formatUuid(json.get("mc_uuid").getAsString()))); } catch (IllegalArgumentException e) { LOGGER.warning("Invalid UUID format: " + json.get("mc_uuid").getAsString()); } } - if (user.getDiscord_id() != null) { - try { - user.setSnowflakeId(Long.parseLong(user.getDiscord_id())); - } catch (NumberFormatException e) { - LOGGER.warning("Discord ID is not a valid snowflake: " + user.getDiscord_id()); - } - } - // Parse relation lists user.setInfractions(getStringListOrEmpty(json, "infractions")); - user.setUsers_home(getStringListOrEmpty(json, "users_home")); + user.setHomes(getStringListOrEmpty(json, "users_home")); user.setInventory_items(getStringListOrEmpty(json, "inventory_items")); user.setClaims(getStringListOrEmpty(json, "claims")); // Parse numeric fields - user.setClaim_limit(getIntOrNull(json, "claim_limit")); - user.setPlay_time(getIntOrNull(json, "play_time")); + user.setClaimLimit(getIntOrNull(json, "claim_limit")); + user.setPlayTime(getIntOrNull(json, "play_time")); user.setBalance(getDoubleOrNull(json, "balance")); user.setDaily_streak(getIntOrNull(json, "daily_streak")); // Parse boolean fields - user.setIs_suspended(getBooleanOrNull(json, "is_suspended")); - user.setIs_banned(getBooleanOrNull(json, "is_banned")); + user.setIsSuspended(getBooleanOrNull(json, "is_suspended")); + user.setIsBanned(getBooleanOrNull(json, "is_banned")); // Parse datetime fields - user.setLast_work(getOffsetDateTimeOrNull(json, "last_work")); + user.setLastWork(getOffsetDateTimeOrNull(json, "last_work")); user.setLast_Played(getOffsetDateTimeOrNull(json, "last_played")); - user.setLast_daily(getOffsetDateTimeOrNull(json, "last_daily")); + user.setLastDaily(getOffsetDateTimeOrNull(json, "last_daily")); user.setCreated(getOffsetDateTimeOrNull(json, "created")); user.setUpdated(getOffsetDateTimeOrNull(json, "updated")); @@ -233,42 +192,43 @@ private DVUser mapToUser(JsonObject json) { * @param user User object to convert * @return JsonObject for PocketBase API */ - private JsonObject mapToJsonObject(DVUser user) { + @NotNull + private JsonObject mapToJsonObject(@NotNull DVUser user) { JsonObject json = new JsonObject(); // Only include fields that PocketBase expects for updates/creates - if (user.getDiscord_id() != null) - json.addProperty("discord_id", user.getDiscord_id()); - if (user.getDiscord_username() != null) - json.addProperty("discord_username", user.getDiscord_username()); - if (user.getDiscord_img() != null) - json.addProperty("discord_img", user.getDiscord_img()); - if (user.getMcUsername() != null) - json.addProperty("mc_username", user.getMcUsername()); - if (user.getMc_uuid() != null) - json.addProperty("mc_uuid", user.getMc_uuid().toString()); + if (user.getDiscordId() != null) + json.addProperty("discord_id", user.getDiscordId()); + if (user.getDiscordUsername() != null) + json.addProperty("discord_username", user.getDiscordUsername()); + if (user.getDiscordAvatarUrl() != null) + json.addProperty("discord_img", user.getDiscordAvatarUrl()); + if (user.getMinecraftUsername() != null) + json.addProperty("mc_username", user.getMinecraftUsername()); + if (user.getMinecraftUuid() != null) + json.addProperty("mc_uuid", user.getMinecraftUuid().toString()); // Add numeric fields - if (user.getClaim_limit() != null) - json.addProperty("claim_limit", user.getClaim_limit()); - if (user.getPlay_time() != null) - json.addProperty("play_time", user.getPlay_time()); + if (user.getClaimLimit() != null) + json.addProperty("claim_limit", user.getClaimLimit()); + if (user.getPlayTime() != null) + json.addProperty("play_time", user.getPlayTime()); if (user.getBalance() != null) json.addProperty("balance", user.getBalance()); if (user.getDaily_streak() != null) json.addProperty("daily_streak", user.getDaily_streak()); // Add boolean fields - if (user.getIs_suspended() != null) - json.addProperty("is_suspended", user.getIs_suspended()); - if (user.getIs_banned() != null) - json.addProperty("is_banned", user.getIs_banned()); + if (user.getIsSuspended() != null) + json.addProperty("is_suspended", user.getIsSuspended()); + if (user.getIsBanned() != null) + json.addProperty("is_banned", user.getIsBanned()); // Format and add datetime fields - if (user.getLast_work() != null) - json.addProperty("last_work", formatDateTime(user.getLast_work())); - if (user.getLast_daily() != null) - json.addProperty("last_daily", formatDateTime(user.getLast_daily())); + if (user.getLastWork() != null) + json.addProperty("last_work", formatDateTime(user.getLastWork())); + if (user.getLastDaily() != null) + json.addProperty("last_daily", formatDateTime(user.getLastDaily())); // Add relation fields (these need to be handled separately based on // PocketBase's expectations) @@ -277,69 +237,8 @@ private JsonObject mapToJsonObject(DVUser user) { return json; } - private String getStringOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsString() : null; - } - - private Integer getIntOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsInt() : null; - } - - private Double getDoubleOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsDouble() : null; - } - - private Boolean getBooleanOrNull(JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsBoolean() : null; - } - - private OffsetDateTime getOffsetDateTimeOrNull(JsonObject json, String key) { - if (json.has(key) && !json.get(key).isJsonNull()) { - try { - String dateStr = json.get(key).getAsString(); - - // Check if the string is empty or blank - if (dateStr == null || dateStr.trim().isEmpty()) { - return null; - } - - // Handle PocketBase date format "yyyy-MM-dd HH:mm:ss.SSSZ" - if (dateStr.contains(" ") && !dateStr.contains("T")) { - // Replace space with 'T' to make it ISO-8601 compatible - dateStr = dateStr.replace(" ", "T"); - } - - return OffsetDateTime.parse(dateStr); - } catch (Exception e) { - LOGGER.warning("Failed to parse date: " + json.get(key).getAsString() + " - " + e.getMessage()); - - // Try alternative parsing with explicit formatter - try { - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSZ"); - String dateStr = json.get(key).getAsString(); - - // Check if the string is empty or blank - if (dateStr == null || dateStr.trim().isEmpty()) { - return null; - } - - // Convert to ISO format for parsing - if (dateStr.endsWith("Z")) { - dateStr = dateStr.substring(0, dateStr.length() - 1) + "+0000"; - } - - return OffsetDateTime.parse(dateStr.replace(" ", "T")); - } catch (Exception ex) { - LOGGER.warning("Alternative date parsing also failed: " + ex.getMessage()); - return null; - } - } - } - return null; - } - @NotNull - private List getStringListOrEmpty(JsonObject json, String key) { + private List getStringListOrEmpty(@NotNull JsonObject json, String key) { if (json.has(key) && !json.get(key).isJsonNull() && json.get(key).isJsonArray()) { Type listType = new TypeToken>() { }.getType(); @@ -348,10 +247,6 @@ private List getStringListOrEmpty(JsonObject json, String key) { return new ArrayList<>(); } - private String formatDateTime(OffsetDateTime dateTime) { - return dateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); - } - @Override public List getAllWhere(String filter) { try { diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/Repository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/Repository.java new file mode 100644 index 0000000..71823a0 --- /dev/null +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/Repository.java @@ -0,0 +1,124 @@ +package org.woftnw.dreamvisitor.data.repository; + +import com.google.gson.JsonObject; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.woftnw.dreamvisitor.Dreamvisitor; + +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; + +public interface Repository { + + // Helper methods for extracting values from JsonObject + @Nullable + default String getStringOrNull(@NotNull JsonObject json, String key) { + if (!json.has(key) || json.get(key).isJsonNull()) { + return null; + } + + com.google.gson.JsonElement element = json.get(key); + if (element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) { + return element.getAsString(); + } else { + Dreamvisitor.getPlugin().getLogger().warning("Field " + key + " is not a string primitive: " + element); + return null; + } + } + + @Nullable + default Integer getIntOrNull(@NotNull JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsInt() : null; + } + + @Nullable + default Long getLongOrNull(@NotNull JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsLong() : null; + } + + @Nullable + default Double getDoubleOrNull(@NotNull JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsDouble() : null; + } + + @Nullable + default Boolean getBooleanOrNull(@NotNull JsonObject json, String key) { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsBoolean() : null; + } + + @Nullable + default OffsetDateTime getOffsetDateTimeOrNull(@NotNull JsonObject json, String key) { + if (json.has(key) && !json.get(key).isJsonNull()) { + try { + String dateStr = json.get(key).getAsString(); + + // Check if the string is empty or blank + if (dateStr == null || dateStr.trim().isEmpty()) { + return null; + } + + // Handle PocketBase date format "yyyy-MM-dd HH:mm:ss.SSSZ" + if (dateStr.contains(" ") && !dateStr.contains("T")) { + // Replace space with 'T' to make it ISO-8601 compatible + dateStr = dateStr.replace(" ", "T"); + } + + return OffsetDateTime.parse(dateStr); + } catch (Exception e) { + Dreamvisitor.getPlugin().getLogger().warning("Failed to parse date: " + json.get(key).getAsString() + " - " + e.getMessage()); + + // Try alternative parsing with explicit formatter + try { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSZ"); + String dateStr = json.get(key).getAsString(); + + // Check if the string is empty or blank + if (dateStr == null || dateStr.trim().isEmpty()) { + return null; + } + + // Convert to ISO format for parsing + if (dateStr.endsWith("Z")) { + dateStr = dateStr.substring(0, dateStr.length() - 1) + "+0000"; + } + + return OffsetDateTime.parse(dateStr.replace(" ", "T")); + } catch (Exception ex) { + Dreamvisitor.getPlugin().getLogger().warning("Alternative date parsing also failed: " + ex.getMessage()); + return null; + } + } + } + return null; + } + + @NotNull + default String formatDateTime(@NotNull OffsetDateTime dateTime) { + return dateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); + } + + /** + * Safely get a JSON array field as a JSON string + * Handles cases where the field could be a string, array, or other type + */ + @Nullable + default String getJsonArrayAsString(@NotNull JsonObject json, String key) { + if (!json.has(key) || json.get(key).isJsonNull()) { + return null; + } + + com.google.gson.JsonElement element = json.get(key); + if (element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) { + // It's already a string, return it directly + return element.getAsString(); + } else if (element.isJsonArray()) { + // It's an array, convert to a well-formatted JSON string + return element.toString(); + } else { + // For any other type, convert to string representation + Dreamvisitor.getPlugin().getLogger().warning("Field " + key + " is not a string or array: " + element); + return element.toString(); + } + } + +} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/RepositoryManager.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/RepositoryManager.java new file mode 100644 index 0000000..77be215 --- /dev/null +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/RepositoryManager.java @@ -0,0 +1,25 @@ +package org.woftnw.dreamvisitor.data.repository; + +import org.woftnw.dreamvisitor.pb.PocketBase; + +/** + * This class stores repositories for access by other functions. The one instance of this is created in the Dreamvisitor enable process and can be accessed with Dreamvisitor.getPlugin().getRepositoryManager() + */ +public class RepositoryManager { + + final ServerLogsRepository serverLogsRepository; + final UserRepository userRepository; + + public RepositoryManager(PocketBase pocketBase) { + serverLogsRepository = new PocketBaseServerLogsRepository(pocketBase); + userRepository = new PocketBaseUserRepository(pocketBase); + } + + public ServerLogsRepository getServerLogsRepository() { + return serverLogsRepository; + } + + public UserRepository getUserRepository() { + return userRepository; + } +} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/ServerLogsRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/ServerLogsRepository.java new file mode 100644 index 0000000..b19565a --- /dev/null +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/ServerLogsRepository.java @@ -0,0 +1,26 @@ +package org.woftnw.dreamvisitor.data.repository; + +import org.woftnw.dreamvisitor.data.type.ServerLog; + +import java.util.List; + +/** + * Repository interface for Item data operations + */ +public interface ServerLogsRepository extends Repository { + /** + * Get the most recent n logs + * + * @return List of most recent n logs + */ + List findLast(int count); + + /** + * Save an item (create or update) + * + * @param item Item to save + * @return Saved item + */ + ServerLog create(ServerLog item); + +} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserInventoryRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserInventoryRepository.java deleted file mode 100644 index 5fe8e4a..0000000 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserInventoryRepository.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.woftnw.dreamvisitor.data.repository; - - -import java.util.List; -import java.util.Optional; - -import org.woftnw.dreamvisitor.data.type.UserInventory; - -/** - * Repository interface for UserInventory data operations - */ -public interface UserInventoryRepository { - /** - * Find an inventory entry by its PocketBase ID - * - * @param id PocketBase record ID - * @return Optional containing the inventory entry if found - */ - Optional findById(String id); - - /** - * Find all inventory entries for a user - * - * @param userId PocketBase user ID - * @return List of inventory entries for the user - */ - List findByUser(String userId); - - /** - * Find inventory entry for a specific user and item - * - * @param userId PocketBase user ID - * @param itemId PocketBase item ID - * @return Optional containing the inventory entry if found - */ - Optional findByUserAndItem(String userId, String itemId); - - /** - * Get all inventory entries - * - * @return List of all inventory entries - */ - List findAll(); - - /** - * Save an inventory entry (create or update) - * - * @param userInventory UserInventory to save - * @return Saved inventory entry - */ - UserInventory save(UserInventory userInventory); - - /** - * Delete an inventory entry - * - * @param userInventory UserInventory to delete - */ - void delete(UserInventory userInventory); - - /** - * Delete an inventory entry by ID - * - * @param id PocketBase ID of inventory entry to delete - */ - void deleteById(String id); - - /** - * Get all inventory entries matching a filter - * - * @param filter PocketBase filter expression - * @return List of inventory entries matching the filter - */ - List getAllWhere(String filter); - - /** - * Load related item data for all inventory entries - * - * @param inventoryEntries List of inventory entries - * @return List of inventory entries with loaded item data - */ - List loadRelatedItems(List inventoryEntries); - - /** - * Load related user data for all inventory entries - * - * @param inventoryEntries List of inventory entries - * @return List of inventory entries with loaded user data - */ - List loadRelatedUsers(List inventoryEntries); -} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserRepository.java index 13ffe3e..b0e56a9 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserRepository.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UserRepository.java @@ -10,7 +10,7 @@ /** * Repository interface for User data operations */ -public interface UserRepository { +public interface UserRepository extends Repository { /** * Find a user by their PocketBase ID * @@ -33,15 +33,7 @@ public interface UserRepository { * @param discordId Discord ID * @return Optional containing the user if found */ - Optional findByDiscordId(String discordId); - - /** - * Find a user by their Discord Snowflake ID - * - * @param snowflakeId Discord Snowflake ID - * @return Optional containing the user if found - */ - Optional findBySnowflakeId(Long snowflakeId); + Optional findByDiscordId(long discordId); /** * Find a user by their Minecraft username diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UsersHomesRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UsersHomesRepository.java new file mode 100644 index 0000000..b881197 --- /dev/null +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/UsersHomesRepository.java @@ -0,0 +1,60 @@ +package org.woftnw.dreamvisitor.data.repository; + + +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.woftnw.dreamvisitor.data.type.DVUser; +import org.woftnw.dreamvisitor.data.type.UserHome; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +/** + * Repository interface for User Home data operations + */ +public interface UsersHomesRepository extends Repository { + /** + * Find a user home by their PocketBase ID + * + * @param id PocketBase record ID + * @return Optional containing the home if found + */ + Optional findById(String id); + + List getHomesOfPlayer(UUID uuid); + + List getHomesOfPlayer(Player player); + + List getHomesOfWorld(World world); + + /** + * Get all user homes + * + * @return List of all homes + */ + List findAll(); + + /** + * Save a user home (create or update) + * + * @param home Home to save + * @return Saved UserHome + */ + UserHome save(UserHome home); + + /** + * Delete a home + * + * @param home Home to delete + */ + void delete(UserHome home); + + /** + * Delete a home by ID + * + * @param id PocketBase ID of home to delete + */ + void deleteById(String id); + +} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/DVUser.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/DVUser.java index 3929ab4..79a1c31 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/DVUser.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/DVUser.java @@ -1,73 +1,88 @@ package org.woftnw.dreamvisitor.data.type; +import org.bukkit.inventory.ItemStack; + import java.time.OffsetDateTime; +import java.util.ArrayList; import java.util.List; import java.util.UUID; public class DVUser { - private String id; - private String collectionId; - private String collectionName; - - private UUID mc_uuid; - private String mcUsername; - private String discord_username; - private String discord_id; - private String discord_img; - private Long snowflakeId; - - private List infractions; - private List users_home; - private List inventory_items; - private List claims; - private List alts; // Added alts field - - private Integer claim_limit; - private Integer play_time; - private Double balance; - private Integer daily_streak; - - private OffsetDateTime last_work; - private OffsetDateTime last_daily; - private OffsetDateTime last_played; - - private Boolean is_suspended; - private Boolean is_banned; - - private OffsetDateTime created; - private OffsetDateTime updated; + // Entry info + private String id = null; + private String collectionId = null; + private String collectionName = null; + + // Identification + private UUID minecraftUuid = null; + private String minecraftUsername = null; + private String discordUsername = null; + private Long discordId = null; + private String discordAvatarUrl = null; + + private List infractions = new ArrayList<>(); // This is irrelevant and can be removed + private List homes = new ArrayList<>(); + private List inventory_items = new ArrayList<>(); // This is irrelevant and can be removed + private List claims = new ArrayList<>(); + private List alts = new ArrayList<>(); // This is irrelevant and can be removed + + // In-game stats + private Integer claimLimit = 0; + private Integer playTime = 0; + // These are irrelevant and can be removed + private Double balance = 0d; + private Integer daily_streak = 0; + + // These are irrelevant and can be removed + private OffsetDateTime lastWork = null; + private OffsetDateTime lastDaily = null; + private OffsetDateTime lastPlayed = null; + + // Standing + private Boolean isSuspended = false; + private Boolean isBanned = false; + + // User options + private Boolean showDiscordMessages = true; + private Boolean flightDisabled = false; + private Boolean vanished = false; + private Boolean autoInvSwapEnabled = true; + private Boolean autoRadioEnabled = false; + + // Sandbox Mode + private Boolean inSandboxMode = false; + + // Inventory selection + private Boolean usingCreativeInv = false; + private ItemStack[] survivalInv = null; + private ItemStack[] creativeInv = null; + + private OffsetDateTime created = null; + private OffsetDateTime updated = null; // Existing getters and setters - public UUID getMc_uuid() { - return mc_uuid; - } - - public Long getSnowflakeId() { - return snowflakeId; + public UUID getMinecraftUuid() { + return minecraftUuid; } - public String getDiscord_username() { - return discord_username; + public String getDiscordUsername() { + return discordUsername; } - public String getMcUsername() { - return mcUsername; + public String getMinecraftUsername() { + return minecraftUsername; } - public void setDiscord_username(String dcUsername) { - this.discord_username = dcUsername; + public void setDiscordUsername(String dcUsername) { + this.discordUsername = dcUsername; } - public void setMcUsername(String mcUsername) { - this.mcUsername = mcUsername; + public void setMinecraftUsername(String minecraftUsername) { + this.minecraftUsername = minecraftUsername; } - public void setSnowflakeId(Long snowflakeId) { - this.snowflakeId = snowflakeId; - } - - public void setMc_uuid(UUID uuid) { - this.mc_uuid = uuid; + public void setMinecraftUuid(UUID minecraftUuid) { + this.minecraftUuid = minecraftUuid; } // New getters and setters @@ -95,20 +110,20 @@ public void setCollectionName(String collectionName) { this.collectionName = collectionName; } - public String getDiscord_id() { - return discord_id; + public Long getDiscordId() { + return discordId; } - public void setDiscord_id(String discord_id) { - this.discord_id = discord_id; + public void setDiscordId(Long discordId) { + this.discordId = discordId; } - public String getDiscord_img() { - return discord_img; + public String getDiscordAvatarUrl() { + return discordAvatarUrl; } - public void setDiscord_img(String discord_img) { - this.discord_img = discord_img; + public void setDiscordAvatarUrl(String discordAvatarUrl) { + this.discordAvatarUrl = discordAvatarUrl; } public List getInfractions() { @@ -119,12 +134,12 @@ public void setInfractions(List infractions) { this.infractions = infractions; } - public List getUsers_home() { - return users_home; + public List getHomes() { + return homes; } - public void setUsers_home(List users_home) { - this.users_home = users_home; + public void setHomes(List homes) { + this.homes = homes; } public List getInventory_items() { @@ -151,20 +166,20 @@ public void setAlts(List alts) { this.alts = alts; } - public Integer getClaim_limit() { - return claim_limit; + public Integer getClaimLimit() { + return claimLimit; } - public void setClaim_limit(Integer claim_limit) { - this.claim_limit = claim_limit; + public void setClaimLimit(Integer claimLimit) { + this.claimLimit = claimLimit; } - public Integer getPlay_time() { - return play_time; + public Integer getPlayTime() { + return playTime; } - public void setPlay_time(Integer play_time) { - this.play_time = play_time; + public void setPlayTime(Integer playTime) { + this.playTime = playTime; } public Double getBalance() { @@ -183,40 +198,40 @@ public void setDaily_streak(Integer daily_streak) { this.daily_streak = daily_streak; } - public OffsetDateTime getLast_work() { - return last_work; + public OffsetDateTime getLastWork() { + return lastWork; } - public void setLast_work(OffsetDateTime last_work) { - this.last_work = last_work; + public void setLastWork(OffsetDateTime lastWork) { + this.lastWork = lastWork; } - public OffsetDateTime getLast_played() { - return last_played; + public OffsetDateTime getLastPlayed() { + return lastPlayed; } - public OffsetDateTime getLast_daily() { - return last_daily; + public OffsetDateTime getLastDaily() { + return lastDaily; } - public void setLast_daily(OffsetDateTime last_daily) { - this.last_daily = last_daily; + public void setLastDaily(OffsetDateTime lastDaily) { + this.lastDaily = lastDaily; } - public Boolean getIs_suspended() { - return is_suspended; + public Boolean getIsSuspended() { + return isSuspended; } - public void setIs_suspended(Boolean is_suspended) { - this.is_suspended = is_suspended; + public void setIsSuspended(Boolean isSuspended) { + this.isSuspended = isSuspended; } - public Boolean getIs_banned() { - return is_banned; + public Boolean getIsBanned() { + return isBanned; } - public void setIs_banned(Boolean is_banned) { - this.is_banned = is_banned; + public void setIsBanned(Boolean isBanned) { + this.isBanned = isBanned; } public OffsetDateTime getCreated() { @@ -236,6 +251,78 @@ public void setUpdated(OffsetDateTime updated) { } public void setLast_Played(OffsetDateTime last_played) { - this.last_played = last_played; + this.lastPlayed = last_played; + } + + public Boolean isShowDiscordOn() { + return showDiscordMessages; + } + + public void setShowDiscordMessages(Boolean showDiscordMessages) { + this.showDiscordMessages = showDiscordMessages; + } + + public Boolean isFlightDisabled() { + return flightDisabled; + } + + public void setFlightDisabled(Boolean flightDisabled) { + this.flightDisabled = flightDisabled; + } + + public Boolean isVanished() { + return vanished; + } + + public void setVanished(Boolean vanished) { + this.vanished = vanished; + } + + public Boolean isAutoInvSwapEnabled() { + return autoInvSwapEnabled; + } + + public void setAutoInvSwapEnabled(Boolean autoInvSwapEnabled) { + this.autoInvSwapEnabled = autoInvSwapEnabled; + } + + public Boolean isAutoRadioEnabled() { + return autoRadioEnabled; + } + + public void setAutoRadioEnabled(Boolean autoRadioEnabled) { + this.autoRadioEnabled = autoRadioEnabled; + } + + public Boolean isInSandboxMode() { + return inSandboxMode; + } + + public void setInSandboxMode(Boolean inSandboxMode) { + this.inSandboxMode = inSandboxMode; + } + + public Boolean isUsingCreativeInv() { + return usingCreativeInv; + } + + public void setUsingCreativeInv(Boolean usingCreativeInv) { + this.usingCreativeInv = usingCreativeInv; + } + + public ItemStack[] getSurvivalInv() { + return survivalInv; + } + + public void setSurvivalInv(ItemStack[] survivalInv) { + this.survivalInv = survivalInv; + } + + public ItemStack[] getCreativeInv() { + return creativeInv; + } + + public void setCreativeInv(ItemStack[] creativeInv) { + this.creativeInv = creativeInv; } } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/ServerLog.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/ServerLog.java new file mode 100644 index 0000000..0b8fe71 --- /dev/null +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/ServerLog.java @@ -0,0 +1,63 @@ +package org.woftnw.dreamvisitor.data.type; + +import java.time.OffsetDateTime; + +public class ServerLog { + private String id; + private String collectionId; + private String collectionName; + + private String logMsg; + + private OffsetDateTime created; + private OffsetDateTime updated; + + // Getters and setters + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getCollectionId() { + return collectionId; + } + + public void setCollectionId(String collectionId) { + this.collectionId = collectionId; + } + + public String getCollectionName() { + return collectionName; + } + + public void setCollectionName(String collectionName) { + this.collectionName = collectionName; + } + + public String getLogMsg() { + return logMsg; + } + + public void setLogMsg(String logMsg) { + this.logMsg = logMsg; + } + + public OffsetDateTime getCreated() { + return created; + } + + public void setCreated(OffsetDateTime created) { + this.created = created; + } + + public OffsetDateTime getUpdated() { + return updated; + } + + public void setUpdated(OffsetDateTime updated) { + this.updated = updated; + } +} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/UserHome.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/UserHome.java new file mode 100644 index 0000000..b0cbd58 --- /dev/null +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/UserHome.java @@ -0,0 +1,75 @@ +package org.woftnw.dreamvisitor.data.type; + +import org.bukkit.Location; + +import java.time.OffsetDateTime; + +public class UserHome { + + private String id; + private String collectionId; + private String collectionName; + + private String name; + private Location location; + + private OffsetDateTime created; + private OffsetDateTime updated; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getCollectionId() { + return collectionId; + } + + public void setCollectionId(String collectionId) { + this.collectionId = collectionId; + } + + public String getCollectionName() { + return collectionName; + } + + public void setCollectionName(String collectionName) { + this.collectionName = collectionName; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Location getLocation() { + return location; + } + + public void setLocation(Location location) { + this.location = location; + } + + public OffsetDateTime getCreated() { + return created; + } + + public void setCreated(OffsetDateTime created) { + this.created = created; + } + + public OffsetDateTime getUpdated() { + return updated; + } + + public void setUpdated(OffsetDateTime updated) { + this.updated = updated; + } + +} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/AutoRestart.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/AutoRestart.java index fd6b64d..ce35acd 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/AutoRestart.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/AutoRestart.java @@ -4,6 +4,7 @@ import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Message; import org.jetbrains.annotations.Nullable; +import org.woftnw.dreamvisitor.util.ConfigKey; import java.awt.*; import java.time.Instant; @@ -18,19 +19,19 @@ public static void enableAutoRestart(@Nullable Message replyMessage) { autoRestartMessage = replyMessage; localAutoRestart = true; // Update the PocketBase config - Config.updateConfigField("autoRestart", true); + Config.set(ConfigKey.AUTO_RESTART, true); } public static void disableAutoRestart() { localAutoRestart = false; autoRestartMessage = null; // Update the PocketBase config - Config.updateConfigField("autoRestart", false); + Config.set(ConfigKey.AUTO_RESTART, false); } public static boolean isAutoRestart() { // Check PocketBase config first, fall back to local state if needed - return Config.getBoolean("autoRestart", localAutoRestart); + return Config.get(ConfigKey.AUTO_RESTART); } /** diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/CommandScheduler.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/CommandScheduler.java index 9567a8f..fd504e5 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/CommandScheduler.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/CommandScheduler.java @@ -16,963 +16,965 @@ import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.util.*; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.regex.PatternSyntaxException; public class CommandScheduler { - private static CommandScheduler instance; - private final List schedules = new ArrayList<>(); - private final File configFile; - private FileConfiguration config; - private int taskId = -1; - // how frequent to run the Scheduler checks - // unit is in Game Tick - // For 20 game ticks is one sec - private final long updateTick = 20L * 5L; - - private CommandScheduler() { - // Initialize config file - configFile = new File(Dreamvisitor.getPlugin().getDataFolder(), "schedules.yml"); - loadConfig(); - - // Start scheduler - startScheduler(); - } - - public static CommandScheduler getInstance() { - if (instance == null) { - instance = new CommandScheduler(); - } - return instance; - } - - /** - * Load schedules from configuration - */ - public void loadConfig() { - schedules.clear(); - if (!configFile.exists()) { - try { - configFile.createNewFile(); - } catch (IOException e) { - Dreamvisitor.getPlugin().getLogger().log(Level.SEVERE, "Could not create schedules.yml", e); - return; - } + private static CommandScheduler instance; + private final List schedules = new ArrayList<>(); + private final File configFile; + private FileConfiguration config; + private int taskId = -1; + // how frequent to run the Scheduler checks + // unit is in Game Tick + // For 20 game ticks is one sec + private final long updateTick = 20L * 5L; + + private CommandScheduler() { + // Initialize config file + configFile = new File(Dreamvisitor.getPlugin().getDataFolder(), "schedules.yml"); + loadConfig(); + + // Start scheduler + startScheduler(); + } + + public static CommandScheduler getInstance() { + if (instance == null) { + instance = new CommandScheduler(); + } + return instance; } - config = YamlConfiguration.loadConfiguration(configFile); - ConfigurationSection schedulesSection = config.getConfigurationSection("schedules"); - - if (schedulesSection != null) { - for (String name : schedulesSection.getKeys(false)) { - ConfigurationSection scheduleSection = schedulesSection.getConfigurationSection(name); - if (scheduleSection != null) { - String type = scheduleSection.getString("type", "interval"); - - switch (type) { - case "interval" -> { - int intervalMinutes = scheduleSection.getInt("interval-minutes"); - loadCommands(name, type, intervalMinutes, scheduleSection); + /** + * Load schedules from configuration + */ + public void loadConfig() { + schedules.clear(); + if (!configFile.exists()) { + try { + configFile.createNewFile(); + } catch (IOException e) { + Dreamvisitor.getPlugin().getLogger().log(Level.SEVERE, "Could not create schedules.yml", e); + return; } - case "daily" -> { - String timeString = scheduleSection.getString("time"); - if (timeString != null) { - try { - LocalTime time = LocalTime.parse(timeString); - loadCommands(name, type, time, scheduleSection); - } catch (DateTimeParseException e) { - Dreamvisitor.getPlugin().getLogger() - .warning("Invalid time format for schedule " + name + ": " + timeString); + } + + config = YamlConfiguration.loadConfiguration(configFile); + ConfigurationSection schedulesSection = config.getConfigurationSection("schedules"); + + if (schedulesSection != null) { + for (String name : schedulesSection.getKeys(false)) { + ConfigurationSection scheduleSection = schedulesSection.getConfigurationSection(name); + if (scheduleSection != null) { + String type = scheduleSection.getString("type", "interval"); + + switch (type) { + case "interval" -> { + int intervalMinutes = scheduleSection.getInt("interval-minutes"); + loadCommands(name, type, intervalMinutes, scheduleSection); + } + case "daily" -> { + String timeString = scheduleSection.getString("time"); + if (timeString != null) { + try { + LocalTime time = LocalTime.parse(timeString); + loadCommands(name, type, time, scheduleSection); + } catch (DateTimeParseException e) { + Dreamvisitor.getPlugin().getLogger() + .warning("Invalid time format for schedule " + name + ": " + timeString); + } + } + } + case "cron" -> { + String pattern = scheduleSection.getString("pattern"); + if (pattern != null) { + try { + CronPattern cronPattern = new CronPattern(pattern); + loadCommands(name, type, cronPattern, scheduleSection); + } catch (PatternSyntaxException e) { + Dreamvisitor.getPlugin().getLogger() + .warning("Invalid cron pattern for schedule " + name + ": " + pattern); + } + } + } + default -> Dreamvisitor.getPlugin().getLogger().warning("Unknown schedule type: " + type); + } } - } } - case "cron" -> { - String pattern = scheduleSection.getString("pattern"); - if (pattern != null) { + } + } + + private void loadCommands(String name, String type, Object timeSpec, ConfigurationSection section) { + List commandList = section.getStringList("commands"); + Map delays = new HashMap<>(); + + ConfigurationSection delaysSection = section.getConfigurationSection("delays"); + if (delaysSection != null) { + for (String key : delaysSection.getKeys(false)) { try { - CronPattern cronPattern = new CronPattern(pattern); - loadCommands(name, type, cronPattern, scheduleSection); - } catch (PatternSyntaxException e) { - Dreamvisitor.getPlugin().getLogger() - .warning("Invalid cron pattern for schedule " + name + ": " + pattern); + int index = Integer.parseInt(key); + int delay = delaysSection.getInt(key); + delays.put(index, delay); + } catch (NumberFormatException e) { + Dreamvisitor.getPlugin().getLogger().warning("Invalid delay index: " + key); } - } } - default -> Dreamvisitor.getPlugin().getLogger().warning("Unknown schedule type: " + type); - } } - } - } - } - private void loadCommands(String name, String type, Object timeSpec, ConfigurationSection section) { - List commandList = section.getStringList("commands"); - Map delays = new HashMap<>(); - - ConfigurationSection delaysSection = section.getConfigurationSection("delays"); - if (delaysSection != null) { - for (String key : delaysSection.getKeys(false)) { - try { - int index = Integer.parseInt(key); - int delay = delaysSection.getInt(key); - delays.put(index, delay); - } catch (NumberFormatException e) { - Dreamvisitor.getPlugin().getLogger().warning("Invalid delay index: " + key); + long lastRun = section.getLong("last-run", 0); + + Schedule schedule; + if (timeSpec instanceof Integer intervalMinutes) { + // Convert minutes to ticks (20 ticks/second * 60 seconds/minute) + int intervalTicks = intervalMinutes * 20 * 60; + schedule = new Schedule(name, intervalTicks, commandList, delays); + } else if (timeSpec instanceof LocalTime time) { + schedule = new Schedule(name, time, commandList, delays); + } else if (timeSpec instanceof CronPattern pattern) { + schedule = new Schedule(name, pattern, commandList, delays); + } else { + return; } - } - } - long lastRun = section.getLong("last-run", 0); - - Schedule schedule; - if (timeSpec instanceof Integer intervalMinutes) { - // Convert minutes to ticks (20 ticks/second * 60 seconds/minute) - int intervalTicks = intervalMinutes * 20 * 60; - schedule = new Schedule(name, intervalTicks, commandList, delays); - } else if (timeSpec instanceof LocalTime time) { - schedule = new Schedule(name, time, commandList, delays); - } else if (timeSpec instanceof CronPattern pattern) { - schedule = new Schedule(name, pattern, commandList, delays); - } else { - return; - } + if (lastRun > 0) { + schedule.setLastRun(LocalDateTime.ofEpochSecond(lastRun, 0, java.time.ZoneOffset.UTC)); + } - if (lastRun > 0) { - schedule.setLastRun(LocalDateTime.ofEpochSecond(lastRun, 0, java.time.ZoneOffset.UTC)); + schedules.add(schedule); } - schedules.add(schedule); - } - - /** - * Saves the current schedules to the configuration file. - *

- * This method serializes all schedule objects to YAML format and writes them to - * the schedules.yml file. Different schedule types (interval, daily, cron) are - * handled with appropriate type-specific properties. The method also saves - * metadata - * such as commands, delays, and last execution time. - *

- * If the save operation fails, an error is logged, but execution continues. - */ - public void saveConfig() { - // Clear existing schedules section to prevent stale data - config.set("schedules", null); - - // Iterate through all schedules and save each one - for (Schedule schedule : schedules) { - String path = "schedules." + schedule.getName(); - - // Save type-specific properties based on schedule type - switch (schedule.getType()) { - case INTERVAL -> { - config.set(path + ".type", "interval"); - // Convert ticks back to minutes for config storage for backward compatibility - // This allows older versions to read the configuration correctly - // TODO: Fix this as it cause losses in time units - config.set(path + ".interval-minutes", schedule.getIntervalMinutes()); - } - case DAILY -> { - config.set(path + ".type", "daily"); - // Format time using standard HH:mm:ss format for consistency - config.set(path + ".time", schedule.getDailyTime().format(DateTimeFormatter.ofPattern("HH:mm:ss"))); - } - case CRON -> { - config.set(path + ".type", "cron"); - // Store the raw cron pattern string - config.set(path + ".pattern", schedule.getCronPattern().getPattern()); - } - } - - config.set(path + ".commands", schedule.getCommands()); - - // Save delays - Map delays = schedule.getDelays(); - if (!delays.isEmpty()) { - for (Map.Entry entry : delays.entrySet()) { - config.set(path + ".delays." + entry.getKey(), entry.getValue()); - } - } - - if (schedule.getLastRun() != null) { - config.set(path + ".last-run", schedule.getLastRun().toEpochSecond(java.time.ZoneOffset.UTC)); - } - } + /** + * Saves the current schedules to the configuration file. + *

+ * This method serializes all schedule objects to YAML format and writes them to + * the schedules.yml file. Different schedule types (interval, daily, cron) are + * handled with appropriate type-specific properties. The method also saves + * metadata + * such as commands, delays, and last execution time. + *

+ * If the save operation fails, an error is logged, but execution continues. + */ + public void saveConfig() { + // Clear existing schedules section to prevent stale data + config.set("schedules", null); + + // Iterate through all schedules and save each one + for (Schedule schedule : schedules) { + String path = "schedules." + schedule.getName(); + + // Save type-specific properties based on schedule type + switch (schedule.getType()) { + case INTERVAL -> { + config.set(path + ".type", "interval"); + // Convert ticks back to minutes for config storage for backward compatibility + // This allows older versions to read the configuration correctly + // TODO: Fix this as it cause losses in time units + config.set(path + ".interval-minutes", schedule.getIntervalMinutes()); + } + case DAILY -> { + config.set(path + ".type", "daily"); + // Format time using standard HH:mm:ss format for consistency + config.set(path + ".time", schedule.getDailyTime().format(DateTimeFormatter.ofPattern("HH:mm:ss"))); + } + case CRON -> { + config.set(path + ".type", "cron"); + // Store the raw cron pattern string + config.set(path + ".pattern", schedule.getCronPattern().getPattern()); + } + } - try { - config.save(configFile); - } catch (IOException e) { - Dreamvisitor.getPlugin().getLogger().log(Level.SEVERE, "Could not save schedules.yml", e); - } - } - - /** - * Start the scheduler task - */ - public void startScheduler() { - if (taskId != -1) { - Bukkit.getScheduler().cancelTask(taskId); - } + config.set(path + ".commands", schedule.getCommands()); - taskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(Dreamvisitor.getPlugin(), this::checkSchedules, 20L, - updateTick); - } - - /** - * Stop the scheduler task - */ - public void stopScheduler() { - if (taskId != -1) { - Bukkit.getScheduler().cancelTask(taskId); - taskId = -1; - } - } - - /** - * Check if any schedules need to be run - */ - private void checkSchedules() { - LocalDateTime now = LocalDateTime.now(); - - for (Schedule schedule : new ArrayList<>(schedules)) { - if (schedule.shouldRun(now)) { - executeSchedule(schedule); - } - } - } - - /** - * Execute a scheduled command - * - * @param schedule The schedule to execute - */ - private void executeSchedule(Schedule schedule) { - Messager.debug("Executing scheduled commands for: " + schedule.getName()); - - final AtomicBoolean success = new AtomicBoolean(true); - List commands = schedule.getCommands(); - Map delays = schedule.getDelays(); - - schedule.setLastRun(LocalDateTime.now()); - saveConfig(); - - for (int i = 0; i < commands.size(); i++) { - final int index = i; - final String command = commands.get(i); - - // Get delay for this command in ticks (no conversion needed) - int delayTicks = 0; - if (delays.containsKey(index)) { - delayTicks = delays.get(index); - } - - Bukkit.getScheduler().runTaskLater(Dreamvisitor.getPlugin(), () -> { - Messager.debug("Executing command " + (index + 1) + "/" + commands.size() + ": " + command); - try { - boolean result = Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command); - if (!result) { - Dreamvisitor.getPlugin().getLogger().warning("Failed to execute scheduled command: " + command); - success.set(false); - } - } catch (Exception e) { - Dreamvisitor.getPlugin().getLogger().log(Level.SEVERE, "Error executing scheduled command: " + command, e); - success.set(false); - } - }, delayTicks); - } - } - - /** - * Add a new interval-based schedule - * - * @param name The name of the schedule - * @param intervalMinutes The interval in minutes - * @param commands The commands to run - * @return The created schedule - */ - public Schedule addSchedule(String name, int intervalMinutes, List commands) { - return addSchedule(name, intervalMinutes, commands, new HashMap<>()); - } - - /** - * Add a new interval-based schedule - * - * @param name The name of the schedule - * @param intervalMinutes The interval in minutes - * @param command Single command to run - * @return The created schedule - */ - public Schedule addSchedule(String name, int intervalMinutes, String command) { - return addSchedule(name, intervalMinutes, Collections.singletonList(command)); - } - - /** - * Add a new interval-based schedule with delays - * - * @param name The name of the schedule - * @param intervalMinutes The interval in minutes - * @param commands The commands to run - * @param delays Map of command index to delay in ticks - * @return The created schedule - */ - public Schedule addSchedule(String name, int intervalMinutes, List commands, Map delays) { - // Remove existing schedule with the same name - removeSchedule(name); - - // Convert minutes to ticks (20 ticks/second * 60 seconds/minute) - int intervalTicks = intervalMinutes * 20 * 60; - Schedule schedule = new Schedule(name, intervalTicks, commands, delays); - schedules.add(schedule); - saveConfig(); - return schedule; - } - - /** - * Add a new daily schedule - * - * @param name The name of the schedule - * @param time The time of day to run - * @param commands The commands to run - * @return The created schedule - */ - public Schedule addDailySchedule(String name, LocalTime time, List commands) { - return addDailySchedule(name, time, commands, new HashMap<>()); - } - - /** - * Add a new daily schedule - * - * @param name The name of the schedule - * @param time The time of day to run - * @param command Single command to run - * @return The created schedule - */ - public Schedule addDailySchedule(String name, LocalTime time, String command) { - return addDailySchedule(name, time, Collections.singletonList(command)); - } - - /** - * Add a new daily schedule with delays - * - * @param name The name of the schedule - * @param time The time of day to run - * @param commands The commands to run - * @param delays Map of command index to delay in ticks - * @return The created schedule - */ - public Schedule addDailySchedule(String name, LocalTime time, List commands, Map delays) { - // Remove existing schedule with the same name - removeSchedule(name); - - Schedule schedule = new Schedule(name, time, commands, delays); - schedules.add(schedule); - saveConfig(); - return schedule; - } - - /** - * Add a new cron-style schedule - * - * @param name The name of the schedule - * @param pattern The cron pattern - * @param commands The commands to run - * @return The created schedule - */ - public Schedule addCronSchedule(String name, String pattern, List commands) { - return addCronSchedule(name, pattern, commands, new HashMap<>()); - } - - /** - * Add a new cron-style schedule - * - * @param name The name of the schedule - * @param pattern The cron pattern - * @param command Single command to run - * @return The created schedule - */ - public Schedule addCronSchedule(String name, String pattern, String command) { - return addCronSchedule(name, pattern, Collections.singletonList(command)); - } - - /** - * Add a new cron-style schedule with delays - * - * @param name The name of the schedule - * @param pattern The cron pattern - * @param commands The commands to run - * @param delays Map of command index to delay in ticks - * @return The created schedule - */ - public Schedule addCronSchedule(String name, String pattern, List commands, Map delays) { - // Remove existing schedule with the same name - removeSchedule(name); - - try { - CronPattern cronPattern = new CronPattern(pattern); - Schedule schedule = new Schedule(name, cronPattern, commands, delays); - schedules.add(schedule); - saveConfig(); - return schedule; - } catch (PatternSyntaxException e) { - Dreamvisitor.getPlugin().getLogger().log(Level.SEVERE, "Invalid cron pattern: " + pattern, e); - return null; - } - } - - /** - * Remove a schedule - * - * @param name The name of the schedule - * @return True if removed, false if not found - */ - public boolean removeSchedule(String name) { - for (Schedule schedule : new ArrayList<>(schedules)) { - if (schedule.getName().equals(name)) { - schedules.remove(schedule); - saveConfig(); - return true; - } - } - return false; - } - - /** - * Get all schedules - * - * @return An unmodifiable list of schedules - */ - public List getSchedules() { - return Collections.unmodifiableList(schedules); - } - - /** - * Run a schedule immediately - * - * @param name The name of the schedule to run - * @return True if run, false if not found - */ - public boolean runScheduleNow(String name) { - for (Schedule schedule : schedules) { - if (schedule.getName().equals(name)) { - executeSchedule(schedule); - return true; - } - } - return false; - } - - /** - * Get a schedule by name - * - * @param name The name of the schedule - * @return The schedule or null if not found - */ - @Nullable - public Schedule getSchedule(String name) { - for (Schedule schedule : schedules) { - if (schedule.getName().equals(name)) { - return schedule; - } - } - return null; - } - - /** - * Add a delay to a command in a schedule - * - * @param name The schedule name - * @param commandIndex The command index (0-based) - * @param delayTicks The delay in ticks (20 ticks = 1 second) - * @return True if successful, false if schedule not found or index invalid - */ - public boolean addDelay(String name, int commandIndex, int delayTicks) { - Schedule schedule = getSchedule(name); - if (schedule == null || commandIndex < 0 || commandIndex >= schedule.getCommands().size()) { - return false; - } + // Save delays + Map delays = schedule.getDelays(); + if (!delays.isEmpty()) { + for (Map.Entry entry : delays.entrySet()) { + config.set(path + ".delays." + entry.getKey(), entry.getValue()); + } + } - schedule.addDelay(commandIndex, delayTicks); - saveConfig(); - return true; - } - - /** - * Remove a delay from a command in a schedule - * - * @param name The schedule name - * @param commandIndex The command index (0-based) - * @return True if successful, false if schedule not found or no delay was set - */ - public boolean removeDelay(String name, int commandIndex) { - Schedule schedule = getSchedule(name); - if (schedule == null) { - return false; - } + if (schedule.getLastRun() != null) { + config.set(path + ".last-run", schedule.getLastRun().toEpochSecond(java.time.ZoneOffset.UTC)); + } + } - boolean result = schedule.removeDelay(commandIndex); - if (result) { - saveConfig(); - } - return result; - } - - /** - * Add a command to an existing schedule - * - * @param name The schedule name - * @param command The command to add - * @return True if successful, false if schedule not found - */ - public boolean addCommand(String name, String command) { - Schedule schedule = getSchedule(name); - if (schedule == null) { - return false; + try { + config.save(configFile); + } catch (IOException e) { + Dreamvisitor.getPlugin().getLogger().log(Level.SEVERE, "Could not save schedules.yml", e); + } } - schedule.addCommand(command); - saveConfig(); - return true; - } - - /** - * Remove a command from a schedule - * - * @param name The schedule name - * @param commandIndex The command index (0-based) - * @return True if successful, false if schedule not found or index invalid - */ - public boolean removeCommand(String name, int commandIndex) { - Schedule schedule = getSchedule(name); - if (schedule == null) { - return false; - } + /** + * Start the scheduler task + */ + public void startScheduler() { + if (taskId != -1) { + Bukkit.getScheduler().cancelTask(taskId); + } - boolean result = schedule.removeCommand(commandIndex); - if (result) { - saveConfig(); - } - return result; - } - - /** - * Simple implementation of cron pattern matching - */ - public static class CronPattern { - // Format: minute hour day-of-month month day-of-week - // Supported: numbers, *, ranges (1-5), lists (1,2,3), step values (*/5, 1-5/2) - private final String pattern; - private final String minutePattern; - private final String hourPattern; - private final String dayOfMonthPattern; - private final String monthPattern; - private final String dayOfWeekPattern; - - public CronPattern(String pattern) throws PatternSyntaxException { - this.pattern = pattern; - String[] parts = pattern.split("\\s+"); - if (parts.length != 5) { - throw new PatternSyntaxException("Cron pattern must have 5 parts", pattern, -1); - } - minutePattern = parts[0]; - hourPattern = parts[1]; - dayOfMonthPattern = parts[2]; - monthPattern = parts[3]; - dayOfWeekPattern = parts[4]; - - // Validate all patterns - validateField(minutePattern, 0, 59); - validateField(hourPattern, 0, 23); - validateField(dayOfMonthPattern, 1, 31); - validateField(monthPattern, 1, 12); - validateField(dayOfWeekPattern, 0, 6); + taskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(Dreamvisitor.getPlugin(), this::checkSchedules, 20L, + updateTick); } - private void validateField(String field, int min, int max) throws PatternSyntaxException { - if (field.equals("*")) { - return; - } - - if (field.contains("/")) { - String[] parts = field.split("/"); - if (parts.length != 2) { - throw new PatternSyntaxException("Invalid step value format", field, -1); - } - validateField(parts[0], min, max); - try { - int step = Integer.parseInt(parts[1]); - if (step <= 0) { - throw new PatternSyntaxException("Step value must be positive", field, -1); - } - } catch (NumberFormatException e) { - throw new PatternSyntaxException("Invalid step value", field, -1); + /** + * Stop the scheduler task + */ + public void stopScheduler() { + if (taskId != -1) { + Bukkit.getScheduler().cancelTask(taskId); + taskId = -1; } - return; - } + } - if (field.contains(",")) { - for (String part : field.split(",")) { - validateField(part, min, max); - } - return; - } + /** + * Check if any schedules need to be run + */ + private void checkSchedules() { + LocalDateTime now = LocalDateTime.now(); - if (field.contains("-")) { - String[] parts = field.split("-"); - if (parts.length != 2) { - throw new PatternSyntaxException("Invalid range format", field, -1); + for (Schedule schedule : new ArrayList<>(schedules)) { + if (schedule.shouldRun(now)) { + executeSchedule(schedule); + } } - try { - int start = Integer.parseInt(parts[0]); - int end = Integer.parseInt(parts[1]); - if (start < min || end > max || start > end) { - throw new PatternSyntaxException("Invalid range values", field, -1); - } - } catch (NumberFormatException e) { - throw new PatternSyntaxException("Invalid range values", field, -1); - } - return; - } - - try { - int value = Integer.parseInt(field); - if (value < min || value > max) { - throw new PatternSyntaxException("Value out of range", field, -1); - } - } catch (NumberFormatException e) { - throw new PatternSyntaxException("Invalid value", field, -1); - } } - public String getPattern() { - return pattern; - } + /** + * Execute a scheduled command + * + * @param schedule The schedule to execute + */ + private void executeSchedule(@NotNull Schedule schedule) { + Messager.debug("Executing scheduled commands for: " + schedule.getName()); - public boolean matches(LocalDateTime dateTime) { - return matchesField(minutePattern, dateTime.getMinute(), 0, 59) - && matchesField(hourPattern, dateTime.getHour(), 0, 23) - && matchesField(dayOfMonthPattern, dateTime.getDayOfMonth(), 1, 31) - && matchesField(monthPattern, dateTime.getMonthValue(), 1, 12) - && matchesField(dayOfWeekPattern, dateTime.getDayOfWeek().getValue() % 7, 0, 6); - } + List commands = schedule.getCommands(); + Map delays = schedule.getDelays(); - private boolean matchesField(String pattern, int value, int min, int max) { - if (pattern.equals("*")) { - return true; - } + schedule.setLastRun(LocalDateTime.now()); + saveConfig(); - if (pattern.contains("/")) { - String[] parts = pattern.split("/"); - String range = parts[0]; - int step = Integer.parseInt(parts[1]); + for (int i = 0; i < commands.size(); i++) { + final int index = i; + final String command = commands.get(i); - if (range.equals("*")) { - return (value - min) % step == 0; - } else { - return matchesField(range, value, min, max) && (value - min) % step == 0; - } - } + // Get delay for this command in ticks (no conversion needed) + int delayTicks = 0; + if (delays.containsKey(index)) { + delayTicks = delays.get(index); + } - if (pattern.contains(",")) { - for (String part : pattern.split(",")) { - if (matchesField(part, value, min, max)) { - return true; - } + Bukkit.getScheduler().runTaskLater(Dreamvisitor.getPlugin(), () -> { + Messager.debug("Executing command " + (index + 1) + "/" + commands.size() + ": " + command); + try { + boolean result = Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command); + if (!result) { + Dreamvisitor.getPlugin().getLogger().warning("Failed to execute scheduled command: " + command); + } + } catch (Exception e) { + Dreamvisitor.getPlugin().getLogger().log(Level.SEVERE, "Error executing scheduled command: " + command, e); + } + }, delayTicks); } - return false; - } - - if (pattern.contains("-")) { - String[] parts = pattern.split("-"); - int start = Integer.parseInt(parts[0]); - int end = Integer.parseInt(parts[1]); - return value >= start && value <= end; - } - - return Integer.parseInt(pattern) == value; - } - } - - /** - * Class representing a scheduled command - */ - public static class Schedule { - private final String name; - private final ScheduleType type; - private final int intervalTicks; // Now storing interval in ticks instead of minutes - private final LocalTime dailyTime; - private final CronPattern cronPattern; - private final List commands; - private final Map delays; // Command index -> delay in ticks - private LocalDateTime lastRun; - - public enum ScheduleType { - INTERVAL, DAILY, CRON } - // Interval constructor - now accepts ticks instead of minutes - public Schedule(String name, int intervalTicks, List commands, Map delays) { - this.name = name; - this.type = ScheduleType.INTERVAL; - this.intervalTicks = intervalTicks; - this.dailyTime = null; - this.cronPattern = null; - this.commands = new ArrayList<>(commands); - this.delays = new HashMap<>(delays); - this.lastRun = null; + /** + * Add a new interval-based schedule + * + * @param name The name of the schedule + * @param intervalMinutes The interval in minutes + * @param commands The commands to run + * @return The created schedule + */ + public Schedule addSchedule(String name, int intervalMinutes, List commands) { + return addSchedule(name, intervalMinutes, commands, new HashMap<>()); } - // Daily constructor - public Schedule(String name, LocalTime time, List commands, Map delays) { - this.name = name; - this.type = ScheduleType.DAILY; - this.intervalTicks = 0; - this.dailyTime = time; - this.cronPattern = null; - this.commands = new ArrayList<>(commands); - this.delays = new HashMap<>(delays); - this.lastRun = null; + /** + * Add a new interval-based schedule + * + * @param name The name of the schedule + * @param intervalMinutes The interval in minutes + * @param command Single command to run + * @return The created schedule + */ + public Schedule addSchedule(String name, int intervalMinutes, String command) { + return addSchedule(name, intervalMinutes, Collections.singletonList(command)); } - // Cron constructor - public Schedule(String name, CronPattern pattern, List commands, Map delays) { - this.name = name; - this.type = ScheduleType.CRON; - this.intervalTicks = 0; - this.dailyTime = null; - this.cronPattern = pattern; - this.commands = new ArrayList<>(commands); - this.delays = new HashMap<>(delays); - this.lastRun = null; + /** + * Add a new interval-based schedule with delays + * + * @param name The name of the schedule + * @param intervalMinutes The interval in minutes + * @param commands The commands to run + * @param delays Map of command index to delay in ticks + * @return The created schedule + */ + public Schedule addSchedule(String name, int intervalMinutes, List commands, Map delays) { + // Remove existing schedule with the same name + removeSchedule(name); + + // Convert minutes to ticks (20 ticks/second * 60 seconds/minute) + int intervalTicks = intervalMinutes * 20 * 60; + Schedule schedule = new Schedule(name, intervalTicks, commands, delays); + schedules.add(schedule); + saveConfig(); + return schedule; } - public String getName() { - return name; + /** + * Add a new daily schedule + * + * @param name The name of the schedule + * @param time The time of day to run + * @param commands The commands to run + * @return The created schedule + */ + public Schedule addDailySchedule(String name, LocalTime time, List commands) { + return addDailySchedule(name, time, commands, new HashMap<>()); } - public ScheduleType getType() { - return type; + /** + * Add a new daily schedule + * + * @param name The name of the schedule + * @param time The time of day to run + * @param command Single command to run + * @return The created schedule + */ + public Schedule addDailySchedule(String name, LocalTime time, String command) { + return addDailySchedule(name, time, Collections.singletonList(command)); } /** - * Get the interval in minutes (converted from ticks for backward compatibility) + * Add a new daily schedule with delays * - * @return The interval in minutes + * @param name The name of the schedule + * @param time The time of day to run + * @param commands The commands to run + * @param delays Map of command index to delay in ticks + * @return The created schedule */ - public int getIntervalMinutes() { - return intervalTicks / (20 * 60); // Convert ticks to minutes + public Schedule addDailySchedule(String name, LocalTime time, List commands, Map delays) { + // Remove existing schedule with the same name + removeSchedule(name); + + Schedule schedule = new Schedule(name, time, commands, delays); + schedules.add(schedule); + saveConfig(); + return schedule; } /** - * Get the interval in ticks + * Add a new cron-style schedule * - * @return The interval in ticks + * @param name The name of the schedule + * @param pattern The cron pattern + * @param commands The commands to run + * @return The created schedule */ - public int getIntervalTicks() { - return intervalTicks; + public Schedule addCronSchedule(String name, String pattern, List commands) { + return addCronSchedule(name, pattern, commands, new HashMap<>()); } - public LocalTime getDailyTime() { - return dailyTime; + /** + * Add a new cron-style schedule + * + * @param name The name of the schedule + * @param pattern The cron pattern + * @param command Single command to run + * @return The created schedule + */ + public Schedule addCronSchedule(String name, String pattern, String command) { + return addCronSchedule(name, pattern, Collections.singletonList(command)); } - public CronPattern getCronPattern() { - return cronPattern; - } + /** + * Add a new cron-style schedule with delays + * + * @param name The name of the schedule + * @param pattern The cron pattern + * @param commands The commands to run + * @param delays Map of command index to delay in ticks + * @return The created schedule + */ + public Schedule addCronSchedule(String name, String pattern, List commands, Map delays) { + // Remove existing schedule with the same name + removeSchedule(name); - public List getCommands() { - return Collections.unmodifiableList(commands); + try { + CronPattern cronPattern = new CronPattern(pattern); + Schedule schedule = new Schedule(name, cronPattern, commands, delays); + schedules.add(schedule); + saveConfig(); + return schedule; + } catch (PatternSyntaxException e) { + Dreamvisitor.getPlugin().getLogger().log(Level.SEVERE, "Invalid cron pattern: " + pattern, e); + return null; + } } - public Map getDelays() { - return Collections.unmodifiableMap(delays); + /** + * Remove a schedule + * + * @param name The name of the schedule + * @return True if removed, false if not found + */ + public boolean removeSchedule(String name) { + for (Schedule schedule : new ArrayList<>(schedules)) { + if (schedule.getName().equals(name)) { + schedules.remove(schedule); + saveConfig(); + return true; + } + } + return false; } - public LocalDateTime getLastRun() { - return lastRun; + /** + * Get all schedules + * + * @return An unmodifiable list of schedules + */ + public List getSchedules() { + return Collections.unmodifiableList(schedules); } - public void setLastRun(LocalDateTime lastRun) { - this.lastRun = lastRun; + /** + * Run a schedule immediately + * + * @param name The name of the schedule to run + * @return True if run, false if not found + */ + public boolean runScheduleNow(String name) { + for (Schedule schedule : schedules) { + if (schedule.getName().equals(name)) { + executeSchedule(schedule); + return true; + } + } + return false; } - public void addCommand(String command) { - this.commands.add(command); + /** + * Get a schedule by name + * + * @param name The name of the schedule + * @return The schedule or null if not found + */ + @Nullable + public Schedule getSchedule(String name) { + for (Schedule schedule : schedules) { + if (schedule.getName().equals(name)) { + return schedule; + } + } + return null; } - public boolean removeCommand(int index) { - if (index < 0 || index >= commands.size()) { - return false; - } - commands.remove(index); - - // Remove any delays for this command - delays.remove(index); - - // Adjust delays for higher indexed commands - Map newDelays = new HashMap<>(); - for (Map.Entry entry : delays.entrySet()) { - int delayIndex = entry.getKey(); - if (delayIndex > index) { - newDelays.put(delayIndex - 1, entry.getValue()); - } else { - newDelays.put(delayIndex, entry.getValue()); + /** + * Add a delay to a command in a schedule + * + * @param name The schedule name + * @param commandIndex The command index (0-based) + * @param delayTicks The delay in ticks (20 ticks = 1 second) + * @return True if successful, false if schedule not found or index invalid + */ + public boolean addDelay(String name, int commandIndex, int delayTicks) { + Schedule schedule = getSchedule(name); + if (schedule == null || commandIndex < 0 || commandIndex >= schedule.getCommands().size()) { + return false; } - } - delays.clear(); - delays.putAll(newDelays); - return true; - } - public void addDelay(int commandIndex, int delayTicks) { - delays.put(commandIndex, delayTicks); + schedule.addDelay(commandIndex, delayTicks); + saveConfig(); + return true; } - public boolean removeDelay(int commandIndex) { - return delays.remove(commandIndex) != null; + /** + * Remove a delay from a command in a schedule + * + * @param name The schedule name + * @param commandIndex The command index (0-based) + * @return True if successful, false if schedule not found or no delay was set + */ + public boolean removeDelay(String name, int commandIndex) { + Schedule schedule = getSchedule(name); + if (schedule == null) { + return false; + } + + boolean result = schedule.removeDelay(commandIndex); + if (result) { + saveConfig(); + } + return result; } /** - * Check if this schedule should run + * Add a command to an existing schedule * - * @param now The current time - * @return True if it should run + * @param name The schedule name + * @param command The command to add + * @return True if successful, false if schedule not found */ - public boolean shouldRun(@NotNull LocalDateTime now) { - switch (type) { - case INTERVAL: - if (lastRun == null) { - return true; // Never run before - } - Duration duration = Duration.between(lastRun, now); - // Convert duration to ticks and compare with intervalTicks - long durationTicks = duration.toSeconds() * 20; - return durationTicks >= intervalTicks; - - case DAILY: - if (lastRun != null && lastRun.toLocalDate().equals(now.toLocalDate())) { - return false; // Already run today - } - LocalTime currentTime = now.toLocalTime(); - return currentTime.isAfter(dailyTime) || currentTime.equals(dailyTime); - - case CRON: - if (lastRun != null) { - LocalDateTime nextMinute = lastRun.plusMinutes(1).withSecond(0).withNano(0); - if (now.isBefore(nextMinute)) { - return false; // Don't run more than once per minute - } - } - return cronPattern.matches(now); + public boolean addCommand(String name, String command) { + Schedule schedule = getSchedule(name); + if (schedule == null) { + return false; + } - default: - return false; - } + schedule.addCommand(command); + saveConfig(); + return true; } /** - * Get a user-friendly string representation of time until next run + * Remove a command from a schedule * - * @return Time until next run as a string + * @param name The schedule name + * @param commandIndex The command index (0-based) + * @return True if successful, false if schedule not found or index invalid + */ + public boolean removeCommand(String name, int commandIndex) { + Schedule schedule = getSchedule(name); + if (schedule == null) { + return false; + } + + boolean result = schedule.removeCommand(commandIndex); + if (result) { + saveConfig(); + } + return result; + } + + /** + * Simple implementation of cron pattern matching */ - public String getTimeUntilNextRun() { - LocalDateTime now = LocalDateTime.now(); - - switch (type) { - case INTERVAL: - if (lastRun == null) { - return "Ready to run"; - } - - // Calculate next run time using ticks - long durationSeconds = intervalTicks / 20; - LocalDateTime nextRun = lastRun.plusSeconds(durationSeconds); - Duration duration = Duration.between(now, nextRun); - - if (duration.isNegative()) { - return "Ready to run"; - } - - long hours = duration.toHours(); - long minutes = duration.toMinutesPart(); - long seconds = duration.toSecondsPart(); - - if (hours > 0) { - return hours + "h " + minutes + "m " + seconds + "s"; - } else if (minutes > 0) { - return minutes + "m " + seconds + "s"; - } else { - return seconds + "s"; - } - - case DAILY: - LocalDateTime nextRunTime = now.toLocalDate().atTime(dailyTime); - if (now.isAfter(nextRunTime)) { - nextRunTime = nextRunTime.plusDays(1); - } - - Duration timeUntil = Duration.between(now, nextRunTime); - long days = timeUntil.toDays(); - long dHours = timeUntil.toHoursPart(); - long dMinutes = timeUntil.toMinutesPart(); - - if (days > 0) { - return days + "d " + dHours + "h " + dMinutes + "m"; - } else if (dHours > 0) { - return dHours + "h " + dMinutes + "m"; - } else { - return dMinutes + "m"; - } - - case CRON: - // For cron, we check the next few hours in 1-minute increments to find the next - // match - LocalDateTime checkTime = now; - for (int i = 0; i < 24 * 60; i++) { // Check up to 24 hours ahead - checkTime = checkTime.plusMinutes(1); - if (cronPattern.matches(checkTime)) { - Duration cronTimeUntil = Duration.between(now, checkTime); - long cronHours = cronTimeUntil.toHours(); - long cronMinutes = cronTimeUntil.toMinutesPart(); - - if (cronHours > 0) { - return cronHours + "h " + cronMinutes + "m"; - } else { - return cronMinutes + "m"; - } + public static class CronPattern { + // Format: minute hour day-of-month month day-of-week + // Supported: numbers, *, ranges (1-5), lists (1,2,3), step values (*/5, 1-5/2) + private final String pattern; + private final String minutePattern; + private final String hourPattern; + private final String dayOfMonthPattern; + private final String monthPattern; + private final String dayOfWeekPattern; + + public CronPattern(String pattern) throws PatternSyntaxException { + this.pattern = pattern; + String[] parts = pattern.split("\\s+"); + if (parts.length != 5) { + throw new PatternSyntaxException("Cron pattern must have 5 parts", pattern, -1); + } + minutePattern = parts[0]; + hourPattern = parts[1]; + dayOfMonthPattern = parts[2]; + monthPattern = parts[3]; + dayOfWeekPattern = parts[4]; + + // Validate all patterns + validateField(minutePattern, 0, 59); + validateField(hourPattern, 0, 23); + validateField(dayOfMonthPattern, 1, 31); + validateField(monthPattern, 1, 12); + validateField(dayOfWeekPattern, 0, 6); + } + + private void validateField(String field, int min, int max) throws PatternSyntaxException { + if (field.equals("*")) { + return; + } + + if (field.contains("/")) { + String[] parts = field.split("/"); + if (parts.length != 2) { + throw new PatternSyntaxException("Invalid step value format", field, -1); + } + validateField(parts[0], min, max); + try { + int step = Integer.parseInt(parts[1]); + if (step <= 0) { + throw new PatternSyntaxException("Step value must be positive", field, -1); + } + } catch (NumberFormatException e) { + throw new PatternSyntaxException("Invalid step value", field, -1); + } + return; + } + + if (field.contains(",")) { + for (String part : field.split(",")) { + validateField(part, min, max); + } + return; + } + + if (field.contains("-")) { + String[] parts = field.split("-"); + if (parts.length != 2) { + throw new PatternSyntaxException("Invalid range format", field, -1); + } + try { + int start = Integer.parseInt(parts[0]); + int end = Integer.parseInt(parts[1]); + if (start < min || end > max || start > end) { + throw new PatternSyntaxException("Invalid range values", field, -1); + } + } catch (NumberFormatException e) { + throw new PatternSyntaxException("Invalid range values", field, -1); + } + return; + } + + try { + int value = Integer.parseInt(field); + if (value < min || value > max) { + throw new PatternSyntaxException("Value out of range", field, -1); + } + } catch (NumberFormatException e) { + throw new PatternSyntaxException("Invalid value", field, -1); + } + } + + public String getPattern() { + return pattern; + } + + public boolean matches(LocalDateTime dateTime) { + return matchesField(minutePattern, dateTime.getMinute(), 0, 59) + && matchesField(hourPattern, dateTime.getHour(), 0, 23) + && matchesField(dayOfMonthPattern, dateTime.getDayOfMonth(), 1, 31) + && matchesField(monthPattern, dateTime.getMonthValue(), 1, 12) + && matchesField(dayOfWeekPattern, dateTime.getDayOfWeek().getValue() % 7, 0, 6); + } + + private boolean matchesField(String pattern, int value, int min, int max) { + if (pattern.equals("*")) { + return true; + } + + if (pattern.contains("/")) { + String[] parts = pattern.split("/"); + String range = parts[0]; + int step = Integer.parseInt(parts[1]); + + if (range.equals("*")) { + return (value - min) % step == 0; + } else { + return matchesField(range, value, min, max) && (value - min) % step == 0; + } + } + + if (pattern.contains(",")) { + for (String part : pattern.split(",")) { + if (matchesField(part, value, min, max)) { + return true; + } + } + return false; } - } - return "More than 24h"; - default: - return "Unknown"; - } + if (pattern.contains("-")) { + String[] parts = pattern.split("-"); + int start = Integer.parseInt(parts[0]); + int end = Integer.parseInt(parts[1]); + return value >= start && value <= end; + } + + return Integer.parseInt(pattern) == value; + } } - @Override - public String toString() { - StringBuilder sb = new StringBuilder("Schedule{name='").append(name).append("', type=").append(type); - - switch (type) { - case INTERVAL -> { - int minutes = intervalTicks / (20 * 60); - int remainingSeconds = (intervalTicks % (20 * 60)) / 20; - if (remainingSeconds > 0) { - sb.append(", interval=").append(minutes).append("m ").append(remainingSeconds).append("s"); - } else { - sb.append(", interval=").append(minutes).append("m"); - } - } - case DAILY -> sb.append(", time=").append(dailyTime); - case CRON -> sb.append(", pattern='").append(cronPattern.getPattern()).append("'"); - } - - sb.append(", commands=").append(commands.size()); - if (!delays.isEmpty()) { - sb.append(", delays=").append(delays); - } - - return sb.append("}").toString(); + /** + * Class representing a scheduled command + */ + public static class Schedule { + private final String name; + private final ScheduleType type; + private final int intervalTicks; // Now storing interval in ticks instead of minutes + private final LocalTime dailyTime; + private final CronPattern cronPattern; + private final List commands; + private final Map delays; // Command index -> delay in ticks + private LocalDateTime lastRun; + + public enum ScheduleType { + INTERVAL, DAILY, CRON + } + + // Interval constructor - now accepts ticks instead of minutes + public Schedule(String name, int intervalTicks, List commands, Map delays) { + this.name = name; + this.type = ScheduleType.INTERVAL; + this.intervalTicks = intervalTicks; + this.dailyTime = null; + this.cronPattern = null; + this.commands = new ArrayList<>(commands); + this.delays = new HashMap<>(delays); + this.lastRun = null; + } + + // Daily constructor + public Schedule(String name, LocalTime time, List commands, Map delays) { + this.name = name; + this.type = ScheduleType.DAILY; + this.intervalTicks = 0; + this.dailyTime = time; + this.cronPattern = null; + this.commands = new ArrayList<>(commands); + this.delays = new HashMap<>(delays); + this.lastRun = null; + } + + // Cron constructor + public Schedule(String name, CronPattern pattern, List commands, Map delays) { + this.name = name; + this.type = ScheduleType.CRON; + this.intervalTicks = 0; + this.dailyTime = null; + this.cronPattern = pattern; + this.commands = new ArrayList<>(commands); + this.delays = new HashMap<>(delays); + this.lastRun = null; + } + + public String getName() { + return name; + } + + public ScheduleType getType() { + return type; + } + + /** + * Get the interval in minutes (converted from ticks for backward compatibility) + * + * @return The interval in minutes + */ + public int getIntervalMinutes() { + return intervalTicks / (20 * 60); // Convert ticks to minutes + } + + /** + * Get the interval in ticks + * + * @return The interval in ticks + */ + public int getIntervalTicks() { + return intervalTicks; + } + + public LocalTime getDailyTime() { + return dailyTime; + } + + public CronPattern getCronPattern() { + return cronPattern; + } + + public List getCommands() { + return Collections.unmodifiableList(commands); + } + + public Map getDelays() { + return Collections.unmodifiableMap(delays); + } + + public LocalDateTime getLastRun() { + return lastRun; + } + + public void setLastRun(LocalDateTime lastRun) { + this.lastRun = lastRun; + } + + public void addCommand(String command) { + this.commands.add(command); + } + + public boolean removeCommand(int index) { + if (index < 0 || index >= commands.size()) { + return false; + } + commands.remove(index); + + // Remove any delays for this command + delays.remove(index); + + // Adjust delays for higher indexed commands + Map newDelays = new HashMap<>(); + for (Map.Entry entry : delays.entrySet()) { + int delayIndex = entry.getKey(); + if (delayIndex > index) { + newDelays.put(delayIndex - 1, entry.getValue()); + } else { + newDelays.put(delayIndex, entry.getValue()); + } + } + delays.clear(); + delays.putAll(newDelays); + return true; + } + + public void addDelay(int commandIndex, int delayTicks) { + delays.put(commandIndex, delayTicks); + } + + public boolean removeDelay(int commandIndex) { + return delays.remove(commandIndex) != null; + } + + /** + * Check if this schedule should run + * + * @param now The current time + * @return True if it should run + */ + public boolean shouldRun(@NotNull LocalDateTime now) { + switch (type) { + case INTERVAL: + if (lastRun == null) { + return true; // Never run before + } + Duration duration = Duration.between(lastRun, now); + // Convert duration to ticks and compare with intervalTicks + long durationTicks = duration.toSeconds() * 20; + return durationTicks >= intervalTicks; + + case DAILY: + if (lastRun != null && lastRun.toLocalDate().equals(now.toLocalDate())) { + return false; // Already run today + } + LocalTime currentTime = now.toLocalTime(); + return currentTime.isAfter(dailyTime) || currentTime.equals(dailyTime); + + case CRON: + if (lastRun != null) { + LocalDateTime nextMinute = lastRun.plusMinutes(1).withSecond(0).withNano(0); + if (now.isBefore(nextMinute)) { + return false; // Don't run more than once per minute + } + } + assert cronPattern != null; + return cronPattern.matches(now); + + default: + return false; + } + } + + /** + * Get a user-friendly string representation of time until next run + * + * @return Time until next run as a string + */ + public String getTimeUntilNextRun() { + LocalDateTime now = LocalDateTime.now(); + + switch (type) { + case INTERVAL: + if (lastRun == null) { + return "Ready to run"; + } + + // Calculate next run time using ticks + long durationSeconds = intervalTicks / 20; + LocalDateTime nextRun = lastRun.plusSeconds(durationSeconds); + Duration duration = Duration.between(now, nextRun); + + if (duration.isNegative()) { + return "Ready to run"; + } + + long hours = duration.toHours(); + long minutes = duration.toMinutesPart(); + long seconds = duration.toSecondsPart(); + + if (hours > 0) { + return hours + "h " + minutes + "m " + seconds + "s"; + } else if (minutes > 0) { + return minutes + "m " + seconds + "s"; + } else { + return seconds + "s"; + } + + case DAILY: + assert dailyTime != null; + LocalDateTime nextRunTime = now.toLocalDate().atTime(dailyTime); + if (now.isAfter(nextRunTime)) { + nextRunTime = nextRunTime.plusDays(1); + } + + Duration timeUntil = Duration.between(now, nextRunTime); + long days = timeUntil.toDays(); + long dHours = timeUntil.toHoursPart(); + long dMinutes = timeUntil.toMinutesPart(); + + if (days > 0) { + return days + "d " + dHours + "h " + dMinutes + "m"; + } else if (dHours > 0) { + return dHours + "h " + dMinutes + "m"; + } else { + return dMinutes + "m"; + } + + case CRON: + // For cron, we check the next few hours in 1-minute increments to find the next + // match + LocalDateTime checkTime = now; + for (int i = 0; i < 24 * 60; i++) { // Check up to 24 hours ahead + checkTime = checkTime.plusMinutes(1); + assert cronPattern != null; + if (cronPattern.matches(checkTime)) { + Duration cronTimeUntil = Duration.between(now, checkTime); + long cronHours = cronTimeUntil.toHours(); + long cronMinutes = cronTimeUntil.toMinutesPart(); + + if (cronHours > 0) { + return cronHours + "h " + cronMinutes + "m"; + } else { + return cronMinutes + "m"; + } + } + } + return "More than 24h"; + + default: + return "Unknown"; + } + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("Schedule{name='").append(name).append("', type=").append(type); + + switch (type) { + case INTERVAL -> { + int minutes = intervalTicks / (20 * 60); + int remainingSeconds = (intervalTicks % (20 * 60)) / 20; + if (remainingSeconds > 0) { + sb.append(", interval=").append(minutes).append("m ").append(remainingSeconds).append("s"); + } else { + sb.append(", interval=").append(minutes).append("m"); + } + } + case DAILY -> sb.append(", time=").append(dailyTime); + case CRON -> { + assert cronPattern != null; + sb.append(", pattern='").append(cronPattern.getPattern()).append("'"); + } + } + + sb.append(", commands=").append(commands.size()); + if (!delays.isEmpty()) { + sb.append(", delays=").append(delays); + } + + return sb.append("}").toString(); + } } - } } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ConsoleLogger.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ConsoleLogger.java index 3a30ad4..117f2b4 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ConsoleLogger.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ConsoleLogger.java @@ -3,6 +3,8 @@ import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.appender.AbstractAppender; import org.jetbrains.annotations.NotNull; +import org.woftnw.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.data.type.ServerLog; public class ConsoleLogger extends AbstractAppender { @@ -25,7 +27,10 @@ public void append(@NotNull LogEvent event) { String message = builder.toString(); - // TODO: Send message. + // Send message to PocketBase + ServerLog logItem = new ServerLog(); + logItem.setLogMsg(message); + Dreamvisitor.getPlugin().getRepositoryManager().getServerLogsRepository().create(logItem); } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Flight.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Flight.java index 7c0f9d2..ee13c9e 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Flight.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Flight.java @@ -1,6 +1,9 @@ package org.woftnw.dreamvisitor.functions; +import org.bukkit.Input; +import org.bukkit.util.Vector; import org.woftnw.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.data.Config; import org.woftnw.dreamvisitor.data.PlayerMemory; import org.woftnw.dreamvisitor.data.PlayerUtility; import org.bukkit.Bukkit; @@ -11,26 +14,30 @@ import org.bukkit.boss.KeyedBossBar; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import org.woftnw.dreamvisitor.data.type.DVUser; +import org.woftnw.dreamvisitor.util.ConfigKey; import java.util.HashMap; import java.util.Map; +import java.util.Objects; public class Flight { - public static double energyCapacity = Dreamvisitor.getPlugin().getConfig().getInt("flightEnergyCapacity"); - public static double reactivationPoint = Dreamvisitor.getPlugin().getConfig().getInt("flightRegenerationPoint"); + public static double energyCapacity = Config.get(ConfigKey.FLIGHT_ENERGY_CAPACITY); + public static double reactivationPoint = Config.get(ConfigKey.FLIGHT_REGENERATION_POINT); public static final Map energy = new HashMap<>(); private static final Map energyDepletion = new HashMap<>(); private static final Map flightRestricted = new HashMap<>(); + private static final Map lastPosition = new HashMap<>(); public static void init() { Bukkit.getScheduler().runTaskTimer(Dreamvisitor.getPlugin(), () -> { for (Player player : Bukkit.getOnlinePlayers()) { - PlayerMemory memory = PlayerUtility.getPlayerMemory(player.getUniqueId()); + DVUser user = PlayerUtility.getUser(player); // If player does not have the dreamvisitor.fly permission, disable flight if not in creative - if ((!player.hasPermission("dreamvisitor.fly") || isFlightRestricted(player) && !inFlightGameMode(player)) || (memory.flightDisabled && !inFlightGameMode(player))) { + if ((!player.hasPermission("dreamvisitor.fly") || isFlightRestricted(player) && !inFlightGameMode(player)) || (user.isFlightDisabled() && !inFlightGameMode(player))) { player.setAllowFlight(false); } else setupFlight(player); @@ -130,7 +137,7 @@ public static void setFlightRestricted(@NotNull Player player, boolean restricte public static void setupFlight(@NotNull Player player) { // Re-enable flight if it gets disabled by game mode change // Dreamvisitor.debug("FlightNotAllowed: " + !player.getAllowFlight() + " Permission: " + player.hasPermission("dreamvisitor.fly") + " NotRestricted: " + !isFlightRestricted(player) + " NotDepleted: " + !isPlayerDepleted(player) + " NotDisabled: " + !PlayerUtility.getPlayerMemory(player.getUniqueId()).flightDisabled); - if (!player.getAllowFlight() && player.hasPermission("dreamvisitor.fly") && !isFlightRestricted(player) && !isPlayerDepleted(player) && !PlayerUtility.getPlayerMemory(player.getUniqueId()).flightDisabled) { + if (!player.getAllowFlight() && player.hasPermission("dreamvisitor.fly") && !isFlightRestricted(player) && !isPlayerDepleted(player) && !PlayerUtility.getUser(player).isFlightDisabled()) { Messager.debug("All requirements met for flight."); Bukkit.getScheduler().runTaskLater(Dreamvisitor.getPlugin(), () -> player.setAllowFlight(true), 1); } @@ -138,10 +145,59 @@ public static void setupFlight(@NotNull Player player) { /** * Whether a player is in a flight-enabled game mode like Creative or Spectator. - * @param player - * @return */ public static boolean inFlightGameMode(@NotNull Player player) { return (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR); } + + public static void tick() { + + for (final Player player : Bukkit.getOnlinePlayers()) { + final Input input = player.getCurrentInput(); + + if (player.isFlying() && !inFlightGameMode(player)) { + // Remove energy if flying + try { + Double energy = Flight.energy.get(player); + Vector lastLoc = lastPosition.get(player); + Vector currentLoc = player.getLocation().toVector(); + + // Check planar movement + double movement2d = 0; + // If pressing movement key, remove 1 + if (input.isBackward() || input.isForward() || input.isLeft() || input.isRight()) movement2d = 1; + // If sprinting, multiply that by 2 + if (player.isSprinting()) movement2d *= 2; + // If not actually moving, don't remove energy + if (lastLoc != null && Objects.equals(currentLoc.getX(), lastLoc.getX()) && Objects.equals(currentLoc.getZ(), lastLoc.getZ())) movement2d = 0; + + // Check vertical movement + double movementY = 0; + // If pressing jump, remove 1 + if (input.isJump()) movementY = 1; + // If not actually moving up, don't remove energy + if (lastLoc != null && Objects.equals(currentLoc.getY(), lastLoc.getY())) movementY = 0; + + // Get multiplication factors from config + final double flightEnergyDepletionXYMultiplier = Config.get(ConfigKey.FLIGHT_ENERGY_DEPLETION_X_Z_MULTIPLIER); + final double flightEnergyDepletionYMultiplier = Config.get(ConfigKey.FLIGHT_ENERGY_DEPLETION_Y_MULTIPLIER); + // Calculate the total energy to remove + final double energyToRemove = movement2d * flightEnergyDepletionXYMultiplier + movementY * flightEnergyDepletionYMultiplier; + + // Calculate what the player's energy should be + energy -= energyToRemove; + + // Ensure energy is not below zero + if (energy < 0) energy = 0.0; + // Save new energy state to player + Flight.energy.put(player, energy); + Flight.lastPosition.put(player, currentLoc); + } catch (NullPointerException e) { + // If the energy for the player doesn't exist for some reason, set it to full + energy.put(player, energyCapacity); + } + } + } + + } } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/InvSwap.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/InvSwap.java index d997632..a7a789f 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/InvSwap.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/InvSwap.java @@ -1,34 +1,34 @@ package org.woftnw.dreamvisitor.functions; -import org.woftnw.dreamvisitor.data.PlayerMemory; import org.woftnw.dreamvisitor.data.PlayerUtility; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; +import org.woftnw.dreamvisitor.data.type.DVUser; public class InvSwap { public static void swapInventories(@NotNull Player player) { - PlayerMemory memory = PlayerUtility.getPlayerMemory(player.getUniqueId()); + DVUser user = PlayerUtility.getUser(player); ItemStack[] invContents; - if (memory.creative) { - memory.creativeInv = player.getInventory().getContents(); - if (memory.survivalInv == null) invContents = null; - else invContents = memory.survivalInv; + if (user.isUsingCreativeInv()) { + user.setCreativeInv(player.getInventory().getContents()); + if (user.getSurvivalInv() == null) invContents = null; + else invContents = user.getSurvivalInv(); } else { - memory.survivalInv = player.getInventory().getContents(); - if (memory.creativeInv == null) invContents = null; - else invContents = memory.creativeInv; + user.setSurvivalInv(player.getInventory().getContents()); + if (user.getCreativeInv() == null) invContents = null; + else invContents = user.getCreativeInv(); } if (invContents == null) player.getInventory().clear(); else player.getInventory().setContents(invContents); - memory.creative = !memory.creative; + user.setUsingCreativeInv(!user.isUsingCreativeInv()); - PlayerUtility.setPlayerMemory(player.getUniqueId(), memory); + PlayerUtility.saveUser(user); } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Sandbox.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Sandbox.java index d475ecb..26491cd 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Sandbox.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Sandbox.java @@ -1,6 +1,5 @@ package org.woftnw.dreamvisitor.functions; -import org.woftnw.dreamvisitor.data.PlayerMemory; import org.woftnw.dreamvisitor.data.PlayerUtility; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.ComponentBuilder; @@ -20,12 +19,13 @@ import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.meta.SpawnEggMeta; import org.jetbrains.annotations.NotNull; +import org.woftnw.dreamvisitor.data.type.DVUser; import java.util.Objects; public class Sandbox implements Listener { - private static final String[] disallowedCommands = {"tpaccept", "tpa", "hub", "etpa", "etpaccept", "home", "ehome"}; + public static final String[] DISALLOWED_COMMANDS = {"tpaccept", "tpa", "hub", "etpa", "etpaccept", "home", "ehome"}; /** * Enable sandbox mode for the given {@link Player}. If they are not already in sandbox mode, they will be put into creative mode and their inventory will be swapped. @@ -33,11 +33,11 @@ public class Sandbox implements Listener { * @param player the player to enable sandbox mode for. */ public static void enableSandbox(@NotNull Player player) { - PlayerMemory memory = PlayerUtility.getPlayerMemory(player.getUniqueId()); + DVUser user = PlayerUtility.getUser(player); - if (memory.sandbox) return; + if (user.isInSandboxMode()) return; - memory.sandbox = true; + user.setInSandboxMode(true); InvSwap.swapInventories(player); player.setGameMode(GameMode.CREATIVE); player.setGlowing(true); @@ -62,11 +62,11 @@ public static void enableSandbox(@NotNull Player player) { * @param player the player to disable sandbox mode for. */ public static void disableSandbox(@NotNull Player player) { - PlayerMemory memory = PlayerUtility.getPlayerMemory(player.getUniqueId()); + DVUser user = PlayerUtility.getUser(player); - if (!memory.sandbox) return; + if (!user.isInSandboxMode()) return; - memory.sandbox = false; + user.setInSandboxMode(false); InvSwap.swapInventories(player); player.setGameMode(GameMode.SURVIVAL); player.setGlowing(false); @@ -74,62 +74,5 @@ public static void disableSandbox(@NotNull Player player) { player.sendMessage(ChatColor.BOLD + "You are no longer in sandbox mode."); } - @EventHandler - public void onPlayerDropItem(@NotNull PlayerDropItemEvent event) { - Player player = event.getPlayer(); - PlayerMemory memory = PlayerUtility.getPlayerMemory(player.getUniqueId()); - if (memory.sandbox) event.setCancelled(true); - } - - @EventHandler - public void onPlayerInteract(@NotNull PlayerInteractEvent event) { - Player player = event.getPlayer(); - PlayerMemory memory = PlayerUtility.getPlayerMemory(player.getUniqueId()); - if (!memory.sandbox) return; - if (event.getAction().equals(Action.RIGHT_CLICK_BLOCK)) { - assert event.getClickedBlock() != null; - if ((event.getClickedBlock().getState() instanceof Container && !player.isSneaking()) - || (event.getClickedBlock().getState() instanceof DecoratedPot) - || (event.getClickedBlock().getState() instanceof EnderChest) - || (event.getItem() != null && event.getItem().getItemMeta() instanceof SpawnEggMeta)) - event.setCancelled(true); - } - } - - @EventHandler - public void onPlayerInteractEntity (@NotNull PlayerInteractEntityEvent event) { - Player player = event.getPlayer(); - PlayerMemory memory = PlayerUtility.getPlayerMemory(player.getUniqueId()); - if (!memory.sandbox) return; - if (event.getRightClicked() instanceof ItemFrame) { - for (Player onlinePlayer : Bukkit.getServer().getOnlinePlayers()) { - if (onlinePlayer.hasPermission("dreamvisitor.sandbox")) { - Messager.send(onlinePlayer, event.getPlayer().getName() + " interacted with an item frame with held item " + Objects.requireNonNull(player.getInventory().getItem(event.getHand())).getType()); - } - } - } - } - - @EventHandler - public void onPlayerCommandPreprocess(@NotNull PlayerCommandPreprocessEvent event) { - - Player player = event.getPlayer(); - PlayerMemory memory = PlayerUtility.getPlayerMemory(player.getUniqueId()); - if (memory.sandbox) { - for (String disallowedCommand : disallowedCommands) { - if (event.getMessage().contains(disallowedCommand)) event.setCancelled(true); - } - } else { - for (String disallowedCommand : disallowedCommands) { - if (event.getMessage().contains(disallowedCommand)) - for (Player onlinePlayer : Bukkit.getOnlinePlayers()) - if (PlayerUtility.getPlayerMemory(onlinePlayer.getUniqueId()).sandbox && event.getMessage().contains(onlinePlayer.getName())) { - event.getPlayer().sendMessage(ChatColor.RED + "That player is currently in Sandbox Mode."); - event.setCancelled(true); - } - - } - } - } } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenCreatureSpawn.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenCreatureSpawn.java index 0f117c6..811b376 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenCreatureSpawn.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenCreatureSpawn.java @@ -24,6 +24,7 @@ public class ListenCreatureSpawn implements Listener { @EventHandler public void onCreatureSpawn(@NotNull CreatureSpawnEvent event) { + // Stop Withers if in region with wither flag denied if (event.getSpawnReason() == CreatureSpawnEvent.SpawnReason.BUILD_WITHER) { org.bukkit.Location bukkitLocation = event.getLocation(); Location location = BukkitAdapter.adapt(bukkitLocation); diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenEntityDamage.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenEntityDamage.java deleted file mode 100644 index 73975a2..0000000 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenEntityDamage.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.woftnw.dreamvisitor.listeners; - -import org.woftnw.dreamvisitor.data.Config; -import org.bukkit.entity.EntityType; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDamageByEntityEvent; - -import org.woftnw.dreamvisitor.Dreamvisitor; -import org.jetbrains.annotations.NotNull; - -public class ListenEntityDamage implements Listener { - - final Dreamvisitor plugin = Dreamvisitor.getPlugin(); - - @EventHandler - public void onEntityDamageEvent(@NotNull EntityDamageByEntityEvent event) { - - // If PvP is disabled and the damage type is player, cancel the event - if ((event.getDamager().getType() == EntityType.PLAYER && event.getEntity().getType() == EntityType.PLAYER) && Config.getBoolean("disable_pvp", false)) { - event.setCancelled(true); - } - } - -} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenEntityToggleGlideEvent.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenEntityToggleGlide.java similarity index 77% rename from dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenEntityToggleGlideEvent.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenEntityToggleGlide.java index ddc2236..d714593 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenEntityToggleGlideEvent.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenEntityToggleGlide.java @@ -5,11 +5,11 @@ import org.bukkit.event.entity.EntityToggleGlideEvent; import org.jetbrains.annotations.NotNull; -public class ListenEntityToggleGlideEvent implements Listener { +public class ListenEntityToggleGlide implements Listener { @EventHandler public void onEntityToggleGlide(@NotNull EntityToggleGlideEvent event) { - + // This has something to do with flight, but I don't remember if (!event.isGliding() && !event.getEntity().isOnGround()) { event.setCancelled(true); } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerChangedWorld.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerChangedWorld.java index d4eeddc..53a15e7 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerChangedWorld.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerChangedWorld.java @@ -10,6 +10,7 @@ public class ListenPlayerChangedWorld implements Listener { @EventHandler public void onPlayerChangedWorld(@NotNull PlayerChangedWorldEvent event) { + // Setup flight when a player moves to a new world Flight.setupFlight(event.getPlayer()); } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerChat.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerChat.java index 186e07f..c0fe83e 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerChat.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerChat.java @@ -5,11 +5,14 @@ import java.util.List; import java.util.regex.Pattern; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import org.bukkit.entity.Player; import org.woftnw.dreamvisitor.data.BadWords; import org.woftnw.dreamvisitor.data.PlayerMemory; import org.woftnw.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.data.type.DVUser; import org.woftnw.dreamvisitor.functions.Chatback; -import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; import net.md_5.bungee.api.chat.ComponentBuilder; import net.md_5.bungee.api.chat.HoverEvent; import net.md_5.bungee.api.chat.TextComponent; @@ -25,6 +28,7 @@ import org.woftnw.dreamvisitor.Dreamvisitor; import org.jetbrains.annotations.NotNull; +import org.woftnw.dreamvisitor.functions.Messager; public class ListenPlayerChat implements Listener { @@ -34,26 +38,52 @@ public class ListenPlayerChat implements Listener { @SuppressWarnings({"null"}) public void onPlayerChatEvent(@NotNull AsyncPlayerChatEvent event) { - if (event.getPlayer().hasPermission("dreamvisitor.set.autoradio")) { - PlayerMemory memory = PlayerUtility.getPlayerMemory(event.getPlayer().getUniqueId()); + String message = event.getMessage(); + Player player = event.getPlayer(); + + // If the player has autoradio on, send there and cancel event + if (player.hasPermission("dreamvisitor.set.autoradio")) { + DVUser user = PlayerUtility.getUser(player); - if (memory.autoRadio) { + if (user.isAutoRadioEnabled()) { event.setCancelled(true); - Bukkit.getScheduler().runTask(Dreamvisitor.getPlugin(), () -> Bukkit.dispatchCommand(event.getPlayer(), "radio " + event.getMessage())); + Bukkit.getScheduler().runTask(Dreamvisitor.getPlugin(), () -> Bukkit.dispatchCommand(player, "radio " + message)); return; } } - List badWords = BadWords.getBadWords(); + // Check for bad words - String message = event.getMessage(); + // Get the list of bad words + List badWords = BadWords.getBadWords(); + // For each... for (String badWord : badWords) { - Pattern pattern = Pattern.compile(".*\\b" + badWord + "\\b.*"); + // Create a pattern for the bad word with word boundaries + Pattern pattern = Pattern.compile(".*\\b" + badWord.toLowerCase() + "\\b.*"); + + // Check if the message matches the pattern + if (pattern.matcher(message.toLowerCase()).matches()) { + // Tell the player that they can't say that word + Messager.sendDanger(player, "You aren't allowed to say " + ChatColor.YELLOW + badWord); + + // Notify social spies + String report = "SocialSpy: " + player.getName() + " tried to say \"" + message + "\", but it was blocked because it contained the word " + badWord; + Essentials ess = (Essentials) Bukkit.getPluginManager().getPlugin("Essentials"); + if (ess != null) { + for (Player onlinePlayer : Bukkit.getOnlinePlayers()) { + User user = ess.getUser(onlinePlayer); + if (user.isSocialSpyEnabled()) { + + Messager.send(onlinePlayer, report); + } + } + } + // Log the message + Dreamvisitor.getPlugin().getLogger().info(report); - if (pattern.matcher(message).matches()) { - event.getPlayer().sendMessage(ChatColor.RED + "You can't say " + ChatColor.YELLOW + badWord + ChatColor.RED + "!"); + // Stop the message from being sent event.setCancelled(true); return; } @@ -66,37 +96,14 @@ public void onPlayerChatEvent(@NotNull AsyncPlayerChatEvent event) { operator, send message */ - + // Make sure the chat is not paused and the event is not cancelled. if (!Dreamvisitor.chatPaused || event.isCancelled()) { if (event.isCancelled()) return; - try { - if (Chatback.nextChatback.containsKey(event.getPlayer())) { - Chatback.ReplyMessage replyMessage = Chatback.nextChatback.get(event.getPlayer()); - - ComponentBuilder replyNotice = new ComponentBuilder(); - replyNotice.append("↱ Reply to ").color(ChatColor.GRAY); - TextComponent replyUser = new TextComponent(); - replyUser.setText(replyMessage.authorEffectiveName); - replyUser.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(replyMessage.authorUsername))); - replyNotice.append(replyUser); - - // TODO: Send message with reply -// Bot.getGameChatChannel().sendMessage(chatMessage).setMessageReference(replyMessage.messageId).failOnInvalidReply(false).queue(); - - Bukkit.spigot().broadcast(replyNotice.create()); - - Chatback.nextChatback.remove(event.getPlayer()); - } else { - // TODO: Send message -// Bot.getGameChatChannel().sendMessage(chatMessage).queue(); - } - - } catch (InsufficientPermissionException e) { - Bukkit.getLogger().warning("Dreamvisitor does not have sufficient permissions to send messages in game chat channel: " + e.getMessage()); - } + sendMessage(player, message); } else { + // The chat is paused. // Load pauseBypass file File file = new File(plugin.getDataFolder().getAbsolutePath() + "/pauseBypass.yml"); @@ -113,40 +120,40 @@ public void onPlayerChatEvent(@NotNull AsyncPlayerChatEvent event) { bypassedPlayers = (fileConfig.getStringList("players")); // If player is on soft whitelist or is op, allow. - if (bypassedPlayers.contains(event.getPlayer().getUniqueId().toString()) - || event.getPlayer().hasPermission("dreamvisitor.nopause")) { - - try { - if (Chatback.nextChatback.containsKey(event.getPlayer())) { - Chatback.ReplyMessage replyMessage = Chatback.nextChatback.get(event.getPlayer()); + if (bypassedPlayers.contains(player.getUniqueId().toString()) + || player.hasPermission("dreamvisitor.nopause")) { - ComponentBuilder replyNotice = new ComponentBuilder(); - replyNotice.append("↱ Reply to ").color(ChatColor.GRAY); - TextComponent replyUser = new TextComponent(replyMessage.authorEffectiveName); - replyUser.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(replyMessage.authorUsername))); - replyNotice.append(replyUser); - - Bukkit.spigot().broadcast(replyNotice.create()); - // TODO: Send message as reply -// Bot.getGameChatChannel().sendMessage(chatMessage).setMessageReference(replyMessage.messageId).failOnInvalidReply(false).queue(); - - Chatback.nextChatback.remove(event.getPlayer()); - } else { - // TODO: Send message -// Bot.getGameChatChannel().sendMessage(chatMessage).queue(); - } - } catch (InsufficientPermissionException e) { - Bukkit.getLogger().warning("Dreamvisitor does not have sufficient permissions to send messages in game chat channel: " + e.getMessage()); - } + sendMessage(player, message); } else { event.setCancelled(true); - event.getPlayer().sendMessage(ChatColor.RED + "Chat is currently paused."); + player.sendMessage(ChatColor.RED + "Chat is currently paused."); - Dreamvisitor.getPlugin().getLogger().info("Message from " + event.getPlayer().getName() + " was blocked: " + event.getMessage()); + Dreamvisitor.getPlugin().getLogger().info("Message from " + player.getName() + " was blocked: " + message); } } } + private static void sendMessage(Player player, String message) { + if (Chatback.nextChatback.containsKey(player)) { + Chatback.ReplyMessage replyMessage = Chatback.nextChatback.get(player); + + ComponentBuilder replyNotice = new ComponentBuilder(); + replyNotice.append("↱ Reply to ").color(ChatColor.GRAY); + TextComponent replyUser = new TextComponent(replyMessage.authorEffectiveName); + replyUser.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(replyMessage.authorUsername))); + replyNotice.append(replyUser); + + Bukkit.spigot().broadcast(replyNotice.create()); + // TODO: Send message as reply +// Bot.getGameChatChannel().sendMessage(chatMessage).setMessageReference(replyMessage.messageId).failOnInvalidReply(false).queue(); + + Chatback.nextChatback.remove(player); + } else { + // TODO: Send message +// Bot.getGameChatChannel().sendMessage(chatMessage).queue(); + } + } + } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerCmdPreprocess.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerCmdPreprocess.java index abdef2b..6765da1 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerCmdPreprocess.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerCmdPreprocess.java @@ -5,6 +5,7 @@ import java.util.List; import org.woftnw.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.data.type.DVUser; import org.woftnw.dreamvisitor.functions.Mail; import org.woftnw.dreamvisitor.functions.Messager; import org.bukkit.Bukkit; @@ -19,11 +20,11 @@ import org.woftnw.dreamvisitor.Dreamvisitor; import net.md_5.bungee.api.ChatColor; import org.jetbrains.annotations.NotNull; +import org.woftnw.dreamvisitor.functions.Sandbox; public class ListenPlayerCmdPreprocess implements Listener { final Dreamvisitor plugin = Dreamvisitor.getPlugin(); - final String[] msgAliases = {"/msg ","/tell ","/whisper ","/reply ","/t ","/w ","/r ", "/mail send "}; final String[] tpAliases = { "/call","/ecall","/tpa","/etpa","/tpask","/etpask", "/tpaccept","/etpaccept","/tpyes","/etpyes", @@ -33,19 +34,37 @@ public class ListenPlayerCmdPreprocess implements Listener { @EventHandler public void onPlayerCommandPreprocess(@NotNull PlayerCommandPreprocessEvent event) { - String cmd = event.getMessage(); - Player player = event.getPlayer(); + final String cmd = event.getMessage(); + final Player player = event.getPlayer(); // Don't allow /tw facts reset because it is very destructive. if ( cmd.stripTrailing().equalsIgnoreCase("/tw facts reset") || cmd.stripTrailing().equalsIgnoreCase("/typewriter facts reset") ) { - player.sendMessage(ChatColor.RED + "Dreamvisitor stopped you from running that command because it's too destructive <3"); + Messager.sendDanger(player, "I stopped you from running that command because it's too dangerous <3"); event.setCancelled(true); return; } + // Don't allow TP for sandbox players + DVUser user = PlayerUtility.getUser(player); + if (user.isInSandboxMode()) { + for (String disallowedCommand : Sandbox.DISALLOWED_COMMANDS) { + if (event.getMessage().contains(disallowedCommand)) event.setCancelled(true); + } + } else { + for (String disallowedCommand : Sandbox.DISALLOWED_COMMANDS) { + if (event.getMessage().contains(disallowedCommand)) + for (Player onlinePlayer : Bukkit.getOnlinePlayers()) + if (PlayerUtility.getUser(onlinePlayer).isInSandboxMode() && event.getMessage().contains(onlinePlayer.getName())) { + event.getPlayer().sendMessage(ChatColor.RED + "That player is currently in Sandbox Mode."); + event.setCancelled(true); + } + + } + } + // '/me' and '/rp' pass through if ((cmd.startsWith("/me " ) || cmd.startsWith("/rp" )) && !event.isCancelled()) { @@ -107,19 +126,6 @@ public void onPlayerCommandPreprocess(@NotNull PlayerCommandPreprocessEvent even // } // Bot.sendLog(message); } - } else { - // Cancel if command is a teleportation command to a sandboxed player. - for (String tpAlias : tpAliases) { - if (cmd.startsWith(tpAlias)) { - if (Mail.isPLayerDeliverer(player)) Mail.cancel(player); - for (Player sandboxer : Bukkit.getOnlinePlayers()) { - if (PlayerUtility.getPlayerMemory(sandboxer.getUniqueId()).sandbox && cmd.contains(sandboxer.getName())) { - Messager.send(player, "That player is currently in Sandbox Mode. Teleportation is not allowed."); - event.setCancelled(true); - } - } - } - } } } } \ No newline at end of file diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerDropItem.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerDropItem.java new file mode 100644 index 0000000..ba40610 --- /dev/null +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerDropItem.java @@ -0,0 +1,20 @@ +package org.woftnw.dreamvisitor.listeners; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.jetbrains.annotations.NotNull; +import org.woftnw.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.data.type.DVUser; + +public class ListenPlayerDropItem implements Listener { + + @EventHandler + public void onPlayerDropItem(@NotNull PlayerDropItemEvent event) { + Player player = event.getPlayer(); + DVUser user = PlayerUtility.getUser(player); + if (user.isInSandboxMode()) event.setCancelled(true); + } + +} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerGameModeChange.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerGameModeChange.java index 3cb5d8c..c67a6ec 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerGameModeChange.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerGameModeChange.java @@ -1,7 +1,7 @@ package org.woftnw.dreamvisitor.listeners; -import org.woftnw.dreamvisitor.data.PlayerMemory; import org.woftnw.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.data.type.DVUser; import org.woftnw.dreamvisitor.functions.Flight; import org.bukkit.Bukkit; import org.bukkit.GameMode; @@ -16,12 +16,14 @@ public class ListenPlayerGameModeChange implements Listener { @EventHandler public void onPlayerGameModeChangeEvent(@NotNull PlayerGameModeChangeEvent event) { - Player player = event.getPlayer(); - PlayerMemory memory = PlayerUtility.getPlayerMemory(player.getUniqueId()); + final Player player = event.getPlayer(); + final DVUser user = PlayerUtility.getUser(player); + // Setup flight on game mode change Flight.setupFlight(player); - if (memory.autoinvswap && ((player.getGameMode().equals(GameMode.SURVIVAL) && event.getNewGameMode().equals(GameMode.CREATIVE)) || (player.getGameMode().equals(GameMode.CREATIVE) && event.getNewGameMode().equals(GameMode.SURVIVAL)))) Bukkit.dispatchCommand(player, "invswap"); + // If auto inventory swap is on and player changes from survival to creative or vise versa, swap inventory + if (user.isAutoInvSwapEnabled() && ((player.getGameMode().equals(GameMode.SURVIVAL) && event.getNewGameMode().equals(GameMode.CREATIVE)) || (player.getGameMode().equals(GameMode.CREATIVE) && event.getNewGameMode().equals(GameMode.SURVIVAL)))) Bukkit.dispatchCommand(player, "invswap"); } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerInteract.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerInteract.java new file mode 100644 index 0000000..47d6403 --- /dev/null +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerInteract.java @@ -0,0 +1,34 @@ +package org.woftnw.dreamvisitor.listeners; + +import org.bukkit.block.Container; +import org.bukkit.block.DecoratedPot; +import org.bukkit.block.EnderChest; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.meta.SpawnEggMeta; +import org.jetbrains.annotations.NotNull; +import org.woftnw.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.data.type.DVUser; + +public class ListenPlayerInteract implements Listener { + + @EventHandler + public void onPlayerInteract(@NotNull PlayerInteractEvent event) { + Player player = event.getPlayer(); + DVUser user = PlayerUtility.getUser(player); + if (!user.isInSandboxMode()) return; + if (event.getAction().equals(Action.RIGHT_CLICK_BLOCK)) { + assert event.getClickedBlock() != null; + if ((event.getClickedBlock().getState() instanceof Container && !player.isSneaking()) + || (event.getClickedBlock().getState() instanceof DecoratedPot) + || (event.getClickedBlock().getState() instanceof EnderChest) + || (event.getItem() != null && event.getItem().getItemMeta() instanceof SpawnEggMeta)) + event.setCancelled(true); + } + } + + +} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerInteractEntity.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerInteractEntity.java new file mode 100644 index 0000000..68903e8 --- /dev/null +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerInteractEntity.java @@ -0,0 +1,32 @@ +package org.woftnw.dreamvisitor.listeners; + +import org.bukkit.Bukkit; +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.jetbrains.annotations.NotNull; +import org.woftnw.dreamvisitor.data.PlayerUtility; +import org.woftnw.dreamvisitor.data.type.DVUser; +import org.woftnw.dreamvisitor.functions.Messager; + +import java.util.Objects; + +public class ListenPlayerInteractEntity implements Listener { + + @EventHandler + public void onPlayerInteractEntity(@NotNull PlayerInteractEntityEvent event) { + Player player = event.getPlayer(); + DVUser user = PlayerUtility.getUser(player); + if (!user.isInSandboxMode()) return; + if (event.getRightClicked() instanceof ItemFrame) { + for (Player onlinePlayer : Bukkit.getServer().getOnlinePlayers()) { + if (onlinePlayer.hasPermission("dreamvisitor.sandbox")) { + Messager.send(onlinePlayer, event.getPlayer().getName() + " interacted with an item frame with held item " + Objects.requireNonNull(player.getInventory().getItem(event.getHand())).getType()); + } + } + } + } + +} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerJoin.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerJoin.java index 3113056..8112742 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerJoin.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerJoin.java @@ -5,6 +5,8 @@ import org.woftnw.dreamvisitor.data.PlayerTribe; import org.woftnw.dreamvisitor.data.PlayerUtility; import org.woftnw.dreamvisitor.data.Tribe; +import org.woftnw.dreamvisitor.data.type.DVUser; +import org.woftnw.dreamvisitor.functions.Flight; import org.woftnw.dreamvisitor.functions.Messager; import org.woftnw.dreamvisitor.functions.Sandbox; import net.luckperms.api.model.user.User; @@ -39,14 +41,14 @@ public void onPlayerJoinEvent(@NotNull PlayerJoinEvent event) { tribeColor = ChatColor.WHITE; } + // Get the prefix from LuckPerms data String prefix = lpUser.getCachedData().getMetaData().getPrefix(); + // Set the player list name with the prefix if (prefix != null) player.setPlayerListName(prefix.replace('&', '§') + tribeColor + player.getName()); } // Enable flight - if (player.hasPermission("dreamvisitor.fly")) { - player.setAllowFlight(true); - } + Flight.setupFlight(player); // TODO: Send join messages // String chatMessage = "**" + Bot.escapeMarkdownFormatting(ChatColor.stripColor(player.getName())) + " joined the game**"; @@ -57,9 +59,10 @@ public void onPlayerJoinEvent(@NotNull PlayerJoinEvent event) { // } // Bot.sendLog(chatMessage); - PlayerMemory memory = PlayerUtility.getPlayerMemory(player.getUniqueId()); + DVUser user = PlayerUtility.getUser(player); - if (memory.sandbox) { + // If the player is in sandbox mode, handle accordingly + if (user.isInSandboxMode()) { boolean sandboxerOnline = false; for (Player onlinePlayer : Bukkit.getServer().getOnlinePlayers()) { if (onlinePlayer.hasPermission("dreamvisitor.sandbox")) { diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerLogin.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerLogin.java index 05777f5..767dbd2 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerLogin.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerLogin.java @@ -18,6 +18,7 @@ import org.woftnw.dreamvisitor.Dreamvisitor; import org.jetbrains.annotations.NotNull; +import org.woftnw.dreamvisitor.util.ConfigKey; public class ListenPlayerLogin implements Listener { @@ -31,11 +32,6 @@ public void onPlayerLoginEvent(@NotNull PlayerLoginEvent event) { if (player.hasPermission("dreamvisitor.nowhitelist")) { // Always allow ops - - // Remind bot login failure to ops - if (Dreamvisitor.botFailed && player.isOp()) { - Messager.sendDanger(player,"Bot login failed on server start! You may need a new login token."); - } event.allow(); } else if (event.getResult() == PlayerLoginEvent.Result.KICK_BANNED) { @@ -57,7 +53,7 @@ public void onPlayerLoginEvent(@NotNull PlayerLoginEvent event) { // Kick for server full event.disallow(Result.KICK_FULL, "The server is full. The current player limit is " + Dreamvisitor.playerLimit); - } else if (Config.getBoolean("softwhitelist", false)) { + } else if (Config.get(ConfigKey.SOFT_WHITELIST)) { // Soft whitelist is enabled allowIfSoftWhitelist(player, event); @@ -72,7 +68,7 @@ public void onPlayerLoginEvent(@NotNull PlayerLoginEvent event) { // Player limit is not overridden // If soft whitelist is on - if (Config.getBoolean("softwhitelist", false)) { + if (Config.get(ConfigKey.SOFT_WHITELIST)) { // Soft whitelist is enabled Bukkit.getLogger().info("Soft whitelist is enabled"); diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerMoveEvent.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerMoveEvent.java deleted file mode 100644 index 2045157..0000000 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerMoveEvent.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.woftnw.dreamvisitor.listeners; - -import org.woftnw.dreamvisitor.data.Config; -import org.woftnw.dreamvisitor.functions.Flight; -import org.bukkit.Location; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerMoveEvent; -import org.jetbrains.annotations.NotNull; - -import java.util.Objects; - -public class ListenPlayerMoveEvent implements Listener { - - @EventHandler - public void onPlayerMove(@NotNull PlayerMoveEvent event) { - - Player player = event.getPlayer(); - if (event.getTo() == null) return; - - if (player.isFlying() && !Flight.inFlightGameMode(player)) { - // Remove energy if flying - try { - Double energy = Flight.energy.get(player); - - // Return if worlds are different - if (!Objects.equals(event.getTo().getWorld(), event.getFrom().getWorld())) return; - - // Calculate energy to remove - double energyToRemove = getEnergyToRemove(event); - - energy -= energyToRemove; - - if (energy < 0) energy = 0.0; - Flight.energy.put(player, energy); - } catch (NullPointerException e) { - Flight.energy.put(player, Flight.energyCapacity); - } - } - } - - private static double getEnergyToRemove(@NotNull PlayerMoveEvent event) { - double energyToRemove; - Location from2d = event.getFrom().clone(); - from2d.setY(0); - Location to2d = Objects.requireNonNull(event.getTo()).clone(); - to2d.setY(0); - - double distance2d = from2d.distance(to2d); - distance2d = Math.abs(distance2d); - - double fromY = event.getFrom().getY(); - double toY = event.getTo().getY(); - - double distanceY = toY - fromY; - if (distanceY < 0) distanceY = 0; - - double flightEnergyDepletionXYMultiplier = Config.getDouble("flightEnergyDepletionXYMultiplier", 1.0); - double flightEnergyDepletionYMultiplier = Config.getDouble("flightEnergyDepletionYMultiplier", 2.00); - energyToRemove = distance2d * flightEnergyDepletionXYMultiplier + distanceY * flightEnergyDepletionYMultiplier; - return energyToRemove; - } - -} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerQuit.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerQuit.java index ebf2502..aa6a21a 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerQuit.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerQuit.java @@ -2,6 +2,7 @@ import org.woftnw.dreamvisitor.Dreamvisitor; import org.woftnw.dreamvisitor.data.PlayerMemory; +import org.woftnw.dreamvisitor.data.type.DVUser; import org.woftnw.dreamvisitor.functions.Messager; import org.woftnw.dreamvisitor.functions.Sandbox; import org.bukkit.Bukkit; @@ -28,9 +29,10 @@ public void onPlayerQuitEvent(@NotNull PlayerQuitEvent event) { // Bot.getGameChatChannel().sendMessage(chatMessage).queue(); // Bot.sendLog(chatMessage); - PlayerMemory memory = PlayerUtility.getPlayerMemory(event.getPlayer().getUniqueId()); + final DVUser user = PlayerUtility.getUser(player); - if (memory.sandbox) { + // Notify moderators if the quitting player is in Sandbox Mode + if (user.isInSandboxMode()) { for (Player onlinePlayer : Bukkit.getServer().getOnlinePlayers()) { if (onlinePlayer.hasPermission("dreamvisitor.sandbox")) { Messager.send(onlinePlayer, event.getPlayer().getName() + " left while in sandbox mode."); @@ -38,15 +40,12 @@ public void onPlayerQuitEvent(@NotNull PlayerQuitEvent event) { } } - try { - PlayerUtility.savePlayerMemory(player.getUniqueId()); - PlayerUtility.clearPlayerMemory(player.getUniqueId()); - } catch (IOException e) { - Bukkit.getLogger().severe("Unable to save player memory! Does the server have write access? Player memory will remain in memory. " + e.getMessage()); - } + // Save and clear player memory + PlayerUtility.saveUser(user); Messager.debug("Checking sandbox."); + // This player might be the last sandbox moderator, so check that Bukkit.getScheduler().runTask(Dreamvisitor.getPlugin(), () -> { Messager.debug("Task start."); @@ -65,7 +64,7 @@ public void onPlayerQuitEvent(@NotNull PlayerQuitEvent event) { Messager.debug("No mods online! Gotta disable sandboxed."); for (Player onlinePlayer : Bukkit.getOnlinePlayers()) { Messager.debug("Is " + onlinePlayer + " sandboxed?"); - if (PlayerUtility.getPlayerMemory(onlinePlayer.getUniqueId()).sandbox) { + if (PlayerUtility.getUser(onlinePlayer).isInSandboxMode()) { Messager.debug("Yes. Disabling."); Sandbox.disableSandbox(onlinePlayer); onlinePlayer.sendMessage("You are no longer in Sandbox Mode because there are no sandbox managers available."); diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerToggleFlightEvent.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerToggleFlight.java similarity index 67% rename from dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerToggleFlightEvent.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerToggleFlight.java index a98c7ec..234f041 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerToggleFlightEvent.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerToggleFlight.java @@ -13,38 +13,47 @@ import org.jetbrains.annotations.NotNull; import java.util.HashMap; +import java.util.Objects; -public class ListenPlayerToggleFlightEvent implements Listener { +public class ListenPlayerToggleFlight implements Listener { private static final HashMap wingFlapSoundTask = new HashMap<>(); @EventHandler public void onToggleFlight(@NotNull PlayerToggleFlightEvent event) { - Player player = event.getPlayer(); + final Player player = event.getPlayer(); if (player.getGameMode() != GameMode.CREATIVE && player.getGameMode() != GameMode.SPECTATOR) { + // If player is in survival or adventure if (event.isFlying()) { + // If the player is going into flight mode + // Set player states player.setGliding(false); player.setFlySpeed(0.05f); player.setFlying(true); + // Start flapping sounds wingFlapSoundTask.put(player, Bukkit.getScheduler().runTaskTimer(Dreamvisitor.getPlugin(), () -> { if (!player.isOnline() || !player.isFlying()) { - // remove this task + // If the player is offline or not flying, cancel future flap sounds. cancelWingFlapSoundTask(player); } else { - player.playSound(player.getLocation(), Sound.ENTITY_ENDER_DRAGON_FLAP, SoundCategory.PLAYERS, 0.5f, 1.2f); + // Otherwise, play it! + Objects.requireNonNull(player.getLocation().getWorld()).playSound(player.getLocation(), Sound.ENTITY_ENDER_DRAGON_FLAP, SoundCategory.PLAYERS, 0.4f, 1.2f); } }, 1, 15)); } else { + // If player is exiting flight, put into glide mode player.setFlying(false); player.setGliding(true); } } else { + // If player is in Creative or Spectator if (event.isFlying()) { + // Set speed accordingly player.setFlySpeed(0.1f); player.setFlying(true); } else { diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenServerPing.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenServerPing.java index 4406b05..00d49c3 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenServerPing.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenServerPing.java @@ -10,8 +10,10 @@ public class ListenServerPing implements Listener { @EventHandler public void onPing(@NotNull ServerListPingEvent event) { + // Show player limit override event.setMaxPlayers(Dreamvisitor.getPlugin().getServer().getMaxPlayers()); + // Show custom MOTD if (Dreamvisitor.MOTD != null) event.setMotd(Dreamvisitor.MOTD); } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenSignChangeEvent.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenSignChange.java similarity index 56% rename from dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenSignChangeEvent.java rename to dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenSignChange.java index 776f0b2..9b131eb 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenSignChangeEvent.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenSignChange.java @@ -9,20 +9,24 @@ import org.bukkit.event.Listener; import org.bukkit.event.block.SignChangeEvent; import org.jetbrains.annotations.NotNull; +import org.woftnw.dreamvisitor.Dreamvisitor; -public class ListenSignChangeEvent implements Listener { +public class ListenSignChange implements Listener { @EventHandler public void onSignChangeEvent(@NotNull SignChangeEvent event) { if (event.isCancelled()) return; - Essentials ess = (Essentials) Bukkit.getPluginManager().getPlugin("Essentials"); + + // Get essentials API + final Essentials ess = (Essentials) Bukkit.getPluginManager().getPlugin("Essentials"); if (ess == null) return; - Player editor = event.getPlayer(); + final Player editor = event.getPlayer(); if (editor.isOp()) return; - Block block = event.getBlock(); - String[] lines = event.getLines(); + final Block block = event.getBlock(); + final String[] lines = event.getLines(); + // If the sign is empty, ignore boolean empty = true; for (String line : lines) { if (!line.isBlank()) { @@ -32,14 +36,18 @@ public void onSignChangeEvent(@NotNull SignChangeEvent event) { } if (empty) return; - String message = ChatColor.GOLD + editor.getName() + " placed or edited a sign at " + block.getX() + ", " + block.getY() + ", " + block.getZ() + " in " + block.getWorld().getName() + ":\n" + ChatColor.RESET + // Create report message + final String message = ChatColor.GOLD + editor.getName() + " placed or edited a sign at " + block.getX() + ", " + block.getY() + ", " + block.getZ() + " in " + block.getWorld().getName() + ":\n" + ChatColor.RESET + lines[0] + "\n" + lines[1] + "\n" + lines[2] + "\n" + lines[3] + "\n"; + // Send to social spies for (Player player : Bukkit.getOnlinePlayers()) { if (ess.getUser(player).isSocialSpyEnabled()) player.sendMessage(message); } - Bukkit.getLogger().info(ChatColor.stripColor(message)); + + // Send to log + Dreamvisitor.getPlugin().getLogger().info(ChatColor.stripColor(message)); } } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigKey.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigKey.java index 3cbf380..fec630f 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigKey.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigKey.java @@ -11,7 +11,6 @@ public enum ConfigKey { AUTO_RESTART("auto_restart", false, Boolean.class), PAUSE_CHAT("pause_chat", false, Boolean.class), SOFT_WHITELIST("soft_whitelist", false, Boolean.class), - DISABLE_PVP("disable_pvp", false, Boolean.class), PLAYER_LIMIT("player_limit", -1, Integer.class), RESOURCE_PACK_REPO("resource_pack_repo", "WOFTNW/Dragonspeak", String.class), HUB_LOCATION("hub_location", null, Location.class), diff --git a/dreamvisitor/src/main/resources/plugin.yml b/dreamvisitor/src/main/resources/plugin.yml index 4a511ab..ae807c3 100644 --- a/dreamvisitor/src/main/resources/plugin.yml +++ b/dreamvisitor/src/main/resources/plugin.yml @@ -1,7 +1,7 @@ main: org.woftnw.dreamvisitor.Dreamvisitor name: Dreamvisitor version: "${project.version}" -api-version: 1.20 +api-version: 1.21 description: A plugin created by Bog for WOFTNW to add various features. authors: [ BogTheMudWing, From 9c76d7f3c2e0eb00c9730173ca5e5f0982b48991 Mon Sep 17 00:00:00 2001 From: Bog Date: Wed, 2 Jul 2025 10:08:38 -0700 Subject: [PATCH 17/39] Add console and command functionality and fix some user issues --- .../org/woftnw/dreamvisitor/Dreamvisitor.java | 58 ++++++-- .../org/woftnw/dreamvisitor/data/Config.java | 65 +++++---- .../PocketBaseServerCommandsRepository.java | 125 ++++++++++++++++++ .../PocketBaseServerLogsRepository.java | 21 +-- .../repository/PocketBaseUserRepository.java | 20 +++ .../data/repository/Repository.java | 18 ++- .../data/repository/RepositoryManager.java | 6 + .../repository/ServerCommandsRepository.java | 36 +++++ .../data/repository/ServerLogsRepository.java | 8 +- .../dreamvisitor/data/type/ServerCommand.java | 77 +++++++++++ .../dreamvisitor/functions/CommandRunner.java | 42 ++++++ .../dreamvisitor/functions/ConsoleLogger.java | 3 +- .../woftnw/dreamvisitor/util/ConfigKey.java | 6 +- 13 files changed, 411 insertions(+), 74 deletions(-) create mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseServerCommandsRepository.java create mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/ServerCommandsRepository.java create mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/ServerCommand.java create mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/CommandRunner.java diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java index df10f1f..81ad326 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java @@ -10,9 +10,12 @@ import dev.jorel.commandapi.CommandAPIBukkitConfig; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandTree; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.scheduler.BukkitTask; import org.woftnw.dreamvisitor.commands.*; import org.woftnw.dreamvisitor.data.*; import org.woftnw.dreamvisitor.data.repository.*; +import org.woftnw.dreamvisitor.data.type.ServerCommand; import org.woftnw.dreamvisitor.functions.*; import org.woftnw.dreamvisitor.functions.worldguard.DragonFlightFlag; import org.woftnw.dreamvisitor.functions.worldguard.WitherFlag; @@ -128,8 +131,29 @@ public void onEnable() { getLogger().info("Checking local config file..."); checkConfig(); + // Create PocketBase client from config + getLogger().info("Initializing PocketBase client..."); + String baseUrl = getConfig().getString("pocketbaseUrl", "http://127.0.0.1:8090/"); + String configId = getConfig().getString("pocketbaseConfigId", ""); + String token = getConfig().getString("pocketbaseToken", ""); + boolean useRealtime = getConfig().getBoolean("pocketbaseUseRealtime", true); + + if (baseUrl.isEmpty() || configId.isEmpty()) { + throw new NullPointerException("Missing PocketBase URL or Config ID"); + } + + Messager.debug("Initialized PocketBase client"); + Map pbConfig = new HashMap<>(); + pbConfig.put("pocketbaseUrl", baseUrl); + pbConfig.put("pocketbaseToken", token); + pocketBase = PocketBase.fromConfig(pbConfig); + getLogger().info("Initializing PocketBase config loader..."); - Config.init(); + try { + Config.init(pocketBase, baseUrl, configId, token, useRealtime); + } catch (IOException e) { + throw new RuntimeException(e); + } getLogger().info("Configuration fetched. Starting enable."); debugMode = Config.get(ConfigKey.DEBUG); @@ -248,21 +272,30 @@ public void onEnable() { Messager.debug("Setting up schedules..."); - Runnable pushConsole = new BukkitRunnable() { - @Override - public void run() { - if (Config.get(ConfigKey.LOG_CONSOLE)) { - + // Fail old commands still sent in PocketBase + List oldCommands = getRepositoryManager().getServerCommandsRepository().getByStatus(ServerCommand.Status.SENT); + for (ServerCommand command : oldCommands) { + command.setStatus(ServerCommand.Status.FAILED); + getRepositoryManager().getServerCommandsRepository().update(command); + } + final CommandRunner commandRunner = new CommandRunner(); - } + Runnable runCommandsAsync = new BukkitRunnable() { + @Override + public void run() { + commandRunner.run(); } }; Runnable scheduledRestarts = new BukkitRunnable() { @Override public void run() { - Config.loadConfig(); + try { + Config.loadConfig(); + } catch (IOException e) { + getLogger().warning("Unable to load configuration!"); + } if (AutoRestart.isAutoRestart() && Bukkit.getOnlinePlayers().isEmpty()) { AutoRestart.sendAutoRestartMessage(); @@ -310,12 +343,9 @@ public void run() { } }; - Runnable tickFlight = new Runnable() { - @Override - public void run() { - Flight.tick(); - } - }; + Runnable tickFlight = Flight::tick; + + Bukkit.getScheduler().runTaskTimerAsynchronously(this, runCommandsAsync, 20, 40); Bukkit.getScheduler().runTaskTimer(this, tick, 0, 0); diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/Config.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/Config.java index 3207893..00ea9f7 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/Config.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/Config.java @@ -26,24 +26,13 @@ public class Config { private static PocketBase pocketBaseClient; private static final String COLLECTION_NAME = "dreamvisitor_config"; - public static void init() { - FileConfiguration pluginConfig = Dreamvisitor.getPlugin().getConfig(); - baseUrl = pluginConfig.getString("pocketbaseUrl", "http://127.0.0.1:8090/"); - configId = pluginConfig.getString("pocketbaseConfigId", ""); - token = pluginConfig.getString("pocketbaseToken", ""); - useRealtime = pluginConfig.getBoolean("pocketbaseUseRealtime", true); - - if (baseUrl.isEmpty() || configId.isEmpty()) { - throw new NullPointerException("Missing PocketBase URL or Config ID"); - } - - // Create PocketBase client from config - Map pbConfig = new HashMap<>(); - pbConfig.put("pocketbaseUrl", baseUrl); - pbConfig.put("pocketbaseToken", token); - pocketBaseClient = PocketBase.fromConfig(pbConfig); + public static void init(PocketBase pocketBase, String baseUrl, String configId, String token, boolean useRealtime) throws IOException { - Messager.debug("Initialized PocketBase client"); + pocketBaseClient = pocketBase; + Config.baseUrl = baseUrl; + Config.configId = configId; + Config.token = token; + Config.useRealtime = useRealtime; // Initial config load loadConfig(); @@ -54,27 +43,24 @@ public static void init() { } } - public static void loadConfig() { - try { - if (pocketBaseClient == null) { - Dreamvisitor.getPlugin().getLogger().warning("PocketBase client not initialized, cannot load config"); - return; - } + public static void loadConfig() throws IOException { + if (pocketBaseClient == null) { + Dreamvisitor.getPlugin().getLogger().warning("PocketBase client not initialized, cannot load config"); + return; + } - // Get record using PocketBase client - JsonObject record = pocketBaseClient.getRecord(COLLECTION_NAME, configId, null, null); + // Get record using PocketBase client + Messager.debug("Getting record " + configId + " from collection " + COLLECTION_NAME); + JsonObject record = pocketBaseClient.getRecord(COLLECTION_NAME, configId, null, null); - // Convert from Gson JsonObject to org.json.JSONObject - String jsonString = record.toString(); - config = new JSONObject(jsonString); + // Convert from Gson JsonObject to org.json.JSONObject + String jsonString = record.toString(); + config = new JSONObject(jsonString); - Messager.debug("Loaded PocketBase configuration: " + config); + Messager.debug("Loaded PocketBase configuration: " + config); - // Apply config values to the system - applyConfig(); - } catch (IOException e) { - Bukkit.getLogger().warning("Error loading PocketBase config: " + e.getMessage()); - } + // Apply config values to the system + applyConfig(); } public static void updateLocalConfig(JSONObject newConfigData) { @@ -167,7 +153,16 @@ public static T get(@NotNull ConfigKey configKey) { value = configKey.getDefaultValue(); } - if (configKey.getType().isInstance(value)) { + Class expectedType = configKey.getType(); + + // Handle numeric coercion + if (expectedType == Double.class && value instanceof Number) { + return (T) Double.valueOf(((Number) value).doubleValue()); + } else if (expectedType == Integer.class && value instanceof Number) { + return (T) Integer.valueOf(((Number) value).intValue()); + } else if (expectedType == Float.class && value instanceof Number) { + return (T) Float.valueOf(((Number) value).floatValue()); + } else if (expectedType.isInstance(value)) { return (T) value; } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseServerCommandsRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseServerCommandsRepository.java new file mode 100644 index 0000000..6382d6d --- /dev/null +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseServerCommandsRepository.java @@ -0,0 +1,125 @@ +package org.woftnw.dreamvisitor.data.repository; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import org.jetbrains.annotations.NotNull; +import org.woftnw.dreamvisitor.data.type.ServerCommand; +import org.woftnw.dreamvisitor.pb.PocketBase; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * PocketBase implementation of the ServerCommandsRepository interface + */ +public class PocketBaseServerCommandsRepository implements ServerCommandsRepository { + private static final Logger LOGGER = Logger.getLogger(PocketBaseServerCommandsRepository.class.getName()); + private static final String COLLECTION_NAME = "server_commands"; + private final PocketBase pocketBase; + private final Gson gson; + + /** + * Constructor for PocketBaseServerBaseRepository + * + * @param pocketBase The PocketBase client to use + */ + public PocketBaseServerCommandsRepository(PocketBase pocketBase) { + this.pocketBase = pocketBase; + this.gson = new Gson(); + } + + /** + * Convert a JsonObject from PocketBase to an ServerCommand object + * + * @param json JsonObject from PocketBase API + * @return Mapped ServerCommand object + */ + @NotNull + private ServerCommand mapToServerCommand(JsonObject json) { + ServerCommand command = new ServerCommand(); + + command.setId(getStringOrNull(json, "id")); + command.setCollectionId(getStringOrNull(json, "collectionId")); + command.setCollectionName(getStringOrNull(json, "collectionName")); + + command.setCommand(getStringOrNull(json, "command")); + try { + command.setStatus(ServerCommand.Status.valueOf(getStringOrNull(json, "status"))); + } catch (IllegalArgumentException e) { + command.setStatus(null); + } + + command.setCreated(getOffsetDateTimeOrNull(json, "created")); + command.setUpdated(getOffsetDateTimeOrNull(json, "updated")); + + return command; + } + + /** + * Convert an ServerCommand object to a JsonObject for PocketBase + * + * @param command ServerCommand object to convert + * @return JsonObject for PocketBase API + */ + @NotNull + private JsonObject mapToJsonObject(@NotNull ServerCommand command) { + JsonObject json = new JsonObject(); + + // This is the only field for this type + if (command.getCommand() != null) + json.addProperty("command", command.getCommand()); + if (command.getStatus() != null) + json.addProperty("status", command.getStatus().toString().toLowerCase()); + + return json; + } + + @Override + public Optional findById(String id) { + try { + JsonObject record = pocketBase.getRecord(COLLECTION_NAME, id, null, null); + return Optional.of(mapToServerCommand(record)); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Error finding server command by ID: " + id, e); + return Optional.empty(); + } + } + + @Override + public List getByStatus(@NotNull ServerCommand.Status status) { + try { + String filter = "status = '" + status.toString().toLowerCase() + "'"; + List records = pocketBase.getFullList(COLLECTION_NAME, null, null, filter, null, null); + List commands = new ArrayList<>(); + for (JsonObject record : records) { + commands.add(mapToServerCommand(record)); + } + return commands; + } catch (IOException e) { + LOGGER.log(Level.FINE, "No commands found with status: " + status); + return new ArrayList<>(); + } + } + + @Override + public ServerCommand update(ServerCommand command) { + try { + JsonObject itemData = mapToJsonObject(command); + + if (command.getId() != null && !command.getId().isEmpty()) { + // Update existing log + JsonObject updatedRecord = pocketBase.updateRecord(COLLECTION_NAME, command.getId(), itemData, null, null); + return mapToServerCommand(updatedRecord); + } else { + throw new UnsupportedOperationException("Cannot create a new command."); + } + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Error saving log: ", e); + throw new RuntimeException("Failed to save log", e); + } + } +} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseServerLogsRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseServerLogsRepository.java index bbc2b40..36f7270 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseServerLogsRepository.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseServerLogsRepository.java @@ -3,20 +3,13 @@ import com.google.gson.Gson; import com.google.gson.JsonObject; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.woftnw.dreamvisitor.data.type.Item; import org.woftnw.dreamvisitor.data.type.ServerLog; import org.woftnw.dreamvisitor.pb.PocketBase; import java.io.IOException; -import java.time.OffsetDateTime; -import java.time.format.DateTimeFormatter; -import java.util.Collections; import java.util.List; -import java.util.Optional; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.stream.Collectors; /** * PocketBase implementation of the ServerRepository interface @@ -50,11 +43,11 @@ public ServerLog create(ServerLog log) { if (log.getId() != null && !log.getId().isEmpty()) { // Update existing log JsonObject updatedRecord = pocketBase.updateRecord(COLLECTION_NAME, log.getId(), itemData, null, null); - return mapToItem(updatedRecord); + return mapToServerLog(updatedRecord); } else { // Create new log JsonObject newRecord = pocketBase.createRecord(COLLECTION_NAME, itemData, null, null); - return mapToItem(newRecord); + return mapToServerLog(newRecord); } } catch (IOException e) { LOGGER.log(Level.SEVERE, "Error saving log: ", e); @@ -63,13 +56,13 @@ public ServerLog create(ServerLog log) { } /** - * Convert a JsonObject from PocketBase to an Item object + * Convert a JsonObject from PocketBase to an ServerLog object * * @param json JsonObject from PocketBase API - * @return Mapped Item object + * @return Mapped ServerLog object */ @NotNull - private ServerLog mapToItem(JsonObject json) { + private ServerLog mapToServerLog(JsonObject json) { ServerLog log = new ServerLog(); log.setId(getStringOrNull(json, "id")); @@ -85,9 +78,9 @@ private ServerLog mapToItem(JsonObject json) { } /** - * Convert an Item object to a JsonObject for PocketBase + * Convert an ServerLog object to a JsonObject for PocketBase * - * @param log Item object to convert + * @param log ServerLog object to convert * @return JsonObject for PocketBase API */ @NotNull diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserRepository.java index bcf6439..275ced3 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserRepository.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/PocketBaseUserRepository.java @@ -175,6 +175,12 @@ private DVUser mapToUser(JsonObject json) { // Parse boolean fields user.setIsSuspended(getBooleanOrNull(json, "is_suspended")); user.setIsBanned(getBooleanOrNull(json, "is_banned")); + user.setShowDiscordMessages(getBooleanOrNull(json, "show_discord_messages")); + user.setFlightDisabled(getBooleanOrNull(json, "flight_disabled")); + user.setVanished(getBooleanOrNull(json, "vanished")); + user.setAutoInvSwapEnabled(getBooleanOrNull(json, "auto_inv_swap_enabled")); + user.setAutoRadioEnabled(getBooleanOrNull(json, "auto_radio_enabled")); + user.setInSandboxMode(getBooleanOrNull(json, "in_sandbox_mode")); // Parse datetime fields user.setLastWork(getOffsetDateTimeOrNull(json, "last_work")); @@ -223,6 +229,20 @@ private JsonObject mapToJsonObject(@NotNull DVUser user) { json.addProperty("is_suspended", user.getIsSuspended()); if (user.getIsBanned() != null) json.addProperty("is_banned", user.getIsBanned()); + if (user.isShowDiscordOn() != null) + json.addProperty("show_discord_messages", user.isShowDiscordOn()); + if (user.isFlightDisabled() != null) + json.addProperty("flight_disabled", user.isFlightDisabled()); + if (user.isVanished() != null) + json.addProperty("vanished", user.isVanished()); + if (user.isAutoInvSwapEnabled() != null) + json.addProperty("auto_inv_swap_enabled", user.isAutoInvSwapEnabled()); + if (user.isAutoRadioEnabled() != null) + json.addProperty("auto_radio_enabled", user.isAutoRadioEnabled()); + if (user.isInSandboxMode() != null) + json.addProperty("in_sandbox_mode", user.isInSandboxMode()); + if (user.isUsingCreativeInv() != null) + json.addProperty("using_creative_inv", user.isUsingCreativeInv()); // Format and add datetime fields if (user.getLastWork() != null) diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/Repository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/Repository.java index 71823a0..6744569 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/Repository.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/Repository.java @@ -28,17 +28,29 @@ default String getStringOrNull(@NotNull JsonObject json, String key) { @Nullable default Integer getIntOrNull(@NotNull JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsInt() : null; + try { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsInt() : null; + } catch (NumberFormatException e) { + return null; + } } @Nullable default Long getLongOrNull(@NotNull JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsLong() : null; + try { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsLong() : null; + } catch (NumberFormatException e) { + return null; + } } @Nullable default Double getDoubleOrNull(@NotNull JsonObject json, String key) { - return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsDouble() : null; + try { + return json.has(key) && !json.get(key).isJsonNull() ? json.get(key).getAsDouble() : null; + } catch (NumberFormatException e) { + return null; + } } @Nullable diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/RepositoryManager.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/RepositoryManager.java index 77be215..22b17ee 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/RepositoryManager.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/RepositoryManager.java @@ -9,10 +9,12 @@ public class RepositoryManager { final ServerLogsRepository serverLogsRepository; final UserRepository userRepository; + final ServerCommandsRepository serverCommandsRepository; public RepositoryManager(PocketBase pocketBase) { serverLogsRepository = new PocketBaseServerLogsRepository(pocketBase); userRepository = new PocketBaseUserRepository(pocketBase); + serverCommandsRepository = new PocketBaseServerCommandsRepository(pocketBase); } public ServerLogsRepository getServerLogsRepository() { @@ -22,4 +24,8 @@ public ServerLogsRepository getServerLogsRepository() { public UserRepository getUserRepository() { return userRepository; } + + public ServerCommandsRepository getServerCommandsRepository() { + return serverCommandsRepository; + } } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/ServerCommandsRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/ServerCommandsRepository.java new file mode 100644 index 0000000..104a95b --- /dev/null +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/ServerCommandsRepository.java @@ -0,0 +1,36 @@ +package org.woftnw.dreamvisitor.data.repository; + +import org.woftnw.dreamvisitor.data.type.ServerCommand; + +import java.util.List; +import java.util.Optional; + +/** + * Repository interface for Item data operations + */ +public interface ServerCommandsRepository extends Repository { + /** + * Find a command by its PocketBase ID + * + * @param id PocketBase record ID + * @return Optional containing the command if found + */ + Optional findById(String id); + + /** + * Get a list of commands by their status. + * + * @param status the status of the commands to get. + * @return a list of commands with the specified status. + */ + List getByStatus(ServerCommand.Status status); + + /** + * Update a command. This will not create one. + * + * @param command ServerCommand to save + * @return Saved ServerCommand + */ + ServerCommand update(ServerCommand command); + +} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/ServerLogsRepository.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/ServerLogsRepository.java index b19565a..83a6081 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/ServerLogsRepository.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/repository/ServerLogsRepository.java @@ -5,7 +5,7 @@ import java.util.List; /** - * Repository interface for Item data operations + * Repository interface for ServerLog data operations */ public interface ServerLogsRepository extends Repository { /** @@ -16,10 +16,10 @@ public interface ServerLogsRepository extends Repository { List findLast(int count); /** - * Save an item (create or update) + * Save a log (create or update) * - * @param item Item to save - * @return Saved item + * @param item ServerLog to save + * @return Saved ServerLog */ ServerLog create(ServerLog item); diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/ServerCommand.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/ServerCommand.java new file mode 100644 index 0000000..38e98a2 --- /dev/null +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/data/type/ServerCommand.java @@ -0,0 +1,77 @@ +package org.woftnw.dreamvisitor.data.type; + +import java.time.OffsetDateTime; + +public class ServerCommand { + private String id; + private String collectionId; + private String collectionName; + + private String command; + private Status status; + + private OffsetDateTime created; + private OffsetDateTime updated; + + // Getters and setters + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getCollectionId() { + return collectionId; + } + + public void setCollectionId(String collectionId) { + this.collectionId = collectionId; + } + + public String getCollectionName() { + return collectionName; + } + + public void setCollectionName(String collectionName) { + this.collectionName = collectionName; + } + + public String getCommand() { + return command; + } + + public void setCommand(String command) { + this.command = command; + } + + public OffsetDateTime getCreated() { + return created; + } + + public void setCreated(OffsetDateTime created) { + this.created = created; + } + + public OffsetDateTime getUpdated() { + return updated; + } + + public void setUpdated(OffsetDateTime updated) { + this.updated = updated; + } + + public Status getStatus() { + return status; + } + + public void setStatus(Status status) { + this.status = status; + } + + public enum Status { + SENT, RECEIVED, EXECUTED, FAILED + } + +} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/CommandRunner.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/CommandRunner.java new file mode 100644 index 0000000..e234a59 --- /dev/null +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/CommandRunner.java @@ -0,0 +1,42 @@ +package org.woftnw.dreamvisitor.functions; + +import org.bukkit.Bukkit; +import org.woftnw.dreamvisitor.Dreamvisitor; +import org.woftnw.dreamvisitor.data.repository.ServerCommandsRepository; +import org.woftnw.dreamvisitor.data.type.ServerCommand; + +import java.util.List; + +public class CommandRunner { + + private final ServerCommandsRepository serverCommandsRepository = Dreamvisitor.getPlugin().getRepositoryManager().getServerCommandsRepository(); + + public void run() { + // Get new commands + List commands = serverCommandsRepository.getByStatus(ServerCommand.Status.SENT); +// Messager.debug("Got " + commands.size() + " new commands."); + + for (ServerCommand command : commands) { + // Set the status to received + command.setStatus(ServerCommand.Status.RECEIVED); + // Update PocketBase + serverCommandsRepository.update(command); + +// Messager.debug("Updated statuses. Executing commands."); + + // Schedule execution + Bukkit.getScheduler().runTask(Dreamvisitor.getPlugin(), () -> { +// Messager.debug("Executing command " + command.getCommand()); + // Run the command + boolean success = Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command.getCommand()); + // Store the result in the status + if (success) command.setStatus(ServerCommand.Status.EXECUTED); + else command.setStatus(ServerCommand.Status.FAILED); +// Messager.debug("Command was " + command.getStatus()); + // Update PocketBase asynchronously + Bukkit.getScheduler().runTaskAsynchronously(Dreamvisitor.getPlugin(), () -> serverCommandsRepository.update(command)); + }); + } + } + +} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ConsoleLogger.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ConsoleLogger.java index 117f2b4..bc4c7f9 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ConsoleLogger.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ConsoleLogger.java @@ -1,5 +1,6 @@ package org.woftnw.dreamvisitor.functions; +import net.md_5.bungee.api.ChatColor; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.appender.AbstractAppender; import org.jetbrains.annotations.NotNull; @@ -29,7 +30,7 @@ public void append(@NotNull LogEvent event) { // Send message to PocketBase ServerLog logItem = new ServerLog(); - logItem.setLogMsg(message); + logItem.setLogMsg(message.replaceAll("\u001B?(\\W1B)?\\[([0-9,;]+)m", "")); Dreamvisitor.getPlugin().getRepositoryManager().getServerLogsRepository().create(logItem); } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigKey.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigKey.java index fec630f..58ba346 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigKey.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigKey.java @@ -18,11 +18,11 @@ public enum ConfigKey { ENABLE_LOG_CONSOLE_COMMANDS("enable_log_console_commands", false, Boolean.class), // Technically this only need to be read by DreamvisitorHub, but it's a good idea to have it here for redundancy. MAIL_DELIVERY_LOCATION_SELECTION_DISTANCE_WEIGHT_MULTIPLIER("mail_delivery_location_selection_distance_weight_multiplier", 1.00, Double.class), MAIL_DISTANCE_TO_REWARD_MULTIPLIER("mail_distance_to_reward_multiplier", 0.05, Double.class), - FLIGHT_ENERGY_CAPACITY("flight_energy_capacity", 400, Integer.class), + FLIGHT_ENERGY_CAPACITY("flight_energy_capacity", 400.00, Double.class), FLIGHT_REGENERATION_POINT("flight_regeneration_point", 200.00, Double.class), FLIGHT_ENERGY_REGENERATION("flight_energy_regeneration", 1.00, Double.class), - FLIGHT_ENERGY_DEPLETION_X_Z_MULTIPLIER("flight_energy_destruction_x_z_multiplier", 1.00, Double.class), - FLIGHT_ENERGY_DEPLETION_Y_MULTIPLIER("flight_energy_destruction_y_multiplier", 2.00, Double.class), + FLIGHT_ENERGY_DEPLETION_X_Z_MULTIPLIER("flight_energy_depletion_x_z_multiplier", 1.00, Double.class), + FLIGHT_ENERGY_DEPLETION_Y_MULTIPLIER("flight_energy_depletion_y_multiplier", 2.00, Double.class), DAYS_UNTIL_INACTIVE_TAX("days_until_inactive_tax", 60, Integer.class), INACTIVE_TAX_PERCENT("inactive_tax_percent", 0.1, Double.class), INACTIVE_DAY_FREQUENCY("inactive_day_frequency", 7, Integer.class), From b59b64f87a2897ea0715916c892fa08cbb618780 Mon Sep 17 00:00:00 2001 From: Bog Date: Wed, 2 Jul 2025 11:00:16 -0700 Subject: [PATCH 18/39] Remove color codes from logs --- .../java/org/woftnw/dreamvisitor/functions/ConsoleLogger.java | 1 - 1 file changed, 1 deletion(-) diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ConsoleLogger.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ConsoleLogger.java index bc4c7f9..24728f2 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ConsoleLogger.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ConsoleLogger.java @@ -1,6 +1,5 @@ package org.woftnw.dreamvisitor.functions; -import net.md_5.bungee.api.ChatColor; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.appender.AbstractAppender; import org.jetbrains.annotations.NotNull; From ff38c7d77b717b274584089884a7c6fb036501db Mon Sep 17 00:00:00 2001 From: Bog Date: Wed, 13 Aug 2025 08:00:56 -0700 Subject: [PATCH 19/39] Disable safely if PocketBase URL or Config ID is not defined. --- .../org/woftnw/dreamvisitor/Dreamvisitor.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java index 81ad326..33be91f 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java @@ -11,6 +11,7 @@ import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandTree; import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.plugin.IllegalPluginAccessException; import org.bukkit.scheduler.BukkitTask; import org.woftnw.dreamvisitor.commands.*; import org.woftnw.dreamvisitor.data.*; @@ -139,7 +140,9 @@ public void onEnable() { boolean useRealtime = getConfig().getBoolean("pocketbaseUseRealtime", true); if (baseUrl.isEmpty() || configId.isEmpty()) { - throw new NullPointerException("Missing PocketBase URL or Config ID"); + getLogger().severe("PocketBase URL or Config ID is not defined. Check the config and restart the server. Dreamvisitor is disabling to prevent issues."); + Bukkit.getPluginManager().disablePlugin(this); + return; } Messager.debug("Initialized PocketBase client"); @@ -430,11 +433,19 @@ public void onDisable() { moonglobe.remove(null); // Save and shutdown the Command Scheduler - CommandScheduler.getInstance().saveConfig(); - CommandScheduler.getInstance().stopScheduler(); + try { + CommandScheduler.getInstance().saveConfig(); + CommandScheduler.getInstance().stopScheduler(); + } catch (IllegalPluginAccessException ignored) { + // This might happen if Dreamvisitor fails to start correctly + } // Unattach the server logger - logger.removeAppender(appender); + try { + logger.removeAppender(appender); + } catch (NullPointerException ignored) { + // This might happen if Dreamvisitor fails to start correctly + } // TODO: Send shutdown signal to PocketBase. From ed47af406c9457e6cf833a8f896a52da732e2e91 Mon Sep 17 00:00:00 2001 From: Bog Date: Wed, 13 Aug 2025 08:14:32 -0700 Subject: [PATCH 20/39] Update CommandAPI to 10.1.2 --- dreamvisitor/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dreamvisitor/pom.xml b/dreamvisitor/pom.xml index e4fed3b..b940681 100644 --- a/dreamvisitor/pom.xml +++ b/dreamvisitor/pom.xml @@ -104,7 +104,7 @@ dev.jorel commandapi-bukkit-shade - 10.1.0 + 10.1.2 compile From d3c550072521361654d751e97d107337eded66e3 Mon Sep 17 00:00:00 2001 From: Bog Date: Wed, 13 Aug 2025 08:15:28 -0700 Subject: [PATCH 21/39] Initialize files before commands Files must exist before commands which rely on them can be initialized. --- .../org/woftnw/dreamvisitor/Dreamvisitor.java | 70 ++++++++++--------- .../woftnw/dreamvisitor/functions/Mail.java | 2 +- 2 files changed, 39 insertions(+), 33 deletions(-) diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java index 33be91f..afc00ff 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java @@ -168,6 +168,43 @@ public void onEnable() { Messager.debug("Setting up repositories..."); repositoryManager = new RepositoryManager(pocketBase); + // Set up files. This must happen first because setting up commands require some files to exist. + + Messager.debug("Creating data folder..."); + boolean directoryCreated = getDataFolder().mkdir(); + if (!directoryCreated) + Messager.debug("Dreamvisitor did not create a data folder. It may already exist."); + saveDefaultConfig(); + + Messager.debug("Initializing mail.yml"); + try { + Mail.init(); + } catch (IOException e) { + getLogger().warning("Unable to mail locations from " + PlayerTribe.file + ": " + e.getMessage()); + } + + Messager.debug("Initializing player-tribes.yml"); + try { + PlayerTribe.setup(); + } catch (IOException e) { + getLogger().warning("Unable to load tribes from " + PlayerTribe.file + ": " + e.getMessage()); + } + + Messager.debug("Initializing energy"); + Flight.init(); + + Messager.debug("Initializing command scheduler"); + CommandScheduler.getInstance().loadConfig(); + + Messager.debug("Initializing badwords.yml"); + try { + BadWords.init(); + } catch (IOException e) { + getLogger().warning("Unable to load bad words from " + BadWords.file + ": " + e.getMessage()); + } + + // Set up listeners and commands + Messager.debug("Registering listeners..."); registerListeners(); @@ -209,38 +246,7 @@ public void onEnable() { Messager.debug("Registering " + commands.size() + " commands..."); registerCommands(commands); - Messager.debug("Creating data folder..."); - boolean directoryCreated = getDataFolder().mkdir(); - if (!directoryCreated) - Messager.debug("Dreamvisitor did not create a data folder. It may already exist."); - saveDefaultConfig(); - - Messager.debug("Initializing mail.yml"); - try { - Mail.init(); - } catch (IOException e) { - getLogger().warning("Unable to mail locations from " + PlayerTribe.file + ": " + e.getMessage()); - } - - Messager.debug("Initializing player-tribes.yml"); - try { - PlayerTribe.setup(); - } catch (IOException e) { - getLogger().warning("Unable to load tribes from " + PlayerTribe.file + ": " + e.getMessage()); - } - - Messager.debug("Initializing energy"); - Flight.init(); - - Messager.debug("Initializing command scheduler"); - CommandScheduler.getInstance().loadConfig(); - - Messager.debug("Initializing badwords.yml"); - try { - BadWords.init(); - } catch (IOException e) { - getLogger().warning("Unable to load bad words from " + BadWords.file + ": " + e.getMessage()); - } + // Set up misc Messager.debug("Initializing LuckPerms API..."); RegisteredServiceProvider provider = Bukkit.getServicesManager().getRegistration(LuckPerms.class); diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Mail.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Mail.java index c0e7da7..b1743ff 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Mail.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Mail.java @@ -36,7 +36,7 @@ public class Mail { - static final File file = new File(Dreamvisitor.getPlugin().getDataFolder().getPath() + "/mail.yml"); + static final File file = new File(Dreamvisitor.getPlugin().getDataFolder(), "/mail.yml"); static List activeDeliverers = new ArrayList<>(); static double maxDistance; From 04e440edfe9c955fbc96ff9208bb2f6a63c128d4 Mon Sep 17 00:00:00 2001 From: Bog Date: Wed, 13 Aug 2025 08:49:15 -0700 Subject: [PATCH 22/39] Change softWhitelist path definition --- .../java/org/woftnw/dreamvisitor/functions/SoftWhitelist.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/SoftWhitelist.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/SoftWhitelist.java index 37b74a6..0d7a5b6 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/SoftWhitelist.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/SoftWhitelist.java @@ -13,7 +13,7 @@ import java.util.UUID; public class SoftWhitelist { - private static final File file = new File(Dreamvisitor.getPlugin().getDataFolder().getAbsolutePath() + "/softWhitelist.yml"); + private static final File file = new File(Dreamvisitor.getPlugin().getDataFolder(),"softWhitelist.yml"); public static void init() throws IOException { if (!file.exists()) { From 86db4f42510bea631be0a546145970c80a2f490e Mon Sep 17 00:00:00 2001 From: Bog Date: Wed, 13 Aug 2025 09:00:13 -0700 Subject: [PATCH 23/39] Combine parcel location info on fewer lines --- .../java/org/woftnw/dreamvisitor/commands/CmdParcel.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdParcel.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdParcel.java index 001d657..78e8ca6 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdParcel.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdParcel.java @@ -81,12 +81,12 @@ public CommandAPICommand getCommand() { for (Mail.MailLocation mailLocation : locations) { message.append("\n").append(mailLocation.getName()).color(net.md_5.bungee.api.ChatColor.YELLOW) - .append("\n").reset().append(String.valueOf(mailLocation.getLocation().getX())) + .append(": ").reset().append(String.valueOf(mailLocation.getLocation().getX())) .append(" ").append(String.valueOf(mailLocation.getLocation().getY())) .append(" ").append(String.valueOf(mailLocation.getLocation().getZ())) - .append(" in world ").append(Objects.requireNonNull(mailLocation.getLocation().getWorld()).getName()) + .append(" in ").append(Objects.requireNonNull(mailLocation.getLocation().getWorld()).getName()) .append("\n Weight: ").append(String.valueOf(mailLocation.getWeight())) - .append("\n Home Tribe: ").append(mailLocation.getHomeTribe().getName()); + .append(", Home Tribe: ").append(mailLocation.getHomeTribe().getName()); } Messager.send(sender, message.create()); }) From 53174bf08ef51caa67171e72b6c2e0d163cb0815 Mon Sep 17 00:00:00 2001 From: Bog Date: Wed, 13 Aug 2025 09:02:08 -0700 Subject: [PATCH 24/39] Remove ItemVoid functionality --- .../org/woftnw/dreamvisitor/Dreamvisitor.java | 33 -------- .../dreamvisitor/commands/CmdItemBanList.java | 31 -------- .../dreamvisitor/functions/ItemBanList.java | 78 ------------------- 3 files changed, 142 deletions(-) delete mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdItemBanList.java delete mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ItemBanList.java diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java index afc00ff..d69e183 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java @@ -221,7 +221,6 @@ public void onEnable() { commands.add(new CmdSoftwhitelist()); commands.add(new CmdTagRadio()); commands.add(new CmdZoop()); - commands.add(new CmdItemBanList()); commands.add(new CmdUser()); commands.add(new CmdTribeUpdate()); commands.add(new CmdUnwax()); @@ -268,13 +267,6 @@ public void onEnable() { playerLimit = Config.get(ConfigKey.PLAYER_LIMIT); getLogger().info("Player limit override is currently set to " + playerLimit); - Messager.debug("Restoring item banlist..."); - try { - ItemBanList.init(); - } catch (IOException e) { - getLogger().warning("Unable to load banned items from " + ItemBanList.file + ": " + e.getMessage()); - } - Messager.debug("Setting up console logging..."); appender = new ConsoleLogger(); logger.addAppender(appender); @@ -330,28 +322,6 @@ public void run() { } }; - Runnable checkBannedItems = new BukkitRunnable() { - @Override - public void run() { - for (Player player : Bukkit.getOnlinePlayers()) { - if (!player.isOp() && ItemBanList.badItems != null) { - - for (ItemStack item : ItemBanList.badItems) { - if (item == null) - continue; - for (ItemStack content : player.getInventory().getContents()) { - if (content == null || !content.isSimilar(item)) - continue; - player.getInventory().remove(item); - getLogger().info("Removed " + item.getType().name() + " (" - + Objects.requireNonNull(item.getItemMeta()).getDisplayName() + ") from " + player.getName()); - } - } - } - } - } - }; - Runnable tickFlight = Flight::tick; Bukkit.getScheduler().runTaskTimerAsynchronously(this, runCommandsAsync, 20, 40); @@ -360,8 +330,6 @@ public void run() { Bukkit.getScheduler().runTaskTimer(this, scheduledRestarts, 200, 1200); - Bukkit.getScheduler().runTaskTimer(this, checkBannedItems, 40, 20 * 10); - Bukkit.getScheduler().runTaskTimer(this, tickFlight, 0, 1); getLogger().log(Level.INFO, "Dreamvisitor has been enabled."); @@ -399,7 +367,6 @@ private void registerListeners() { pluginManager.registerEvents(new ListenPlayerJoin(), this); pluginManager.registerEvents(new ListenPlayerLogin(), this); pluginManager.registerEvents(new ListenPlayerQuit(), this); - pluginManager.registerEvents(new ItemBanList(), this); pluginManager.registerEvents(new ListenPlayerGameModeChange(), this); pluginManager.registerEvents(new ListenServerPing(), this); pluginManager.registerEvents(new Sandbox(), this); diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdItemBanList.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdItemBanList.java deleted file mode 100644 index 394b0bb..0000000 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdItemBanList.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.woftnw.dreamvisitor.commands; - -import dev.jorel.commandapi.CommandAPI; -import dev.jorel.commandapi.CommandAPICommand; -import dev.jorel.commandapi.CommandPermission; -import org.woftnw.dreamvisitor.functions.ItemBanList; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; - -public class CmdItemBanList implements DVCommand { - - @NotNull - @Override - public CommandAPICommand getCommand() { - return new CommandAPICommand("itembanlist") - .withPermission(CommandPermission.fromString("dreamvisitor.itembanlist")) - .withHelp("Manage the item ban list.", "Open the item ban list inventory GUI.") - .executesNative(((sender, args) -> { - final CommandSender callee = sender.getCallee(); - if (callee instanceof Player player) { - if (ItemBanList.badItems != null) { - ItemBanList.inv.setContents(ItemBanList.badItems.toArray(new ItemStack[0])); - } - player.openInventory(ItemBanList.inv); - } else throw CommandAPI.failWithString("This command must be executed as a player!"); - - })); - } -} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ItemBanList.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ItemBanList.java deleted file mode 100644 index 9117cb8..0000000 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/ItemBanList.java +++ /dev/null @@ -1,78 +0,0 @@ -package org.woftnw.dreamvisitor.functions; - -import org.woftnw.dreamvisitor.Dreamvisitor; -import org.bukkit.Bukkit; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.inventory.InventoryCloseEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -public class ItemBanList implements Listener { - public static final Inventory inv = Bukkit.createInventory(null, 27, "Banned Items"); - public static List badItems = new ArrayList<>(); - - public static final File file = new File(Dreamvisitor.getPlugin().getDataFolder().getPath() + "/bannedItems.yml"); - static FileConfiguration config = YamlConfiguration.loadConfiguration(file); - - public static void init() throws IOException { - // If the file does not exist, create one - if (!file.exists()) { - Messager.debug(file.getName() + " does not exist. Creating one now..."); - try { - if (!file.createNewFile()) - throw new IOException("The existence of " + file.getName() + " cannot be verified!", null); - } catch (IOException e) { - throw new IOException("Dreamvisitor tried to create " + file.getName() + ", but it cannot be read/written! Does the server have read/write access?", e); - } - } - config = YamlConfiguration.loadConfiguration(file); - try { - badItems = (List) config.getList("items", new ArrayList<>()); - } catch (Exception e) { - Dreamvisitor.getPlugin().getLogger().warning("Unable to restore item ban list."); - } - } - - public static void saveItems() { - badItems = List.of(inv.getContents()); - config.set("items", badItems); - try { - config.save(file); - } catch (IOException e) { - Dreamvisitor.getPlugin().getLogger().warning("Unable to save to " + file.getName() + "!"); - } - } - - @EventHandler - public void onInventoryClose(@NotNull InventoryCloseEvent event) { - Player player = (Player) event.getPlayer(); - - if (!player.isOp() && ItemBanList.badItems != null) { - - for (ItemStack item : ItemBanList.badItems) { - if (item == null) continue; - for (ItemStack content : player.getInventory().getContents()) { - if (content == null || !content.isSimilar(item)) continue; - player.getInventory().remove(item); - Dreamvisitor.getPlugin().getLogger().info("Removed " + item.getType().name() + " (" + Objects.requireNonNull(item.getItemMeta()).getDisplayName() + ") from " + player.getName()); - } - } - } - - if (event.getInventory().equals(ItemBanList.inv)) { - ItemBanList.saveItems(); - } - } - -} From 70feb901a72f3e332536ec12539820688439346b Mon Sep 17 00:00:00 2001 From: Bog Date: Wed, 13 Aug 2025 09:07:16 -0700 Subject: [PATCH 25/39] Remove PlayerCap functionality --- .../org/woftnw/dreamvisitor/Dreamvisitor.java | 10 ---- .../dreamvisitor/commands/CmdPanic.java | 1 - .../dreamvisitor/commands/CmdPlayerlimit.java | 53 ------------------- .../listeners/ListenPlayerLogin.java | 20 ------- .../woftnw/dreamvisitor/util/ConfigKey.java | 1 - 5 files changed, 85 deletions(-) delete mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPlayerlimit.java diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java index d69e183..f46d387 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java @@ -10,9 +10,7 @@ import dev.jorel.commandapi.CommandAPIBukkitConfig; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandTree; -import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.plugin.IllegalPluginAccessException; -import org.bukkit.scheduler.BukkitTask; import org.woftnw.dreamvisitor.commands.*; import org.woftnw.dreamvisitor.data.*; import org.woftnw.dreamvisitor.data.repository.*; @@ -27,8 +25,6 @@ import org.apache.logging.log4j.LogManager; import org.bukkit.Bukkit; import org.bukkit.Location; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.java.JavaPlugin; @@ -48,7 +44,6 @@ public class Dreamvisitor extends JavaPlugin { public static LuckPerms luckperms; public static String MOTD = null; public static boolean chatPaused; - public static int playerLimit; public static Location hubLocation; public static boolean debugMode; private static ConsoleLogger appender; @@ -215,7 +210,6 @@ public void onEnable() { commands.add(new CmdPanic()); commands.add(new CmdPauseBypass()); commands.add(new CmdPausechat()); - commands.add(new CmdPlayerlimit()); commands.add(new CmdRadio()); commands.add(new CmdSethub()); commands.add(new CmdSoftwhitelist()); @@ -263,10 +257,6 @@ public void onEnable() { getLogger().info("Chat is currently paused from last session! Use /pausechat to allow users to chat."); } - Messager.debug("Restoring player limit override..."); - playerLimit = Config.get(ConfigKey.PLAYER_LIMIT); - getLogger().info("Player limit override is currently set to " + playerLimit); - Messager.debug("Setting up console logging..."); appender = new ConsoleLogger(); logger.addAppender(appender); diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPanic.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPanic.java index 5f11c84..687a720 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPanic.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPanic.java @@ -38,7 +38,6 @@ public void run() { player.kickPlayer("Panic!"); } } - Dreamvisitor.playerLimit = 0; plugin.getConfig().set("playerlimit", 0); plugin.saveConfig(); Bukkit.getServer().broadcastMessage( diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPlayerlimit.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPlayerlimit.java deleted file mode 100644 index bb24b09..0000000 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPlayerlimit.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.woftnw.dreamvisitor.commands; - -import dev.jorel.commandapi.CommandAPICommand; -import dev.jorel.commandapi.CommandPermission; -import dev.jorel.commandapi.arguments.IntegerArgument; -import org.woftnw.dreamvisitor.functions.Messager; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.entity.Player; - -import org.woftnw.dreamvisitor.Dreamvisitor; -import org.jetbrains.annotations.NotNull; - -public class CmdPlayerlimit implements DVCommand { - - final Dreamvisitor plugin = Dreamvisitor.getPlugin(); - - @NotNull - @Override - public CommandAPICommand getCommand() { - return new CommandAPICommand("playerlimit") - .withPermission(CommandPermission.fromString("dreamvisitor.playerlimit")) - .withHelp("Set the player limit.", "Override the server player limit.") - .withOptionalArguments(new IntegerArgument("newLimit", -1)) - .executesNative((sender, args) -> { - - Object newLimitArg = args.get("newLimit"); - if (newLimitArg == null) { - Messager.send(sender, "Player limit override is currently set to " + Dreamvisitor.playerLimit + "."); - } else { - try { - // Change config - final int result = (int) newLimitArg; - // Dreamvisitor.getPlugin().getServer().setMaxPlayers(result); - - for (Player player : Bukkit.getServer().getOnlinePlayers()) { - if (player.isOp()) { - player.sendMessage(ChatColor.BLUE + "Player limit override set to " + result); - } - } - - Dreamvisitor.playerLimit = result; - plugin.getConfig().set("playerlimit", result); - plugin.saveConfig(); - - } catch (NumberFormatException e) { - Messager.sendDanger(sender, "Incorrect arguments! /playerlimit "); - } - } - - }); - } -} diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerLogin.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerLogin.java index 767dbd2..81f18f5 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerLogin.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/listeners/ListenPlayerLogin.java @@ -44,26 +44,6 @@ public void onPlayerLoginEvent(@NotNull PlayerLoginEvent event) { // Always deny non-whitelisted event.disallow(Result.KICK_WHITELIST, "You are not whitelisted."); - } else if (Dreamvisitor.playerLimit != -1) { - // If player limit has been overridden - - // If server is full - if (Bukkit.getOnlinePlayers().size() >= Dreamvisitor.playerLimit) { - - // Kick for server full - event.disallow(Result.KICK_FULL, "The server is full. The current player limit is " + Dreamvisitor.playerLimit); - - } else if (Config.get(ConfigKey.SOFT_WHITELIST)) { - - // Soft whitelist is enabled - allowIfSoftWhitelist(player, event); - - } else { - // Soft whitelist not enabled - event.allow(); - } - - } else { // Player limit is not overridden diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigKey.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigKey.java index 58ba346..d1b126a 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigKey.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/util/ConfigKey.java @@ -11,7 +11,6 @@ public enum ConfigKey { AUTO_RESTART("auto_restart", false, Boolean.class), PAUSE_CHAT("pause_chat", false, Boolean.class), SOFT_WHITELIST("soft_whitelist", false, Boolean.class), - PLAYER_LIMIT("player_limit", -1, Integer.class), RESOURCE_PACK_REPO("resource_pack_repo", "WOFTNW/Dragonspeak", String.class), HUB_LOCATION("hub_location", null, Location.class), LOG_CONSOLE("log_console", false, Boolean.class), From e90abe4cd4918f32a5dbe93d3eb50744502d151a Mon Sep 17 00:00:00 2001 From: Bog Date: Wed, 13 Aug 2025 09:59:42 -0700 Subject: [PATCH 26/39] Added nameOrCountEntity to Messager --- .../woftnw/dreamvisitor/commands/CmdVelocity.java | 2 +- .../woftnw/dreamvisitor/functions/Messager.java | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdVelocity.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdVelocity.java index 05d1f6b..ffdded9 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdVelocity.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdVelocity.java @@ -47,8 +47,8 @@ public CommandAPICommand getCommand() { } else { entity.setVelocity(entity.getVelocity().add(force.toVector())); } - Messager.send(sender, "Applied velocity to " + Messager.chooseCountForm(entities, "entity", "entities") + "."); } + Messager.send(sender, "Applied velocity to " + Messager.nameOrCountEntity(entities) + "."); }); } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Messager.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Messager.java index 8ec6718..3f39333 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Messager.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Messager.java @@ -1,5 +1,6 @@ package org.woftnw.dreamvisitor.functions; +import org.bukkit.entity.Entity; import org.woftnw.dreamvisitor.Dreamvisitor; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.BaseComponent; @@ -76,6 +77,20 @@ public static String nameOrCountPlayer(@NotNull Collection targets) { return chooseCountForm(targets, "player ", "players"); } + /** + * Get the name of a {@link Collection} of {@link Player}s. + * + * @param targets the {@link Collection} of {@link Player}s. + * @return the name of the {@link Collection} of {@link Player)s. + */ + @NotNull + public static String nameOrCountEntity(@NotNull Collection targets) { + if (targets.size() == 1) { + return targets.iterator().next().getName(); + } + return chooseCountForm(targets, "entity ", "entities"); + } + /** * Get the name of a {@link Collection} of {@link String}s. * From e309adfda2fdeb9a854d8fa4ae7b812ca0c0dafd Mon Sep 17 00:00:00 2001 From: Bog Date: Wed, 13 Aug 2025 10:02:55 -0700 Subject: [PATCH 27/39] Remove /discord command --- .../org/woftnw/dreamvisitor/Dreamvisitor.java | 1 - .../dreamvisitor/commands/CmdDiscord.java | 36 ------------------- 2 files changed, 37 deletions(-) delete mode 100644 dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdDiscord.java diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java index f46d387..bde805a 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/Dreamvisitor.java @@ -205,7 +205,6 @@ public void onEnable() { List commands = new ArrayList<>(); commands.add(new CmdAdminRadio()); - commands.add(new CmdDiscord()); commands.add(new CmdHub()); commands.add(new CmdPanic()); commands.add(new CmdPauseBypass()); diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdDiscord.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdDiscord.java deleted file mode 100644 index c73cb6c..0000000 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdDiscord.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.woftnw.dreamvisitor.commands; - -import dev.jorel.commandapi.CommandAPI; -import dev.jorel.commandapi.CommandAPICommand; -import org.woftnw.dreamvisitor.data.PlayerUtility; -import org.woftnw.dreamvisitor.data.type.DVUser; -import org.woftnw.dreamvisitor.functions.Messager; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; - -public class CmdDiscord implements DVCommand { - - @NotNull - @Override - public CommandAPICommand getCommand() { - return new CommandAPICommand("discord") - .withHelp("Toggles Discord message visibility.", "Toggle whether messages from the Discord chat bridge appear in your chat.") - .executesNative(((sender, args) -> { - final CommandSender callee = sender.getCallee(); - if (callee instanceof Player player) { - - final DVUser user = PlayerUtility.getUser(player); - - user.setShowDiscordMessages(!user.isShowDiscordOn()); - - Messager.send(player, "Discord visibility toggled to " + user.isShowDiscordOn() + "."); - - PlayerUtility.saveUser(user); - - } else throw CommandAPI.failWithString("This command must be executed as a player!"); - - - })); - } -} From 9be08969474064b451230ef5cca2cfc7c33c1189 Mon Sep 17 00:00:00 2001 From: Bog Date: Wed, 13 Aug 2025 10:08:35 -0700 Subject: [PATCH 28/39] Use PB config for checking if in debug --- .../main/java/org/woftnw/dreamvisitor/functions/Messager.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Messager.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Messager.java index 3f39333..1a4eef3 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Messager.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/functions/Messager.java @@ -8,6 +8,8 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import org.woftnw.dreamvisitor.data.Config; +import org.woftnw.dreamvisitor.util.ConfigKey; import java.awt.*; import java.util.Collection; @@ -58,7 +60,7 @@ public static void sendDanger(@NotNull CommandSender target, String message) { * @param message the message to log. */ public static void debug(String message) { - if (Dreamvisitor.getPlugin().getConfig().getBoolean("debug")) { + if (Config.get(ConfigKey.DEBUG)) { Dreamvisitor.getPlugin().getLogger().info("DEBUG: " + message); } } From ee1b63ad7519a5677e2644484ce14e66549607ab Mon Sep 17 00:00:00 2001 From: Bog Date: Wed, 13 Aug 2025 10:33:14 -0700 Subject: [PATCH 29/39] Use more Message methods for nicer messages --- .../main/java/org/woftnw/dreamvisitor/commands/CmdHub.java | 7 +------ .../org/woftnw/dreamvisitor/commands/CmdMoonglobe.java | 2 +- .../java/org/woftnw/dreamvisitor/commands/CmdPanic.java | 3 ++- .../java/org/woftnw/dreamvisitor/commands/CmdParcel.java | 2 +- .../java/org/woftnw/dreamvisitor/commands/CmdSetback.java | 2 +- 5 files changed, 6 insertions(+), 10 deletions(-) diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdHub.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdHub.java index 38842cd..44db97a 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdHub.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdHub.java @@ -72,12 +72,7 @@ public CommandAPICommand getCommand() { } else entity.teleport(Dreamvisitor.hubLocation, TeleportCause.COMMAND); } } - if (entitySelect.size() == 1) { - Messager.send(callee, "Teleported " + entitySelect.stream().findFirst().get().getName() + " to the hub."); - } - else { - Messager.send(callee, "Teleported " + entitySelect.size() + " entities to the hub."); - } + Messager.send(callee, "Teleported " + Messager.nameOrCountEntity(entitySelect) + " to the hub."); } } else { diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdMoonglobe.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdMoonglobe.java index dfa62ae..14efb28 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdMoonglobe.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdMoonglobe.java @@ -36,7 +36,7 @@ private static String create(@NotNull Collection players, @NotNull Locat if (!alreadyHasGlobe) new Moonglobe(player.getUniqueId(), location, maxDistance); } - return ("Created moon globes for " + players.size() + " players."); + return ("Created moon globes for " + Messager.nameOrCountPlayer(players) + "."); } diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPanic.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPanic.java index 687a720..315713e 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPanic.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdPanic.java @@ -38,7 +38,8 @@ public void run() { player.kickPlayer("Panic!"); } } - plugin.getConfig().set("playerlimit", 0); + // TODO: Set player limit through PlayerCap +// plugin.getConfig().set("playerlimit", 0); plugin.saveConfig(); Bukkit.getServer().broadcastMessage( ChatColor.RED + "Panicked by " + sender.getName() + ".\nPlayer limit override set to 0."); diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdParcel.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdParcel.java index 78e8ca6..76148f9 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdParcel.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdParcel.java @@ -148,7 +148,7 @@ public CommandAPICommand getCommand() { } } - Messager.send(sender, "Toggled mail for " + players.size() + "."); + Messager.send(sender, "Toggled mail for " + Messager.nameOrCountPlayer(players) + "."); }) ) diff --git a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSetback.java b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSetback.java index dce8267..3d06258 100644 --- a/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSetback.java +++ b/dreamvisitor/src/main/java/org/woftnw/dreamvisitor/commands/CmdSetback.java @@ -78,7 +78,7 @@ public CommandAPICommand getCommand() { Messager.send(sender, "Set back location to " + location.getBlockX() + ", " + location.getBlockY() + ", " + location.getBlockZ() + " of " + Objects.requireNonNull(location.getWorld()).getName() + " for " + - players.size() + " player(s)."); + Messager.nameOrCountPlayer(players) + "."); }); } From c520a6151d792a8c62347a57666ad4479d37d324 Mon Sep 17 00:00:00 2001 From: Bog Date: Wed, 13 Aug 2025 10:33:58 -0700 Subject: [PATCH 30/39] Reformat pom.xml --- dreamvisitor/pom.xml | 313 ++++++++++++++++++++++--------------------- 1 file changed, 157 insertions(+), 156 deletions(-) diff --git a/dreamvisitor/pom.xml b/dreamvisitor/pom.xml index b940681..70a4fd4 100644 --- a/dreamvisitor/pom.xml +++ b/dreamvisitor/pom.xml @@ -1,162 +1,163 @@ - - 4.0.0 - org.woftnw - dreamvisitor - 3.0.0 - jar + + 4.0.0 + org.woftnw + dreamvisitor + 3.0.0 + jar - Dreamvisitor + Dreamvisitor - - UTF-8 - 21 - 21 - - - - - spigot-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots/ - - - jitpack.io - https://jitpack.io - - - essentialsx-releases - EssentialsX API Repository - https://repo.essentialsx.net/releases - - - paper-repo - https://repo.papermc.io/repository/maven-public/ - - - minecraft-repo - https://libraries.minecraft.net/ - - - sk89q-repo - https://maven.enginehub.org/repo/ - - + + UTF-8 + 21 + 21 + - - - - org.spigotmc - spigot-api - 1.21.4-R0.1-SNAPSHOT - provided - - - - net.dv8tion - JDA - 5.0.0-beta.24 - - - - org.apache.logging.log4j - log4j-api - 2.23.1 - - - - org.apache.logging.log4j - log4j-core - 2.20.0 - - - - com.sparkjava - spark-core - 2.9.4 - - - - net.essentialsx - EssentialsX - 2.20.1 - provided - - - - org.json - json - 20240303 - - - - com.github.SparklingComet - java-mojang-api - 592fabf3e2 - - - - net.luckperms - api - 5.4 - provided - - - - dev.jorel - commandapi-bukkit-shade - 10.1.2 - compile - - - - com.sk89q.worldguard - worldguard-bukkit - 7.0.12 - provided - - + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + jitpack.io + https://jitpack.io + + + essentialsx-releases + EssentialsX API Repository + https://repo.essentialsx.net/releases + + + paper-repo + https://repo.papermc.io/repository/maven-public/ + + + minecraft-repo + https://libraries.minecraft.net/ + + + sk89q-repo + https://maven.enginehub.org/repo/ + + - - clean package - ${project.basedir}/src/main/java - - - ${project.basedir}/src/main/resources - true - - plugin.yml - config.yml - names.yml - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - 17 - 17 - - - - org.apache.maven.plugins - maven-shade-plugin - 3.5.3 - - - package - - shade - - - - - false - false - - - - + + + + org.spigotmc + spigot-api + 1.21.4-R0.1-SNAPSHOT + provided + + + + net.dv8tion + JDA + 5.0.0-beta.24 + + + + org.apache.logging.log4j + log4j-api + 2.23.1 + + + + org.apache.logging.log4j + log4j-core + 2.20.0 + + + + com.sparkjava + spark-core + 2.9.4 + + + + net.essentialsx + EssentialsX + 2.20.1 + provided + + + + org.json + json + 20240303 + + + + com.github.SparklingComet + java-mojang-api + 592fabf3e2 + + + + net.luckperms + api + 5.4 + provided + + + + dev.jorel + commandapi-bukkit-shade + 10.1.2 + compile + + + + com.sk89q.worldguard + worldguard-bukkit + 7.0.12 + provided + + + + + clean package + ${project.basedir}/src/main/java + + + ${project.basedir}/src/main/resources + true + + plugin.yml + config.yml + names.yml + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 17 + 17 + + + + org.apache.maven.plugins + maven-shade-plugin + 3.5.3 + + + package + + shade + + + + + false + false + + + + \ No newline at end of file From c951eec8130e8c6845facbd4fe0345df8046066d Mon Sep 17 00:00:00 2001 From: Bog Date: Wed, 13 Aug 2025 10:36:05 -0700 Subject: [PATCH 31/39] Add adventure API --- dreamvisitor/pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dreamvisitor/pom.xml b/dreamvisitor/pom.xml index 70a4fd4..5752479 100644 --- a/dreamvisitor/pom.xml +++ b/dreamvisitor/pom.xml @@ -115,6 +115,12 @@ 7.0.12 provided + + + net.kyori + adventure-api + 4.24.0 + From d7b6c1e90e395b681c8a8936c85e3b4065003ef5 Mon Sep 17 00:00:00 2001 From: Bog Date: Wed, 13 Aug 2025 12:41:59 -0700 Subject: [PATCH 32/39] Make everything use Paper and Adventure APIs --- dreamvisitor/.idea/jarRepositories.xml | 5 + dreamvisitor/pom.xml | 11 +- .../org/woftnw/dreamvisitor/Dreamvisitor.java | 8 +- .../dreamvisitor/commands/CmdChatback.java | 6 +- .../commands/CmdDreamvisitor.java | 2 +- .../dreamvisitor/commands/CmdDvset.java | 125 +++++++++--------- .../dreamvisitor/commands/CmdPanic.java | 6 +- .../dreamvisitor/commands/CmdParcel.java | 34 +++-- .../dreamvisitor/commands/CmdPausechat.java | 6 +- .../dreamvisitor/commands/CmdSandbox.java | 29 ++-- .../dreamvisitor/commands/CmdSchedule.java | 46 ++++--- .../org/woftnw/dreamvisitor/data/Config.java | 4 +- .../org/woftnw/dreamvisitor/data/Tribe.java | 29 ++-- .../woftnw/dreamvisitor/functions/Mail.java | 29 ++-- .../dreamvisitor/functions/Messager.java | 65 ++++++--- .../dreamvisitor/functions/Moonglobe.java | 2 +- .../dreamvisitor/functions/PauseBypass.java | 6 +- .../woftnw/dreamvisitor/functions/Radio.java | 19 ++- .../dreamvisitor/functions/Sandbox.java | 26 ++-- .../dreamvisitor/functions/SoftWhitelist.java | 6 +- .../dreamvisitor/functions/Whitelist.java | 9 +- .../listeners/ListenCreatureSpawn.java | 3 +- .../listeners/ListenPlayerChat.java | 31 +++-- .../listeners/ListenPlayerCmdPreprocess.java | 8 +- .../listeners/ListenPlayerDeath.java | 2 +- .../listeners/ListenPlayerJoin.java | 11 +- .../listeners/ListenPlayerLogin.java | 2 +- .../listeners/ListenSignChange.java | 21 ++- 28 files changed, 310 insertions(+), 241 deletions(-) diff --git a/dreamvisitor/.idea/jarRepositories.xml b/dreamvisitor/.idea/jarRepositories.xml index 2028f3d..854dfda 100644 --- a/dreamvisitor/.idea/jarRepositories.xml +++ b/dreamvisitor/.idea/jarRepositories.xml @@ -46,5 +46,10 @@