Don't delete constructors because it might containe stuff we actually want. Instead rename to init and invoke from constructors. Magic.
This commit is contained in:
@@ -25,6 +25,8 @@ public class Method
|
|||||||
public static final short ACC_SYNCHRONIZED = 0x20;
|
public static final short ACC_SYNCHRONIZED = 0x20;
|
||||||
public static final short ACC_ABSTRACT = 0x400;
|
public static final short ACC_ABSTRACT = 0x400;
|
||||||
|
|
||||||
|
public static final short ACCESS_MODIFIERS = ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED;
|
||||||
|
|
||||||
private Methods methods;
|
private Methods methods;
|
||||||
|
|
||||||
private short accessFlags;
|
private short accessFlags;
|
||||||
@@ -146,6 +148,11 @@ public class Method
|
|||||||
return (accessFlags & ACC_PRIVATE) != 0;
|
return (accessFlags & ACC_PRIVATE) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPrivate()
|
||||||
|
{
|
||||||
|
accessFlags = (short) ((accessFlags & ~ACCESS_MODIFIERS) | ACC_PRIVATE);
|
||||||
|
}
|
||||||
|
|
||||||
public Exceptions getExceptions()
|
public Exceptions getExceptions()
|
||||||
{
|
{
|
||||||
return (Exceptions) attributes.findType(AttributeType.EXCEPTIONS);
|
return (Exceptions) attributes.findType(AttributeType.EXCEPTIONS);
|
||||||
|
|||||||
@@ -19,8 +19,10 @@ import net.runelite.deob.attributes.code.instructions.DLoad;
|
|||||||
import net.runelite.deob.attributes.code.instructions.FLoad;
|
import net.runelite.deob.attributes.code.instructions.FLoad;
|
||||||
import net.runelite.deob.attributes.code.instructions.ILoad;
|
import net.runelite.deob.attributes.code.instructions.ILoad;
|
||||||
import net.runelite.deob.attributes.code.instructions.InvokeSpecial;
|
import net.runelite.deob.attributes.code.instructions.InvokeSpecial;
|
||||||
|
import net.runelite.deob.attributes.code.instructions.InvokeVirtual;
|
||||||
import net.runelite.deob.attributes.code.instructions.LLoad;
|
import net.runelite.deob.attributes.code.instructions.LLoad;
|
||||||
import net.runelite.deob.attributes.code.instructions.New;
|
import net.runelite.deob.attributes.code.instructions.New;
|
||||||
|
import net.runelite.deob.attributes.code.instructions.Pop;
|
||||||
import net.runelite.deob.attributes.code.instructions.Return;
|
import net.runelite.deob.attributes.code.instructions.Return;
|
||||||
import net.runelite.deob.signature.Type;
|
import net.runelite.deob.signature.Type;
|
||||||
|
|
||||||
@@ -86,15 +88,46 @@ public class InjectReplace
|
|||||||
replaceNew(classToInject);
|
replaceNew(classToInject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final String INITFN = "init";
|
||||||
|
|
||||||
private void injectConstructors(ClassFile classToInject)
|
private void injectConstructors(ClassFile classToInject)
|
||||||
{
|
{
|
||||||
// Delete compiler generate constructors
|
// Delete compiler generate constructors
|
||||||
Methods methods = classToInject.getMethods();
|
Methods methods = classToInject.getMethods();
|
||||||
Methods vanillaMethods = vanilla.getMethods();
|
Methods vanillaMethods = vanilla.getMethods();
|
||||||
|
|
||||||
for (Method m : new ArrayList<>(methods.getMethods()))
|
boolean seen = false;
|
||||||
|
for (Method m : methods.getMethods())
|
||||||
if (m.getName().equals("<init>"))
|
if (m.getName().equals("<init>"))
|
||||||
methods.removeMethod(m);
|
{
|
||||||
|
assert seen == false; // only one ctor allowed
|
||||||
|
seen = true;
|
||||||
|
|
||||||
|
Code code = m.getCode();
|
||||||
|
Instructions instructions = code.getInstructions();
|
||||||
|
|
||||||
|
m.setName(INITFN); // magic
|
||||||
|
|
||||||
|
// replace invokespecial call
|
||||||
|
|
||||||
|
for (Instruction i : instructions.getInstructions())
|
||||||
|
{
|
||||||
|
if (!(i instanceof InvokeSpecial))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
InvokeSpecial is = (InvokeSpecial) i;
|
||||||
|
net.runelite.deob.pool.Method method = (net.runelite.deob.pool.Method) is.getMethod();
|
||||||
|
assert method.getNameAndType().getDescriptor().size() == 0; // Replace classes must extend Object so this must be Object.init()
|
||||||
|
|
||||||
|
instructions.replace(i, new Pop(instructions)); // pop this
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m.setPrivate();
|
||||||
|
|
||||||
|
// now we'll just add a call to init in the constructors
|
||||||
|
}
|
||||||
|
|
||||||
// Add constructors
|
// Add constructors
|
||||||
for (Method m : vanillaMethods.getMethods())
|
for (Method m : vanillaMethods.getMethods())
|
||||||
@@ -154,6 +187,15 @@ public class InjectReplace
|
|||||||
}
|
}
|
||||||
|
|
||||||
ins.add(new InvokeSpecial(instructions, m.getPoolMethod()));
|
ins.add(new InvokeSpecial(instructions, m.getPoolMethod()));
|
||||||
|
|
||||||
|
// invoke our init func if it exists
|
||||||
|
Method initfn = methods.findMethod(INITFN);
|
||||||
|
if (initfn != null)
|
||||||
|
{
|
||||||
|
ins.add(new ALoad(instructions, 0)); // this
|
||||||
|
ins.add(new InvokeVirtual(instructions, initfn.getPoolMethod()));
|
||||||
|
}
|
||||||
|
|
||||||
ins.add(new Return(instructions, InstructionType.RETURN));
|
ins.add(new Return(instructions, InstructionType.RETURN));
|
||||||
|
|
||||||
methods.addMethod(constructor);
|
methods.addMethod(constructor);
|
||||||
@@ -293,6 +335,7 @@ public class InjectReplace
|
|||||||
if (i instanceof New)
|
if (i instanceof New)
|
||||||
{
|
{
|
||||||
New n = (New) i;
|
New n = (New) i;
|
||||||
|
|
||||||
if (!n.getNewClass().equals(vanilla.getPoolClass()))
|
if (!n.getNewClass().equals(vanilla.getPoolClass()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user