Fix mixins with multiple targets, turn injectutil into a interface
This commit is contained in:
@@ -31,7 +31,7 @@ import net.runelite.asm.pool.Class;
|
||||
import net.runelite.asm.signature.Signature;
|
||||
import net.runelite.deob.DeobAnnotations;
|
||||
|
||||
public class InjectUtil
|
||||
public interface InjectUtil
|
||||
{
|
||||
/**
|
||||
* Finds a static method in deob and converts it to ob
|
||||
@@ -40,7 +40,7 @@ public class InjectUtil
|
||||
* @param name The name of the method you want to find
|
||||
* @return The obfuscated version of the found method
|
||||
*/
|
||||
public static Method findStaticMethod(InjectData data, String name) throws Injexception
|
||||
static Method findStaticMethod(InjectData data, String name) throws Injexception
|
||||
{
|
||||
return findStaticMethod(data, name, null, null);
|
||||
}
|
||||
@@ -55,10 +55,10 @@ public class InjectUtil
|
||||
*
|
||||
* @return The obfuscated version of the found method
|
||||
*/
|
||||
public static Method findStaticMethod(InjectData data, String name, String classHint, Signature sig) throws Injexception
|
||||
static Method findStaticMethod(InjectData data, String name, String classHint, Signature sig) throws Injexception
|
||||
{
|
||||
final ClassGroup deob = data.getDeobfuscated();
|
||||
Method method = null;
|
||||
Method method;
|
||||
|
||||
if (classHint != null)
|
||||
{
|
||||
@@ -95,7 +95,7 @@ public class InjectUtil
|
||||
throw new Injexception("Static method " + name + " doesn't exist");
|
||||
}
|
||||
|
||||
private static ClassFile findClassOrThrow(ClassGroup group, String name) throws Injexception
|
||||
static ClassFile findClassOrThrow(ClassGroup group, String name) throws Injexception
|
||||
{
|
||||
ClassFile clazz = group.findClass(name);
|
||||
if (clazz == null)
|
||||
@@ -112,12 +112,12 @@ public class InjectUtil
|
||||
*
|
||||
* @return The obfuscated version of the found method
|
||||
*/
|
||||
public static Method findStaticMethod(InjectData data, net.runelite.asm.pool.Method pool) throws Injexception
|
||||
static Method findStaticMethod(InjectData data, net.runelite.asm.pool.Method pool) throws Injexception
|
||||
{
|
||||
return findStaticMethod(data, pool.getName(), pool.getClazz().getName(), pool.getType());
|
||||
}
|
||||
|
||||
public static Method findMethodWithArgs(InjectData data, String name, String hintClass, Signature sig) throws Injexception
|
||||
static Method findMethodWithArgs(InjectData data, String name, String hintClass, Signature sig) throws Injexception
|
||||
{
|
||||
final ClassGroup deob = data.getDeobfuscated();
|
||||
if (hintClass != null)
|
||||
@@ -137,7 +137,7 @@ public class InjectUtil
|
||||
throw new Injexception("Method called " + name + " with args matching " + sig + " doesn't exist");
|
||||
}
|
||||
|
||||
public static Method findMethodWithArgsDeep(InjectData data, ClassFile clazz, String name, Signature sig) throws Injexception
|
||||
static Method findMethodWithArgsDeep(InjectData data, ClassFile clazz, String name, Signature sig) throws Injexception
|
||||
{
|
||||
do
|
||||
for (Method m : clazz.getMethods())
|
||||
@@ -151,19 +151,7 @@ public class InjectUtil
|
||||
/**
|
||||
* Fail-fast implementation of ClassGroup.findStaticMethod
|
||||
*/
|
||||
public static Method findStaticMethod(ClassGroup group, String name) throws Injexception
|
||||
{
|
||||
Method m = group.findStaticMethod(name);
|
||||
if (m == null)
|
||||
throw new Injexception(String.format("Method %s couldn't be found", name));
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fail-fast implementation of ClassGroup.findStaticMethod
|
||||
*/
|
||||
public static Method findStaticMethod(ClassGroup group, String name, Signature type) throws Injexception
|
||||
static Method findStaticMethod(ClassGroup group, String name, Signature type) throws Injexception
|
||||
{
|
||||
Method m = group.findStaticMethod(name, type);
|
||||
if (m == null)
|
||||
@@ -176,20 +164,7 @@ public class InjectUtil
|
||||
/**
|
||||
* Fail-fast implementation of ClassFile.findMethodDeep
|
||||
*/
|
||||
public static Method findMethodDeep(ClassFile clazz, String name) throws Injexception
|
||||
{
|
||||
Method m = clazz.findMethodDeep(name);
|
||||
if (m == null)
|
||||
{
|
||||
throw new Injexception(String.format("Method %s couldn't be found", name));
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fail-fast implementation of ClassFile.findMethodDeep
|
||||
*/
|
||||
public static Method findMethodDeep(ClassFile clazz, String name, Signature type) throws Injexception
|
||||
static Method findMethodDeep(ClassFile clazz, String name, Signature type) throws Injexception
|
||||
{
|
||||
Method m = clazz.findMethodDeep(name, type);
|
||||
if (m == null)
|
||||
@@ -204,7 +179,7 @@ public class InjectUtil
|
||||
*
|
||||
* well...
|
||||
*/
|
||||
public static Field findStaticField(ClassGroup group, String name) throws Injexception
|
||||
static Field findStaticField(ClassGroup group, String name) throws Injexception
|
||||
{
|
||||
for (ClassFile clazz : group)
|
||||
{
|
||||
@@ -227,10 +202,10 @@ public class InjectUtil
|
||||
*
|
||||
* @return The obfuscated version of the found field
|
||||
*/
|
||||
public static Field findStaticField(InjectData data, String name, String classHint, Type type) throws Injexception
|
||||
static Field findStaticField(InjectData data, String name, String classHint, Type type) throws Injexception
|
||||
{
|
||||
final ClassGroup deob = data.getDeobfuscated();
|
||||
Field field = null;
|
||||
Field field;
|
||||
|
||||
if (classHint != null)
|
||||
{
|
||||
@@ -279,7 +254,7 @@ public class InjectUtil
|
||||
*
|
||||
* @return The obfuscated version of the found field
|
||||
*/
|
||||
public static Field findStaticField(InjectData data, net.runelite.asm.pool.Field pool) throws Injexception
|
||||
static Field findStaticField(InjectData data, net.runelite.asm.pool.Field pool) throws Injexception
|
||||
{
|
||||
return findStaticField(data, pool.getName(), pool.getClazz().getName(), pool.getType());
|
||||
}
|
||||
@@ -287,7 +262,7 @@ public class InjectUtil
|
||||
/**
|
||||
* Fail-fast implementation of ClassGroup.findFieldDeep
|
||||
*/
|
||||
public static Field findFieldDeep(ClassFile clazz, String name) throws Injexception
|
||||
static Field findFieldDeep(ClassFile clazz, String name) throws Injexception
|
||||
{
|
||||
do
|
||||
{
|
||||
@@ -301,13 +276,13 @@ public class InjectUtil
|
||||
throw new Injexception("Couldn't find field " + name);
|
||||
}
|
||||
|
||||
public static Field findField(InjectData data, String name, String hintClass) throws Injexception
|
||||
static Field findField(InjectData data, String name, String hintClass) throws Injexception
|
||||
{
|
||||
final ClassGroup deob = data.getDeobfuscated();
|
||||
return data.toVanilla(findField(deob, name, hintClass));
|
||||
}
|
||||
|
||||
public static Field findField(ClassGroup group, String name, String hintClass) throws Injexception
|
||||
static Field findField(ClassGroup group, String name, String hintClass) throws Injexception
|
||||
{
|
||||
Field field;
|
||||
if (hintClass != null)
|
||||
@@ -333,12 +308,12 @@ public class InjectUtil
|
||||
throw new Injexception("Field " + name + " doesn't exist");
|
||||
}
|
||||
|
||||
public static ClassFile fromApiMethod(InjectData data, RSApiMethod apiMethod)
|
||||
static ClassFile fromApiMethod(InjectData data, RSApiMethod apiMethod)
|
||||
{
|
||||
return data.toVanilla(data.toDeob(apiMethod.getClazz().getName()));
|
||||
}
|
||||
|
||||
public static Signature apiToDeob(InjectData data, Signature api)
|
||||
static Signature apiToDeob(InjectData data, Signature api)
|
||||
{
|
||||
return new Signature.Builder()
|
||||
.setReturnType(apiToDeob(data, api.getReturnValue()))
|
||||
@@ -349,7 +324,7 @@ public class InjectUtil
|
||||
).build();
|
||||
}
|
||||
|
||||
public static Type apiToDeob(InjectData data, Type api)
|
||||
static Type apiToDeob(InjectData data, Type api)
|
||||
{
|
||||
if (api.isPrimitive())
|
||||
{
|
||||
@@ -392,7 +367,7 @@ public class InjectUtil
|
||||
return api;
|
||||
}
|
||||
|
||||
public static Type deobToVanilla(InjectData data, Type deobT)
|
||||
static Type deobToVanilla(InjectData data, Type deobT)
|
||||
{
|
||||
if (deobT.isPrimitive())
|
||||
{
|
||||
@@ -408,12 +383,12 @@ public class InjectUtil
|
||||
return Type.getType("L" + data.toVanilla(deobClass).getName() + ";", deobT.getDimensions());
|
||||
}
|
||||
|
||||
public static boolean apiToDeobSigEquals(InjectData data, Signature deobSig, Signature apiSig)
|
||||
static boolean apiToDeobSigEquals(InjectData data, Signature deobSig, Signature apiSig)
|
||||
{
|
||||
return deobSig.equals(apiToDeob(data, apiSig));
|
||||
}
|
||||
|
||||
public static boolean argsMatch(Signature a, Signature b)
|
||||
static boolean argsMatch(Signature a, Signature b)
|
||||
{
|
||||
List<Type> aa = a.getArguments();
|
||||
List<Type> bb = b.getArguments();
|
||||
@@ -439,7 +414,7 @@ public class InjectUtil
|
||||
*
|
||||
* If the annotation doesn't exist return the current name instead.
|
||||
*/
|
||||
public static <T extends Annotated & Named> String getObfuscatedName(T from)
|
||||
static <T extends Annotated & Named> String getObfuscatedName(T from)
|
||||
{
|
||||
Annotation name = from.getAnnotations().find(DeobAnnotations.OBFUSCATED_NAME);
|
||||
return name == null ? from.getName() : name.getElement().getString();
|
||||
@@ -448,7 +423,7 @@ public class InjectUtil
|
||||
/**
|
||||
* Gets the value of the @Export annotation on the object.
|
||||
*/
|
||||
public static String getExportedName(Annotated from)
|
||||
static String getExportedName(Annotated from)
|
||||
{
|
||||
Annotation export = from.getAnnotations().find(DeobAnnotations.EXPORT);
|
||||
return export == null ? null : export.getElement().getString();
|
||||
@@ -457,7 +432,7 @@ public class InjectUtil
|
||||
/**
|
||||
* Creates the correct load instruction for the variable with Type type and var index index.
|
||||
*/
|
||||
public static Instruction createLoadForTypeIndex(Instructions instructions, Type type, int index)
|
||||
static Instruction createLoadForTypeIndex(Instructions instructions, Type type, int index)
|
||||
{
|
||||
if (type.getDimensions() > 0 || !type.isPrimitive())
|
||||
{
|
||||
@@ -486,7 +461,7 @@ public class InjectUtil
|
||||
/**
|
||||
* Creates the right return instruction for an object with Type type
|
||||
*/
|
||||
public static Instruction createReturnForType(Instructions instructions, Type type)
|
||||
static Instruction createReturnForType(Instructions instructions, Type type)
|
||||
{
|
||||
if (!type.isPrimitive())
|
||||
{
|
||||
@@ -514,7 +489,7 @@ public class InjectUtil
|
||||
}
|
||||
}
|
||||
|
||||
public static Instruction createInvokeFor(Instructions instructions, net.runelite.asm.pool.Method method, boolean isStatic)
|
||||
static Instruction createInvokeFor(Instructions instructions, net.runelite.asm.pool.Method method, boolean isStatic)
|
||||
{
|
||||
if (isStatic)
|
||||
{
|
||||
@@ -525,4 +500,14 @@ public class InjectUtil
|
||||
return new InvokeVirtual(instructions, method);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Legit fuck annotations
|
||||
*/
|
||||
static ClassFile getVanillaClassFromAnnotationString(InjectData data, Annotation annotation)
|
||||
{
|
||||
Object v = annotation.getElement().getValue();
|
||||
String str = ((org.objectweb.asm.Type) v).getInternalName();
|
||||
return data.toVanilla(data.toDeob(str));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import net.runelite.asm.Method;
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.Code;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import net.runelite.asm.attributes.annotation.ArrayElement;
|
||||
import net.runelite.asm.attributes.code.Instruction;
|
||||
import net.runelite.asm.attributes.code.Instructions;
|
||||
import net.runelite.asm.attributes.code.instruction.types.FieldInstruction;
|
||||
@@ -28,7 +29,6 @@ import net.runelite.asm.attributes.code.instruction.types.PushConstantInstructio
|
||||
import net.runelite.asm.attributes.code.instruction.types.ReturnInstruction;
|
||||
import net.runelite.asm.attributes.code.instructions.ALoad;
|
||||
import net.runelite.asm.attributes.code.instructions.ANewArray;
|
||||
import net.runelite.asm.attributes.code.instructions.CheckCast;
|
||||
import net.runelite.asm.attributes.code.instructions.GetField;
|
||||
import net.runelite.asm.attributes.code.instructions.ILoad;
|
||||
import net.runelite.asm.attributes.code.instructions.InvokeDynamic;
|
||||
@@ -78,7 +78,7 @@ public class MixinInjector extends AbstractInjector
|
||||
|
||||
for (Map.Entry<Provider<ClassFile>, List<ClassFile>> entry : mixinTargets.entrySet())
|
||||
{
|
||||
findShadowFields(entry.getKey(), entry.getValue());
|
||||
findShadowFields(entry.getKey());
|
||||
}
|
||||
|
||||
log.info("Shadowed {} fields", shadowFields.size());
|
||||
@@ -106,8 +106,6 @@ public class MixinInjector extends AbstractInjector
|
||||
// to make sure we aren't changing code in all classes at once
|
||||
if (MIXIN.equals(annotation.getType()))
|
||||
{
|
||||
final String str = ((org.objectweb.asm.Type) annotation.getElement().getValue()).getInternalName();
|
||||
|
||||
builder.put(
|
||||
new Provider<ClassFile>()
|
||||
{
|
||||
@@ -117,7 +115,7 @@ public class MixinInjector extends AbstractInjector
|
||||
return mixinClass;
|
||||
}
|
||||
},
|
||||
ImmutableList.of(inject.toVanilla(inject.toDeob(str)))
|
||||
ImmutableList.of(InjectUtil.getVanillaClassFromAnnotationString(inject, annotation))
|
||||
);
|
||||
}
|
||||
else if (MIXINS.equals(annotation.getType()))
|
||||
@@ -141,15 +139,18 @@ public class MixinInjector extends AbstractInjector
|
||||
}
|
||||
};
|
||||
|
||||
final List<ClassFile> targetClasses = annotation
|
||||
.getElements()
|
||||
.stream()
|
||||
.map(e -> ((org.objectweb.asm.Type) e.getValue()).getInternalName())
|
||||
.map(inject::toDeob)
|
||||
.map(inject::toVanilla)
|
||||
.collect(ImmutableList.toImmutableList());
|
||||
assert annotation.getElement() instanceof ArrayElement;
|
||||
ArrayElement arr = (ArrayElement) annotation.getElement();
|
||||
|
||||
builder.put(mixinProvider, targetClasses);
|
||||
ImmutableList.Builder<ClassFile> b = ImmutableList.builder();
|
||||
|
||||
for (Object ob : arr)
|
||||
{
|
||||
assert ob instanceof Annotation;
|
||||
b.add(InjectUtil.getVanillaClassFromAnnotationString(inject, (Annotation) ob));
|
||||
}
|
||||
|
||||
builder.put(mixinProvider, b.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -195,7 +196,7 @@ public class MixinInjector extends AbstractInjector
|
||||
}
|
||||
}
|
||||
|
||||
private void findShadowFields(Provider<ClassFile> mixinProvider, List<ClassFile> targetClasses) throws Injexception
|
||||
private void findShadowFields(Provider<ClassFile> mixinProvider) throws Injexception
|
||||
{
|
||||
final ClassFile mixinClass = mixinProvider.get();
|
||||
|
||||
@@ -267,7 +268,7 @@ public class MixinInjector extends AbstractInjector
|
||||
throw new Injexception("Mixin methods cannot have more parameters than their corresponding ob method");
|
||||
}
|
||||
|
||||
Method copy = new Method(targetClass, "copy$" + copiedName, sourceMethod.getObfuscatedSignature());
|
||||
Method copy = new Method(targetClass, "copy$" + copiedName, sourceMethod.getDescriptor());
|
||||
moveCode(copy, sourceMethod.getCode());
|
||||
copy.setAccessFlags(sourceMethod.getAccessFlags());
|
||||
copy.setPublic();
|
||||
@@ -444,32 +445,32 @@ public class MixinInjector extends AbstractInjector
|
||||
throw new Injexception("Mixin methods cannot have more parameters than their corresponding ob method");
|
||||
}
|
||||
|
||||
Type returnType = mixinMethod.getDescriptor().getReturnValue();
|
||||
Type deobReturnType = InjectUtil.apiToDeob(inject, returnType);
|
||||
if (!returnType.equals(deobReturnType))
|
||||
{
|
||||
ClassFile deobReturnTypeClassFile = inject.getDeobfuscated()
|
||||
.findClass(deobReturnType.getInternalName());
|
||||
if (deobReturnTypeClassFile != null)
|
||||
{
|
||||
ClassFile obReturnTypeClass = inject.toVanilla(deobReturnTypeClassFile);
|
||||
//Type returnType = mixinMethod.getDescriptor().getReturnValue();
|
||||
//Type deobReturnType = InjectUtil.apiToDeob(inject, returnType);
|
||||
//if (!returnType.equals(deobReturnType))
|
||||
//{
|
||||
// ClassFile deobReturnTypeClassFile = inject.getDeobfuscated()
|
||||
// .findClass(deobReturnType.getInternalName());
|
||||
// if (deobReturnTypeClassFile != null)
|
||||
// {
|
||||
// ClassFile obReturnTypeClass = inject.toVanilla(deobReturnTypeClassFile);
|
||||
|
||||
Instructions instructions = mixinMethod.getCode().getInstructions();
|
||||
ListIterator<Instruction> listIter = instructions.listIterator();
|
||||
while (listIter.hasNext())
|
||||
{
|
||||
Instruction instr = listIter.next();
|
||||
if (instr instanceof ReturnInstruction)
|
||||
{
|
||||
listIter.previous();
|
||||
CheckCast checkCast = new CheckCast(instructions);
|
||||
checkCast.setType(new Type(obReturnTypeClass.getName()));
|
||||
listIter.add(checkCast);
|
||||
listIter.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Instructions instructions = mixinMethod.getCode().getInstructions();
|
||||
// ListIterator<Instruction> listIter = instructions.listIterator();
|
||||
// while (listIter.hasNext())
|
||||
// {
|
||||
// Instruction instr = listIter.next();
|
||||
// if (instr instanceof ReturnInstruction)
|
||||
// {
|
||||
// listIter.previous();
|
||||
// CheckCast checkCast = new CheckCast(instructions);
|
||||
// checkCast.setType(new Type(obReturnTypeClass.getName()));
|
||||
// listIter.add(checkCast);
|
||||
// listIter.next();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
moveCode(obMethod, mixinMethod.getCode());
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ public class RSApiClassVisitor extends ClassVisitor
|
||||
{
|
||||
private final RSApiClass apiClass;
|
||||
|
||||
public RSApiClassVisitor(RSApiClass apiClass)
|
||||
RSApiClassVisitor(RSApiClass apiClass)
|
||||
{
|
||||
super(Opcodes.ASM5);
|
||||
this.apiClass = apiClass;
|
||||
|
||||
@@ -1,42 +1,27 @@
|
||||
package com.openosrs.injector.rsapi;
|
||||
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import net.runelite.asm.attributes.annotation.Element;
|
||||
import net.runelite.asm.attributes.annotation.SimpleElement;
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
public class RSApiMethodAnnotationVisitor extends AnnotationVisitor
|
||||
{
|
||||
private final RSApiMethod method;
|
||||
private final Type type;
|
||||
private final Annotation annotation;
|
||||
|
||||
public RSApiMethodAnnotationVisitor(RSApiMethod method, Type type)
|
||||
RSApiMethodAnnotationVisitor(Annotation annotation)
|
||||
{
|
||||
super(Opcodes.ASM5);
|
||||
|
||||
this.method = method;
|
||||
this.type = type;
|
||||
|
||||
annotation = new Annotation(method.getAnnotations());
|
||||
annotation.setType(type);
|
||||
this.annotation = annotation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(String name, Object value)
|
||||
{
|
||||
Element element = new Element(annotation);
|
||||
|
||||
element.setName(name);
|
||||
element.setValue(value);
|
||||
Element element = new SimpleElement(name, value);
|
||||
|
||||
annotation.addElement(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnd()
|
||||
{
|
||||
method.getAnnotations().addAnnotation(annotation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.openosrs.injector.rsapi;
|
||||
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
@@ -17,8 +18,8 @@ public class RSApiMethodVisitor extends MethodVisitor
|
||||
|
||||
public AnnotationVisitor visitAnnotation(String descriptor, boolean visible)
|
||||
{
|
||||
final Type type = new Type(descriptor);
|
||||
|
||||
return new RSApiMethodAnnotationVisitor(method, type);
|
||||
Annotation annotation = new Annotation(new Type(descriptor));
|
||||
this.method.getAnnotations().addAnnotation(annotation);
|
||||
return new RSApiMethodAnnotationVisitor(annotation);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user