New 'make jump' effect, PathfinderGoals (in test), not ready for release

This commit is contained in:
Richard 2016-02-04 22:29:41 -02:00
parent addb99a1f2
commit 06fbaf5a81
13 changed files with 633 additions and 80 deletions

View File

@ -3,13 +3,7 @@
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
<classpathentry kind="lib" path="C:/Users/Rubi/AppData/Roaming/.minecraft/Server - Survival - 1.8/plugins/Skript.jar"/>
<classpathentry kind="lib" path="C:/Users/Rubi/AppData/Roaming/.minecraft/workspace/Spigot 1.8, 1.8.3/1.8.3.jar"/>
<classpathentry kind="lib" path="C:/Users/Rubi/AppData/Roaming/.minecraft/workspace/Spigot 1.8, 1.8.3/1.8.jar"/>
<classpathentry kind="lib" path="C:/Users/Rubi/AppData/Roaming/.minecraft/Server - Survival - 1.8/plugins/WorldEdit.jar"/>
<classpathentry kind="lib" path="C:/Users/Rubi/AppData/Roaming/.minecraft/workspace/Spigot 1.8, 1.8.3/1.7.10.jar"/>
<classpathentry kind="lib" path="C:/Users/Rubi/AppData/Roaming/.minecraft/workspace/Spigot 1.8, 1.8.3/1.7.9.jar"/>
<classpathentry kind="lib" path="C:/Users/Rubi/AppData/Roaming/.minecraft/workspace/Spigot 1.8, 1.8.3/1.7.5.jar"/>
<classpathentry kind="lib" path="C:/Users/Rubi/AppData/Roaming/.minecraft/workspace/Spigot 1.8, 1.8.3/1.7.2.jar"/>
<classpathentry kind="lib" path="C:/Users/Rubi/AppData/Roaming/.minecraft/workspace/Spigot 1.8, 1.8.3/1.8.7.jar"/>
<classpathentry kind="lib" path="C:/Users/Rubi/AppData/Roaming/.minecraft/workspace/Spigot 1.8, 1.8.3/VanishNoPacket.jar"/>
<classpathentry kind="output" path="bin"/>

View File

@ -1,6 +1,6 @@
name: SkStuff
author: TheBukor
description: A Skript addon which adds extra functionalities such as NBT and extended WorldEdit support.
version: 1.4.2.1
version: 1.5
main: me.TheBukor.SkStuff.SkStuff
softdepend: [Skript, WorldEdit]

View File

@ -26,9 +26,11 @@ 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.EffMakeCylinder;
import me.TheBukor.SkStuff.effects.EffMakeJump;
import me.TheBukor.SkStuff.effects.EffMakePyramid;
import me.TheBukor.SkStuff.effects.EffMakeSphere;
import me.TheBukor.SkStuff.effects.EffMakeWalls;
@ -36,6 +38,7 @@ import me.TheBukor.SkStuff.effects.EffNaturalize;
import me.TheBukor.SkStuff.effects.EffRememberChanges;
import me.TheBukor.SkStuff.effects.EffReplaceBlocksWE;
import me.TheBukor.SkStuff.effects.EffSetBlocksWE;
import me.TheBukor.SkStuff.effects.EffSetPathGoals;
import me.TheBukor.SkStuff.effects.EffSimulateSnow;
import me.TheBukor.SkStuff.effects.EffToggleVanish;
import me.TheBukor.SkStuff.effects.EffUndoRedoSession;
@ -69,8 +72,10 @@ public class SkStuff extends JavaPlugin {
private int exprAmount = 0;
private int typeAmount = 0;
private Class<?> nbtClass = ReflectionUtils.getNMSClass("NBTTagCompound");
private Class<?> nbtParserClass = ReflectionUtils.getNMSClass("MojangsonParser");
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);
@SuppressWarnings("unchecked")
public void onEnable() {
@ -86,6 +91,10 @@ public class SkStuff extends JavaPlugin {
exprAmount += 4;
getLogger().info("Trying to register version specific stuff...");
Skript.registerEffect(EffClearPathGoals.class, "(clear|delete) [all] pathfind[er] goals (of|from) %livingentity%");
// Skript.registerEffect(EffSetPathGoals.class, "add pathfind[er] goal leap at target to %livingentity% with [leap] height [of] %number%");
Skript.registerEffect(EffSetPathGoals.class, "add pathfind[er] goal [priority %-integer%] (0¦(avoid|run away from) %entitydata%,[ ]radius %number%,[ ][at] speed %number%,[ ][at] speed if close %number%|1¦break door[s]|2¦breed,[ ][move to[wards] lover at] speed %number%|3¦eat grass|4¦(flee from the sun|seek shad(e|ow)),[ ][at] speed %number%|5¦float (in[side]|on) water|6¦follow (owner|tamer),[ ][at] speed %number%|7¦follow (adult[s]|parent[s]),[ ][at] speed %number%|8¦(fight back|react to|target) (damager|attacker) [[of] type %entitydata%]|9¦o(c|z)elot jump on blocks,[ ][at] speed %number%|10¦leap at target height %number%|11¦look at players,[ ]radius %number%|12¦melee attack %entitydata%,[ ][at] speed %number%|13¦(move|go) indoors|14¦move thr(u|ough) village,[ ][at] speed %number%|15¦move to[wards] target,[ ][at] speed %number%,[ ]radius %number%|16¦attack nearest entity [of] type %entitydata%|17¦o(c|z)elot attack [chicken]|18¦open door[s]|19¦(panic|flee),[ ][at] speed %number%|20¦look around randomly|21¦(walk around randomly|wander),[ ][at] speed %number%,[ ][with] %integer% ticks between mov(e[ment]|ing)|22¦sit|23¦[creeper] swell)");
Skript.registerEffect(EffMakeJump.class, "make %livingentity% jump");
Skript.registerExpression(ExprNBTOf.class, Object.class, ExpressionType.PROPERTY, "nbt[[ ]tag[s]] of %entity/block/itemstack%", "%entity/block/itemstack%'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%");
@ -98,8 +107,8 @@ public class SkStuff extends JavaPlugin {
@Override
@Nullable
public Class<?>[] acceptChange(ChangeMode mode) {
if (mode == ChangeMode.ADD || mode == ChangeMode.REMOVE) {
return CollectionUtils.array(String[].class);
if (mode == ChangeMode.ADD || mode == ChangeMode.REMOVE || mode == ChangeMode.SET) {
return CollectionUtils.array(String[].class, nbtArrayClass);
}
return null;
}
@ -107,22 +116,31 @@ public class SkStuff extends JavaPlugin {
@Override
public void change(Object[] NBT, @Nullable Object[] delta, ChangeMode mode) {
if (NBT[0].getClass().getName().contains("NBTTagCompound")) {
if (!(delta[0] instanceof String))
if (!(delta[0] instanceof String) || !(delta[0].getClass().isInstance(nbtClass)))
return;
String newTags = (String) delta[0];
if (mode == ChangeMode.ADD) {
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;
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();
}
ex.printStackTrace();
NBTUtil.addCompound(NBT[0], NBT1);
} else {
NBTUtil.addCompound(NBT[0], delta[0]);
}
NBTUtil.addCompound(NBT[0], NBT1);
} 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);
@ -137,13 +155,13 @@ public class SkStuff extends JavaPlugin {
@Override
public String getVariableNamePattern() {
return "nbt:{.+:.+}";
return ".+";
}
@Override
@Nullable
public Object parse(String rawNBT, ParseContext context) {
if (rawNBT.startsWith("{") && rawNBT.contains(":") && rawNBT.endsWith("}")) {
if (rawNBT.startsWith("nbt:{") && rawNBT.endsWith("}")) {
Object NBT = null;
try {
NBT = nbtParserClass.getMethod("parse", String.class).invoke(NBT, rawNBT);
@ -168,10 +186,93 @@ public class SkStuff extends JavaPlugin {
@Override
public String toVariableNameString(Object compound) {
return "nbt:" + compound.toString();
return compound.toString();
}
}));
typeAmount += 1;
Classes.registerClass(new ClassInfo<Object>((Class<Object>) nbtListClass, "nbtlist").user("nbt ?list ?(tag)?").name("NBT List").changer(new Changer<Object>() {
@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<Object>() {
@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();
}
}));
typeAmount += 2;
exprAmount += 6;
if (Bukkit.getPluginManager().getPlugin("WorldEdit") != null) {
getLogger().info("WorldEdit found! Registering WorldEdit stuff...");

View File

@ -0,0 +1,54 @@
package me.TheBukor.SkStuff.effects;
import java.util.List;
import javax.annotation.Nullable;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
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;
import me.TheBukor.SkStuff.util.ReflectionUtils;
public class EffClearPathGoals extends Effect {
private Expression<LivingEntity> entity;
private Class<?> goalSelectorClass = ReflectionUtils.getNMSClass("PathfinderGoalSelector", false);
private Class<?> insentientEnt = ReflectionUtils.getNMSClass("EntityInsentient", false);
private Class<?> craftLivEnt = ReflectionUtils.getOBCClass("entity.CraftLivingEntity");
@SuppressWarnings("unchecked")
@Override
public boolean init(Expression<?>[] expr, int matchedPattern, Kleenean arg2, ParseResult result) {
entity = (Expression<LivingEntity>) expr[0];
return true;
}
@Override
public String toString(@Nullable Event e, boolean arg1) {
return "clear all pathfind goals of " + entity.toString(e, false);
}
@Override
protected void execute(Event e) {
LivingEntity ent = entity.getSingle(e);
if (ent instanceof Player || ent == null)
return;
Object obcEnt = craftLivEnt.cast(ent);
try {
Object nmsEnt = insentientEnt.cast(obcEnt.getClass().getMethod("getHandle").invoke(obcEnt));
Object goalSelector = ReflectionUtils.getField("goalSelector", insentientEnt, nmsEnt);
Object targetSelector = ReflectionUtils.getField("targetSelector", insentientEnt, nmsEnt);
((List<?>) ReflectionUtils.getField("b", goalSelectorClass, goalSelector)).clear();
((List<?>) ReflectionUtils.getField("c", goalSelectorClass, goalSelector)).clear();
((List<?>) ReflectionUtils.getField("b", goalSelectorClass, targetSelector)).clear();
((List<?>) ReflectionUtils.getField("c", goalSelectorClass, targetSelector)).clear();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

View File

@ -0,0 +1,47 @@
package me.TheBukor.SkStuff.effects;
import javax.annotation.Nullable;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
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;
import me.TheBukor.SkStuff.util.ReflectionUtils;
public class EffMakeJump extends Effect {
private Expression<LivingEntity> entity;
private Class<?> entInsent = ReflectionUtils.getNMSClass("EntityInsentient", false);
private Class<?> craftLivEnt = ReflectionUtils.getOBCClass("entity.CraftLivingEntity");
@SuppressWarnings("unchecked")
@Override
public boolean init(Expression<?>[] expr, int matchedPattern, Kleenean arg2, ParseResult result) {
entity = (Expression<LivingEntity>) expr[0];
return true;
}
@Override
public String toString(@Nullable Event e, boolean arg1) {
return "make ent jump";
}
@Override
protected void execute(Event e) {
LivingEntity ent = entity.getSingle(e);
if (ent instanceof Player || ent == null)
return;
Object obcEnt = craftLivEnt.cast(ent);
try {
Object nmsEnt = entInsent.cast(obcEnt.getClass().getMethod("getHandle").invoke(obcEnt));
Object controllerJump = nmsEnt.getClass().getMethod("getControllerJump").invoke(nmsEnt);
controllerJump.getClass().getMethod("a").invoke(controllerJump);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

View File

@ -0,0 +1,188 @@
package me.TheBukor.SkStuff.effects;
import javax.annotation.Nullable;
import org.bukkit.Bukkit;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import ch.njol.skript.entity.EntityData;
import ch.njol.skript.lang.Effect;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.util.Kleenean;
import me.TheBukor.SkStuff.util.ReflectionUtils;
public class EffSetPathGoals extends Effect {
private Expression<Integer> goalPriority;
private Expression<EntityData<?>> entityToAvoid;
private Expression<Number> avoidRadius;
private Expression<Number> avoidSpeed1;
private Expression<Number> avoidSpeed2;
private Expression<Number> breedSpeed;
private Expression<Number> fleeSunSpeed;
@SuppressWarnings("unused")
private Expression<Number> followOwnerSpeed;
@SuppressWarnings("unused")
private Expression<Number> followAdultsSpeed;
@SuppressWarnings("unused")
private Expression<EntityData<?>> entitiesToFightBack;
@SuppressWarnings("unused")
private Expression<Number> jumpOnBlockSpeed;
@SuppressWarnings("unused")
private Expression<Number> leapHeight;
@SuppressWarnings("unused")
private Expression<Number> lookRadius;
@SuppressWarnings("unused")
private Expression<EntityData<?>> meleeTarget;
@SuppressWarnings("unused")
private Expression<Number> meleeSpeed;
@SuppressWarnings("unused")
private Expression<Number> moveVillageSpeed;
@SuppressWarnings("unused")
private Expression<Number> moveTargetSpeed;
@SuppressWarnings("unused")
private Expression<Number> moveTargetRadius;
@SuppressWarnings("unused")
private Expression<EntityData<?>> nearTarget;
@SuppressWarnings("unused")
private Expression<Number> panicSpeed;
@SuppressWarnings("unused")
private Expression<Number> randomWalkSpeed;
@SuppressWarnings("unused")
private Expression<Integer> randomWalkInterval;
private Expression<LivingEntity> entity;
private int mark;
private Class<?> goal = ReflectionUtils.getNMSClass("PathfinderGoal", false);
private Class<?> goalSelector = ReflectionUtils.getNMSClass("PathfinderGoalSelector", false);
private Class<?> goalAvoid = ReflectionUtils.getNMSClass("PathfinderGoalAvoidTarget", false);
private Class<?> goalBreed = ReflectionUtils.getNMSClass("PathfinderGoalBreed", false);
private Class<?> goalBreakDoor = ReflectionUtils.getNMSClass("PathfinderGoalBreakDoor", false);
private Class<?> goalEatGrass = ReflectionUtils.getNMSClass("PathfinderGoalEatTile", false);
private Class<?> goalFleeSun = ReflectionUtils.getNMSClass("PathfinderGoalFleeSun", false);
@SuppressWarnings("unused")
private Class<?> goalLeapTarget = ReflectionUtils.getNMSClass("PathfinderGoalLeapAtTarget", false);
private Class<?> entAnimal = ReflectionUtils.getNMSClass("EntityAnimal", false);
private Class<?> entCreature = ReflectionUtils.getNMSClass("EntityCreature", false);
private Class<?> entInsent = ReflectionUtils.getNMSClass("EntityInsentient", false);
private Class<?> craftLivEnt = ReflectionUtils.getOBCClass("entity.CraftLivingEntity");
@SuppressWarnings("unchecked")
@Override
public boolean init(Expression<?>[] expr, int matchedPattern, Kleenean arg2, ParseResult result) {
goalPriority = (Expression<Integer>) expr[0];
mark = result.mark;
if (mark == 0) {
entityToAvoid = (Expression<EntityData<?>>) expr[1];
avoidRadius = (Expression<Number>) expr[2];
avoidSpeed1 = (Expression<Number>) expr[3];
avoidSpeed2 = (Expression<Number>) expr[4];
} else if (mark == 2) {
breedSpeed = (Expression<Number>) expr[5];
} else if (mark == 4) {
fleeSunSpeed = (Expression<Number>) expr[6];
} else if (mark == 6) {
followOwnerSpeed = (Expression<Number>) expr[7];
} else if (mark == 7) {
followAdultsSpeed = (Expression<Number>) expr[8];
} else if (mark == 8) {
entitiesToFightBack = (Expression<EntityData<?>>) expr[9];
} else if (mark == 9) {
jumpOnBlockSpeed = (Expression<Number>) expr[10];
} else if (mark == 10) {
leapHeight = (Expression<Number>) expr[11];
} else if (mark == 11) {
lookRadius = (Expression<Number>) expr[12];
} else if (mark == 12) {
meleeTarget = (Expression<EntityData<?>>) expr[13];
meleeSpeed = (Expression<Number>) expr[14];
} else if (mark == 13) {
moveVillageSpeed = (Expression<Number>) expr[15];
} else if (mark == 15) {
moveTargetSpeed = (Expression<Number>) expr[16];
moveTargetRadius = (Expression<Number>) expr[17];
} else if (mark == 16) {
nearTarget = (Expression<EntityData<?>>) expr[18];
} else if (mark == 19) {
panicSpeed = (Expression<Number>) expr[19];
} else if (mark == 21) {
randomWalkSpeed = (Expression<Number>) expr[20];
randomWalkInterval = (Expression<Integer>) expr[21];
}
entity = (Expression<LivingEntity>) expr[22];
return true;
}
@Override
public String toString(@Nullable Event e, boolean arg1) {
return "add pathfinder goal to ent";
}
@Override
protected void execute(Event e) {
int priority = 0;
if (goalPriority != null) {
priority = goalPriority.getSingle(e).intValue();
} else {
priority = 1;
}
if (priority < 0) {
priority = 1;
} else if (priority > 9) {
priority = 9;
}
LivingEntity ent = entity.getSingle(e);
if (ent instanceof Player || ent == null)
return;
Object obcEnt = craftLivEnt.cast(ent);
try {
Object newGoal = null;
Object nmsEnt = entInsent.cast(obcEnt.getClass().getMethod("getHandle").invoke(obcEnt));
Object goals = ReflectionUtils.getField("goalSelector", entInsent, nmsEnt);
if (mark == 0) {
float radius = avoidRadius.getSingle(e).floatValue();
double spd1 = avoidSpeed1.getSingle(e).doubleValue();
double spd2 = avoidSpeed2.getSingle(e).doubleValue();
EntityData<?> entityData;
String exprInput = entityToAvoid.toString(e, false);
if (exprInput.startsWith("the ")) {
exprInput = exprInput.substring(4);
}
entityData = EntityData.parseWithoutIndefiniteArticle(exprInput);
String className = entityData.getType().getSimpleName();
if (className.equals("HumanEntity"))
className = "Human";
className = "Entity" + className;
Class<?> nmsClass = ReflectionUtils.getNMSClass(className, false);
if (nmsClass == null)
return;
newGoal = goalAvoid.getConstructor(entCreature, Class.class, float.class, double.class, double.class).newInstance(nmsEnt, nmsClass, radius, spd1, spd2);
newGoal = goalSelector.getMethod("a", int.class, goal).invoke(goals, priority, newGoal);
} else if (mark == 1) {
newGoal = goalBreakDoor.getConstructor(entInsent).newInstance(nmsEnt);
newGoal = goalSelector.getMethod("a", int.class, goal).invoke(goals, priority, newGoal);
} else if (mark == 2) {
double spd = breedSpeed.getSingle(e).doubleValue();
if (!(nmsEnt.getClass().isAssignableFrom(entAnimal)))
return;
newGoal = goalBreed.getConstructor(entAnimal, double.class).newInstance(nmsEnt, spd);
newGoal = goalSelector.getMethod("a", int.class, goal).invoke(goals, priority, newGoal);
} else if (mark == 3) {
newGoal = goalEatGrass.getConstructor(entInsent).newInstance(nmsEnt);
newGoal = goalSelector.getMethod("a", int.class, goal).invoke(goals, priority, newGoal);
} else if (mark == 4) {
double spd = fleeSunSpeed.getSingle(e).doubleValue();
newGoal = goalFleeSun.getConstructor(entCreature, double.class).newInstance(nmsEnt, spd);
newGoal = goalSelector.getMethod("a", int.class, goal).invoke(goals, priority, newGoal);
} else {
Bukkit.broadcastMessage("Not an Avoid, BreakDoor, Breed or FleeSun goal");
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

View File

@ -28,9 +28,9 @@ import me.TheBukor.SkStuff.util.ReflectionUtils;
public class ExprFileNBT extends SimpleExpression<Object> {
private Expression<String> input;
private Class<?> nbtClass = ReflectionUtils.getNMSClass("NBTTagCompound");
private Class<?> nbtParserClass = ReflectionUtils.getNMSClass("MojangsonParser");
private Class<?> nbtCompressedClass = ReflectionUtils.getNMSClass("NBTCompressedStreamTools");
private Class<?> nbtClass = ReflectionUtils.getNMSClass("NBTTagCompound", false);
private Class<?> nbtParserClass = ReflectionUtils.getNMSClass("MojangsonParser", false);
private Class<?> nbtCompressedClass = ReflectionUtils.getNMSClass("NBTCompressedStreamTools", false);
@Override
public Class<? extends Object> getReturnType() {

View File

@ -1,7 +1,5 @@
package me.TheBukor.SkStuff.expressions;
import java.lang.reflect.Field;
import javax.annotation.Nullable;
import org.bukkit.entity.Entity;
@ -71,14 +69,7 @@ public class ExprFireProof extends SimpleExpression<Boolean> {
}
if (mode == ChangeMode.SET) {
Boolean newValue = (Boolean) delta[0];
try {
Field field = nmsEnt.getClass().getDeclaredField("fireProof");
field.setAccessible(true);
field.setBoolean(nmsEnt, newValue);
field.setAccessible(false);
} catch (Exception ex) {
ex.printStackTrace();
}
ReflectionUtils.setField("fireProof", nmsEnt.getClass(), nmsEnt, newValue);
}
}

View File

@ -20,9 +20,9 @@ public class ExprItemNBT extends SimpleExpression<ItemStack> {
private Expression<ItemStack> itemStack;
private Expression<String> string;
private Class<?> nbtClass = ReflectionUtils.getNMSClass("NBTTagCompound");
private Class<?> nbtParseClass = ReflectionUtils.getNMSClass("MojangsonParser");
private Class<?> nmsItemClass = ReflectionUtils.getNMSClass("ItemStack");
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");

View File

@ -25,10 +25,10 @@ import me.TheBukor.SkStuff.util.ReflectionUtils;
public class ExprNBTOf extends SimpleExpression<Object> {
private Expression<?> target;
private Class<?> nbtClass = ReflectionUtils.getNMSClass("NBTTagCompound");
private Class<?> nbtParserClass = ReflectionUtils.getNMSClass("MojangsonParser");
private Class<?> nmsPosClass = ReflectionUtils.getNMSClass("BlockPosition");
private Class<?> nmsItemClass = ReflectionUtils.getNMSClass("ItemStack");
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");

View File

@ -16,8 +16,8 @@ public class ExprTagOf extends SimpleExpression<Object> {
private Expression<String> string;
private Expression<Object> compound;
private Class<?> nbtClass = ReflectionUtils.getNMSClass("NBTTagCompound");
private Class<?> nbtBaseClass = ReflectionUtils.getNMSClass("NBTBase");
private Class<?> nbtClass = ReflectionUtils.getNMSClass("NBTTagCompound", false);
private Class<?> nbtBaseClass = ReflectionUtils.getNMSClass("NBTBase", false);
@Override
public Class<? extends Object> getReturnType() {
@ -47,7 +47,7 @@ public class ExprTagOf extends SimpleExpression<Object> {
String stringTag = string.getSingle(e);
Object tag = null;
try {
tag = NBT.getClass().getMethod("get", String.class).invoke(NBT, stringTag);
tag = nbtClass.getMethod("get", String.class).invoke(NBT, stringTag);
} catch (Exception ex) {
ex.printStackTrace();
}
@ -62,34 +62,45 @@ public class ExprTagOf extends SimpleExpression<Object> {
try {
switch (id) {
case 1:
return new Byte[] { Byte.valueOf(NBT.getClass().getMethod("getByte", String.class).invoke(NBT, stringTag).toString()) };
return new Byte[] { Byte.valueOf(nbtClass.getMethod("getByte", String.class).invoke(NBT, stringTag).toString()) };
case 2:
return new Short[] { Short.valueOf(NBT.getClass().getMethod("getShort", String.class).invoke(NBT, stringTag).toString()) };
return new Short[] { Short.valueOf(nbtClass.getMethod("getShort", String.class).invoke(NBT, stringTag).toString()) };
case 3:
return new Integer[] { Integer.valueOf(NBT.getClass().getMethod("getInt", String.class).invoke(NBT, stringTag).toString()) };
return new Integer[] { Integer.valueOf(nbtClass.getMethod("getInt", String.class).invoke(NBT, stringTag).toString()) };
case 4:
return new Long[] { Long.valueOf(NBT.getClass().getMethod("getLong", String.class).invoke(NBT, stringTag).toString()) };
return new Long[] { Long.valueOf(nbtClass.getMethod("getLong", String.class).invoke(NBT, stringTag).toString()) };
case 5:
return new Float[] { Float.valueOf(NBT.getClass().getMethod("getFloat", String.class).invoke(NBT, stringTag).toString()) };
return new Float[] { Float.valueOf(nbtClass.getMethod("getFloat", String.class).invoke(NBT, stringTag).toString()) };
case 6:
return new Double[] { Double.valueOf(NBT.getClass().getMethod("getDouble", String.class).invoke(NBT, stringTag).toString()) };
return new Double[] { Double.valueOf(nbtClass.getMethod("getDouble", String.class).invoke(NBT, stringTag).toString()) };
case 7: //Byte array, only used in chunk files. Also doesn't have support for the MojangsonParser.
break;
case 8:
return new String[] { NBT.getClass().getMethod("getString", String.class).invoke(NBT, stringTag).toString() };
//Lists will be probably an ASS to implement when I get to them
return new String[] { nbtClass.getMethod("getString", String.class).invoke(NBT, stringTag).toString() };
case 9:
int i;
Object[] list = new Object[] { new Object() };
for (i = 1; i <= 11; i++) { //To get a list I need to know the type of the tags it contains inside,
//since I can't predict what type the list will have, I just loop all of the IDs until I find a non-empty list.
list[0] = nbtClass.getMethod("getList", String.class, int.class).invoke(NBT, stringTag, i); //Try to get the list with the ID "loop-number".
if (!list[0].toString().equals("[]")) { //If list is not empty.
break; //Stop loop.
}
}
return list;
/*
REMOVED TEMPORARILY, HOPEFULLY THE NEW IMPLEMENTATION SHOULD WORK BETTER
int i;
Object list = null;
for (i = 1; i <= 11; i++) { //To get a list I need to know the type of the tags it contains inside,
//since I can't predict what type the list will have, I just loop all of the IDs until I find a non-empty list.
list = NBT.getClass().getMethod("getList", String.class, int.class).invoke(NBT, stringTag, i); //Try to get the list with the ID "loop-number".
list = nbtClass.getMethod("getList", String.class, int.class).invoke(NBT, stringTag, i); //Try to get the list with the ID "loop-number".
if (!list.toString().equals("[]")) { //If list is not empty.
break; //Stop loop.
}
}
String methodName = null;
switch (((int) list.getClass().getMethod("f").invoke(list))) { //list.f() gets the type of the tags in the list.
switch (NBTUtil.getContentsId(list)) {
case 5: //Float
methodName = "e"; //list.e(int) = get float from the specified index.
break;
@ -115,10 +126,11 @@ public class ExprTagOf extends SimpleExpression<Object> {
tags[i] = gottenTag;
}
return tags;
*/
case 10:
return new Object[] { NBT.getClass().getMethod("getCompound", String.class).invoke(NBT, stringTag) };
return new Object[] { nbtClass.getMethod("getCompound", String.class).invoke(NBT, stringTag) };
case 11: //Integer array, this one is only used on the chunk files (and maybe schematic files?).
return new Object[] { NBT.getClass().getMethod("getIntArray", String.class).invoke(NBT, stringTag).toString() };
return new Object[] { nbtClass.getMethod("getIntArray", String.class).invoke(NBT, stringTag).toString() };
default: //This shouldn't happen, but it's better to have this just in case it spills errors everywhere.
break;
}
@ -142,19 +154,19 @@ public class ExprTagOf extends SimpleExpression<Object> {
Object newValue = delta[0];
try {
if (newValue instanceof Byte) {
NBT.getClass().getMethod("setByte", String.class, byte.class).invoke(NBT, stringTag, (byte) newValue);
nbtClass.getMethod("setByte", String.class, byte.class).invoke(NBT, stringTag, ((Byte) newValue).byteValue());
} else if (newValue instanceof Short) {
NBT.getClass().getMethod("setShort", String.class, short.class).invoke(NBT, stringTag, (short) newValue);
nbtClass.getMethod("setShort", String.class, short.class).invoke(NBT, stringTag, ((Short) newValue).shortValue());
} else if (newValue instanceof Integer) {
NBT.getClass().getMethod("setInt", String.class, int.class).invoke(NBT, stringTag, (int) newValue);
nbtClass.getMethod("setInt", String.class, int.class).invoke(NBT, stringTag, ((Integer) newValue).intValue());
} else if (newValue instanceof Long) {
NBT.getClass().getMethod("setLong", String.class, long.class).invoke(NBT, stringTag, (long) newValue);
nbtClass.getMethod("setLong", String.class, long.class).invoke(NBT, stringTag, ((Long) newValue).longValue());
} else if (newValue instanceof Float) {
NBT.getClass().getMethod("setFloat", String.class, float.class).invoke(NBT, stringTag, (float) newValue);
nbtClass.getMethod("setFloat", String.class, float.class).invoke(NBT, stringTag, ((Float) newValue).floatValue());
} else if (newValue instanceof Double) {
NBT.getClass().getMethod("setDouble", String.class, double.class).invoke(NBT, stringTag, (double) newValue);
nbtClass.getMethod("setDouble", String.class, double.class).invoke(NBT, stringTag, ((Double) newValue).doubleValue());
} else if (newValue instanceof String) {
NBT.getClass().getMethod("setString", String.class, String.class).invoke(NBT, stringTag, (String) newValue);
nbtClass.getMethod("setString", String.class, String.class).invoke(NBT, stringTag, String.valueOf(newValue));
} else {
return; //Something else like a list or entire compound.
}
@ -163,7 +175,7 @@ public class ExprTagOf extends SimpleExpression<Object> {
}
} else if (mode == ChangeMode.RESET || mode == ChangeMode.DELETE) {
try {
NBT.getClass().getMethod("set", String.class, nbtBaseClass).invoke(NBT, stringTag, nbtBaseClass.newInstance());
nbtClass.getMethod("set", String.class, nbtBaseClass).invoke(NBT, stringTag, nbtBaseClass.newInstance());
} catch (Exception ex) {
ex.printStackTrace();
}

View File

@ -3,11 +3,17 @@ package me.TheBukor.SkStuff.util;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.fusesource.jansi.Ansi;
import ch.njol.skript.Skript;
public class NBTUtil {
private static Class<?> nbtBaseClass = ReflectionUtils.getNMSClass("NBTBase");
private static Class<?> nbtClass = ReflectionUtils.getNMSClass("NBTTagCompound");
private static Class<?> nbtBaseClass = ReflectionUtils.getNMSClass("NBTBase", false);
private static Class<?> nbtClass = ReflectionUtils.getNMSClass("NBTTagCompound", false);
private static Class<?> nbtListClass = ReflectionUtils.getNMSClass("NBTTagList", false);
/**
* This is actually a copy of the "a(NBTTagCompound)" method in the NBTTagCompound class.
@ -19,22 +25,20 @@ public class NBTUtil {
*/
@SuppressWarnings("unchecked")
public static void addCompound(Object NBT, Object toAdd) {
if (NBT.getClass().getName().contains("NBTTagCompound") && toAdd.getClass().getName().contains("NBTTagCompound")) {
Field map = null;
if (NBT.getClass() == nbtClass && toAdd.getClass() == nbtClass) {
try {
map = nbtClass.getDeclaredField("map");
map.setAccessible(true);
HashMap<String, Object> map = (HashMap<String, Object>) ReflectionUtils.getField("map", nbtClass, toAdd);
Set<String> keySet = (Set<String>) nbtClass.getMethod("c").invoke(toAdd);
Iterator<String> iterator = keySet.iterator();
while(iterator.hasNext()) {
String string = (String) iterator.next();
Object base = nbtBaseClass.cast((((HashMap<String, Object>) map.get(toAdd)).get(string)));
Object base = nbtBaseClass.cast(map.get(string));
if((byte) nbtBaseClass.getMethod("getTypeId").invoke(base) == 10) {
if((boolean) nbtClass.getMethod("hasKeyOfType", String.class, int.class).invoke(NBT, string, 10)) {
Object localNBT = null;
localNBT = nbtClass.getMethod("getCompound", String.class).invoke(localNBT, string);
NBTUtil.addCompound(localNBT, base.getClass().cast(nbtClass));
NBTUtil.addCompound(localNBT, nbtBaseClass.cast(nbtClass));
} else {
nbtClass.getMethod("set", String.class, nbtBaseClass).invoke(NBT, string, base.getClass().getMethod("clone").invoke(base));
}
@ -42,11 +46,139 @@ public class NBTUtil {
nbtClass.getMethod("set", String.class, nbtBaseClass).invoke(NBT, string, base.getClass().getMethod("clone").invoke(base));
}
}
map.setAccessible(false);
} catch (Exception ex) {
map.setAccessible(false);
ex.printStackTrace();
}
}
}
/**
* Gets the ID of the contents inside a NBT List.
* I needed to add this because the 1.7 and before versions of the NBTTagList
* class had a different name for the method that got this value.
* 1.8 used "f()", while 1.7 used "d()".
*/
public static int getContentsId(Object list) {
if (list.getClass() == nbtListClass) {
Field type = null;
int result = 0;
try {
type = nbtListClass.getDeclaredField("type");
type.setAccessible(true);
result = type.getInt(list);
type.setAccessible(false);
return result;
} catch (Exception ex) {
type.setAccessible(false);
ex.printStackTrace();
}
return result;
}
return 0;
}
/**
* Used for the "addToList()" and "setIndex()" methods if the typeId of the contents is still not defined.
*/
public static void setContentsId(Object list, int newId) {
if (list.getClass() == nbtListClass) {
Field type = null;
try {
type = nbtListClass.getDeclaredField("type");
type.setAccessible(true);
type.set(list, newId);
type.setAccessible(false);
} catch (Exception ex) {
type.setAccessible(false);
ex.printStackTrace();
}
}
}
@SuppressWarnings("unchecked")
public static List<Object> getContents(Object list) {
if (list.getClass() == nbtListClass) {
List<Object> result = null;
try {
result = (List<Object>) ReflectionUtils.getField("list", nbtListClass, list);
return result;
} catch (Exception ex) {
ex.printStackTrace();
}
return result;
}
return null;
}
/**
* Kind of a copy of the "add()" method from the NBTTagList class.
*/
public static void addToList(Object list, Object[] toAdd) {
if (list.getClass() == nbtListClass && toAdd[0].getClass() == nbtBaseClass) {
int listTypeId = NBTUtil.getContentsId(list);
int toAddId = 0;
try {
toAddId = (int) toAdd.getClass().getMethod("getTypeId").invoke(toAdd);
} catch (Exception ex) {
ex.printStackTrace();
}
if (listTypeId == 0) {
try {
NBTUtil.setContentsId(list, toAddId);
} catch (Exception ex) {
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));
return;
}
for (Object tag : toAdd) {
NBTUtil.getContents(list).add(tag);
}
}
}
public static void removefromList(Object list, int index) {
if (list.getClass() == nbtListClass) {
if (index >= 0 && index < NBTUtil.getContents(list).size()) {
NBTUtil.getContents(list).remove(index);
}
}
}
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()) {
int listTypeId = NBTUtil.getContentsId(list);
int toAddId = 0;
try {
toAddId = (int) toAdd.getClass().getMethod("getTypeId").invoke(toAdd);
} catch (Exception ex) {
ex.printStackTrace();
}
if (listTypeId == 0) {
try {
NBTUtil.setContentsId(list, toAddId);
} catch (Exception ex) {
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));
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()) {
NBTUtil.getContents(list).get(index);
}
}
return null;
}
}

View File

@ -1,13 +1,17 @@
package me.TheBukor.SkStuff.util;
import java.lang.reflect.Field;
import org.bukkit.Bukkit;
import org.fusesource.jansi.Ansi;
public class ReflectionUtils {
public static Class<?> getNMSClass(String classString) {
public static Class<?> getNMSClass(String classString, boolean isArray) {
String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3] + ".";
String name = "net.minecraft.server." + version + classString;
if (isArray)
name = "[L" + name;
Class<?> nmsClass = null;
try {
nmsClass = Class.forName(name);
@ -31,6 +35,36 @@ public class ReflectionUtils {
return obcClass;
}
public static Object getField(String field, Class<?> clazz, Object object) {
Field f = null;
Object obj = null;
try {
f = clazz.getDeclaredField(field);
f.setAccessible(true);
obj = f.get(object);
f.setAccessible(false);
} catch (Exception ex) {
if (f != null)
f.setAccessible(false);
ex.printStackTrace();
}
return obj;
}
public static void setField(String field, Class<?> clazz, Object object, Object toSet) {
Field f = null;
try {
f = clazz.getDeclaredField(field);
f.setAccessible(true);
f.set(object, toSet);
f.setAccessible(false);
} catch (Exception ex) {
if (f != null)
f.setAccessible(false);
ex.printStackTrace();
}
}
public static String getVersion() {
return Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3] + ".";
}