From d16472d0ba38c04d46fbdb59cc035c6796b4798f Mon Sep 17 00:00:00 2001 From: Ben Staddon Date: Fri, 23 Nov 2018 23:37:53 +0000 Subject: [PATCH] Improve reflection helper methods (#4853) --- .../client/model/ModelLoader.java | 4 +- .../net/minecraftforge/common/ForgeHooks.java | 9 +- .../event/ForgeEventFactory.java | 2 +- .../fml/client/FMLClientHandler.java | 6 +- .../fml/common/FMLCommonHandler.java | 2 +- .../common/ObfuscationReflectionHelper.java | 86 ++++++++++- .../fml/common/patcher/ClassPatchManager.java | 4 +- .../common/registry/EntityEntryBuilder.java | 7 +- .../fml/relauncher/CoreModManager.java | 3 +- .../fml/relauncher/FMLLaunchHandler.java | 5 +- .../fml/relauncher/ReflectionHelper.java | 138 +++++++++++++----- .../fml/server/FMLServerHandler.java | 4 +- .../registries/ForgeRegistry.java | 10 +- 13 files changed, 219 insertions(+), 61 deletions(-) diff --git a/src/main/java/net/minecraftforge/client/model/ModelLoader.java b/src/main/java/net/minecraftforge/client/model/ModelLoader.java index f1678fa962..01782f490b 100644 --- a/src/main/java/net/minecraftforge/client/model/ModelLoader.java +++ b/src/main/java/net/minecraftforge/client/model/ModelLoader.java @@ -67,7 +67,6 @@ import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.VertexFormat; import net.minecraft.client.resources.IResourceManager; import net.minecraft.item.Item; -import net.minecraft.launchwrapper.Launch; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.util.registry.IRegistry; @@ -84,6 +83,7 @@ import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.common.ProgressManager; import net.minecraftforge.fml.common.ProgressManager.ProgressBar; import net.minecraftforge.fml.common.registry.ForgeRegistries; +import net.minecraftforge.fml.relauncher.FMLLaunchHandler; import net.minecraftforge.registries.IRegistryDelegate; import org.apache.commons.lang3.tuple.Pair; @@ -128,7 +128,7 @@ public final class ModelLoader extends ModelBakery return isLoading; } - private final boolean enableVerboseMissingInfo = (Boolean)Launch.blackboard.get("fml.deobfuscatedEnvironment") || Boolean.parseBoolean(System.getProperty("forge.verboseMissingModelLogging", "false")); + private final boolean enableVerboseMissingInfo = FMLLaunchHandler.isDeobfuscatedEnvironment() || Boolean.parseBoolean(System.getProperty("forge.verboseMissingModelLogging", "false")); private final int verboseMissingInfoCount = Integer.parseInt(System.getProperty("forge.verboseMissingModelLoggingCount", "5")); public ModelLoader(IResourceManager manager, TextureMap map, BlockModelShapes shapes) diff --git a/src/main/java/net/minecraftforge/common/ForgeHooks.java b/src/main/java/net/minecraftforge/common/ForgeHooks.java index 76121b9899..cf14b94cf3 100644 --- a/src/main/java/net/minecraftforge/common/ForgeHooks.java +++ b/src/main/java/net/minecraftforge/common/ForgeHooks.java @@ -146,11 +146,11 @@ import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.LoaderState; import net.minecraftforge.fml.common.ModContainer; +import net.minecraftforge.fml.common.ObfuscationReflectionHelper; import net.minecraftforge.fml.common.eventhandler.Event; import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher; import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.ConnectionType; import net.minecraftforge.fml.common.registry.ForgeRegistries; -import net.minecraftforge.fml.relauncher.ReflectionHelper; import net.minecraftforge.registries.IForgeRegistry; import net.minecraftforge.registries.RegistryManager; @@ -270,19 +270,19 @@ public class ForgeHooks } toolInit = true; - Set blocks = ReflectionHelper.getPrivateValue(ItemPickaxe.class, null, 0); + Set blocks = ObfuscationReflectionHelper.getPrivateValue(ItemPickaxe.class, null, "field_150915"+"_c"); for (Block block : blocks) { block.setHarvestLevel("pickaxe", 0); } - blocks = ReflectionHelper.getPrivateValue(ItemSpade.class, null, 0); + blocks = ObfuscationReflectionHelper.getPrivateValue(ItemSpade.class, null, "field_150916"+"_c"); for (Block block : blocks) { block.setHarvestLevel("shovel", 0); } - blocks = ReflectionHelper.getPrivateValue(ItemAxe.class, null, 0); + blocks = ObfuscationReflectionHelper.getPrivateValue(ItemAxe.class, null, "field_150917"+"_c"); for (Block block : blocks) { block.setHarvestLevel("axe", 0); @@ -330,7 +330,6 @@ public class ForgeHooks return new ItemStack(Items.WHEAT_SEEDS, 1 + rand.nextInt(fortune * 2 + 1)); } }); - initTools(); } /** diff --git a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java index 2ecef111b9..712b467748 100644 --- a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java +++ b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java @@ -395,7 +395,7 @@ public class ForgeEventFactory public static void firePlayerLoadingEvent(EntityPlayer player, IPlayerFileData playerFileData, String uuidString) { SaveHandler sh = (SaveHandler) playerFileData; - File dir = ObfuscationReflectionHelper.getPrivateValue(SaveHandler.class, sh, "playersDirectory", "field_"+"75771_c"); + File dir = ObfuscationReflectionHelper.getPrivateValue(SaveHandler.class, sh, "field_"+"75771_c"); MinecraftForge.EVENT_BUS.post(new PlayerEvent.LoadFromFile(player, dir, uuidString)); } diff --git a/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java b/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java index 54247bcaae..a2e11b4085 100644 --- a/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java +++ b/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java @@ -961,7 +961,7 @@ public class FMLClientHandler implements IFMLSidedHandler Logger logger = LogManager.getLogger("FML.TEXTURE_ERRORS"); logger.error(Strings.repeat("+=", 25)); logger.error("The following texture errors were found."); - Map resManagers = ObfuscationReflectionHelper.getPrivateValue(SimpleReloadableResourceManager.class, (SimpleReloadableResourceManager)Minecraft.getMinecraft().getResourceManager(), "domainResourceManagers", "field_110548"+"_a"); + Map resManagers = ObfuscationReflectionHelper.getPrivateValue(SimpleReloadableResourceManager.class, (SimpleReloadableResourceManager)Minecraft.getMinecraft().getResourceManager(), "field_110548"+"_a"); for (String resourceDomain : badTextureDomains) { Set missing = missingTextures.get(resourceDomain); @@ -976,7 +976,7 @@ public class FMLClientHandler implements IFMLSidedHandler } else { - List resPacks = ObfuscationReflectionHelper.getPrivateValue(FallbackResourceManager.class, fallbackResourceManager, "resourcePacks","field_110540"+"_a"); + List resPacks = ObfuscationReflectionHelper.getPrivateValue(FallbackResourceManager.class, fallbackResourceManager, "field_110540"+"_a"); logger.error(" domain {} has {} location{}:",resourceDomain, resPacks.size(), resPacks.size() != 1 ? "s" :""); for (IResourcePack resPack : resPacks) { @@ -988,7 +988,7 @@ public class FMLClientHandler implements IFMLSidedHandler else if (resPack instanceof AbstractResourcePack) { AbstractResourcePack resourcePack = (AbstractResourcePack) resPack; - File resPath = ObfuscationReflectionHelper.getPrivateValue(AbstractResourcePack.class, resourcePack, "resourcePackFile","field_110597"+"_b"); + File resPath = ObfuscationReflectionHelper.getPrivateValue(AbstractResourcePack.class, resourcePack, "field_110597"+"_b"); logger.error(" resource pack at path {}",resPath.getPath()); } else diff --git a/src/main/java/net/minecraftforge/fml/common/FMLCommonHandler.java b/src/main/java/net/minecraftforge/fml/common/FMLCommonHandler.java index 91c099518c..3feeacc4c3 100644 --- a/src/main/java/net/minecraftforge/fml/common/FMLCommonHandler.java +++ b/src/main/java/net/minecraftforge/fml/common/FMLCommonHandler.java @@ -507,7 +507,7 @@ public class FMLCommonHandler MinecraftServer server = getMinecraftServerInstance(); Loader.instance().serverStopped(); // FORCE the internal server to stop: hello optifine workaround! - if (server!=null) ObfuscationReflectionHelper.setPrivateValue(MinecraftServer.class, server, false, "field_71316"+"_v", "u", "serverStopped"); + if (server!=null) ObfuscationReflectionHelper.setPrivateValue(MinecraftServer.class, server, false, "field_71316"+"_v"); // allow any pending exit to continue, clear exitLatch CountDownLatch latch = exitLatch; diff --git a/src/main/java/net/minecraftforge/fml/common/ObfuscationReflectionHelper.java b/src/main/java/net/minecraftforge/fml/common/ObfuscationReflectionHelper.java index f88fa81498..41b4825141 100644 --- a/src/main/java/net/minecraftforge/fml/common/ObfuscationReflectionHelper.java +++ b/src/main/java/net/minecraftforge/fml/common/ObfuscationReflectionHelper.java @@ -19,14 +19,18 @@ package net.minecraftforge.fml.common; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.util.Arrays; import net.minecraftforge.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper; import net.minecraftforge.fml.relauncher.ReflectionHelper; import net.minecraftforge.fml.relauncher.ReflectionHelper.UnableToAccessFieldException; import net.minecraftforge.fml.relauncher.ReflectionHelper.UnableToFindFieldException; +import org.objectweb.asm.Type; -import org.apache.logging.log4j.Level; +import javax.annotation.Nullable; /** * Some reflection helper code. @@ -36,6 +40,7 @@ import org.apache.logging.log4j.Level; */ public class ObfuscationReflectionHelper { + @Deprecated // TODO: remove public static T getPrivateValue(Class classToAccess, E instance, int fieldIndex) { try @@ -49,6 +54,7 @@ public class ObfuscationReflectionHelper } } + @Deprecated // TODO: remove public static String[] remapFieldNames(String className, String... fieldNames) { String internalClassName = FMLDeobfuscatingRemapper.INSTANCE.unmap(className.replace('.', '/')); @@ -61,6 +67,22 @@ public class ObfuscationReflectionHelper return mappedNames; } + private static String remapFieldName(Class clazz, String fieldName) + { + String internalClassName = FMLDeobfuscatingRemapper.INSTANCE.unmap(Type.getInternalName(clazz)); + return FMLDeobfuscatingRemapper.INSTANCE.mapFieldName(internalClassName, fieldName, null); + } + + private static String remapMethodName(Class clazz, String methodName, Class returnType, Class... parameterTypes) + { + String internalClassName = FMLDeobfuscatingRemapper.INSTANCE.unmap(Type.getInternalName(clazz)); + Type[] params = Arrays.stream(parameterTypes).map(Type::getType).toArray(Type[]::new); + String desc = Type.getMethodDescriptor(Type.getType(returnType), params); + return FMLDeobfuscatingRemapper.INSTANCE.mapMethodName(internalClassName, methodName, desc); + } + + /** @deprecated use {@link #getPrivateValue(Class, Object, String)} */ + @Deprecated // TODO: remove public static T getPrivateValue(Class classToAccess, E instance, String... fieldNames) { try @@ -79,6 +101,12 @@ public class ObfuscationReflectionHelper } } + public static T getPrivateValue(Class classToAccess, @Nullable E instance, String srgName) + { + return ReflectionHelper.getPrivateValue(classToAccess, instance, remapFieldName(classToAccess, srgName), null); + } + + @Deprecated // TODO: remove public static void setPrivateValue(Class classToAccess, T instance, E value, int fieldIndex) { try @@ -92,6 +120,8 @@ public class ObfuscationReflectionHelper } } + /** @deprecated use {@link #setPrivateValue(Class, Object, Object, String)} */ + @Deprecated // TODO: remove public static void setPrivateValue(Class classToAccess, T instance, E value, String... fieldNames) { try @@ -109,4 +139,58 @@ public class ObfuscationReflectionHelper throw e; } } + + public static void setPrivateValue(Class classToAccess, @Nullable T instance, @Nullable E value, String srgName) + { + ReflectionHelper.setPrivateValue(classToAccess, instance, value, remapFieldName(classToAccess, srgName), null); + } + + /** + * Finds a field with the specified name in the given class and makes it accessible. + * Note: for performance, store the returned value and avoid calling this repeatedly. + *

+ * Throws an exception if the field is not found. + * + * @param clazz The class to find the field on. + * @param srgName The obfuscated name of the field to find. + * + * @return The field with the specified name in the given class. + */ + public static Field findField(Class clazz, String srgName) + { + return ReflectionHelper.findField(clazz, remapFieldName(clazz, srgName), null); + } + + /** + * Finds a method with the specified name and parameters in the given class and makes it accessible. + * Note: for performance, store the returned value and avoid calling this repeatedly. + *

+ * Throws an exception if the method is not found. + * + * @param clazz The class to find the method on. + * @param srgName The obfuscated name of the method to find. + * @param returnType The return type of the method to find. + * @param parameterTypes The parameter types of the method to find. + * + * @return The method with the specified name and type signature in the given class. + */ + public static Method findMethod(Class clazz, String srgName, Class returnType, Class... parameterTypes) + { + String mappedName = remapMethodName(clazz, srgName, returnType, parameterTypes); + return ReflectionHelper.findMethod(clazz, mappedName, null, parameterTypes); + } + + /** + * Finds a constructor in the specified class that has matching parameter types. + * + * @param klass The class to find the constructor in + * @param parameterTypes The parameter types of the constructor. + * @param The type + * + * @return The constructor + */ + public static Constructor findConstructor(Class klass, Class... parameterTypes) + { + return ReflectionHelper.findConstructor(klass, parameterTypes); + } } diff --git a/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatchManager.java b/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatchManager.java index 5d8e3d6f44..68e6467707 100644 --- a/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatchManager.java +++ b/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatchManager.java @@ -33,9 +33,9 @@ import java.util.jar.JarOutputStream; import java.util.jar.Pack200; import java.util.regex.Pattern; -import net.minecraft.launchwrapper.Launch; import net.minecraft.launchwrapper.LaunchClassLoader; import net.minecraftforge.fml.common.FMLLog; +import net.minecraftforge.fml.relauncher.FMLLaunchHandler; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.repackage.com.nothome.delta.GDiffPatcher; import LZMA.LzmaInputStream; @@ -172,7 +172,7 @@ public class ClassPatchManager { InputStream binpatchesCompressed = getClass().getResourceAsStream("/binpatches.pack.lzma"); if (binpatchesCompressed==null) { - if (!((Boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment"))) + if (!FMLLaunchHandler.isDeobfuscatedEnvironment()) { FMLLog.log.fatal("The binary patch set is missing, things are not going to work!"); } diff --git a/src/main/java/net/minecraftforge/fml/common/registry/EntityEntryBuilder.java b/src/main/java/net/minecraftforge/fml/common/registry/EntityEntryBuilder.java index bf0459007c..068b2eada7 100644 --- a/src/main/java/net/minecraftforge/fml/common/registry/EntityEntryBuilder.java +++ b/src/main/java/net/minecraftforge/fml/common/registry/EntityEntryBuilder.java @@ -31,7 +31,8 @@ import net.minecraft.world.biome.Biome; import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.ModContainer; -import net.minecraftforge.fml.relauncher.ReflectionHelper; +import net.minecraftforge.fml.common.ObfuscationReflectionHelper; +import net.minecraftforge.fml.relauncher.ReflectionHelper.UnknownConstructorException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; @@ -250,7 +251,7 @@ public final class EntityEntryBuilder * @throws IllegalStateException If the entity id has not been provided * @throws IllegalStateException If the entity name has not been provided * @throws IllegalStateException If spawns have been provided for a non {@link EntityLiving} - * @throws ReflectionHelper.UnknownConstructorException If a {@link #factory} has not been provided + * @throws UnknownConstructorException If a {@link #factory} has not been provided * and {@link #entity} does not have a constructor accepting {@link World} */ @Nonnull @@ -293,7 +294,7 @@ public final class EntityEntryBuilder ConstructorFactory(final Class entity) { - this.constructor = ReflectionHelper.findConstructor(entity, World.class); + this.constructor = ObfuscationReflectionHelper.findConstructor(entity, World.class); } @Override diff --git a/src/main/java/net/minecraftforge/fml/relauncher/CoreModManager.java b/src/main/java/net/minecraftforge/fml/relauncher/CoreModManager.java index 5e55d2a5ee..80edc00299 100644 --- a/src/main/java/net/minecraftforge/fml/relauncher/CoreModManager.java +++ b/src/main/java/net/minecraftforge/fml/relauncher/CoreModManager.java @@ -76,13 +76,14 @@ public class CoreModManager { private static List ignoredModFiles = Lists.newArrayList(); private static Map> transformers = Maps.newHashMap(); private static List loadPlugins; - private static boolean deobfuscatedEnvironment; private static FMLTweaker tweaker; private static File mcDir; private static List candidateModFiles = Lists.newArrayList(); private static List accessTransformers = Lists.newArrayList(); private static Set rootNames = Sets.newHashSet(); + static boolean deobfuscatedEnvironment; + static { for(String cls : rootPlugins) diff --git a/src/main/java/net/minecraftforge/fml/relauncher/FMLLaunchHandler.java b/src/main/java/net/minecraftforge/fml/relauncher/FMLLaunchHandler.java index ea5be70a96..d47f815cf6 100644 --- a/src/main/java/net/minecraftforge/fml/relauncher/FMLLaunchHandler.java +++ b/src/main/java/net/minecraftforge/fml/relauncher/FMLLaunchHandler.java @@ -135,5 +135,8 @@ public class FMLLaunchHandler INSTANCE.injectPostfixTransformers(); } - + public static boolean isDeobfuscatedEnvironment() + { + return CoreModManager.deobfuscatedEnvironment; + } } diff --git a/src/main/java/net/minecraftforge/fml/relauncher/ReflectionHelper.java b/src/main/java/net/minecraftforge/fml/relauncher/ReflectionHelper.java index 908a622ac1..aaee4f8606 100644 --- a/src/main/java/net/minecraftforge/fml/relauncher/ReflectionHelper.java +++ b/src/main/java/net/minecraftforge/fml/relauncher/ReflectionHelper.java @@ -19,8 +19,8 @@ package net.minecraftforge.fml.relauncher; +import com.google.common.base.MoreObjects; import com.google.common.base.Preconditions; -import net.minecraft.launchwrapper.Launch; import org.apache.commons.lang3.StringUtils; import javax.annotation.Nonnull; @@ -29,65 +29,79 @@ import javax.annotation.Nullable; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.util.StringJoiner; + /** * Some reflection helper code. * - * @author cpw + * This is in FML's coremod land. + * It's split in two because the two classes need to exist in separate classloaders. + * Modders shouldn't be using this class anyways. * + * Use {@link net.minecraftforge.fml.common.ObfuscationReflectionHelper} + * when dealing with obfuscated fields or methods. + * + * @author cpw + * @deprecated not for external use */ +@Deprecated // TODO: remove/relocate/replace public class ReflectionHelper { public static class UnableToFindMethodException extends RuntimeException { private static final long serialVersionUID = 1L; - //private String[] methodNames; + @Deprecated // TODO: remove public UnableToFindMethodException(String[] methodNames, Exception failed) { super(failed); - //this.methodNames = methodNames; } public UnableToFindMethodException(Throwable failed) { super(failed); } - } public static class UnableToFindClassException extends RuntimeException { private static final long serialVersionUID = 1L; - //private String[] classNames; public UnableToFindClassException(String[] classNames, @Nullable Exception err) { super(err); - //this.classNames = classNames; } - } public static class UnableToAccessFieldException extends RuntimeException { private static final long serialVersionUID = 1L; - //private String[] fieldNameList; + @Deprecated // TODO: remove public UnableToAccessFieldException(String[] fieldNames, Exception e) { super(e); - //this.fieldNameList = fieldNames; + } + + public UnableToAccessFieldException(Exception e) + { + super(e); } } public static class UnableToFindFieldException extends RuntimeException { private static final long serialVersionUID = 1L; - //private String[] fieldNameList; + + @Deprecated // TODO: remove public UnableToFindFieldException(String[] fieldNameList, Exception e) { super(e); - //this.fieldNameList = fieldNameList; + } + + public UnableToFindFieldException(Exception e) + { + super(e); } } @@ -99,6 +113,8 @@ public class ReflectionHelper } } + /** @deprecated use {@link #findField(Class, String, String)} */ + @Deprecated // TODO: remove public static Field findField(Class clazz, String... fieldNames) { Exception failed = null; @@ -118,7 +134,41 @@ public class ReflectionHelper throw new UnableToFindFieldException(fieldNames, failed); } + /** + * Finds a field with the specified name in the given class and makes it accessible. + * Note: for performance, store the returned value and avoid calling this repeatedly. + *

+ * Throws an exception if the field is not found. + * + * @param clazz The class to find the field on. + * @param fieldName The name of the field to find (used in developer environments, i.e. "maxStackSize"). + * @param fieldObfName The obfuscated name of the field to find (used in obfuscated environments, i.e. "field_77777_bU"). + * If the name you are looking for is on a class that is never obfuscated, this should be null. + * + * @return The field with the specified name in the given class. + */ + @Nonnull + public static Field findField(@Nonnull Class clazz, @Nonnull String fieldName, @Nullable String fieldObfName) + { + Preconditions.checkNotNull(clazz); + Preconditions.checkArgument(StringUtils.isNotEmpty(fieldName), "Field name cannot be empty"); + + String nameToFind = FMLLaunchHandler.isDeobfuscatedEnvironment() ? fieldName : MoreObjects.firstNonNull(fieldObfName, fieldName); + + try + { + Field f = clazz.getDeclaredField(nameToFind); + f.setAccessible(true); + return f; + } + catch (Exception e) + { + throw new UnableToFindFieldException(e); + } + } + @SuppressWarnings("unchecked") + @Deprecated // TODO: remove public static T getPrivateValue(Class classToAccess, @Nullable E instance, int fieldIndex) { try @@ -129,11 +179,13 @@ public class ReflectionHelper } catch (Exception e) { - throw new UnableToAccessFieldException(new String[0], e); + throw new UnableToAccessFieldException(e); } } + /** @deprecated use {@link #getPrivateValue(Class, Object, String, String )} */ @SuppressWarnings("unchecked") + @Deprecated // TODO: remove public static T getPrivateValue(Class classToAccess, E instance, String... fieldNames) { try @@ -146,6 +198,20 @@ public class ReflectionHelper } } + @SuppressWarnings("unchecked") + public static T getPrivateValue(Class classToAccess, @Nullable E instance, String fieldName, @Nullable String fieldObfName) + { + try + { + return (T) findField(classToAccess, fieldName, fieldObfName).get(instance); + } + catch (Exception e) + { + throw new UnableToAccessFieldException(e); + } + } + + @Deprecated // TODO: remove public static void setPrivateValue(Class classToAccess, T instance, E value, int fieldIndex) { try @@ -156,10 +222,12 @@ public class ReflectionHelper } catch (Exception e) { - throw new UnableToAccessFieldException(new String[0] , e); + throw new UnableToAccessFieldException(e); } } + /** @deprecated use {@link #setPrivateValue(Class, Object, Object, String, String)} */ + @Deprecated // TODO: remove public static void setPrivateValue(Class classToAccess, T instance, E value, String... fieldNames) { try @@ -172,6 +240,18 @@ public class ReflectionHelper } } + public static void setPrivateValue(Class classToAccess, @Nullable T instance, @Nullable E value, String fieldName, @Nullable String fieldObfName) + { + try + { + findField(classToAccess, fieldName, fieldObfName).set(instance, value); + } + catch (Exception e) + { + throw new UnableToAccessFieldException(e); + } + } + @SuppressWarnings("unchecked") public static Class getClass(ClassLoader loader, String... classNames) { @@ -210,15 +290,7 @@ public class ReflectionHelper Preconditions.checkNotNull(clazz); Preconditions.checkArgument(StringUtils.isNotEmpty(methodName), "Method name cannot be empty"); - String nameToFind; - if (methodObfName == null || (Boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment")) - { - nameToFind = methodName; - } - else - { - nameToFind = methodObfName; - } + String nameToFind = FMLLaunchHandler.isDeobfuscatedEnvironment() ? methodName : MoreObjects.firstNonNull(methodObfName, methodName); try { @@ -249,27 +321,25 @@ public class ReflectionHelper Preconditions.checkNotNull(klass, "class"); Preconditions.checkNotNull(parameterTypes, "parameter types"); - final Constructor constructor; try { - constructor = klass.getDeclaredConstructor(parameterTypes); + Constructor constructor = klass.getDeclaredConstructor(parameterTypes); constructor.setAccessible(true); + return constructor; } catch (final NoSuchMethodException e) { final StringBuilder desc = new StringBuilder(); - desc.append(klass.getSimpleName()).append('('); - for (int i = 0, length = parameterTypes.length; i < length; i++) + desc.append(klass.getSimpleName()); + + StringJoiner joiner = new StringJoiner(", ", "(", ")"); + for (Class type : parameterTypes) { - desc.append(parameterTypes[i].getName()); - if (i > length) - { - desc.append(',').append(' '); - } + joiner.add(type.getSimpleName()); } - desc.append(')'); + desc.append(joiner); + throw new UnknownConstructorException("Could not find constructor '" + desc.toString() + "' in " + klass); } - return constructor; } } diff --git a/src/main/java/net/minecraftforge/fml/server/FMLServerHandler.java b/src/main/java/net/minecraftforge/fml/server/FMLServerHandler.java index 9cf088c05e..cee7f454b9 100644 --- a/src/main/java/net/minecraftforge/fml/server/FMLServerHandler.java +++ b/src/main/java/net/minecraftforge/fml/server/FMLServerHandler.java @@ -26,7 +26,6 @@ import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; -import net.minecraft.launchwrapper.Launch; import net.minecraft.network.INetHandler; import net.minecraft.network.NetHandlerPlayServer; import net.minecraft.network.NetworkManager; @@ -45,6 +44,7 @@ import net.minecraftforge.fml.common.ModContainer; import net.minecraftforge.fml.common.StartupQuery; import net.minecraftforge.fml.common.eventhandler.EventBus; import net.minecraftforge.fml.common.network.FMLNetworkEvent; +import net.minecraftforge.fml.relauncher.FMLLaunchHandler; import net.minecraftforge.fml.relauncher.Side; import com.google.common.collect.ImmutableList; @@ -243,7 +243,7 @@ public class FMLServerHandler implements IFMLSidedHandler ZipFile zip = null; try { - if (source.isDirectory() && (Boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment")) + if (source.isDirectory() && FMLLaunchHandler.isDeobfuscatedEnvironment()) { File f = new File(source.toURI().resolve(langFile).getPath()); if (!f.exists()) diff --git a/src/main/java/net/minecraftforge/registries/ForgeRegistry.java b/src/main/java/net/minecraftforge/registries/ForgeRegistry.java index 37ead12aa5..c814810b0c 100644 --- a/src/main/java/net/minecraftforge/registries/ForgeRegistry.java +++ b/src/main/java/net/minecraftforge/registries/ForgeRegistry.java @@ -19,6 +19,7 @@ package net.minecraftforge.registries; +import java.lang.reflect.Method; import java.util.BitSet; import java.util.Collection; import java.util.Collections; @@ -26,20 +27,18 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.apache.commons.lang3.Validate; -import java.util.Set; - import com.google.common.base.Preconditions; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; @@ -56,7 +55,6 @@ import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.common.InjectedModContainer; import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.ModContainer; -import net.minecraftforge.fml.relauncher.ReflectionHelper; public class ForgeRegistry> implements IForgeRegistryInternal, IForgeRegistryModifiable { @@ -431,7 +429,9 @@ public class ForgeRegistry> implements IForgeRe { try { - ReflectionHelper.findMethod(BitSet.class, "trimToSize", null).invoke(this.availabilityMap); + Method method = BitSet.class.getDeclaredMethod("trimToSize"); + method.setAccessible(true); + method.invoke(this.availabilityMap); } catch (Exception e) {