From 5665f39cb57c0dd0495499bdbd35e9f1ddf52f16 Mon Sep 17 00:00:00 2001 From: Richard Date: Sun, 24 Jan 2016 01:22:25 -0200 Subject: [PATCH] Annoying stacktraces when a NBT parse fails are finally gone... ... the effect "add "{blah:someValue}" to nbt of {_something}" now properly supports versions below 1.8 --- plugin.yml | 2 +- src/me/TheBukor/SkStuff/SkStuff.java | 24 +++------ .../SkStuff/expressions/ExprFileNBT.java | 40 ++++++-------- .../SkStuff/expressions/ExprItemNBT.java | 6 +-- .../SkStuff/expressions/ExprNBTOf.java | 52 +++++++------------ src/me/TheBukor/SkStuff/util/NBTUtil.java | 48 +++++++++++++++++ 6 files changed, 93 insertions(+), 79 deletions(-) create mode 100644 src/me/TheBukor/SkStuff/util/NBTUtil.java diff --git a/plugin.yml b/plugin.yml index 32b39e4..9cc7c29 100644 --- a/plugin.yml +++ b/plugin.yml @@ -1,6 +1,6 @@ name: SkStuff author: TheBukor description: A Skript addon which adds extra functionalities such as NBT and extended WorldEdit support. -version: 1.4.1.3 +version: 1.4.2 main: me.TheBukor.SkStuff.SkStuff softdepend: [Skript, WorldEdit] \ No newline at end of file diff --git a/src/me/TheBukor/SkStuff/SkStuff.java b/src/me/TheBukor/SkStuff/SkStuff.java index b9c9436..861f4a3 100644 --- a/src/me/TheBukor/SkStuff/SkStuff.java +++ b/src/me/TheBukor/SkStuff/SkStuff.java @@ -5,6 +5,7 @@ import java.lang.reflect.InvocationTargetException; import javax.annotation.Nullable; import org.bukkit.Bukkit; +import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.entity.Player; @@ -58,6 +59,7 @@ import me.TheBukor.SkStuff.expressions.ExprToLowerCase; import me.TheBukor.SkStuff.expressions.ExprToUpperCase; import me.TheBukor.SkStuff.expressions.ExprVanishState; import me.TheBukor.SkStuff.expressions.ExprWordsToUpperCase; +import me.TheBukor.SkStuff.util.NBTUtil; import me.TheBukor.SkStuff.util.ReflectionUtils; public class SkStuff extends JavaPlugin { @@ -93,8 +95,6 @@ public class SkStuff extends JavaPlugin { Classes.registerClass(new ClassInfo((Class) nbtClass, "compound").user("((nbt)?( ?tag)?) ?compounds?").name("NBT Compound").changer(new Changer() { - private Class nbtBaseClass = ReflectionUtils.getNMSClass("NBTBase"); - @Override @Nullable public Class[] acceptChange(ChangeMode mode) { @@ -106,25 +106,16 @@ public class SkStuff extends JavaPlugin { @Override public void change(Object[] NBT, @Nullable Object[] delta, ChangeMode mode) { - Boolean using1_7 = false; - String bukkitVersion = ReflectionUtils.getVersion(); - if (bukkitVersion.startsWith("v1_7_R")) { - using1_7 = true; - } String newTags = (String) delta[0]; if (mode == ChangeMode.ADD) { Object NBT1 = null; try { NBT1 = nbtParserClass.getMethod("parse", String.class).invoke(NBT1, newTags); - if (!using1_7) { - NBT.getClass().getMethod("a", nbtClass).invoke(NBT, NBT1); - } else { - NBT.getClass().getMethod("set", String.class, nbtBaseClass).invoke(NBT, "", NBT1); - } + NBTUtil.addCompound(NBT[0], NBT1); } catch (Exception ex) { if (ex instanceof InvocationTargetException) { - if (ex.getCause().getClass().getName().equals("MojangsonParseException") ) { - Skript.error("Error when parsing NBT - " + ex.getCause().getMessage()); + if (ex.getCause().getClass().getName().contains("MojangsonParseException") ) { + Bukkit.getConsoleSender().sendMessage("[SkStuff] " + ChatColor.RED + "Error when parsing NBT - " + ex.getCause().getMessage()); return; } ex.printStackTrace(); @@ -151,7 +142,7 @@ public class SkStuff extends JavaPlugin { @Override @Nullable public Object parse(String s, ParseContext context) { - if (s.startsWith("{")) { + if (s.startsWith("{") && s.endsWith("}")) { Object NBT = null; try { NBT = nbtClass.newInstance(); @@ -164,7 +155,7 @@ public class SkStuff extends JavaPlugin { nbtClass.getMethod("a", nbtClass).invoke(NBT, NBT1); } catch (Exception ex) { if (ex instanceof InvocationTargetException) { - if (ex.getCause().getClass().getName().equals("MojangsonParseException") ) { + if (ex.getCause().getClass().getName().contains("MojangsonParseException") ) { return null; } ex.printStackTrace(); @@ -235,6 +226,7 @@ public class SkStuff extends JavaPlugin { evtWE = true; } catch (ClassNotFoundException ex) { Skript.error("Unable to register \"On WorldEdit block change\" event! You will need to upgrade to WorldEdit 6.0"); + return; } condAmount += 1; effAmount += 12; diff --git a/src/me/TheBukor/SkStuff/expressions/ExprFileNBT.java b/src/me/TheBukor/SkStuff/expressions/ExprFileNBT.java index 4570dd3..e0fb37f 100644 --- a/src/me/TheBukor/SkStuff/expressions/ExprFileNBT.java +++ b/src/me/TheBukor/SkStuff/expressions/ExprFileNBT.java @@ -13,24 +13,23 @@ import java.lang.reflect.InvocationTargetException; import javax.annotation.Nullable; import org.bukkit.Bukkit; +import org.bukkit.ChatColor; import org.bukkit.event.Event; -import ch.njol.skript.Skript; import ch.njol.skript.classes.Changer.ChangeMode; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.util.Kleenean; import ch.njol.util.coll.CollectionUtils; +import me.TheBukor.SkStuff.util.NBTUtil; import me.TheBukor.SkStuff.util.ReflectionUtils; public class ExprFileNBT extends SimpleExpression { private Expression input; - private boolean using1_7 = false; - private Class nbtBaseClass = ReflectionUtils.getNMSClass("NBTBase"); - private Class nbtToolsClass = ReflectionUtils.getNMSClass("NBTCompressedStreamTools"); private Class nbtClass = ReflectionUtils.getNMSClass("NBTTagCompound"); + private Class nbtCompressedClass = ReflectionUtils.getNMSClass("NBTCompressedStreamTools"); private Class nbtParserClass = ReflectionUtils.getNMSClass("MojangsonParser"); @Override @@ -47,10 +46,6 @@ public class ExprFileNBT extends SimpleExpression { @Override public boolean init(Expression[] expr, int matchedPattern, Kleenean arg2, ParseResult arg3) { input = (Expression) expr[0]; - String bukkitVersion = ReflectionUtils.getVersion(); - if (bukkitVersion.startsWith("v1_7_R")) { - using1_7 = true; - } return true; } @@ -71,12 +66,12 @@ public class ExprFileNBT extends SimpleExpression { return null; // File doesn't exist } try { - NBT = nbtToolsClass.getMethod("a", FileInputStream.class).invoke(NBT, fis); + NBT = nbtCompressedClass.getMethod("a", FileInputStream.class).invoke(NBT, fis); fis.close(); } catch (Exception ex) { if (ex instanceof InvocationTargetException) { - if (ex.getCause().getClass().getName().equals("MojangsonParseException") ) { - Skript.error("Error when parsing NBT - " + ex.getCause().getMessage()); + if (ex.getCause().getClass().getName().contains("MojangsonParseException") ) { + Bukkit.getConsoleSender().sendMessage("[SkStuff] " + ChatColor.RED + "Error when parsing NBT - " + ex.getCause().getMessage()); return null; } ex.printStackTrace(); @@ -107,21 +102,17 @@ public class ExprFileNBT extends SimpleExpression { if (mode == ChangeMode.ADD) { try { Object NBT = null; - NBT = nbtToolsClass.getMethod("a", FileInputStream.class).invoke(NBT, fis); + NBT = nbtCompressedClass.getMethod("a", FileInputStream.class).invoke(NBT, fis); Object NBT1 = null; NBT1 = nbtParserClass.getMethod("parse", nbtClass).invoke(NBT1, tags); - if (!using1_7) { - NBT.getClass().getMethod("a", nbtClass).invoke(NBT, NBT1); - } else { - NBT.getClass().getMethod("set", String.class, nbtBaseClass).invoke(NBT, "", NBT1); - } - nbtToolsClass.getMethod("a", nbtClass, FileOutputStream.class).invoke(nbtToolsClass.newInstance(), NBT, os); + NBTUtil.addCompound(NBT, NBT1); + nbtCompressedClass.getMethod("a", nbtClass, FileOutputStream.class).invoke(nbtCompressedClass.newInstance(), NBT, os); fis.close(); os.close(); } catch (Exception ex) { if (ex instanceof InvocationTargetException) { - if (ex.getCause().getClass().getName().equals("MojangsonParseException") ) { - Skript.error("Error when parsing NBT - " + ex.getCause().getMessage()); + if (ex.getCause().getClass().getName().contains("MojangsonParseException") ) { + Bukkit.getConsoleSender().sendMessage("[SkStuff] " + ChatColor.RED + "Error when parsing NBT - " + ex.getCause().getMessage()); return; } ex.printStackTrace(); @@ -138,18 +129,17 @@ public class ExprFileNBT extends SimpleExpression { } else if (mode == ChangeMode.REMOVE) { try { Object NBT = null; - NBT = nbtToolsClass.getMethod("a", FileInputStream.class).invoke(NBT, fis); + NBT = nbtCompressedClass.getMethod("a", FileInputStream.class).invoke(NBT, fis); for (Object s : delta) { nbtClass.getMethod("remove", String.class).invoke(NBT, s); } - nbtToolsClass.getMethod("a", nbtClass, FileOutputStream.class).invoke(nbtToolsClass.newInstance(), NBT, os); - Bukkit.broadcastMessage("\n\nSecond: " + NBT.toString()); + nbtCompressedClass.getMethod("a", nbtClass, FileOutputStream.class).invoke(nbtCompressedClass.newInstance(), NBT, os); fis.close(); os.close(); } catch (Exception ex) { if (ex instanceof InvocationTargetException) { - if (ex.getCause().getClass().getName().equals("MojangsonParseException") ) { - Skript.error("Error when parsing NBT - " + ex.getCause().getMessage()); + if (ex.getCause().getClass().getName().contains("MojangsonParseException") ) { + Bukkit.getConsoleSender().sendMessage("[SkStuff] " + ChatColor.RED + "Error when parsing NBT - " + ex.getCause().getMessage()); return; } ex.printStackTrace(); diff --git a/src/me/TheBukor/SkStuff/expressions/ExprItemNBT.java b/src/me/TheBukor/SkStuff/expressions/ExprItemNBT.java index feb8600..e813112 100644 --- a/src/me/TheBukor/SkStuff/expressions/ExprItemNBT.java +++ b/src/me/TheBukor/SkStuff/expressions/ExprItemNBT.java @@ -2,12 +2,12 @@ package me.TheBukor.SkStuff.expressions; import javax.annotation.Nullable; +import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.event.Event; import org.bukkit.inventory.ItemStack; -import ch.njol.skript.Skript; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.util.SimpleExpression; @@ -69,8 +69,8 @@ public class ExprItemNBT extends SimpleExpression { } nmsItem.getClass().getMethod("setTag", nbtClass).invoke(nmsItem, NBT); } catch (Exception ex) { - if (ex.getCause().getClass().getName().equals("MojangsonParseException") ) { - Skript.warning(ChatColor.RED + "Error when parsing NBT - " + ex.getMessage()); + if (ex.getCause().getClass().getName().contains("MojangsonParseException") ) { + Bukkit.getConsoleSender().sendMessage("[SkStuff] " + ChatColor.RED + "Error when parsing NBT - " + ex.getCause().getMessage()); return null; } } diff --git a/src/me/TheBukor/SkStuff/expressions/ExprNBTOf.java b/src/me/TheBukor/SkStuff/expressions/ExprNBTOf.java index cc21f50..cf34bdc 100644 --- a/src/me/TheBukor/SkStuff/expressions/ExprNBTOf.java +++ b/src/me/TheBukor/SkStuff/expressions/ExprNBTOf.java @@ -4,13 +4,14 @@ import java.lang.reflect.InvocationTargetException; import javax.annotation.Nullable; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.event.Event; import org.bukkit.inventory.ItemStack; -import ch.njol.skript.Skript; import ch.njol.skript.classes.Changer.ChangeMode; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; @@ -18,13 +19,12 @@ import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.skript.util.Slot; import ch.njol.util.Kleenean; import ch.njol.util.coll.CollectionUtils; +import me.TheBukor.SkStuff.util.NBTUtil; import me.TheBukor.SkStuff.util.ReflectionUtils; public class ExprNBTOf extends SimpleExpression { - private Boolean using1_7 = false; private Expression target; - private Class nbtBaseClass = ReflectionUtils.getNMSClass("NBTBase"); private Class nbtClass = ReflectionUtils.getNMSClass("NBTTagCompound"); private Class nbtParserClass = ReflectionUtils.getNMSClass("MojangsonParser"); private Class nmsPosClass = ReflectionUtils.getNMSClass("BlockPosition"); @@ -47,10 +47,6 @@ public class ExprNBTOf extends SimpleExpression { @Override public boolean init(Expression[] expr, int matchedPattern, Kleenean arg2, ParseResult arg3) { target = expr[0]; - String bukkitVersion = ReflectionUtils.getVersion(); - if (bukkitVersion.startsWith("v1_7_R")) { - using1_7 = true; - } return true; } @@ -134,21 +130,17 @@ public class ExprNBTOf extends SimpleExpression { try { Object NBT1 = null; NBT1 = nbtParserClass.getMethod("parse", String.class).invoke(NBT1, newTags); - NBT1.getClass().getMethod("remove", String.class).invoke(NBT1, "UUIDMost"); - NBT1.getClass().getMethod("remove", String.class).invoke(NBT1, "UUIDLeast"); - NBT1.getClass().getMethod("remove", String.class).invoke(NBT1, "WorldUUIDMost"); - NBT1.getClass().getMethod("remove", String.class).invoke(NBT1, "WorldUUIDLeast"); - NBT1.getClass().getMethod("remove", String.class).invoke(NBT1, "Bukkit.updateLevel"); - if (!using1_7) { - NBT.getClass().getMethod("a", nbtClass).invoke(NBT, NBT1); - } else { - NBT.getClass().getMethod("set", String.class, nbtBaseClass).invoke(NBT, "", NBT1); - } + NBT1.getClass().getMethod("remove", String.class).invoke(NBT1, "UUIDMost"); // Prevent crucial data from being modified + NBT1.getClass().getMethod("remove", String.class).invoke(NBT1, "UUIDLeast"); // Prevent crucial data from being modified + NBT1.getClass().getMethod("remove", String.class).invoke(NBT1, "WorldUUIDMost"); // Prevent crucial data from being modified + NBT1.getClass().getMethod("remove", String.class).invoke(NBT1, "WorldUUIDLeast"); // Prevent crucial data from being modified + NBT1.getClass().getMethod("remove", String.class).invoke(NBT1, "Bukkit.updateLevel"); // Prevent crucial data from being modified + NBTUtil.addCompound(NBT, NBT1); nmsEnt.getClass().getMethod("f", nbtClass).invoke(nmsEnt, NBT); } catch (Exception ex) { if (ex instanceof InvocationTargetException) { - if (ex.getCause().getClass().getName().equals("MojangsonParseException") ) { - Skript.error("Error when parsing NBT - " + ex.getCause().getMessage()); + if (ex.getCause().getClass().getName().contains("MojangsonParseException")) { + Bukkit.getConsoleSender().sendMessage("[SkStuff] " + ChatColor.RED + "Error when parsing NBT - " + ex.getCause().getMessage()); return; } ex.printStackTrace(); @@ -157,7 +149,7 @@ public class ExprNBTOf extends SimpleExpression { } } else if (mode == ChangeMode.REMOVE) { for (Object s : delta) { - if (s != "UUIDMost" || s != "UUIDLeast" || s != "WorldUUIDMost" || s != "WorldUUIDLeast" || s != "Bukkit.updateLevel") { + if (s != "UUIDMost" || s != "UUIDLeast" || s != "WorldUUIDMost" || s != "WorldUUIDLeast" || s != "Bukkit.updateLevel") { // Prevent crucial data from being modified try { NBT.getClass().getMethod("remove", String.class).invoke(NBT, (String) s); nmsEnt.getClass().getMethod("f", nbtClass).invoke(nmsEnt, NBT); @@ -193,11 +185,7 @@ public class ExprNBTOf extends SimpleExpression { try { Object NBT1 = null; NBT1 = nbtParserClass.getMethod("parse", String.class).invoke(NBT1, newTags); - if (!using1_7) { - NBT.getClass().getMethod("a", nbtClass).invoke(NBT, NBT1); - } else { - NBT.getClass().getMethod("set", String.class, nbtBaseClass).invoke(NBT, "", NBT1); - } + NBTUtil.addCompound(NBT, NBT1); NBT1.getClass().getMethod("setInt", String.class, int.class).invoke(NBT1, "x", block.getX()); NBT1.getClass().getMethod("setInt", String.class, int.class).invoke(NBT1, "y", block.getY()); NBT1.getClass().getMethod("setInt", String.class, int.class).invoke(NBT1, "z", block.getZ()); @@ -206,8 +194,8 @@ public class ExprNBTOf extends SimpleExpression { nmsWorld.getClass().getMethod("notify", nmsPosClass).invoke(nmsWorld, tileEntity.getClass().getMethod("getPosition").invoke(tileEntity)); } catch (Exception ex) { if (ex instanceof InvocationTargetException) { - if (ex.getCause().getClass().getName().equals("MojangsonParseException") ) { - Skript.error("Error when parsing NBT - " + ex.getCause().getMessage()); + if (ex.getCause().getClass().getName().contains("MojangsonParseException")) { + Bukkit.getConsoleSender().sendMessage("[SkStuff] " + ChatColor.RED + "Error when parsing NBT - " + ex.getCause().getMessage()); return; } ex.printStackTrace(); @@ -258,11 +246,7 @@ public class ExprNBTOf extends SimpleExpression { try { Object NBT1 = null; NBT1 = nbtParserClass.getMethod("parse", String.class).invoke(NBT1, newTags); - if (!using1_7) { - NBT.getClass().getMethod("a", nbtClass).invoke(NBT, NBT1); - } else { - NBT.getClass().getMethod("set", String.class, nbtBaseClass).invoke(NBT, "", NBT1); - } + NBTUtil.addCompound(NBT, NBT1); nmsItem.getClass().getMethod("setTag", nbtClass).invoke(nmsItem, NBT); Object newItem = null; newItem = craftItemClass.getMethod("asCraftMirror", nmsItemClass).invoke(newItem, nmsItem); @@ -273,8 +257,8 @@ public class ExprNBTOf extends SimpleExpression { ((Slot) slot[0]).setItem((ItemStack) newItem); } catch (Exception ex) { if (ex instanceof InvocationTargetException) { - if (ex.getCause().getClass().getName().equals("MojangsonParseException") ) { - Skript.error("Error when parsing NBT - " + ex.getCause().getMessage()); + if (ex.getCause().getClass().getName().contains("MojangsonParseException") ) { + Bukkit.getConsoleSender().sendMessage("[SkStuff] " + ChatColor.RED + "Error when parsing NBT - " + ex.getCause().getMessage()); return; } ex.printStackTrace(); diff --git a/src/me/TheBukor/SkStuff/util/NBTUtil.java b/src/me/TheBukor/SkStuff/util/NBTUtil.java new file mode 100644 index 0000000..8bec5dc --- /dev/null +++ b/src/me/TheBukor/SkStuff/util/NBTUtil.java @@ -0,0 +1,48 @@ +package me.TheBukor.SkStuff.util; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Set; + +public class NBTUtil { + private static Class nbtBaseClass = ReflectionUtils.getNMSClass("NBTBase"); + private static Class nbtClass = ReflectionUtils.getNMSClass("NBTTagCompound"); + + /** + * This is actually a copy of the "a(NBTTagCompound)" method in the NBTTagCompound class using reflection + * I needed to add this because the 1.7 and before versions of the NBTTagCompound class didn't have this method, + * so there wasn't actually a reliable way to multiple tags at once into a compound. + * For the original code for the method, check https://github.com/linouxis9/mc-dev-1.8.7/blob/master/net/minecraft/server/NBTTagCompound.java#L348 + */ + @SuppressWarnings("unchecked") + public static void addCompound(Object source, Object toAdd) { + if (source.getClass().getName().contains("NBTTagCompound") && toAdd.getClass().getName().contains("NBTTagCompound")) { + try { + Field map = nbtClass.getDeclaredField("map"); + map.setAccessible(true); + Set keySet = (Set) nbtClass.getMethod("c").invoke(toAdd); + Iterator iterator = keySet.iterator(); + + while(iterator.hasNext()) { + String string = (String) iterator.next(); + Object base = nbtBaseClass.cast((((HashMap) map.get(toAdd)).get(string))); + if((byte) nbtBaseClass.getMethod("getTypeId").invoke(base) == 10) { + if((boolean) nbtClass.getMethod("hasKeyOfType", String.class, int.class).invoke(source, string, 10)) { + Object NBT = null; + NBT = nbtClass.getMethod("getCompound", String.class).invoke(NBT, string); + NBTUtil.addCompound(NBT, base.getClass().cast(nbtClass)); + } else { + nbtClass.getMethod("set", String.class, nbtBaseClass).invoke(source, string, base.getClass().getMethod("clone").invoke(base)); + } + } else { + nbtClass.getMethod("set", String.class, nbtBaseClass).invoke(source, string, base.getClass().getMethod("clone").invoke(base)); + } + } + map.setAccessible(false); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } +}