diff options
author | Draknyte1 <Draknyte1@hotmail.com> | 2017-08-09 18:13:54 +1000 |
---|---|---|
committer | Draknyte1 <Draknyte1@hotmail.com> | 2017-08-09 18:13:54 +1000 |
commit | f329a56cfc49be13de84523bee9990ee14597b62 (patch) | |
tree | 5c6b24987035a880749e4d62692d42cc7ab563cf | |
parent | d99058863bb4c717f6c63926d555811df48558af (diff) | |
download | GT5-Unofficial-f329a56cfc49be13de84523bee9990ee14597b62.tar.gz GT5-Unofficial-f329a56cfc49be13de84523bee9990ee14597b62.tar.bz2 GT5-Unofficial-f329a56cfc49be13de84523bee9990ee14597b62.zip |
% Rewrote the Preloader mod to now be a dummy mod.
+ Added ASM usage to Preloader.
+ MC Version annotations to both GT++ and it's child mod GT++ Dark world.
10 files changed, 318 insertions, 58 deletions
diff --git a/src/Java/gtPlusPlus/GTplusplus.java b/src/Java/gtPlusPlus/GTplusplus.java index 7680d504de..46a9caf73a 100644 --- a/src/Java/gtPlusPlus/GTplusplus.java +++ b/src/Java/gtPlusPlus/GTplusplus.java @@ -16,6 +16,7 @@ import org.apache.commons.lang3.reflect.FieldUtils; import cpw.mods.fml.common.*; import cpw.mods.fml.common.Mod.EventHandler; import cpw.mods.fml.common.event.*; +import cpw.mods.fml.relauncher.IFMLLoadingPlugin.MCVersion; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import gregtech.api.enums.GT_Values; @@ -38,6 +39,7 @@ import gtPlusPlus.xmod.gregtech.common.blocks.textures.TexturesGtTools; import net.minecraft.launchwrapper.Launch; import net.minecraftforge.common.config.Configuration; +@MCVersion(value = "1.7.10") @Mod(modid = CORE.MODID, name = CORE.name, version = CORE.VERSION, dependencies = "required-after:Forge; after:PlayerAPI; after:dreamcraft; after:IC2; after:ihl; after:psychedelicraft; after:gregtech; after:Forestry; after:MagicBees; after:CoFHCore; after:Growthcraft; after:Railcraft; after:CompactWindmills; after:ForbiddenMagic; after:MorePlanet; after:PneumaticCraft; after:ExtraUtilities; after:Thaumcraft; after:rftools; after:simplyjetpacks; after:BigReactors; after:EnderIO;") public class GTplusplus implements ActionListener { diff --git a/src/Java/gtPlusPlus/GTplusplus_Secondary.java b/src/Java/gtPlusPlus/GTplusplus_Secondary.java index e9888ded70..057810955f 100644 --- a/src/Java/gtPlusPlus/GTplusplus_Secondary.java +++ b/src/Java/gtPlusPlus/GTplusplus_Secondary.java @@ -11,6 +11,7 @@ import cpw.mods.fml.common.Mod.CustomProperty; import cpw.mods.fml.common.Mod.EventHandler; import cpw.mods.fml.common.event.*; import cpw.mods.fml.common.registry.GameRegistry; +import cpw.mods.fml.relauncher.IFMLLoadingPlugin.MCVersion; import gtPlusPlus.core.lib.CORE; import gtPlusPlus.core.util.Utils; import gtPlusPlus.core.world.darkworld.Dimension_DarkWorld; @@ -19,6 +20,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.world.World; import net.minecraft.world.chunk.IChunkProvider; +@MCVersion(value = "1.7.10") @ChildMod(parent = CORE.MODID, mod = @Mod(modid = "GT++DarkWorld", name = "GT++ Dark World", version = CORE.VERSION, diff --git a/src/Java/gtPlusPlus/core/util/Utils.java b/src/Java/gtPlusPlus/core/util/Utils.java index b31c248e22..471fcadb62 100644 --- a/src/Java/gtPlusPlus/core/util/Utils.java +++ b/src/Java/gtPlusPlus/core/util/Utils.java @@ -11,6 +11,7 @@ import org.apache.logging.log4j.Logger; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.FMLLog; +import cpw.mods.fml.relauncher.FMLRelaunchLog; import gregtech.api.enums.Materials; import gregtech.api.enums.TC_Aspects; import gregtech.api.enums.TC_Aspects.TC_AspectStack; @@ -203,6 +204,11 @@ public class Utils { //} } + //Non-Dev Comments + public static void LOG_ASM(final String s){ + FMLRelaunchLog.info("", s); + } + public static void paintBox(final Graphics g, final int MinA, final int MinB, final int MaxA, final int MaxB){ g.drawRect (MinA, MinB, MaxA, MaxB); } @@ -547,7 +553,7 @@ public class Utils { return output; } - + public static String sanitizeStringKeepBrackets(final String input){ String temp; String output; diff --git a/src/Java/gtPlusPlus/preloader/CORE_Preloader.java b/src/Java/gtPlusPlus/preloader/CORE_Preloader.java index 562f7d67de..c6d09acbb7 100644 --- a/src/Java/gtPlusPlus/preloader/CORE_Preloader.java +++ b/src/Java/gtPlusPlus/preloader/CORE_Preloader.java @@ -1,8 +1,16 @@ package gtPlusPlus.preloader; +import java.util.ArrayList; +import java.util.List; + +import cpw.mods.fml.common.versioning.ArtifactVersion; +import scala.actors.threadpool.Arrays; + public class CORE_Preloader { public static final String NAME = "GT++ Preloader"; public static final String MODID = "GT++_Preloader"; public static final String VERSION = "0.1-Alpha"; public static boolean enableOldGTcircuits = false; + @SuppressWarnings("unchecked") + public static List<ArtifactVersion> DEPENDENCIES = new ArrayList<>(Arrays.asList(new String[] {"required-before:gregtech;"})); } diff --git a/src/Java/gtPlusPlus/preloader/GTplusplus_Preloader.java b/src/Java/gtPlusPlus/preloader/GTplusplus_Preloader.java deleted file mode 100644 index 737038c84b..0000000000 --- a/src/Java/gtPlusPlus/preloader/GTplusplus_Preloader.java +++ /dev/null @@ -1,55 +0,0 @@ -package gtPlusPlus.preloader; - -import static gtPlusPlus.preloader.CORE_Preloader.*; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.File; - -import cpw.mods.fml.common.Mod; -import cpw.mods.fml.common.Mod.EventHandler; -import cpw.mods.fml.common.event.*; -import gtPlusPlus.core.util.Utils; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.common.config.Configuration; - -@Mod(modid = MODID, name = NAME, version = VERSION, dependencies = "required-before:gregtech;") -public class GTplusplus_Preloader implements ActionListener { - - @EventHandler - public void load(final FMLInitializationEvent e) { - Utils.LOG_INFO("Begin resource allocation for " + MODID + " V" + VERSION); - } - - // Pre-Init - @Mod.EventHandler - public void preInit(final FMLPreInitializationEvent event) { - Utils.LOG_INFO("Loading " + MODID + " V" + VERSION); - // Handle GT++ Config - handleConfigFile(event); - if (CORE_Preloader.enableOldGTcircuits) { - MinecraftForge.EVENT_BUS.register(new Preloader_GT_OreDict()); - } - } - - @EventHandler - public static void postInit(final FMLPostInitializationEvent e) { - Utils.LOG_INFO("Finished loading GT++ Pre-Loader."); - } - - @Override - public void actionPerformed(ActionEvent arg0) { - // TODO Auto-generated method stub - } - - public static void handleConfigFile(final FMLPreInitializationEvent event) { - final Configuration config = new Configuration( - new File(event.getModConfigurationDirectory(), "GTplusplus/GTplusplus.cfg")); - config.load(); - - // Circuits - CORE_Preloader.enableOldGTcircuits = config.getBoolean("enableOldGTcircuits", "gregtech", false, - "Restores circuits and their recipes from Pre-5.09.28 times."); - } - -} diff --git a/src/Java/gtPlusPlus/preloader/Preloader_GT_OreDict.java b/src/Java/gtPlusPlus/preloader/Preloader_GT_OreDict.java index b81f7a2ef4..7583493be4 100644 --- a/src/Java/gtPlusPlus/preloader/Preloader_GT_OreDict.java +++ b/src/Java/gtPlusPlus/preloader/Preloader_GT_OreDict.java @@ -64,7 +64,7 @@ public class Preloader_GT_OreDict { } } - private boolean removeCircuit(ItemStack circuit) { + public static boolean removeCircuit(ItemStack circuit) { int damageValue = circuit.getItemDamage() - 32000; if (circuit.getItem() instanceof GT_MetaGenerated_Item_01) { // 700-720 if (damageValue >= 700 && damageValue <= 720) { @@ -99,7 +99,7 @@ public class Preloader_GT_OreDict { } // Simplification of Life. - private boolean isInstanceOf(Class clazz, Object obj) { + private static boolean isInstanceOf(Class clazz, Object obj) { return clazz.isInstance(obj); } diff --git a/src/Java/gtPlusPlus/preloader/asm/Modify_OreDict.java b/src/Java/gtPlusPlus/preloader/asm/Modify_OreDict.java new file mode 100644 index 0000000000..b4a8bf5c00 --- /dev/null +++ b/src/Java/gtPlusPlus/preloader/asm/Modify_OreDict.java @@ -0,0 +1,93 @@ +package gtPlusPlus.preloader.asm; + +import java.lang.reflect.Field; +import java.util.*; + +import com.google.common.collect.Lists; + +import cpw.mods.fml.common.FMLLog; +import cpw.mods.fml.common.Loader; +import cpw.mods.fml.common.registry.GameData; +import gtPlusPlus.core.util.reflect.ReflectionUtils; +import net.minecraft.item.ItemStack; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.oredict.OreDictionary; + +@SuppressWarnings("unchecked") +public class Modify_OreDict extends OreDictionary{ + + static Field stack; + static Field id; + + private static Map<Integer, List<Integer>> stackToId; // Calculated from 128 * 0.75 + private static List<ArrayList<ItemStack>> idToStack; //ToDo: Unqualify to List when possible {1.8} + + + static { + try { + stack = ReflectionUtils.getField(OreDictionary.class, "stackToId"); + id = ReflectionUtils.getField(OreDictionary.class, "idToStack"); + stackToId = (Map<Integer, List<Integer>>) stack.get(OreDictionary.class); + idToStack = (List<ArrayList<ItemStack>>) stack.get(OreDictionary.class); + } + catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) {} + } + + //Utils.LOG_INFO("O-"+(byte) nameField.get(clazz) + " | "+newValue); + + /** + * Registers a ore item into the dictionary. + * Raises the registerOre function in all registered handlers. + * + * @param name The name of the ore + * @param id The ID of the ore + * @param ore The ore's ItemStack + */ + private static void registerOreImpl(String name, ItemStack ore) + { + if (name == null || name.isEmpty() || "Unknown".equals(name)) return; //prevent bad IDs. + if (ore == null || ore.getItem() == null) + { + FMLLog.bigWarning("Invalid registration attempt for an Ore Dictionary item with name %s has occurred. The registration has been denied to prevent crashes. The mod responsible for the registration needs to correct this.", name); + return; //prevent bad ItemStacks. + } + + int oreID = getOreID(name); + // HACK: use the registry name's ID. It is unique and it knows about substitutions. Fallback to a -1 value (what Item.getIDForItem would have returned) in the case where the registry is not aware of the item yet + // IT should be noted that -1 will fail the gate further down, if an entry already exists with value -1 for this name. This is what is broken and being warned about. + // APPARENTLY it's quite common to do this. OreDictionary should be considered alongside Recipes - you can't make them properly until you've registered with the game. + String registryName = ore.getItem().delegate.name(); + int hash; + if (registryName == null) + { + FMLLog.bigWarning("A broken ore dictionary registration with name %s has occurred. It adds an item (type: %s) which is currently unknown to the game registry. This dictionary item can only support a single value when" + + " registered with ores like this, and NO I am not going to turn this spam off. Just register your ore dictionary entries after the GameRegistry.\n" + + "TO USERS: YES this is a BUG in the mod "+Loader.instance().activeModContainer().getName()+" report it to them!", name, ore.getItem().getClass()); + hash = -1; + } + else + { + hash = GameData.getItemRegistry().getId(registryName); + } + if (ore.getItemDamage() != WILDCARD_VALUE) + { + hash |= ((ore.getItemDamage() + 1) << 16); // +1 so 0 is significant + } + + //Add things to the baked version, and prevent duplicates + List<Integer> ids = stackToId.get(hash); + if (ids != null && ids.contains(oreID)) return; + if (ids == null) + { + ids = Lists.newArrayList(); + stackToId.put(hash, ids); + } + ids.add(oreID); + + //Add to the unbaked version + ore = ore.copy(); + idToStack.get(oreID).add(ore); + MinecraftForge.EVENT_BUS.post(new OreRegisterEvent(name, ore)); + } + +} diff --git a/src/Java/gtPlusPlus/preloader/asm/Preloader_ClassTransformer.java b/src/Java/gtPlusPlus/preloader/asm/Preloader_ClassTransformer.java new file mode 100644 index 0000000000..330aef318a --- /dev/null +++ b/src/Java/gtPlusPlus/preloader/asm/Preloader_ClassTransformer.java @@ -0,0 +1,88 @@ +package gtPlusPlus.preloader.asm; + +import static org.objectweb.asm.Opcodes.ALOAD; +import static org.objectweb.asm.Opcodes.INVOKESTATIC; + +import java.util.Iterator; + +import org.objectweb.asm.*; +import org.objectweb.asm.tree.*; + +import gtPlusPlus.core.util.Utils; +import net.minecraft.launchwrapper.IClassTransformer; + +public class Preloader_ClassTransformer implements IClassTransformer { + + @Override + public byte[] transform(String name, String transformedName, byte[] basicClass) { + + /*if (name.equals("abq")) { + Utils.LOG_ASM("[ASM] INSIDE OBFUSCATED EXPLOSION TRANSFORMER ABOUT TO PATCH: " + name); + return patchClassASM(name, basicClass, true); + } + + else if (name.equals("net.minecraftforge.oredict.OreDictionary")) { + Utils.LOG_ASM("[ASM] INSIDE OREDICT TRANSFORMER ABOUT TO PATCH: " + name); + return patchClassASM(name, basicClass, false); + }*/ + return basicClass; + } + + public byte[] patchClassASM(String name, byte[] bytes, boolean obfuscated) { + + String targetMethodName = ""; + + if(obfuscated == true) + targetMethodName ="a"; + else + targetMethodName ="registerOreImpl"; + + + //set up ASM class manipulation stuff. Consult the ASM docs for details + ClassNode classNode = new ClassNode(); + ClassReader classReader = new ClassReader(bytes); + classReader.accept(classNode, 0); + + + + //Now we loop over all of the methods declared inside the Explosion class until we get to the targetMethodName "doExplosionB" + + // find method to inject into + Iterator<MethodNode> methods = classNode.methods.iterator(); + while(methods.hasNext()) + { + MethodNode m = methods.next(); + Utils.LOG_ASM("[ASM] Method Name: "+m.name + " Desc:" + m.desc); + + //Check if this is doExplosionB and it's method signature is (Z)V which means that it accepts a boolean (Z) and returns a void (V) + if ((m.name.equals(targetMethodName) && m.desc.equals("(Ljava/lang/String;Lnet/minecraft/item/ItemStack;)V"))) + { + Utils.LOG_ASM("[ASM] Inside target method!"); + // find interesting instructions in method, there is a single FDIV instruction we use as target + + // make new instruction list + InsnList toInject = new InsnList(); + + //toInject.add(new VarInsnNode(ALOAD, 0)); + + toInject.add(new VarInsnNode(ALOAD, 1)); + toInject.add(new MethodInsnNode(INVOKESTATIC, "gtPlusPlus/preloader/Preloader_GT_OreDict", "removeCircuit", "(Lnet/minecraft/item/ItemStack;)Z, false")); + toInject.add(new VarInsnNode(Opcodes.IFEQ, 1)); + toInject.add(new VarInsnNode(Opcodes.RETURN, 0)); + //toInject.add(new VarInsnNode(org.objectweb.asm.Opcodes.LABEL END, 0)); + + // inject new instruction list into method instruction list + m.instructions.insert(toInject); + + Utils.LOG_ASM("Patching Complete!"); + break; + } + } + + //ASM specific for cleaning up and returning the final bytes for JVM processing. + ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); + classNode.accept(writer); + return writer.toByteArray(); + } + +} diff --git a/src/Java/gtPlusPlus/preloader/asm/Preloader_DummyContainer.java b/src/Java/gtPlusPlus/preloader/asm/Preloader_DummyContainer.java new file mode 100644 index 0000000000..74289f2cf3 --- /dev/null +++ b/src/Java/gtPlusPlus/preloader/asm/Preloader_DummyContainer.java @@ -0,0 +1,78 @@ +package gtPlusPlus.preloader.asm; + +import java.io.File; +import java.util.Arrays; + +import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.Subscribe; + +import cpw.mods.fml.common.*; +import cpw.mods.fml.common.Mod.EventHandler; +import cpw.mods.fml.common.event.*; +import gtPlusPlus.core.util.Utils; +import gtPlusPlus.preloader.CORE_Preloader; +import net.minecraftforge.common.config.Configuration; + +public class Preloader_DummyContainer extends DummyModContainer { + + public Preloader_DummyContainer() { + + super(new ModMetadata()); + ModMetadata meta = getMetadata(); + meta.modId = CORE_Preloader.MODID; + meta.name = CORE_Preloader.NAME; + meta.version = CORE_Preloader.VERSION; + meta.credits = "Roll Credits ..."; + meta.authorList = Arrays.asList("Alkalus"); + meta.description = ""; + meta.url = ""; + meta.updateUrl = ""; + meta.screenshots = new String[0]; + meta.logoFile = ""; + meta.dependencies = CORE_Preloader.DEPENDENCIES; + + } + + @Override + public boolean registerBus(EventBus bus, LoadController controller) { + bus.register(this); + return true; + } + + @Subscribe + public void modConstruction(FMLConstructionEvent evt){ + + } + + @Subscribe + public void init(FMLInitializationEvent evt) { + + } + + @EventHandler + public void load(final FMLInitializationEvent e) { + Utils.LOG_INFO("Begin resource allocation for " + CORE_Preloader.MODID + " V" + CORE_Preloader.VERSION); + } + + @Subscribe + public void preInit(FMLPreInitializationEvent event) { + Utils.LOG_INFO("Loading " + CORE_Preloader.MODID + " V" + CORE_Preloader.VERSION); + // Handle GT++ Config + handleConfigFile(event); + } + + @Subscribe + public void postInit(FMLPostInitializationEvent evt) { + Utils.LOG_INFO("Finished loading GT++ Pre-Loader."); + } + + public static void handleConfigFile(final FMLPreInitializationEvent event) { + final Configuration config = new Configuration( + new File(event.getModConfigurationDirectory(), "GTplusplus/GTplusplus.cfg")); + config.load(); + + // Circuits + CORE_Preloader.enableOldGTcircuits = config.getBoolean("enableOldGTcircuits", "gregtech", false, + "Restores circuits and their recipes from Pre-5.09.28 times."); + } +}
\ No newline at end of file diff --git a/src/Java/gtPlusPlus/preloader/asm/Preloader_FMLLoadingPlugin.java b/src/Java/gtPlusPlus/preloader/asm/Preloader_FMLLoadingPlugin.java new file mode 100644 index 0000000000..9070e880e6 --- /dev/null +++ b/src/Java/gtPlusPlus/preloader/asm/Preloader_FMLLoadingPlugin.java @@ -0,0 +1,38 @@ +package gtPlusPlus.preloader.asm; + +import java.util.Map; + +import cpw.mods.fml.relauncher.IFMLLoadingPlugin; +import cpw.mods.fml.relauncher.IFMLLoadingPlugin.MCVersion; + +@MCVersion(value = "1.7.10") +public class Preloader_FMLLoadingPlugin implements IFMLLoadingPlugin { + + @Override + public String getAccessTransformerClass() { + return null; + } + + @Override + public String[] getASMTransformerClass() { + //This will return the name of the class + return new String[]{Preloader_ClassTransformer.class.getName()}; + } + + @Override + public String getModContainerClass() { + //This is the name of our dummy container + return Preloader_DummyContainer.class.getName(); + } + + @Override + public String getSetupClass() { + return null; + } + + @Override + public void injectData(Map<String, Object> data) { + + } + +}
\ No newline at end of file |