Fix for 1.8, worldguard 6 support, fix epicspawners hard dependency

This commit is contained in:
Esophose 2019-05-11 02:15:40 -06:00
parent 2664203c1a
commit 164e4e995d
27 changed files with 854 additions and 77 deletions

View File

@ -4,7 +4,7 @@ stages:
variables: variables:
name: "EpicAnchors" name: "EpicAnchors"
path: "/builds/$CI_PROJECT_PATH" path: "/builds/$CI_PROJECT_PATH"
version: "1.2.3" version: "1.2.4"
build: build:
stage: build stage: build

View File

@ -1,8 +1,6 @@
package com.songoda.epicanchors.api; package com.songoda.epicanchors.api;
import org.bukkit.ChatColor;
/** /**
* The access point of the EpicAnchorsAPI, a class acting as a bridge between API * 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 * and plugin implementation. It is from here where developers should access the

View File

@ -22,7 +22,7 @@ public interface ClaimableProtectionPluginHook extends ProtectionPluginHook {
* @return true if the location is within the claim, false otherwise or if the * @return true if the location is within the claim, false otherwise or if the
* claim ID does not exist * 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 * 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 * @return the unique String ID. null if no claim exists
*/ */
public String getClaimID(String name); String getClaimID(String name);
} }

View File

@ -21,7 +21,7 @@ public interface ProtectionPluginHook {
* *
* @return the hooking plugin * @return the hooking plugin
*/ */
public JavaPlugin getPlugin(); JavaPlugin getPlugin();
/** /**
* Check whether the provided player may build at the specified location * 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 * @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 * 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 * @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()); return block != null && canBuild(player, block.getLocation());
} }

View File

@ -9,15 +9,24 @@ import com.songoda.epicanchors.api.anchor.AnchorManager;
import com.songoda.epicanchors.api.utils.ClaimableProtectionPluginHook; import com.songoda.epicanchors.api.utils.ClaimableProtectionPluginHook;
import com.songoda.epicanchors.api.utils.ProtectionPluginHook; import com.songoda.epicanchors.api.utils.ProtectionPluginHook;
import com.songoda.epicanchors.command.CommandManager; 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.BlockListeners;
import com.songoda.epicanchors.listeners.InteractListeners; 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.ConfigWrapper;
import com.songoda.epicanchors.utils.Methods; import com.songoda.epicanchors.utils.Methods;
import com.songoda.epicanchors.utils.ServerVersion; import com.songoda.epicanchors.utils.ServerVersion;
import com.songoda.epicanchors.utils.SettingsManager; import com.songoda.epicanchors.utils.SettingsManager;
import com.songoda.epicanchors.utils.updateModules.LocaleModule; import com.songoda.epicanchors.utils.updateModules.LocaleModule;
import com.songoda.epicanchors.utils.version.NMSUtil;
import com.songoda.update.Plugin; import com.songoda.update.Plugin;
import com.songoda.update.SongodaUpdate; import com.songoda.update.SongodaUpdate;
import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.ArrayUtils;
@ -25,6 +34,8 @@ import org.apache.commons.lang.math.NumberUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.Sound;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -237,6 +248,13 @@ public class EpicAnchorsPlugin extends JavaPlugin implements EpicAnchors {
anchor.getLocation().getWorld().dropItemNaturally(anchor.getLocation(), item); anchor.getLocation().getWorld().dropItemNaturally(anchor.getLocation(), item);
} }
location.getBlock().setType(Material.AIR); 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); getAnchorManager().removeAnchor(location);
} }
@ -247,6 +265,7 @@ public class EpicAnchorsPlugin extends JavaPlugin implements EpicAnchors {
public boolean isServerVersion(ServerVersion version) { public boolean isServerVersion(ServerVersion version) {
return serverVersion == version; return serverVersion == version;
} }
public boolean isServerVersion(ServerVersion... versions) { public boolean isServerVersion(ServerVersion... versions) {
return ArrayUtils.contains(versions, serverVersion); return ArrayUtils.contains(versions, serverVersion);
} }

View File

@ -6,7 +6,16 @@ import com.google.common.collect.Lists;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.plugin.java.JavaPlugin; 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.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; 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 * 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 * @param fileName the name of the file to save
* @return true if the operation was successful, false otherwise * @return true if the operation was successful, false otherwise
*/ */
@ -322,7 +331,7 @@ public class Locale {
/** /**
* Get a message set for a specific node * 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 * @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 * @return the message for the specified node. Default if none found
*/ */

View File

@ -3,19 +3,15 @@ package com.songoda.epicanchors.anchor;
import com.songoda.epicanchors.EpicAnchorsPlugin; import com.songoda.epicanchors.EpicAnchorsPlugin;
import com.songoda.epicanchors.api.anchor.Anchor; import com.songoda.epicanchors.api.anchor.Anchor;
import com.songoda.epicanchors.gui.GUIOverview; 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 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.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.RegisteredServiceProvider; 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 { public class EAnchor implements Anchor {
private Location location; private Location location;
@ -61,8 +57,11 @@ public class EAnchor implements Anchor {
} }
ticksLeft = ticksLeft + 20 * 60 * 30; ticksLeft = ticksLeft + 20 * 60 * 30;
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.getWorld().spawnParticle(Particle.SPELL_WITCH, getLocation().add(.5,.5,.5), 100, .5, .5, .5); 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 @Override

View File

@ -5,7 +5,7 @@ import org.bukkit.command.CommandSender;
public abstract class AbstractCommand { public abstract class AbstractCommand {
public enum ReturnType { SUCCESS, FAILURE, SYNTAX_ERROR } public enum ReturnType {SUCCESS, FAILURE, SYNTAX_ERROR}
private final AbstractCommand parent; private final AbstractCommand parent;

View File

@ -1,7 +1,7 @@
package com.songoda.epicanchors.command.commands; package com.songoda.epicanchors.command.commands;
import com.songoda.epicanchors.command.AbstractCommand;
import com.songoda.epicanchors.EpicAnchorsPlugin; import com.songoda.epicanchors.EpicAnchorsPlugin;
import com.songoda.epicanchors.command.AbstractCommand;
import com.songoda.epicanchors.utils.Methods; import com.songoda.epicanchors.utils.Methods;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;

View File

@ -1,8 +1,7 @@
package com.songoda.epicanchors.command.commands; package com.songoda.epicanchors.command.commands;
import com.songoda.epicanchors.command.AbstractCommand;
import com.songoda.epicanchors.EpicAnchorsPlugin; import com.songoda.epicanchors.EpicAnchorsPlugin;
import com.songoda.epicanchors.utils.Methods; import com.songoda.epicanchors.command.AbstractCommand;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;

View File

@ -1,7 +1,7 @@
package com.songoda.epicanchors.command.commands; package com.songoda.epicanchors.command.commands;
import com.songoda.epicanchors.command.AbstractCommand;
import com.songoda.epicanchors.EpicAnchorsPlugin; import com.songoda.epicanchors.EpicAnchorsPlugin;
import com.songoda.epicanchors.command.AbstractCommand;
import com.songoda.epicanchors.utils.Methods; import com.songoda.epicanchors.utils.Methods;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;

View File

@ -3,7 +3,7 @@ package com.songoda.epicanchors.gui;
import com.songoda.epicanchors.EpicAnchorsPlugin; import com.songoda.epicanchors.EpicAnchorsPlugin;
import com.songoda.epicanchors.anchor.EAnchor; import com.songoda.epicanchors.anchor.EAnchor;
import com.songoda.epicanchors.utils.Methods; 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.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -31,7 +31,7 @@ public class GUIOverview extends AbstractGUI {
} }
@Override @Override
protected void constructGUI() { public void constructGUI() {
String timeRemaining = Methods.makeReadable((long) (anchor.getTicksLeft() / 20) * 1000) + " remaining."; String timeRemaining = Methods.makeReadable((long) (anchor.getTicksLeft() / 20) * 1000) + " remaining.";
int nu = 0; int nu = 0;

View File

@ -4,7 +4,13 @@ import com.songoda.epicanchors.EpicAnchorsPlugin;
import com.songoda.epicanchors.api.anchor.Anchor; import com.songoda.epicanchors.api.anchor.Anchor;
import com.songoda.epicanchors.utils.ServerVersion; import com.songoda.epicanchors.utils.ServerVersion;
import com.songoda.epicspawners.api.EpicSpawnersAPI; 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.block.Block;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
@ -56,11 +62,11 @@ public class AnchorHandler {
} catch (ReflectiveOperationException e) { } catch (ReflectiveOperationException e) {
e.printStackTrace(); 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. Bukkit.getScheduler().scheduleSyncRepeatingTask(instance, this::doAnchorCheck, 0, 1); //ToDo: way to fast.
if (instance.isServerVersionAtLeast(ServerVersion.V1_9)) 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() { 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)); 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)) if (instance.isServerVersionAtLeast(ServerVersion.V1_9))
location.getWorld().spawnParticle(Particle.LAVA, location.clone().add(.5, .5, .5), 5, 0, 0, 0, 5); 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) 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); location.getBlock().setType(Material.AIR);
chunk.unload(); chunk.unload();
} }

View File

@ -1,34 +1,56 @@
package com.songoda.epicanchors.hooks; 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 com.songoda.epicanchors.api.utils.ProtectionPluginHook;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import java.lang.reflect.Method;
public class HookWorldGuard implements ProtectionPluginHook { public class HookWorldGuard implements ProtectionPluginHook {
private final WorldGuard worldGuard; private Method wg6canBuild;
private Object wg6inst;
private boolean isWorldGuard7;
public HookWorldGuard() { 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 @Override
public JavaPlugin getPlugin() { 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 @Override
public boolean canBuild(Player player, Location location) { public boolean canBuild(Player player, Location location) {
RegionQuery q = worldGuard.getPlatform().getRegionContainer().createQuery(); if (this.isWorldGuard7) {
ApplicableRegionSet ars = q.getApplicableRegions(BukkitAdapter.adapt(player.getLocation())); com.sk89q.worldguard.protection.regions.RegionQuery q = com.sk89q.worldguard.WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();
return ars.testState(WorldGuardPlugin.inst().wrapPlayer(player), Flags.BUILD); 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;
}
}
} }
} }

View File

@ -1,7 +1,7 @@
package com.songoda.epicanchors.listeners; package com.songoda.epicanchors.listeners;
import com.songoda.epicanchors.anchor.EAnchor;
import com.songoda.epicanchors.EpicAnchorsPlugin; import com.songoda.epicanchors.EpicAnchorsPlugin;
import com.songoda.epicanchors.anchor.EAnchor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -25,7 +25,8 @@ public class BlockListeners implements Listener {
Block block = event.getBlock(); Block block = event.getBlock();
if (!instance.canBuild(player, block.getLocation()) 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(); ItemStack item = event.getItemInHand();

View File

@ -1,10 +1,11 @@
package com.songoda.epicanchors.listeners; package com.songoda.epicanchors.listeners;
import com.songoda.epicanchors.EpicAnchorsPlugin;
import com.songoda.epicanchors.anchor.EAnchor; import com.songoda.epicanchors.anchor.EAnchor;
import com.songoda.epicanchors.api.anchor.Anchor; import com.songoda.epicanchors.api.anchor.Anchor;
import com.songoda.epicanchors.utils.Methods; import com.songoda.epicanchors.utils.Methods;
import com.songoda.epicanchors.EpicAnchorsPlugin;
import com.songoda.epicanchors.utils.ServerVersion; import com.songoda.epicanchors.utils.ServerVersion;
import com.songoda.epicanchors.utils.version.NMSUtil;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Particle; import org.bukkit.Particle;
@ -63,16 +64,18 @@ public class InteractListeners implements Listener {
if (player.getGameMode() != GameMode.CREATIVE) if (player.getGameMode() != GameMode.CREATIVE)
Methods.takeItem(player, 1); 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); event.setCancelled(true);
return; return;
} }
((EAnchor)anchor).overview(player); ((EAnchor) anchor).overview(player);
} }

View File

@ -1,8 +1,12 @@
package com.songoda.epicanchors.utils; package com.songoda.epicanchors.utils;
import com.songoda.epicanchors.EpicAnchorsPlugin; import com.songoda.epicanchors.EpicAnchorsPlugin;
import com.songoda.epicspawners.utils.Debugger; import org.bukkit.Bukkit;
import org.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.block.Block;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -20,16 +24,16 @@ public class Methods {
private static Map<String, Location> serializeCache = new HashMap<>(); private static Map<String, Location> serializeCache = new HashMap<>();
public static void takeItem(Player p, int amt) { public static void takeItem(Player p, int amt) {
if (p.getGameMode() != GameMode.CREATIVE) { if (p.getGameMode() != GameMode.CREATIVE) {
int result = p.getInventory().getItemInHand().getAmount() - amt; int result = p.getInventory().getItemInHand().getAmount() - amt;
if (result > 0) { if (result > 0) {
ItemStack is = p.getItemInHand(); ItemStack is = p.getItemInHand();
is.setAmount(is.getAmount() - amt); is.setAmount(is.getAmount() - amt);
p.setItemInHand(is); p.setItemInHand(is);
} else { } else {
p.setItemInHand(null); p.setItemInHand(null);
}
} }
}
} }
public static String formatName(int ticks2, boolean full) { public static String formatName(int ticks2, boolean full) {
@ -67,10 +71,10 @@ public class Methods {
ItemStack glass; ItemStack glass;
if (rainbow) { if (rainbow) {
glass = new ItemStack(EpicAnchorsPlugin.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) ? 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 { } else {
glass = new ItemStack(EpicAnchorsPlugin.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) ? 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(); ItemMeta glassmeta = glass.getItemMeta();
glassmeta.setDisplayName("§l"); glassmeta.setDisplayName("§l");

View File

@ -1,6 +1,7 @@
package com.songoda.epicanchors.utils; package com.songoda.epicanchors.utils;
import com.songoda.epicanchors.EpicAnchorsPlugin; import com.songoda.epicanchors.EpicAnchorsPlugin;
import com.songoda.epicanchors.utils.version.NMSUtil;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
@ -14,8 +15,11 @@ import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import java.util.*; import java.util.ArrayList;
import java.util.regex.Matcher; import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
@ -172,14 +176,14 @@ public class SettingsManager implements Listener {
public enum Setting { public enum Setting {
o1("Main.Name-Tag", "&eAnchor &8(&7{REMAINING}&8)"), 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."), 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), o4("Main.Add Time With Economy", true),
o5("Main.Economy Cost", 5000.0), o5("Main.Economy Cost", 5000.0),
o6("Main.Add Time With XP", true), o6("Main.Add Time With XP", true),
o7("Main.XP Cost", 10), o7("Main.XP Cost", 10),
o8("Main.Allow Anchor Breaking", false), o8("Main.Allow Anchor Breaking", false),
o9("Interfaces.Economy Icon", "SUNFLOWER"), o9("Interfaces.Economy Icon", NMSUtil.getVersionNumber() > 12 ? "SUNFLOWER" : "GOLD_INGOT"),
o10("Interfaces.XP Icon", "EXPERIENCE_BOTTLE"), o10("Interfaces.XP Icon", NMSUtil.getVersionNumber() > 12 ? "EXPERIENCE_BOTTLE" : "EXP_BOTTLE"),
o11("Interfaces.Glass Type 1", 7), o11("Interfaces.Glass Type 1", 7),
o12("Interfaces.Glass Type 2", 11), o12("Interfaces.Glass Type 2", 11),
o13("Interfaces.Glass Type 3", 3), o13("Interfaces.Glass Type 3", 3),
@ -210,7 +214,9 @@ public class SettingsManager implements Listener {
return EpicAnchorsPlugin.getInstance().getConfig().getString(setting); 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);
}
} }

View File

@ -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<AnvilSlot, ItemStack> 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;
}
}
}

View File

@ -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<Range, Clickable> clickables = new HashMap<>();
private List<OnClose> onCloses = new ArrayList<>();
private Map<Range, Boolean> 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<Range, Boolean> 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<Range, Clickable> entries = new HashMap<>(gui.clickables);
for (Map.Entry<Range, Clickable> 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<String> 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<String> 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;
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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();
}
}
}