From a782c6aac342dc83605534c4b6d18f8eebcdada8 Mon Sep 17 00:00:00 2001 From: MrMicky Date: Tue, 6 Jul 2021 21:14:59 +0200 Subject: [PATCH] Add Java 16 support (#22) * Add Java 16 support * Fix order in VoxelShapeArray --- pom.xml | 10 +-- .../injector/BoundingBoxFixer.java | 87 +++++++++++++------ 2 files changed, 63 insertions(+), 34 deletions(-) diff --git a/pom.xml b/pom.xml index 3afd0c8..67adcf6 100644 --- a/pom.xml +++ b/pom.xml @@ -30,19 +30,11 @@ - - - org.projectlombok - lombok - 1.18.20 - provided - - com.viaversion viaversion-api - 4.0.0-1.17-rc2-SNAPSHOT + 4.0.0 provided diff --git a/src/main/java/de/gerrygames/viarewind/legacysupport/injector/BoundingBoxFixer.java b/src/main/java/de/gerrygames/viarewind/legacysupport/injector/BoundingBoxFixer.java index c98f8ff..bcd66ba 100644 --- a/src/main/java/de/gerrygames/viarewind/legacysupport/injector/BoundingBoxFixer.java +++ b/src/main/java/de/gerrygames/viarewind/legacysupport/injector/BoundingBoxFixer.java @@ -1,29 +1,31 @@ package de.gerrygames.viarewind.legacysupport.injector; import com.viaversion.viaversion.api.Via; +import de.gerrygames.viarewind.legacysupport.BukkitPlugin; import de.gerrygames.viarewind.legacysupport.reflection.ReflectionAPI; -import java.lang.reflect.Constructor; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.logging.Level; public class BoundingBoxFixer { public static void fixLilyPad() { try { - Class blockWaterLilyClass = NMSReflection.getNMSClass("BlockWaterLily"); + 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); + Object boundingBox = boundingBoxField.get(null); + + setBoundingBox(boundingBox, 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(); + BukkitPlugin.getInstance().getLogger().log(Level.SEVERE, "Could not fix lily pad bounding box.", ex); } } public static void fixLadder() { try { - Class blockLadderClass = NMSReflection.getNMSClass("BlockLadder"); + Class blockLadderClass = NMSReflection.getNMSClass("BlockLadder"); Field boundingBoxNorthField, boundingBoxSouthField, boundingBoxWestField, boundingBoxEastField; @@ -45,28 +47,63 @@ public class BoundingBoxFixer { 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); + setBoundingBox(boundingBoxEastField.get(null), 0.0D, 0.0D, 0.0D, 0.125D, 1.0D, 1.0D); + setBoundingBox(boundingBoxWestField.get(null), 0.875D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D); + setBoundingBox(boundingBoxSouthField.get(null), 0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 0.125D); + setBoundingBox(boundingBoxNorthField.get(null), 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(); + BukkitPlugin.getInstance().getLogger().log(Level.SEVERE, "Could not fix ladder bounding box.", ex); } } - 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(); + private static void setBoundingBox(Object boundingBox, double... values) throws ReflectiveOperationException { + if (boundingBox.getClass().getSimpleName().equals("VoxelShapeArray")) { + setVoxelShapeArray(boundingBox, values); + return; + } + + if (boundingBox.getClass().getSimpleName().equals("AxisAlignedBB")) { + setAxisAlignedBB(boundingBox, values); + return; + } + + throw new IllegalStateException("Unknown bounding box type: " + boundingBox.getClass().getName()); + } + + private static void setAxisAlignedBB(Object boundingBox, double[] values) throws ReflectiveOperationException { + Field[] doubleFields = Arrays.stream(boundingBox.getClass().getDeclaredFields()) + .filter(f -> f.getType() == double.class) + .toArray(Field[]::new); + + if (doubleFields.length < 6) { + throw new IllegalStateException("Invalid field count for " + boundingBox.getClass().getName() + ": " + doubleFields.length); + } + + for (int i = 0; i < 6; i++) { + Field currentField = doubleFields[i]; + currentField.setAccessible(true); + currentField.setDouble(boundingBox, values[i]); + } + } + + private static void setVoxelShapeArray(Object voxelShapeArray, double[] values) throws ReflectiveOperationException { + Field[] doubleListFields = Arrays.stream(voxelShapeArray.getClass().getDeclaredFields()) + .filter(f -> f.getType().getSimpleName().equals("DoubleList")) + .toArray(Field[]::new); + + if (doubleListFields.length < 3) { + throw new IllegalStateException("Invalid field count for " + voxelShapeArray.getClass().getName() + ": " + doubleListFields.length); + } + + // fastutil is relocated on Spigot but not on Paper + String doubleArrayListClass = doubleListFields[0].getType().getName().replace("DoubleList", "DoubleArrayList"); + Method wrapMethod = Class.forName(doubleArrayListClass).getMethod("wrap", double[].class); + + for (int i = 0; i < 3; i++) { + double[] array = {values[i], values[i + 3]}; + Field field = doubleListFields[i]; + field.setAccessible(true); + field.set(voxelShapeArray, wrapMethod.invoke(null, (Object) array)); } } }