diff --git a/core/src/main/java/github/nighter/smartspawner/SmartSpawner.java b/core/src/main/java/github/nighter/smartspawner/SmartSpawner.java index bee4d999..83bafb74 100644 --- a/core/src/main/java/github/nighter/smartspawner/SmartSpawner.java +++ b/core/src/main/java/github/nighter/smartspawner/SmartSpawner.java @@ -236,11 +236,29 @@ private void initializeCoreComponents() { this.spawnerStorageUI = new SpawnerStorageUI(this); this.filterConfigUI = new FilterConfigUI(this); this.spawnerMenuUI = new SpawnerMenuUI(this); - this.spawnerMenuFormUI = new SpawnerMenuFormUI(this); this.spawnerGuiViewManager = new SpawnerGuiViewManager(this); this.spawnerLootGenerator = new SpawnerLootGenerator(this); this.spawnerSellManager = new SpawnerSellManager(this); this.rangeChecker = new SpawnerRangeChecker(this); + + // Initialize FormUI components only if Floodgate is available + initializeFormUIComponents(); + } + + private void initializeFormUIComponents() { + if (integrationManager != null && integrationManager.getFloodgateHook() != null + && integrationManager.getFloodgateHook().isEnabled()) { + try { + this.spawnerMenuFormUI = new SpawnerMenuFormUI(this); + getLogger().info("FormUI components initialized successfully for Bedrock player support"); + } catch (NoClassDefFoundError | Exception e) { + getLogger().warning("Failed to initialize FormUI components: " + e.getMessage()); + this.spawnerMenuFormUI = null; + } + } else { + this.spawnerMenuFormUI = null; + debug("FormUI components not initialized - Floodgate integration not available"); + } } private void initializeHandlers() { diff --git a/core/src/main/java/github/nighter/smartspawner/commands/list/gui/management/SpawnerManagementHandler.java b/core/src/main/java/github/nighter/smartspawner/commands/list/gui/management/SpawnerManagementHandler.java index aa2c747c..b21768d8 100644 --- a/core/src/main/java/github/nighter/smartspawner/commands/list/gui/management/SpawnerManagementHandler.java +++ b/core/src/main/java/github/nighter/smartspawner/commands/list/gui/management/SpawnerManagementHandler.java @@ -80,7 +80,17 @@ private void handleTeleport(Player player, SpawnerData spawner) { } private void handleOpenSpawner(Player player, SpawnerData spawner) { - spawnerMenuUI.openSpawnerMenu(player, spawner, false); + // Check if player is Bedrock and use appropriate menu + if (isBedrockPlayer(player)) { + if (plugin.getSpawnerMenuFormUI() != null) { + plugin.getSpawnerMenuFormUI().openSpawnerForm(player, spawner); + } else { + // Fallback to standard GUI if FormUI not available + spawnerMenuUI.openSpawnerMenu(player, spawner, false); + } + } else { + spawnerMenuUI.openSpawnerMenu(player, spawner, false); + } player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1.0f, 1.0f); } @@ -132,4 +142,12 @@ private void handleBack(Player player, String worldName, int listPage) { listSubCommand.openSpawnerListGUI(player, worldName, listPage, filter, sort); player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1.0f, 1.0f); } + + private boolean isBedrockPlayer(Player player) { + if (plugin.getIntegrationManager() == null || + plugin.getIntegrationManager().getFloodgateHook() == null) { + return false; + } + return plugin.getIntegrationManager().getFloodgateHook().isBedrockPlayer(player); + } } \ No newline at end of file diff --git a/core/src/main/java/github/nighter/smartspawner/hooks/IntegrationManager.java b/core/src/main/java/github/nighter/smartspawner/hooks/IntegrationManager.java index ec3348ff..5bdd226f 100644 --- a/core/src/main/java/github/nighter/smartspawner/hooks/IntegrationManager.java +++ b/core/src/main/java/github/nighter/smartspawner/hooks/IntegrationManager.java @@ -8,6 +8,7 @@ import github.nighter.smartspawner.hooks.protections.api.PlotSquared; import github.nighter.smartspawner.hooks.protections.api.SuperiorSkyblock2; import github.nighter.smartspawner.hooks.rpg.AuraSkillsIntegration; +import github.nighter.smartspawner.hooks.bedrock.FloodgateHook; import lombok.Getter; import me.ryanhamshire.GriefPrevention.GriefPrevention; import org.bukkit.Bukkit; @@ -37,9 +38,11 @@ public class IntegrationManager { // Integration plugin flags private boolean hasAuraSkills = false; + private boolean hasFloodgate = false; // Integration instances public AuraSkillsIntegration auraSkillsIntegration; + public FloodgateHook floodgateHook; public IntegrationManager(SmartSpawner plugin) { this.plugin = plugin; @@ -156,6 +159,17 @@ private void checkIntegrationPlugins() { return false; } }, true); + + hasFloodgate = checkPlugin("Floodgate", () -> { + Plugin floodgatePlugin = Bukkit.getPluginManager().getPlugin("floodgate"); + if (floodgatePlugin != null && floodgatePlugin.isEnabled()) { + this.floodgateHook = new FloodgateHook(plugin); + return this.floodgateHook.isEnabled(); + } else { + this.floodgateHook = null; + return false; + } + }, true); } private boolean checkPlugin(String pluginName, PluginCheck checker, boolean logSuccess) { diff --git a/core/src/main/java/github/nighter/smartspawner/hooks/bedrock/FloodgateHook.java b/core/src/main/java/github/nighter/smartspawner/hooks/bedrock/FloodgateHook.java new file mode 100644 index 00000000..fd30c54d --- /dev/null +++ b/core/src/main/java/github/nighter/smartspawner/hooks/bedrock/FloodgateHook.java @@ -0,0 +1,106 @@ +package github.nighter.smartspawner.hooks.bedrock; + +import github.nighter.smartspawner.SmartSpawner; +import org.bukkit.entity.Player; +import org.geysermc.floodgate.api.FloodgateApi; + +import java.util.UUID; + +/** + * Hook for Floodgate API to check if players are Bedrock Edition players. + * This provides a centralized way to check Bedrock players without repeatedly + * accessing the FloodgateApi instance. + */ +public class FloodgateHook { + private final SmartSpawner plugin; + private FloodgateApi floodgateApi; + private boolean enabled = false; + + public FloodgateHook(SmartSpawner plugin) { + this.plugin = plugin; + initialize(); + } + + private void initialize() { + try { + // Check if Floodgate plugin is available + if (plugin.getServer().getPluginManager().getPlugin("floodgate") == null) { + plugin.debug("Floodgate plugin not found"); + return; + } + + // Get FloodgateApi instance + floodgateApi = FloodgateApi.getInstance(); + if (floodgateApi == null) { + plugin.getLogger().warning("Failed to get FloodgateApi instance"); + return; + } + + enabled = true; + plugin.getLogger().info("Floodgate integration initialized successfully!"); + } catch (NoClassDefFoundError | NullPointerException e) { + plugin.debug("Floodgate API not available: " + e.getMessage()); + enabled = false; + } catch (Exception e) { + plugin.getLogger().warning("Error initializing Floodgate integration: " + e.getMessage()); + enabled = false; + } + } + + /** + * Check if the Floodgate integration is enabled and available. + * + * @return true if Floodgate is available, false otherwise + */ + public boolean isEnabled() { + return enabled && floodgateApi != null; + } + + /** + * Check if a player is a Bedrock Edition player. + * + * @param player The player to check + * @return true if the player is a Bedrock player, false otherwise + */ + public boolean isBedrockPlayer(Player player) { + if (!isEnabled() || player == null) { + return false; + } + + try { + return floodgateApi.isFloodgatePlayer(player.getUniqueId()); + } catch (Exception e) { + plugin.debug("Error checking if player is Bedrock: " + e.getMessage()); + return false; + } + } + + /** + * Check if a UUID belongs to a Bedrock Edition player. + * + * @param uuid The UUID to check + * @return true if the UUID belongs to a Bedrock player, false otherwise + */ + public boolean isBedrockPlayer(UUID uuid) { + if (!isEnabled() || uuid == null) { + return false; + } + + try { + return floodgateApi.isFloodgatePlayer(uuid); + } catch (Exception e) { + plugin.debug("Error checking if UUID is Bedrock: " + e.getMessage()); + return false; + } + } + + /** + * Get the FloodgateApi instance. + * Only use this if you need direct access to the API. + * + * @return The FloodgateApi instance, or null if not available + */ + public FloodgateApi getApi() { + return floodgateApi; + } +} diff --git a/core/src/main/java/github/nighter/smartspawner/spawner/gui/main/SpawnerMenuAction.java b/core/src/main/java/github/nighter/smartspawner/spawner/gui/main/SpawnerMenuAction.java index ef3afb40..88e22a3b 100644 --- a/core/src/main/java/github/nighter/smartspawner/spawner/gui/main/SpawnerMenuAction.java +++ b/core/src/main/java/github/nighter/smartspawner/spawner/gui/main/SpawnerMenuAction.java @@ -313,7 +313,18 @@ public void handleExpBottleClick(Player player, SpawnerData spawner, boolean isS // Reset spawner exp and update menu spawner.setSpawnerExp(0); plugin.getSpawnerManager().markSpawnerModified(spawner.getSpawnerId()); - spawnerMenuUI.openSpawnerMenu(player, spawner, true); + + // Check if player is Bedrock and use appropriate menu + if (isBedrockPlayer(player)) { + if (plugin.getSpawnerMenuFormUI() != null) { + plugin.getSpawnerMenuFormUI().openSpawnerForm(player, spawner); + } else { + // Fallback to standard GUI if FormUI not available + spawnerMenuUI.openSpawnerMenu(player, spawner, true); + } + } else { + spawnerMenuUI.openSpawnerMenu(player, spawner, true); + } // Update all viewers instead of just current player spawnerGuiViewManager.updateSpawnerMenuViewers(spawner); @@ -427,4 +438,12 @@ private void giveAuraSkillsXp(Player player, SpawnerData spawner, int totalExp) plugin.debug("AuraSkills integration error: " + e.toString()); } } + + private boolean isBedrockPlayer(Player player) { + if (plugin.getIntegrationManager() == null || + plugin.getIntegrationManager().getFloodgateHook() == null) { + return false; + } + return plugin.getIntegrationManager().getFloodgateHook().isBedrockPlayer(player); + } } diff --git a/core/src/main/java/github/nighter/smartspawner/spawner/gui/stacker/SpawnerStackerHandler.java b/core/src/main/java/github/nighter/smartspawner/spawner/gui/stacker/SpawnerStackerHandler.java index e6bd9a1f..70de33f7 100644 --- a/core/src/main/java/github/nighter/smartspawner/spawner/gui/stacker/SpawnerStackerHandler.java +++ b/core/src/main/java/github/nighter/smartspawner/spawner/gui/stacker/SpawnerStackerHandler.java @@ -116,7 +116,17 @@ public void onInventoryClick(InventoryClickEvent event) { // Handle navigation back to main menu if spawner is clicked if (clickedItem.getType() == Material.SPAWNER) { - spawnerMenuUI.openSpawnerMenu(player, spawner, true); + // Check if player is Bedrock and use appropriate menu + if (isBedrockPlayer(player)) { + if (plugin.getSpawnerMenuFormUI() != null) { + plugin.getSpawnerMenuFormUI().openSpawnerForm(player, spawner); + } else { + // Fallback to standard GUI if FormUI not available + spawnerMenuUI.openSpawnerMenu(player, spawner, true); + } + } else { + spawnerMenuUI.openSpawnerMenu(player, spawner, true); + } player.playSound(player.getLocation(), CLICK_SOUND, SOUND_VOLUME, SOUND_PITCH); return; } @@ -670,4 +680,12 @@ public void closeAllViewersInventory(String spawnerId) { } } } + + private boolean isBedrockPlayer(Player player) { + if (plugin.getIntegrationManager() == null || + plugin.getIntegrationManager().getFloodgateHook() == null) { + return false; + } + return plugin.getIntegrationManager().getFloodgateHook().isBedrockPlayer(player); + } } diff --git a/core/src/main/java/github/nighter/smartspawner/spawner/gui/storage/SpawnerStorageAction.java b/core/src/main/java/github/nighter/smartspawner/spawner/gui/storage/SpawnerStorageAction.java index ff761609..94dac73f 100644 --- a/core/src/main/java/github/nighter/smartspawner/spawner/gui/storage/SpawnerStorageAction.java +++ b/core/src/main/java/github/nighter/smartspawner/spawner/gui/storage/SpawnerStorageAction.java @@ -529,7 +529,26 @@ private void openMainMenu(Player player, SpawnerData spawner) { spawnerManager.markSpawnerModified(spawner.getSpawnerId()); spawner.clearInteracted(); } - spawnerMenuUI.openSpawnerMenu(player, spawner, true); + + // Check if player is Bedrock and use appropriate menu + if (isBedrockPlayer(player)) { + if (plugin.getSpawnerMenuFormUI() != null) { + plugin.getSpawnerMenuFormUI().openSpawnerForm(player, spawner); + } else { + // Fallback to standard GUI if FormUI not available + spawnerMenuUI.openSpawnerMenu(player, spawner, true); + } + } else { + spawnerMenuUI.openSpawnerMenu(player, spawner, true); + } + } + + private boolean isBedrockPlayer(Player player) { + if (plugin.getIntegrationManager() == null || + plugin.getIntegrationManager().getFloodgateHook() == null) { + return false; + } + return plugin.getIntegrationManager().getFloodgateHook().isBedrockPlayer(player); } private void handleSortItemsClick(Player player, SpawnerData spawner, Inventory inventory) { diff --git a/core/src/main/java/github/nighter/smartspawner/spawner/interactions/click/SpawnerClickManager.java b/core/src/main/java/github/nighter/smartspawner/spawner/interactions/click/SpawnerClickManager.java index 14eac83d..aaffcb7c 100644 --- a/core/src/main/java/github/nighter/smartspawner/spawner/interactions/click/SpawnerClickManager.java +++ b/core/src/main/java/github/nighter/smartspawner/spawner/interactions/click/SpawnerClickManager.java @@ -22,7 +22,6 @@ import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.ItemStack; -import org.geysermc.floodgate.api.FloodgateApi; import java.util.Map; import java.util.UUID; @@ -216,12 +215,16 @@ private void handleInactiveSpawnerInteraction(Player player, Block block, Spawne private void openSpawnerMenu(Player player, SpawnerData spawner) { // Check if the player is a Bedrock player and use FormUI if (isBedrockPlayer(player)) { - spawnerMenuFormUI.openSpawnerForm(player, spawner); + if (spawnerMenuFormUI != null) { + spawnerMenuFormUI.openSpawnerForm(player, spawner); + } else { + // Fallback to standard GUI if FormUI not available + spawnerMenuUI.openSpawnerMenu(player, spawner, false); + } } else { // Open the regular GUI menu for Java players spawnerMenuUI.openSpawnerMenu(player, spawner, false); } - // spawnerMenuUI.openSpawnerMenu(player, spawner, false); } private boolean isSpawnEgg(Material material) { @@ -229,12 +232,11 @@ private boolean isSpawnEgg(Material material) { } private boolean isBedrockPlayer(Player player) { - try { - FloodgateApi api = FloodgateApi.getInstance(); - return api != null && api.isFloodgatePlayer(player.getUniqueId()); - } catch (NoClassDefFoundError | NullPointerException e) { + if (plugin.getIntegrationManager() == null || + plugin.getIntegrationManager().getFloodgateHook() == null) { return false; } + return plugin.getIntegrationManager().getFloodgateHook().isBedrockPlayer(player); } private void initCleanupTask() { diff --git a/core/src/main/java/github/nighter/smartspawner/spawner/utils/SpawnerMobHeadTexture.java b/core/src/main/java/github/nighter/smartspawner/spawner/utils/SpawnerMobHeadTexture.java index 4b5ba178..d2e8320d 100644 --- a/core/src/main/java/github/nighter/smartspawner/spawner/utils/SpawnerMobHeadTexture.java +++ b/core/src/main/java/github/nighter/smartspawner/spawner/utils/SpawnerMobHeadTexture.java @@ -1,5 +1,6 @@ package github.nighter.smartspawner.spawner.utils; +import github.nighter.smartspawner.SmartSpawner; import github.nighter.smartspawner.nms.TextureWrapper; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -11,7 +12,6 @@ import org.bukkit.inventory.meta.SkullMeta; import org.bukkit.profile.PlayerTextures; import org.bukkit.profile.PlayerProfile; -import org.geysermc.floodgate.api.FloodgateApi; import java.net.URL; import java.util.EnumMap; @@ -26,13 +26,12 @@ public class SpawnerMobHeadTexture { } private static boolean isBedrockPlayer(Player player) { - UUID uuid = player.getUniqueId(); - try { - FloodgateApi api = FloodgateApi.getInstance(); - return api.isFloodgatePlayer(uuid); - } catch (NoClassDefFoundError | NullPointerException e) { + SmartSpawner plugin = SmartSpawner.getInstance(); + if (plugin == null || plugin.getIntegrationManager() == null || + plugin.getIntegrationManager().getFloodgateHook() == null) { return false; } + return plugin.getIntegrationManager().getFloodgateHook().isBedrockPlayer(player); } public static ItemStack getCustomHead(EntityType entityType, Player player) {