ForgePatch/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemStackTransformer.java

86 lines
3.1 KiB
Java
Raw Normal View History

2014-09-23 05:01:24 +00:00
package net.minecraftforge.fml.common.asm.transformers;
import java.util.ListIterator;
import net.minecraft.launchwrapper.IClassTransformer;
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.FieldInsnNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
public class ItemStackTransformer implements IClassTransformer {
private static final String ITEM_TYPE = "Lnet/minecraft/item/Item;";
private static final String GETITEM_DESC = "()"+ ITEM_TYPE;
@Override
public byte[] transform(String name, String transformedName, byte[] basicClass) {
if (!"net.minecraft.item.ItemStack".equals(name))
return basicClass;
ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader(basicClass);
classReader.accept(classNode, 0);
FieldNode itemField = null;
for (FieldNode f : classNode.fields)
{
if (ITEM_TYPE.equals(f.desc) && itemField == null)
{
itemField = f;
}
else if (ITEM_TYPE.equals(f.desc))
{
throw new RuntimeException("Error processing ItemStack - found a duplicate Item field");
}
}
if (itemField == null)
{
throw new RuntimeException("Error processing ItemStack - no Item field declared (is the code somehow obfuscated?)");
}
MethodNode getItemMethod = null;
for (MethodNode m: classNode.methods)
{
if (GETITEM_DESC.equals(m.desc) && getItemMethod == null)
{
getItemMethod = m;
}
else if (GETITEM_DESC.equals(m.desc))
{
throw new RuntimeException("Error processing ItemStack - duplicate getItem method found");
}
}
if (getItemMethod == null)
{
throw new RuntimeException("Error processing ItemStack - no getItem method found (is the code somehow obfuscated?)");
}
for (MethodNode m: classNode.methods)
{
for (ListIterator<AbstractInsnNode> it = m.instructions.iterator(); it.hasNext(); )
{
AbstractInsnNode insnNode = it.next();
if (insnNode.getType() == AbstractInsnNode.FIELD_INSN)
{
FieldInsnNode fi = (FieldInsnNode)insnNode;
if (itemField.name.equals(fi.name) && fi.getOpcode() == Opcodes.GETFIELD)
{
it.remove();
MethodInsnNode replace = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "net/minecraft/item/ItemStack",getItemMethod.name, getItemMethod.desc, false);
it.add(replace);
}
}
}
}
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
classNode.accept(writer);
return writer.toByteArray();
}
}