fix doublegui plugin close dupe, add more compatibility sounds, convert update gui to new system, add highlighter

This commit is contained in:
jascotty2 2019-08-27 20:48:42 -05:00
parent 49d8503592
commit c5745477f7
14 changed files with 1221 additions and 962 deletions

View File

@ -1,5 +1,6 @@
package com.songoda.core;
import com.songoda.core.compatibility.LegacyMaterials;
import org.bukkit.plugin.java.JavaPlugin;
import org.json.simple.JSONObject;
@ -7,20 +8,25 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class PluginInfo {
public final class PluginInfo {
private final JavaPlugin javaPlugin;
private final int songodaId;
protected final JavaPlugin javaPlugin;
protected final int songodaId;
protected final String coreIcon;
protected final LegacyMaterials icon;
private final List<PluginInfoModule> modules = new ArrayList<>();
private boolean hasUpdate = false;
private String latestVersion;
private String notification;
private String changeLog;
private String marketplaceLink;
private JSONObject json;
protected PluginInfo(JavaPlugin javaPlugin, int songodaId) {
protected PluginInfo(JavaPlugin javaPlugin, int songodaId, String icon) {
this.javaPlugin = javaPlugin;
this.songodaId = songodaId;
this.coreIcon = icon;
this.icon = LegacyMaterials.getMaterial(icon);
}
public String getLatestVersion() {
@ -29,6 +35,7 @@ public class PluginInfo {
public void setLatestVersion(String latestVersion) {
this.latestVersion = latestVersion;
hasUpdate = !javaPlugin.getDescription().getVersion().equalsIgnoreCase(latestVersion);
}
public String getNotification() {
@ -39,6 +46,14 @@ public class PluginInfo {
this.notification = notification;
}
public boolean hasUpdate() {
return hasUpdate;
}
public void setHasUpdate(boolean hasUpdate) {
this.hasUpdate = hasUpdate;
}
public String getChangeLog() {
return changeLog;
}

View File

@ -1,6 +1,8 @@
package com.songoda.core;
import com.songoda.core.commands.CommandManager;
import com.songoda.core.compatibility.LegacyMaterials;
import com.songoda.core.gui.GUIManager;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@ -35,18 +37,23 @@ public class SongodaCore {
private static SongodaCore INSTANCE = null;
private JavaPlugin piggybackedPlugin;
protected GUIManager guiManager;
private final CommandManager commandManager;
private final EventListener loginListener = new EventListener();
private final HashMap<UUID, Long> lastCheck = new HashMap();
public static void registerPlugin(JavaPlugin plugin, int pluginID) {
public static void registerPlugin(JavaPlugin plugin, int pluginID, LegacyMaterials icon) {
registerPlugin(plugin, pluginID, icon == null ? "STONE" : icon.name());
}
public static void registerPlugin(JavaPlugin plugin, int pluginID, String icon) {
if(INSTANCE == null) {
// First: are there any other instances of SongodaCore active?
for (Class<?> clazz : Bukkit.getServicesManager().getKnownServices()) {
if(clazz.getSimpleName().equals("SongodaCore")) {
try {
// use the active service
clazz.getMethod("registerPlugin", JavaPlugin.class, int.class).invoke(null, plugin, pluginID);
clazz.getMethod("registerPlugin", JavaPlugin.class, int.class, String.class).invoke(null, plugin, pluginID, icon);
return;
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ignored) {
@ -57,7 +64,7 @@ public class SongodaCore {
INSTANCE = new SongodaCore(plugin);
Bukkit.getServicesManager().register(SongodaCore.class, INSTANCE, plugin, ServicePriority.Normal);
}
INSTANCE.register(plugin, pluginID);
INSTANCE.register(plugin, pluginID, icon);
}
public SongodaCore(JavaPlugin javaPlugin) {
@ -66,11 +73,15 @@ public class SongodaCore {
commandManager.registerCommandDynamically(new SongodaCoreCommand(this))
.addSubCommand(new SongodaCoreDiagCommand(this));
Bukkit.getPluginManager().registerEvents(loginListener, javaPlugin);
// we aggressevely want to own this command
Bukkit.getScheduler().runTaskLaterAsynchronously(javaPlugin, ()->{CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager);}, 20 * 60 * 1);
Bukkit.getScheduler().runTaskLaterAsynchronously(javaPlugin, ()->{CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager);}, 20 * 60 * 2);
Bukkit.getScheduler().runTaskLaterAsynchronously(javaPlugin, ()->{CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager);}, 20 * 60 * 2);
}
private void register(JavaPlugin plugin, int pluginID) {
private void register(JavaPlugin plugin, int pluginID, String icon) {
System.out.println(getPrefix() + "Hooked " + plugin.getName() + ".");
PluginInfo info = new PluginInfo(plugin, pluginID);
PluginInfo info = new PluginInfo(plugin, pluginID, icon);
// don't forget to check for language pack updates ;)
info.addModule(new LocaleModule());
registeredPlugins.add(info);
@ -166,6 +177,9 @@ public class SongodaCore {
}
if(event.getPlugin() == piggybackedPlugin) {
// uh-oh! Abandon ship!!
if(guiManager != null) {
guiManager.closeAll();
}
Bukkit.getServicesManager().unregisterAll(piggybackedPlugin);
// can we move somewhere else?
if((pi = registeredPlugins.stream().findFirst().orElse(null)) != null) {
@ -174,6 +188,7 @@ public class SongodaCore {
Bukkit.getServicesManager().register(SongodaCore.class, INSTANCE, piggybackedPlugin, ServicePriority.Normal);
Bukkit.getPluginManager().registerEvents(loginListener, piggybackedPlugin);
CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager);
guiManager = null;
}
}
}

View File

@ -1,6 +1,7 @@
package com.songoda.core;
import com.songoda.core.commands.AbstractCommand;
import com.songoda.core.gui.GUIManager;
import java.util.List;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -16,7 +17,10 @@ class SongodaCoreCommand extends AbstractCommand {
@Override
protected ReturnType runCommand(CommandSender sender, String... args) {
if(sender instanceof Player) {
new SongodaCoreOverviewGUI(instance, (Player) sender);
if(instance.guiManager == null) {
instance.guiManager = new GUIManager(SongodaCore.getHijackedPlugin());
}
instance.guiManager.showGUI((Player) sender, new SongodaCoreOverviewGUI(instance));
} else {
sender.sendMessage("/songoda diag");
}

View File

@ -1,50 +1,50 @@
package com.songoda.core;
import com.songoda.core.utils.gui.AbstractGUI;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import com.songoda.core.compatibility.LegacyMaterials;
import com.songoda.core.gui.GUI;
import com.songoda.core.gui.GuiUtils;
import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.event.inventory.ClickType;
class SongodaCoreOverviewGUI extends AbstractGUI {
final class SongodaCoreOverviewGUI extends GUI {
private final SongodaCore update;
protected SongodaCoreOverviewGUI(SongodaCore update, Player player) {
super(player);
protected SongodaCoreOverviewGUI(SongodaCore update) {
this.update = update;
init("Songoda Update", 36);
}
@Override
protected void constructGUI() {
List<PluginInfo> plugins = update.getPlugins();
// could do pages, too, but don't think we'll have that many at a time for a while
int max = (int) Math.ceil(plugins.size() / 9.);
setRows(max);
setTitle("Songoda Plugins");
// TODO: this could use some decorating
for (int i = 0; i < plugins.size(); i++) {
PluginInfo plugin = plugins.get(i);
createButton(i + 9, Material.STONE, "&6" + plugin.getJavaPlugin().getName(),
"&7Latest Version: " + plugin.getLatestVersion(),
"&7Installed Version: " + plugin.getJavaPlugin().getDescription().getVersion(),
"",
"Change log:",
plugin.getChangeLog(),
"",
"&6Click for the marketplace page link.");
registerClickable(i + 9, ((player1, inventory1, cursor, slot, type) ->
player.sendMessage(plugin.getMarketplaceLink())));
if (plugin.hasUpdate()) {
setButton(i, GuiUtils.createButtonItem(plugin.icon != null ? plugin.icon : LegacyMaterials.STONE,
ChatColor.GOLD + plugin.getJavaPlugin().getName(),
ChatColor.GRAY + "Latest Version: " + plugin.getLatestVersion(),
ChatColor.GRAY + "Installed Version: " + plugin.getJavaPlugin().getDescription().getVersion(),
"",
"Change log:",
plugin.getChangeLog(),
"",
ChatColor.GOLD + "Click for the marketplace page link."
),
ClickType.LEFT, (player, inv, gui, cursor, slot, type) -> player.sendMessage(plugin.getMarketplaceLink()));
highlightItem(i);
} else {
setButton(i, GuiUtils.createButtonItem(plugin.icon != null ? plugin.icon : LegacyMaterials.STONE,
ChatColor.GOLD + plugin.getJavaPlugin().getName(),
ChatColor.GRAY + "Installed Version: " + plugin.getJavaPlugin().getDescription().getVersion(),
"",
ChatColor.GOLD + "Click for the marketplace page link."
),
ClickType.LEFT, (player, inv, gui, cursor, slot, type) -> player.sendMessage(plugin.getMarketplaceLink()));
}
}
}
@Override
protected void registerClickables() {
}
@Override
protected void registerOnCloses() {
}
}

View File

@ -8,13 +8,13 @@ public enum ServerVersion {
UNKNOWN, V1_7, V1_8, V1_9, V1_10, V1_11, V1_12, V1_13, V1_14, V1_15, V1_16, V1_17, V1_18, V1_19, V1_20;
private final static String serverPackagePath = Bukkit.getServer().getClass().getPackage().getName();
private final static String serverPackageVersion = serverPackagePath.substring(serverPackagePath.lastIndexOf('.') + 1).toUpperCase();
private final static String serverPackageVersion = serverPackagePath.substring(serverPackagePath.lastIndexOf('.') + 1);
private static ServerVersion serverVersion = UNKNOWN;
private static String serverReleaseVersion;
static {
for (ServerVersion version : values()) {
if (serverPackageVersion.startsWith(version.name())) {
if (serverPackageVersion.toUpperCase().startsWith(version.name())) {
serverVersion = version;
serverReleaseVersion = serverPackageVersion.substring(version.name().length() + 2);
}

View File

@ -7,6 +7,7 @@ import com.songoda.core.gui.methods.Droppable;
import com.songoda.core.gui.methods.Openable;
import com.songoda.core.gui.methods.Pagable;
import com.songoda.core.gui.methods.SimpleClickable;
import com.songoda.core.utils.ItemUtils;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -18,9 +19,9 @@ import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
/**
* DO NOT USE YET!
* TODO: does not restore inventory if server is shut down while player inventory is open (1.8)
* TODO: does not restore inventory if server crashes while player inventory is open
* Method to fix: save inv + ender slot to file, store paper in ender inv with name of cache file, check for paper item in slot when loading
* Or just manually manage all inventories in a file and remove when restored
*
* @since 2019-08-25
* @author jascotty2
@ -106,6 +107,25 @@ public class DoubleGUI extends GUI {
return this;
}
public DoubleGUI highlightPlayerItem(int cell) {
final int invCell = invOffset(cell);
ItemStack item = cellItems.get(invCell);
if (item != null) {
setPlayerItem(cell, ItemUtils.addGlow(item));
}
return this;
}
public DoubleGUI highlightPlayerItem(int row, int col) {
final int cell = col + row * 9;
final int invCell = invOffset(cell);
ItemStack item = cellItems.get(invCell);
if (item != null) {
setPlayerItem(cell, ItemUtils.addGlow(item));
}
return this;
}
public DoubleGUI setPlayerAction(int cell, Clickable action) {
setConditional(invOffset(cell), null, action, null);
return this;
@ -307,7 +327,7 @@ public class DoubleGUI extends GUI {
ItemStack[] oldInv = player.getInventory().getContents();
ItemStack[] newInv = new ItemStack[oldInv.length];
for (int i = 0; i < newInv.length; ++i) {
for (int i = 0; i < 36; ++i) {
final ItemStack item = cellItems.get(invOffset(i < 9 ? i + 27 : i - 9));
newInv[i] = item != null ? item : blankItem;
}
@ -402,6 +422,16 @@ public class DoubleGUI extends GUI {
return (DoubleGUI) super.setItem(row, col, item);
}
@Override
public DoubleGUI highlightItem(int cell) {
return (DoubleGUI) super.highlightItem(cell);
}
@Override
public DoubleGUI highlightItem(int row, int col) {
return (DoubleGUI) super.highlightItem(row, col);
}
@Override
public DoubleGUI updateItem(int cell, String name, String... lore) {
return (DoubleGUI) super.updateItem(cell, name, lore);

View File

@ -7,6 +7,7 @@ import com.songoda.core.gui.methods.Droppable;
import com.songoda.core.gui.methods.Closable;
import com.songoda.core.gui.methods.Openable;
import com.songoda.core.gui.methods.SimpleClickable;
import com.songoda.core.utils.ItemUtils;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@ -15,6 +16,7 @@ import java.util.stream.Collectors;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
@ -32,7 +34,7 @@ public class GUI {
protected Inventory inventory;
protected String title;
protected GUIType type = GUIType.STANDARD;
protected GUIType inventoryType = GUIType.STANDARD;
protected int rows, page, pages;
protected boolean acceptsItems = false;
protected boolean allowDropItems = true;
@ -58,7 +60,7 @@ public class GUI {
}
public GUI(GUIType type) {
this.type = type;
this.inventoryType = type;
switch (type) {
case HOPPER:
case DISPENSER:
@ -140,7 +142,7 @@ public class GUI {
}
public GUIType getType() {
return type;
return inventoryType;
}
public GUI setUnlocked(int cell) {
@ -190,7 +192,7 @@ public class GUI {
}
public GUI setRows(int rows) {
switch (type) {
switch (inventoryType) {
case HOPPER:
case DISPENSER:
break;
@ -222,6 +224,40 @@ public class GUI {
return this;
}
public GUI highlightItem(int cell) {
ItemStack item = cellItems.get(cell);
if (item != null && item.getType() != Material.AIR) {
setItem(cell, ItemUtils.addGlow(item));
}
return this;
}
public GUI highlightItem(int row, int col) {
final int cell = col + row * 9;
ItemStack item = cellItems.get(cell);
if (item != null && item.getType() != Material.AIR) {
setItem(cell, ItemUtils.addGlow(item));
}
return this;
}
public GUI removeHighlight(int cell) {
ItemStack item = cellItems.get(cell);
if (item != null && item.getType() != Material.AIR) {
setItem(cell, ItemUtils.removeGlow(item));
}
return this;
}
public GUI removeHighlight(int row, int col) {
final int cell = col + row * 9;
ItemStack item = cellItems.get(cell);
if (item != null && item.getType() != Material.AIR) {
setItem(cell, ItemUtils.removeGlow(item));
}
return this;
}
public GUI updateItem(int row, int col, String name, String... lore) {
return updateItem(col + row * 9, name, lore);
}
@ -571,7 +607,7 @@ public class GUI {
protected Inventory generateInventory() {
final int cells = rows * 9;
InventoryType t = type == null ? InventoryType.CHEST : type.type;
InventoryType t = inventoryType == null ? InventoryType.CHEST : inventoryType.type;
switch (t) {
case DISPENSER:
case HOPPER:

View File

@ -27,6 +27,7 @@ public class GUIManager {
final GuiListener listener = new GuiListener(this);
final Map<Player, Inventory> openInventories = new HashMap();
private boolean initialized = false;
private boolean shutdown = false;
public GUIManager(Plugin plugin) {
this.plugin = plugin;
@ -38,6 +39,7 @@ public class GUIManager {
public void init() {
Bukkit.getPluginManager().registerEvents(listener, plugin);
initialized = true;
shutdown = false;
}
/**
@ -118,7 +120,11 @@ public class GUIManager {
if (!gui.allowDropItems) {
player.setItemOnCursor(null);
}
Bukkit.getScheduler().runTaskLater(manager.plugin, () -> gui.onClose(manager, player), 1);
if(manager.shutdown) {
gui.onClose(manager, player);
} else {
Bukkit.getScheduler().runTaskLater(manager.plugin, () -> gui.onClose(manager, player), 1);
}
manager.openInventories.remove(player);
}
}
@ -127,6 +133,7 @@ public class GUIManager {
void onDisable(PluginDisableEvent event) {
if (event.getPlugin() == manager.plugin) {
// uh-oh! Abandon ship!!
manager.shutdown = true;
manager.closeAll();
manager.initialized = false;
}

View File

@ -5,7 +5,7 @@ import org.bukkit.configuration.MemorySection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.Plugin;
import java.io.*;
import java.util.ArrayList;
import java.util.LinkedHashMap;
@ -14,9 +14,9 @@ import java.util.Map;
public class Config {
private final JavaPlugin plugin;
private final Plugin plugin;
private final String folderName, fileName;
private FileConfiguration fileConfiguration;
private File configFile;
@ -319,7 +319,7 @@ public class Config {
return fileName;
}
public JavaPlugin getPlugin() {
public Plugin getPlugin() {
return plugin;
}
}

View File

@ -15,16 +15,16 @@ import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.*;
import org.bukkit.plugin.Plugin;
/**
* Created by songoda on 6/4/2017.
*/
public class SettingsManagerOld implements Listener {
private final JavaPlugin plugin;
private final Plugin plugin;
private final Config config;
private Map<Player, String> cat = new HashMap<>();

View File

@ -3,7 +3,6 @@ package com.songoda.core.settings.editor;
import com.songoda.core.compatibility.LegacyMaterials;
import com.songoda.core.settings.Config;
import com.songoda.core.utils.gui.AbstractGUI;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;

View File

@ -8,14 +8,21 @@ import com.mojang.authlib.properties.Property;
import com.songoda.core.compatibility.LegacyMaterials;
import com.songoda.core.compatibility.ServerVersion;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Base64;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Stream;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.OfflinePlayer;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.enchantments.EnchantmentTarget;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta;
@ -41,6 +48,119 @@ public class ItemUtils {
return clone;
}
static Class cb_ItemStack = NMSUtils.getCraftClass("inventory.CraftItemStack");
static Class mc_ItemStack = NMSUtils.getNMSClass("ItemStack");
static Class mc_NBTTagCompound = NMSUtils.getNMSClass("NBTTagCompound");
static Class mc_NBTTagList = NMSUtils.getNMSClass("NBTTagList");
static Class mc_NBTBase = NMSUtils.getNMSClass("NBTBase");
static Method mc_ItemStack_getTag;
static Method mc_ItemStack_setTag;
static Method mc_NBTTagCompound_set;
static Method mc_NBTTagCompound_remove;
static Method mc_NBTTagCompound_setShort;
static Method mc_NBTTagCompound_setString;
static Method mc_NBTTagList_add;
static Method cb_CraftItemStack_asNMSCopy;
static Method cb_CraftItemStack_asCraftMirror;
static {
if(cb_ItemStack != null) {
try {
mc_ItemStack_getTag = mc_ItemStack.getDeclaredMethod("getTag");
mc_ItemStack_setTag = mc_ItemStack.getDeclaredMethod("setTag", mc_NBTTagCompound);
mc_NBTTagCompound_set = mc_NBTTagCompound.getDeclaredMethod("set", String.class, mc_NBTBase);
mc_NBTTagCompound_remove = mc_NBTTagCompound.getDeclaredMethod("remove", String.class);
mc_NBTTagCompound_setShort = mc_NBTTagCompound.getDeclaredMethod("setShort", String.class, short.class);
mc_NBTTagCompound_setString = mc_NBTTagCompound.getDeclaredMethod("setString", String.class, String.class);
cb_CraftItemStack_asNMSCopy = cb_ItemStack.getDeclaredMethod("asNMSCopy", ItemStack.class);
cb_CraftItemStack_asCraftMirror = cb_ItemStack.getDeclaredMethod("asCraftMirror", mc_ItemStack);
mc_NBTTagList_add = ServerVersion.isServerVersionAtLeast(ServerVersion.V1_14)
? NMSUtils.getPrivateMethod(mc_NBTTagList, "a", mc_NBTBase)
: mc_NBTTagList.getDeclaredMethod("add", mc_NBTBase);
} catch (Exception ex) {
Logger.getLogger(ItemUtils.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
/**
* Make an item glow as if it contained an enchantment. <br>
* Tested working 1.8-1.14
*
* @param item itemstack to create a glowing copy of
* @return copy of item with a blank enchantment nbt tag
*/
public static ItemStack addGlow(ItemStack item) {
// from 1.11 up, fake enchantments don't work without more steps
// creating a new Enchantment involves some very involved reflection,
// as the namespace is the same but until 1.12 requires an int, but versions after require a String
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_11)) {
item.addUnsafeEnchantment(Enchantment.DURABILITY, 1);
// you can at least hide the enchantment, though
ItemMeta m = item.getItemMeta();
m.addItemFlags(ItemFlag.HIDE_ENCHANTS);
item.setItemMeta(m);
return item;
} else {
// hack a fake enchant onto the item
// Confirmed works on 1.8, 1.9, 1.10
// Does not work 1.11+ (minecraft ignores the glitched enchantment)
if (item != null && item.getType() != Material.AIR && cb_CraftItemStack_asCraftMirror != null) {
try {
Object nmsStack = cb_CraftItemStack_asNMSCopy.invoke(null, item);
Object tag = mc_ItemStack_getTag.invoke(nmsStack);
if (tag == null) {
tag = mc_NBTTagCompound.newInstance();
}
// set to have a fake enchantment
Object enchantmentList = mc_NBTTagList.newInstance();
/*
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)) {
// Servers from 1.13 and up change the id to a string
Object fakeEnchantment = mc_NBTTagCompound.newInstance();
mc_NBTTagCompound_setString.invoke(fakeEnchantment, "id", "glow:glow");
mc_NBTTagCompound_setShort.invoke(fakeEnchantment, "lvl", (short) 0);
mc_NBTTagList_add.invoke(enchantmentList, fakeEnchantment);
} else if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_11)) {
// Servers from 1.11 and up require *something* in the enchantment field
Object fakeEnchantment = mc_NBTTagCompound.newInstance();
mc_NBTTagCompound_setShort.invoke(fakeEnchantment, "id", (short) 245);
mc_NBTTagCompound_setShort.invoke(fakeEnchantment, "lvl", (short) 1);
mc_NBTTagList_add.invoke(enchantmentList, fakeEnchantment);
}//*/
mc_NBTTagCompound_set.invoke(tag, "ench", enchantmentList);
mc_ItemStack_setTag.invoke(nmsStack, tag);
item = (ItemStack) cb_CraftItemStack_asCraftMirror.invoke(null, nmsStack);
} catch (Exception ex) {
Bukkit.getLogger().log(Level.SEVERE, "Failed to set glow enchantment on item: " + item, ex);
}
}
}
return item;
}
/**
* Remove all enchantments, including hidden enchantments
* @param item item to clear enchants from
* @return copy of the item without any enchantment tag
*/
public static ItemStack removeGlow(ItemStack item) {
if (item != null && item.getType() != Material.AIR && cb_CraftItemStack_asCraftMirror != null) {
try {
Object nmsStack = cb_CraftItemStack_asNMSCopy.invoke(null, item);
Object tag = mc_ItemStack_getTag.invoke(nmsStack);
if (tag != null) {
// remove enchantment list
mc_NBTTagCompound_remove.invoke(tag, "ench");
mc_ItemStack_setTag.invoke(nmsStack, tag);
item = (ItemStack) cb_CraftItemStack_asCraftMirror.invoke(null, nmsStack);
}
} catch (Exception ex) {
Bukkit.getLogger().log(Level.SEVERE, "Failed to set glow enchantment on item: " + item, ex);
}
}
return item;
}
public static String getItemName(ItemStack it) {
if (!check_compatibility) {
init();

View File

@ -4,8 +4,9 @@ import com.songoda.core.compatibility.ServerVersion;
import org.bukkit.entity.Player;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class NMSUtil {
public class NMSUtils {
public static Class<?> getNMSClass(String className) {
try {
@ -29,6 +30,12 @@ public class NMSUtil {
}
}
public static Method getPrivateMethod(Class<?> c, String methodName, Class<?> ... parameters) throws Exception {
Method m = c.getDeclaredMethod(methodName, parameters);
m.setAccessible(true);
return m;
}
public static Field getField(Class<?> clazz, String name, boolean declared) {
try {
Field field;