From ba4d64cb56c0e5619d5457106b12cd62d461adf7 Mon Sep 17 00:00:00 2001 From: Gerrygames Date: Tue, 23 Jul 2019 12:35:25 +0200 Subject: [PATCH] Update lily pad bb fix to 1.13.x, 1.14.x, add ladder bb fix --- pom.xml | 4 +- .../viarewind/legacysupport/BukkitPlugin.java | 25 +- .../injector/BoundingBoxFixer.java | 73 ++++ .../legacysupport/injector/LilyPadFixer.java | 19 - .../legacysupport/injector/NMSReflection.java | 2 +- .../reflection/ReflectionAPI.java | 383 ++++++++++++++++-- src/main/resources/config.yml | 2 + 7 files changed, 434 insertions(+), 74 deletions(-) create mode 100644 src/main/java/de/gerrygames/viarewind/legacysupport/injector/BoundingBoxFixer.java delete mode 100644 src/main/java/de/gerrygames/viarewind/legacysupport/injector/LilyPadFixer.java diff --git a/pom.xml b/pom.xml index eab63b8..a72aceb 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ de.gerrygames viarewind-legacy-support - 1.3.1 + 1.3.2 jar @@ -42,7 +42,7 @@ us.myles viaversion - 2.1.1 + 2.1.3 provided diff --git a/src/main/java/de/gerrygames/viarewind/legacysupport/BukkitPlugin.java b/src/main/java/de/gerrygames/viarewind/legacysupport/BukkitPlugin.java index a010203..5b07cda 100644 --- a/src/main/java/de/gerrygames/viarewind/legacysupport/BukkitPlugin.java +++ b/src/main/java/de/gerrygames/viarewind/legacysupport/BukkitPlugin.java @@ -1,6 +1,6 @@ package de.gerrygames.viarewind.legacysupport; -import de.gerrygames.viarewind.legacysupport.injector.LilyPadFixer; +import de.gerrygames.viarewind.legacysupport.injector.BoundingBoxFixer; import de.gerrygames.viarewind.legacysupport.listener.AreaEffectCloudListener; import de.gerrygames.viarewind.legacysupport.listener.BounceListener; import de.gerrygames.viarewind.legacysupport.listener.BrewingListener; @@ -27,23 +27,26 @@ public class BukkitPlugin extends JavaPlugin { new BukkitRunnable() { @Override public void run() { - if (ProtocolRegistry.SERVER_PROTOCOL==-1) return; + if (ProtocolRegistry.SERVER_PROTOCOL == -1) return; cancel(); - if (ProtocolRegistry.SERVER_PROTOCOL>5 && config.getBoolean("enchanting-gui-fix")) + if (ProtocolRegistry.SERVER_PROTOCOL > 5 && config.getBoolean("enchanting-gui-fix")) Bukkit.getPluginManager().registerEvents(new EnchantingListener(), BukkitPlugin.this); - if (ProtocolRegistry.SERVER_PROTOCOL>78 && config.getBoolean("brewing-stand-gui-fix")) + if (ProtocolRegistry.SERVER_PROTOCOL > 78 && config.getBoolean("brewing-stand-gui-fix")) Bukkit.getPluginManager().registerEvents(new BrewingListener(), BukkitPlugin.this); - if (ProtocolRegistry.SERVER_PROTOCOL>84 && config.getBoolean("lily-pad-fix")) - LilyPadFixer.fix(); - if (ProtocolRegistry.SERVER_PROTOCOL>47 && config.getBoolean("sound-fix")) + if (ProtocolRegistry.SERVER_PROTOCOL > 84 && config.getBoolean("lily-pad-fix")) + BoundingBoxFixer.fixLilyPad(); + if (ProtocolRegistry.SERVER_PROTOCOL > 48 && config.getBoolean("ladder-fix")) + BoundingBoxFixer.fixLadder(); + if (ProtocolRegistry.SERVER_PROTOCOL > 47 && config.getBoolean("sound-fix")) Bukkit.getPluginManager().registerEvents(new SoundListener(), BukkitPlugin.this); - if (ProtocolRegistry.SERVER_PROTOCOL>5 && config.getBoolean("slime-fix")) + if (ProtocolRegistry.SERVER_PROTOCOL > 5 && config.getBoolean("slime-fix")) Bukkit.getPluginManager().registerEvents(new BounceListener(), BukkitPlugin.this); - if (ProtocolRegistry.SERVER_PROTOCOL>76 && config.getBoolean("elytra-fix")) + if (ProtocolRegistry.SERVER_PROTOCOL > 76 && config.getBoolean("elytra-fix")) Bukkit.getPluginManager().registerEvents(new ElytraListener(), BukkitPlugin.this); - if (ProtocolRegistry.SERVER_PROTOCOL>54 && config.getBoolean("area-effect-cloud-particles")) + if (ProtocolRegistry.SERVER_PROTOCOL > 54 && config.getBoolean("area-effect-cloud-particles")) Bukkit.getPluginManager().registerEvents(new AreaEffectCloudListener(), BukkitPlugin.this); - if (config.getBoolean("versioninfo.active")) new VersionInformer(); + if (config.getBoolean("versioninfo.active")) + new VersionInformer(); } }.runTaskTimer(this, 1L, 1L); } diff --git a/src/main/java/de/gerrygames/viarewind/legacysupport/injector/BoundingBoxFixer.java b/src/main/java/de/gerrygames/viarewind/legacysupport/injector/BoundingBoxFixer.java new file mode 100644 index 0000000..9e044d3 --- /dev/null +++ b/src/main/java/de/gerrygames/viarewind/legacysupport/injector/BoundingBoxFixer.java @@ -0,0 +1,73 @@ +package de.gerrygames.viarewind.legacysupport.injector; + +import de.gerrygames.viarewind.legacysupport.reflection.ReflectionAPI; +import us.myles.ViaVersion.api.protocol.ProtocolRegistry; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class BoundingBoxFixer { + + public static void fixLilyPad() { + try { + Class blockWaterLilyClass = NMSReflection.getNMSClass("BlockWaterLily"); + Field boundingBoxField = ReflectionAPI.getFieldAccessible(blockWaterLilyClass, "a"); + setBoundingBox(boundingBoxField, 0.0625, 0.0, 0.0625, 0.9375, 0.015625, 0.9375); + } catch (Exception ex) { + System.out.println("Could not fix lily pad bounding box."); + ex.printStackTrace(); + } + } + + public static void fixLadder() { + try { + Class blockLadderClass = NMSReflection.getNMSClass("BlockLadder"); + + Field boundingBoxNorthField, boundingBoxSouthField, boundingBoxWestField, boundingBoxEastField; + + if (ProtocolRegistry.SERVER_PROTOCOL < 107) { + return; + } else if (ProtocolRegistry.SERVER_PROTOCOL <= 340) { + boundingBoxEastField = ReflectionAPI.getFieldAccessible(blockLadderClass, "b"); + boundingBoxWestField = ReflectionAPI.getFieldAccessible(blockLadderClass, "c"); + boundingBoxSouthField = ReflectionAPI.getFieldAccessible(blockLadderClass, "d"); + boundingBoxNorthField = ReflectionAPI.getFieldAccessible(blockLadderClass, "e"); + } else if (ProtocolRegistry.SERVER_PROTOCOL <= 404) { + boundingBoxEastField = ReflectionAPI.getFieldAccessible(blockLadderClass, "c"); + boundingBoxWestField = ReflectionAPI.getFieldAccessible(blockLadderClass, "o"); + boundingBoxSouthField = ReflectionAPI.getFieldAccessible(blockLadderClass, "p"); + boundingBoxNorthField = ReflectionAPI.getFieldAccessible(blockLadderClass, "q"); + } else { + boundingBoxEastField = ReflectionAPI.getFieldAccessible(blockLadderClass, "c"); + boundingBoxWestField = ReflectionAPI.getFieldAccessible(blockLadderClass, "d"); + boundingBoxSouthField = ReflectionAPI.getFieldAccessible(blockLadderClass, "e"); + boundingBoxNorthField = ReflectionAPI.getFieldAccessible(blockLadderClass, "f"); + } + + setBoundingBox(boundingBoxEastField, 0.0D, 0.0D, 0.0D, 0.125D, 1.0D, 1.0D); + setBoundingBox(boundingBoxWestField, 0.875D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D); + setBoundingBox(boundingBoxSouthField, 0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 0.125D); + setBoundingBox(boundingBoxNorthField, 0.0D, 0.0D, 0.875D, 1.0D, 1.0D, 1.0D); + } catch (Exception ex) { + System.out.println("Could not fix ladder bounding box."); + ex.printStackTrace(); + } + } + + private static void setBoundingBox(Field field, double x1, double y1, double z1, double x2, double y2, double z2) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { + if (field.getType().getSimpleName().equals("AxisAlignedBB")) { + Class boundingBoxClass = field.getType(); + Constructor boundingBoxConstructor = boundingBoxClass.getConstructor(double.class, double.class, double.class, double.class, double.class, double.class); + Object boundingBox = boundingBoxConstructor.newInstance(x1, y1, z1, x2, y2, z2); + ReflectionAPI.setFinalValue(field, boundingBox); + } else if (field.getType().getSimpleName().equals("VoxelShape")) { + Method createVoxelShape = ReflectionAPI.getMethod(NMSReflection.getNMSClass("VoxelShapes"), "create", double.class, double.class, double.class, double.class, double.class, double.class); + Object boundingBox = ReflectionAPI.invokeMethod(createVoxelShape, x1, y1, z1, x2, y2, z2); + ReflectionAPI.setFinalValue(field, boundingBox); + } else { + throw new IllegalStateException(); + } + } +} diff --git a/src/main/java/de/gerrygames/viarewind/legacysupport/injector/LilyPadFixer.java b/src/main/java/de/gerrygames/viarewind/legacysupport/injector/LilyPadFixer.java deleted file mode 100644 index 193891d..0000000 --- a/src/main/java/de/gerrygames/viarewind/legacysupport/injector/LilyPadFixer.java +++ /dev/null @@ -1,19 +0,0 @@ -package de.gerrygames.viarewind.legacysupport.injector; - -import de.gerrygames.viarewind.legacysupport.reflection.ReflectionAPI; - -import java.lang.reflect.Constructor; - -public class LilyPadFixer { - public static void fix() { - try { - Class blockWaterLilyClass = NMSReflection.getNMSClass("BlockWaterLily"); - Class boundingBoxClass = NMSReflection.getNMSClass("AxisAlignedBB"); - Constructor boundingBoxConstructor = boundingBoxClass.getConstructor(double.class, double.class, double.class, double.class, double.class, double.class); - Object boundingBox = boundingBoxConstructor.newInstance(0.0625, 0.0, 0.0625, 0.9375, 0.015625, 0.9375); - ReflectionAPI.setFinalValue(blockWaterLilyClass, "a", boundingBox); - } catch (Exception ignored) { - System.out.println("Could not fix Lily Pads bounding box."); - } - } -} diff --git a/src/main/java/de/gerrygames/viarewind/legacysupport/injector/NMSReflection.java b/src/main/java/de/gerrygames/viarewind/legacysupport/injector/NMSReflection.java index 8fbed5b..b76bdf6 100644 --- a/src/main/java/de/gerrygames/viarewind/legacysupport/injector/NMSReflection.java +++ b/src/main/java/de/gerrygames/viarewind/legacysupport/injector/NMSReflection.java @@ -7,7 +7,7 @@ public class NMSReflection { private static String version; public static String getVersion() { - return version==null ? version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3] : version; + return version == null ? version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3] : version; } public static Class getNMSClass(String name) { diff --git a/src/main/java/de/gerrygames/viarewind/legacysupport/reflection/ReflectionAPI.java b/src/main/java/de/gerrygames/viarewind/legacysupport/reflection/ReflectionAPI.java index c944b4a..a1b5738 100644 --- a/src/main/java/de/gerrygames/viarewind/legacysupport/reflection/ReflectionAPI.java +++ b/src/main/java/de/gerrygames/viarewind/legacysupport/reflection/ReflectionAPI.java @@ -1,123 +1,392 @@ package de.gerrygames.viarewind.legacysupport.reflection; +import sun.reflect.ReflectionFactory; + +import java.lang.reflect.Constructor; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.Map; public class ReflectionAPI { private static Map fields = new HashMap<>(); + private static Map methods = new HashMap<>(); - public static Field getField(Class clazz, String fieldname) throws NoSuchFieldException { - String c = clazz.getName() + ":" + fieldname; - Field f = fields.get(c); - if (f == null) { - f = clazz.getDeclaredField(fieldname); - fields.put(c, f); + public static Field getField(Class clazz, String fieldname) { + String key = clazz.getName() + ":" + fieldname; + Field field = null; + if (fields.containsKey(key)) { + field = fields.get(key); + } else { + try { + field = clazz.getDeclaredField(fieldname); + } catch (NoSuchFieldException ignored) {} + fields.put(key, field); } - return f; - } - - public static void setFieldNotFinal(Field field) { - try { - Field modifiers = Field.class.getDeclaredField("modifiers"); - modifiers.setAccessible(true); - if (Modifier.isFinal(field.getModifiers())) { - modifiers.set(field, field.getModifiers() & ~Modifier.FINAL); - } - } catch (Exception ignored) {} - } - - public static Field getFieldAccessible(Class clazz, String fieldname) throws NoSuchFieldException { - Field field = getField(clazz, fieldname); - field.setAccessible(true); return field; } - public static Object getValue(Class clazz, Object object, String fieldname) throws Exception { - return getFieldAccessible(clazz, fieldname).get(object); + public static boolean hasField(Class clazz, String fieldname) { + return getField(clazz, fieldname) != null; } - public static Object getValue(Object object, String fieldname) throws Exception { + public static Field getFieldAccessible(Class clazz, String fieldname) { + Field field = getField(clazz, fieldname); + if (field != null) field.setAccessible(true); + return field; + } + + public static void setFieldNotFinal(Field field) { + int modifiers = field.getModifiers(); + if (!Modifier.isFinal(modifiers)) return; + setValuePrintException(Field.class, field, "modifiers", modifiers & ~Modifier.FINAL); + } + + public static Constructor getEmptyConstructor(Class clazz) { + try { + return getConstructor(clazz, Object.class.getDeclaredConstructor()); + } catch (NoSuchMethodException ex) { + ex.printStackTrace(); + } + return null; + } + + public static Constructor getConstructor(Class clazz, Constructor superConstructor) { + return (Constructor) ReflectionFactory.getReflectionFactory().newConstructorForSerialization(clazz, superConstructor); + } + + public static E getEmptyObject(Class clazz) { + Constructor constructor = getEmptyConstructor(clazz); + try { + return clazz.cast(constructor.newInstance()); + } catch (InstantiationException | IllegalArgumentException | InvocationTargetException | IllegalAccessException ex) { + ex.printStackTrace(); + } + return null; + } + + public static E copyAndExtendObject(O object, Class clazz) { + if (!object.getClass().isAssignableFrom(clazz)) throw new IllegalArgumentException(clazz.getName() + " is not compatible to " + object.getClass().getName()); + + E copy = getEmptyObject(clazz); + + Class current = object.getClass(); + do { + for (Field f : current.getDeclaredFields()) { + int modifiers = f.getModifiers(); + if (Modifier.isStatic(modifiers)) continue; + if (Modifier.isFinal(modifiers)) setFieldNotFinal(f); + if (!f.isAccessible()) f.setAccessible(true); + try { + f.set(copy, f.get(object)); + } catch (IllegalAccessException ex) { + ex.printStackTrace(); + } + } + } while (((current = current.getSuperclass()) != Object.class)); + + return copy; + } + + public static E invokeMethod(Object object, Method method, Class returnType, Object... params) { + try { + return (E) method.invoke(object, params); + } catch (Exception ex) { + ex.printStackTrace(); + } + return null; + } + + public static E invokeMethod(Method method, Class returnType, Object... params) { + return invokeMethod(null, method, returnType, params); + } + + public static E invokeMethod(Object object, Method method, Object... params) { + try { + return (E) method.invoke(object, params); + } catch (Exception ex) { + ex.printStackTrace(); + } + return null; + } + + public static E invokeMethod(Method method, Object... params) { + return invokeMethod(null, method, params); + } + + public static Method getMethod(Class clazz, String methodname, Class... params) throws NoSuchMethodException { + if (clazz == null) throw new NullPointerException(); + NoSuchMethodException exception = null; + while (clazz != null) { + try { + Method method = clazz.getDeclaredMethod(methodname, params); + method.setAccessible(true); + return method; + } catch (NoSuchMethodException ex) { + exception = ex; + } + clazz = clazz.getSuperclass(); + } + if (exception != null) { + throw exception; + } else { + throw new IllegalStateException(); + } + } + + public static Method getMethodPrintException(Class clazz, String methodname, Class... params) { + try { + return getMethod(clazz, methodname, params); + } catch (NoSuchMethodException ex) { + ex.printStackTrace(); + } + return null; + } + + public static Method getMethodOrNull(Class clazz, String methodname, Class... params) { + try { + return getMethod(clazz, methodname, params); + } catch (NoSuchMethodException ex) { + return null; + } + } + + public static E getValue(Class clazz, Object object, String fieldname) throws NoSuchFieldException, IllegalAccessException { + return (E) getFieldAccessible(clazz, fieldname).get(object); + } + + public static E getValue(Object object, String fieldname) throws NoSuchFieldException, IllegalAccessException { return getValue(object.getClass(), object, fieldname); } - public static Object getValue(Class clazz, String fieldname) throws Exception { + public static E getValue(Class clazz, String fieldname) throws NoSuchFieldException, IllegalAccessException { return getValue(clazz, null, fieldname); } - public static Object getValuePrintException(Object object, String fieldname) { + public static E getValue(Field field) throws IllegalAccessException { + return (E) field.get(null); + } + + public static E getValue(Object object, Field field) throws IllegalAccessException { + return (E) field.get(object); + } + + public static E getValuePrintException(Class clazz, Object object, String fieldname) { + try { + return getValue(clazz, object, fieldname); + } catch (Exception ex) { + ex.printStackTrace(); + } + return null; + } + + public static E getValuePrintException(Object object, String fieldname) { try { return getValue(object, fieldname); - } catch (Exception ex) {ex.printStackTrace();} + } catch (Exception ex) { + ex.printStackTrace(); + } return null; } - public static Object getValuePrintException(Class clazz, String fieldname) { + public static E getValuePrintException(Class clazz, String fieldname) { try { return getValue(clazz, fieldname); - } catch (Exception ex) {ex.printStackTrace();} + } catch (Exception ex) { + ex.printStackTrace(); + } return null; } - public static Object getValueIgnoreException(Object object, String fieldname) { + public static E getValuePrintException(Field field) { + try { + return (E) field.get(null); + } catch (IllegalAccessException ex) { + ex.printStackTrace(); + } + return null; + } + + public static E getValuePrintException(Object object, Field field) { + try { + return (E) field.get(object); + } catch (IllegalAccessException ex) { + ex.printStackTrace(); + } + return null; + } + + public static E getValueIgnoreException(Class clazz, Object object, String fieldname) { + try { + return getValue(clazz, object, fieldname); + } catch (Exception ignored) {} + return null; + } + + public static E getValueIgnoreException(Object object, String fieldname) { try { return getValue(object, fieldname); } catch (Exception ignored) {} return null; } - public static Object getValueIgnoreException(Class clazz, String fieldname) { + public static E getValueIgnoreException(Class clazz, String fieldname) { try { return getValue(clazz, fieldname); } catch (Exception ignored) {} return null; } - private static void setValue(Class clazz, Object object, String fieldname, Object value, boolean isFinal) throws Exception { + public static E getValueIgnoreException(Field field) { + try { + return (E) field.get(null); + } catch (IllegalAccessException ignored) {} + return null; + } + + public static E getValueIgnoreException(Object object, Field field) { + try { + return (E) field.get(object); + } catch (IllegalAccessException ignored) {} + return null; + } + + public static void setValue(Class clazz, Object object, String fieldname, Object value, boolean isFinal) throws NoSuchFieldException, IllegalAccessException { Field field = getFieldAccessible(clazz, fieldname); if (isFinal) setFieldNotFinal(field); field.set(object, value); } - public static void setValue(Object object, String fieldname, Object value) throws Exception { + public static void setValue(Class clazz, Object object, String fieldname, Object value) throws NoSuchFieldException, IllegalAccessException { + setValue(clazz, object, fieldname, value, false); + } + + public static void setValue(Object object, String fieldname, Object value) throws NoSuchFieldException, IllegalAccessException { setValue(object.getClass(), object, fieldname, value, false); } - public static void setValue(Class clazz, String fieldname, Object value) throws Exception { + public static void setValue(Class clazz, String fieldname, Object value) throws NoSuchFieldException, IllegalAccessException { setValue(clazz, null, fieldname, value, false); } - public static void setFinalValue(Object object, String fieldname, Object value) throws Exception { + public static void setValue(Field field, Object value) throws IllegalAccessException { + field.set(null, value); + } + + public static void setValue(Object object, Field field, Object value) throws IllegalAccessException { + field.set(object, value); + } + + public static void setFinalValue(Class clazz, Object object, String fieldname, Object value) throws NoSuchFieldException, IllegalAccessException { + setValue(clazz, object, fieldname, value, true); + } + + public static void setFinalValue(Object object, String fieldname, Object value) throws NoSuchFieldException, IllegalAccessException { setValue(object.getClass(), object, fieldname, value, true); } - public static void setFinalValue(Class clazz, String fieldname, Object value) throws Exception { + public static void setFinalValue(Class clazz, String fieldname, Object value) throws NoSuchFieldException, IllegalAccessException { setValue(clazz, null, fieldname, value, true); } + public static void setFinalValue(Field field, Object value) throws IllegalAccessException { + setFieldNotFinal(field); + field.set(null, value); + } + + public static void setFinalValue(Object object, Field field, Object value) throws IllegalAccessException { + setFieldNotFinal(field); + field.set(object, value); + } + + public static void setValuePrintException(Class clazz, Object object, String fieldname, Object value) { + try { + setValue(clazz, object, fieldname, value); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + public static void setValuePrintException(Object object, String fieldname, Object value) { try { setValue(object, fieldname, value); - } catch (Exception ex) {ex.printStackTrace();} + } catch (Exception ex) { + ex.printStackTrace(); + } } public static void setValuePrintException(Class clazz, String fieldname, Object value) { try { setValue(clazz, fieldname, value); - } catch (Exception ex) {ex.printStackTrace();} + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public static void setValuePrintException(Field field, Object value) { + try { + field.set(null, value); + } catch (IllegalAccessException ex) { + ex.printStackTrace(); + } + } + + public static void setValuePrintException(Object object, Field field, Object value) { + try { + field.set(object, value); + } catch (IllegalAccessException ex) { + ex.printStackTrace(); + } + } + + public static void setFinalValuePrintException(Class clazz, Object object, String fieldname, Object value) { + try { + setFinalValue(clazz, object, fieldname, value); + } catch (Exception ex) { + ex.printStackTrace(); + } } public static void setFinalValuePrintException(Object object, String fieldname, Object value) { try { setFinalValue(object, fieldname, value); - } catch (Exception ex) {ex.printStackTrace();} + } catch (Exception ex) { + ex.printStackTrace(); + } } public static void setFinalValuePrintException(Class clazz, String fieldname, Object value) { try { setFinalValue(clazz, fieldname, value); - } catch (Exception ex) {ex.printStackTrace();} + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public static void setFinalValuePrintException(Field field, Object value) { + setFieldNotFinal(field); + try { + field.set(null, value); + } catch (IllegalAccessException ex) { + ex.printStackTrace(); + } + } + + public static void setFinalValuePrintException(Object object, Field field, Object value) { + setFieldNotFinal(field); + try { + field.set(object, value); + } catch (IllegalAccessException ex) { + ex.printStackTrace(); + } + } + + public static void setValueIgnoreException(Class clazz, Object object, String fieldname, Object value) { + try { + setValue(clazz, object, fieldname, value); + } catch (Exception ignored) {} } public static void setValueIgnoreException(Object object, String fieldname, Object value) { @@ -132,6 +401,24 @@ public class ReflectionAPI { } catch (Exception ignored) {} } + public static void setValueIgnoreException(Field field, Object value) { + try { + field.set(null, value); + } catch (IllegalAccessException ignored) {} + } + + public static void setValueIgnoreException(Object object, Field field, Object value) { + try { + field.set(object, value); + } catch (IllegalAccessException ignored) {} + } + + public static void setFinalValueIgnoreException(Class clazz, Object object, String fieldname, Object value) { + try { + setFinalValue(clazz, object, fieldname, value); + } catch (Exception ignored) {} + } + public static void setFinalValueIgnoreException(Object object, String fieldname, Object value) { try { setFinalValue(object, fieldname, value); @@ -143,4 +430,18 @@ public class ReflectionAPI { setFinalValue(clazz, fieldname, value); } catch (Exception ignored) {} } + + public static void setFinalValueIgnoreException(Field field, Object value) { + setFieldNotFinal(field); + try { + field.set(null, value); + } catch (IllegalAccessException ignored) {} + } + + public static void setFinalValueIgnoreException(Object object, Field field, Object value) { + setFieldNotFinal(field); + try { + field.set(object, value); + } catch (IllegalAccessException ignored) {} + } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index a4fbe7e..647e928 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -4,6 +4,8 @@ brewing-stand-gui-fix: true enchanting-gui-fix: true #Fix the lily pad bounding box to prevent clients lower than 1.9 from glitching lily-pad-fix: true +#Fix the ladder bounding box to prevent clients lower than 1.9 from glitching +ladder-fix: true #If set to true, this plugin will play sounds for 1.8 and lower that got clientside on 1.9 and higher sound-fix: true #If set to true, this plugin will apply velocity to 1.7 if they fall onto slime blocks