From 164e4e995d5171e64732fff8c0571e09d4013ae6 Mon Sep 17 00:00:00 2001 From: Esophose Date: Sat, 11 May 2019 02:15:40 -0600 Subject: [PATCH] Fix for 1.8, worldguard 6 support, fix epicspawners hard dependency --- .gitlab-ci.yml | 2 +- .../epicanchors/api/EpicAnchorsAPI.java | 2 - .../utils/ClaimableProtectionPluginHook.java | 4 +- .../api/utils/ProtectionPluginHook.java | 6 +- .../epicanchors/EpicAnchorsPlugin.java | 23 +- .../java/com/songoda/epicanchors/Locale.java | 15 +- .../songoda/epicanchors/anchor/EAnchor.java | 21 +- .../epicanchors/command/AbstractCommand.java | 2 +- .../command/commands/CommandEpicAnchors.java | 2 +- .../command/commands/CommandGive.java | 3 +- .../command/commands/CommandReload.java | 2 +- .../songoda/epicanchors/gui/GUIOverview.java | 4 +- .../epicanchors/handlers/AnchorHandler.java | 15 +- .../epicanchors/hooks/HookFactions.java | 2 +- .../epicanchors/hooks/HookKingdoms.java | 4 +- .../epicanchors/hooks/HookRedProtect.java | 2 +- .../epicanchors/hooks/HookWorldGuard.java | 46 ++- .../epicanchors/listeners/BlockListeners.java | 5 +- .../listeners/InteractListeners.java | 11 +- .../songoda/epicanchors/utils/Methods.java | 30 +- .../epicanchors/utils/SettingsManager.java | 18 +- .../utils/gui/AbstractAnvilGUI.java | 310 ++++++++++++++++++ .../epicanchors/utils/gui/AbstractGUI.java | 226 +++++++++++++ .../epicanchors/utils/gui/Clickable.java | 11 + .../epicanchors/utils/gui/OnClose.java | 10 + .../songoda/epicanchors/utils/gui/Range.java | 55 ++++ .../epicanchors/utils/version/NMSUtil.java | 100 ++++++ 27 files changed, 854 insertions(+), 77 deletions(-) create mode 100644 EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/gui/AbstractAnvilGUI.java create mode 100644 EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/gui/AbstractGUI.java create mode 100644 EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/gui/Clickable.java create mode 100644 EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/gui/OnClose.java create mode 100644 EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/gui/Range.java create mode 100644 EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/version/NMSUtil.java diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a079ecf..4a66597 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,7 +4,7 @@ stages: variables: name: "EpicAnchors" path: "/builds/$CI_PROJECT_PATH" - version: "1.2.3" + version: "1.2.4" build: stage: build diff --git a/EpicAnchors-API/src/main/java/com/songoda/epicanchors/api/EpicAnchorsAPI.java b/EpicAnchors-API/src/main/java/com/songoda/epicanchors/api/EpicAnchorsAPI.java index d1fae16..2389f40 100644 --- a/EpicAnchors-API/src/main/java/com/songoda/epicanchors/api/EpicAnchorsAPI.java +++ b/EpicAnchors-API/src/main/java/com/songoda/epicanchors/api/EpicAnchorsAPI.java @@ -1,8 +1,6 @@ package com.songoda.epicanchors.api; -import org.bukkit.ChatColor; - /** * The access point of the EpicAnchorsAPI, a class acting as a bridge between API * and plugin implementation. It is from here where developers should access the diff --git a/EpicAnchors-API/src/main/java/com/songoda/epicanchors/api/utils/ClaimableProtectionPluginHook.java b/EpicAnchors-API/src/main/java/com/songoda/epicanchors/api/utils/ClaimableProtectionPluginHook.java index 948e9db..581226b 100644 --- a/EpicAnchors-API/src/main/java/com/songoda/epicanchors/api/utils/ClaimableProtectionPluginHook.java +++ b/EpicAnchors-API/src/main/java/com/songoda/epicanchors/api/utils/ClaimableProtectionPluginHook.java @@ -22,7 +22,7 @@ public interface ClaimableProtectionPluginHook extends ProtectionPluginHook { * @return true if the location is within the claim, false otherwise or if the * claim ID does not exist */ - public boolean isInClaim(Location location, String id); + boolean isInClaim(Location location, String id); /** * Get the ID of the claim with the given name. Often times this is unnecessary @@ -34,6 +34,6 @@ public interface ClaimableProtectionPluginHook extends ProtectionPluginHook { * * @return the unique String ID. null if no claim exists */ - public String getClaimID(String name); + String getClaimID(String name); } \ No newline at end of file diff --git a/EpicAnchors-API/src/main/java/com/songoda/epicanchors/api/utils/ProtectionPluginHook.java b/EpicAnchors-API/src/main/java/com/songoda/epicanchors/api/utils/ProtectionPluginHook.java index 7eaa535..7eac058 100644 --- a/EpicAnchors-API/src/main/java/com/songoda/epicanchors/api/utils/ProtectionPluginHook.java +++ b/EpicAnchors-API/src/main/java/com/songoda/epicanchors/api/utils/ProtectionPluginHook.java @@ -21,7 +21,7 @@ public interface ProtectionPluginHook { * * @return the hooking plugin */ - public JavaPlugin getPlugin(); + JavaPlugin getPlugin(); /** * Check whether the provided player may build at the specified location @@ -31,7 +31,7 @@ public interface ProtectionPluginHook { * * @return true if player is permitted to build, false otherwise */ - public boolean canBuild(Player player, Location location); + boolean canBuild(Player player, Location location); /** * Check whether the provided player may build at the specified block @@ -41,7 +41,7 @@ public interface ProtectionPluginHook { * * @return true if player is permitted to build, false otherwise */ - public default boolean canBuild(Player player, Block block) { + default boolean canBuild(Player player, Block block) { return block != null && canBuild(player, block.getLocation()); } diff --git a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/EpicAnchorsPlugin.java b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/EpicAnchorsPlugin.java index 0855b63..ce982e3 100644 --- a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/EpicAnchorsPlugin.java +++ b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/EpicAnchorsPlugin.java @@ -9,15 +9,24 @@ import com.songoda.epicanchors.api.anchor.AnchorManager; import com.songoda.epicanchors.api.utils.ClaimableProtectionPluginHook; import com.songoda.epicanchors.api.utils.ProtectionPluginHook; import com.songoda.epicanchors.command.CommandManager; +import com.songoda.epicanchors.handlers.AnchorHandler; +import com.songoda.epicanchors.hooks.HookASkyBlock; +import com.songoda.epicanchors.hooks.HookFactions; +import com.songoda.epicanchors.hooks.HookGriefPrevention; +import com.songoda.epicanchors.hooks.HookKingdoms; +import com.songoda.epicanchors.hooks.HookPlotSquared; +import com.songoda.epicanchors.hooks.HookRedProtect; +import com.songoda.epicanchors.hooks.HookTowny; +import com.songoda.epicanchors.hooks.HookUSkyBlock; +import com.songoda.epicanchors.hooks.HookWorldGuard; import com.songoda.epicanchors.listeners.BlockListeners; import com.songoda.epicanchors.listeners.InteractListeners; -import com.songoda.epicanchors.handlers.AnchorHandler; -import com.songoda.epicanchors.hooks.*; import com.songoda.epicanchors.utils.ConfigWrapper; import com.songoda.epicanchors.utils.Methods; import com.songoda.epicanchors.utils.ServerVersion; import com.songoda.epicanchors.utils.SettingsManager; import com.songoda.epicanchors.utils.updateModules.LocaleModule; +import com.songoda.epicanchors.utils.version.NMSUtil; import com.songoda.update.Plugin; import com.songoda.update.SongodaUpdate; import org.apache.commons.lang.ArrayUtils; @@ -25,6 +34,8 @@ import org.apache.commons.lang.math.NumberUtils; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.Particle; +import org.bukkit.Sound; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -237,6 +248,13 @@ public class EpicAnchorsPlugin extends JavaPlugin implements EpicAnchors { anchor.getLocation().getWorld().dropItemNaturally(anchor.getLocation(), item); } location.getBlock().setType(Material.AIR); + + if (NMSUtil.getVersionNumber() > 8) + location.getWorld().spawnParticle(Particle.LAVA, location.clone().add(.5, .5, .5), 5, 0, 0, 0, 5); + + location.getWorld().playSound(location, this.isServerVersionAtLeast(ServerVersion.V1_13) + ? Sound.ENTITY_GENERIC_EXPLODE : Sound.valueOf("EXPLODE"), 10, 10); + getAnchorManager().removeAnchor(location); } @@ -247,6 +265,7 @@ public class EpicAnchorsPlugin extends JavaPlugin implements EpicAnchors { public boolean isServerVersion(ServerVersion version) { return serverVersion == version; } + public boolean isServerVersion(ServerVersion... versions) { return ArrayUtils.contains(versions, serverVersion); } diff --git a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/Locale.java b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/Locale.java index 7a93fc8..84ff243 100644 --- a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/Locale.java +++ b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/Locale.java @@ -6,7 +6,16 @@ import com.google.common.collect.Lists; import org.bukkit.ChatColor; import org.bukkit.plugin.java.JavaPlugin; -import java.io.*; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -150,7 +159,7 @@ public class Locale { /** * Save a default locale file from the project source directory, to the locale folder * - * @param in file to save + * @param in file to save * @param fileName the name of the file to save * @return true if the operation was successful, false otherwise */ @@ -322,7 +331,7 @@ public class Locale { /** * Get a message set for a specific node * - * @param node the node to get + * @param node the node to get * @param defaultValue the default value given that a value for the node was not found * @return the message for the specified node. Default if none found */ diff --git a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/anchor/EAnchor.java b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/anchor/EAnchor.java index 447dd93..89edfe6 100644 --- a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/anchor/EAnchor.java +++ b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/anchor/EAnchor.java @@ -3,19 +3,15 @@ package com.songoda.epicanchors.anchor; import com.songoda.epicanchors.EpicAnchorsPlugin; import com.songoda.epicanchors.api.anchor.Anchor; import com.songoda.epicanchors.gui.GUIOverview; -import com.songoda.epicanchors.utils.Methods; +import com.songoda.epicanchors.utils.version.NMSUtil; import net.milkbowl.vault.economy.Economy; -import org.bukkit.*; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.plugin.RegisteredServiceProvider; -import java.util.ArrayList; -import java.util.List; - -//ToDo: I want there to be a GUI for this that has the timer going down in real time. public class EAnchor implements Anchor { private Location location; @@ -61,8 +57,11 @@ public class EAnchor implements Anchor { } ticksLeft = ticksLeft + 20 * 60 * 30; - player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 0.6F, 15.0F); - player.getWorld().spawnParticle(Particle.SPELL_WITCH, getLocation().add(.5,.5,.5), 100, .5, .5, .5); + Sound sound = NMSUtil.getVersionNumber() > 8 ? Sound.ENTITY_PLAYER_LEVELUP : Sound.valueOf("LEVEL_UP"); + player.playSound(player.getLocation(), sound, 0.6F, 15.0F); + + if (NMSUtil.getVersionNumber() > 8) + player.getWorld().spawnParticle(Particle.SPELL_WITCH, getLocation().add(.5, .5, .5), 100, .5, .5, .5); } @Override diff --git a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/command/AbstractCommand.java b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/command/AbstractCommand.java index c44f889..cb7c8d1 100644 --- a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/command/AbstractCommand.java +++ b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/command/AbstractCommand.java @@ -5,7 +5,7 @@ import org.bukkit.command.CommandSender; public abstract class AbstractCommand { - public enum ReturnType { SUCCESS, FAILURE, SYNTAX_ERROR } + public enum ReturnType {SUCCESS, FAILURE, SYNTAX_ERROR} private final AbstractCommand parent; diff --git a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/command/commands/CommandEpicAnchors.java b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/command/commands/CommandEpicAnchors.java index a1f647e..671ef0c 100644 --- a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/command/commands/CommandEpicAnchors.java +++ b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/command/commands/CommandEpicAnchors.java @@ -1,7 +1,7 @@ package com.songoda.epicanchors.command.commands; -import com.songoda.epicanchors.command.AbstractCommand; import com.songoda.epicanchors.EpicAnchorsPlugin; +import com.songoda.epicanchors.command.AbstractCommand; import com.songoda.epicanchors.utils.Methods; import org.bukkit.command.CommandSender; diff --git a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/command/commands/CommandGive.java b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/command/commands/CommandGive.java index 28d9062..c9251cf 100644 --- a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/command/commands/CommandGive.java +++ b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/command/commands/CommandGive.java @@ -1,8 +1,7 @@ package com.songoda.epicanchors.command.commands; -import com.songoda.epicanchors.command.AbstractCommand; import com.songoda.epicanchors.EpicAnchorsPlugin; -import com.songoda.epicanchors.utils.Methods; +import com.songoda.epicanchors.command.AbstractCommand; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; diff --git a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/command/commands/CommandReload.java b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/command/commands/CommandReload.java index b190d92..781650a 100644 --- a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/command/commands/CommandReload.java +++ b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/command/commands/CommandReload.java @@ -1,7 +1,7 @@ package com.songoda.epicanchors.command.commands; -import com.songoda.epicanchors.command.AbstractCommand; import com.songoda.epicanchors.EpicAnchorsPlugin; +import com.songoda.epicanchors.command.AbstractCommand; import com.songoda.epicanchors.utils.Methods; import org.bukkit.command.CommandSender; diff --git a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/gui/GUIOverview.java b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/gui/GUIOverview.java index c9414f8..7162d06 100644 --- a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/gui/GUIOverview.java +++ b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/gui/GUIOverview.java @@ -3,7 +3,7 @@ package com.songoda.epicanchors.gui; import com.songoda.epicanchors.EpicAnchorsPlugin; import com.songoda.epicanchors.anchor.EAnchor; import com.songoda.epicanchors.utils.Methods; -import com.songoda.epicspawners.utils.gui.AbstractGUI; +import com.songoda.epicanchors.utils.gui.AbstractGUI; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -31,7 +31,7 @@ public class GUIOverview extends AbstractGUI { } @Override - protected void constructGUI() { + public void constructGUI() { String timeRemaining = Methods.makeReadable((long) (anchor.getTicksLeft() / 20) * 1000) + " remaining."; int nu = 0; diff --git a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/handlers/AnchorHandler.java b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/handlers/AnchorHandler.java index f503c7e..fb0cc74 100644 --- a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/handlers/AnchorHandler.java +++ b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/handlers/AnchorHandler.java @@ -4,7 +4,13 @@ import com.songoda.epicanchors.EpicAnchorsPlugin; import com.songoda.epicanchors.api.anchor.Anchor; import com.songoda.epicanchors.utils.ServerVersion; import com.songoda.epicspawners.api.EpicSpawnersAPI; -import org.bukkit.*; +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Particle; +import org.bukkit.Sound; import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; @@ -56,11 +62,11 @@ public class AnchorHandler { } catch (ReflectiveOperationException e) { e.printStackTrace(); } - epicSpawners = instance.getServer().getPluginManager().getPlugin("EpicSpawners") != null; + epicSpawners = instance.getServer().getPluginManager().getPlugin("EpicSpawners") != null; Bukkit.getScheduler().scheduleSyncRepeatingTask(instance, this::doAnchorCheck, 0, 1); //ToDo: way to fast. if (instance.isServerVersionAtLeast(ServerVersion.V1_9)) - Bukkit.getScheduler().scheduleSyncRepeatingTask(instance, this::doParticle, 0, 2); //ToDo: way to fast. + Bukkit.getScheduler().scheduleSyncRepeatingTask(instance, this::doParticle, 0, 2); //ToDo: way to fast. } private void doParticle() { @@ -81,7 +87,6 @@ public class AnchorHandler { location1.getWorld().spawnParticle(Particle.REDSTONE, location1, 5, xx, yy, zz, 1, new Particle.DustOptions(Color.WHITE, 1F)); - } } @@ -125,7 +130,7 @@ public class AnchorHandler { if (instance.isServerVersionAtLeast(ServerVersion.V1_9)) location.getWorld().spawnParticle(Particle.LAVA, location.clone().add(.5, .5, .5), 5, 0, 0, 0, 5); location.getWorld().playSound(location, instance.isServerVersionAtLeast(ServerVersion.V1_13) - ? Sound.ENTITY_GENERIC_EXPLODE : Sound.valueOf("EXLODE"), 10, 10); + ? Sound.ENTITY_GENERIC_EXPLODE : Sound.valueOf("EXPLODE"), 10, 10); location.getBlock().setType(Material.AIR); chunk.unload(); } diff --git a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/hooks/HookFactions.java b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/hooks/HookFactions.java index 2c3d08f..7329efb 100644 --- a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/hooks/HookFactions.java +++ b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/hooks/HookFactions.java @@ -27,7 +27,7 @@ public class HookFactions implements ClaimableProtectionPluginHook { public boolean canBuild(Player player, Location location) { FPlayer fPlayer = FPlayers.getBySender(player); Faction faction = Factions.getFactionAt(location); - + return faction.isNone() || fPlayer.getFaction().equals(faction); } diff --git a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/hooks/HookKingdoms.java b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/hooks/HookKingdoms.java index 9066337..b53d499 100644 --- a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/hooks/HookKingdoms.java +++ b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/hooks/HookKingdoms.java @@ -27,11 +27,11 @@ public class HookKingdoms implements ProtectionPluginHook { public boolean canBuild(Player player, Location location) { KingdomPlayer kPlayer = GameManagement.getPlayerManager().getOfflineKingdomPlayer(player).getKingdomPlayer(); if (kPlayer.getKingdom() == null) return true; - + SimpleChunkLocation chunkLocation = new SimpleChunkLocation(location.getChunk()); Land land = GameManagement.getLandManager().getOrLoadLand(chunkLocation); String owner = land.getOwner(); - + return owner == null || kPlayer.getKingdom().getKingdomName().equals(owner); } diff --git a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/hooks/HookRedProtect.java b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/hooks/HookRedProtect.java index 5515209..c4341b3 100644 --- a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/hooks/HookRedProtect.java +++ b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/hooks/HookRedProtect.java @@ -25,7 +25,7 @@ public class HookRedProtect implements ProtectionPluginHook { public boolean canBuild(Player player, Location location) { RedProtectAPI api = redProtect.getAPI(); Region region = api.getRegion(location); - + return region != null && region.canBuild(player); } diff --git a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/hooks/HookWorldGuard.java b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/hooks/HookWorldGuard.java index b237e4c..0181466 100644 --- a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/hooks/HookWorldGuard.java +++ b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/hooks/HookWorldGuard.java @@ -1,34 +1,56 @@ package com.songoda.epicanchors.hooks; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldguard.WorldGuard; -import com.sk89q.worldguard.bukkit.WorldGuardPlugin; -import com.sk89q.worldguard.protection.ApplicableRegionSet; -import com.sk89q.worldguard.protection.flags.Flags; -import com.sk89q.worldguard.protection.regions.RegionQuery; import com.songoda.epicanchors.api.utils.ProtectionPluginHook; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; +import java.lang.reflect.Method; + public class HookWorldGuard implements ProtectionPluginHook { - private final WorldGuard worldGuard; + private Method wg6canBuild; + private Object wg6inst; + private boolean isWorldGuard7; public HookWorldGuard() { - this.worldGuard = WorldGuard.getInstance(); + try { + Class.forName("com.sk89q.worldguard.WorldGuard"); + this.isWorldGuard7 = true; + } catch (ClassNotFoundException ex) { + this.isWorldGuard7 = false; + try { + this.wg6inst = Class.forName("com.sk89q.worldguard.bukkit.WorldGuardPlugin").getMethod("inst").invoke(null); + this.wg6canBuild = this.wg6inst.getClass().getMethod("canBuild", Player.class, Location.class); + } catch (Exception ignored) { + } + } } @Override public JavaPlugin getPlugin() { - return WorldGuardPlugin.inst(); + try { + if (this.isWorldGuard7) + return com.sk89q.worldguard.bukkit.WorldGuardPlugin.inst(); + return (JavaPlugin) Class.forName("com.sk89q.worldguard.bukkit.WorldGuardPlugin").getMethod("inst").invoke(null); + } catch (Exception ex) { + return null; + } } @Override public boolean canBuild(Player player, Location location) { - RegionQuery q = worldGuard.getPlatform().getRegionContainer().createQuery(); - ApplicableRegionSet ars = q.getApplicableRegions(BukkitAdapter.adapt(player.getLocation())); - return ars.testState(WorldGuardPlugin.inst().wrapPlayer(player), Flags.BUILD); + if (this.isWorldGuard7) { + com.sk89q.worldguard.protection.regions.RegionQuery q = com.sk89q.worldguard.WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery(); + com.sk89q.worldguard.protection.ApplicableRegionSet ars = q.getApplicableRegions(com.sk89q.worldedit.bukkit.BukkitAdapter.adapt(player.getLocation())); + return ars.testState(com.sk89q.worldguard.bukkit.WorldGuardPlugin.inst().wrapPlayer(player), com.sk89q.worldguard.protection.flags.Flags.BUILD); + } else { + try { + return (boolean) this.wg6canBuild.invoke(this.wg6inst, player, location); + } catch (Exception ex) { + return true; + } + } } } \ No newline at end of file diff --git a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/listeners/BlockListeners.java b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/listeners/BlockListeners.java index 9f1e080..52c53db 100644 --- a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/listeners/BlockListeners.java +++ b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/listeners/BlockListeners.java @@ -1,7 +1,7 @@ package com.songoda.epicanchors.listeners; -import com.songoda.epicanchors.anchor.EAnchor; import com.songoda.epicanchors.EpicAnchorsPlugin; +import com.songoda.epicanchors.anchor.EAnchor; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Player; @@ -25,7 +25,8 @@ public class BlockListeners implements Listener { Block block = event.getBlock(); if (!instance.canBuild(player, block.getLocation()) - || event.getBlock().getType() != Material.valueOf(instance.getConfig().getString("Main.Anchor Block Material"))) return; + || event.getBlock().getType() != Material.valueOf(instance.getConfig().getString("Main.Anchor Block Material"))) + return; ItemStack item = event.getItemInHand(); diff --git a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/listeners/InteractListeners.java b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/listeners/InteractListeners.java index 7d78433..e7b5668 100644 --- a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/listeners/InteractListeners.java +++ b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/listeners/InteractListeners.java @@ -1,10 +1,11 @@ package com.songoda.epicanchors.listeners; +import com.songoda.epicanchors.EpicAnchorsPlugin; import com.songoda.epicanchors.anchor.EAnchor; import com.songoda.epicanchors.api.anchor.Anchor; import com.songoda.epicanchors.utils.Methods; -import com.songoda.epicanchors.EpicAnchorsPlugin; import com.songoda.epicanchors.utils.ServerVersion; +import com.songoda.epicanchors.utils.version.NMSUtil; import org.bukkit.GameMode; import org.bukkit.Material; import org.bukkit.Particle; @@ -63,16 +64,18 @@ public class InteractListeners implements Listener { if (player.getGameMode() != GameMode.CREATIVE) Methods.takeItem(player, 1); - player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 0.6F, 15.0F); + Sound sound = NMSUtil.getVersionNumber() > 8 ? Sound.ENTITY_PLAYER_LEVELUP : Sound.valueOf("LEVEL_UP"); + player.playSound(player.getLocation(), sound, 0.6F, 15.0F); - player.getWorld().spawnParticle(Particle.SPELL_WITCH, anchor.getLocation().add(.5,.5,.5), 100, .5, .5, .5); + if (NMSUtil.getVersionNumber() > 8) + player.getWorld().spawnParticle(Particle.SPELL_WITCH, anchor.getLocation().add(.5, .5, .5), 100, .5, .5, .5); event.setCancelled(true); return; } - ((EAnchor)anchor).overview(player); + ((EAnchor) anchor).overview(player); } diff --git a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/Methods.java b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/Methods.java index 127f5b1..573e7f3 100644 --- a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/Methods.java +++ b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/Methods.java @@ -1,8 +1,12 @@ package com.songoda.epicanchors.utils; import com.songoda.epicanchors.EpicAnchorsPlugin; -import com.songoda.epicspawners.utils.Debugger; -import org.bukkit.*; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -20,16 +24,16 @@ public class Methods { private static Map serializeCache = new HashMap<>(); public static void takeItem(Player p, int amt) { - if (p.getGameMode() != GameMode.CREATIVE) { - int result = p.getInventory().getItemInHand().getAmount() - amt; - if (result > 0) { - ItemStack is = p.getItemInHand(); - is.setAmount(is.getAmount() - amt); - p.setItemInHand(is); - } else { - p.setItemInHand(null); - } + if (p.getGameMode() != GameMode.CREATIVE) { + int result = p.getInventory().getItemInHand().getAmount() - amt; + if (result > 0) { + ItemStack is = p.getItemInHand(); + is.setAmount(is.getAmount() - amt); + p.setItemInHand(is); + } else { + p.setItemInHand(null); } + } } public static String formatName(int ticks2, boolean full) { @@ -67,10 +71,10 @@ public class Methods { ItemStack glass; if (rainbow) { glass = new ItemStack(EpicAnchorsPlugin.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) ? - Material.LEGACY_STAINED_GLASS_PANE : Material.valueOf("STAINED_GLASS_PANE"), 1, (short) randomNum); + Material.LEGACY_STAINED_GLASS_PANE : Material.valueOf("STAINED_GLASS_PANE"), 1, (short) randomNum); } else { glass = new ItemStack(EpicAnchorsPlugin.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) ? - Material.LEGACY_STAINED_GLASS_PANE : Material.valueOf("STAINED_GLASS_PANE"), 1, (short) type); + Material.LEGACY_STAINED_GLASS_PANE : Material.valueOf("STAINED_GLASS_PANE"), 1, (short) type); } ItemMeta glassmeta = glass.getItemMeta(); glassmeta.setDisplayName("§l"); diff --git a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/SettingsManager.java b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/SettingsManager.java index 8bdad48..affd416 100644 --- a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/SettingsManager.java +++ b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/SettingsManager.java @@ -1,6 +1,7 @@ package com.songoda.epicanchors.utils; import com.songoda.epicanchors.EpicAnchorsPlugin; +import com.songoda.epicanchors.utils.version.NMSUtil; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; @@ -14,8 +15,11 @@ import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; -import java.util.*; -import java.util.regex.Matcher; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.regex.Pattern; /** @@ -172,14 +176,14 @@ public class SettingsManager implements Listener { public enum Setting { o1("Main.Name-Tag", "&eAnchor &8(&7{REMAINING}&8)"), o2("Main.Anchor-Lore", "&7Place down to keep that chunk|&7loaded until the time runs out."), - o3("Main.Anchor Block Material", EpicAnchorsPlugin.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) ? "END_PORTAL_FRAME" : "ENDER_PORTAL_FRAME"), + o3("Main.Anchor Block Material", NMSUtil.getVersionNumber() > 12 ? "END_PORTAL_FRAME" : "ENDER_PORTAL_FRAME"), o4("Main.Add Time With Economy", true), o5("Main.Economy Cost", 5000.0), o6("Main.Add Time With XP", true), o7("Main.XP Cost", 10), o8("Main.Allow Anchor Breaking", false), - o9("Interfaces.Economy Icon", "SUNFLOWER"), - o10("Interfaces.XP Icon", "EXPERIENCE_BOTTLE"), + o9("Interfaces.Economy Icon", NMSUtil.getVersionNumber() > 12 ? "SUNFLOWER" : "GOLD_INGOT"), + o10("Interfaces.XP Icon", NMSUtil.getVersionNumber() > 12 ? "EXPERIENCE_BOTTLE" : "EXP_BOTTLE"), o11("Interfaces.Glass Type 1", 7), o12("Interfaces.Glass Type 2", 11), o13("Interfaces.Glass Type 3", 3), @@ -210,7 +214,9 @@ public class SettingsManager implements Listener { return EpicAnchorsPlugin.getInstance().getConfig().getString(setting); } - public char getChar() { return EpicAnchorsPlugin.getInstance().getConfig().getString(setting).charAt(0); } + public char getChar() { + return EpicAnchorsPlugin.getInstance().getConfig().getString(setting).charAt(0); + } } diff --git a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/gui/AbstractAnvilGUI.java b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/gui/AbstractAnvilGUI.java new file mode 100644 index 0000000..43e9ebf --- /dev/null +++ b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/gui/AbstractAnvilGUI.java @@ -0,0 +1,310 @@ +package com.songoda.epicanchors.utils.gui; + +import com.songoda.epicanchors.EpicAnchorsPlugin; +import com.songoda.epicanchors.utils.version.NMSUtil; +import org.bukkit.Bukkit; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +public class AbstractAnvilGUI { + + private static Class BlockPositionClass; + private static Class PacketPlayOutOpenWindowClass; + private static Class IChatBaseComponentClass; + private static Class ICraftingClass; + private static Class ContainerAnvilClass; + private static Class ChatMessageClass; + private static Class EntityHumanClass; + private static Class ContainerClass; + private static Class ContainerAccessClass; + private static Class WorldClass; + private static Class PlayerInventoryClass; + private static Class ContainersClass; + + private Player player; + private Map items = new HashMap<>(); + private OnClose onClose = null; + private Inventory inv; + private Listener listener; + + private Sound closeSound; + + static { + BlockPositionClass = NMSUtil.getNMSClass("BlockPosition"); + PacketPlayOutOpenWindowClass = NMSUtil.getNMSClass("PacketPlayOutOpenWindow"); + IChatBaseComponentClass = NMSUtil.getNMSClass("IChatBaseComponent"); + ICraftingClass = NMSUtil.getNMSClass("ICrafting"); + ContainerAnvilClass = NMSUtil.getNMSClass("ContainerAnvil"); + EntityHumanClass = NMSUtil.getNMSClass("EntityHuman"); + ChatMessageClass = NMSUtil.getNMSClass("ChatMessage"); + ContainerClass = NMSUtil.getNMSClass("Container"); + WorldClass = NMSUtil.getNMSClass("World"); + PlayerInventoryClass = NMSUtil.getNMSClass("PlayerInventory"); + + if (NMSUtil.getVersionNumber() > 13) { + ContainerAccessClass = NMSUtil.getNMSClass("ContainerAccess"); + ContainersClass = NMSUtil.getNMSClass("Containers"); + } + } + + public AbstractAnvilGUI(final Player player, final AnvilClickEventHandler handler) { + this.player = player; + + if (NMSUtil.getVersionNumber() > 8) { + this.closeSound = Sound.ENTITY_PLAYER_LEVELUP; + } else { + this.closeSound = Sound.valueOf("LEVEL_UP"); + } + + this.listener = new Listener() { + @EventHandler(priority = EventPriority.LOWEST) + public void onInventoryClick(InventoryClickEvent event) { + if (event.getWhoClicked() instanceof Player) { + + if (event.getInventory().equals(inv)) { + event.setCancelled(true); + + ItemStack item = event.getCurrentItem(); + int slot = event.getRawSlot(); + String name = ""; + + if (item != null) { + if (item.hasItemMeta()) { + ItemMeta meta = item.getItemMeta(); + + if (meta != null && meta.hasDisplayName()) { + name = meta.getDisplayName(); + } + } + } + + AnvilClickEvent clickEvent = new AnvilClickEvent(AnvilSlot.bySlot(slot), name); + + handler.onAnvilClick(clickEvent); + + if (clickEvent.getWillClose()) { + event.getWhoClicked().closeInventory(); + } + + if (clickEvent.getWillDestroy()) { + destroy(); + } + } + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onInventoryClose(InventoryCloseEvent event) { + if (event.getPlayer() instanceof Player) { + Inventory inv = event.getInventory(); + player.setLevel(player.getLevel() - 1); + if (inv.equals(inv)) { + inv.clear(); + player.playSound(player.getLocation(), closeSound, 1F, 1F); + Bukkit.getScheduler().scheduleSyncDelayedTask(EpicAnchorsPlugin.getInstance(), () -> { + if (onClose != null) onClose.OnClose(player, inv); + destroy(); + }, 1L); + + } + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerQuit(PlayerQuitEvent event) { + if (event.getPlayer().equals(getPlayer())) { + player.setLevel(player.getLevel() - 1); + destroy(); + } + } + }; + + Bukkit.getPluginManager().registerEvents(listener, EpicAnchorsPlugin.getInstance()); + } + + public Player getPlayer() { + return player; + } + + public void setSlot(AnvilSlot slot, ItemStack item) { + items.put(slot, item); + } + + public void open() { + player.setLevel(player.getLevel() + 1); + + try { + Object craftPlayer = NMSUtil.getCraftClass("entity.CraftPlayer").cast(player); + Method getHandleMethod = craftPlayer.getClass().getMethod("getHandle"); + Object entityPlayer = getHandleMethod.invoke(craftPlayer); + Object playerInventory = NMSUtil.getFieldObject(entityPlayer, NMSUtil.getField(entityPlayer.getClass(), "inventory", false)); + Object world = NMSUtil.getFieldObject(entityPlayer, NMSUtil.getField(entityPlayer.getClass(), "world", false)); + Object blockPosition = BlockPositionClass.getConstructor(int.class, int.class, int.class).newInstance(0, 0, 0); + + Object container; + + if (NMSUtil.getVersionNumber() > 13) { + container = ContainerAnvilClass + .getConstructor(int.class, PlayerInventoryClass, ContainerAccessClass) + .newInstance(7, playerInventory, ContainerAccessClass.getMethod("at", WorldClass, BlockPositionClass).invoke(null, world, blockPosition)); + } else { + container = ContainerAnvilClass + .getConstructor(PlayerInventoryClass, WorldClass, BlockPositionClass, EntityHumanClass) + .newInstance(playerInventory, world, blockPosition, entityPlayer); + } + + NMSUtil.getField(ContainerClass, "checkReachable", true).set(container, false); + + Method getBukkitViewMethod = container.getClass().getMethod("getBukkitView"); + Object bukkitView = getBukkitViewMethod.invoke(container); + Method getTopInventoryMethod = bukkitView.getClass().getMethod("getTopInventory"); + inv = (Inventory) getTopInventoryMethod.invoke(bukkitView); + + for (AnvilSlot slot : items.keySet()) { + inv.setItem(slot.getSlot(), items.get(slot)); + } + + Method nextContainerCounterMethod = entityPlayer.getClass().getMethod("nextContainerCounter"); + int c = (int) nextContainerCounterMethod.invoke(entityPlayer); + + Constructor chatMessageConstructor = ChatMessageClass.getConstructor(String.class, Object[].class); + Object inventoryTitle = chatMessageConstructor.newInstance("Repairing", new Object[]{}); + + Object packet; + + if (NMSUtil.getVersionNumber() > 13) { + packet = PacketPlayOutOpenWindowClass + .getConstructor(int.class, ContainersClass, IChatBaseComponentClass) + .newInstance(c, ContainersClass.getField("ANVIL").get(null), inventoryTitle); + } else { + packet = PacketPlayOutOpenWindowClass + .getConstructor(int.class, String.class, IChatBaseComponentClass, int.class) + .newInstance(c, "minecraft:anvil", inventoryTitle, 0); + } + + NMSUtil.sendPacket(player, packet); + + Field activeContainerField = NMSUtil.getField(EntityHumanClass, "activeContainer", true); + + if (activeContainerField != null) { + activeContainerField.set(entityPlayer, container); + NMSUtil.getField(ContainerClass, "windowId", true).set(activeContainerField.get(entityPlayer), c); + Method addSlotListenerMethod = activeContainerField.get(entityPlayer).getClass().getMethod("addSlotListener", ICraftingClass); + addSlotListenerMethod.invoke(activeContainerField.get(entityPlayer), entityPlayer); + + if (NMSUtil.getVersionNumber() > 13) { + ContainerClass.getMethod("setTitle", IChatBaseComponentClass).invoke(container, inventoryTitle); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void destroy() { + player = null; + items = null; + + HandlerList.unregisterAll(listener); + + listener = null; + } + + private OnClose getOnClose() { + return onClose; + } + + public void setOnClose(OnClose onClose) { + this.onClose = onClose; + } + + public void setCloseSound(Sound sound) { + closeSound = sound; + } + + public enum AnvilSlot { + INPUT_LEFT(0), + INPUT_RIGHT(1), + OUTPUT(2); + + private int slot; + + AnvilSlot(int slot) { + this.slot = slot; + } + + public static AnvilSlot bySlot(int slot) { + for (AnvilSlot anvilSlot : values()) { + if (anvilSlot.getSlot() == slot) { + return anvilSlot; + } + } + + return null; + } + + public int getSlot() { + return slot; + } + } + + @FunctionalInterface + public interface AnvilClickEventHandler { + void onAnvilClick(AnvilClickEvent event); + } + + public class AnvilClickEvent { + private AnvilSlot slot; + + private String name; + + private boolean close = true; + private boolean destroy = true; + + public AnvilClickEvent(AnvilSlot slot, String name) { + this.slot = slot; + this.name = name; + } + + public AnvilSlot getSlot() { + return slot; + } + + public String getName() { + return name; + } + + public boolean getWillClose() { + return close; + } + + public void setWillClose(boolean close) { + this.close = close; + } + + public boolean getWillDestroy() { + return destroy; + } + + public void setWillDestroy(boolean destroy) { + this.destroy = destroy; + } + } + +} \ No newline at end of file diff --git a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/gui/AbstractGUI.java b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/gui/AbstractGUI.java new file mode 100644 index 0000000..8c11398 --- /dev/null +++ b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/gui/AbstractGUI.java @@ -0,0 +1,226 @@ +package com.songoda.epicanchors.utils.gui; + +import com.songoda.epicanchors.EpicAnchorsPlugin; +import com.songoda.epicanchors.utils.Methods; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public abstract class AbstractGUI implements Listener { + + private static boolean listenersInitialized = false; + protected Player player; + protected Inventory inventory = null; + protected String setTitle = null; + protected boolean cancelBottom = false; + private Map clickables = new HashMap<>(); + private List onCloses = new ArrayList<>(); + private Map draggableRanges = new HashMap<>(); + + public AbstractGUI(Player player) { + this.player = player; + } + + public static void initializeListeners(JavaPlugin plugin) { + if (listenersInitialized) return; + + Bukkit.getPluginManager().registerEvents(new Listener() { + @EventHandler + public void onClickGUI(InventoryClickEvent event) { + Inventory inventory = event.getClickedInventory(); + if (inventory == null) return; + AbstractGUI gui = getGUIFromInventory(inventory); + Player player = (Player) event.getWhoClicked(); + + boolean bottom = false; + + InventoryType type = event.getClickedInventory().getType(); + if (type != InventoryType.CHEST && type != InventoryType.PLAYER) return; + + if (gui == null && event.getWhoClicked().getOpenInventory().getTopInventory() != null) { + Inventory top = event.getWhoClicked().getOpenInventory().getTopInventory(); + gui = getGUIFromInventory(top); + + if (gui != null && gui.cancelBottom) event.setCancelled(true); + bottom = true; + } + + if (gui == null) return; + + if (!bottom) event.setCancelled(true); + + if (!gui.draggableRanges.isEmpty() && !bottom) { + for (Map.Entry entry : gui.draggableRanges.entrySet()) { + Range range = entry.getKey(); + if (range.getMax() == range.getMin() && event.getSlot() == range.getMin() + || event.getSlot() >= range.getMin() && event.getSlot() <= range.getMax()) { + event.setCancelled(!entry.getValue()); + if (!entry.getValue()) break; + } + } + } + + Map entries = new HashMap<>(gui.clickables); + + for (Map.Entry entry : entries.entrySet()) { + Range range = entry.getKey(); + if (range.isBottom() && !bottom || !range.isBottom() && bottom || range.getClickType() != null && range.getClickType() != event.getClick()) + continue; + if (event.getSlot() >= range.getMin() && event.getSlot() <= range.getMax()) { + entry.getValue().Clickable(player, inventory, event.getCursor(), event.getSlot(), event.getClick()); + player.playSound(player.getLocation(), entry.getKey().getOnClickSound(), 1F, 1F); + } + } + } + + @EventHandler + public void onCloseGUI(InventoryCloseEvent event) { + Inventory inventory = event.getInventory(); + AbstractGUI gui = getGUIFromInventory(inventory); + + if (gui == null || gui.inventory == null) return; + + for (OnClose onClose : gui.onCloses) { + onClose.OnClose((Player) event.getPlayer(), inventory); + } + } + + private AbstractGUI getGUIFromInventory(Inventory inventory) { + if (inventory.getHolder() == null) return null; + InventoryHolder holder = inventory.getHolder(); + if (!(holder instanceof GUIHolder)) return null; + + return ((AbstractGUI.GUIHolder) holder).getGUI(); + } + }, plugin); + listenersInitialized = true; + } + + public void init(String title, int slots) { + if (inventory == null + || inventory.getSize() != slots + || ChatColor.translateAlternateColorCodes('&', title) != player.getOpenInventory().getTitle()) { + this.inventory = Bukkit.getServer().createInventory(new GUIHolder(), slots, Methods.formatText(title)); + this.setTitle = Methods.formatText(title); + if (this.clickables.size() == 0) + registerClickables(); + if (this.onCloses.size() == 0) + registerOnCloses(); + } + constructGUI(); + initializeListeners(EpicAnchorsPlugin.getInstance()); + player.openInventory(inventory); + } + + public abstract void constructGUI(); + + protected void addDraggable(Range range, boolean option) { + this.draggableRanges.put(range, option); + } + + protected void removeDraggable() { + this.draggableRanges.clear(); + } + + protected abstract void registerClickables(); + + protected abstract void registerOnCloses(); + + protected ItemStack createButton(int slot, Inventory inventory, ItemStack item, String name, String... lore) { + ItemMeta meta = item.getItemMeta(); + meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', name)); + if (lore != null && lore.length != 0) { + List newLore = new ArrayList<>(); + for (String line : lore) newLore.add(ChatColor.translateAlternateColorCodes('&', line)); + meta.setLore(newLore); + } + item.setItemMeta(meta); + inventory.setItem(slot, item); + return item; + } + + protected ItemStack createButton(int slot, ItemStack item, String name, String... lore) { + return createButton(slot, inventory, item, name, lore); + } + + protected ItemStack createButton(int slot, Inventory inventory, Material material, String name, String... lore) { + return createButton(slot, inventory, new ItemStack(material), name, lore); + } + + protected ItemStack createButton(int slot, Material material, String name, String... lore) { + return createButton(slot, inventory, new ItemStack(material), name, lore); + } + + protected ItemStack createButton(int slot, Material material, String name, ArrayList lore) { + return createButton(slot, material, name, lore.toArray(new String[0])); + } + + protected void registerClickable(int min, int max, ClickType clickType, boolean bottom, Clickable clickable) { + clickables.put(new Range(min, max, clickType, bottom), clickable); + } + + protected void registerClickable(int min, int max, ClickType clickType, Clickable clickable) { + registerClickable(min, max, clickType, false, clickable); + } + + protected void registerClickable(int slot, ClickType clickType, Clickable clickable) { + registerClickable(slot, slot, clickType, false, clickable); + } + + protected void registerClickable(int min, int max, Clickable clickable) { + registerClickable(min, max, null, false, clickable); + } + + protected void registerClickable(int slot, boolean bottom, Clickable clickable) { + registerClickable(slot, slot, null, bottom, clickable); + } + + protected void registerClickable(int slot, Clickable clickable) { + registerClickable(slot, slot, null, false, clickable); + } + + protected void resetClickables() { + clickables.clear(); + } + + protected void registerOnClose(OnClose onClose) { + onCloses.add(onClose); + } + + public Inventory getInventory() { + return inventory; + } + + public class GUIHolder implements InventoryHolder { + + @Override + public Inventory getInventory() { + return inventory; + } + + public AbstractGUI getGUI() { + return AbstractGUI.this; + } + } + + public String getSetTitle() { + return setTitle; + } +} \ No newline at end of file diff --git a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/gui/Clickable.java b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/gui/Clickable.java new file mode 100644 index 0000000..e1ed585 --- /dev/null +++ b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/gui/Clickable.java @@ -0,0 +1,11 @@ +package com.songoda.epicanchors.utils.gui; + +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +public interface Clickable { + + void Clickable(Player player, Inventory inventory, ItemStack cursor, int slot, ClickType type); +} \ No newline at end of file diff --git a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/gui/OnClose.java b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/gui/OnClose.java new file mode 100644 index 0000000..c7a0023 --- /dev/null +++ b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/gui/OnClose.java @@ -0,0 +1,10 @@ +package com.songoda.epicanchors.utils.gui; + +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; + +public interface OnClose { + + void OnClose(Player player, Inventory inventory); + +} \ No newline at end of file diff --git a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/gui/Range.java b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/gui/Range.java new file mode 100644 index 0000000..9c0c2d8 --- /dev/null +++ b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/gui/Range.java @@ -0,0 +1,55 @@ +package com.songoda.epicanchors.utils.gui; + +import com.songoda.epicanchors.utils.version.NMSUtil; +import org.bukkit.Sound; +import org.bukkit.event.inventory.ClickType; + +public class Range { + + private int min; + private int max; + private ClickType clickType; + private boolean bottom; + private Sound onClickSound; + + public Range(int min, int max, ClickType clickType, boolean bottom) { + this(min, max, null, clickType, bottom); + } + + public Range(int min, int max, Sound onClickSound, ClickType clickType, boolean bottom) { + this.min = min; + this.max = max; + this.clickType = clickType; + this.bottom = bottom; + + if (onClickSound == null) { + if (NMSUtil.getVersionNumber() > 8) { + this.onClickSound = Sound.UI_BUTTON_CLICK; + } else { + this.onClickSound = Sound.valueOf("CLICK"); + } + } else { + this.onClickSound = onClickSound; + } + } + + public int getMin() { + return min; + } + + public int getMax() { + return max; + } + + public ClickType getClickType() { + return clickType; + } + + public boolean isBottom() { + return bottom; + } + + public Sound getOnClickSound() { + return onClickSound; + } +} \ No newline at end of file diff --git a/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/version/NMSUtil.java b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/version/NMSUtil.java new file mode 100644 index 0000000..1fe8190 --- /dev/null +++ b/EpicAnchors-Plugin/src/main/java/com/songoda/epicanchors/utils/version/NMSUtil.java @@ -0,0 +1,100 @@ +package com.songoda.epicanchors.utils.version; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.lang.reflect.Field; + +public class NMSUtil { + + public static String getVersion() { + String name = Bukkit.getServer().getClass().getPackage().getName(); + return name.substring(name.lastIndexOf('.') + 1) + "."; + } + + public static int getVersionNumber() { + String name = getVersion().substring(3); + return Integer.valueOf(name.substring(0, name.length() - 4)); + } + + public static int getVersionReleaseNumber() { + String NMSVersion = getVersion(); + return Integer.valueOf(NMSVersion.substring(NMSVersion.length() - 2).replace(".", "")); + } + + public static Class getNMSClass(String className) { + try { + String fullName = "net.minecraft.server." + getVersion() + className; + Class clazz = Class.forName(fullName); + return clazz; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public static Class getCraftClass(String className) throws ClassNotFoundException { + try { + String fullName = "org.bukkit.craftbukkit." + getVersion() + className; + Class clazz = Class.forName(fullName); + return clazz; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public static Field getField(Class clazz, String name, boolean declared) { + try { + Field field; + + if (declared) { + field = clazz.getDeclaredField(name); + } else { + field = clazz.getField(name); + } + + field.setAccessible(true); + return field; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public static Object getFieldObject(Object object, Field field) { + try { + return field.get(object); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public static void setField(Object object, String fieldName, Object fieldValue, boolean declared) { + try { + Field field; + + if (declared) { + field = object.getClass().getDeclaredField(fieldName); + } else { + field = object.getClass().getField(fieldName); + } + + field.setAccessible(true); + field.set(object, fieldValue); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void sendPacket(Player player, Object packet) { + try { + Object handle = player.getClass().getMethod("getHandle").invoke(player); + Object playerConnection = handle.getClass().getField("playerConnection").get(handle); + playerConnection.getClass().getMethod("sendPacket", getNMSClass("Packet")).invoke(playerConnection, packet); + } catch (Exception e) { + e.printStackTrace(); + } + } +} \ No newline at end of file