package codechicken.core.asm; import codechicken.lib.asm.ObfMapping; import com.google.common.collect.ImmutableBiMap; import net.minecraftforge.fml.common.asm.transformers.AccessTransformer; import net.minecraftforge.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper; import java.io.IOException; import java.lang.reflect.Field; public class CodeChickenAccessTransformer extends AccessTransformer { private static boolean makeAllPublic; private static Field f_classNameBiMap; private static Object emptyMap = ImmutableBiMap.of(); public CodeChickenAccessTransformer() throws IOException { super(); loadPublicConfig(); } private void loadPublicConfig() { if (ObfMapping.obfuscated) { return; } makeAllPublic = CodeChickenCoreModContainer.config.getTag("dev.runtimePublic").setComment("Enabling this setting will make all minecraft classes public at runtime in MCP just as they are in modloader." + "\nYou should ONLY use this when you are testing with a mod that relies on runtime publicity and doesn't include access transformers." + "\nSuch mods are doing the wrong thing and should be fixed.").getBooleanValue(false); if (!makeAllPublic) { return; } try { f_classNameBiMap = FMLDeobfuscatingRemapper.class.getDeclaredField("classNameBiMap"); f_classNameBiMap.setAccessible(true); } catch (Exception e) { throw new RuntimeException(e); } } @Override public byte[] transform(String name, String transformedName, byte[] bytes) { boolean setPublic = makeAllPublic && name.startsWith("net.minecraft."); if (setPublic) { setClassMap(name); } bytes = super.transform(name, transformedName, bytes); if (setPublic) { restoreClassMap(); } return bytes; } private void restoreClassMap() { try { f_classNameBiMap.set(FMLDeobfuscatingRemapper.INSTANCE, emptyMap); } catch (Exception e) { throw new RuntimeException(e); } } private void setClassMap(String name) { try { f_classNameBiMap.set(FMLDeobfuscatingRemapper.INSTANCE, ImmutableBiMap.of(name.replace('.', '/'), "")); } catch (Exception e) { throw new RuntimeException(e); } } }