diff options
author | Alkalus <Draknyte1@hotmail.com> | 2020-05-27 13:45:04 +0100 |
---|---|---|
committer | Alkalus <Draknyte1@hotmail.com> | 2020-05-27 13:45:04 +0100 |
commit | c66ed4cb8ba64a2fc6132cd7c039738922d0bb23 (patch) | |
tree | d3b23671e5d8409b196e3d1d14b40210c2b8fc49 /src | |
parent | 527f3c0e675ed99b82f36108b29884711b3e1a55 (diff) | |
download | GT5-Unofficial-c66ed4cb8ba64a2fc6132cd7c039738922d0bb23.tar.gz GT5-Unofficial-c66ed4cb8ba64a2fc6132cd7c039738922d0bb23.tar.bz2 GT5-Unofficial-c66ed4cb8ba64a2fc6132cd7c039738922d0bb23.zip |
$ Fixed TC dependency within the Fake Player checker.
+ Added basic TC transformer to try debug the StackOverflowError caused by TC/ExU/GT.
Diffstat (limited to 'src')
8 files changed, 305 insertions, 38 deletions
diff --git a/src/Java/gtPlusPlus/core/handler/events/BlockEventHandler.java b/src/Java/gtPlusPlus/core/handler/events/BlockEventHandler.java index 6da2dac38b..03bb99bb2a 100644 --- a/src/Java/gtPlusPlus/core/handler/events/BlockEventHandler.java +++ b/src/Java/gtPlusPlus/core/handler/events/BlockEventHandler.java @@ -1,18 +1,11 @@ package gtPlusPlus.core.handler.events; -import static gtPlusPlus.core.lib.CORE.ConfigSwitches.*; +import static gtPlusPlus.core.lib.CORE.ConfigSwitches.chanceToDropDrainedShard; +import static gtPlusPlus.core.lib.CORE.ConfigSwitches.chanceToDropFluoriteOre; import java.util.ArrayList; -import java.util.Map; -import java.util.WeakHashMap; import cpw.mods.fml.common.eventhandler.SubscribeEvent; - -import net.minecraft.block.Block; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; -import net.minecraft.item.ItemStack; -import net.minecraft.util.ChunkCoordinates; import gtPlusPlus.api.objects.Logger; import gtPlusPlus.core.item.ModItems; import gtPlusPlus.core.lib.LoadedMods; @@ -20,12 +13,14 @@ import gtPlusPlus.core.material.nuclear.FLUORIDES; import gtPlusPlus.core.util.math.MathUtils; import gtPlusPlus.core.util.minecraft.ItemUtils; import gtPlusPlus.core.util.minecraft.PlayerUtils; -import net.minecraftforge.common.util.FakePlayer; +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; import net.minecraftforge.event.entity.living.LivingDropsEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.world.BlockEvent; import net.minecraftforge.oredict.OreDictionary; -import thaumcraft.common.lib.FakeThaumcraftPlayer; public class BlockEventHandler { public static ArrayList<ItemStack> oreLimestone; diff --git a/src/Java/gtPlusPlus/core/handler/events/EntityDeathHandler.java b/src/Java/gtPlusPlus/core/handler/events/EntityDeathHandler.java index 3492ee4788..391672e028 100644 --- a/src/Java/gtPlusPlus/core/handler/events/EntityDeathHandler.java +++ b/src/Java/gtPlusPlus/core/handler/events/EntityDeathHandler.java @@ -11,14 +11,10 @@ import gtPlusPlus.core.item.ModItems; import gtPlusPlus.core.util.math.MathUtils; import gtPlusPlus.core.util.minecraft.ItemUtils; import gtPlusPlus.core.util.minecraft.PlayerUtils; -import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; -import net.minecraft.util.ChunkCoordinates; -import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.event.entity.living.LivingDropsEvent; -import thaumcraft.common.lib.FakeThaumcraftPlayer; public class EntityDeathHandler { diff --git a/src/Java/gtPlusPlus/core/util/minecraft/PlayerUtils.java b/src/Java/gtPlusPlus/core/util/minecraft/PlayerUtils.java index 110b2baf25..24ffa295b7 100644 --- a/src/Java/gtPlusPlus/core/util/minecraft/PlayerUtils.java +++ b/src/Java/gtPlusPlus/core/util/minecraft/PlayerUtils.java @@ -4,8 +4,8 @@ import java.util.*; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; -import gtPlusPlus.core.handler.events.BlockEventHandler; import gtPlusPlus.core.util.Utils; +import gtPlusPlus.core.util.reflect.ReflectionUtils; import net.minecraft.client.Minecraft; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; @@ -16,11 +16,20 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.util.ChunkCoordinates; import net.minecraft.world.World; import net.minecraftforge.common.util.FakePlayer; -import thaumcraft.common.lib.FakeThaumcraftPlayer; public class PlayerUtils { public static final Map<String, EntityPlayer> mCachedFakePlayers = new WeakHashMap<String, EntityPlayer>(); + private static final Class mThaumcraftFakePlayer; + + static { + if (ReflectionUtils.doesClassExist("thaumcraft.common.lib.FakeThaumcraftPlayer")) { + mThaumcraftFakePlayer = ReflectionUtils.getClass("thaumcraft.common.lib.FakeThaumcraftPlayer"); + } + else { + mThaumcraftFakePlayer = null; + } + } public static void messagePlayer(final EntityPlayer P, final String S){ gregtech.api.util.GT_Utility.sendChatToPlayer(P, S); @@ -203,7 +212,7 @@ public class PlayerUtils { public static void cacheFakePlayer(EntityPlayer aPlayer) { ChunkCoordinates aChunkLocation = aPlayer.getPlayerCoordinates(); // Cache Fake Player - if (aPlayer instanceof FakePlayer || aPlayer instanceof FakeThaumcraftPlayer + if (aPlayer instanceof FakePlayer || (mThaumcraftFakePlayer != null && mThaumcraftFakePlayer.isInstance(aPlayer)) || (aPlayer.getCommandSenderName() == null || aPlayer.getCommandSenderName().length() <= 0) || (aPlayer.isEntityInvulnerable() && !aPlayer.canCommandSenderUseCommand(0, "") @@ -225,7 +234,7 @@ public class PlayerUtils { cacheFakePlayer(p); return false; } - if (p instanceof FakeThaumcraftPlayer) { + if (mThaumcraftFakePlayer != null && mThaumcraftFakePlayer.isInstance(p) ) { cacheFakePlayer(p); return false; } diff --git a/src/Java/gtPlusPlus/preloader/asm/ClassesToTransform.java b/src/Java/gtPlusPlus/preloader/asm/ClassesToTransform.java index 3366f4aefe..a29cebfda1 100644 --- a/src/Java/gtPlusPlus/preloader/asm/ClassesToTransform.java +++ b/src/Java/gtPlusPlus/preloader/asm/ClassesToTransform.java @@ -52,6 +52,7 @@ public class ClassesToTransform { public static final String THAUMCRAFT_ITEM_WISP_ESSENCE = "thaumcraft.common.items.ItemWispEssence"; + public static final String THAUMCRAFT_CRAFTING_MANAGER = "thaumcraft.common.lib.crafting.ThaumcraftCraftingManager"; public static final String THAUMICTINKERER_TILE_REPAIRER = "thaumic.tinkerer.common.block.tile.TileRepairer"; public static final String IC2_ITEM_ARMOUR_HAZMAT = "ic2.core.item.armor.ItemArmorHazmat"; diff --git a/src/Java/gtPlusPlus/preloader/asm/helpers/MethodHelper_TC.java b/src/Java/gtPlusPlus/preloader/asm/helpers/MethodHelper_TC.java new file mode 100644 index 0000000000..e7355c7d90 --- /dev/null +++ b/src/Java/gtPlusPlus/preloader/asm/helpers/MethodHelper_TC.java @@ -0,0 +1,121 @@ +package gtPlusPlus.preloader.asm.helpers; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import gtPlusPlus.core.util.reflect.ReflectionUtils; +import gtPlusPlus.preloader.Preloader_Logger; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import thaumcraft.api.ThaumcraftApi; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.common.lib.crafting.ThaumcraftCraftingManager; + +public class MethodHelper_TC { + + private static Class mThaumcraftCraftingManager; + + public static AspectList generateTags(final Item item, final int meta, final ArrayList<List> history) { + int tmeta = meta; + if (item == null) { + return null; + } + Preloader_Logger.INFO("Generating aspect tags for "+item.getUnlocalizedName()+":"+meta); + try { + tmeta = ((new ItemStack(item, 1, meta).getItem().isDamageable() || !new ItemStack(item, 1, meta).getItem().getHasSubtypes()) ? 32767 : meta); + } + catch (Exception ex) {} + Preloader_Logger.INFO("Set Meta to "+tmeta); + if (ThaumcraftApi.exists(item, tmeta)) { + return ThaumcraftCraftingManager.getObjectTags(new ItemStack(item, 1, tmeta)); + } + if (history.contains(Arrays.asList(item, tmeta))) { + return null; + } + history.add(Arrays.asList(item, tmeta)); + if (history.size() < 100) { + AspectList ret = generateTagsFromRecipes(item, (tmeta == 32767) ? 0 : meta, history); + ret = capAspects(ret, 64); + ThaumcraftApi.registerObjectTag(new ItemStack(item, 1, tmeta), ret); + return ret; + } + return null; + } + + private static AspectList capAspects(final AspectList sourcetags, final int amount) { + if (sourcetags == null) { + return sourcetags; + } + final AspectList out = new AspectList(); + for (final Aspect aspect : sourcetags.getAspects()) { + out.merge(aspect, Math.min(amount, sourcetags.getAmount(aspect))); + } + return out; + } + + private static AspectList generateTagsFromRecipes(final Item item, final int meta, final ArrayList<List> history) { + AspectList ret = null; + ret = generateTagsFromCrucibleRecipes(item, meta, history); + if (ret != null) { + return ret; + } + ret = generateTagsFromArcaneRecipes(item, meta, history); + if (ret != null) { + return ret; + } + ret = generateTagsFromInfusionRecipes(item, meta, history); + if (ret != null) { + return ret; + } + ret = generateTagsFromCraftingRecipes(item, meta, history); + return ret; + } + + private static boolean isClassSet() { + if (mThaumcraftCraftingManager == null) { + mThaumcraftCraftingManager = ReflectionUtils.getClass("thaumcraft.common.lib.crafting.ThaumcraftCraftingManager"); + } + return true; + } + + private static Method mGetTagsFromCraftingRecipes; + private static Method mGetTagsFromInfusionRecipes; + private static Method mGetTagsFromArcaneRecipes; + private static Method mGetTagsFromCrucibleRecipes; + + private static AspectList generateTagsFromCraftingRecipes(Item item, int meta, ArrayList<List> history) { + isClassSet(); + if (mGetTagsFromCraftingRecipes == null) { + mGetTagsFromCraftingRecipes = ReflectionUtils.getMethod(mThaumcraftCraftingManager, "generateTagsFromCraftingRecipes", new Class[] {Item.class, int.class, ArrayList.class}); + } + return (AspectList) ReflectionUtils.invokeNonBool(null, mGetTagsFromCraftingRecipes, new Object[] {item, meta, history}); + } + + private static AspectList generateTagsFromInfusionRecipes(Item item, int meta, ArrayList<List> history) { + isClassSet(); + if (mGetTagsFromInfusionRecipes == null) { + mGetTagsFromInfusionRecipes = ReflectionUtils.getMethod(mThaumcraftCraftingManager, "generateTagsFromInfusionRecipes", new Class[] {Item.class, int.class, ArrayList.class}); + } + return (AspectList) ReflectionUtils.invokeNonBool(null, mGetTagsFromInfusionRecipes, new Object[] {item, meta, history}); + } + + private static AspectList generateTagsFromArcaneRecipes(Item item, int meta, ArrayList<List> history) { + isClassSet(); + if (mGetTagsFromArcaneRecipes == null) { + mGetTagsFromArcaneRecipes = ReflectionUtils.getMethod(mThaumcraftCraftingManager, "generateTagsFromArcaneRecipes", new Class[] {Item.class, int.class, ArrayList.class}); + } + return (AspectList) ReflectionUtils.invokeNonBool(null, mGetTagsFromArcaneRecipes, new Object[] {item, meta, history}); + } + + private static AspectList generateTagsFromCrucibleRecipes(Item item, int meta, ArrayList<List> history) { + isClassSet(); + if (mGetTagsFromCrucibleRecipes == null) { + mGetTagsFromCrucibleRecipes = ReflectionUtils.getMethod(mThaumcraftCraftingManager, "generateTagsFromCrucibleRecipes", new Class[] {Item.class, int.class, ArrayList.class}); + } + return (AspectList) ReflectionUtils.invokeNonBool(null, mGetTagsFromCrucibleRecipes, new Object[] {item, meta, history}); + } + +} diff --git a/src/Java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_TC_ThaumcraftCraftingManager.java b/src/Java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_TC_ThaumcraftCraftingManager.java new file mode 100644 index 0000000000..d502af0fc8 --- /dev/null +++ b/src/Java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_TC_ThaumcraftCraftingManager.java @@ -0,0 +1,131 @@ +package gtPlusPlus.preloader.asm.transformers; + +import static org.objectweb.asm.Opcodes.*; + +import org.apache.logging.log4j.Level; +import org.objectweb.asm.*; + +import gtPlusPlus.preloader.Preloader_Logger; + +public class ClassTransformer_TC_ThaumcraftCraftingManager { + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + + public ClassTransformer_TC_ThaumcraftCraftingManager(byte[] basicClass) { + + ClassReader aTempReader = null; + ClassWriter aTempWriter = null; + + aTempReader = new ClassReader(basicClass); + aTempWriter = new ClassWriter(aTempReader, ClassWriter.COMPUTE_FRAMES); + localClassVisitor aTempMethodRemover = new localClassVisitor(aTempWriter); + aTempReader.accept(aTempMethodRemover, 0); + boolean wasMethodObfuscated = aTempMethodRemover.getObfuscatedRemoval(); + + if (aTempReader != null && aTempWriter != null) { + isValid = true; + } else { + isValid = false; + } + + Preloader_Logger.LOG("TC CraftingManager Patch", Level.INFO, "Valid patch? " + isValid + "."); + reader = aTempReader; + writer = aTempWriter; + + if (reader != null && writer != null) { + Preloader_Logger.LOG("TC CraftingManager Patch", Level.INFO, "Attempting Method Injection."); + injectMethod("generateTags", wasMethodObfuscated); + } + + } + + public boolean isValidTransformer() { + return isValid; + } + + public ClassReader getReader() { + return reader; + } + + public ClassWriter getWriter() { + return writer; + } + + public boolean injectMethod(String aMethodName, boolean wasMethodObfuscated) { + MethodVisitor mv; + boolean didInject = false; + ClassWriter cw = getWriter(); + String aitemClassName = wasMethodObfuscated ? "adb" : "net/minecraft/item/Item"; + String aClassName = "thaumcraft.common.lib.crafting.ThaumcraftCraftingManager"; + if (aMethodName.equals("generateTags")) { + Preloader_Logger.LOG("TC CraftingManager Patch", Level.INFO, "Injecting " + aMethodName + ", static replacement call to "+aClassName+"."); + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "generateTags", "(L"+aitemClassName+";ILjava/util/ArrayList;)Lthaumcraft/api/aspects/AspectList;", "(L"+aitemClassName+";ILjava/util/ArrayList<Ljava/util/List;>;)Lthaumcraft/api/aspects/AspectList;", null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(23, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ILOAD, 1); + mv.visitVarInsn(ALOAD, 2); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/preloader/asm/helpers/MethodHelper_TC", "generateTags", "(L"+aitemClassName+";ILjava/util/ArrayList;)Lthaumcraft/api/aspects/AspectList;", false); + mv.visitInsn(ARETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("item", "L"+aitemClassName+";", null, l0, l1, 0); + mv.visitLocalVariable("meta", "I", null, l0, l1, 1); + mv.visitLocalVariable("history", "Ljava/util/ArrayList;", "Ljava/util/ArrayList<Ljava/util/List;>;", l0, l1, 2); + mv.visitMaxs(3, 3); + mv.visitEnd(); + didInject = true; + } + + Preloader_Logger.LOG("TC CraftingManager Patch", Level.INFO, "Method injection complete."); + return didInject; + } + + public final class localClassVisitor extends ClassVisitor { + + boolean obfuscated = false; + + public localClassVisitor(ClassVisitor cv) { + super(ASM5, cv); + } + + public boolean getObfuscatedRemoval() { + return obfuscated; + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + MethodVisitor methodVisitor; + String aDeObfName = "net/minecraft/item/Item"; + String aObfName = "adb"; + String aDesc1 = "(L+aDeObfName+;ILjava/util/ArrayList;)Lthaumcraft/api/aspects/AspectList;"; + String aDesc2 = "(L"+aObfName+";ILjava/util/ArrayList;)Lthaumcraft/api/aspects/AspectList;"; + + if (name.equals("generateTags") && (desc.equals(aDesc1) || desc.equals(aDesc2))) { + Preloader_Logger.INFO("Found method descriptor: "+desc); + if (desc.equals(aDesc1)) { + obfuscated = false; + methodVisitor = null; + } + else { + obfuscated = true; + methodVisitor = null; + } + } + else { + methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + } + + if (methodVisitor == null) { + Preloader_Logger.LOG("TC CraftingManager Patch", Level.INFO, "Found method " + name + ", removing."); + Preloader_Logger.LOG("TC CraftingManager Patch", Level.INFO, "Descriptor: "+desc); + } + return methodVisitor; + } + } + +} diff --git a/src/Java/gtPlusPlus/preloader/asm/transformers/Preloader_Transformer_Handler.java b/src/Java/gtPlusPlus/preloader/asm/transformers/Preloader_Transformer_Handler.java index cb9799fce7..d9496e2c0c 100644 --- a/src/Java/gtPlusPlus/preloader/asm/transformers/Preloader_Transformer_Handler.java +++ b/src/Java/gtPlusPlus/preloader/asm/transformers/Preloader_Transformer_Handler.java @@ -271,6 +271,10 @@ public class Preloader_Transformer_Handler implements IClassTransformer { Preloader_Logger.INFO("Thaumcraft WispEssence_Patch", "Transforming "+transformedName); return new ClassTransformer_TC_ItemWispEssence(basicClass, obfuscated).getWriter().toByteArray(); } + if (transformedName.equals(THAUMCRAFT_CRAFTING_MANAGER)) { + Preloader_Logger.INFO("Thaumcraft CraftingManager Patch", "Transforming "+transformedName); + return new ClassTransformer_TC_ThaumcraftCraftingManager(basicClass).getWriter().toByteArray(); + } //Fix Thaumic Tinkerer Shit if (transformedName.equals(THAUMICTINKERER_TILE_REPAIRER) && AsmConfig.enableThaumicTinkererRepairFix) { //Preloader_Logger.INFO("Thaumic Tinkerer RepairItem Patch", "Transforming "+transformedName); diff --git a/src/Java/gtPlusPlus/xmod/gregtech/common/helpers/VolumetricFlaskHelper.java b/src/Java/gtPlusPlus/xmod/gregtech/common/helpers/VolumetricFlaskHelper.java index e85a78b8aa..84bb52d064 100644 --- a/src/Java/gtPlusPlus/xmod/gregtech/common/helpers/VolumetricFlaskHelper.java +++ b/src/Java/gtPlusPlus/xmod/gregtech/common/helpers/VolumetricFlaskHelper.java @@ -3,6 +3,8 @@ package gtPlusPlus.xmod.gregtech.common.helpers; import java.lang.reflect.Constructor; import java.lang.reflect.Method; +import gtPlusPlus.api.objects.Logger; +import gtPlusPlus.core.lib.CORE; import gtPlusPlus.core.util.minecraft.ItemUtils; import gtPlusPlus.core.util.reflect.ReflectionUtils; import gtPlusPlus.xmod.gregtech.api.enums.GregtechItemList; @@ -21,7 +23,15 @@ public class VolumetricFlaskHelper { static { if (Meta_GT_Proxy.sDoesVolumetricFlaskExist) { sClassVolumetricFlask = ReflectionUtils.getClass("gregtech.common.items.GT_VolumetricFlask"); - sMethodGetFlaskMaxCapacity = ReflectionUtils.getMethod(sClassVolumetricFlask, "getMaxCapacity", new Class[] {}); + Method aMaxCapacity = null; + try { + aMaxCapacity = sClassVolumetricFlask.getDeclaredMethod("getMaxCapacity", new Class[] {}); + } + catch (NoSuchMethodException e) { + e.printStackTrace(); + CORE.crash("Secondary Error Obtaining instance of 'getMaxCapacity' from 'GT_VolumetricFlask'. Crashing."); + } + sMethodGetFlaskMaxCapacity = aMaxCapacity; } else { sClassVolumetricFlask = null; @@ -101,24 +111,24 @@ public class VolumetricFlaskHelper { } return null; } - - public static void setFluid(ItemStack stack, FluidStack fluidStack) { - boolean removeFluid = (fluidStack == null) || (fluidStack.amount <= 0); - NBTTagCompound nbt = stack.getTagCompound(); - if (nbt == null) { - if (removeFluid) - return; - stack.setTagCompound(nbt = new NBTTagCompound()); - } - if (removeFluid) { - nbt.removeTag("Fluid"); - if (nbt.hasNoTags()) { - stack.setTagCompound(null); - } - } else { - nbt.setTag("Fluid", fluidStack.writeToNBT(new NBTTagCompound())); - } - } + + public static void setFluid(ItemStack stack, FluidStack fluidStack) { + boolean removeFluid = (fluidStack == null) || (fluidStack.amount <= 0); + NBTTagCompound nbt = stack.getTagCompound(); + if (nbt == null) { + if (removeFluid) + return; + stack.setTagCompound(nbt = new NBTTagCompound()); + } + if (removeFluid) { + nbt.removeTag("Fluid"); + if (nbt.hasNoTags()) { + stack.setTagCompound(null); + } + } else { + nbt.setTag("Fluid", fluidStack.writeToNBT(new NBTTagCompound())); + } + } public static int getFlaskCapacity(ItemStack aStack) { int capacity = 1000; |