Forge compatibility WIP
This commit is contained in:
		| @@ -1,10 +1,16 @@ | |||||||
| package me.libraryaddict.disguise.utilities; | package me.libraryaddict.disguise.utilities; | ||||||
|  |  | ||||||
|  | import java.io.*; | ||||||
| import java.lang.reflect.Field; | import java.lang.reflect.Field; | ||||||
| import java.lang.reflect.Method; | import java.lang.reflect.Method; | ||||||
| import java.lang.reflect.Modifier; | import java.lang.reflect.Modifier; | ||||||
|  | import java.util.HashMap; | ||||||
|  | import java.util.Map; | ||||||
| import java.util.UUID; | import java.util.UUID; | ||||||
|  | import java.util.regex.Matcher; | ||||||
|  | import java.util.regex.Pattern; | ||||||
|  |  | ||||||
|  | import me.libraryaddict.disguise.disguisetypes.PlayerDisguise; | ||||||
| import org.bukkit.Art; | import org.bukkit.Art; | ||||||
| import org.bukkit.Bukkit; | import org.bukkit.Bukkit; | ||||||
| import org.bukkit.Location; | import org.bukkit.Location; | ||||||
| @@ -56,8 +62,83 @@ public class ReflectionManager { | |||||||
|     private static Method damageAndIdleSoundMethod; |     private static Method damageAndIdleSoundMethod; | ||||||
|     private static Class itemClass; |     private static Class itemClass; | ||||||
|     private static Field pingField; |     private static Field pingField; | ||||||
|  |     private static boolean isForge = Bukkit.getServer().getName().equalsIgnoreCase("Cauldron"); | ||||||
|  |     /** | ||||||
|  |      * Map of mc-dev simple class name to fully qualified Forge class name. | ||||||
|  |      */ | ||||||
|  |     private static Map<String, String> ForgeClassMappings; | ||||||
|  |     /** | ||||||
|  |      * Map of Forge fully qualified class names to a map from mc-dev field names to Forge field names. | ||||||
|  |      */ | ||||||
|  |     private static Map<String, Map<String, String>> ForgeFieldMappings; | ||||||
|  |     /** | ||||||
|  |      * Map of Forge fully qualified class names to a map from mc-dev method names to Forge method names. | ||||||
|  |      */ | ||||||
|  |     private static Map<String, Map<String, String>> ForgeMethodMappings; | ||||||
|  |  | ||||||
|  |     private static String dir2fqn(String s) { | ||||||
|  |         return s.replaceAll("/", "."); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     static { |     static { | ||||||
|  |         if (isForge) { | ||||||
|  |             // Initialize the maps by reading the srg file | ||||||
|  |             ForgeClassMappings = new HashMap<String, String>(); | ||||||
|  |             ForgeFieldMappings = new HashMap<String, Map<String, String>>(); | ||||||
|  |             //ForgeMethodMappings = new HashMap<String, Map<String, String>>(); | ||||||
|  |             try { | ||||||
|  |                 InputStream stream = Class.forName("net.minecraftforge.common.MinecraftForge").getClassLoader() | ||||||
|  |                         .getResourceAsStream("mappings/" + getBukkitVersion() + "/cb2numpkg.srg"); | ||||||
|  |                 BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); | ||||||
|  |                 // 1: cb-simpleName | ||||||
|  |                 // 2: forge-fullName (Needs dir2fqn()) | ||||||
|  |                 Pattern classPattern = Pattern.compile("^CL: net/minecraft/server/(\\w+) ([a-zA-Z0-9$/_]+)$"); | ||||||
|  |                 // 1: cb-simpleName | ||||||
|  |                 // 2: cb-fieldName | ||||||
|  |                 // 3: forge-fullName (Needs dir2fqn()) | ||||||
|  |                 // 4: forge-fieldName | ||||||
|  |                 Pattern fieldPattern = Pattern.compile("^FD: net/minecraft/server/(\\w+)/(\\w+) ([a-zA-Z0-9$/_]+)/([a-zA-Z0-9$/_]+)$"); | ||||||
|  |  | ||||||
|  |                 Pattern methodPattern = Pattern.compile("!XXX todo"); | ||||||
|  |  | ||||||
|  |                 String line; | ||||||
|  |                 System.out.println("Reading"); | ||||||
|  |                 while ((line = reader.readLine()) != null) { | ||||||
|  |                     Matcher classMatcher = classPattern.matcher(line); | ||||||
|  |                     if (classMatcher.matches()) { | ||||||
|  |                         ForgeClassMappings.put(classMatcher.group(1), dir2fqn(classMatcher.group(2))); | ||||||
|  |                         continue; | ||||||
|  |                     } | ||||||
|  |                     Matcher fieldMatcher = fieldPattern.matcher(line); | ||||||
|  |                     if (fieldMatcher.matches()) { | ||||||
|  |                         Map<String, String> innerMap = ForgeFieldMappings.get(dir2fqn(fieldMatcher.group(3))); | ||||||
|  |                         if (innerMap == null) { | ||||||
|  |                             innerMap = new HashMap<String, String>(); | ||||||
|  |                             ForgeFieldMappings.put(dir2fqn(fieldMatcher.group(3)), innerMap); | ||||||
|  |                         } | ||||||
|  |                         innerMap.put(fieldMatcher.group(2), fieldMatcher.group(4)); | ||||||
|  |                         continue; | ||||||
|  |                     } | ||||||
|  |                     Matcher methodMatcher = methodPattern.matcher(line); | ||||||
|  |                     if (methodMatcher.matches()) { | ||||||
|  |                         // todo | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 System.out.println(ForgeClassMappings.size() + " class mappings loaded"); | ||||||
|  |                 System.out.println(ForgeFieldMappings.size() + " field mappings loaded"); | ||||||
|  |                 System.out.println(ForgeMethodMappings.size() + " method mappings loaded"); | ||||||
|  |             } catch (ClassNotFoundException e) { | ||||||
|  |                 e.printStackTrace(); | ||||||
|  |                 System.err.println("Warning: Running on Cauldron server, but couldn't load mappings file"); | ||||||
|  |             } catch (IOException e) { | ||||||
|  |                 e.printStackTrace(); | ||||||
|  |                 System.err.println("Warning: Running on Cauldron server, but couldn't load mappings file"); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             System.out.println(ForgeClassMappings.get("EntityLiving")); | ||||||
|  |             System.out.println(getNmsClass("EntityLiving")); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         for (Method method : getNmsClass("EntityLiving").getDeclaredMethods()) { |         for (Method method : getNmsClass("EntityLiving").getDeclaredMethods()) { | ||||||
|             try { |             try { | ||||||
|                 if (method.getReturnType() == float.class && Modifier.isProtected(method.getModifiers()) |                 if (method.getReturnType() == float.class && Modifier.isProtected(method.getModifiers()) | ||||||
| @@ -76,7 +157,7 @@ public class ReflectionManager { | |||||||
|         } |         } | ||||||
|         try { |         try { | ||||||
|             itemClass = getCraftClass("inventory.CraftItemStack"); |             itemClass = getCraftClass("inventory.CraftItemStack"); | ||||||
|             pingField = getNmsClass("EntityPlayer").getField("ping"); |             pingField = getNmsField("EntityPlayer", "ping"); | ||||||
|         } catch (Exception e) { |         } catch (Exception e) { | ||||||
|             e.printStackTrace(); |             e.printStackTrace(); | ||||||
|         } |         } | ||||||
| @@ -113,7 +194,7 @@ public class ReflectionManager { | |||||||
|  |  | ||||||
|     public static FakeBoundingBox getBoundingBox(Entity entity) { |     public static FakeBoundingBox getBoundingBox(Entity entity) { | ||||||
|         try { |         try { | ||||||
|             Object boundingBox = getNmsClass("Entity").getField("boundingBox").get(getNmsEntity(entity)); |             Object boundingBox = getNmsField("Entity", "boundingBox").get(getNmsEntity(entity)); | ||||||
|             double x = 0, y = 0, z = 0; |             double x = 0, y = 0, z = 0; | ||||||
|             int stage = 0; |             int stage = 0; | ||||||
|             for (Field field : boundingBox.getClass().getFields()) { |             for (Field field : boundingBox.getClass().getFields()) { | ||||||
| @@ -236,9 +317,17 @@ public class ReflectionManager { | |||||||
|  |  | ||||||
|     public static Class getNmsClass(String className) { |     public static Class getNmsClass(String className) { | ||||||
|         try { |         try { | ||||||
|  |             if (isForge) { | ||||||
|  |                 String forgeName = ForgeClassMappings.get(className); | ||||||
|  |                 if (forgeName == null) { | ||||||
|  |                     throw new RuntimeException("Missing Forge mapping for " + className); | ||||||
|  |                 } | ||||||
|  |                 return Class.forName(forgeName); | ||||||
|  |             } | ||||||
|  |  | ||||||
|             return Class.forName("net.minecraft.server." + getBukkitVersion() + "." + className); |             return Class.forName("net.minecraft.server." + getBukkitVersion() + "." + className); | ||||||
|         } catch (Exception e) { |         } catch (Exception e) { | ||||||
|             // e.printStackTrace(); |             e.printStackTrace(); | ||||||
|         } |         } | ||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
| @@ -261,6 +350,38 @@ public class ReflectionManager { | |||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public static Field getNmsField(String className, String fieldName) { | ||||||
|  |         return getNmsField(getNmsClass(className), fieldName); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public static Field getNmsField(Class clazz, String fieldName) { | ||||||
|  |         try { | ||||||
|  |             if (isForge) { | ||||||
|  |                 return clazz.getField(ForgeFieldMappings.get(clazz.getName()).get(fieldName)); | ||||||
|  |             } | ||||||
|  |             return clazz.getField(fieldName); | ||||||
|  |         } catch (NoSuchFieldException e) { | ||||||
|  |             e.printStackTrace(); | ||||||
|  |         } | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public static Method getNmsMethod(String className, String methodName, Class<?>... parameters) { | ||||||
|  |         return getNmsMethod(getNmsClass(className), methodName, parameters); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public static Method getNmsMethod(Class clazz, String methodName, Class<?>... parameters) { | ||||||
|  |         try { | ||||||
|  |             if (isForge) { | ||||||
|  |                 return clazz.getMethod(ForgeMethodMappings.get(clazz.getName()).get(methodName), parameters); | ||||||
|  |             } | ||||||
|  |             return clazz.getMethod(methodName, parameters); | ||||||
|  |         } catch (NoSuchMethodException e) { | ||||||
|  |             e.printStackTrace(); | ||||||
|  |         } | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public static double getPing(Player player) { |     public static double getPing(Player player) { | ||||||
|         try { |         try { | ||||||
|             return (double) pingField.getInt(ReflectionManager.getNmsEntity(player)); |             return (double) pingField.getInt(ReflectionManager.getNmsEntity(player)); | ||||||
| @@ -272,7 +393,7 @@ public class ReflectionManager { | |||||||
|  |  | ||||||
|     public static float[] getSize(Entity entity) { |     public static float[] getSize(Entity entity) { | ||||||
|         try { |         try { | ||||||
|             float length = getNmsClass("Entity").getField("length").getFloat(getNmsEntity(entity)); |             float length = getNmsField("Entity", "length").getFloat(getNmsEntity(entity)); | ||||||
|             float width = getNmsClass("Entity").getField("width").getFloat(getNmsEntity(entity)); |             float width = getNmsClass("Entity").getField("width").getFloat(getNmsEntity(entity)); | ||||||
|             float height = getNmsClass("Entity").getField("height").getFloat(getNmsEntity(entity)); |             float height = getNmsClass("Entity").getField("height").getFloat(getNmsEntity(entity)); | ||||||
|             return new float[] { length, width, height }; |             return new float[] { length, width, height }; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user