From 97c0855f8f2c0dc118d9ce0de7f73f83009b025d Mon Sep 17 00:00:00 2001 From: Konicai <71294714+Konicai@users.noreply.github.com> Date: Sat, 4 Jun 2022 00:01:28 -0400 Subject: [PATCH] Strip menu/form/accessitem components --- README.md | 22 +- pom.xml | 43 +-- .../{GeyserHubMain.java => GeyserHub.java} | 38 +- .../projectg/geyserhub/GeyserHubCommand.java | 83 +++++ .../teleporter => }/JoinTeleporter.java | 12 +- .../{SelectorLogger.java => Logger.java} | 10 +- .../scoreboard => }/ScoreboardManager.java | 7 +- .../{module/world => }/WorldSettings.java | 26 +- .../geyserhub/command/GeyserHubCommand.java | 135 ------- .../projectg/geyserhub/config/ConfigId.java | 3 +- .../geyserhub/config/ConfigManager.java | 12 +- .../geyserhub/config/ConfigUpdater.java | 1 + .../geyserhub/config/updaters/SELECTOR_1.java | 50 --- .../{module => }/message/Broadcast.java | 15 +- .../{module => }/message/MessageJoin.java | 6 +- .../geyserhub/module/menu/AccessItem.java | 132 ------- .../module/menu/AccessItemRegistry.java | 183 ---------- .../module/menu/InventoryManager.java | 196 ---------- .../geyserhub/module/menu/MenuUtils.java | 186 ---------- .../module/menu/bedrock/BedrockButton.java | 51 --- .../module/menu/bedrock/BedrockForm.java | 200 ----------- .../menu/bedrock/BedrockFormRegistry.java | 114 ------ .../module/menu/button/OutcomeButton.java | 61 ---- .../module/menu/button/TextButton.java | 38 -- .../module/menu/java/ItemButton.java | 83 ----- .../geyserhub/module/menu/java/JavaMenu.java | 340 ------------------ .../module/menu/java/JavaMenuListeners.java | 45 --- .../module/menu/java/JavaMenuRegistry.java | 144 -------- .../reloadable/ReloadableRegistry.java | 8 +- .../projectg/geyserhub/utils/FileUtils.java | 6 +- .../geyserhub/utils/PlaceholderUtils.java | 12 +- src/main/resources/plugin.yml | 13 +- src/main/resources/selector.yml | 156 -------- 33 files changed, 166 insertions(+), 2265 deletions(-) rename src/main/java/dev/projectg/geyserhub/{GeyserHubMain.java => GeyserHub.java} (63%) create mode 100644 src/main/java/dev/projectg/geyserhub/GeyserHubCommand.java rename src/main/java/dev/projectg/geyserhub/{module/teleporter => }/JoinTeleporter.java (89%) rename src/main/java/dev/projectg/geyserhub/{SelectorLogger.java => Logger.java} (83%) rename src/main/java/dev/projectg/geyserhub/{module/scoreboard => }/ScoreboardManager.java (78%) rename src/main/java/dev/projectg/geyserhub/{module/world => }/WorldSettings.java (77%) delete mode 100644 src/main/java/dev/projectg/geyserhub/command/GeyserHubCommand.java delete mode 100644 src/main/java/dev/projectg/geyserhub/config/updaters/SELECTOR_1.java rename src/main/java/dev/projectg/geyserhub/{module => }/message/Broadcast.java (70%) rename src/main/java/dev/projectg/geyserhub/{module => }/message/MessageJoin.java (77%) delete mode 100644 src/main/java/dev/projectg/geyserhub/module/menu/AccessItem.java delete mode 100644 src/main/java/dev/projectg/geyserhub/module/menu/AccessItemRegistry.java delete mode 100644 src/main/java/dev/projectg/geyserhub/module/menu/InventoryManager.java delete mode 100644 src/main/java/dev/projectg/geyserhub/module/menu/MenuUtils.java delete mode 100644 src/main/java/dev/projectg/geyserhub/module/menu/bedrock/BedrockButton.java delete mode 100644 src/main/java/dev/projectg/geyserhub/module/menu/bedrock/BedrockForm.java delete mode 100644 src/main/java/dev/projectg/geyserhub/module/menu/bedrock/BedrockFormRegistry.java delete mode 100644 src/main/java/dev/projectg/geyserhub/module/menu/button/OutcomeButton.java delete mode 100644 src/main/java/dev/projectg/geyserhub/module/menu/button/TextButton.java delete mode 100644 src/main/java/dev/projectg/geyserhub/module/menu/java/ItemButton.java delete mode 100644 src/main/java/dev/projectg/geyserhub/module/menu/java/JavaMenu.java delete mode 100644 src/main/java/dev/projectg/geyserhub/module/menu/java/JavaMenuListeners.java delete mode 100644 src/main/java/dev/projectg/geyserhub/module/menu/java/JavaMenuRegistry.java delete mode 100644 src/main/resources/selector.yml diff --git a/README.md b/README.md index 7ba0879..7fe6cc0 100644 --- a/README.md +++ b/README.md @@ -4,39 +4,27 @@ [![Discord](https://img.shields.io/discord/853331530004299807?color=7289da&label=discord&logo=discord&logoColor=white)](https://discord.gg/M2SvqCu4e9) [![License](https://img.shields.io/badge/License-GPL-orange)](https://github.com/ProjectG-Plugins/GeyserUpdater/blob/master/LICENSE) - # GeyserHub -**Note: This plugin has been superseded by [CrossplatForms](https://github.com/ProjectG-Plugins/CrossplatForms). GeyserHub will eventually be stripped of its form, menu, and access item capabilities.** +**Note: This plugin has been superseded by [CrossplatForms](https://github.com/ProjectG-Plugins/CrossplatForms). GeyserHub no longer has form, menu, and access item capabilities.** -A crossplay lobby plugin for Spigot servers that provides server selector and command menus through Bedrock forms for Bedrock players, and inventory menus for Java players, with high customizability. Supports BungeeCord, and Velocity if BungeeCord plugin messaging is enabled in `velocity.toml`. +GeyserHub now only provides server/hub capabilities. ### Other Features: Anything can be toggled off. -- Fully customizable Bedrock forms and Java inventory menus that can run commands and move players to other servers -- Hotbar items for quick access to different forms/menus -- Full Placeholder API support - Simple scoreboard - Welcome messages - Automatic broadcasts - World restrictions +- Full Placeholder API support - The legacy simple ServerSelector only for Geyser players can be found [here](https://ci.projectg.dev/job/GeyserHub/job/legacy-selector/). -###### Note: This is NOT an official GeyserMC plugin. It is made to work with Geyser, but it is not maintained or produced by GeyserMC. If you need support with this plugin, please do not ask the Geyser developers — instead, please go to our Discord server which is linked above. - -## Installation - -GeyserHub is a lobby plugin that must be installed on any backend servers you want the selector on. -[Floodgate](https://github.com/GeyserMC/Floodgate) must be installed on the backend servers, AND properly configured. -See this [guide](https://github.com/GeyserMC/Floodgate/wiki/Setup-and-Usage#installing-floodgate-also-on-spigot-servers-behind-bungeecord-or-velocity) for more information. +###### Note: This is NOT an official GeyserMC plugin, it is not maintained or produced by GeyserMC. If you need support with this plugin, please do not ask the Geyser developers — instead, please go to our Discord server which is linked above. ## Commands: | Command | Permission | Info | | ------- | -----------| ---- | -| `ghub` | `geyserhub.main` | Open the default server selector (The help page if console)| -| `ghub form` | `geyserhub.form` | Open a form/menu (The help page if console)| -| `ghub
` | `geyserhub.form.others` | Make someone else open a form/menu | | `ghub reload` | `geyserhub.reload` | Reload the configuration | +| `ghub help` | | View the help menu| ## Permissions: diff --git a/pom.xml b/pom.xml index df5e89e..d99e1d9 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ dev.projectg GeyserHub GeyserHub - 1.3.2 + 2.0.0 UTF-8 @@ -21,31 +21,12 @@ spigot-repo https://hub.spigotmc.org/nexus/content/repositories/snapshots/ - - opencollab-release-repo - https://repo.opencollab.dev/maven-releases/ - - true - - - false - - - - opencollab-snapshot-repo - https://repo.opencollab.dev/maven-snapshots/ - - false - - - true - - placeholderapi https://repo.extendedclip.com/content/repositories/placeholderapi/ + org.spigotmc @@ -53,25 +34,21 @@ 1.14.4-R0.1-SNAPSHOT provided - - org.geysermc.cumulus - api - 1.0-SNAPSHOT - provided - - - org.geysermc.floodgate - api - 2.1.0-SNAPSHOT - provided - me.clip placeholderapi 2.11.1 provided + + + com.google.code.findbugs + jsr305 + 3.0.2 + provided + + diff --git a/src/main/java/dev/projectg/geyserhub/GeyserHubMain.java b/src/main/java/dev/projectg/geyserhub/GeyserHub.java similarity index 63% rename from src/main/java/dev/projectg/geyserhub/GeyserHubMain.java rename to src/main/java/dev/projectg/geyserhub/GeyserHub.java index b7121bb..59dddd8 100644 --- a/src/main/java/dev/projectg/geyserhub/GeyserHubMain.java +++ b/src/main/java/dev/projectg/geyserhub/GeyserHub.java @@ -1,17 +1,8 @@ package dev.projectg.geyserhub; -import dev.projectg.geyserhub.command.GeyserHubCommand; import dev.projectg.geyserhub.config.ConfigManager; -import dev.projectg.geyserhub.module.menu.AccessItemRegistry; -import dev.projectg.geyserhub.module.menu.InventoryManager; -import dev.projectg.geyserhub.module.menu.java.JavaMenuListeners; -import dev.projectg.geyserhub.module.menu.bedrock.BedrockFormRegistry; -import dev.projectg.geyserhub.module.menu.java.JavaMenuRegistry; -import dev.projectg.geyserhub.module.message.Broadcast; -import dev.projectg.geyserhub.module.message.MessageJoin; -import dev.projectg.geyserhub.module.scoreboard.ScoreboardManager; -import dev.projectg.geyserhub.module.teleporter.JoinTeleporter; -import dev.projectg.geyserhub.module.world.WorldSettings; +import dev.projectg.geyserhub.message.Broadcast; +import dev.projectg.geyserhub.message.MessageJoin; import dev.projectg.geyserhub.utils.FileUtils; import dev.projectg.geyserhub.utils.bstats.Metrics; import org.bukkit.Bukkit; @@ -21,8 +12,8 @@ import java.util.Objects; import java.util.Properties; -public class GeyserHubMain extends JavaPlugin { - private static GeyserHubMain plugin; +public class GeyserHub extends JavaPlugin { + private static GeyserHub plugin; private ConfigManager configManager; @@ -31,7 +22,7 @@ public void onEnable() { long start = System.currentTimeMillis(); plugin = this; // getting the logger forces the config to load before our loadConfiguration() is called... - SelectorLogger logger = SelectorLogger.getLogger(); + Logger logger = Logger.getLogger(); try { Properties gitProperties = new Properties(); @@ -55,24 +46,9 @@ public void onEnable() { // Bungee channel for selector getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); - // Load forms - AccessItemRegistry accessItemRegistry = new AccessItemRegistry(); - BedrockFormRegistry bedrockFormRegistry = new BedrockFormRegistry(); - JavaMenuRegistry javaMenuRegistry = new JavaMenuRegistry(); + Objects.requireNonNull(getCommand("ghub")).setExecutor(new GeyserHubCommand()); - // todo: and add command suggestions/completions, help pages that only shows available commands - Objects.requireNonNull(getCommand("ghub")).setExecutor(new GeyserHubCommand(bedrockFormRegistry, javaMenuRegistry)); - - // todo: sort all of this, and make checking for enable value in config consistent - - // Listeners for the Bedrock and Java menus - Bukkit.getServer().getPluginManager().registerEvents(new InventoryManager(accessItemRegistry, bedrockFormRegistry, javaMenuRegistry), this); - Bukkit.getServer().getPluginManager().registerEvents(new JavaMenuListeners(javaMenuRegistry), this); - - // Listener the Join Teleporter module Bukkit.getServer().getPluginManager().registerEvents(new JoinTeleporter(), this); - - // Listener for world settings Bukkit.getServer().getPluginManager().registerEvents(new WorldSettings(), this); // load the scoreboard if enabled @@ -105,7 +81,7 @@ public void initializeScoreboard() { }, 20L, ScoreboardManager.REFRESH_RATE * 20L); } - public static GeyserHubMain getInstance() { + public static GeyserHub getInstance() { return plugin; } diff --git a/src/main/java/dev/projectg/geyserhub/GeyserHubCommand.java b/src/main/java/dev/projectg/geyserhub/GeyserHubCommand.java new file mode 100644 index 0000000..98d21c6 --- /dev/null +++ b/src/main/java/dev/projectg/geyserhub/GeyserHubCommand.java @@ -0,0 +1,83 @@ +package dev.projectg.geyserhub; + +import com.google.common.collect.ImmutableMap; +import dev.projectg.geyserhub.reloadable.ReloadableRegistry; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.Nonnull; +import java.util.Map; +import java.util.Objects; + +public class GeyserHubCommand implements CommandExecutor { + + private static final Map LOGGER_COLORS = ImmutableMap.of( + Logger.Level.INFO, ChatColor.RESET, + Logger.Level.WARN, ChatColor.GOLD, + Logger.Level.SEVERE, ChatColor.RED); + + private static final String[] HELP = { + "/ghub - Opens the default form if one exists. If not, shows the help page", + "/ghub - Opens the help page", + "/ghub form - Open a form with the defined name", + "/ghub form - Sends a form to a given player", + "/ghub reload - reloads the selector" + }; + + private static final String NO_PERMISSION = "Sorry, you don't have permission to run that command!"; + private static final String UNKNOWN = "Sorry, that's an unknown command!"; + + @Override + public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String[] args) { + if (!(commandSender instanceof Player || commandSender instanceof ConsoleCommandSender)) { + return false; + } + // todo: cleanup + if (args.length == 0) { + sendHelp(commandSender); + return true; + } + + // At least one arg + switch (args[0]) { + case "reload": + if (commandSender.hasPermission("geyserhub.reload")) { + if (!ReloadableRegistry.reloadAll()) { + sendMessage(commandSender, Logger.Level.SEVERE, "There was an error reloading something! Please check the server console for further information."); + } + } else { + sendMessage(commandSender, Logger.Level.SEVERE, NO_PERMISSION); + } + break; + case "help": + sendHelp(commandSender); + break; + default: + sendMessage(commandSender, Logger.Level.SEVERE, UNKNOWN); + break; + } + return true; + } + + private void sendHelp(CommandSender commandSender) { + // todo: only show players with the given permissions certain entries? not sure if it can be integrated any way into spigot command completions + commandSender.sendMessage(HELP); + } + + public static void sendMessage(@Nonnull CommandSender sender, @Nonnull Logger.Level level, @Nonnull String message) { + Objects.requireNonNull(sender); + Objects.requireNonNull(level); + Objects.requireNonNull(message); + + if (sender instanceof ConsoleCommandSender) { + Logger.getLogger().log(level, message); + } else { + sender.sendMessage("[GeyserHub] " + LOGGER_COLORS.getOrDefault(level, ChatColor.RESET) + message); + } + } +} diff --git a/src/main/java/dev/projectg/geyserhub/module/teleporter/JoinTeleporter.java b/src/main/java/dev/projectg/geyserhub/JoinTeleporter.java similarity index 89% rename from src/main/java/dev/projectg/geyserhub/module/teleporter/JoinTeleporter.java rename to src/main/java/dev/projectg/geyserhub/JoinTeleporter.java index 9a6ba4a..85016cb 100644 --- a/src/main/java/dev/projectg/geyserhub/module/teleporter/JoinTeleporter.java +++ b/src/main/java/dev/projectg/geyserhub/JoinTeleporter.java @@ -1,10 +1,8 @@ -package dev.projectg.geyserhub.module.teleporter; +package dev.projectg.geyserhub; -import dev.projectg.geyserhub.GeyserHubMain; import dev.projectg.geyserhub.config.ConfigId; import dev.projectg.geyserhub.reloadable.Reloadable; import dev.projectg.geyserhub.reloadable.ReloadableRegistry; -import dev.projectg.geyserhub.SelectorLogger; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; @@ -26,7 +24,7 @@ public class JoinTeleporter implements Listener, Reloadable { private Location location; public JoinTeleporter() { - FileConfiguration config = GeyserHubMain.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); + FileConfiguration config = GeyserHub.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); ReloadableRegistry.registerReloadable(this); enabled = load(config); } @@ -44,7 +42,7 @@ public void onPlayerJoin(PlayerJoinEvent event) { * @return false if there was an error loading or if its disabled in the config */ private boolean load(@Nonnull FileConfiguration config) { - SelectorLogger logger = SelectorLogger.getLogger(); + Logger logger = Logger.getLogger(); if (!config.contains("Join-Teleporter", true) || !config.isConfigurationSection("Join-Teleporter")) { logger.warn("Configuration does not contain Join-Teleporter section, skipping module."); @@ -71,7 +69,7 @@ private boolean load(@Nonnull FileConfiguration config) { * @return false if there was an error setting the location */ private boolean setLocation(@Nonnull ConfigurationSection section) { - SelectorLogger logger = SelectorLogger.getLogger(); + Logger logger = Logger.getLogger(); if (!(section.contains("World", true) && section.isString("World"))) { logger.severe("Join-Teleporter config section does not contain a valid World string, skipping module!"); @@ -108,7 +106,7 @@ private boolean setLocation(@Nonnull ConfigurationSection section) { @Override public boolean reload() { - enabled = load(GeyserHubMain.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN)); + enabled = load(GeyserHub.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN)); return true; } } diff --git a/src/main/java/dev/projectg/geyserhub/SelectorLogger.java b/src/main/java/dev/projectg/geyserhub/Logger.java similarity index 83% rename from src/main/java/dev/projectg/geyserhub/SelectorLogger.java rename to src/main/java/dev/projectg/geyserhub/Logger.java index 6c9ffb2..960f5d9 100644 --- a/src/main/java/dev/projectg/geyserhub/SelectorLogger.java +++ b/src/main/java/dev/projectg/geyserhub/Logger.java @@ -3,18 +3,18 @@ import dev.projectg.geyserhub.reloadable.Reloadable; import dev.projectg.geyserhub.reloadable.ReloadableRegistry; -public class SelectorLogger implements Reloadable { +public class Logger implements Reloadable { - private static final SelectorLogger LOGGER = new SelectorLogger(GeyserHubMain.getInstance()); + private static final Logger LOGGER = new Logger(GeyserHub.getInstance()); - private final GeyserHubMain plugin; + private final GeyserHub plugin; private boolean debug; - public static SelectorLogger getLogger() { + public static Logger getLogger() { return LOGGER; } - private SelectorLogger(GeyserHubMain plugin) { + private Logger(GeyserHub plugin) { this.plugin = plugin; debug = plugin.getConfig().getBoolean("Enable-Debug", false); ReloadableRegistry.registerReloadable(this); diff --git a/src/main/java/dev/projectg/geyserhub/module/scoreboard/ScoreboardManager.java b/src/main/java/dev/projectg/geyserhub/ScoreboardManager.java similarity index 78% rename from src/main/java/dev/projectg/geyserhub/module/scoreboard/ScoreboardManager.java rename to src/main/java/dev/projectg/geyserhub/ScoreboardManager.java index fa2a26e..a35ff84 100644 --- a/src/main/java/dev/projectg/geyserhub/module/scoreboard/ScoreboardManager.java +++ b/src/main/java/dev/projectg/geyserhub/ScoreboardManager.java @@ -1,6 +1,5 @@ -package dev.projectg.geyserhub.module.scoreboard; +package dev.projectg.geyserhub; -import dev.projectg.geyserhub.GeyserHubMain; import dev.projectg.geyserhub.config.ConfigId; import dev.projectg.geyserhub.utils.PlaceholderUtils; import org.bukkit.Bukkit; @@ -14,7 +13,7 @@ public class ScoreboardManager { - public static final int REFRESH_RATE = GeyserHubMain.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN).getInt("Scoreboard.Refresh-rate"); + public static final int REFRESH_RATE = GeyserHub.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN).getInt("Scoreboard.Refresh-rate"); public static void addScoreboard() { @@ -24,7 +23,7 @@ public static void addScoreboard() { } public static void createScoreboard(Player player) { - FileConfiguration config = GeyserHubMain.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); + FileConfiguration config = GeyserHub.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); Scoreboard board = Objects.requireNonNull(Bukkit.getServer().getScoreboardManager()).getNewScoreboard(); Objective objective = board.registerNewObjective("GeyserHub", "dummy", PlaceholderUtils.setPlaceholders(player, config.getString("Scoreboard.Title", "GeyserHub"))); diff --git a/src/main/java/dev/projectg/geyserhub/module/world/WorldSettings.java b/src/main/java/dev/projectg/geyserhub/WorldSettings.java similarity index 77% rename from src/main/java/dev/projectg/geyserhub/module/world/WorldSettings.java rename to src/main/java/dev/projectg/geyserhub/WorldSettings.java index 41cd72c..7de35a5 100644 --- a/src/main/java/dev/projectg/geyserhub/module/world/WorldSettings.java +++ b/src/main/java/dev/projectg/geyserhub/WorldSettings.java @@ -1,6 +1,5 @@ -package dev.projectg.geyserhub.module.world; +package dev.projectg.geyserhub; -import dev.projectg.geyserhub.GeyserHubMain; import dev.projectg.geyserhub.config.ConfigId; import org.bukkit.Material; import org.bukkit.configuration.file.FileConfiguration; @@ -20,7 +19,7 @@ public class WorldSettings implements Listener { @EventHandler public void onEntityDamage(EntityDamageEvent event) { - FileConfiguration config = GeyserHubMain.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); + FileConfiguration config = GeyserHub.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); if (!(event.getEntity() instanceof Player)) { return; } @@ -42,7 +41,7 @@ else if (config.getBoolean("World-settings.disable-fire-damage") @EventHandler(priority = EventPriority.HIGH) public void onFoodChange(FoodLevelChangeEvent event) { - FileConfiguration config = GeyserHubMain.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); + FileConfiguration config = GeyserHub.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); if (!config.getBoolean("World-settings.disable-hunger-loss")) return; if (!(event.getEntity() instanceof Player)) @@ -52,7 +51,7 @@ public void onFoodChange(FoodLevelChangeEvent event) { @EventHandler public void onFireSpread(BlockIgniteEvent event) { - FileConfiguration config = GeyserHubMain.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); + FileConfiguration config = GeyserHub.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); if (!config.getBoolean("World-settings.disable-block-fire-spread")) return; if (event.getCause() == BlockIgniteEvent.IgniteCause.SPREAD) @@ -61,7 +60,7 @@ public void onFireSpread(BlockIgniteEvent event) { @EventHandler public void onBlockBurn(BlockBurnEvent event) { - FileConfiguration config = GeyserHubMain.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); + FileConfiguration config = GeyserHub.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); if (!config.getBoolean("World-settings.disable-disable-block-burn")) return; event.setCancelled(true); @@ -69,7 +68,7 @@ public void onBlockBurn(BlockBurnEvent event) { @EventHandler(priority = EventPriority.HIGH) public void onLeafDecay(LeavesDecayEvent event) { - FileConfiguration config = GeyserHubMain.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); + FileConfiguration config = GeyserHub.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); if (!config.getBoolean("World-settings.disable_block-leaf-decay")) return; event.setCancelled(true); @@ -77,7 +76,7 @@ public void onLeafDecay(LeavesDecayEvent event) { @EventHandler(priority = EventPriority.HIGH) public void onCreatureSpawn(CreatureSpawnEvent event) { - FileConfiguration config = GeyserHubMain.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); + FileConfiguration config = GeyserHub.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); if (!config.getBoolean("World-settings.disable-mob-spawning")) return; if (event.getSpawnReason() == CreatureSpawnEvent.SpawnReason.CUSTOM) return; @@ -86,7 +85,7 @@ public void onCreatureSpawn(CreatureSpawnEvent event) { @EventHandler(priority = EventPriority.HIGH) public void onWeatherChange(WeatherChangeEvent event) { - FileConfiguration config = GeyserHubMain.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); + FileConfiguration config = GeyserHub.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); if (!config.getBoolean("World-settings.disable-weather-change")) return; @@ -95,16 +94,16 @@ public void onWeatherChange(WeatherChangeEvent event) { @EventHandler(priority = EventPriority.HIGH) public void onEntityDamage(EntityDamageByEntityEvent event) { - FileConfiguration config = GeyserHubMain.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); + FileConfiguration config = GeyserHub.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); if (!config.getBoolean("World-settings.disable-player-pvp")) return; if (!(event.getEntity() instanceof Player)) return; event.setCancelled(true); - } + @EventHandler(priority = EventPriority.HIGH) public void onBlockBreak(BlockBreakEvent event) { - FileConfiguration config = GeyserHubMain.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); + FileConfiguration config = GeyserHub.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); if (!config.getBoolean("World-settings.disable-block-break") || event.isCancelled()) return; @@ -114,12 +113,11 @@ public void onBlockBreak(BlockBreakEvent event) { } player.sendMessage("You can't break blocks here!"); event.setCancelled(true); - } @EventHandler(priority = EventPriority.HIGH) public void onBlockPlace(BlockPlaceEvent event) { - FileConfiguration config = GeyserHubMain.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); + FileConfiguration config = GeyserHub.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); if (!config.getBoolean("World-settings.disable-block-place") || event.isCancelled()) return; diff --git a/src/main/java/dev/projectg/geyserhub/command/GeyserHubCommand.java b/src/main/java/dev/projectg/geyserhub/command/GeyserHubCommand.java deleted file mode 100644 index bc08f25..0000000 --- a/src/main/java/dev/projectg/geyserhub/command/GeyserHubCommand.java +++ /dev/null @@ -1,135 +0,0 @@ -package dev.projectg.geyserhub.command; - -import com.google.common.collect.ImmutableMap; -import dev.projectg.geyserhub.SelectorLogger; -import dev.projectg.geyserhub.module.menu.MenuUtils; -import dev.projectg.geyserhub.module.menu.java.JavaMenuRegistry; -import dev.projectg.geyserhub.reloadable.ReloadableRegistry; -import dev.projectg.geyserhub.module.menu.bedrock.BedrockFormRegistry; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.command.ConsoleCommandSender; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; - -import javax.annotation.Nonnull; -import java.util.Map; -import java.util.Objects; - -public class GeyserHubCommand implements CommandExecutor { - - private static final Map LOGGER_COLORS = ImmutableMap.of( - SelectorLogger.Level.INFO, ChatColor.RESET, - SelectorLogger.Level.WARN, ChatColor.GOLD, - SelectorLogger.Level.SEVERE, ChatColor.RED); - - private static final String[] HELP = { - "/ghub - Opens the default form if one exists. If not, shows the help page", - "/ghub - Opens the help page", - "/ghub form - Open a form with the defined name", - "/ghub form - Sends a form to a given player", - "/ghub reload - reloads the selector" - }; - - private static final String NO_PERMISSION = "Sorry, you don't have permission to run that command!"; - private static final String UNKNOWN = "Sorry, that's an unknown command!"; - - private final BedrockFormRegistry bedrockFormRegistry; - private final JavaMenuRegistry javaMenuRegistry; - - public GeyserHubCommand(BedrockFormRegistry bedrockFormRegistry, JavaMenuRegistry javaMenuRegistry) { - this.bedrockFormRegistry = bedrockFormRegistry; - this.javaMenuRegistry = javaMenuRegistry; - } - - @Override - public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String[] args) { - if (!(commandSender instanceof Player || commandSender instanceof ConsoleCommandSender)) { - return false; - } - // todo: cleanup - if (args.length == 0) { - // send the default form, help if console - sendForm(commandSender, BedrockFormRegistry.DEFAULT); - return true; - } - - // At least one arg - switch (args[0]) { - case "reload": - if (commandSender.hasPermission("geyserhub.reload")) { - if (!ReloadableRegistry.reloadAll()) { - sendMessage(commandSender, SelectorLogger.Level.SEVERE, "There was an error reloading something! Please check the server console for further information."); - } - } else { - sendMessage(commandSender, SelectorLogger.Level.SEVERE, NO_PERMISSION); - } - break; - case "help": - sendHelp(commandSender); - break; - case "form": - if (commandSender.hasPermission("geyserhub.form")) { - if (args.length == 1) { - sendMessage(commandSender, SelectorLogger.Level.SEVERE, "Please specify a form to open! Specify a form with \"/ghub form \""); - } else if (args.length == 2) { - sendForm(commandSender, args[1]); - } else if (args.length == 3) { - if (commandSender.hasPermission("geyserhub.form.others")) { - Player target = Bukkit.getServer().getPlayer(args[2]); - if (target == null) { - sendMessage(commandSender, SelectorLogger.Level.SEVERE, "That player doesn't exist!"); - } else { - sendForm(target, args[1]); - sendMessage(commandSender, SelectorLogger.Level.INFO, "Made " + target.getName() + " open form: " + args[1]); - } - } else { - sendMessage(commandSender, SelectorLogger.Level.SEVERE, NO_PERMISSION); - } - } else { - sendMessage(commandSender, SelectorLogger.Level.SEVERE, "Too many command arguments!"); - } - } else { - sendMessage(commandSender, SelectorLogger.Level.SEVERE, NO_PERMISSION); - } - break; - default: - sendMessage(commandSender, SelectorLogger.Level.SEVERE, UNKNOWN); - break; - } - return true; - } - - private void sendHelp(CommandSender commandSender) { - // todo: only show players with the given permissions certain entries? not sure if it can be integrated any way into spigot command completions - commandSender.sendMessage(HELP); - } - - /** - * send a form to a command sender. if the commandsender is a console then it will just send the help page. - * @param commandSender the command sender. - * @param formName the form name to send - */ - private void sendForm(@Nonnull CommandSender commandSender, @Nonnull String formName) { - if (commandSender instanceof Player) { - MenuUtils.sendForm((Player) commandSender, bedrockFormRegistry, javaMenuRegistry, formName); - } else if (commandSender instanceof ConsoleCommandSender) { - sendHelp(commandSender); - } - } - - public static void sendMessage(@Nonnull CommandSender sender, @Nonnull SelectorLogger.Level level, @Nonnull String message) { - Objects.requireNonNull(sender); - Objects.requireNonNull(level); - Objects.requireNonNull(message); - - if (sender instanceof ConsoleCommandSender) { - SelectorLogger.getLogger().log(level, message); - } else { - sender.sendMessage("[GeyserHub] " + LOGGER_COLORS.getOrDefault(level, ChatColor.RESET) + message); - } - } -} diff --git a/src/main/java/dev/projectg/geyserhub/config/ConfigId.java b/src/main/java/dev/projectg/geyserhub/config/ConfigId.java index 24d8ffb..18b368b 100644 --- a/src/main/java/dev/projectg/geyserhub/config/ConfigId.java +++ b/src/main/java/dev/projectg/geyserhub/config/ConfigId.java @@ -4,8 +4,7 @@ * An enum containing the identities of all valid configuration files. */ public enum ConfigId { - MAIN("config.yml", 6), - SELECTOR("selector.yml", 2); + MAIN("config.yml", 6); public static final ConfigId[] VALUES = values(); diff --git a/src/main/java/dev/projectg/geyserhub/config/ConfigManager.java b/src/main/java/dev/projectg/geyserhub/config/ConfigManager.java index 232f92b..5f3b3ee 100644 --- a/src/main/java/dev/projectg/geyserhub/config/ConfigManager.java +++ b/src/main/java/dev/projectg/geyserhub/config/ConfigManager.java @@ -1,10 +1,9 @@ package dev.projectg.geyserhub.config; -import dev.projectg.geyserhub.GeyserHubMain; -import dev.projectg.geyserhub.SelectorLogger; +import dev.projectg.geyserhub.GeyserHub; +import dev.projectg.geyserhub.Logger; import dev.projectg.geyserhub.config.updaters.MAIN_4; import dev.projectg.geyserhub.config.updaters.MAIN_5; -import dev.projectg.geyserhub.config.updaters.SELECTOR_1; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.FileConfiguration; @@ -27,13 +26,12 @@ public class ConfigManager { mainUpdaters.put(4, MAIN_4.class); mainUpdaters.put(5, MAIN_5.class); - updaters.put(ConfigId.SELECTOR, Collections.singletonMap(1, SELECTOR_1.class)); updaters.put(ConfigId.MAIN, mainUpdaters); } private final Map configurations = new HashMap<>(); - private final SelectorLogger logger; + private final Logger logger; public ConfigManager() { if (CONFIG_MANAGER == null) { @@ -42,7 +40,7 @@ public ConfigManager() { throw new UnsupportedOperationException("Only one instance of ConfigManager is allowed!"); } - this.logger = SelectorLogger.getLogger(); + this.logger = Logger.getLogger(); } /** @@ -66,7 +64,7 @@ public boolean loadAllConfigs() { * @return The success state */ public boolean loadConfig(@Nonnull ConfigId config) { - GeyserHubMain plugin = GeyserHubMain.getInstance(); + GeyserHub plugin = GeyserHub.getInstance(); // Get the file File file = new File(plugin.getDataFolder(), config.fileName); diff --git a/src/main/java/dev/projectg/geyserhub/config/ConfigUpdater.java b/src/main/java/dev/projectg/geyserhub/config/ConfigUpdater.java index 3b698b0..af97975 100644 --- a/src/main/java/dev/projectg/geyserhub/config/ConfigUpdater.java +++ b/src/main/java/dev/projectg/geyserhub/config/ConfigUpdater.java @@ -5,6 +5,7 @@ /** * All implementing classes must have a zero-argument constructor. */ +@FunctionalInterface public interface ConfigUpdater { /** diff --git a/src/main/java/dev/projectg/geyserhub/config/updaters/SELECTOR_1.java b/src/main/java/dev/projectg/geyserhub/config/updaters/SELECTOR_1.java deleted file mode 100644 index c229e55..0000000 --- a/src/main/java/dev/projectg/geyserhub/config/updaters/SELECTOR_1.java +++ /dev/null @@ -1,50 +0,0 @@ -package dev.projectg.geyserhub.config.updaters; - -import dev.projectg.geyserhub.config.ConfigManager; -import dev.projectg.geyserhub.config.ConfigUpdater; -import org.bukkit.configuration.ConfigurationSection; - -import java.util.Map; -import java.util.Objects; - -public class SELECTOR_1 implements ConfigUpdater { - - @Override - public boolean update(ConfigurationSection config) throws IllegalArgumentException { - if (!config.contains("Config-Version", true) || config.getInt("Config-Version") != 1) { - throw new IllegalArgumentException("Config is not version 1"); - } - - if (!config.contains("Selector-Item", true) || !config.isConfigurationSection("Selector-Item")) { - throw new IllegalArgumentException("Config does not contain configuration section 'Selector-Item'"); - } - - // Get the mutable ConfigurationSection - ConfigurationSection items = config.getConfigurationSection("Selector-Item"); - Objects.requireNonNull(items); - // Remove it from the parent afterwards, since it must be renamed - config.set("Selector-Item", null); - - // A map containing the same information as the configuration section - Map defaultItem = ConfigManager.asMap(items); - defaultItem.put("Form", "default"); // new data - - // Clear the section - for (String key : items.getKeys(false)) { - // Remove the old single access item data - items.set(key, null); - } - - // Add the enable key and put the old single access item data in a subsection - items.set("Enable", true); // new data - items.createSection("Items.default", defaultItem); // re-insert the old data into the default access item - - // Add the Selector-Item section back in, under the new name - config.createSection("Access-Items", ConfigManager.asMap(items)); - - // bump version - config.set("Config-Version", 2); - - return true; - } -} diff --git a/src/main/java/dev/projectg/geyserhub/module/message/Broadcast.java b/src/main/java/dev/projectg/geyserhub/message/Broadcast.java similarity index 70% rename from src/main/java/dev/projectg/geyserhub/module/message/Broadcast.java rename to src/main/java/dev/projectg/geyserhub/message/Broadcast.java index ad828f2..0ac5c99 100644 --- a/src/main/java/dev/projectg/geyserhub/module/message/Broadcast.java +++ b/src/main/java/dev/projectg/geyserhub/message/Broadcast.java @@ -1,11 +1,10 @@ -package dev.projectg.geyserhub.module.message; +package dev.projectg.geyserhub.message; -import dev.projectg.geyserhub.GeyserHubMain; -import dev.projectg.geyserhub.SelectorLogger; +import dev.projectg.geyserhub.GeyserHub; +import dev.projectg.geyserhub.Logger; import dev.projectg.geyserhub.config.ConfigId; import dev.projectg.geyserhub.utils.PlaceholderUtils; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; @@ -15,13 +14,13 @@ public class Broadcast { public static void startBroadcastTimer(BukkitScheduler scheduler) { - FileConfiguration config = GeyserHubMain.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); - scheduler.scheduleSyncDelayedTask(GeyserHubMain.getInstance(), () -> { + FileConfiguration config = GeyserHub.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); + scheduler.scheduleSyncDelayedTask(GeyserHub.getInstance(), () -> { if (config.getBoolean("Broadcasts.Enable", false)) { ConfigurationSection parentSection = config.getConfigurationSection("Broadcasts.Messages"); if (parentSection == null) { - SelectorLogger.getLogger().severe("Broadcasts.Messages configuration section is malformed, unable to send."); + Logger.getLogger().severe("Broadcasts.Messages configuration section is malformed, unable to send."); return; } @@ -34,7 +33,7 @@ public static void startBroadcastTimer(BukkitScheduler scheduler) { } } } else { - SelectorLogger.getLogger().severe("Broadcast with ID " + broadcastId + " has a malformed message list, unable to send."); + Logger.getLogger().severe("Broadcast with ID " + broadcastId + " has a malformed message list, unable to send."); } } startBroadcastTimer(scheduler); diff --git a/src/main/java/dev/projectg/geyserhub/module/message/MessageJoin.java b/src/main/java/dev/projectg/geyserhub/message/MessageJoin.java similarity index 77% rename from src/main/java/dev/projectg/geyserhub/module/message/MessageJoin.java rename to src/main/java/dev/projectg/geyserhub/message/MessageJoin.java index d98ec0d..1384c95 100644 --- a/src/main/java/dev/projectg/geyserhub/module/message/MessageJoin.java +++ b/src/main/java/dev/projectg/geyserhub/message/MessageJoin.java @@ -1,6 +1,6 @@ -package dev.projectg.geyserhub.module.message; +package dev.projectg.geyserhub.message; -import dev.projectg.geyserhub.GeyserHubMain; +import dev.projectg.geyserhub.GeyserHub; import dev.projectg.geyserhub.config.ConfigId; import dev.projectg.geyserhub.utils.PlaceholderUtils; import org.bukkit.configuration.file.FileConfiguration; @@ -15,7 +15,7 @@ public class MessageJoin implements Listener { @EventHandler public void onJoin(PlayerJoinEvent e) { - FileConfiguration config = GeyserHubMain.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); + FileConfiguration config = GeyserHub.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); Player player = e.getPlayer(); List messages = config.getStringList("Join-Message.Messages"); diff --git a/src/main/java/dev/projectg/geyserhub/module/menu/AccessItem.java b/src/main/java/dev/projectg/geyserhub/module/menu/AccessItem.java deleted file mode 100644 index 8afa9d7..0000000 --- a/src/main/java/dev/projectg/geyserhub/module/menu/AccessItem.java +++ /dev/null @@ -1,132 +0,0 @@ -package dev.projectg.geyserhub.module.menu; - -import dev.projectg.geyserhub.GeyserHubMain; -import dev.projectg.geyserhub.utils.PlaceholderUtils; -import org.bukkit.Material; -import org.bukkit.NamespacedKey; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.persistence.PersistentDataType; - -import javax.annotation.Nonnull; -import java.util.List; -import java.util.Objects; - -public class AccessItem { - - /** - * A key that should be of type {@link #ACCESS_ITEM_KEY_TYPE}, with the value being the {@link #itemId} - */ - public static final NamespacedKey ACCESS_ITEM_KEY = new NamespacedKey(GeyserHubMain.getInstance(), "geyserHubAccessItem"); - public static final PersistentDataType ACCESS_ITEM_KEY_TYPE = PersistentDataType.STRING; - - /** - * The id of the access item. - */ - public final String itemId; - - /** - * The hotbar slot for the item to be, by default. - * Should be placed elsewhere in the hotbar if not possible. - * Should not be given if the hotbar is full. - */ - public final int slot; - - private final String displayName; - private final Material material; - private final List lore; - - /** - * True for players to receive it when they join - */ - public final boolean onJoin; - - /** - * True for players to receive it when they respawn - */ - public final boolean onRespawn; - - /** - * True for players to be able to drop the item - */ - public final boolean allowDrop; - - /** - * True for the item to be destroyed when dropped - */ - public final boolean destroyDropped; - - /** - * True for players to be able to move the item - */ - public final boolean allowMove; - - /** - * The form/menu name to open. - */ - public final String formName; - - /** - * Immutable Access Item to open a form. - * @param itemId The ID of the form (the parent key in the config, generally) - * @param slot The slot of the inventory this should be put in by default - * @param displayName The Display Name of the ItemStack, supports placeholders. - * @param material The material for the ItemStack to be - * @param lore The lore for the ItemStack - * @param onJoin True for players to receive it when they join - * @param onRespawn True for players to receive it when they respawn (excluding server join) - * @param allowDrop True for players to be able to drop the item - * @param destroyDropped True for the item to be destroyed when dropped - * @param allowMove True for players to be able to move the item - * @param formName The form/menu name to open. - */ - public AccessItem(@Nonnull String itemId, int slot, @Nonnull String displayName, @Nonnull Material material, @Nonnull List lore, - boolean onJoin, boolean onRespawn, boolean allowDrop, boolean destroyDropped, boolean allowMove, - @Nonnull String formName) { - Objects.requireNonNull(material); - if (new ItemStack(material).getItemMeta() == null) { - throw new IllegalArgumentException("Cannot create an access item with a Material that results in an ItemStack with null ItemMeta!"); - } - this.itemId = Objects.requireNonNull(itemId); - this.slot = slot; - this.displayName = Objects.requireNonNull(displayName); - this.material = material; - this.lore = Objects.requireNonNull(lore); - - this.onJoin = onJoin; - this.onRespawn = onRespawn; - this.allowDrop = allowDrop; - this.destroyDropped = destroyDropped; - this.allowMove = allowMove; - - this.formName = formName; - } - - private ItemStack createItemStack(@Nonnull String displayName, @Nonnull Material material, @Nonnull List lore) { - ItemStack item = new ItemStack(material); - ItemMeta meta = Objects.requireNonNull(item.getItemMeta()); - meta.setDisplayName(displayName); - meta.setLore(lore); - meta.getPersistentDataContainer().set(ACCESS_ITEM_KEY, ACCESS_ITEM_KEY_TYPE, itemId); - item.setItemMeta(meta); - return item; - } - - /** - * @return The ItemStack of the access item, with no placeholders set. - */ - public ItemStack getItemStack() { - return createItemStack(displayName, material, lore); - } - - /** - * @param player The player to apply to placeholders - * @return The ItemStack of the access item, with placeholders in the display name and lore set according to the given player - */ - public ItemStack getItemStack(@Nonnull Player player) { - String displayName = PlaceholderUtils.setPlaceholders(player, this.displayName); - List lore = PlaceholderUtils.setPlaceholders(player, this.lore); - return createItemStack(displayName, material, lore); - } -} diff --git a/src/main/java/dev/projectg/geyserhub/module/menu/AccessItemRegistry.java b/src/main/java/dev/projectg/geyserhub/module/menu/AccessItemRegistry.java deleted file mode 100644 index a536945..0000000 --- a/src/main/java/dev/projectg/geyserhub/module/menu/AccessItemRegistry.java +++ /dev/null @@ -1,183 +0,0 @@ -package dev.projectg.geyserhub.module.menu; - - -import dev.projectg.geyserhub.GeyserHubMain; -import dev.projectg.geyserhub.SelectorLogger; -import dev.projectg.geyserhub.config.ConfigId; -import dev.projectg.geyserhub.reloadable.Reloadable; -import dev.projectg.geyserhub.reloadable.ReloadableRegistry; -import org.bukkit.Material; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.*; - -public class AccessItemRegistry implements Reloadable { - - private boolean isEnabled = false; - private final Map items = new HashMap<>(); - - public AccessItemRegistry() { - load(); - ReloadableRegistry.registerReloadable(this); - } - - /** - * Adds access items in {@link this#items} from {@link ConfigId#SELECTOR}. - * Does not clear existing items. - */ - private void load() { - SelectorLogger logger = SelectorLogger.getLogger(); - - FileConfiguration selectorConfig = GeyserHubMain.getInstance().getConfigManager().getFileConfiguration(ConfigId.SELECTOR); - if (!selectorConfig.contains("Access-Items") || !selectorConfig.isConfigurationSection("Access-Items")) { - logger.warn("Not creating any access items because selector.yml does not contain the Access-Items config!"); - return; - } - ConfigurationSection accessSection = Objects.requireNonNull(selectorConfig.getConfigurationSection("Access-Items")); - if (accessSection.contains("Enable") && accessSection.isBoolean("Enable")) { - if (!accessSection.getBoolean("Enable")) { - return; - } - } - if (!accessSection.contains("Items") || !accessSection.isConfigurationSection("Items")) { - logger.warn("Not creating any access items because Access-Items in selector.yml does not list any items!"); - return; - } - ConfigurationSection configItems = Objects.requireNonNull(accessSection.getConfigurationSection("Items")); - - for (String itemId : configItems.getKeys(false)) { - if (!configItems.isConfigurationSection(itemId)) { - continue; - } - ConfigurationSection itemEntry = configItems.getConfigurationSection(itemId); - Objects.requireNonNull(itemEntry); - - // Get the material - Material material; - if (itemEntry.contains("Material", true)) { - String materialName = itemEntry.getString("Material"); - Objects.requireNonNull(materialName); - material = Material.getMaterial(materialName); - if (material == null) { - SelectorLogger.getLogger().warn("Failed to find a Material for '" + materialName + "' for access item: " + itemId + ". Defaulting to COMPASS for the access item."); - material = Material.COMPASS; - } - } else { - SelectorLogger.getLogger().warn("Failed to find Access-Items. " + itemId + ".Material in the config! Defaulting to COMPASS."); - material = Material.COMPASS; - } - - // Create a new item with the material, get the meta - ItemStack item = new ItemStack(material); - ItemMeta meta = item.getItemMeta(); - if (meta == null) { - logger.warn("Failed to create access item " + itemId + " with Material " + material + " because the ItemMeta returned null."); - continue; - } - - // Set the display name in the meta - String name; - if (itemEntry.contains("Name", true)) { - name = itemEntry.getString("Name"); - Objects.requireNonNull(name); - } else { - SelectorLogger.getLogger().warn("Failed to find Access-Items. " + itemId + ".Name in the config! Defaulting to '§6Server Selector'."); - name = "§6Server Selector"; - } - meta.setDisplayName(name); - - // Set the lore in the meta - List lore; - if (itemEntry.contains("Lore", true) && itemEntry.isList("Lore")) { - lore = itemEntry.getStringList("Lore"); - } else { - lore = Collections.emptyList(); - } - meta.setLore(lore); - - // Set the meta and set the field - item.setItemMeta(meta); - - if (!itemEntry.contains("Form") || !itemEntry.isString("Form")) { - logger.warn("Access item: " + itemId + " does not contain a form! Not registering the item."); - continue; - } - String formName = Objects.requireNonNull(itemEntry.getString("Form")); - - if (itemEntry.contains("Slot", true) && itemEntry.isInt("Slot")) { - int slot = Math.abs(itemEntry.getInt("Slot")); - items.put(itemId, new AccessItem(itemId, - slot, - name, - material, - lore, - itemEntry.getBoolean("Join", true), - itemEntry.getBoolean("Respawn", true), - itemEntry.getBoolean("Allow-Drop", false), - itemEntry.getBoolean("Destroy-Dropped", true), - itemEntry.getBoolean("Allow-Move", false), - formName)); - - isEnabled = true; - } else { - logger.warn("Failed to create access item " + itemId + " because a Slot Integer value wasn't given."); - } - } - } - - @Override - public boolean reload() { - items.clear(); - load(); - return true; - } - - public boolean isEnabled() { - return isEnabled; - } - - /** - * Get all the Access Items - * @return A map whose keys are the identifiers of the access items, and the values are the access items - */ - public HashMap getAccessItems() { - return new HashMap<>(items); - } - - /** - * Attempt to retrieve the Access Item that an ItemStack points to - * @param itemStack The ItemStack to check. If it contains null ItemMeta, this will return null. - * @return The Access Item if the ItemStack contained the identifier of the Access Item, and the Access Item exists. Will return null if their conditions are false. - */ - @Nullable - public AccessItem getAccessItem(@Nonnull ItemStack itemStack) { - String identifier = getAccessItemId(itemStack); - if (identifier == null) { - return null; - } else { - return items.get(identifier); - } - } - - /** - * Attempt to retrieve the Access Item ID that an ItemStack points to. The Access Item ID may or may not refer - * to an actual AccessItem - * @param itemStack The ItemStack to check - * @return The AccessItem ID if the ItemStack contained the name, null if not. - */ - @Nullable - public static String getAccessItemId(@Nonnull ItemStack itemStack) { - Objects.requireNonNull(itemStack); - ItemMeta meta = itemStack.getItemMeta(); - if (meta == null) { - return null; - } else { - return meta.getPersistentDataContainer().get(AccessItem.ACCESS_ITEM_KEY, AccessItem.ACCESS_ITEM_KEY_TYPE); - } - } -} diff --git a/src/main/java/dev/projectg/geyserhub/module/menu/InventoryManager.java b/src/main/java/dev/projectg/geyserhub/module/menu/InventoryManager.java deleted file mode 100644 index 8050ad0..0000000 --- a/src/main/java/dev/projectg/geyserhub/module/menu/InventoryManager.java +++ /dev/null @@ -1,196 +0,0 @@ -package dev.projectg.geyserhub.module.menu; - -import dev.projectg.geyserhub.module.menu.bedrock.BedrockFormRegistry; -import dev.projectg.geyserhub.module.menu.java.JavaMenuRegistry; -import org.bukkit.Material; -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.inventory.InventoryClickEvent; -import org.bukkit.event.player.PlayerDropItemEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerRespawnEvent; -import org.bukkit.event.player.PlayerSwapHandItemsEvent; -import org.bukkit.inventory.ItemStack; - -import java.util.function.Predicate; - -public class InventoryManager implements Listener { - - private final AccessItemRegistry accessItemRegistry; - private final BedrockFormRegistry bedrockFormRegistry; - private final JavaMenuRegistry javaMenuRegistry; - - public InventoryManager(AccessItemRegistry accessItemRegistry, BedrockFormRegistry bedrockFormRegistry, JavaMenuRegistry javaMenuRegistry) { - this.accessItemRegistry = accessItemRegistry; - this.bedrockFormRegistry = bedrockFormRegistry; - this.javaMenuRegistry = javaMenuRegistry; - } - - @EventHandler - public void onInteract(PlayerInteractEvent event) { // opening menus through access items - if (!accessItemRegistry.isEnabled()) { - return; - } - - if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) { - ItemStack item = event.getItem(); - if (item != null) { - AccessItem accessItem = accessItemRegistry.getAccessItem(item); - if (accessItem != null) { - event.setCancelled(true); // todo: what happens if we don't cancel this? does the chest open before or after ours? - - Player player = event.getPlayer(); - String formName = accessItem.formName; - MenuUtils.sendForm(player, bedrockFormRegistry, javaMenuRegistry, formName); - } - } - } - } - - @EventHandler - public void onInventoryClick(InventoryClickEvent event) { // keep the access items in place - if (!accessItemRegistry.isEnabled()) { - return; - } - - // todo: don't allow duplication for creative players - ItemStack item = event.getCurrentItem(); - if (item != null) { - AccessItem accessItem = accessItemRegistry.getAccessItem(item); - if (accessItem != null) { - event.setCancelled(!accessItem.allowMove); - } - } - } - - @EventHandler - public void PlayerSwapHandItemsEvent(PlayerSwapHandItemsEvent event) { - if (!accessItemRegistry.isEnabled()) { - return; - } - - ItemStack item = event.getOffHandItem(); - if (item != null) { - AccessItem access = accessItemRegistry.getAccessItem(item); - if (access != null) { - event.setCancelled(true); - } - } - } - - @EventHandler - public void onPlayerDropItem(PlayerDropItemEvent event) { // don't let the access item be dropped, destroy it if it is - if (!accessItemRegistry.isEnabled()) { - return; - } - - ItemStack item = event.getItemDrop().getItemStack(); - AccessItem accessItem = accessItemRegistry.getAccessItem(item); - if (accessItem != null) { - if (!accessItem.allowDrop) { - event.setCancelled(true); - } else if (accessItem.destroyDropped) { - event.getItemDrop().remove(); - } - } - } - - @EventHandler - public void onPlayerJoin(PlayerJoinEvent event) { // give the access item when the player joins - giveAccessItems(event.getPlayer(), accessItemRegistry, accessItem -> accessItem.onJoin); - } - - @EventHandler - public void onPlayerRespawn(PlayerRespawnEvent event) { // give the access item when the player respawns - giveAccessItems(event.getPlayer(), accessItemRegistry, accessItem -> accessItem.onRespawn); - } - - /** - * Remove all the access items from a player's inventory - * @param player The player whose inventory to remove from - */ - private static void removeAccessItems(Player player) { - // Remove any access items that are already in the inventory - for (ItemStack item : player.getInventory().getContents()) { - if (item != null) { - if (AccessItemRegistry.getAccessItemId(item) != null) { - // Even if this specific item/access item is no longer registered - // The fact it has the ID inside of it means it once was or still is - player.getInventory().remove(item); - } - } - } - } - - /** - * Clears all access items a player has, gives them all access items from a given registry - * @param player The player to give the access items to - * @param registry The registry to get access items from - * @param addItem Should test true if the access item should be added - */ - private static void giveAccessItems(Player player, AccessItemRegistry registry, Predicate addItem) { - if (!registry.isEnabled()) { - return; - } - - removeAccessItems(player); - - boolean holdItem = true; // True if the next access item should have be set as the held slot - for (AccessItem accessItem : registry.getAccessItems().values()) { - if (addItem.test(accessItem)) { - if (giveAccessItem(player, accessItem, holdItem)) { - // Only set the held item once - holdItem = false; - } - } - } - } - - /** - * Gives a player an access item - * @param player The player to give the access item to - * @param accessItem The access item to give - * @param setHeldSlot True if the player's selected item should be forced to the access item - * @return True if the access item was successfully given - */ - private static boolean giveAccessItem(Player player, AccessItem accessItem, boolean setHeldSlot) { - ItemStack accessItemStack = accessItem.getItemStack(player); // todo update placeholders after the fact. but when? - - int desiredSlot = accessItem.slot; - ItemStack oldItem = player.getInventory().getItem(desiredSlot); - boolean success = false; - if (oldItem == null || oldItem.getType() == Material.AIR) { - // put the item in the desired place - player.getInventory().setItem(desiredSlot, accessItemStack); - success = true; - } else { - for (int i = 0; i < 9; i++) { - // Try and find an empty slot - - ItemStack otherItem = player.getInventory().getItem(i); - if (otherItem == null || otherItem.getType() == Material.AIR) { - // slot is empty, move the item that is blocking us to it - player.getInventory().setItem(i, oldItem); - // put the access item in the slot that is no longer blocked - player.getInventory().setItem(desiredSlot, accessItemStack); - success = true; - break; - } - } - // If the player doesn't have the space in their hotbar then they don't get it - } - - if (success) { - if (setHeldSlot) { - // Set the held item to the slot of the access item - player.getInventory().setHeldItemSlot(accessItem.slot); - } - return true; - } else { - return false; - } - } -} diff --git a/src/main/java/dev/projectg/geyserhub/module/menu/MenuUtils.java b/src/main/java/dev/projectg/geyserhub/module/menu/MenuUtils.java deleted file mode 100644 index 12376a9..0000000 --- a/src/main/java/dev/projectg/geyserhub/module/menu/MenuUtils.java +++ /dev/null @@ -1,186 +0,0 @@ -package dev.projectg.geyserhub.module.menu; - -import dev.projectg.geyserhub.GeyserHubMain; -import dev.projectg.geyserhub.SelectorLogger; -import dev.projectg.geyserhub.config.ConfigId; -import dev.projectg.geyserhub.module.menu.bedrock.BedrockForm; -import dev.projectg.geyserhub.module.menu.bedrock.BedrockFormRegistry; -import dev.projectg.geyserhub.module.menu.java.JavaMenu; -import dev.projectg.geyserhub.module.menu.java.JavaMenuRegistry; -import dev.projectg.geyserhub.utils.PlaceholderUtils; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.command.CommandSender; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Player; -import org.geysermc.floodgate.api.FloodgateApi; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.Collections; -import java.util.List; -import java.util.Objects; - -public class MenuUtils { - - public static final String playerPrefix = "player;"; - public static final String consolePrefix = "console;"; - - /** - * Sends a given form, identified by its name, to a BE or JE player. - * If the form does not exist for their platform, they will be sent a message. - * If forms are disabled on their platform, they will be sent a message. - * @param player The {@link Player} to send the form to - * @param bedrockRegistry The registry to pull bedrock forms from - * @param javaMenuRegistry The registry to pull java inventory GUIs from - * @param formName The name of the form to open - */ - public static void sendForm(@Nonnull Player player, @Nonnull BedrockFormRegistry bedrockRegistry, @Nonnull JavaMenuRegistry javaMenuRegistry, @Nonnull String formName) { - if (FloodgateApi.getInstance().isFloodgatePlayer(player.getUniqueId())) { - if (bedrockRegistry.isEnabled()) { - BedrockForm form = bedrockRegistry.getMenu(formName); - if (form == null) { - player.sendMessage("[GeyserHub] " + ChatColor.RED + "Sorry, that form doesn't exist! Specify a form with '/ghub form '"); - } else { - form.sendForm(FloodgateApi.getInstance().getPlayer(player.getUniqueId())); - } - } else { - player.sendMessage("[GeyserHub] " + ChatColor.RED + "Sorry, Bedrock forms are disabled!"); - } - } else { - if (javaMenuRegistry.isEnabled()) { - JavaMenu menu = javaMenuRegistry.getMenu(formName); - if (menu == null) { - player.sendMessage("[GeyserHub] " + ChatColor.RED + "Sorry, that form doesn't exist! Specify a form with '/ghub form '"); - } else { - menu.sendMenu(player); - } - } else { - player.sendMessage("[GeyserHub] " + ChatColor.RED + "Sorry, Java menus are disabled!"); - } - } - - } - - /** - * @param commands Commands list, an empty list can be passed for no commands. - * @param serverName The server name, can passed as null for no server. - * @param player the Player to run everything on. - */ - public static void affectPlayer(@Nonnull List commands, @Nullable String serverName, @Nonnull Player player) { - Objects.requireNonNull(commands); - Objects.requireNonNull(player); - FileConfiguration config = GeyserHubMain.getInstance().getConfigManager().getFileConfiguration(ConfigId.MAIN); - if (!commands.isEmpty()) { - // Get the commands from the list of commands and replace any playerName placeholders - for (String command : commands) { - MenuUtils.runCommand(PlaceholderUtils.setPlaceholders(player, command), player); - } - } - - if (serverName != null) { - // This should never be out of bounds considering its size is the number of valid buttons - try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream out = new DataOutputStream(baos)) { - out.writeUTF("Connect"); - out.writeUTF(serverName); - player.sendPluginMessage(GeyserHubMain.getInstance(), "BungeeCord", baos.toByteArray()); - String message = config.getString("Bungeecord-Message", ""); - if (!message.isEmpty()) { - player.sendMessage(PlaceholderUtils.setPlaceholders(player, message).replace("%server%", serverName)); - } - } catch (IOException e) { - SelectorLogger.getLogger().severe("Failed to send a plugin message to Bungeecord!"); - e.printStackTrace(); - } - } - } - - /** - * Process a command and run it. - * If the command is prefixed with "player;" the command will be run as the player given, which CANNOT be null. - * If the command is prefixed with "console;" the command will be run as the console. - * - * @param command The command to run - * @param player the Player to run the command as, if prefixed with "player;" - */ - public static void runCommand(@Nonnull String command, @Nullable Player player) { - Objects.requireNonNull(command); - - // Run as console by default - CommandSender sender = Bukkit.getServer().getConsoleSender(); - if (command.startsWith(playerPrefix)) { - if (player == null) { - throw new IllegalArgumentException("The following command is denoted to be run by a player, but a null player was passed internally: " + command); - } else { - sender = player; - } - } - - String executableCommand; - if (command.startsWith(playerPrefix) || command.startsWith(consolePrefix)) { - // Split the input into two strings between ";" and get the second string - executableCommand = command.split(";", 2)[1].trim(); - } else { - executableCommand = command; - } - - SelectorLogger.getLogger().debug("Running command: [" + executableCommand + "] as " + sender.getName()); - Bukkit.getServer().dispatchCommand(sender, executableCommand); - } - - /** - * Gets the commands from a config section with a "Commands" string list. - * @param buttonData the config section with the string list - * @return the commands. will return an empty list in case of failure, or if the list was empty. - */ - @Nonnull - public static List getCommands(@Nonnull ConfigurationSection buttonData) { - Objects.requireNonNull(buttonData); - SelectorLogger logger = SelectorLogger.getLogger(); - - if (buttonData.contains("Commands", true) && buttonData.isList("Commands")) { - List commands = buttonData.getStringList("Commands"); - if (commands.isEmpty()) { - logger.warn(getParentName(buttonData) + "." + buttonData.getName() + " contains commands list but the list was empty."); - } else { - return commands; - } - } - return Collections.emptyList(); - } - - /** - * Get the server name from a button configuration section - * @param buttonData the config section - * @return the server name, null if there was no server - */ - @Nullable - public static String getServer(@Nonnull ConfigurationSection buttonData) { - Objects.requireNonNull(buttonData); - - if (buttonData.contains("Server", true) && buttonData.isString("Server")) { - return Objects.requireNonNull(buttonData.getString("Server")); - } - return null; - } - - /** - * Get the name of the parent of a config section - * @param configSection the config section - * @return the parent name, "null" if there was no parent, or if the the given configSection was null - */ - @Nonnull - public static String getParentName(@Nullable ConfigurationSection configSection) { - if (configSection != null) { - ConfigurationSection parent = configSection.getParent(); - if (parent != null) { - return parent.getName(); - } - } - return "null"; - } -} diff --git a/src/main/java/dev/projectg/geyserhub/module/menu/bedrock/BedrockButton.java b/src/main/java/dev/projectg/geyserhub/module/menu/bedrock/BedrockButton.java deleted file mode 100644 index aa9892a..0000000 --- a/src/main/java/dev/projectg/geyserhub/module/menu/bedrock/BedrockButton.java +++ /dev/null @@ -1,51 +0,0 @@ -package dev.projectg.geyserhub.module.menu.bedrock; - -import dev.projectg.geyserhub.module.menu.button.OutcomeButton; -import edu.umd.cs.findbugs.annotations.NonNull; -import org.geysermc.cumulus.component.ButtonComponent; -import org.geysermc.cumulus.util.FormImage; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -public class BedrockButton extends OutcomeButton { - - @Nullable private FormImage image; - - /** - * Create a button. - * @param text the text of the button - */ - public BedrockButton(@Nonnull String text) { - super(text); - } - - /** - * Copy constructor. - * @param button The button to make a copy of - */ - public BedrockButton(@Nonnull BedrockButton button) { - super(button); - this.image = button.image; - } - - /** - * Set the image of the button. - * @param image the image - */ - public void setImage(@Nullable FormImage image) { - this.image = image; - } - - public @Nullable FormImage getImage() { - return this.image; // Form image is immutable - } - - /** - * Get the button component based off the text and image off the Button. - * @return the button component - */ - public @NonNull ButtonComponent getButtonComponent() { - return ButtonComponent.of(getText(), getImage()); - } -} diff --git a/src/main/java/dev/projectg/geyserhub/module/menu/bedrock/BedrockForm.java b/src/main/java/dev/projectg/geyserhub/module/menu/bedrock/BedrockForm.java deleted file mode 100644 index 3c25d82..0000000 --- a/src/main/java/dev/projectg/geyserhub/module/menu/bedrock/BedrockForm.java +++ /dev/null @@ -1,200 +0,0 @@ -package dev.projectg.geyserhub.module.menu.bedrock; - -import dev.projectg.geyserhub.SelectorLogger; -import dev.projectg.geyserhub.module.menu.MenuUtils; -import dev.projectg.geyserhub.utils.PlaceholderUtils; -import org.bukkit.Bukkit; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.entity.Player; -import org.geysermc.cumulus.SimpleForm; -import org.geysermc.cumulus.response.SimpleFormResponse; -import org.geysermc.cumulus.util.FormImage; -import org.geysermc.floodgate.api.player.FloodgatePlayer; - -import javax.annotation.Nonnull; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.stream.Collectors; - -public class BedrockForm { - - private final SelectorLogger logger; - - /** - * If the form actually works and can be used. - */ - public final boolean isEnabled; - - /** - * The name of the form, from the config. - */ - public final String formName; - - /** - * The title of the Bedrock form (shown in the GUI) - */ - private String title; - - /** - * The text shown under the {@link #title} - */ - private String content; - - /** - * A list of all the buttons. Index is the button ID. - */ - private List allButtons; - - // todo: constructor that doesnt use config section - - /** - * Create a new bedrock selector form and initializes it with the given form config section - */ - protected BedrockForm(@Nonnull ConfigurationSection configSection) { - logger = SelectorLogger.getLogger(); - Objects.requireNonNull(configSection); - formName = configSection.getName(); - - // Get the Title and Content - if (configSection.contains("Title", true) && configSection.contains("Content", true)) { - this.title = Objects.requireNonNull(configSection.getString("Title")); - this.content = Objects.requireNonNull(configSection.getString("Content")); - } else { - logger.warn("Bedrock Form: " + formName + " does not contain a Title or Content value! Failed to create the form."); - isEnabled = false; - return; - } - - // Get our Buttons - if (!(configSection.contains("Buttons", true) && configSection.isConfigurationSection("Buttons"))) { - logger.warn("Bedrock Form: " + formName + " does not contain a Buttons section, unable to create form"); - isEnabled = false; - return; - } - ConfigurationSection buttonSection = configSection.getConfigurationSection("Buttons"); - Objects.requireNonNull(buttonSection); - List buttons = getButtons(buttonSection); - if (buttons.isEmpty()) { - logger.warn("Failed to create any valid buttons of Bedrock form: " + formName + "! All listed buttons have a malformed section!"); - isEnabled = false; - return; - } - this.allButtons = buttons; - - isEnabled = true; - } - - /** - * Get all the buttons in the "Buttons" section - * @return A list of Buttons, which may be empty. - */ - private List getButtons(@Nonnull ConfigurationSection configSection) { - logger.debug("Getting buttons for Bedrock form: " + formName); - - // Get all the defined buttons in the buttons section - Set allButtonIds = configSection.getKeys(false); - if (allButtonIds.isEmpty()) { - logger.warn("No buttons were listed for form: " + formName); - return Collections.emptyList(); - } - - // Create a list of buttons. For every defined button with a valid server or command configuration, we add its button. - List compiledButtons = new LinkedList<>(); - for (String buttonId : allButtonIds) { - ConfigurationSection buttonInfo = configSection.getConfigurationSection(buttonId); - if (buttonInfo == null) { - // This will be null if the buttonId key isn't actually a configuration section - logger.warn(buttonId + " was not added because it is not a configuration section!"); - continue; - } - - if (buttonInfo.contains("Button-Text", true) && buttonInfo.isString("Button-Text")) { - String buttonText = buttonInfo.getString("Button-Text"); - Objects.requireNonNull(buttonText); - logger.debug(formName + "." + buttonId + " has text: " + buttonText); - - // Add image if specified - FormImage image = null; - if (buttonInfo.contains("ImageURL", true)) { - String imageURL = buttonInfo.getString("ImageURL"); - Objects.requireNonNull(imageURL); - image = FormImage.of(FormImage.Type.URL, imageURL); - logger.debug(formName + "." + buttonId + " contains image: " + image.getData()); - } - - // Add commands if specified - List commands = MenuUtils.getCommands(buttonInfo); - if (!commands.isEmpty()) { - logger.debug(formName + "." + buttonId + " contains commands: " + commands); - } - - // Add server if specified - String serverName = MenuUtils.getServer(buttonInfo); - if (serverName != null) { - logger.debug(formName + "." + buttonId + " contains target server: " + serverName); - } - - BedrockButton button = new BedrockButton(buttonText); - button.setImage(image); - button.setCommands(commands); - button.setServer(serverName); - compiledButtons.add(button); - } else { - logger.warn(buttonId + " does not contain a valid Button-Text value, not adding."); - } - } - - return compiledButtons; - } - - /** - * Send the server selector - * @param floodgatePlayer the floodgate player to send it to - */ - public void sendForm(@Nonnull FloodgatePlayer floodgatePlayer) { - if (!isEnabled) { - throw new AssertionError("Bedrock Form: " + title + " that failed to load was called to be sent to a player!"); - } - - SelectorLogger logger = SelectorLogger.getLogger(); - - Player player = Bukkit.getServer().getPlayer(floodgatePlayer.getCorrectUniqueId()); - if (player == null) { - logger.severe("Unable to find a Bukkit Player for the given Floodgate Player: " + floodgatePlayer.getCorrectUniqueId().toString()); - return; - } - - // Resolve any placeholders in the button text - List formattedButtons = new ArrayList<>(); - for (BedrockButton rawButton : allButtons) { - BedrockButton copiedButton = new BedrockButton(rawButton); - copiedButton.setText(PlaceholderUtils.setPlaceholders(player, copiedButton.getText())); - formattedButtons.add(copiedButton); - } - - // Create the form - SimpleForm serverSelector = SimpleForm.of(PlaceholderUtils.setPlaceholders(player, title), PlaceholderUtils.setPlaceholders(player, content), formattedButtons.stream().map(BedrockButton::getButtonComponent).collect(Collectors.toList())); - - // Set the response handler - serverSelector.setResponseHandler((responseData) -> { - SimpleFormResponse response = serverSelector.parseResponse(responseData); - if (!response.isCorrect()) { - // isCorrect() = !isClosed() && !isInvalid() - // player closed the form or returned invalid info (see FormResponse) - return; - } - - BedrockButton button = formattedButtons.get(response.getClickedButtonId()); - - // Run the commands if given, move the player to another server if given. - MenuUtils.affectPlayer(button.getCommands(), button.getServer(), player); - }); - - // Send the form to the floodgate player - floodgatePlayer.sendForm(serverSelector); - } -} diff --git a/src/main/java/dev/projectg/geyserhub/module/menu/bedrock/BedrockFormRegistry.java b/src/main/java/dev/projectg/geyserhub/module/menu/bedrock/BedrockFormRegistry.java deleted file mode 100644 index d06aeb3..0000000 --- a/src/main/java/dev/projectg/geyserhub/module/menu/bedrock/BedrockFormRegistry.java +++ /dev/null @@ -1,114 +0,0 @@ -package dev.projectg.geyserhub.module.menu.bedrock; - -import dev.projectg.geyserhub.GeyserHubMain; -import dev.projectg.geyserhub.config.ConfigId; -import dev.projectg.geyserhub.reloadable.Reloadable; -import dev.projectg.geyserhub.reloadable.ReloadableRegistry; -import dev.projectg.geyserhub.SelectorLogger; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.FileConfiguration; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -public class BedrockFormRegistry implements Reloadable { - - public static final String DEFAULT = "default"; - - /** - * If bedrock forms are enabled. may be false if disabled in the config or if all forms failed to load. - */ - private boolean isEnabled; - private final Map enabledForms = new HashMap<>(); - - public BedrockFormRegistry() { - ReloadableRegistry.registerReloadable(this); - isEnabled = load(); - } - - private boolean load() { - FileConfiguration config = GeyserHubMain.getInstance().getConfigManager().getFileConfiguration(ConfigId.SELECTOR); - SelectorLogger logger = SelectorLogger.getLogger(); - - enabledForms.clear(); - - if (config.contains("Bedrock-Selector", true) && config.isConfigurationSection("Bedrock-Selector")) { - ConfigurationSection selectorSection = config.getConfigurationSection("Bedrock-Selector"); - Objects.requireNonNull(selectorSection); - - if (selectorSection.contains("Enable", true) && selectorSection.isBoolean("Enable")) { - if (selectorSection.getBoolean("Enable")) { - if (selectorSection.contains("Forms", true) && selectorSection.isConfigurationSection("Forms")) { - ConfigurationSection forms = selectorSection.getConfigurationSection("Forms"); - Objects.requireNonNull(forms); - - boolean noSuccess = true; - boolean containsDefault = false; - for (String entry : forms.getKeys(false)) { - if (!forms.isConfigurationSection(entry)) { - logger.warn("Bedrock form with name " + entry + " is being skipped because it is not a configuration section"); - continue; - } - ConfigurationSection formInfo = forms.getConfigurationSection(entry); - Objects.requireNonNull(formInfo); - BedrockForm form = new BedrockForm(formInfo); - if (form.isEnabled) { - enabledForms.put(entry, form); - noSuccess = false; - } else { - logger.warn("Not adding form for config section: " + entry + " because there was a failure loading it."); - } - if ("default".equals(entry)) { - containsDefault = true; - } - } - - if (!containsDefault) { - logger.warn("Failed to load a default form! The Server Selector compass will not work and players will not be able to open the default form with \"/ghub\""); - } - if (noSuccess) { - logger.warn("Failed to load ALL bedrock forms, due to configuration error."); - } else { - logger.info("Valid Bedrock forms are: " + enabledForms.keySet()); - return true; - } - } - } else { - logger.debug("Not enabling bedrock forms because it is disabled in the config."); - } - } else { - logger.warn("Not enabling bedrock forms because the Enable value is not present in the config."); - } - } else { - logger.warn("Not enabling bedrock forms because the whole configuration section is not present."); - } - return false; - } - - /** - * @return True, if Java menus are enabled. - */ - public boolean isEnabled() { - return isEnabled; - } - - /** - * Get a BedrockForm, based off its name. - * @param menuName The menu name - * @return the BedrockForm, null if it doesn't exist. - */ - @Nullable - public BedrockForm getMenu(@Nonnull String menuName) { - Objects.requireNonNull(menuName); - return enabledForms.get(menuName); - } - - @Override - public boolean reload() { - isEnabled = load(); - return true; - } -} diff --git a/src/main/java/dev/projectg/geyserhub/module/menu/button/OutcomeButton.java b/src/main/java/dev/projectg/geyserhub/module/menu/button/OutcomeButton.java deleted file mode 100644 index 8e17fc5..0000000 --- a/src/main/java/dev/projectg/geyserhub/module/menu/button/OutcomeButton.java +++ /dev/null @@ -1,61 +0,0 @@ -package dev.projectg.geyserhub.module.menu.button; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Objects; - -public class OutcomeButton extends TextButton { - - @Nonnull private List commands = Collections.emptyList(); - @Nullable private String server; - - /** - * Create a button. - * @param text the text of the button - */ - public OutcomeButton(@Nonnull String text) { - super(text); - } - - /** - * Copy constructor. - * @param button The button to make a copy of - */ - public OutcomeButton(@Nonnull OutcomeButton button) { - super(button); - this.commands = button.getCommands(); // lists are mutable, everything else here isn't - this.server = button.getServer(); - } - - /** - * Set the commands list. - * @param commands the commands list, which can be empty - */ - public void setCommands(@Nonnull List commands) { - Objects.requireNonNull(commands); - this.commands = new ArrayList<>(commands); - } - - /** - * Set the server name. - * @param server the server name - */ - public void setServer(@Nullable String server) { - this.server = server; - } - - /** - * Get the commands that should be executed when this button is pressed. - * @return a List of commands, which may be empty - */ - public @Nonnull List getCommands() { - return new ArrayList<>(this.commands); // Lists are mutable - } - - public @Nullable String getServer() { - return this.server; // Strings are immutable - } -} diff --git a/src/main/java/dev/projectg/geyserhub/module/menu/button/TextButton.java b/src/main/java/dev/projectg/geyserhub/module/menu/button/TextButton.java deleted file mode 100644 index 921cab6..0000000 --- a/src/main/java/dev/projectg/geyserhub/module/menu/button/TextButton.java +++ /dev/null @@ -1,38 +0,0 @@ -package dev.projectg.geyserhub.module.menu.button; - -import javax.annotation.Nonnull; -import java.util.Objects; - -public class TextButton { - - @Nonnull private String text; - - /** - * Create a button. - * @param text the text of the button - */ - public TextButton(@Nonnull String text) { - this.text = Objects.requireNonNull(text); - } - - /** - * Copy constructor. - * @param button The button to make a copy of - */ - public TextButton(@Nonnull TextButton button) { - this.text = button.text; - } - - /** - * Set the text of the button. - * @param text the new text - */ - public void setText(@Nonnull String text) { - this.text = Objects.requireNonNull(text); - } - - public @Nonnull String getText() { - return this.text; // Strings are immutable - } - -} diff --git a/src/main/java/dev/projectg/geyserhub/module/menu/java/ItemButton.java b/src/main/java/dev/projectg/geyserhub/module/menu/java/ItemButton.java deleted file mode 100644 index 7836792..0000000 --- a/src/main/java/dev/projectg/geyserhub/module/menu/java/ItemButton.java +++ /dev/null @@ -1,83 +0,0 @@ -package dev.projectg.geyserhub.module.menu.java; - -import dev.projectg.geyserhub.module.menu.button.OutcomeButton; -import org.bukkit.Material; - -import javax.annotation.Nonnull; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Objects; - -public class ItemButton { - - @Nonnull private String displayName; - @Nonnull private Material material; - @Nonnull private List lore = Collections.emptyList(); - - @Nonnull private final OutcomeButton rightClickButton; - @Nonnull private final OutcomeButton leftClickButton; - - /** - * Main constructor. - * @param text the display name of the item button - * @param material the material of the item button - */ - public ItemButton(@Nonnull String text, @Nonnull Material material) { - this.displayName = Objects.requireNonNull(text); - this.material = Objects.requireNonNull(material); - - rightClickButton = new OutcomeButton(text); - leftClickButton = new OutcomeButton(text); - } - - /** - * Copy constructor. - * @param button The button to make a copy of - */ - public ItemButton(@Nonnull ItemButton button) { - this.displayName = button.getDisplayName(); - this.material = button.getMaterial(); - this.lore = button.getLore(); - - this.rightClickButton = button.getOutcomeButton(true); - this.leftClickButton = button.getOutcomeButton(false); - } - - public @Nonnull String getDisplayName() { - return this.displayName; - } - public @Nonnull Material getMaterial() { - return this.material; - } - public @Nonnull List getLore() { - return new ArrayList<>(lore); // lists are mutable, make a new list instance - } - - public void setDisplayName(@Nonnull String displayName) { - Objects.requireNonNull(displayName); - this.displayName = displayName; - } - public void setMaterial(@Nonnull Material material) { - Objects.requireNonNull(material); - this.material = material; - } - public void setLore(@Nonnull List lore) { - Objects.requireNonNull(lore); - this.lore = lore; - } - - /** - * Get the {@link OutcomeButton} for when the player clicks on this ItemButton. - * Warning: the text of the OutcomeButton is ignored. - * @param rightClick True to get the right side OutcomeButton, or false to get the left side. - * @return the OutcomeButton - */ - public @Nonnull OutcomeButton getOutcomeButton(boolean rightClick) { - if (rightClick) { - return rightClickButton; - } else { - return leftClickButton; - } - } -} diff --git a/src/main/java/dev/projectg/geyserhub/module/menu/java/JavaMenu.java b/src/main/java/dev/projectg/geyserhub/module/menu/java/JavaMenu.java deleted file mode 100644 index 15dff5e..0000000 --- a/src/main/java/dev/projectg/geyserhub/module/menu/java/JavaMenu.java +++ /dev/null @@ -1,340 +0,0 @@ -package dev.projectg.geyserhub.module.menu.java; - -import dev.projectg.geyserhub.GeyserHubMain; -import dev.projectg.geyserhub.SelectorLogger; -import dev.projectg.geyserhub.module.menu.MenuUtils; -import dev.projectg.geyserhub.module.menu.button.OutcomeButton; -import dev.projectg.geyserhub.utils.PlaceholderUtils; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.NamespacedKey; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.InventoryType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.persistence.PersistentDataType; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.*; - -public class JavaMenu { - - public static final int MAX_SIZE = 54; - public static final int HOPPER_SIZE = 5; - - protected static final NamespacedKey BUTTON_KEY = new NamespacedKey(GeyserHubMain.getInstance(), "geyserHubButton"); - protected static final PersistentDataType BUTTON_KEY_TYPE = PersistentDataType.STRING; - - private final SelectorLogger logger; - - /** - * If the menu actually works and can be used. - */ - public final boolean isEnabled; - - /** - * The name of the menu, from the config. - */ - @Nonnull private final String menuName; - - /** - * The title of the inventory (shown in the GUI) - */ - private String title; - - /** - * The size of the inventory - */ - private int size; - - /** - * Map of inventory slot to ItemButton - */ - private Map buttons; - - // todo: constructor that doesnt use config section - - /** - * Create a new java selector menu and initializes it with the given menu config section - */ - protected JavaMenu(@Nonnull ConfigurationSection configSection) { - logger = SelectorLogger.getLogger(); - Objects.requireNonNull(configSection); - menuName = configSection.getName(); - - // Get the inventory title and size - if (configSection.contains("Title", true) && configSection.contains("Size", true) && configSection.isInt("Size")) { - title = Objects.requireNonNull(configSection.getString("Title")); - size = Math.abs(configSection.getInt("Size")); - logger.debug("Java Menu: " + menuName + " has Title: " + title); - } else { - logger.warn("Java Menu: " + menuName + " does not contain a Title or Size value, unable to create menu"); - isEnabled = false; - return; - } - - // Get the Buttons - if (configSection.contains("Buttons", true) && configSection.isConfigurationSection("Buttons")) { - ConfigurationSection buttonSection = configSection.getConfigurationSection("Buttons"); - Objects.requireNonNull(buttonSection); - Map buttons = getAllButtons(buttonSection); - if (buttons.isEmpty()) { - logger.warn("Failed to create any valid buttons of Bedrock form: " + menuName + "! All listed buttons have a malformed section!"); - isEnabled = false; - return; - } - this.buttons = buttons; - } else { - logger.warn("Java Menu: " + menuName + " does not contain a Buttons section, unable to create form."); - isEnabled = false; - return; - } - - validateSize(); - logger.debug("Java menu '" + menuName + "' has a total inventory size of " + size); - - isEnabled = true; - } - - /** - * Get all the buttons in the "Buttons" section - * @return A list of Buttons, which may be empty. - */ - @Nonnull - private Map getAllButtons(@Nonnull ConfigurationSection configSection) { - - // Get all the defined buttons in the buttons section - Set allButtonIds = configSection.getKeys(false); - if (allButtonIds.isEmpty()) { - logger.warn("No buttons were listed for form: " + menuName); - return Collections.emptyMap(); - } - - // Create a list of buttons. For every defined button with a valid server or command configuration, we add its button. - Map compiledButtons = new HashMap<>(); - for (String buttonId : allButtonIds) { - - // Make sure its a configuration section (we know it exists) - ConfigurationSection buttonInfo = configSection.getConfigurationSection(buttonId); - if (buttonInfo == null) { - logger.warn("Java Button: " + menuName + "." + buttonId + " was not added because it is not a configuration section!"); - continue; - } - // Make sure the key is a integer (the slot value of the button item) - int slot; - try { - slot = Integer.parseUnsignedInt(buttonId); - } catch (NumberFormatException e) { - logger.warn("Java Button: " + menuName + "." + buttonId + " was not added because its config name is not a positive integer!"); - continue; - } - - ItemButton button = getButton(buttonInfo); - if (button != null) { - compiledButtons.put(slot, button); - } - } - return compiledButtons; - } - - /** - * Process the config section of a single button config section - * @return the ItemButton. may be null. - */ - @Nullable - private ItemButton getButton(@Nonnull ConfigurationSection buttonInfo) { - String buttonId = buttonInfo.getName(); - - String displayName; - if (buttonInfo.contains("Display-Name", true) && buttonInfo.isString("Display-Name")) { - displayName = buttonInfo.getString("Display-Name"); - Objects.requireNonNull(displayName); - logger.debug(menuName + "." + buttonId + " has Display-Name: " + displayName); - } else { - logger.warn("Java Button: " + menuName + "." + buttonId + " does not contain a valid Button-Text value, not adding."); - return null; - } - - List lore = Collections.emptyList(); - if (buttonInfo.contains("Lore", true) && buttonInfo.isList("Lore")) { - lore = buttonInfo.getStringList("Lore"); - logger.debug(menuName + "." + buttonId + " has Lore: " + lore); - } - - Material material; - if (buttonInfo.contains("Material", true) && buttonInfo.isString("Material")) { - String materialName = buttonInfo.getString("Material"); - Objects.requireNonNull(materialName); - material = Material.getMaterial(materialName, false); - if (material == null) { - material = Material.getMaterial(materialName, true); - if (material == null) { - logger.warn("Java Button: " + menuName + "." + buttonId + " was not added because the Material it provided was not valid."); - return null; - } else { - logger.warn("Java Button: " + menuName + "." + buttonId + "specified a legacy Material, please update it: https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/Material.html"); - } - } - } else { - logger.warn("Java Button: " + menuName + "." + buttonId + " was not added because it is does not contain a Material value!"); - return null; - } - - // Create the button - ItemButton button = new ItemButton(displayName, material); - button.setLore(lore); - OutcomeButton rightOutcome = button.getOutcomeButton(true); - OutcomeButton leftOutcome = button.getOutcomeButton(false); - - // Set server(s) and commands - ConfigurationSection rightClick = buttonInfo.getConfigurationSection("Right-Click"); - ConfigurationSection leftClick = buttonInfo.getConfigurationSection("Left-Click"); - ConfigurationSection anyClick = buttonInfo.getConfigurationSection("Any-Click"); - if (anyClick != null) { - if (rightClick != null || leftClick != null) { - logger.warn("Java Button: " + menuName + "." + buttonId + " Cannot define both Any-Click behaviour and also Right/Left-Click behaviour! Ignoring Any-Click section."); - } - List commands = MenuUtils.getCommands(anyClick); - String server = MenuUtils.getServer(anyClick); - rightOutcome.setCommands(commands); - rightOutcome.setServer(server); - leftOutcome.setCommands(commands); - leftOutcome.setServer(server); - } else { - if (rightClick != null) { - rightOutcome.setCommands(MenuUtils.getCommands(rightClick)); - rightOutcome.setServer(MenuUtils.getServer(rightClick)); - } - if (leftClick != null) { - leftOutcome.setCommands(MenuUtils.getCommands(leftClick)); - leftOutcome.setServer(MenuUtils.getServer(leftClick)); - } - } - - if (!rightOutcome.getCommands().isEmpty()) { - logger.debug(menuName + "." + buttonId + ".right" + " contains commands: " + rightOutcome.getCommands()); - } - if (rightOutcome.getServer() != null) { - logger.debug(menuName + "." + buttonId + ".right" + " contains target server: " + rightOutcome.getServer()); - } - if (!leftOutcome.getCommands().isEmpty()) { - logger.debug(menuName + "." + buttonId + ".left" + " contains commands: " + leftOutcome.getCommands()); - } - if (leftOutcome.getServer() != null) { - logger.debug(menuName + "." + buttonId + ".left" + " contains target server: " + leftOutcome.getServer()); - } - - return button; - } - - /** - * Modifies the {@link #buttons} list and {@link #size} to not exceed what is allowed. - */ - private void validateSize() { - - // ensure size is not greater than max size - if (size > MAX_SIZE) { - size = MAX_SIZE; - logger.warn("Setting the size of Java menu " + menuName + " to " + MAX_SIZE + " because it exceeded the maximum size."); - } - - int min_size = 5; // assume an initial minimum size of 5 - - // Remove buttons that are impossible to fit in any inventory and determined the minimum size to fit all buttons. - for (Integer index: buttons.keySet()) { - if (index > MAX_SIZE - 1) { - logger.warn("Removing button with index " + index + " from Java menu " + menuName + " because it exceeds the max possible index of " + (MAX_SIZE - 1) + "(max possible size of " + MAX_SIZE + ")"); - buttons.remove(index); - continue; - } - - // Minimum size should be equal to or less than max size - min_size = Math.max(min_size, index + 1); - } - - boolean increasedSize; - // Increased the size to fit all buttons if necessary. - // Buttons that exceeded the MAX_SIZE were not considered for the minimum size, - // so this should not increase the size past the maximum size. - if (min_size > size) { - size = min_size; - increasedSize = true; - logger.warn("Java Menu: " + menuName + " has a button that needs a size of " + min_size + ", but the inventory size is only " + size + ". Increased size to " + min_size); - } else { - increasedSize = false; - } - - // Make sure that the inventory size is a multiple of 9, or the hopper size. - if (size != HOPPER_SIZE && size % 9 != 0) { - // Divide the size by 9D, round the ratio up to the next int value, then multiply by 9 to get the closest higher number that is a multiple of 9 - size = (int) (9*(Math.ceil(size/9D))); - if (!increasedSize) { - logger.warn("Java Menu: " + menuName + " size is not 5 (allowed value for hopper), and is not a multiple of 9 between 9 and 54 (allowed values for chests). Increasing size to " + size); - } - } - } - - /** - * @return A non-copy of the contents of this form. - */ - @Nonnull - public Map getContents() { - return this.buttons; - } - - public void sendMenu(@Nonnull Player player) { - if (!isEnabled) { - throw new AssertionError("Tried to send Java Menu: " + menuName + " to a player but the form was not enabled"); - } - - Inventory selectorGUI; - if (size == HOPPER_SIZE) { - selectorGUI = Bukkit.createInventory(player, InventoryType.HOPPER, PlaceholderUtils.setPlaceholders(player, title)); - } else { - selectorGUI = Bukkit.createInventory(player, size, PlaceholderUtils.setPlaceholders(player, title)); - } - - for (Integer slot : buttons.keySet()) { - ItemButton button = buttons.get(slot); - - // Construct the item - ItemStack item = new ItemStack(button.getMaterial()); - ItemMeta meta = item.getItemMeta(); - if (meta == null) { - logger.severe("Java Button: " + menuName + "." + slot + " with Material: " + button.getMaterial() + " returned null ItemMeta, not adding the button!"); - } else { - meta.setDisplayName(PlaceholderUtils.setPlaceholders(player, button.getDisplayName())); - meta.setLore(PlaceholderUtils.setPlaceholders(player, button.getLore())); - meta.getPersistentDataContainer().set(BUTTON_KEY, PersistentDataType.STRING, menuName); - item.setItemMeta(meta); - selectorGUI.setItem(slot, item); - } - } - - player.openInventory(selectorGUI); - } - - /** - * @param slot The inventory slot - * @return If there is a button at the given inventory slot - */ - public boolean isButton(int slot) { - return getContents().get(slot) != null; - } - - /** - * Process a button click by a player in the menu. - * @param slot The slot in the inventory. Nothing will happen if the slot does not contain a button. - * @param rightClick True if it was a right click, false if a left click. - * @param player the Player who clicked on the button. - */ - public void process(int slot, boolean rightClick, @Nonnull Player player) { - if (this.isButton(slot)) { - OutcomeButton button = this.getContents().get(slot).getOutcomeButton(rightClick); - MenuUtils.affectPlayer(button.getCommands(), button.getServer(), player); - } - } -} diff --git a/src/main/java/dev/projectg/geyserhub/module/menu/java/JavaMenuListeners.java b/src/main/java/dev/projectg/geyserhub/module/menu/java/JavaMenuListeners.java deleted file mode 100644 index d3aea93..0000000 --- a/src/main/java/dev/projectg/geyserhub/module/menu/java/JavaMenuListeners.java +++ /dev/null @@ -1,45 +0,0 @@ -package dev.projectg.geyserhub.module.menu.java; - -import dev.projectg.geyserhub.GeyserHubMain; -import dev.projectg.geyserhub.config.ConfigId; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.inventory.ItemStack; - -import javax.annotation.Nonnull; -import java.util.Objects; - -public class JavaMenuListeners implements Listener { - - private final JavaMenuRegistry javaMenuRegistry; - - public JavaMenuListeners(@Nonnull JavaMenuRegistry javaMenuRegistry) { - this.javaMenuRegistry = Objects.requireNonNull(javaMenuRegistry); - } - - @EventHandler - public void onInventoryClick(InventoryClickEvent event) { - // This is used for processing inventory clicks WITHIN the java menu GUI - - FileConfiguration config = GeyserHubMain.getInstance().getConfigManager().getFileConfiguration(ConfigId.SELECTOR); - if (!config.getBoolean("Java-Selector.Enable")) { - return; - } - - if (event.getWhoClicked() instanceof Player) { - Player player = (Player) event.getWhoClicked(); - ItemStack item = event.getCurrentItem(); - - if (item != null) { - JavaMenu menu = javaMenuRegistry.getMenu(item); - if (menu != null) { - event.setCancelled(true); - menu.process(event.getSlot(), event.isRightClick(), player); - } - } - } - } -} \ No newline at end of file diff --git a/src/main/java/dev/projectg/geyserhub/module/menu/java/JavaMenuRegistry.java b/src/main/java/dev/projectg/geyserhub/module/menu/java/JavaMenuRegistry.java deleted file mode 100644 index 74dbb20..0000000 --- a/src/main/java/dev/projectg/geyserhub/module/menu/java/JavaMenuRegistry.java +++ /dev/null @@ -1,144 +0,0 @@ -package dev.projectg.geyserhub.module.menu.java; - -import dev.projectg.geyserhub.GeyserHubMain; -import dev.projectg.geyserhub.SelectorLogger; -import dev.projectg.geyserhub.config.ConfigId; -import dev.projectg.geyserhub.reloadable.Reloadable; -import dev.projectg.geyserhub.reloadable.ReloadableRegistry; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.*; - -public class JavaMenuRegistry implements Reloadable { - - public static final String DEFAULT = "default"; - - /** - * If java menus are enabled. may be false if disabled in the config or if all forms failed to load. - */ - private boolean isEnabled; - private final Map enabledMenus = new HashMap<>(); - - public JavaMenuRegistry() { - ReloadableRegistry.registerReloadable(this); - isEnabled = load(); - } - - private boolean load() { - FileConfiguration config = GeyserHubMain.getInstance().getConfigManager().getFileConfiguration(ConfigId.SELECTOR); - SelectorLogger logger = SelectorLogger.getLogger(); - - enabledMenus.clear(); - - if (config.contains("Java-Selector", true) && config.isConfigurationSection("Java-Selector")) { - ConfigurationSection selectorSection = config.getConfigurationSection("Java-Selector"); - Objects.requireNonNull(selectorSection); - - if (selectorSection.contains("Enable", true) && selectorSection.isBoolean("Enable")) { - if (selectorSection.getBoolean("Enable")) { - if (selectorSection.contains("Menus", true) && selectorSection.isConfigurationSection("Menus")) { - ConfigurationSection menus = selectorSection.getConfigurationSection("Menus"); - Objects.requireNonNull(menus); - - boolean noSuccess = true; - boolean containsDefault = false; - for (String entry : menus.getKeys(false)) { - if (!menus.isConfigurationSection(entry)) { - logger.warn("Java menu with name " + entry + " is being skipped because it is not a configuration section"); - continue; - } - ConfigurationSection formInfo = menus.getConfigurationSection(entry); - Objects.requireNonNull(formInfo); - JavaMenu menu = new JavaMenu(formInfo); - if (menu.isEnabled) { - enabledMenus.put(entry, menu); - noSuccess = false; - } else { - logger.warn("Not adding Java manu for config section: " + entry + " because there was a failure loading it."); - } - if ("default".equals(entry)) { - containsDefault = true; - } - } - - if (!containsDefault) { - logger.warn("Failed to load a default Java menus! The Java Server Selector compass will not work and players will not be able to open the default form with \"/ghub\""); - } - if (noSuccess) { - logger.warn("Failed to load ALL Java menus, due to configuration error."); - } else { - logger.info("Valid Java menus are: " + enabledMenus.keySet()); - return true; - } - } - } else { - logger.debug("Not enabling Java menus because it is disabled in the config."); - } - } else { - logger.warn("Not enabling Java menus because the Enable value is not present in the config."); - } - } else { - logger.warn("Not enabling Java menus because the whole configuration section is not present."); - } - return false; - } - - /** - * @return True, if Java menus are enabled. - */ - public boolean isEnabled() { - return isEnabled; - } - - /** - * Get a Java menu, based off its name. - * @param menuName The menu name - * @return the JavaMenu, null if it doesn't exist. - */ - @Nullable - public JavaMenu getMenu(@Nonnull String menuName) { - Objects.requireNonNull(menuName); - return enabledMenus.get(menuName); - } - - /** - * Attempt to retrieve the menu that an ItemStack points to - * @param itemStack The ItemStack to check. If it contains null ItemMeta, this will return null. - * @return The menu if the ItemStack contained the menu name and the menu exists. If no menu name was contained or the menu contained doesn't exist, this will return null. - */ - @Nullable - public JavaMenu getMenu(@Nonnull ItemStack itemStack) { - String menuName = getMenuName(itemStack); - if (menuName == null) { - return null; - } else { - return getMenu(menuName); - } - } - - /** - * Attempt to retrieve the menu name that an ItemStack is contained in - * @param itemStack The ItemStack to check - * @return The menu name if the ItemStack contained the menu name, null if not. ItemStacks with null ItemMeta will always return null. - */ - @Nullable - public String getMenuName(@Nonnull ItemStack itemStack) { - Objects.requireNonNull(itemStack); - ItemMeta meta = itemStack.getItemMeta(); - if (meta != null) { - return meta.getPersistentDataContainer().get(JavaMenu.BUTTON_KEY, JavaMenu.BUTTON_KEY_TYPE); - } - return null; - } - - @Override - public boolean reload() { - isEnabled = load(); - return true; - } -} diff --git a/src/main/java/dev/projectg/geyserhub/reloadable/ReloadableRegistry.java b/src/main/java/dev/projectg/geyserhub/reloadable/ReloadableRegistry.java index 0556205..b4f6682 100644 --- a/src/main/java/dev/projectg/geyserhub/reloadable/ReloadableRegistry.java +++ b/src/main/java/dev/projectg/geyserhub/reloadable/ReloadableRegistry.java @@ -1,7 +1,7 @@ package dev.projectg.geyserhub.reloadable; -import dev.projectg.geyserhub.GeyserHubMain; -import dev.projectg.geyserhub.SelectorLogger; +import dev.projectg.geyserhub.GeyserHub; +import dev.projectg.geyserhub.Logger; import dev.projectg.geyserhub.config.ConfigId; import dev.projectg.geyserhub.config.ConfigManager; import org.bukkit.ChatColor; @@ -26,9 +26,9 @@ public static void registerReloadable(@Nonnull Reloadable reloadable) { } public static boolean reloadAll() { - SelectorLogger logger = SelectorLogger.getLogger(); + Logger logger = Logger.getLogger(); - ConfigManager configManager = GeyserHubMain.getInstance().getConfigManager(); + ConfigManager configManager = GeyserHub.getInstance().getConfigManager(); // loadConfiguration() will never remove a key so I don't think this will result in ConcurrentModificationException... for (ConfigId configId : configManager.getAllFileConfigurations().keySet()) { if (configManager.loadConfig(configId)) { diff --git a/src/main/java/dev/projectg/geyserhub/utils/FileUtils.java b/src/main/java/dev/projectg/geyserhub/utils/FileUtils.java index 768c488..befd783 100644 --- a/src/main/java/dev/projectg/geyserhub/utils/FileUtils.java +++ b/src/main/java/dev/projectg/geyserhub/utils/FileUtils.java @@ -3,10 +3,14 @@ import javax.annotation.Nullable; import java.io.InputStream; -public class FileUtils { +public final class FileUtils { @Nullable public static InputStream getResource(String resource) { return FileUtils.class.getClassLoader().getResourceAsStream(resource); } + + private FileUtils() { + + } } diff --git a/src/main/java/dev/projectg/geyserhub/utils/PlaceholderUtils.java b/src/main/java/dev/projectg/geyserhub/utils/PlaceholderUtils.java index 41694c2..c128d11 100644 --- a/src/main/java/dev/projectg/geyserhub/utils/PlaceholderUtils.java +++ b/src/main/java/dev/projectg/geyserhub/utils/PlaceholderUtils.java @@ -1,6 +1,6 @@ package dev.projectg.geyserhub.utils; -import dev.projectg.geyserhub.SelectorLogger; +import dev.projectg.geyserhub.Logger; import me.clip.placeholderapi.PlaceholderAPI; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -9,15 +9,15 @@ import java.util.ArrayList; import java.util.List; -public class PlaceholderUtils { +public final class PlaceholderUtils { private static final boolean usePlaceholders; static { - SelectorLogger.getLogger().debug("Initializing PlaceholderUtils"); + Logger.getLogger().debug("Initializing PlaceholderUtils"); usePlaceholders = Bukkit.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"); if (usePlaceholders && !PlaceholderAPI.isRegistered("player")) { - SelectorLogger.getLogger().warn("PlaceholderAPI is installed but the Player extension is not installed! %player_name% and %player_uuid% will NOT be resolved. Please install the Player extension."); + Logger.getLogger().warn("PlaceholderAPI is installed but the Player extension is not installed! %player_name% and %player_uuid% will NOT be resolved. Please install the Player extension."); } } @@ -48,4 +48,8 @@ public static List setPlaceholders(@Nonnull Player player, @Nonnull List } return processedText; } + + private PlaceholderUtils() { + + } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 7868ad3..39789f8 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,11 +1,8 @@ -main: dev.projectg.geyserhub.GeyserHubMain +main: dev.projectg.geyserhub.GeyserHub name: ${project.name} version: ${project.version} api-version: 1.14 -description: A crossplay compatible lobby plugin - -depend: - - floodgate +description: A simple lobby plugin softdepend: - PlaceholderAPI @@ -18,12 +15,6 @@ permissions: geyserhub.main: description: Access to the base command /ghub. Opens the default form if a player runs the command. default: true - geyserhub.form: - description: Access to /ghub form - default: true - geyserhub.form.others: - description: Access to /ghub form - default: op geyserhub.reload: description: Access to /ghub reload default: op diff --git a/src/main/resources/selector.yml b/src/main/resources/selector.yml deleted file mode 100644 index 783f1ae..0000000 --- a/src/main/resources/selector.yml +++ /dev/null @@ -1,156 +0,0 @@ -# Item to access the default menu -Access-Items: - Enable: true - Items: - default: - Material: COMPASS - Name: "§6Server Selector" - Lore: - - "Right click me!" - Slot: 4 - Form: default - - # Give the access item on server join - Join: true - # Give the access item on player respawn - Respawn: true - # Stop the player from dropping the item - Allow-Drop: false - # Destroy the compass if the player drops it - Destroy-Dropped: true - # Stop the player from moving the compass in their inventory - Allow-Move: false - minigamesShortcut: - Material: CARROT_ON_A_STICK - Name: "§6Minigames Shortcut" - Slot: 5 - Form: minigames - Join: true - Respawn: true - Allow-Drop: true - Destroy-Dropped: true - Allow-Move: false - -# Please see our readme for information on configuring this section. -# https://github.com/ProjectG-Plugins/GeyserServerSelector#Configuration -Java-Selector: - Enable: true - - Menus: - default: - # The title of the inventory that the player sees - Title: "§0Server Selector" - # The size of the inventory. Must be greater by at least one than the highest button number. Must be 5, or a multiple of 9 (54 or lower). - Size: 9 - Buttons: - # The slot of the button in the inventory - 2: - Display-Name: "§6Lobby" - # The material of the item. Must exist here: https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/Material.html - Material: DIAMOND - # The lore for the item. Can be removed. - Lore: - - "§2Online players: %bungee_lobby%" - # You can specify different functionality for different clicks. - Right-Click: - # Both Server and Commands are optional; they can be removed. Commands are run before the player is moved to the new server. - Commands: - - "console; tell %player_name% Sending you to the lobby in a right click fashion..." - Server: "lobby" - Left-Click: - Commands: - - "console; tell %player_name% Sending you to the lobby in a left click fashion..." - Server: "lobby" - 4: - Display-Name: "§6Minigames" - Material: GRASS - Lore: - - "Currently Available:" - - "§fSpleef" - - "§fHide § Seek" - Any-Click: - Commands: - - "player; ghub form minigames" - 6: - Display-Name: "§6Survival" - Material: EMERALD - Lore: - - "§2online players: %bungee_survival%" - # You can also only use "Any-Click" to specify identical behaviour for both left and right clicks. - Any-Click: - Commands: - - "console; tell %player_name% Sending you to Survival..." - Server: "survival" - minigames: - Title: "§0Minigames" - Size: 5 - Buttons: - 1: - Display-Name: "§6Spleef" - Material: SNOWBALL - Any-Click: - Server: "spleef" - 3: - Display-Name: "§6Hide § Seek" - Material: DIRT - Any-Click: - Server: "hideseek" - -Bedrock-Selector: - Enable: true - - Forms: - # Name of the form. "default" must exist. Create as many more as you want. - default: - # Title of the form. - Title: "Server Selector" - # Content of the form. - Content: "Click on the server button of choice." - # The list of buttons. Add as many buttons as you want. - # Button-Text is a required value. ImageURL can be removed. Each button can contain a Commands list, a Server value, or both. - Buttons: - # Name of the section. - lobby: - # Button text, Placeholders can be used in here. - Button-Text: "Server Lobby: %bungee_lobby% players" - # Here you can set your own custom icon, This has to be an URL or you can delete it if not needed! - ImageURL: "https://www.digminecraft.com/block_recipes/images/cyan_concrete.png" - # A list of commands to run. prefix with "console;" to run the command from the console, or "player;" to run the command as the player. - # All commands are run before the player is teleported to the server (if specified). - Commands: - - "console; tell %player_name% Taking you to the lobby." - # Server has to be exact the same (case sensitive) as in the bungeecord config! - Server: "lobby" - - survival: - Button-Text: "Survival: %bungee_survival% players" - ImageURL: "https://www.digminecraft.com/block_recipes/images/blue_concrete.png" - Server: "survival" - - # You can also execute commands with buttons as seen below! Use "player;" or "console;" to choose who to run the command as. - gamesCommand: - Button-Text: "Minigames" - Image-URL: "https://www.digminecraft.com/weapon_recipes/images/diamond_sword.png" - Commands: - - "player; ghub form minigames" - - spawnCommand: - Button-Text: "Spawn" - Commands: - - "console; tp %player_name% 0 80 0" - # An example secondary form. - minigames: - Title: "Minigames" - Content: "Click on a minigame of choice." - Buttons: - spleef: - Button-Text: "Spleef" - ImageURL: "https://www.digminecraft.com/materials/images/snowball.png" - Server: "spleef" - - hideseek: - Button-Text: "Hide & Seek" - Server: "hideseek" - -# Don't touch this -Config-Version: 2