From f3fcb59fa18cdfb2a5c92e8c08654eeab8ddce0e Mon Sep 17 00:00:00 2001 From: Richard Date: Sun, 28 Feb 2016 20:01:28 -0300 Subject: [PATCH] So reflection was awful to work with. I'm moving on to a new method... using an Interface full of useful NMS methods. I'm still using reflection, but only when absolutely needed. I'm also working on a new and better implementation for NBT Lists. Made NBT Lists and NBT Compounds serializable (can be saved in variables through restarts), needs testing. --- .classpath | 3 + plugin.yml | 2 +- src/me/TheBukor/SkStuff/SkStuff.java | 263 ++------ .../TheBukor/SkStuff/effects/EffGZipFile.java | 56 ++ .../SkStuff/events/WorldEditExtent.java | 3 +- .../SkStuff/expressions/ExprFileNBT.java | 103 +-- .../SkStuff/expressions/ExprItemNBT.java | 41 +- .../expressions/ExprNBTListContents.java | 77 +++ .../SkStuff/expressions/ExprNBTListIndex.java | 77 +++ .../SkStuff/expressions/ExprNBTOf.java | 260 ++------ src/me/TheBukor/SkStuff/util/NBTUtil.java | 17 +- .../TheBukor/SkStuff/util/NMSInterface.java | 52 ++ src/me/TheBukor/SkStuff/util/NMS_v1_7_R4.java | 444 +++++++++++++ src/me/TheBukor/SkStuff/util/NMS_v1_8_R1.java | 434 +++++++++++++ src/me/TheBukor/SkStuff/util/NMS_v1_8_R2.java | 439 +++++++++++++ src/me/TheBukor/SkStuff/util/NMS_v1_8_R3.java | 588 ++++++++++++++++++ .../SkStuff/util/ReflectionUtils.java | 2 +- 17 files changed, 2316 insertions(+), 545 deletions(-) create mode 100644 src/me/TheBukor/SkStuff/effects/EffGZipFile.java create mode 100644 src/me/TheBukor/SkStuff/expressions/ExprNBTListContents.java create mode 100644 src/me/TheBukor/SkStuff/expressions/ExprNBTListIndex.java create mode 100644 src/me/TheBukor/SkStuff/util/NMSInterface.java create mode 100644 src/me/TheBukor/SkStuff/util/NMS_v1_7_R4.java create mode 100644 src/me/TheBukor/SkStuff/util/NMS_v1_8_R1.java create mode 100644 src/me/TheBukor/SkStuff/util/NMS_v1_8_R2.java create mode 100644 src/me/TheBukor/SkStuff/util/NMS_v1_8_R3.java diff --git a/.classpath b/.classpath index f48ebbe..229d6b7 100644 --- a/.classpath +++ b/.classpath @@ -6,5 +6,8 @@ + + + diff --git a/plugin.yml b/plugin.yml index e9e2062..c5f377c 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.5 +version: 1.5.1 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 c3f9846..4fda291 100644 --- a/src/me/TheBukor/SkStuff/SkStuff.java +++ b/src/me/TheBukor/SkStuff/SkStuff.java @@ -1,7 +1,5 @@ package me.TheBukor.SkStuff; -import java.lang.reflect.InvocationTargetException; - import javax.annotation.Nullable; import org.bukkit.Bukkit; @@ -11,25 +9,21 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.java.JavaPlugin; -import org.fusesource.jansi.Ansi; import com.sk89q.worldedit.EditSession; import ch.njol.skript.Skript; -import ch.njol.skript.classes.Changer; import ch.njol.skript.classes.ClassInfo; -import ch.njol.skript.classes.Parser; import ch.njol.skript.lang.ExpressionType; -import ch.njol.skript.lang.ParseContext; import ch.njol.skript.lang.util.SimpleEvent; import ch.njol.skript.registrations.Classes; import ch.njol.skript.registrations.EventValues; import ch.njol.skript.util.Getter; -import ch.njol.util.coll.CollectionUtils; import me.TheBukor.SkStuff.conditions.CondSelectionContains; import me.TheBukor.SkStuff.effects.EffClearPathGoals; import me.TheBukor.SkStuff.effects.EffDrainLiquid; import me.TheBukor.SkStuff.effects.EffDrawLineWE; +import me.TheBukor.SkStuff.effects.EffGZipFile; import me.TheBukor.SkStuff.effects.EffMakeCylinder; import me.TheBukor.SkStuff.effects.EffMakeJump; import me.TheBukor.SkStuff.effects.EffMakePyramid; @@ -55,6 +49,8 @@ import me.TheBukor.SkStuff.expressions.ExprEndermanBlocks; import me.TheBukor.SkStuff.expressions.ExprFileNBT; import me.TheBukor.SkStuff.expressions.ExprFireProof; import me.TheBukor.SkStuff.expressions.ExprItemNBT; +import me.TheBukor.SkStuff.expressions.ExprNBTListContents; +import me.TheBukor.SkStuff.expressions.ExprNBTListIndex; import me.TheBukor.SkStuff.expressions.ExprNBTOf; import me.TheBukor.SkStuff.expressions.ExprNewEditSession; import me.TheBukor.SkStuff.expressions.ExprNoClip; @@ -68,7 +64,11 @@ 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.NMSInterface; +import me.TheBukor.SkStuff.util.NMS_v1_7_R4; +import me.TheBukor.SkStuff.util.NMS_v1_8_R1; +import me.TheBukor.SkStuff.util.NMS_v1_8_R2; +import me.TheBukor.SkStuff.util.NMS_v1_8_R3; import me.TheBukor.SkStuff.util.ReflectionUtils; public class SkStuff extends JavaPlugin { @@ -77,213 +77,48 @@ public class SkStuff extends JavaPlugin { private int evtAmount = 0; private int exprAmount = 0; private int typeAmount = 0; + + public static SkStuff instance; - private Class nbtClass = ReflectionUtils.getNMSClass("NBTTagCompound", false); - private Class nbtListClass = ReflectionUtils.getNMSClass("NBTTagList", false); - private Class nbtArrayClass = ReflectionUtils.getNMSClass("NBTTagCompound", true); - private Class nbtParserClass = ReflectionUtils.getNMSClass("MojangsonParser", false); + private static NMSInterface nmsMethods; - @SuppressWarnings("unchecked") public void onEnable() { if (Bukkit.getPluginManager().getPlugin("Skript") != null && Skript.isAcceptRegistrations()) { Skript.registerAddon(this); getLogger().info("SkStuff " + this.getDescription().getVersion() + " has been successfully enabled!"); getLogger().info("Registering general non version specific stuff..."); + Skript.registerEffect(EffShowEntityEffect.class, "(display|play|show) entity effect (0¦firework[s] explo(de|sion)|1¦hurt|2¦[[iron] golem] (give|offer) (rose|poppy)|3¦[sheep] eat grass|4¦wolf shake) at %entity%"); Skript.registerExpression(ExprToUpperCase.class, String.class, ExpressionType.SIMPLE, "%string% [converted] to [all] (cap[ital]s|upper[ ]case)", "convert %string% to [all] (cap[ital]s|upper[ ]case)", "capitalize [all] [char[acter]s (of|in)] %string%"); Skript.registerExpression(ExprToLowerCase.class, String.class, ExpressionType.SIMPLE, "%string% [converted] to [all] lower[ ]case", "convert %string% to [all] lower[ ]case", "un[( |-)]capitalize [all] [char[acter]s (of|in)] %string%"); Skript.registerExpression(ExprWordsToUpperCase.class, String.class, ExpressionType.SIMPLE, "(first|1st) (letter|char[acter]) (of|in) (each word|[all] words) (of|in) %string% [converted] to (cap[ital]s|upper[ ]case) (0¦|1¦ignoring [other] upper[ ]case [(char[acter]s|letters)])", "convert (first|1st) (letter|char[acter]) (of|in) (each word|[all] words) (of|in) %string% to (cap[ital]s|upper[ ]case) (0¦|1¦ignoring [other] upper[ ]case [(char[acter]s|letters)])", "capitalize (first|1st) (letter|char[acter]) (of|in) (each word|[all] words) (of|in) %string% (0¦|1¦ignoring [other] upper[ ]case [(char[acter]s|letters)])"); Skript.registerExpression(ExprTimespanToNumber.class, Number.class, ExpressionType.SIMPLE, "%timespan% [converted] [in]to (0¦ticks|1¦sec[ond]s|2¦min[ute]s|3¦hours|4¦days)"); Skript.registerExpression(ExprClickedInventory.class, Inventory.class, ExpressionType.SIMPLE, "[skstuff] clicked inventory"); + effAmount += 1; exprAmount += 5; - getLogger().info("Trying to register version specific stuff..."); - Skript.registerEffect(EffClearPathGoals.class, "(clear|delete) [all] pathfind[er] goals (of|from) %livingentity%"); - Skript.registerEffect(EffRemovePathGoal.class, "remove pathfind[er] goal (0¦(avoid|run away from) entit(y|ies)|1¦break door[s]|2¦breed|3¦eat grass|4¦(flee from the sun|seek shad(e|ow))|5¦float (in[side]|on) water|6¦follow (owner|tamer)|7¦follow (adult|parent)[s]|8¦(fight back|react to|target) (damager|attacker)|9¦o(c|z)elot jump on blocks|10¦leap at target|11¦look at entit(y|ies)|12¦melee attack entit(y|ies)|13¦move to[wards] target|14¦target nearest entity|15¦o(c|z)elot attack [chicken[s]]|16¦open door[s]|17¦(panic|flee)|18¦look around randomly|19¦(walk around randomly|wander)|20¦sit|21¦[creeper] (explode|inflate|swell)|22¦squid (swim|wander)|23¦shoot fireball[s]|24¦[silverfish] hide (in[side]|on) block[s]|25¦(wake other silverfish[es]|[silverfish] call (help|reinforcement|other [hidden] silverfish[es]))|26¦[enderm(a|e)n] pick[[ ]up] block[s]|27¦[enderm(a|e)n] place block[s]|28¦[enderman] attack player (staring|looking) [at eye[s]]|29¦ghast move to[wards] target|30¦ghast (idle move[ment]|wander|random fl(ight|y[ing]))|31¦(tempt to|follow players (holding|with)) [a[n]] item|32¦target [random] entity (if|when) (not tamed|untamed)|33¦guardian attack [entity]|34¦[z[ombie[ ]]pig[man]] attack [player[s]] (if|when) angry|35¦[z[ombie[ ]]pig[man]] (react to|fight back|target) (attacker|damager) (if|when) angry|36¦[rabbit] eat carrot crops|37¦[killer] rabbit [melee] attack|38¦slime [random] jump|39¦slime change (direction|facing) randomly|40¦slime (idle move[ment]|wander)) from %livingentity%"); - Skript.registerEffect(EffSetPathGoal.class, "add pathfind[er] goal [[with] priority %-integer%] (0¦(avoid|run away from) %entitydata%[, radius %-number%[, speed %-number%[, speed (if|when) (close|near) %-number]]]|1¦break door[s]|2¦breed[,[move[ment]] speed %-number%]|3¦eat grass|4¦(flee from the sun|seek shad(e|ow))[, [move[ment]] speed %-number%]|5¦(float (in[side]|on) water|swim)|6¦follow (owner|tamer)[, speed %-number%[, min[imum] distance %-number%[, max[imum] distance %-number%]]]|7¦follow (adult|parent)[s][, [move[ment]] speed %-number%]|8¦(fight back|react to|target) (damager|attacker) [[of] type] %entitydata%[, call ([for] help|reinforcement) %-boolean%]|9¦o(c|z)elot jump on blocks[, [move[ment]] speed %-number%]|10¦leap at target[, [leap] height %-number%]|11¦look at %entitydata%[, (radius|max[imum] distance) %-number%]|12¦melee attack %entitydata%[, [move[ment]] speed %-number%[, (memorize|do('nt| not) forget) target [for [a] long[er] time] %-boolean%]]|13¦move to[wards] target[, [move[ment]] speed %-number%[, (radius|max[imum] distance) %-number%]]|14¦target nearest [entity [of] type] %entitydata%[, check sight %-boolean%]|15¦o(c|z)elot attack|16¦open door[s]|17¦(panic|flee)[, [move[ment]] speed %-number%]|18¦look around randomly|19¦(walk around randomly|wander)[, [move[ment]] speed %-number%[, min[imum] [of] %-timespan% between mov(e[ment][s]|ing)]]|20¦sit|21¦[creeper] (explode|inflate|swell)|22¦squid (swim around|wander)|23¦shoot fireball[s]|24¦[silverfish] hide (in[side]|on) block[s]|25¦((call|summon|wake) [other] [hidden] silverfish[es])|26¦[enderman] pick[[ ]up] block[s]|27¦[enderman] place block[s]|28¦[enderman] attack player (staring|looking) at [their] eye[s]]|29¦ghast move to[wards] target|30¦ghast (idle move[ment]|wander|random fl(ight|y[ing]))|31¦(tempt to|follow players (holding|with)) %-itemstack%[, [move[ment]] speed %number%[, scared of player movement %-boolean%]]|32¦target [random] %entitydata% (if|when) (not |un)tamed|33¦guardian attack [entities]|34¦[z[ombie[ ]]pig[man]] attack [player[s]] (if|when) angry|35¦[z[ombie[ ]]pig[man]] (react to|fight back|target) (attacker|damager) (if|when) angry|36¦[rabbit] eat carrot crops|37¦[killer] rabbit [melee] attack|38¦slime [random] jump|39¦slime change (direction|facing) randomly|40¦slime (idle move[ment]|wander)) to %livingentity%"); - Skript.registerEffect(EffMakeJump.class, "make %livingentities% jump", "force %livingentities% to jump"); - Skript.registerEffect(EffShowEntityEffect.class, "(display|play|show) entity effect (0¦firework[s] explo(de|sion)|1¦hurt|2¦[[iron] golem] (give|offer) (rose|poppy)|3¦[sheep] eat grass|4¦wolf shake) at %entity%"); - Skript.registerExpression(ExprNBTOf.class, Object.class, ExpressionType.PROPERTY, "nbt[[ ]tag[s]] of %object%", "%object%'s nbt[[ ]tag[s]]"); - Skript.registerExpression(ExprItemNBT.class, ItemStack.class, ExpressionType.SIMPLE, "%itemstack% with [custom] nbt[[ ]tag[s]] %string%"); - Skript.registerExpression(ExprTagOf.class, Object.class, ExpressionType.PROPERTY, "[nbt[ ]]tag %string% of [[nbt] compound] %compound%"); - Skript.registerExpression(ExprFileNBT.class, Object.class, ExpressionType.PROPERTY, "nbt[[ ]tag[s]] from [file] %string%"); - Skript.registerExpression(ExprNoClip.class, Boolean.class, ExpressionType.PROPERTY, "no[( |-)]clip (state|mode) of %entities%", "%entities%'s no[( |-)]clip (state|mode)"); - Skript.registerExpression(ExprFireProof.class, Boolean.class, ExpressionType.PROPERTY, "fire[ ]proof (state|mode) of %entities%", "%entities%'s fire[ ]proof (state|mode)"); - Skript.registerExpression(ExprEndermanBlocks.class, ItemStack.class, ExpressionType.PROPERTY, "blocks that %entity% can (carry|hold|grab|steal)"); - - Classes.registerClass(new ClassInfo((Class) nbtClass, "compound").user("((nbt)?( ?tag)?) ?compounds?").name("NBT Compound").changer(new Changer() { - - @Override - @Nullable - public Class[] acceptChange(ChangeMode mode) { - if (mode == ChangeMode.ADD || mode == ChangeMode.REMOVE || mode == ChangeMode.SET) { - return CollectionUtils.array(String[].class, nbtArrayClass); - } - return null; - } - - @Override - public void change(Object[] NBT, @Nullable Object[] delta, ChangeMode mode) { - if (NBT[0].getClass().getName().contains("NBTTagCompound")) { - if (!(delta[0] instanceof String) || !(delta[0].getClass().isInstance(nbtClass))) - return; - String newTags = (String) delta[0]; - if (mode == ChangeMode.SET) { - if (!(delta[0] instanceof String)) - NBT[0] = delta[0]; - } else if (mode == ChangeMode.ADD) { - if (delta[0] instanceof String) { - Object NBT1 = null; - try { - NBT1 = nbtParserClass.getMethod("parse", String.class).invoke(NBT1, newTags); - } catch (Exception ex) { - if (ex instanceof InvocationTargetException && ex.getCause().getClass().getName().contains("MojangsonParseException")) { - getLogger().warning(Ansi.ansi().fgBright(Ansi.Color.RED) + "Error when parsing NBT - " + ex.getCause().getMessage() + Ansi.ansi().fgBright(Ansi.Color.DEFAULT)); - return; - } - ex.printStackTrace(); - } - NBTUtil.addCompound(NBT[0], NBT1); - } else { - NBTUtil.addCompound(NBT[0], delta[0]); - } - } else if (mode == ChangeMode.REMOVE) { - if (!(delta[0] instanceof String)) - return; - for (Object s : delta) { - try { - nbtClass.getMethod("remove", String.class).invoke(NBT[0], (String) s); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - } - } - } - }).parser(new Parser() { - - @Override - public String getVariableNamePattern() { - return ".+"; - } - - @Override - @Nullable - public Object parse(String rawNBT, ParseContext context) { - if (rawNBT.startsWith("nbt:{") && rawNBT.endsWith("}")) { - Object NBT = null; - try { - NBT = nbtParserClass.getMethod("parse", String.class).invoke(NBT, rawNBT); - } catch (Exception ex) { - if (ex instanceof InvocationTargetException && ex.getCause().getClass().getName().contains("MojangsonParseException")) { - return null; - } - ex.printStackTrace(); - } - if (NBT.toString().equals("{}") || NBT == null) { - return null; - } - return NBT; - } - return null; - } - - @Override - public String toString(Object compound, int arg1) { - return compound.toString(); - } - - @Override - public String toVariableNameString(Object compound) { - return "nbt:" + compound.toString(); - } - })); - - Classes.registerClass(new ClassInfo((Class) nbtListClass, "nbtlist").user("nbt ?list ?(tag)?").name("NBT List").changer(new Changer() { - - @Override - @Nullable - public Class[] acceptChange(ChangeMode mode) { - if (mode == ChangeMode.ADD || mode == ChangeMode.SET || mode == ChangeMode.DELETE || mode == ChangeMode.RESET) { - return CollectionUtils.array(Float[].class, Double[].class, String[].class, nbtArrayClass, Integer[].class); - } - return null; - } - - @Override - public void change(Object[] list, @Nullable Object[] delta, ChangeMode mode) { - if (list[0].getClass().getName().contains("NBTTagList")) { - int typeId = 0; - if (delta instanceof Float[]) { - typeId = 5; - } else if (delta instanceof Double[]) { - typeId = 6; - } else if (delta instanceof String[]) { - typeId = 8; - } else if (delta.getClass() == nbtArrayClass) { - typeId = 10; - } else if (delta instanceof Integer[]) { - typeId = 11; - } else { - return; - } - if (mode == ChangeMode.SET) { - if (NBTUtil.getContentsId(list) == typeId) - list[0] = delta[0]; - } else if (mode == ChangeMode.ADD) { - if (NBTUtil.getContentsId(list) == typeId) { - if (typeId == 10) { - String newTags = (String) delta[0]; - Object NBT1 = null; - try { - NBT1 = nbtParserClass.getMethod("parse", String.class).invoke(NBT1, newTags); - } catch (Exception ex) { - if (ex instanceof InvocationTargetException && ex.getCause().getClass().getName().contains("MojangsonParseException")) { - Skript.warning(Ansi.ansi().fgBright(Ansi.Color.RED) + "Error when parsing NBT - " + ex.getCause().getMessage() + Ansi.ansi().fgBright(Ansi.Color.DEFAULT)); - return; - } - ex.printStackTrace(); - } - NBTUtil.addToList(list[0], new Object[] { NBT1 }); - } else { - NBTUtil.addToList(list[0], delta); - } - } - } else if (mode == ChangeMode.DELETE || mode == ChangeMode.RESET) { - try { - list[0] = nbtListClass.newInstance(); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - } - } - }).parser(new Parser() { - - @Override - public String getVariableNamePattern() { - return ".+"; - } - - @Override - @Nullable - public Object parse(String rawNBTList, ParseContext context) { - return null; - } - - @Override - public String toString(Object list, int arg1) { - return list.toString(); - } - - @Override - public String toVariableNameString(Object list) { - return list.toString(); - } - })); - effAmount += 5; - exprAmount += 6; - typeAmount += 2; + if (setupNMSVersion()) { + getLogger().info("Trying to register version specific stuff..."); + Skript.registerEffect(EffClearPathGoals.class, "(clear|delete) [all] pathfind[er] goals (of|from) %livingentity%"); + Skript.registerEffect(EffRemovePathGoal.class, "remove pathfind[er] goal (0¦(avoid|run away from) entit(y|ies)|1¦break door[s]|2¦breed|3¦eat grass|4¦(flee from the sun|seek shad(e|ow))|5¦float (in[side]|on) water|6¦follow (owner|tamer)|7¦follow (adult|parent)[s]|8¦(fight back|react to|target) (damager|attacker)|9¦o(c|z)elot jump on blocks|10¦leap at target|11¦look at entit(y|ies)|12¦melee attack entit(y|ies)|13¦move to[wards] target|14¦target nearest entity|15¦o(c|z)elot attack [chicken[s]]|16¦open door[s]|17¦(panic|flee)|18¦look around randomly|19¦(walk around randomly|wander)|20¦sit|21¦[creeper] (explode|inflate|swell)|22¦squid (swim|wander)|23¦shoot fireball[s]|24¦[silverfish] hide (in[side]|on) block[s]|25¦(wake other silverfish[es]|[silverfish] call (help|reinforcement|other [hidden] silverfish[es]))|26¦[enderm(a|e)n] pick[[ ]up] block[s]|27¦[enderm(a|e)n] place block[s]|28¦[enderman] attack player (staring|looking) [at eye[s]]|29¦ghast move to[wards] target|30¦ghast (idle move[ment]|wander|random fl(ight|y[ing]))|31¦(tempt to|follow players (holding|with)) [a[n]] item|32¦target [random] entity (if|when) (not tamed|untamed)|33¦guardian attack [entity]|34¦[z[ombie[ ]]pig[man]] attack [player[s]] (if|when) angry|35¦[z[ombie[ ]]pig[man]] (react to|fight back|target) (attacker|damager) (if|when) angry|36¦[rabbit] eat carrot crops|37¦[killer] rabbit [melee] attack|38¦slime [random] jump|39¦slime change (direction|facing) randomly|40¦slime (idle move[ment]|wander)) from %livingentity%"); + Skript.registerEffect(EffSetPathGoal.class, "add pathfind[er] goal [[with] priority %-integer%] (0¦(avoid|run away from) %entitydata%[, radius %-number%[, speed %-number%[, speed (if|when) (close|near) %-number%]]]|1¦break door[s]|2¦breed[,[move[ment]] speed %-number%]|3¦eat grass|4¦(flee from the sun|seek shad(e|ow))[, [move[ment]] speed %-number%]|5¦(float (in[side]|on) water|swim)|6¦follow (owner|tamer)[, speed %-number%[, min[imum] distance %-number%[, max[imum] distance %-number%]]]|7¦follow (adult|parent)[s][, [move[ment]] speed %-number%]|8¦(fight back|react to|target) (damager|attacker) [[of] type] %entitydata%[, call ([for] help|reinforcement) %-boolean%]|9¦o(c|z)elot jump on blocks[, [move[ment]] speed %-number%]|10¦leap at target[, [leap] height %-number%]|11¦look at %entitydata%[, (radius|max[imum] distance) %-number%]|12¦melee attack %entitydata%[, [move[ment]] speed %-number%[, (memorize|do('nt| not) forget) target [for [a] long[er] time] %-boolean%]]|13¦move to[wards] target[, [move[ment]] speed %-number%[, (radius|max[imum] distance) %-number%]]|14¦target nearest [entity [of] type] %entitydata%[, check sight %-boolean%]|15¦o(c|z)elot attack|16¦open door[s]|17¦(panic|flee)[, [move[ment]] speed %-number%]|18¦look around randomly|19¦(walk around randomly|wander)[, [move[ment]] speed %-number%[, min[imum] [of] %-timespan% between mov(e[ment][s]|ing)]]|20¦sit|21¦[creeper] (explode|inflate|swell)|22¦squid (swim around|wander)|23¦shoot fireball[s]|24¦[silverfish] hide (in[side]|on) block[s]|25¦((call|summon|wake) [other] [hidden] silverfish[es])|26¦[enderman] pick[[ ]up] block[s]|27¦[enderman] place block[s]|28¦[enderman] attack player (staring|looking) at [their] eye[s]]|29¦ghast move to[wards] target|30¦ghast (idle move[ment]|wander|random fl(ight|y[ing]))|31¦(tempt to|follow players (holding|with)) %-itemstack%[, [move[ment]] speed %number%[, scared of player movement %-boolean%]]|32¦target [random] %entitydata% (if|when) (not |un)tamed|33¦guardian attack [entities]|34¦[z[ombie[ ]]pig[man]] attack [player[s]] (if|when) angry|35¦[z[ombie[ ]]pig[man]] (react to|fight back|target) (attacker|damager) (if|when) angry|36¦[rabbit] eat carrot crops|37¦[killer] rabbit [melee] attack|38¦slime [random] jump|39¦slime change (direction|facing) randomly|40¦slime (idle move[ment]|wander)) to %livingentity%"); + Skript.registerEffect(EffMakeJump.class, "make %livingentities% jump", "force %livingentities% to jump"); + Skript.registerEffect(EffGZipFile.class, "create [a] gzip[ped] file [at] %string%"); + Skript.registerExpression(ExprNBTOf.class, Object.class, ExpressionType.PROPERTY, "nbt[[ ]tag[s]] of %~object%", "%~object%'s nbt[[ ]tag[s]]"); + Skript.registerExpression(ExprItemNBT.class, ItemStack.class, ExpressionType.SIMPLE, "%itemstack% with [custom] nbt[[ ]tag[s]] %string%"); + Skript.registerExpression(ExprTagOf.class, Object.class, ExpressionType.PROPERTY, "[nbt[ ]]tag %string% of [[nbt] compound] %compound%"); + Skript.registerExpression(ExprFileNBT.class, Object.class, ExpressionType.PROPERTY, "nbt[[ ]tag[s]] from [file] %string%"); + Skript.registerExpression(ExprNBTListIndex.class, Object.class, ExpressionType.PROPERTY, "[nbt[ ]list] %nbtlist% index %number%"); + Skript.registerExpression(ExprNBTListContents.class, Object.class, ExpressionType.PROPERTY, "[all] contents (of|from) [nbt[ ]list] %nbtlist%", "[nbt[ ]list] %nbtlist% contents"); + Skript.registerExpression(ExprNoClip.class, Boolean.class, ExpressionType.PROPERTY, "no[( |-)]clip (state|mode) of %entities%", "%entities%'s no[( |-)]clip (state|mode)"); + Skript.registerExpression(ExprFireProof.class, Boolean.class, ExpressionType.PROPERTY, "fire[ ]proof (state|mode) of %entities%", "%entities%'s fire[ ]proof (state|mode)"); + Skript.registerExpression(ExprEndermanBlocks.class, ItemStack.class, ExpressionType.PROPERTY, "blocks that %entity% can (carry|hold|grab|steal)"); + nmsMethods.registerCompoundClassInfo(); + nmsMethods.registerNBTListClassInfo(); + effAmount += 5; + exprAmount += 9; + typeAmount += 2; + } if (Bukkit.getPluginManager().getPlugin("WorldEdit") != null) { getLogger().info("WorldEdit found! Registering WorldEdit stuff..."); Skript.registerCondition(CondSelectionContains.class, "[(world[ ]edit|we)] selection of %player% (contains|has) %location%", "%player%'s [(world[ ]edit|we)] selection (contains|has) %location%", "[(world[ ]edit|we)] selection of %player% does(n't| not) (contain|have) %location%", "%player%'s [(world[ ]edit|we)] selection does(n't| not) (contain|have) %location%"); @@ -350,6 +185,34 @@ public class SkStuff extends JavaPlugin { } } + private boolean setupNMSVersion() { + String version = ReflectionUtils.getVersion(); + if (version.equals("v1_7_R4.")) { + nmsMethods = new NMS_v1_7_R4(); + getLogger().info("It looks like you're running 1.7.10!"); + } else if (version.equals("v1_8_R1.")) { + nmsMethods = new NMS_v1_8_R1(); + getLogger().info("It looks like you're running 1.8.0!"); + } else if (version.equals("v1_8_R2.")) { + nmsMethods = new NMS_v1_8_R2(); + getLogger().info("It looks like you're running 1.8.3!"); + } else if (version.equals("v1_8_R3.")) { + nmsMethods = new NMS_v1_8_R3(); + getLogger().info("It looks like you're either running 1.8.7, 1.8.8 or 1.8.9!"); + } else { + getLogger().warning("It looks like you're running an unsupported server version, some features will not be available :("); + } + return nmsMethods != null; + } + + public static SkStuff getInstance() { + return instance; + } + + public static NMSInterface getNMSMethods() { + return nmsMethods; + } + public void onDisable() { getLogger().info("SkStuff " + this.getDescription().getVersion() + " has been successfully disabled."); } diff --git a/src/me/TheBukor/SkStuff/effects/EffGZipFile.java b/src/me/TheBukor/SkStuff/effects/EffGZipFile.java new file mode 100644 index 0000000..470177a --- /dev/null +++ b/src/me/TheBukor/SkStuff/effects/EffGZipFile.java @@ -0,0 +1,56 @@ +package me.TheBukor.SkStuff.effects; + +import java.io.EOFException; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.zip.GZIPOutputStream; + +import javax.annotation.Nullable; + +import org.bukkit.event.Event; + +import ch.njol.skript.lang.Effect; +import ch.njol.skript.lang.Expression; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.util.Kleenean; + +public class EffGZipFile extends Effect { + private Expression filePath; + + @SuppressWarnings("unchecked") + @Override + public boolean init(Expression[] expr, int matchedPattern, Kleenean arg2, ParseResult result) { + filePath = (Expression) expr[0]; + return true; + } + + @Override + public String toString(@Nullable Event e, boolean debug) { + return "create GZipped file at " + filePath.toString(e, debug); + } + + @Override + protected void execute(Event e) { + File newFile = new File(filePath.getSingle(e)); + /* + if (!newFile.exists()) { + try { + newFile.createNewFile(); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + */ + try { + new GZIPOutputStream(new FileOutputStream(newFile)).close(); + } catch (FileNotFoundException ex) { + ex.printStackTrace(); + } catch (IOException ex) { + if (!(ex instanceof EOFException)) { + ex.printStackTrace(); + } + } + } +} diff --git a/src/me/TheBukor/SkStuff/events/WorldEditExtent.java b/src/me/TheBukor/SkStuff/events/WorldEditExtent.java index 78bee02..5db5314 100644 --- a/src/me/TheBukor/SkStuff/events/WorldEditExtent.java +++ b/src/me/TheBukor/SkStuff/events/WorldEditExtent.java @@ -28,6 +28,7 @@ public class WorldEditExtent extends AbstractLoggingExtent { protected void onBlockChange(final Vector vec, BaseBlock baseBlock) { final Block b = BukkitUtil.toLocation(world, vec).getBlock(); final Player p = Bukkit.getPlayerExact(actor.getName()); - Bukkit.getPluginManager().callEvent(new EvtWorldEditChange(p, b)); + EvtWorldEditChange event = new EvtWorldEditChange(p, b); + Bukkit.getPluginManager().callEvent(event); } } \ No newline at end of file diff --git a/src/me/TheBukor/SkStuff/expressions/ExprFileNBT.java b/src/me/TheBukor/SkStuff/expressions/ExprFileNBT.java index 0438f52..63995b5 100644 --- a/src/me/TheBukor/SkStuff/expressions/ExprFileNBT.java +++ b/src/me/TheBukor/SkStuff/expressions/ExprFileNBT.java @@ -1,36 +1,24 @@ package me.TheBukor.SkStuff.expressions; -import java.io.EOFException; import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.lang.reflect.InvocationTargetException; import javax.annotation.Nullable; import org.bukkit.event.Event; -import org.fusesource.jansi.Ansi; -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.SkStuff; import me.TheBukor.SkStuff.util.ReflectionUtils; public class ExprFileNBT extends SimpleExpression { private Expression input; private Class nbtClass = ReflectionUtils.getNMSClass("NBTTagCompound", false); - private Class nbtParserClass = ReflectionUtils.getNMSClass("MojangsonParser", false); - private Class nbtCompressedClass = ReflectionUtils.getNMSClass("NBTCompressedStreamTools", false); @Override public Class getReturnType() { @@ -57,82 +45,31 @@ public class ExprFileNBT extends SimpleExpression { @Override @Nullable public Object[] get(Event e) { - Object NBT = null; - File file = new File(input.getSingle(e)); - InputStream fis; - try { - fis = new FileInputStream(file); - } catch (FileNotFoundException ex) { - return null; // File doesn't exist - } - try { - NBT = nbtCompressedClass.getMethod("a", FileInputStream.class).invoke(NBT, fis); - fis.close(); - } catch (Exception ex) { - ex.printStackTrace(); - } finally { - try { - fis.close(); - } catch (IOException ex) { - ex.printStackTrace(); - } - } - return new Object[] { NBT }; + String fileName = input.getSingle(e); + fileName = !fileName.endsWith(".dat") ? fileName + ".dat" : fileName; + File file = new File(fileName); + if (!file.exists()) + return null; + return new Object[] { SkStuff.getNMSMethods().getFileNBT(file) }; } @Override public void change(Event e, @Nullable Object[] delta, ChangeMode mode) { - File file = new File(input.getSingle(e)); - String tags = (String) delta[0]; - OutputStream os = null; - InputStream fis = null; - try { - os = new FileOutputStream(file); - fis = new FileInputStream(file); - } catch (FileNotFoundException ex) { - return; // File doesn't exist. - } + String fileName = input.getSingle(e); + fileName = !fileName.endsWith(".dat") ? fileName + ".dat" : fileName; + File file = new File(fileName); + if (!file.exists()) + return; + Object fileNBT = SkStuff.getNMSMethods().getFileNBT(file); if (mode == ChangeMode.ADD) { - try { - Object NBT = null; - NBT = nbtCompressedClass.getMethod("a", FileInputStream.class).invoke(NBT, fis); - Object NBT1 = null; - NBT1 = nbtParserClass.getMethod("parse", String.class).invoke(NBT1, tags); - 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 && ex.getCause().getClass().getName().contains("MojangsonParseException")) { - Skript.warning(Ansi.ansi().fgBright(Ansi.Color.RED) + "Error when parsing NBT - " + ex.getCause().getMessage() + Ansi.ansi().fgBright(Ansi.Color.DEFAULT)); - return; - } - ex.printStackTrace(); - } finally { - try { - fis.close(); - os.close(); - } catch (IOException e1) { - e1.printStackTrace(); - } - } + Object parsedNBT = SkStuff.getNMSMethods().parseRawNBT((String) delta[0]); + SkStuff.getNMSMethods().addToCompound(fileNBT, parsedNBT); + SkStuff.getNMSMethods().setFileNBT(file, fileNBT); } else if (mode == ChangeMode.REMOVE) { - try { - Object NBT = null; - NBT = nbtCompressedClass.getMethod("a", FileInputStream.class).invoke(NBT, fis); - for (Object s : delta) { - nbtClass.getMethod("remove", String.class).invoke(NBT, s); - } - nbtCompressedClass.getMethod("a", nbtClass, FileOutputStream.class).invoke(nbtCompressedClass.newInstance(), NBT, os); - fis.close(); - os.close(); - } catch (Exception ex) { - if (ex instanceof EOFException) { - // No actual error, just end of the file. Ignore it. - } else { - ex.printStackTrace(); - } + for (Object s : delta) { + SkStuff.getNMSMethods().removeFromCompound(fileNBT, (String) s); } + SkStuff.getNMSMethods().setFileNBT(file, fileNBT); } } @@ -141,7 +78,7 @@ public class ExprFileNBT extends SimpleExpression { @Nullable public Class[] acceptChange(ChangeMode mode) { if (mode == ChangeMode.ADD || mode == ChangeMode.REMOVE) { - return CollectionUtils.array(String.class); + return CollectionUtils.array(String[].class); } return null; } diff --git a/src/me/TheBukor/SkStuff/expressions/ExprItemNBT.java b/src/me/TheBukor/SkStuff/expressions/ExprItemNBT.java index 40356e2..703f143 100644 --- a/src/me/TheBukor/SkStuff/expressions/ExprItemNBT.java +++ b/src/me/TheBukor/SkStuff/expressions/ExprItemNBT.java @@ -1,30 +1,21 @@ package me.TheBukor.SkStuff.expressions; -import java.lang.reflect.InvocationTargetException; - import javax.annotation.Nullable; import org.bukkit.Material; import org.bukkit.event.Event; import org.bukkit.inventory.ItemStack; -import org.fusesource.jansi.Ansi; -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; import ch.njol.util.Kleenean; -import me.TheBukor.SkStuff.util.ReflectionUtils; +import me.TheBukor.SkStuff.SkStuff; public class ExprItemNBT extends SimpleExpression { private Expression itemStack; private Expression string; - private Class nbtClass = ReflectionUtils.getNMSClass("NBTTagCompound", false); - private Class nbtParseClass = ReflectionUtils.getNMSClass("MojangsonParser", false); - private Class nmsItemClass = ReflectionUtils.getNMSClass("ItemStack", false); - - private Class craftItemClass = ReflectionUtils.getOBCClass("inventory.CraftItemStack"); @Override public Class getReturnType() { @@ -57,32 +48,8 @@ public class ExprItemNBT extends SimpleExpression { if (item.getType() == Material.AIR || item == null) { return null; } - Object nmsItem = null; - try { - nmsItem = craftItemClass.getMethod("asNMSCopy", ItemStack.class).invoke(item, item); - } catch (Exception ex) { - ex.printStackTrace(); - } - try { - Object NBT = null; - NBT = nbtParseClass.getMethod("parse", String.class).invoke(NBT, newTags); - if (NBT == null || NBT.toString().equals("{}")) { //"{}" is an empty compound. - return new ItemStack[] { item }; //There's no NBT involved, so just give a normal item. - } - nmsItem.getClass().getMethod("setTag", nbtClass).invoke(nmsItem, NBT); - } catch (Exception ex) { - if (ex instanceof InvocationTargetException && ex.getCause().getClass().getName().contains("MojangsonParseException")) { - Skript.warning(Ansi.ansi().fgBright(Ansi.Color.RED) + "Error when parsing NBT - " + ex.getCause().getMessage() + Ansi.ansi().fgBright(Ansi.Color.DEFAULT)); - return null; - } - ex.printStackTrace(); - } - Object newItem = null; - try { - newItem = craftItemClass.getMethod("asCraftMirror", nmsItemClass).invoke(newItem, nmsItem); - } catch (Exception ex) { - ex.printStackTrace(); - } - return new ItemStack[] { (ItemStack) newItem }; + Object parsedNBT = SkStuff.getNMSMethods().parseRawNBT(newTags); + ItemStack newItem = SkStuff.getNMSMethods().getItemWithNBT(item, parsedNBT); + return new ItemStack[] { newItem }; } } \ No newline at end of file diff --git a/src/me/TheBukor/SkStuff/expressions/ExprNBTListContents.java b/src/me/TheBukor/SkStuff/expressions/ExprNBTListContents.java new file mode 100644 index 0000000..356b82a --- /dev/null +++ b/src/me/TheBukor/SkStuff/expressions/ExprNBTListContents.java @@ -0,0 +1,77 @@ +package me.TheBukor.SkStuff.expressions; + +import javax.annotation.Nullable; + +import org.bukkit.event.Event; + +//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.SkStuff; +//import me.TheBukor.SkStuff.util.ReflectionUtils; + +public class ExprNBTListContents extends SimpleExpression { + private Expression nbtList; + + //private Class nbtListClass = ReflectionUtils.getNMSClass("NBTTagList", false); + //private Class nbtClass = ReflectionUtils.getNMSClass("NBTTagCompound", false); + + @Override + public Class getReturnType() { + return Object.class; + } + + @Override + public boolean isSingle() { + return false; + } + + @SuppressWarnings("unchecked") + @Override + public boolean init(Expression[] expr, int matchedPattern, Kleenean arg2, ParseResult result) { + nbtList = (Expression) expr[0]; + return false; + } + + @Override + public String toString(@Nullable Event e, boolean debug) { + return "contents from NBT list " + nbtList.toString(e, debug); + } + + @Override + @Nullable + protected Object[] get(Event e) { + Object list = nbtList.getSingle(e); + SkStuff.getNMSMethods().getContents(list); + return null; + } + + /* + @Override + public void change(Event e, @Nullable Object[] delta, ChangeMode mode) { + Object list = nbtList.getSingle(e); + if (mode == ChangeMode.ADD) { + if (!(delta[0] instanceof Number || delta[0] instanceof String || nbtListClass.isAssignableFrom(delta[0].getClass()) || nbtClass.isAssignableFrom(delta[0].getClass()))) + return; //NBT can only store numbers, strings, lists or compounds. + SkStuff.getNMSMethods().addToList(list, delta[0]); + } else if (mode == ChangeMode.REMOVE) { + // TODO A method to remove a specific object from a NBT List + } else if (mode == ChangeMode.REMOVE_ALL) { + // TODO A method to remove all objects of some type from a NBT List + } + } + + @SuppressWarnings("unchecked") + @Override + @Nullable + public Class[] acceptChange(ChangeMode mode) { + if (mode == ChangeMode.ADD || mode == ChangeMode.REMOVE || mode == ChangeMode.REMOVE_ALL) { + return CollectionUtils.array(Object.class); + } + return null; + } + */ +} diff --git a/src/me/TheBukor/SkStuff/expressions/ExprNBTListIndex.java b/src/me/TheBukor/SkStuff/expressions/ExprNBTListIndex.java new file mode 100644 index 0000000..1e12618 --- /dev/null +++ b/src/me/TheBukor/SkStuff/expressions/ExprNBTListIndex.java @@ -0,0 +1,77 @@ +package me.TheBukor.SkStuff.expressions; + +import javax.annotation.Nullable; + +import org.bukkit.event.Event; + +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.SkStuff; +import me.TheBukor.SkStuff.util.ReflectionUtils; + +public class ExprNBTListIndex extends SimpleExpression { + private Expression nbtList; + private Expression index; + + private Class nbtBaseClass = ReflectionUtils.getNMSClass("NBTBase", false); + + @Override + public Class getReturnType() { + return Object.class; + } + + @Override + public boolean isSingle() { + return false; + } + + @SuppressWarnings("unchecked") + @Override + public boolean init(Expression[] expr, int matchedPattern, Kleenean arg2, ParseResult result) { + nbtList = (Expression) expr[0]; + index = (Expression) expr[1]; + return false; + } + + @Override + public String toString(@Nullable Event e, boolean debug) { + return "NBT list" + nbtList.toString(e, debug) + " index " + index.toString(e, debug); + } + + @Override + @Nullable + protected Object[] get(Event e) { + int i = index.getSingle(e).intValue(); + Object list = nbtList.getSingle(e); + SkStuff.getNMSMethods().getIndex(list, i); + return null; + } + + @Override + public void change(Event e, @Nullable Object[] delta, ChangeMode mode) { + int i = index.getSingle(e).intValue(); + Object list = nbtList.getSingle(e); + if (mode == ChangeMode.SET) { + if (!(delta[0] instanceof Number || delta[0] instanceof String || nbtBaseClass.isAssignableFrom(delta[0].getClass()))) + //All NBTTags extends NBTBase, so it will check if delta[0] is instance of NBTTagList or NBTTagCompound, because these are the only NBTTagX classes registered in this addon. + return; //NBT can only store numbers, strings, lists or compounds. + SkStuff.getNMSMethods().setIndex(list, i, delta[0]); + } else if (mode == ChangeMode.DELETE) { + SkStuff.getNMSMethods().removeFromList(list, i); + } + } + + @SuppressWarnings("unchecked") + @Override + @Nullable + public Class[] acceptChange(ChangeMode mode) { + if (mode == ChangeMode.SET || mode == ChangeMode.DELETE) { + return CollectionUtils.array(Object.class); + } + return null; + } +} diff --git a/src/me/TheBukor/SkStuff/expressions/ExprNBTOf.java b/src/me/TheBukor/SkStuff/expressions/ExprNBTOf.java index f08469b..7ba8810 100644 --- a/src/me/TheBukor/SkStuff/expressions/ExprNBTOf.java +++ b/src/me/TheBukor/SkStuff/expressions/ExprNBTOf.java @@ -1,38 +1,32 @@ package me.TheBukor.SkStuff.expressions; -import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; import javax.annotation.Nullable; -import org.bukkit.Material; +import org.bukkit.Bukkit; import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.event.Event; import org.bukkit.inventory.ItemStack; -import org.fusesource.jansi.Ansi; +import ch.njol.skript.ScriptLoader; 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.skript.log.ErrorQuality; 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.SkStuff; import me.TheBukor.SkStuff.util.ReflectionUtils; public class ExprNBTOf extends SimpleExpression { private Expression target; private Class nbtClass = ReflectionUtils.getNMSClass("NBTTagCompound", false); - private Class nbtParserClass = ReflectionUtils.getNMSClass("MojangsonParser", false); - private Class nmsPosClass = ReflectionUtils.getNMSClass("BlockPosition", false); - private Class nmsItemClass = ReflectionUtils.getNMSClass("ItemStack", false); - - private Class craftEntClass = ReflectionUtils.getOBCClass("entity.CraftEntity"); - private Class craftItemClass = ReflectionUtils.getOBCClass("inventory.CraftItemStack"); - private Class craftWorldClass = ReflectionUtils.getOBCClass("CraftWorld"); @Override public Class getReturnType() { @@ -46,8 +40,17 @@ public class ExprNBTOf extends SimpleExpression { @SuppressWarnings("unchecked") @Override - public boolean init(Expression[] expr, int matchedPattern, Kleenean arg2, ParseResult arg3) { + public boolean init(Expression[] expr, int matchedPattern, Kleenean arg2, ParseResult result) { target = (Expression) expr[0]; + Class type = target.getReturnType(); + Class[] evts = ScriptLoader.getCurrentEvents(); + for (int i = 0; i < evts.length; i++) { + Bukkit.broadcastMessage("Event #" + i + ": \u00A7b" + evts[i].getSimpleName()); + } + Bukkit.broadcastMessage("Object type: \u00A79" + type.getSimpleName()); + if (type != Entity.class || type != Block.class || type != ItemStack.class || type != Slot.class) { + Skript.error(target.toString() + " is neither an entity, a block nor an itemstack.", ErrorQuality.SEMANTIC_ERROR); + } return true; } @@ -61,54 +64,11 @@ public class ExprNBTOf extends SimpleExpression { public Object[] get(Event e) { Object tar = target.getSingle(e); if (tar instanceof Entity) { - Object NBT = null; - try { - Object nmsEnt = craftEntClass.getMethod("getHandle").invoke(tar); - NBT = nbtClass.newInstance(); - nmsEnt.getClass().getMethod("e", nbtClass).invoke(nmsEnt, NBT); - } catch (Exception ex) { - ex.printStackTrace(); - } - return new Object[] { NBT }; - + return new Object[] { SkStuff.getNMSMethods().getEntityNBT((Entity) tar) }; } else if (tar instanceof Block) { - Block block = (Block) tar; - Object NBT = null; - Object tileEntity = null; - try { - NBT = nbtClass.newInstance(); - Object craftWorld = craftWorldClass.cast(block.getWorld()); - Object nmsWorld = craftWorld.getClass().getMethod("getHandle").invoke(craftWorld); - tileEntity = nmsWorld.getClass().getMethod("getTileEntity", nmsPosClass).invoke(nmsWorld, nmsPosClass.getConstructor(int.class, int.class, int.class).newInstance(block.getX(), block.getY(), block.getZ())); - } catch (Exception ex) { - ex.printStackTrace(); - } - if (tileEntity == null) { - return null; - } - try { - tileEntity.getClass().getMethod("b", nbtClass).invoke(tileEntity, NBT); - } catch (Exception ex) { - ex.printStackTrace(); - } - return new Object[] { NBT }; - + return new Object[] { SkStuff.getNMSMethods().getTileNBT((Block) tar) }; } else if (tar instanceof ItemStack) { - ItemStack item = (ItemStack) tar; - if (item.getType() == Material.AIR) { - return null; - } - Object NBT = null; - try { - Object nmsItem = craftItemClass.getMethod("asNMSCopy", ItemStack.class).invoke(item, item); - NBT = nmsItem.getClass().getMethod("getTag").invoke(nmsItem); - } catch (Exception ex) { - ex.printStackTrace(); - } - if (NBT == null || NBT.toString().equals("{}")) { //Null or empty. - return null; - } - return new Object[] { NBT }; + return new Object[] { SkStuff.getNMSMethods().getItemNBT((ItemStack) tar) }; } return null; } @@ -116,182 +76,60 @@ public class ExprNBTOf extends SimpleExpression { @Override public void change(Event e, Object[] delta, ChangeMode mode) { Object tar = target.getSingle(e); - if (!(delta[0] instanceof String)) - return; if (tar instanceof Entity) { - Object NBT = null; - Object nmsEnt = null; - try { - nmsEnt = craftEntClass.getMethod("getHandle").invoke(tar); - NBT = nbtClass.newInstance(); - nmsEnt.getClass().getMethod("e", nbtClass).invoke(nmsEnt, NBT); - } catch (Exception ex) { - ex.printStackTrace(); - } + Object entNBT = SkStuff.getNMSMethods().getEntityNBT((Entity) tar); if (mode == ChangeMode.ADD) { - String newTags = (String) (delta[0]); - try { - Object NBT1 = null; - NBT1 = nbtParserClass.getMethod("parse", String.class).invoke(NBT1, newTags); - 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 && ex.getCause().getClass().getName().contains("MojangsonParseException")) { - Skript.warning(Ansi.ansi().fgBright(Ansi.Color.RED) + "Error when parsing NBT - " + ex.getCause().getMessage() + Ansi.ansi().fgBright(Ansi.Color.DEFAULT)); - return; - } - ex.printStackTrace(); - } + Object parsedNBT = SkStuff.getNMSMethods().parseRawNBT((String) delta[0]); + SkStuff.getNMSMethods().removeFromCompound(parsedNBT, "UUIDMost", "UUIDLeast", "WorldUUDMost", "WorldUUIDLeast", "Bukkit.updateLevel"); + SkStuff.getNMSMethods().addToCompound(entNBT, parsedNBT); + SkStuff.getNMSMethods().setEntityNBT((Entity) tar, entNBT); } else if (mode == ChangeMode.REMOVE) { for (Object s : delta) { 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); - } catch (Exception ex) { - ex.printStackTrace(); - } + SkStuff.getNMSMethods().removeFromCompound(entNBT, (String) s); } } + SkStuff.getNMSMethods().setEntityNBT((Entity) tar, entNBT); } } else if (tar instanceof Block) { - Block block = (Block) tar; - Object NBT = null; - Object tileEntity = null; - Object nmsWorld = null; - try { - NBT = nbtClass.newInstance(); - Object craftWorld = craftWorldClass.cast(block.getWorld()); - nmsWorld = craftWorld.getClass().getMethod("getHandle").invoke(craftWorld); - tileEntity = nmsWorld.getClass().getMethod("getTileEntity", nmsPosClass).invoke(nmsWorld, nmsPosClass.getConstructor(int.class, int.class, int.class).newInstance(block.getX(), block.getY(), block.getZ())); - } catch (Exception ex) { - ex.printStackTrace(); - } - if (tileEntity == null) { - return; - } + Object blockNBT = SkStuff.getNMSMethods().getTileNBT((Block) tar); if (mode == ChangeMode.ADD) { - String newTags = (String) (delta[0]); - try { - tileEntity.getClass().getMethod("b", nbtClass).invoke(tileEntity, NBT); - } catch (Exception ex) { - ex.printStackTrace(); - } - try { - Object NBT1 = null; - NBT1 = nbtParserClass.getMethod("parse", String.class).invoke(NBT1, newTags); - 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()); - tileEntity.getClass().getMethod("a", nbtClass).invoke(tileEntity, NBT); - tileEntity.getClass().getMethod("update").invoke(tileEntity); - nmsWorld.getClass().getMethod("notify", nmsPosClass).invoke(nmsWorld, tileEntity.getClass().getMethod("getPosition").invoke(tileEntity)); - } catch (Exception ex) { - if (ex instanceof InvocationTargetException && ex.getCause().getClass().getName().contains("MojangsonParseException")) { - Skript.warning(Ansi.ansi().fgBright(Ansi.Color.RED) + "Error when parsing NBT - " + ex.getCause().getMessage() + Ansi.ansi().fgBright(Ansi.Color.DEFAULT)); - return; - } - ex.printStackTrace(); - } + Object parsedNBT = SkStuff.getNMSMethods().parseRawNBT((String) delta[0]); + SkStuff.getNMSMethods().removeFromCompound(parsedNBT, "x", "y", "z", "id"); + SkStuff.getNMSMethods().addToCompound(blockNBT, parsedNBT); + SkStuff.getNMSMethods().setTileNBT((Block) tar, blockNBT); } else if (mode == ChangeMode.REMOVE) { - try { - tileEntity.getClass().getMethod("b", nbtClass).invoke(tileEntity, NBT); - } catch (Exception ex) { - ex.printStackTrace(); - } for (Object s : delta) { if (s != "x" || s != "y" || s != "z" || s != "id") { - try { - NBT.getClass().getMethod("remove", String.class).invoke(NBT, ((String) s)); - tileEntity.getClass().getMethod("a", nbtClass).invoke(tileEntity, NBT); - tileEntity.getClass().getMethod("update").invoke(tileEntity); - nmsWorld.getClass().getMethod("notify", nmsPosClass).invoke(nmsWorld, tileEntity.getClass().getMethod("getPosition").invoke(tileEntity)); - } catch (Exception ex) { - ex.printStackTrace(); - } + SkStuff.getNMSMethods().removeFromCompound(blockNBT, (String) s); } } + SkStuff.getNMSMethods().setTileNBT((Block) tar, blockNBT); } } else if (tar instanceof ItemStack) { - ItemStack item = (ItemStack) tar; - if (item.getType() == Material.AIR) { - return; - } - Object nmsItem = null; - Object NBT = null; - try { - nmsItem = craftItemClass.getMethod("asNMSCopy", ItemStack.class).invoke(item, item); - NBT = nmsItem.getClass().getMethod("getTag").invoke(nmsItem); - } catch (Exception ex) { - ex.printStackTrace(); - } - if (NBT == null) { //No need to check for "{}" (empty) NBT because a new instance of NBT is actually "{}". - try { - NBT = nbtClass.newInstance(); - } catch (Exception ex) { - ex.printStackTrace(); - } - } + Object itemNBT = SkStuff.getNMSMethods().getItemNBT((ItemStack) tar); if (mode == ChangeMode.ADD) { - String newTags = (String) (delta[0]); - try { - Object NBT1 = null; - NBT1 = nbtParserClass.getMethod("parse", String.class).invoke(NBT1, newTags); - NBTUtil.addCompound(NBT, NBT1); - nmsItem.getClass().getMethod("setTag", nbtClass).invoke(nmsItem, NBT); - Object newItem = null; - newItem = craftItemClass.getMethod("asCraftMirror", nmsItemClass).invoke(newItem, nmsItem); - Object[] slot = target.getSource().getAll(e); - if (!(slot[0] instanceof Slot)) { - return; - } - ((Slot) slot[0]).setItem((ItemStack) newItem); - } catch (Exception ex) { - if (ex instanceof InvocationTargetException && ex.getCause().getClass().getName().contains("MojangsonParseException")) { - Skript.warning(Ansi.ansi().fgBright(Ansi.Color.RED) + "Error when parsing NBT - " + ex.getCause().getMessage() + Ansi.ansi().fgBright(Ansi.Color.DEFAULT)); - return; - } - ex.printStackTrace(); + Object parsedNBT = SkStuff.getNMSMethods().parseRawNBT((String) delta[0]); + SkStuff.getNMSMethods().addToCompound(itemNBT, parsedNBT); + ItemStack newItem = SkStuff.getNMSMethods().getItemWithNBT((ItemStack) tar, itemNBT); + Object slot = target.getSource().getSingle(e); + if (slot instanceof Slot) { + ((Slot) slot).setItem(newItem); } } else if (mode == ChangeMode.REMOVE) { - if (NBT == null || NBT.toString().equals("{}")) { //Check for "{}" (empty) NBT because executing the remove is just useless. - return; + String[] toRemove = Arrays.copyOf(delta, delta.length, String[].class); + SkStuff.getNMSMethods().removeFromCompound(itemNBT, toRemove); + ItemStack newItem = SkStuff.getNMSMethods().getItemWithNBT((ItemStack) tar, itemNBT); + Object slot = target.getSource().getSingle(e); + if (slot instanceof Slot) { + ((Slot) slot).setItem(newItem); } - for (Object s : delta) { - try { - NBT.getClass().getMethod("remove", String.class).invoke(NBT ,((String) s)); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - Object newItem = null; - try { - nmsItem.getClass().getMethod("setTag", nbtClass).invoke(nmsItem, NBT); - newItem = craftItemClass.getMethod("asCraftMirror", nmsItemClass).invoke(newItem, nmsItem); - } catch (Exception ex) { - ex.printStackTrace(); - } - Object[] slot = target.getSource().getAll(e); - ((Slot) slot[0]).setItem((ItemStack) newItem); } else if (mode == ChangeMode.DELETE || mode == ChangeMode.RESET) { - Object newItem = null; - try { - nmsItem.getClass().getMethod("setTag", nbtClass).invoke(nmsItem, nbtClass.newInstance()); - newItem = craftItemClass.getMethod("asCraftMirror", nmsItemClass).invoke(newItem, nmsItem); - } catch (Exception ex) { - ex.printStackTrace(); + ItemStack newItem = SkStuff.getNMSMethods().getItemWithNBT((ItemStack) tar, null); + Object slot = target.getSource().getSingle(e); + if (slot instanceof Slot) { + ((Slot) slot).setItem(newItem); } - Object[] slot = target.getSource().getAll(e); - if (!(slot[0] instanceof Slot)) { - return; - } - ((Slot) slot[0]).setItem((ItemStack) newItem); } } } diff --git a/src/me/TheBukor/SkStuff/util/NBTUtil.java b/src/me/TheBukor/SkStuff/util/NBTUtil.java index ab36d42..a40a2dd 100644 --- a/src/me/TheBukor/SkStuff/util/NBTUtil.java +++ b/src/me/TheBukor/SkStuff/util/NBTUtil.java @@ -99,12 +99,7 @@ public class NBTUtil { public static List getContents(Object list) { if (list.getClass() == nbtListClass) { List result = null; - try { - result = (List) ReflectionUtils.getField("list", nbtListClass, list); - return result; - } catch (Exception ex) { - ex.printStackTrace(); - } + result = (List) ReflectionUtils.getField("list", nbtListClass, list); return result; } return null; @@ -138,7 +133,7 @@ public class NBTUtil { } } } - + public static void removefromList(Object list, int index) { if (list.getClass() == nbtListClass) { if (index >= 0 && index < NBTUtil.getContents(list).size()) { @@ -146,7 +141,7 @@ public class NBTUtil { } } } - + public static void setIndex(Object list, int index, Object toAdd) { if (list.getClass() == nbtListClass && toAdd.getClass() == nbtBaseClass) { if (index >= 0 && index < NBTUtil.getContents(list).size()) { @@ -164,15 +159,15 @@ public class NBTUtil { ex.printStackTrace(); } } else if (listTypeId != toAddId) { - Skript.warning(Ansi.ansi().fgBright(Ansi.Color.RED) + "Adding mismatching tag types to NBT list" + Ansi.ansi().fgBright(Ansi.Color.DEFAULT)); + Skript.warning("Adding mismatching tag types to NBT list"); return; } - + NBTUtil.getContents(list).set(index, toAdd); } } } - + public static Object getIndex(Object list, int index) { if (list.getClass() == nbtListClass) { if (index >= 0 && index < NBTUtil.getContents(list).size()) { diff --git a/src/me/TheBukor/SkStuff/util/NMSInterface.java b/src/me/TheBukor/SkStuff/util/NMSInterface.java new file mode 100644 index 0000000..95fb29a --- /dev/null +++ b/src/me/TheBukor/SkStuff/util/NMSInterface.java @@ -0,0 +1,52 @@ +package me.TheBukor.SkStuff.util; + +import java.io.File; + +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.inventory.ItemStack; + +public interface NMSInterface { + + public void addToCompound(Object compound, Object toAdd); + + public void removeFromCompound(Object compound, String ... toRemove); + + public Object parseRawNBT(String rawNBT); + + public int getContentsId(Object nbtList); + + public Object[] getContents(Object nbtList); + + public void addToList(Object nbtList, Object toAdd); + + public void removeFromList(Object nbtList, int index); + + public void setIndex(Object nbtList, int index, Object toSet); + + public Object getIndex(Object nbtList, int index); + + public void removePathfinderGoal(Object entity, Class goalClass, boolean isTargetSelector); + + public void addPathfinderGoal(Object entity, int priority, Object goal, boolean isTargetSelector); + + public void registerCompoundClassInfo(); + + public void registerNBTListClassInfo(); + + public Object getEntityNBT(Entity entity); + + public Object getTileNBT(Block block); + + public Object getItemNBT(ItemStack itemStack); + + public void setEntityNBT(Entity entity, Object newCompound); + + public void setTileNBT(Block block, Object newCompound); + + public ItemStack getItemWithNBT(ItemStack itemStack, Object compound); + + public Object getFileNBT(File file); + + public void setFileNBT(File file, Object newCompound); +} diff --git a/src/me/TheBukor/SkStuff/util/NMS_v1_7_R4.java b/src/me/TheBukor/SkStuff/util/NMS_v1_7_R4.java new file mode 100644 index 0000000..8836542 --- /dev/null +++ b/src/me/TheBukor/SkStuff/util/NMS_v1_7_R4.java @@ -0,0 +1,444 @@ +package me.TheBukor.SkStuff.util; + +import java.io.EOFException; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import javax.annotation.Nullable; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_7_R4.CraftWorld; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_7_R4.inventory.CraftItemStack; +import org.bukkit.entity.Entity; +import org.bukkit.inventory.ItemStack; + +import ch.njol.skript.Skript; +import ch.njol.skript.classes.Changer; +import ch.njol.skript.classes.ClassInfo; +import ch.njol.skript.classes.Parser; +import ch.njol.skript.lang.ParseContext; +import ch.njol.skript.registrations.Classes; +import ch.njol.util.coll.CollectionUtils; +import net.minecraft.server.v1_7_R4.MojangsonParser; +import net.minecraft.server.v1_7_R4.NBTBase; +import net.minecraft.server.v1_7_R4.NBTCompressedStreamTools; +import net.minecraft.server.v1_7_R4.NBTTagCompound; +import net.minecraft.server.v1_7_R4.NBTTagDouble; +import net.minecraft.server.v1_7_R4.NBTTagEnd; +import net.minecraft.server.v1_7_R4.NBTTagFloat; +import net.minecraft.server.v1_7_R4.NBTTagInt; +import net.minecraft.server.v1_7_R4.NBTTagList; +import net.minecraft.server.v1_7_R4.NBTTagString; +import net.minecraft.server.v1_7_R4.TileEntity; +import net.minecraft.server.v1_7_R4.World; + +public class NMS_v1_7_R4 implements NMSInterface { + + @SuppressWarnings("unchecked") + @Override + public void addToCompound(Object compound, Object toAdd) { + if (compound instanceof NBTTagCompound && toAdd instanceof NBTTagCompound) { + HashMap map = (HashMap) ReflectionUtils.getField("map", NBTTagCompound.class, toAdd); + Set keySet = ((NBTTagCompound) toAdd).c(); + Iterator iterator = keySet.iterator(); + + while(iterator.hasNext()) { + String string = (String) iterator.next(); + NBTBase base = (NBTBase) map.get(string); + if(base.getTypeId() == 10) { + if(((NBTTagCompound) compound).hasKeyOfType(string, 10)) { + NBTTagCompound localNBT = ((NBTTagCompound) compound).getCompound(string); + addToCompound(localNBT, (NBTTagCompound) base); + } else { + ((NBTTagCompound) compound).set(string, base.clone()); + } + } else { + ((NBTTagCompound) compound).set(string, base.clone()); + } + } + } + } + + @Override + public void removeFromCompound(Object compound, String ... toRemove) { + if (compound instanceof NBTTagCompound) { + ((NBTTagCompound) compound).remove(toRemove.toString()); //FIXME + } + } + + @Override + public Object parseRawNBT(String rawNBT) { + NBTTagCompound parsedNBT = null; + parsedNBT = (NBTTagCompound) MojangsonParser.parse(rawNBT); + return parsedNBT; + } + + @Override + public int getContentsId(Object nbtList) { + if (nbtList instanceof NBTTagList) { + return ((NBTTagList) nbtList).d(); + } + return 0; + } + + @Override + public Object[] getContents(Object nbtList) { + if (nbtList instanceof NBTTagList) { + List contents = new ArrayList(); + for (int i = 0; i < ((NBTTagList) nbtList).size(); i++) { + if (getIndex(nbtList, i) != null) { + contents.add(getIndex(nbtList, i)); + } + } + return contents.toArray(); + } + return null; + } + + @Override + public void addToList(Object nbtList, Object toAdd) { + if (nbtList instanceof NBTTagList && toAdd instanceof NBTBase) { + ((NBTTagList) nbtList).add((NBTBase) toAdd); + } + } + + @SuppressWarnings("unchecked") + @Override + public void removeFromList(Object nbtList, int index) { + if (nbtList instanceof NBTTagList && index >= 0 && index < ((NBTTagList) nbtList).size()) { + List actualList = null; + actualList = (List) ReflectionUtils.getField("list", NBTTagList.class, nbtList); + actualList.remove(index); + } + } + + @SuppressWarnings("unchecked") + @Override + public void setIndex(Object nbtList, int index, Object toSet) { + if (nbtList instanceof NBTTagList && toSet instanceof NBTBase && index >= 0 && index < ((NBTTagList) nbtList).size()) { + int typeId = getContentsId(nbtList); + int toSetId = ((NBTBase) toSet).getTypeId(); + if (typeId == 0) { + ReflectionUtils.setField("type", NBTTagList.class, nbtList, toSetId); + } else if (typeId != toSetId) { + Skript.warning("Adding mismatching tag types to NBT list"); + return; + } + List actualList = null; + actualList = (List) ReflectionUtils.getField("list", NBTTagList.class, nbtList); + actualList.set(index, toSet); + } + } + + @SuppressWarnings("unchecked") + @Override + public Object getIndex(Object nbtList, int index) { + if (nbtList instanceof NBTTagList && index >= 0 && index < ((NBTTagList) nbtList).size()) { + List actualList = null; + actualList = (List) ReflectionUtils.getField("list", NBTTagList.class, nbtList); + NBTBase value = (NBTBase) actualList.get(index); + if (value instanceof NBTTagEnd) + return null; + else + return value; + } + return null; + } + + @Override + public void removePathfinderGoal(Object entity, Class goalClass, boolean isTargetSelector) { + Bukkit.getLogger().warning("Sorry, Pathfinder Goals are only supported in 1.8 and above"); + } + + @Override + public void addPathfinderGoal(Object entity, int priority, Object goal, boolean isTargetSelector) { + Bukkit.getLogger().warning("Sorry, Pathfinder Goals are only supported in 1.8 and above"); + } + + @Override + public void registerCompoundClassInfo() { + Classes.registerClass(new ClassInfo(NBTTagCompound.class, "compound").user("((nbt)?( ?tag)?) ?compounds?").name("NBT Compound").changer(new Changer() { + + @SuppressWarnings("unchecked") + @Override + @Nullable + public Class[] acceptChange(ChangeMode mode) { + if (mode == ChangeMode.ADD || mode == ChangeMode.REMOVE || mode == ChangeMode.SET) { + return CollectionUtils.array(String[].class, NBTTagCompound[].class); + } + return null; + } + + @Override + public void change(NBTTagCompound[] NBT, @Nullable Object[] delta, ChangeMode mode) { + if (mode == ChangeMode.SET) { + if (delta[0] instanceof NBTTagCompound) { + NBT[0] = (NBTTagCompound) delta[0]; + } else { + NBTTagCompound parsedNBT = (NBTTagCompound) parseRawNBT((String) delta[0]); + NBT[0] = parsedNBT; + } + } else if (mode == ChangeMode.ADD) { + if (delta[0] instanceof String) { + NBTTagCompound parsedNBT = (NBTTagCompound) parseRawNBT((String) delta[0]); + addToCompound(NBT[0], parsedNBT); + } else { + addToCompound(NBT[0], delta[0]); + } + } else if (mode == ChangeMode.REMOVE) { + if (delta[0] instanceof NBTTagCompound) + return; + for (Object s : delta) { + NBT[0].remove((String) s); + } + } + } + }).parser(new Parser() { + + @Override + public String getVariableNamePattern() { + return ".+"; + } + + @Override + @Nullable + public NBTTagCompound parse(String rawNBT, ParseContext context) { + if (rawNBT.startsWith("nbt:{") && rawNBT.endsWith("}")) { + rawNBT.substring(4); + NBTTagCompound NBT = (NBTTagCompound) parseRawNBT(rawNBT); + if (NBT.toString().equals("{}")) { + return null; + } + return NBT; + } + return null; + } + + @Override + public String toString(NBTTagCompound compound, int arg1) { + return compound.toString(); + } + + @Override + public String toVariableNameString(NBTTagCompound compound) { + return "nbt:" + compound.toString(); + } + })); + + } + + @Override + public void registerNBTListClassInfo() { + Classes.registerClass(new ClassInfo(NBTTagList.class, "nbtlist").user("nbt ?list ?(tag)?").name("NBT List").changer(new Changer() { + + @SuppressWarnings("unchecked") + @Override + @Nullable + public Class[] acceptChange(ChangeMode mode) { + if (mode == ChangeMode.ADD || mode == ChangeMode.SET || mode == ChangeMode.DELETE || mode == ChangeMode.RESET) { + return CollectionUtils.array(Float[].class, Double[].class, String[].class, NBTTagCompound[].class, Integer[].class, NBTTagList[].class); + } + return null; + } + + @Override + public void change(NBTTagList[] nbtList, @Nullable Object[] delta, ChangeMode mode) { + int typeId = 0; + if (delta instanceof Float[]) { + typeId = 5; + } else if (delta instanceof Double[]) { + typeId = 6; + } else if (delta instanceof String[]) { + typeId = 8; + } else if (delta instanceof NBTTagList[]) { + typeId = 9; + } else if (delta instanceof NBTTagCompound[]) { + typeId = 10; + } else if (delta instanceof Integer[]) { + typeId = 11; + } else { + return; + } + if (mode == ChangeMode.SET) { + if (typeId == 9) + nbtList[0] = (NBTTagList) delta[0]; + } else if (mode == ChangeMode.ADD) { + if (getContentsId(nbtList[0]) == typeId) { + if (typeId == 5) { + NBTTagFloat floatTag = new NBTTagFloat((float) delta[0]); + addToList(nbtList[0], floatTag); + } else if (typeId == 6) { + NBTTagDouble doubleTag = new NBTTagDouble((double) delta[0]); + addToList(nbtList[0], doubleTag); + } else if (typeId == 8) { + NBTTagString stringTag = new NBTTagString((String) delta [0]); + addToList(nbtList[0], stringTag); + } else if (typeId == 10) { + addToList(nbtList[0], delta[0]); + } else if (typeId == 11) { + NBTTagInt intTag = new NBTTagInt((int) delta[0]); + addToList(nbtList[0], intTag); + } + } + } else if (mode == ChangeMode.DELETE || mode == ChangeMode.RESET) { + nbtList[0] = new NBTTagList(); + } + } + }).parser(new Parser() { + + @Override + public String getVariableNamePattern() { + return ".+"; + } + + @Override + @Nullable + public NBTTagList parse(String ignored, ParseContext context) { + return null; + } + + @Override + public String toString(NBTTagList nbtList, int arg1) { + return nbtList.toString(); + } + + @Override + public String toVariableNameString(NBTTagList nbtList) { + return nbtList.toString(); + } + })); + } + + @Override + public Object getEntityNBT(Entity entity) { + net.minecraft.server.v1_7_R4.Entity nmsEntity = ((CraftEntity) entity).getHandle(); + NBTTagCompound NBT = new NBTTagCompound(); + nmsEntity.e(NBT); + return NBT; + } + + @Override + public Object getTileNBT(Block block) { + NBTTagCompound NBT = new NBTTagCompound(); + World nmsWorld = ((CraftWorld) block.getWorld()).getHandle(); + TileEntity tileEntity = nmsWorld.getTileEntity(block.getX(), block.getY(), block.getZ()); + if (tileEntity == null) + return null; + tileEntity.b(NBT); + return NBT; + } + + @Override + public Object getItemNBT(ItemStack itemStack) { + if (itemStack.getType() == Material.AIR) + return null; + NBTTagCompound NBT = new NBTTagCompound(); + net.minecraft.server.v1_7_R4.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + NBT = nmsItem.getTag(); + if (NBT == null || NBT.toString().equals("{}")) //Null or empty. + return null; + return new Object[] { NBT }; + } + + @Override + public void setEntityNBT(Entity entity, Object newCompound) { + if (newCompound instanceof NBTTagCompound) { + net.minecraft.server.v1_7_R4.Entity nmsEntity = ((CraftEntity) entity).getHandle(); + nmsEntity.f((NBTTagCompound) newCompound); + } + } + + @Override + public void setTileNBT(Block block, Object newCompound) { + if (newCompound instanceof NBTTagCompound) { + World nmsWorld = ((CraftWorld) block.getWorld()).getHandle(); + TileEntity tileEntity = nmsWorld.getTileEntity(block.getX(), block.getY(), block.getZ()); + if (tileEntity == null) + return; + tileEntity.a((NBTTagCompound) newCompound); + tileEntity.update(); + nmsWorld.notify(tileEntity.x, tileEntity.y, tileEntity.z); + } + } + + @Override + public ItemStack getItemWithNBT(ItemStack itemStack, Object compound) { + if (compound instanceof NBTTagCompound) { + if (itemStack.getType() == Material.AIR || itemStack == null) + return null; + if (compound == null || compound.toString().equals("{}")) + return itemStack; + net.minecraft.server.v1_7_R4.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + nmsItem.setTag((NBTTagCompound) compound); + ItemStack newItem = CraftItemStack.asCraftMirror(nmsItem); + return newItem; + } + return null; + } + + @Override + public Object getFileNBT(File file) { + FileInputStream fis = null; + try { + fis = new FileInputStream(file); + } catch (FileNotFoundException ex) { + return null; //File doesn't exist. + } + NBTTagCompound fileNBT = null; + try { + fileNBT = NBTCompressedStreamTools.a(fis); + fis.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } finally { + try { + fis.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + return fileNBT; + } + + @Override + public void setFileNBT(File file, Object newCompound) { + OutputStream os = null; + try { + os = new FileOutputStream(file); + } catch (FileNotFoundException ex) { + ex.printStackTrace(); + } + try { + NBTCompressedStreamTools.a((NBTTagCompound) newCompound, os); + os.close(); + } catch (Exception ex) { + if (ex instanceof EOFException) { + ; //Ignore, just end of the file + } else { + ex.printStackTrace(); + } + } finally { + try { + os.close(); + } catch (Exception ex) { + if (ex instanceof EOFException) { + ; //Ignore. + } else { + ex.printStackTrace(); + } + } + } + } +} \ No newline at end of file diff --git a/src/me/TheBukor/SkStuff/util/NMS_v1_8_R1.java b/src/me/TheBukor/SkStuff/util/NMS_v1_8_R1.java new file mode 100644 index 0000000..116375a --- /dev/null +++ b/src/me/TheBukor/SkStuff/util/NMS_v1_8_R1.java @@ -0,0 +1,434 @@ +package me.TheBukor.SkStuff.util; + +import java.io.EOFException; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.annotation.Nullable; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_8_R1.CraftWorld; +import org.bukkit.craftbukkit.v1_8_R1.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_8_R1.inventory.CraftItemStack; +import org.bukkit.entity.Entity; +import org.bukkit.inventory.ItemStack; + +import ch.njol.skript.classes.Changer; +import ch.njol.skript.classes.ClassInfo; +import ch.njol.skript.classes.Parser; +import ch.njol.skript.lang.ParseContext; +import ch.njol.skript.registrations.Classes; +import ch.njol.util.coll.CollectionUtils; +import net.minecraft.server.v1_8_R1.BlockPosition; +import net.minecraft.server.v1_8_R1.EntityInsentient; +import net.minecraft.server.v1_8_R1.MojangsonParser; +import net.minecraft.server.v1_8_R1.NBTBase; +import net.minecraft.server.v1_8_R1.NBTCompressedStreamTools; +import net.minecraft.server.v1_8_R1.NBTTagCompound; +import net.minecraft.server.v1_8_R1.NBTTagDouble; +import net.minecraft.server.v1_8_R1.NBTTagEnd; +import net.minecraft.server.v1_8_R1.NBTTagFloat; +import net.minecraft.server.v1_8_R1.NBTTagInt; +import net.minecraft.server.v1_8_R1.NBTTagList; +import net.minecraft.server.v1_8_R1.NBTTagString; +import net.minecraft.server.v1_8_R1.PathfinderGoal; +import net.minecraft.server.v1_8_R1.PathfinderGoalSelector; +import net.minecraft.server.v1_8_R1.TileEntity; +import net.minecraft.server.v1_8_R1.World; + +public class NMS_v1_8_R1 implements NMSInterface { + + @Override + public void addToCompound(Object compound, Object toAdd) { + if (compound instanceof NBTTagCompound && toAdd instanceof NBTTagCompound) { + ((NBTTagCompound) compound).a((NBTTagCompound) toAdd); + } + } + + @Override + public void removeFromCompound(Object compound, String ... toRemove) { + if (compound instanceof NBTTagCompound) { + ((NBTTagCompound) compound).remove(toRemove.toString()); //FIXME + } + } + + @Override + public Object parseRawNBT(String rawNBT) { + NBTTagCompound parsedNBT = null; + parsedNBT = MojangsonParser.parse(rawNBT); + return parsedNBT; + } + + @Override + public int getContentsId(Object nbtList) { + if (nbtList instanceof NBTTagList) { + return ((NBTTagList) nbtList).f(); + } + return 0; + } + + @Override + public Object[] getContents(Object nbtList) { + if (nbtList instanceof NBTTagList) { + List contents = new ArrayList(); + for (int i = 0; i < ((NBTTagList) nbtList).size(); i++) { + if (getIndex(nbtList, i) != null) { + contents.add(getIndex(nbtList, i)); + } + } + return contents.toArray(); + } + return null; + } + + @Override + public void addToList(Object nbtList, Object toAdd) { + if (nbtList instanceof NBTTagList && toAdd instanceof NBTBase) { + ((NBTTagList) nbtList).add((NBTBase) toAdd); + } + } + + @Override + public void removeFromList(Object nbtList, int index) { + if (nbtList instanceof NBTTagList) { + ((NBTTagList) nbtList).a(index); + } + } + + @Override + public void setIndex(Object nbtList, int index, Object toSet) { + if (nbtList instanceof NBTTagList && toSet instanceof NBTBase) { + ((NBTTagList) nbtList).a(index, (NBTBase) toSet); + } + } + + @Override + public Object getIndex(Object nbtList, int index) { + if (nbtList instanceof NBTTagList) { + NBTBase value = ((NBTTagList) nbtList).g(index); + if (value instanceof NBTTagEnd) + return null; + else + return value; + } + return null; + } + + @Override + public void removePathfinderGoal(Object entity, Class goalClass, boolean isTargetSelector) { + if (entity instanceof EntityInsentient) { + ((EntityInsentient) entity).setGoalTarget(null); + if (isTargetSelector) { + Iterator goals = ((List) ReflectionUtils.getField("b", PathfinderGoalSelector.class, ((EntityInsentient) entity).targetSelector)).iterator(); + while (goals.hasNext()) { + Object goal = goals.next(); + if (ReflectionUtils.getField("a", goal.getClass(), goal).getClass() == goalClass) { + goals.remove(); + } + } + } else { + Iterator goals = ((List) ReflectionUtils.getField("b", PathfinderGoalSelector.class, ((EntityInsentient) entity).goalSelector)).iterator(); + while (goals.hasNext()) { + Object goal = goals.next(); + if (ReflectionUtils.getField("a", goal.getClass(), goal).getClass() == goalClass) { + goals.remove(); + } + } + } + } + } + + @Override + public void addPathfinderGoal(Object entity, int priority, Object goal, boolean isTargetSelector) { + if (entity instanceof EntityInsentient && goal instanceof PathfinderGoal) { + if (isTargetSelector) + ((EntityInsentient) entity).targetSelector.a(priority, (PathfinderGoal) goal); + else + ((EntityInsentient) entity).goalSelector.a(priority, (PathfinderGoal) goal); + } + } + + @Override + public void registerCompoundClassInfo() { + Classes.registerClass(new ClassInfo(NBTTagCompound.class, "compound").user("((nbt)?( ?tag)?) ?compounds?").name("NBT Compound").changer(new Changer() { + + @SuppressWarnings("unchecked") + @Override + @Nullable + public Class[] acceptChange(ChangeMode mode) { + if (mode == ChangeMode.ADD || mode == ChangeMode.REMOVE || mode == ChangeMode.SET) { + return CollectionUtils.array(String[].class, NBTTagCompound[].class); + } + return null; + } + + @Override + public void change(NBTTagCompound[] NBT, @Nullable Object[] delta, ChangeMode mode) { + if (mode == ChangeMode.SET) { + if (delta[0] instanceof NBTTagCompound) { + NBT[0] = (NBTTagCompound) delta[0]; + } else { + NBTTagCompound parsedNBT = (NBTTagCompound) parseRawNBT((String) delta[0]); + NBT[0] = parsedNBT; + } + } else if (mode == ChangeMode.ADD) { + if (delta[0] instanceof String) { + NBTTagCompound parsedNBT = (NBTTagCompound) parseRawNBT((String) delta[0]); + addToCompound(NBT[0], parsedNBT); + } else { + addToCompound(NBT[0], delta[0]); + } + } else if (mode == ChangeMode.REMOVE) { + if (delta[0] instanceof NBTTagCompound) + return; + for (Object s : delta) { + NBT[0].remove((String) s); + } + } + } + }).parser(new Parser() { + + @Override + public String getVariableNamePattern() { + return ".+"; + } + + @Override + @Nullable + public NBTTagCompound parse(String rawNBT, ParseContext context) { + if (rawNBT.startsWith("nbt:{") && rawNBT.endsWith("}")) { + rawNBT.substring(4); + rawNBT.substring(4); + NBTTagCompound NBT = (NBTTagCompound) parseRawNBT(rawNBT); + if (NBT.toString().equals("{}")) { + return null; + } + return NBT; + } + return null; + } + + @Override + public String toString(NBTTagCompound compound, int arg1) { + return compound.toString(); + } + + @Override + public String toVariableNameString(NBTTagCompound compound) { + return "nbt:" + compound.toString(); + } + })); + + } + + @Override + public void registerNBTListClassInfo() { + Classes.registerClass(new ClassInfo(NBTTagList.class, "nbtlist").user("nbt ?list ?(tag)?").name("NBT List").changer(new Changer() { + + @SuppressWarnings("unchecked") + @Override + @Nullable + public Class[] acceptChange(ChangeMode mode) { + if (mode == ChangeMode.ADD || mode == ChangeMode.SET || mode == ChangeMode.DELETE || mode == ChangeMode.RESET) { + return CollectionUtils.array(Float[].class, Double[].class, String[].class, NBTTagCompound[].class, Integer[].class, NBTTagList[].class); + } + return null; + } + + @Override + public void change(NBTTagList[] nbtList, @Nullable Object[] delta, ChangeMode mode) { + int typeId = 0; + if (delta instanceof Float[]) { + typeId = 5; + } else if (delta instanceof Double[]) { + typeId = 6; + } else if (delta instanceof String[]) { + typeId = 8; + } else if (delta instanceof NBTTagList[]) { + typeId = 9; + } else if (delta instanceof NBTTagCompound[]) { + typeId = 10; + } else if (delta instanceof Integer[]) { + typeId = 11; + } else { + return; + } + if (mode == ChangeMode.SET) { + if (typeId == 9) + nbtList[0] = (NBTTagList) delta[0]; + } else if (mode == ChangeMode.ADD) { + if (getContentsId(nbtList[0]) == typeId) { + if (typeId == 5) { + NBTTagFloat floatTag = new NBTTagFloat((float) delta[0]); + addToList(nbtList[0], floatTag); + } else if (typeId == 6) { + NBTTagDouble doubleTag = new NBTTagDouble((double) delta[0]); + addToList(nbtList[0], doubleTag); + } else if (typeId == 8) { + NBTTagString stringTag = new NBTTagString((String) delta [0]); + addToList(nbtList[0], stringTag); + } else if (typeId == 10) { + addToList(nbtList[0], delta[0]); + } else if (typeId == 11) { + NBTTagInt intTag = new NBTTagInt((int) delta[0]); + addToList(nbtList[0], intTag); + } + } + } else if (mode == ChangeMode.DELETE || mode == ChangeMode.RESET) { + nbtList[0] = new NBTTagList(); + } + } + }).parser(new Parser() { + + @Override + public String getVariableNamePattern() { + return ".+"; + } + + @Override + @Nullable + public NBTTagList parse(String ignored, ParseContext context) { + return null; + } + + @Override + public String toString(NBTTagList nbtList, int arg1) { + return nbtList.toString(); + } + + @Override + public String toVariableNameString(NBTTagList nbtList) { + return nbtList.toString(); + } + })); + } + + @Override + public Object getEntityNBT(Entity entity) { + net.minecraft.server.v1_8_R1.Entity nmsEntity = ((CraftEntity) entity).getHandle(); + NBTTagCompound NBT = new NBTTagCompound(); + nmsEntity.e(NBT); + return NBT; + } + + @Override + public Object getTileNBT(Block block) { + NBTTagCompound NBT = new NBTTagCompound(); + World nmsWorld = ((CraftWorld) block.getWorld()).getHandle(); + TileEntity tileEntity = nmsWorld.getTileEntity(new BlockPosition(block.getX(), block.getY(), block.getZ())); + if (tileEntity == null) + return null; + tileEntity.b(NBT); + return NBT; + } + + @Override + public Object getItemNBT(ItemStack itemStack) { + if (itemStack.getType() == Material.AIR) + return null; + NBTTagCompound NBT = new NBTTagCompound(); + net.minecraft.server.v1_8_R1.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + NBT = nmsItem.getTag(); + if (NBT == null || NBT.toString().equals("{}")) //Null or empty. + return null; + return new Object[] { NBT }; + } + + @Override + public void setEntityNBT(Entity entity, Object newCompound) { + if (newCompound instanceof NBTTagCompound) { + net.minecraft.server.v1_8_R1.Entity nmsEntity = ((CraftEntity) entity).getHandle(); + nmsEntity.f((NBTTagCompound) newCompound); + } + } + + @Override + public void setTileNBT(Block block, Object newCompound) { + if (newCompound instanceof NBTTagCompound) { + World nmsWorld = ((CraftWorld) block.getWorld()).getHandle(); + TileEntity tileEntity = nmsWorld.getTileEntity(new BlockPosition(block.getX(), block.getY(), block.getZ())); + if (tileEntity == null) + return; + tileEntity.a((NBTTagCompound) newCompound); + tileEntity.update(); + nmsWorld.notify(tileEntity.getPosition()); + } + } + + @Override + public ItemStack getItemWithNBT(ItemStack itemStack, Object compound) { + if (compound instanceof NBTTagCompound) { + if (itemStack.getType() == Material.AIR || itemStack == null) + return null; + if (compound == null || compound.toString().equals("{}")) + return itemStack; + net.minecraft.server.v1_8_R1.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + nmsItem.setTag((NBTTagCompound) compound); + ItemStack newItem = CraftItemStack.asCraftMirror(nmsItem); + return newItem; + } + return null; + } + + @Override + public Object getFileNBT(File file) { + FileInputStream fis = null; + try { + fis = new FileInputStream(file); + } catch (FileNotFoundException ex) { + return null; //File doesn't exist. + } + NBTTagCompound fileNBT = null; + try { + fileNBT = NBTCompressedStreamTools.a(fis); + fis.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } finally { + try { + fis.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + return fileNBT; + } + + @Override + public void setFileNBT(File file, Object newCompound) { + OutputStream os = null; + try { + os = new FileOutputStream(file); + } catch (FileNotFoundException ex) { + ex.printStackTrace(); + } + try { + NBTCompressedStreamTools.a((NBTTagCompound) newCompound, os); + os.close(); + } catch (Exception ex) { + if (ex instanceof EOFException) { + ; //Ignore, just end of the file + } else { + ex.printStackTrace(); + } + } finally { + try { + os.close(); + } catch (Exception ex) { + if (ex instanceof EOFException) { + ; //Ignore. + } else { + ex.printStackTrace(); + } + } + } + } +} \ No newline at end of file diff --git a/src/me/TheBukor/SkStuff/util/NMS_v1_8_R2.java b/src/me/TheBukor/SkStuff/util/NMS_v1_8_R2.java new file mode 100644 index 0000000..b45bd96 --- /dev/null +++ b/src/me/TheBukor/SkStuff/util/NMS_v1_8_R2.java @@ -0,0 +1,439 @@ +package me.TheBukor.SkStuff.util; + +import java.io.EOFException; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.annotation.Nullable; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_8_R2.CraftWorld; +import org.bukkit.craftbukkit.v1_8_R2.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_8_R2.inventory.CraftItemStack; +import org.bukkit.entity.Entity; +import org.bukkit.inventory.ItemStack; + +import ch.njol.skript.Skript; +import ch.njol.skript.classes.Changer; +import ch.njol.skript.classes.ClassInfo; +import ch.njol.skript.classes.Parser; +import ch.njol.skript.lang.ParseContext; +import ch.njol.skript.registrations.Classes; +import ch.njol.util.coll.CollectionUtils; +import net.minecraft.server.v1_8_R2.BlockPosition; +import net.minecraft.server.v1_8_R2.EntityInsentient; +import net.minecraft.server.v1_8_R2.MojangsonParseException; +import net.minecraft.server.v1_8_R2.MojangsonParser; +import net.minecraft.server.v1_8_R2.NBTBase; +import net.minecraft.server.v1_8_R2.NBTCompressedStreamTools; +import net.minecraft.server.v1_8_R2.NBTTagCompound; +import net.minecraft.server.v1_8_R2.NBTTagDouble; +import net.minecraft.server.v1_8_R2.NBTTagEnd; +import net.minecraft.server.v1_8_R2.NBTTagFloat; +import net.minecraft.server.v1_8_R2.NBTTagInt; +import net.minecraft.server.v1_8_R2.NBTTagList; +import net.minecraft.server.v1_8_R2.NBTTagString; +import net.minecraft.server.v1_8_R2.PathfinderGoal; +import net.minecraft.server.v1_8_R2.PathfinderGoalSelector; +import net.minecraft.server.v1_8_R2.TileEntity; +import net.minecraft.server.v1_8_R2.World; + +public class NMS_v1_8_R2 implements NMSInterface { + + @Override + public void addToCompound(Object compound, Object toAdd) { + if (compound instanceof NBTTagCompound && toAdd instanceof NBTTagCompound) { + ((NBTTagCompound) compound).a((NBTTagCompound) toAdd); + } + } + + @Override + public void removeFromCompound(Object compound, String ... toRemove) { + if (compound instanceof NBTTagCompound) { + ((NBTTagCompound) compound).remove(toRemove.toString()); //FIXME + } + } + + @Override + public Object parseRawNBT(String rawNBT) { + NBTTagCompound parsedNBT = null; + try { + parsedNBT = MojangsonParser.parse(rawNBT); + } catch (MojangsonParseException ex) { + Skript.warning("Error when parsing NBT - " + ex.getMessage()); + } + return parsedNBT; + } + + @Override + public int getContentsId(Object nbtList) { + if (nbtList instanceof NBTTagList) { + return ((NBTTagList) nbtList).f(); + } + return 0; + } + + @Override + public Object[] getContents(Object nbtList) { + if (nbtList instanceof NBTTagList) { + List contents = new ArrayList(); + for (int i = 0; i < ((NBTTagList) nbtList).size(); i++) { + if (getIndex(nbtList, i) != null) { + contents.add(getIndex(nbtList, i)); + } + } + return contents.toArray(); + } + return null; + } + + @Override + public void addToList(Object nbtList, Object toAdd) { + if (nbtList instanceof NBTTagList && toAdd instanceof NBTBase) { + ((NBTTagList) nbtList).add((NBTBase) toAdd); + } + } + + @Override + public void removeFromList(Object nbtList, int index) { + if (nbtList instanceof NBTTagList) { + ((NBTTagList) nbtList).a(index); + } + } + + @Override + public void setIndex(Object nbtList, int index, Object toSet) { + if (nbtList instanceof NBTTagList && toSet instanceof NBTBase) { + ((NBTTagList) nbtList).a(index, (NBTBase) toSet); + } + } + + @Override + public Object getIndex(Object nbtList, int index) { + if (nbtList instanceof NBTTagList) { + NBTBase value = ((NBTTagList) nbtList).g(index); + if (value instanceof NBTTagEnd) + return null; + else + return value; + } + return null; + } + + @Override + public void removePathfinderGoal(Object entity, Class goalClass, boolean isTargetSelector) { + if (entity instanceof EntityInsentient) { + ((EntityInsentient) entity).setGoalTarget(null); + if (isTargetSelector) { + Iterator goals = ((List) ReflectionUtils.getField("b", PathfinderGoalSelector.class, ((EntityInsentient) entity).targetSelector)).iterator(); + while (goals.hasNext()) { + Object goal = goals.next(); + if (ReflectionUtils.getField("a", goal.getClass(), goal).getClass() == goalClass) { + goals.remove(); + } + } + } else { + Iterator goals = ((List) ReflectionUtils.getField("b", PathfinderGoalSelector.class, ((EntityInsentient) entity).goalSelector)).iterator(); + while (goals.hasNext()) { + Object goal = goals.next(); + if (ReflectionUtils.getField("a", goal.getClass(), goal).getClass() == goalClass) { + goals.remove(); + } + } + } + } + } + + @Override + public void addPathfinderGoal(Object entity, int priority, Object goal, boolean isTargetSelector) { + if (entity instanceof EntityInsentient && goal instanceof PathfinderGoal) { + if (isTargetSelector) + ((EntityInsentient) entity).targetSelector.a(priority, (PathfinderGoal) goal); + else + ((EntityInsentient) entity).goalSelector.a(priority, (PathfinderGoal) goal); + } + } + + @Override + public void registerCompoundClassInfo() { + Classes.registerClass(new ClassInfo(NBTTagCompound.class, "compound").user("((nbt)?( ?tag)?) ?compounds?").name("NBT Compound").changer(new Changer() { + + @SuppressWarnings("unchecked") + @Override + @Nullable + public Class[] acceptChange(ChangeMode mode) { + if (mode == ChangeMode.ADD || mode == ChangeMode.REMOVE || mode == ChangeMode.SET) { + return CollectionUtils.array(String[].class, NBTTagCompound[].class); + } + return null; + } + + @Override + public void change(NBTTagCompound[] NBT, @Nullable Object[] delta, ChangeMode mode) { + if (mode == ChangeMode.SET) { + if (delta[0] instanceof NBTTagCompound) { + NBT[0] = (NBTTagCompound) delta[0]; + } else { + NBTTagCompound parsedNBT = (NBTTagCompound) parseRawNBT((String) delta[0]); + NBT[0] = parsedNBT; + } + } else if (mode == ChangeMode.ADD) { + if (delta[0] instanceof String) { + NBTTagCompound parsedNBT = (NBTTagCompound) parseRawNBT((String) delta[0]); + addToCompound(NBT[0], parsedNBT); + } else { + addToCompound(NBT[0], delta[0]); + } + } else if (mode == ChangeMode.REMOVE) { + if (delta[0] instanceof NBTTagCompound) + return; + for (Object s : delta) { + NBT[0].remove((String) s); + } + } + } + }).parser(new Parser() { + + @Override + public String getVariableNamePattern() { + return ".+"; + } + + @Override + @Nullable + public NBTTagCompound parse(String rawNBT, ParseContext context) { + if (rawNBT.startsWith("nbt:{") && rawNBT.endsWith("}")) { + rawNBT.substring(4); + NBTTagCompound NBT = (NBTTagCompound) parseRawNBT(rawNBT); + if (NBT.toString().equals("{}")) { + return null; + } + return NBT; + } + return null; + } + + @Override + public String toString(NBTTagCompound compound, int arg1) { + return compound.toString(); + } + + @Override + public String toVariableNameString(NBTTagCompound compound) { + return "nbt:" + compound.toString(); + } + })); + + } + + @Override + public void registerNBTListClassInfo() { + Classes.registerClass(new ClassInfo(NBTTagList.class, "nbtlist").user("nbt ?list ?(tag)?").name("NBT List").changer(new Changer() { + + @SuppressWarnings("unchecked") + @Override + @Nullable + public Class[] acceptChange(ChangeMode mode) { + if (mode == ChangeMode.ADD || mode == ChangeMode.SET || mode == ChangeMode.DELETE || mode == ChangeMode.RESET) { + return CollectionUtils.array(Float[].class, Double[].class, String[].class, NBTTagCompound[].class, Integer[].class, NBTTagList[].class); + } + return null; + } + + @Override + public void change(NBTTagList[] nbtList, @Nullable Object[] delta, ChangeMode mode) { + int typeId = 0; + if (delta instanceof Float[]) { + typeId = 5; + } else if (delta instanceof Double[]) { + typeId = 6; + } else if (delta instanceof String[]) { + typeId = 8; + } else if (delta instanceof NBTTagList[]) { + typeId = 9; + } else if (delta instanceof NBTTagCompound[]) { + typeId = 10; + } else if (delta instanceof Integer[]) { + typeId = 11; + } else { + return; + } + if (mode == ChangeMode.SET) { + if (typeId == 9) + nbtList[0] = (NBTTagList) delta[0]; + } else if (mode == ChangeMode.ADD) { + if (getContentsId(nbtList[0]) == typeId) { + if (typeId == 5) { + NBTTagFloat floatTag = new NBTTagFloat((float) delta[0]); + addToList(nbtList[0], floatTag); + } else if (typeId == 6) { + NBTTagDouble doubleTag = new NBTTagDouble((double) delta[0]); + addToList(nbtList[0], doubleTag); + } else if (typeId == 8) { + NBTTagString stringTag = new NBTTagString((String) delta [0]); + addToList(nbtList[0], stringTag); + } else if (typeId == 10) { + addToList(nbtList[0], delta[0]); + } else if (typeId == 11) { + NBTTagInt intTag = new NBTTagInt((int) delta[0]); + addToList(nbtList[0], intTag); + } + } + } else if (mode == ChangeMode.DELETE || mode == ChangeMode.RESET) { + nbtList[0] = new NBTTagList(); + } + } + }).parser(new Parser() { + + @Override + public String getVariableNamePattern() { + return ".+"; + } + + @Override + @Nullable + public NBTTagList parse(String ignored, ParseContext context) { + return null; + } + + @Override + public String toString(NBTTagList nbtList, int arg1) { + return nbtList.toString(); + } + + @Override + public String toVariableNameString(NBTTagList nbtList) { + return nbtList.toString(); + } + })); + } + + @Override + public Object getEntityNBT(Entity entity) { + net.minecraft.server.v1_8_R2.Entity nmsEntity = ((CraftEntity) entity).getHandle(); + NBTTagCompound NBT = new NBTTagCompound(); + nmsEntity.e(NBT); + return NBT; + } + + @Override + public Object getTileNBT(Block block) { + NBTTagCompound NBT = new NBTTagCompound(); + World nmsWorld = ((CraftWorld) block.getWorld()).getHandle(); + TileEntity tileEntity = nmsWorld.getTileEntity(new BlockPosition(block.getX(), block.getY(), block.getZ())); + if (tileEntity == null) + return null; + tileEntity.b(NBT); + return NBT; + } + + @Override + public Object getItemNBT(ItemStack itemStack) { + if (itemStack.getType() == Material.AIR) + return null; + NBTTagCompound NBT = new NBTTagCompound(); + net.minecraft.server.v1_8_R2.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + NBT = nmsItem.getTag(); + if (NBT == null || NBT.toString().equals("{}")) //Null or empty. + return null; + return new Object[] { NBT }; + } + + @Override + public void setEntityNBT(Entity entity, Object newCompound) { + if (newCompound instanceof NBTTagCompound) { + net.minecraft.server.v1_8_R2.Entity nmsEntity = ((CraftEntity) entity).getHandle(); + nmsEntity.f((NBTTagCompound) newCompound); + } + } + + @Override + public void setTileNBT(Block block, Object newCompound) { + if (newCompound instanceof NBTTagCompound) { + World nmsWorld = ((CraftWorld) block.getWorld()).getHandle(); + TileEntity tileEntity = nmsWorld.getTileEntity(new BlockPosition(block.getX(), block.getY(), block.getZ())); + if (tileEntity == null) + return; + tileEntity.a((NBTTagCompound) newCompound); + tileEntity.update(); + nmsWorld.notify(tileEntity.getPosition()); + } + } + + @Override + public ItemStack getItemWithNBT(ItemStack itemStack, Object compound) { + if (compound instanceof NBTTagCompound) { + if (itemStack.getType() == Material.AIR || itemStack == null) + return null; + if (compound == null || compound.toString().equals("{}")) + return itemStack; + net.minecraft.server.v1_8_R2.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + nmsItem.setTag((NBTTagCompound) compound); + ItemStack newItem = CraftItemStack.asCraftMirror(nmsItem); + return newItem; + } + return null; + } + + @Override + public Object getFileNBT(File file) { + FileInputStream fis = null; + try { + fis = new FileInputStream(file); + } catch (FileNotFoundException ex) { + return null; //File doesn't exist. + } + NBTTagCompound fileNBT = null; + try { + fileNBT = NBTCompressedStreamTools.a(fis); + fis.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } finally { + try { + fis.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + return fileNBT; + } + + @Override + public void setFileNBT(File file, Object newCompound) { + OutputStream os = null; + try { + os = new FileOutputStream(file); + } catch (FileNotFoundException ex) { + ex.printStackTrace(); + } + try { + NBTCompressedStreamTools.a((NBTTagCompound) newCompound, os); + os.close(); + } catch (Exception ex) { + if (ex instanceof EOFException) { + ; //Ignore, just end of the file + } else { + ex.printStackTrace(); + } + } finally { + try { + os.close(); + } catch (Exception ex) { + if (ex instanceof EOFException) { + ; //Ignore. + } else { + ex.printStackTrace(); + } + } + } + } +} \ No newline at end of file diff --git a/src/me/TheBukor/SkStuff/util/NMS_v1_8_R3.java b/src/me/TheBukor/SkStuff/util/NMS_v1_8_R3.java new file mode 100644 index 0000000..f8fcdc4 --- /dev/null +++ b/src/me/TheBukor/SkStuff/util/NMS_v1_8_R3.java @@ -0,0 +1,588 @@ +package me.TheBukor.SkStuff.util; + +import java.io.EOFException; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.NotSerializableException; +import java.io.OutputStream; +import java.io.StreamCorruptedException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.annotation.Nullable; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack; +import org.bukkit.entity.Entity; +import org.bukkit.inventory.ItemStack; + +import ch.njol.skript.Skript; +import ch.njol.skript.classes.Changer; +import ch.njol.skript.classes.ClassInfo; +import ch.njol.skript.classes.Parser; +import ch.njol.skript.classes.Serializer; +import ch.njol.skript.lang.ParseContext; +import ch.njol.skript.registrations.Classes; +import ch.njol.util.coll.CollectionUtils; +import ch.njol.yggdrasil.Fields; +import net.minecraft.server.v1_8_R3.BlockPosition; +import net.minecraft.server.v1_8_R3.EntityInsentient; +import net.minecraft.server.v1_8_R3.MojangsonParseException; +import net.minecraft.server.v1_8_R3.MojangsonParser; +import net.minecraft.server.v1_8_R3.NBTBase; +import net.minecraft.server.v1_8_R3.NBTCompressedStreamTools; +import net.minecraft.server.v1_8_R3.NBTTagByte; +import net.minecraft.server.v1_8_R3.NBTTagCompound; +import net.minecraft.server.v1_8_R3.NBTTagDouble; +import net.minecraft.server.v1_8_R3.NBTTagEnd; +import net.minecraft.server.v1_8_R3.NBTTagFloat; +import net.minecraft.server.v1_8_R3.NBTTagInt; +import net.minecraft.server.v1_8_R3.NBTTagList; +import net.minecraft.server.v1_8_R3.NBTTagLong; +import net.minecraft.server.v1_8_R3.NBTTagShort; +import net.minecraft.server.v1_8_R3.NBTTagString; +import net.minecraft.server.v1_8_R3.PathfinderGoal; +import net.minecraft.server.v1_8_R3.PathfinderGoalSelector; +import net.minecraft.server.v1_8_R3.TileEntity; +import net.minecraft.server.v1_8_R3.World; + +public class NMS_v1_8_R3 implements NMSInterface { + + @Override + public void addToCompound(Object compound, Object toAdd) { + if (compound instanceof NBTTagCompound && toAdd instanceof NBTTagCompound) { + ((NBTTagCompound) compound).a((NBTTagCompound) toAdd); + } + } + + @Override + public void removeFromCompound(Object compound, String ... toRemove) { + if (compound instanceof NBTTagCompound) { + for (String s : toRemove) { + ((NBTTagCompound) compound).remove(s); + } + } + } + + @Override + public Object parseRawNBT(String rawNBT) { + NBTTagCompound parsedNBT = null; + try { + parsedNBT = MojangsonParser.parse(rawNBT); + } catch (MojangsonParseException ex) { + Skript.warning("Error when parsing NBT - " + ex.getMessage()); + } + return parsedNBT; + } + + @Override + public int getContentsId(Object nbtList) { + if (nbtList instanceof NBTTagList) { + return ((NBTTagList) nbtList).f(); + } + return 0; + } + + @Override + public Object[] getContents(Object nbtList) { + if (nbtList instanceof NBTTagList) { + List contents = new ArrayList(); + for (int i = 0; i < ((NBTTagList) nbtList).size(); i++) { + if (getIndex(nbtList, i) != null) { + contents.add(getIndex(nbtList, i)); + } + } + return contents.toArray(); + } + return null; + } + + @Override + public void addToList(Object nbtList, Object toAdd) { + if (nbtList instanceof NBTTagList && toAdd instanceof NBTBase) { + ((NBTTagList) nbtList).add((NBTBase) toAdd); + } + } + + @Override + public void removeFromList(Object nbtList, int index) { + if (nbtList instanceof NBTTagList) { + ((NBTTagList) nbtList).a(index); + } + } + + @Override + public void setIndex(Object nbtList, int index, Object toSet) { + if (nbtList instanceof NBTTagList) { + if (toSet instanceof NBTBase) { + ((NBTTagList) nbtList).a(index, (NBTBase) toSet); + } else { + if (toSet instanceof Byte) { + ((NBTTagList) nbtList).a(index, new NBTTagByte((byte) toSet)); + } else if (toSet instanceof Short) { + ((NBTTagList) nbtList).a(index, new NBTTagShort((short) toSet)); + } else if (toSet instanceof Integer) { + ((NBTTagList) nbtList).a(index, new NBTTagInt((int) toSet)); + } else if (toSet instanceof Long) { + ((NBTTagList) nbtList).a(index, new NBTTagLong((long) toSet)); + } else if (toSet instanceof Float) { + ((NBTTagList) nbtList).a(index, new NBTTagFloat((float) toSet)); + } else if (toSet instanceof Double) { + ((NBTTagList) nbtList).a(index, new NBTTagDouble((double) toSet)); + } else if (toSet instanceof String) { + ((NBTTagList) nbtList).a(index, new NBTTagString((String) toSet)); + } //No need to check for NBTTagList and NBTTagCompound, these extend NBTBase. + } + } + } + + @Override + public Object getIndex(Object nbtList, int index) { + if (nbtList instanceof NBTTagList) { + NBTBase value = ((NBTTagList) nbtList).g(index); + if (value instanceof NBTTagEnd) { + return null; + } else if (value instanceof NBTTagByte) { + return ((NBTTagByte) value).f(); //Byte stored inside a NBTNumber + } else if (value instanceof NBTTagShort) { + return ((NBTTagShort) value).e(); //Short inside a NBTNumber + } else if (value instanceof NBTTagInt) { + return ((NBTTagInt) value).d(); //Integer inside a NBTNumber + } else if (value instanceof NBTTagLong) { + return ((NBTTagLong) value).c(); //Long inside a NBTNumber + } else if (value instanceof NBTTagFloat) { + return ((NBTTagFloat) value).h(); //Float inside a NBTNumber + } else if (value instanceof NBTTagDouble) { + return ((NBTTagDouble) value).g(); //Double inside a NBTNumber + } else if (value instanceof NBTTagString) { + return ((NBTTagString) value).a_(); //String inside the NBTTagString + } else if (value instanceof NBTTagList || value instanceof NBTTagCompound) { + return value; //No need to convert anything, these are registered by the addon. + } + } + return null; + } + + @Override + public void removePathfinderGoal(Object entity, Class goalClass, boolean isTargetSelector) { + if (entity instanceof EntityInsentient) { + ((EntityInsentient) entity).setGoalTarget(null); + if (isTargetSelector) { + Iterator goals = ((List) ReflectionUtils.getField("b", PathfinderGoalSelector.class, ((EntityInsentient) entity).targetSelector)).iterator(); + while (goals.hasNext()) { + Object goal = goals.next(); + if (ReflectionUtils.getField("a", goal.getClass(), goal).getClass() == goalClass) { + goals.remove(); + } + } + } else { + Iterator goals = ((List) ReflectionUtils.getField("b", PathfinderGoalSelector.class, ((EntityInsentient) entity).goalSelector)).iterator(); + while (goals.hasNext()) { + Object goal = goals.next(); + if (ReflectionUtils.getField("a", goal.getClass(), goal).getClass() == goalClass) { + goals.remove(); + } + } + } + } + } + + @Override + public void addPathfinderGoal(Object entity, int priority, Object goal, boolean isTargetSelector) { + if (entity instanceof EntityInsentient && goal instanceof PathfinderGoal) { + if (isTargetSelector) + ((EntityInsentient) entity).targetSelector.a(priority, (PathfinderGoal) goal); + else + ((EntityInsentient) entity).goalSelector.a(priority, (PathfinderGoal) goal); + } + } + + @Override + public void registerCompoundClassInfo() { + Classes.registerClass(new ClassInfo(NBTTagCompound.class, "compound").user("((nbt)?( ?tag)?) ?compounds?").name("NBT Compound").changer(new Changer() { + + @SuppressWarnings("unchecked") + @Override + @Nullable + public Class[] acceptChange(ChangeMode mode) { + if (mode == ChangeMode.ADD || mode == ChangeMode.REMOVE || mode == ChangeMode.SET) { + return CollectionUtils.array(String[].class, NBTTagCompound[].class); + } + return null; + } + + @Override + public void change(NBTTagCompound[] NBT, @Nullable Object[] delta, ChangeMode mode) { + if (mode == ChangeMode.SET) { + if (delta[0] instanceof NBTTagCompound) { + NBT[0] = (NBTTagCompound) delta[0]; + } else { + NBTTagCompound parsedNBT = (NBTTagCompound) parseRawNBT((String) delta[0]); + NBT[0] = parsedNBT; + } + } else if (mode == ChangeMode.ADD) { + if (delta[0] instanceof String) { + NBTTagCompound parsedNBT = (NBTTagCompound) parseRawNBT((String) delta[0]); + addToCompound(NBT[0], parsedNBT); + } else { + addToCompound(NBT[0], delta[0]); + } + } else if (mode == ChangeMode.REMOVE) { + if (delta[0] instanceof NBTTagCompound) + return; + for (Object s : delta) { + NBT[0].remove((String) s); + } + } + } + }).parser(new Parser() { + + @Override + public String getVariableNamePattern() { + return ".+"; + } + + @Override + @Nullable + public NBTTagCompound parse(String rawNBT, ParseContext context) { + if (rawNBT.startsWith("nbt:{") && rawNBT.endsWith("}")) { + Bukkit.broadcastMessage("rawNBT: \u00A72" + rawNBT.substring(4)); + NBTTagCompound NBT = (NBTTagCompound) parseRawNBT(rawNBT.substring(4)); + return NBT; + } + return null; + } + + @Override + public String toString(NBTTagCompound compound, int arg1) { + return compound.toString(); + } + + @Override + public String toVariableNameString(NBTTagCompound compound) { + return "nbt:" + compound.toString(); + } + }).serializer(new Serializer() { + + @Override + public Fields serialize(NBTTagCompound compound) throws NotSerializableException { + Fields f = new Fields(); + f.putObject("asString", compound.toString()); + return f; + } + + @Override + public void deserialize(NBTTagCompound compound, Fields f) throws StreamCorruptedException, NotSerializableException { + assert false; + } + + @Override + protected boolean canBeInstantiated() { + return false; + } + + @Override + protected NBTTagCompound deserialize(Fields fields) throws StreamCorruptedException, NotSerializableException { + String s = fields.getObject("asString", String.class); + NBTTagCompound compound = (NBTTagCompound) parseRawNBT(s); + return compound; + } + + @Override + @Nullable + public NBTTagCompound deserialize(String s) { + NBTTagCompound compound = (NBTTagCompound) parseRawNBT(s); + return compound; + } + + @Override + public boolean mustSyncDeserialization() { + return true; + } + })); + + } + + @Override + public void registerNBTListClassInfo() { + Classes.registerClass(new ClassInfo(NBTTagList.class, "nbtlist").user("nbt ?list ?(tag)?").name("NBT List").changer(new Changer() { + + @SuppressWarnings("unchecked") + @Override + @Nullable + public Class[] acceptChange(ChangeMode mode) { + if (mode == ChangeMode.ADD || mode == ChangeMode.SET || mode == ChangeMode.DELETE || mode == ChangeMode.RESET) { + return CollectionUtils.array(Float[].class, Double[].class, String[].class, NBTTagCompound[].class, Integer[].class, NBTTagList[].class); + } + return null; + } + + @Override + public void change(NBTTagList[] nbtList, @Nullable Object[] delta, ChangeMode mode) { + int typeId = 0; + if (delta instanceof Byte[]) { + typeId = 1; + } else if (delta instanceof Short[]) { + typeId = 2; + } else if (delta instanceof Integer[]) { + typeId = 3; + } else if (delta instanceof Long[]) { + typeId = 4; + } else if (delta instanceof Float[]) { + typeId = 5; + } else if (delta instanceof Double[]) { + typeId = 6; + } else if (delta instanceof String[]) { + typeId = 8; + } else if (delta instanceof NBTTagList[]) { + typeId = 9; + } else if (delta instanceof NBTTagCompound[]) { + typeId = 10; + } else { + return; + } + if (mode == ChangeMode.SET) { + if (typeId == 9) + nbtList[0] = (NBTTagList) delta[0]; + } else if (mode == ChangeMode.ADD) { + if (getContentsId(nbtList[0]) == typeId) { + if (typeId == 1) { + NBTTagByte byteTag = new NBTTagByte((byte) delta[0]); + addToList(nbtList[0], byteTag); + } else if (typeId == 2) { + NBTTagShort shortTag = new NBTTagShort((short) delta[0]); + addToList(nbtList[0], shortTag); + } else if (typeId == 3) { + NBTTagInt intTag = new NBTTagInt((int) delta[0]); + addToList(nbtList[0], intTag); + } else if (typeId == 4) { + NBTTagLong longTag = new NBTTagLong((long) delta[0]); + addToList(nbtList[0], longTag); + } else if (typeId == 5) { + NBTTagFloat floatTag = new NBTTagFloat((float) delta[0]); + addToList(nbtList[0], floatTag); + } else if (typeId == 6) { + NBTTagDouble doubleTag = new NBTTagDouble((double) delta[0]); + addToList(nbtList[0], doubleTag); + } else if (typeId == 8) { + NBTTagString stringTag = new NBTTagString((String) delta [0]); + addToList(nbtList[0], stringTag); + } else if (typeId == 9) { + addToList(nbtList[0], delta[0]); + } else if (typeId == 10) { + addToList(nbtList[0], delta[0]); + } + } + } else if (mode == ChangeMode.DELETE || mode == ChangeMode.RESET) { + nbtList[0] = new NBTTagList(); + } + } + }).parser(new Parser() { + + @Override + public String getVariableNamePattern() { + return ".+"; + } + + @Override + @Nullable + public NBTTagList parse(String listString, ParseContext context) { + if (listString.startsWith("[") && listString.endsWith("]")) { + NBTTagCompound NBT = (NBTTagCompound) parseRawNBT("{SkStuffIsCool:[0:" + listString.substring(1) + "}"); + NBTTagList parsedList = (NBTTagList) NBT.get("SkStuffIsCool"); + return parsedList; + } + return null; + } + + @Override + public String toString(NBTTagList nbtList, int arg1) { + return nbtList.toString(); + } + + @Override + public String toVariableNameString(NBTTagList nbtList) { + return nbtList.toString(); + } + }).serializer(new Serializer() { + + @Override + public Fields serialize(NBTTagList nbtList) throws NotSerializableException { + Fields f = new Fields(); + f.putObject("asString", nbtList.toString()); + return f; + } + + @Override + public void deserialize(NBTTagList nbtList, Fields f) throws StreamCorruptedException, NotSerializableException { + assert false; + } + + @Override + protected boolean canBeInstantiated() { + return false; + } + + @Override + protected NBTTagList deserialize(Fields fields) throws StreamCorruptedException, NotSerializableException { + String s = fields.getObject("asString", String.class); + NBTTagCompound tempNBT = (NBTTagCompound) parseRawNBT("{SkStuffIsCool:" + s + "}"); + NBTTagList nbtList = (NBTTagList) tempNBT.get("SkStuffIsCool"); + return nbtList; + } + + @Override + @Nullable + public NBTTagList deserialize(String s) { + NBTTagCompound tempNBT = (NBTTagCompound) parseRawNBT("{SkStuffIsCool:" + s + "}"); + NBTTagList nbtList = (NBTTagList) tempNBT.get("SkStuffIsCool"); + return nbtList; + } + + @Override + public boolean mustSyncDeserialization() { + return true; + } + })); + } + + @Override + public Object getEntityNBT(Entity entity) { + net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) entity).getHandle(); + NBTTagCompound NBT = new NBTTagCompound(); + nmsEntity.e(NBT); + return NBT; + } + + @Override + public Object getTileNBT(Block block) { + NBTTagCompound NBT = new NBTTagCompound(); + World nmsWorld = ((CraftWorld) block.getWorld()).getHandle(); + TileEntity tileEntity = nmsWorld.getTileEntity(new BlockPosition(block.getX(), block.getY(), block.getZ())); + if (tileEntity == null) + return null; + tileEntity.b(NBT); + return NBT; + } + + @Override + public Object getItemNBT(ItemStack itemStack) { + if (itemStack.getType() == Material.AIR) + return null; + NBTTagCompound itemNBT = CraftItemStack.asNMSCopy(itemStack).getTag(); + Bukkit.broadcastMessage(String.valueOf(itemNBT)); + if (itemNBT.isEmpty()) + itemNBT = null; + return itemNBT; + } + + @Override + public void setEntityNBT(Entity entity, Object newCompound) { + if (newCompound instanceof NBTTagCompound) { + net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) entity).getHandle(); + nmsEntity.f((NBTTagCompound) newCompound); + } + } + + @Override + public void setTileNBT(Block block, Object newCompound) { + if (newCompound instanceof NBTTagCompound) { + World nmsWorld = ((CraftWorld) block.getWorld()).getHandle(); + TileEntity tileEntity = nmsWorld.getTileEntity(new BlockPosition(block.getX(), block.getY(), block.getZ())); + if (tileEntity == null) + return; + tileEntity.a((NBTTagCompound) newCompound); + tileEntity.update(); + nmsWorld.notify(tileEntity.getPosition()); + } + } + + @Override + public ItemStack getItemWithNBT(ItemStack itemStack, Object compound) { + net.minecraft.server.v1_8_R3.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + if (compound instanceof NBTTagCompound && itemStack != null) { + if (itemStack.getType() == Material.AIR) + return null; + if (((NBTTagCompound) compound).isEmpty()) + return itemStack; + nmsItem.setTag((NBTTagCompound) compound); + ItemStack newItem = CraftItemStack.asBukkitCopy(nmsItem); + return newItem; + } else if (compound == null) { + nmsItem.setTag(null); + ItemStack newItem = CraftItemStack.asBukkitCopy(nmsItem); + return newItem; + } + return itemStack; + } + + @Override + public Object getFileNBT(File file) { + FileInputStream fis = null; + try { + fis = new FileInputStream(file); + } catch (FileNotFoundException ex) { + return null; //File doesn't exist. + } + NBTTagCompound fileNBT = null; + try { + fileNBT = NBTCompressedStreamTools.a(fis); + fis.close(); + } catch (IOException ex) { + if (ex instanceof EOFException) { + ; //Nothing. + } else { + ex.printStackTrace(); + } + } finally { + try { + fis.close(); + } catch (IOException ex) { + if (ex instanceof EOFException) { + ; //Ignore it! + } else { + ex.printStackTrace(); + } + } + } + return fileNBT; + } + + @Override + public void setFileNBT(File file, Object newCompound) { + OutputStream os = null; + try { + os = new FileOutputStream(file); + } catch (FileNotFoundException ex) { + ex.printStackTrace(); + } + try { + NBTCompressedStreamTools.a((NBTTagCompound) newCompound, os); + os.close(); + } catch (IOException ex) { + if (ex instanceof EOFException) { + ; //Ignore, just end of the file + } else { + ex.printStackTrace(); + } + } finally { + try { + os.close(); + } catch (IOException ex) { + if (ex instanceof EOFException) { + ; //Ignore. + } else { + ex.printStackTrace(); + } + } + } + } +} \ No newline at end of file diff --git a/src/me/TheBukor/SkStuff/util/ReflectionUtils.java b/src/me/TheBukor/SkStuff/util/ReflectionUtils.java index 3322c04..495de15 100644 --- a/src/me/TheBukor/SkStuff/util/ReflectionUtils.java +++ b/src/me/TheBukor/SkStuff/util/ReflectionUtils.java @@ -46,7 +46,7 @@ public class ReflectionUtils { } return obj; } - + public static void setField(String field, Class clazz, Object object, Object toSet) { Field f = null; try {