diff --git a/src/main/java/org/ultramine/server/UMHooks.java b/src/main/java/org/ultramine/server/UMHooks.java new file mode 100644 index 0000000..0c63943 --- /dev/null +++ b/src/main/java/org/ultramine/server/UMHooks.java @@ -0,0 +1,67 @@ +package org.ultramine.server; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.tileentity.TileEntity; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.ultramine.server.event.WorldEventProxy; +import org.ultramine.server.event.WorldUpdateObject; + +public class UMHooks +{ + private static final Logger log = LogManager.getLogger(); + + public static void printStackTrace(Throwable t) + { + log.warn("Direct Throwable.printStackTrace() call"); + WorldEventProxy wep = WorldEventProxy.getCurrent(); + if(wep != null) + { + int dim = wep.getWorld().provider.dimensionId; + WorldUpdateObject obj = wep.getUpdateObject(); + switch(obj.getType()) + { + case BLOCK_EVENT: + log.warn("On block event update [{}]({}, {}, {})", dim, obj.getX(), obj.getY(), obj.getZ()); + break; + case BLOCK_PENDING: + log.warn("On block pending update [{}]({}, {}, {})", dim, obj.getX(), obj.getY(), obj.getZ()); + break; + case BLOCK_RANDOM: + log.warn("On block random update [{}]({}, {}, {})", dim, obj.getX(), obj.getY(), obj.getZ()); + break; + case ENTITY: + Entity ent = obj.getEntity(); + log.warn("On entity update [{}]({}, {}, {}). Entity: {}, Class: {}", dim, ent.posX, ent.posY, ent.posZ, ent, ent.getClass().getName()); + break; + case ENTITY_WEATHER: + Entity went = obj.getEntity(); + log.warn("On weather entity update [{}]({}, {}, {}). Entity: {}, Class: {}", dim, went.posX, went.posY, went.posZ, went, went.getClass().getName()); + break; + case PLAYER: + EntityPlayer player = (EntityPlayer)obj.getEntity(); + log.warn("On player packet [{}]({}, {}, {}). Entity: {}", dim, player.posX, player.posY, player.posZ, player); + break; + case TILEE_ENTITY: + TileEntity te = obj.getTileEntity(); + log.warn("On entity update [{}]({}, {}, {}). Class: {}", dim, te.xCoord, te.yCoord, te.zCoord, te.getClass().getName()); + break; + case WEATHER: + log.warn("On weather action at world [{}]", dim); + break; + case UNKNOWN: + log.warn("On unknown action at world [{}]", dim); + break; + } + } + else + { + log.warn("On unknown action"); + } + + log.warn("Invoked here", new Throwable("stacktrace")); + log.warn("Original stacktrace", t); + } +} diff --git a/src/main/java/org/ultramine/server/UltraminePlugin.java b/src/main/java/org/ultramine/server/UltraminePlugin.java index 3a4451e..c550c25 100644 --- a/src/main/java/org/ultramine/server/UltraminePlugin.java +++ b/src/main/java/org/ultramine/server/UltraminePlugin.java @@ -15,7 +15,8 @@ public String[] getASMTransformerClass() { return new String[]{ - "org.ultramine.server.asm.transformers.TrigMathTransformer" + "org.ultramine.server.asm.transformers.TrigMathTransformer", + "org.ultramine.server.asm.transformers.PrintStackTraceTransformer", }; } diff --git a/src/main/java/org/ultramine/server/asm/transformers/PrintStackTraceTransformer.java b/src/main/java/org/ultramine/server/asm/transformers/PrintStackTraceTransformer.java new file mode 100644 index 0000000..49bf8b6 --- /dev/null +++ b/src/main/java/org/ultramine/server/asm/transformers/PrintStackTraceTransformer.java @@ -0,0 +1,68 @@ +package org.ultramine.server.asm.transformers; + +import java.util.HashSet; +import java.util.ListIterator; +import java.util.Set; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.AbstractInsnNode; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.MethodInsnNode; +import org.objectweb.asm.tree.MethodNode; + +import net.minecraft.launchwrapper.IClassTransformer; + +public class PrintStackTraceTransformer implements IClassTransformer +{ + private static final Logger log = LogManager.getLogger(); + + private static final String UMHOOKS_TYPE = "org/ultramine/server/UMHooks"; + private static final Set THROWABLE_TYPES = new HashSet(); + private static final String PST_NAME = "printStackTrace"; + private static final String PST_DESC = "()V"; + private static final String UM_PST_DESC = "(Ljava/lang/Throwable;)V"; + + static + { + THROWABLE_TYPES.add("java/lang/Throwable"); + THROWABLE_TYPES.add("java/lang/Exception"); + THROWABLE_TYPES.add("java/lang/RuntimeException"); + THROWABLE_TYPES.add("java/io/IOException"); + } + + @Override + public byte[] transform(String name, String transformedName, byte[] basicClass) + { + if(basicClass == null) + return null; + ClassNode classNode = new ClassNode(); + ClassReader classReader = new ClassReader(basicClass); + classReader.accept(classNode, 0); + + for(MethodNode m: classNode.methods) + { + for(ListIterator it = m.instructions.iterator(); it.hasNext(); ) + { + AbstractInsnNode insnNode = it.next(); + if(insnNode.getType() == AbstractInsnNode.METHOD_INSN) + { + MethodInsnNode fi = (MethodInsnNode)insnNode; + if(THROWABLE_TYPES.contains(fi.owner) && PST_NAME.equals(fi.name) && PST_DESC.equals(fi.desc) && fi.getOpcode() == Opcodes.INVOKEVIRTUAL) + { + log.trace("Method {}.{}{}: Replacing INVOKEVIRTUAL {}.printStackTrace with INVOKESTATIC UMHooks.printStackTrace", name, m.name, m.desc, fi.owner); + it.remove(); + MethodInsnNode replace = new MethodInsnNode(Opcodes.INVOKESTATIC, UMHOOKS_TYPE, PST_NAME, UM_PST_DESC, false); + it.add(replace); + } + } + } + } + ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); + classNode.accept(writer); + return writer.toByteArray(); + } +} diff --git a/src/main/java/org/ultramine/server/asm/transformers/TrigMathTransformer.java b/src/main/java/org/ultramine/server/asm/transformers/TrigMathTransformer.java index 704fa4f..d2a91d1 100644 --- a/src/main/java/org/ultramine/server/asm/transformers/TrigMathTransformer.java +++ b/src/main/java/org/ultramine/server/asm/transformers/TrigMathTransformer.java @@ -19,12 +19,12 @@ { private static final Logger log = LogManager.getLogger(); - private static String TRIGMATH_TYPE = "org/ultramine/server/util/TrigMath"; - private static String MATH_TYPE = "java/lang/Math"; - private static String ATAN2_NAME = "atan2"; - private static String ATAN2_DESC = "(DD)D"; - private static String ATAN_NAME = "atan"; - private static String ATAN_DESC = "(D)D"; + private static final String TRIGMATH_TYPE = "org/ultramine/server/util/TrigMath"; + private static final String MATH_TYPE = "java/lang/Math"; + private static final String ATAN2_NAME = "atan2"; + private static final String ATAN2_DESC = "(DD)D"; + private static final String ATAN_NAME = "atan"; + private static final String ATAN_DESC = "(D)D"; @Override public byte[] transform(String name, String transformedName, byte[] basicClass)