Merge pull request #9 from Lucwousin/annotations
Update injector for new Annotations
This commit is contained in:
@@ -15,10 +15,10 @@ plugins {
|
||||
id("se.patrikerdes.use-latest-versions") version "0.2.14"
|
||||
}
|
||||
|
||||
val oprsver = "3.3.1"
|
||||
val oprsver = "3.4.0"
|
||||
|
||||
group = "com.openosrs"
|
||||
version = "1.1.4"
|
||||
version = "1.1.5"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
||||
@@ -14,14 +14,14 @@ import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import net.runelite.asm.Annotated;
|
||||
import net.runelite.asm.Annotation;
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.asm.Field;
|
||||
import net.runelite.asm.Method;
|
||||
import net.runelite.asm.Named;
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import net.runelite.asm.attributes.Annotated;
|
||||
import net.runelite.asm.attributes.code.Instruction;
|
||||
import net.runelite.asm.attributes.code.InstructionType;
|
||||
import net.runelite.asm.attributes.code.Instructions;
|
||||
@@ -368,8 +368,8 @@ public interface InjectUtil
|
||||
*/
|
||||
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();
|
||||
Annotation name = from.findAnnotation(DeobAnnotations.OBFUSCATED_NAME);
|
||||
return name == null ? from.getName() : name.getValueString();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -377,8 +377,8 @@ public interface InjectUtil
|
||||
*/
|
||||
static String getExportedName(Annotated from)
|
||||
{
|
||||
Annotation export = from.getAnnotations().find(DeobAnnotations.EXPORT);
|
||||
return export == null ? null : export.getElement().getString();
|
||||
Annotation export = from.findAnnotation(DeobAnnotations.EXPORT);
|
||||
return export == null ? null : export.getValueString();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -450,7 +450,7 @@ public interface InjectUtil
|
||||
*/
|
||||
static ClassFile getVanillaClassFromAnnotationString(InjectData data, Annotation annotation)
|
||||
{
|
||||
Object v = annotation.getElement().getValue();
|
||||
Object v = annotation.getValue();
|
||||
String str = ((org.objectweb.asm.Type) v).getInternalName();
|
||||
return data.toVanilla(data.toDeob(str));
|
||||
}
|
||||
|
||||
@@ -36,10 +36,10 @@ import com.openosrs.injector.injection.InjectData;
|
||||
import com.openosrs.injector.rsapi.RSApiMethod;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import net.runelite.asm.Annotation;
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.Code;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import net.runelite.asm.attributes.code.Instruction;
|
||||
import net.runelite.asm.attributes.code.Instructions;
|
||||
import net.runelite.asm.attributes.code.instructions.CheckCast;
|
||||
@@ -67,7 +67,7 @@ public class InjectConstruct extends AbstractInjector
|
||||
{
|
||||
for (RSApiMethod apiMethod : inject.getRsApi().getConstructs())
|
||||
{
|
||||
Annotation construct = apiMethod.getAnnotations().find(CONSTRUCT);
|
||||
Annotation construct = apiMethod.findAnnotation(CONSTRUCT);
|
||||
if (construct == null)
|
||||
continue;
|
||||
|
||||
|
||||
@@ -40,12 +40,12 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.inject.Provider;
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.runelite.asm.Annotation;
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.Field;
|
||||
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.code.Instruction;
|
||||
import net.runelite.asm.attributes.code.InstructionType;
|
||||
import net.runelite.asm.attributes.code.Instructions;
|
||||
@@ -101,14 +101,12 @@ public class InjectHook extends AbstractInjector
|
||||
{
|
||||
for (Method mixinMethod : mixinClass.getMethods())
|
||||
{
|
||||
final Annotation fieldHook = mixinMethod.getAnnotations().find(FIELDHOOK);
|
||||
final Annotation fieldHook = mixinMethod.findAnnotation(FIELDHOOK);
|
||||
if (fieldHook == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final String hookName = fieldHook.getElement().getString();
|
||||
final boolean before = fieldHook.getElements().size() == 2 && fieldHook.getElements().get(1).getValue().equals(true);
|
||||
final String hookName = fieldHook.getValueString();
|
||||
final boolean before = isBefore(fieldHook);
|
||||
|
||||
final ClassFile deobTarget = inject.toDeob(targetClass.getName());
|
||||
final Field deobField;
|
||||
@@ -361,4 +359,10 @@ public class InjectHook extends AbstractInjector
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isBefore(Annotation a)
|
||||
{
|
||||
Object val = a.get("before");
|
||||
return val instanceof Boolean && (Boolean) val;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,10 +37,10 @@ import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import javax.inject.Provider;
|
||||
import net.runelite.asm.Annotation;
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.Method;
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import net.runelite.asm.attributes.code.Instruction;
|
||||
import net.runelite.asm.attributes.code.Instructions;
|
||||
import net.runelite.asm.attributes.code.instruction.types.ReturnInstruction;
|
||||
@@ -78,15 +78,15 @@ public class InjectHookMethod extends AbstractInjector
|
||||
{
|
||||
for (Method mixinMethod : mixinClass.getMethods())
|
||||
{
|
||||
final Annotation methodHook = mixinMethod.getAnnotations().find(METHODHOOK);
|
||||
final Annotation methodHook = mixinMethod.findAnnotation(METHODHOOK);
|
||||
if (methodHook == null)
|
||||
continue;
|
||||
|
||||
if (!mixinMethod.getDescriptor().isVoid())
|
||||
throw new InjectException("Method hook " + mixinMethod.getPoolMethod() + " doesn't have void return type");
|
||||
|
||||
final String hookName = methodHook.getElement().getString();
|
||||
final boolean end = methodHook.getElements().size() == 2 && methodHook.getElements().get(1).getValue().equals(true);
|
||||
final String hookName = methodHook.getValueString();
|
||||
final boolean end = isEnd(methodHook);
|
||||
|
||||
final ClassFile deobTarget = inject.toDeob(targetClass.getName());
|
||||
final Signature deobSig = InjectUtil.apiToDeob(inject, mixinMethod.getDescriptor());
|
||||
@@ -164,4 +164,10 @@ public class InjectHookMethod extends AbstractInjector
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private static boolean isEnd(Annotation annotation)
|
||||
{
|
||||
Object val = annotation.get("end");
|
||||
return val instanceof Boolean && (Boolean) val;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
package com.openosrs.injector.injectors;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.openosrs.injector.InjectException;
|
||||
import com.openosrs.injector.InjectUtil;
|
||||
@@ -41,15 +40,17 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.inject.Provider;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Value;
|
||||
import net.runelite.asm.Annotation;
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.Field;
|
||||
import net.runelite.asm.Method;
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.Annotated;
|
||||
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;
|
||||
@@ -63,10 +64,10 @@ 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;
|
||||
import net.runelite.asm.attributes.code.instructions.InvokeSpecial;
|
||||
import net.runelite.asm.attributes.code.instructions.InvokeStatic;
|
||||
import net.runelite.asm.attributes.code.instructions.LDC;
|
||||
import net.runelite.asm.attributes.code.instructions.Pop;
|
||||
import net.runelite.asm.attributes.code.instructions.PutField;
|
||||
import net.runelite.asm.signature.Signature;
|
||||
@@ -137,48 +138,11 @@ public class MixinInjector extends AbstractInjector
|
||||
|
||||
for (ClassFile mixinClass : inject.getMixins())
|
||||
{
|
||||
for (Annotation annotation : mixinClass.getAnnotations())
|
||||
{
|
||||
// If there's multiple mixins we gotta create new copies of the classfiles
|
||||
// to make sure we aren't changing code in all classes at once
|
||||
if (MIXIN.equals(annotation.getType()))
|
||||
{
|
||||
builder.put(
|
||||
() -> mixinClass,
|
||||
ImmutableList.of(InjectUtil.getVanillaClassFromAnnotationString(inject, annotation))
|
||||
);
|
||||
}
|
||||
else if (MIXINS.equals(annotation.getType()))
|
||||
{
|
||||
final Provider<ClassFile>mixinProvider = new Provider<ClassFile>()
|
||||
{
|
||||
byte[] bytes = null;
|
||||
|
||||
@Override
|
||||
public ClassFile get()
|
||||
{
|
||||
if (bytes != null)
|
||||
return JarUtil.loadClass(bytes);
|
||||
|
||||
bytes = JarUtil.writeClass(mixinClass.getGroup(), mixinClass);
|
||||
return mixinClass;
|
||||
}
|
||||
};
|
||||
|
||||
assert annotation.getElement() instanceof ArrayElement;
|
||||
ArrayElement arr = (ArrayElement) annotation.getElement();
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
final List<ClassFile> ret = getMixins(mixinClass);
|
||||
builder.put(
|
||||
(ret.size() > 1 ? mixinProvider(mixinClass) : () -> mixinClass),
|
||||
ret
|
||||
);
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
@@ -192,9 +156,8 @@ public class MixinInjector extends AbstractInjector
|
||||
{
|
||||
for (Field field : mixinClass.getFields())
|
||||
{
|
||||
if (field.getAnnotations().find(INJECT) == null &&
|
||||
(!ASSERTION_FIELD.equals(field.getName()) ||
|
||||
targetClass.findField(ASSERTION_FIELD, Type.BOOLEAN) != null))
|
||||
if (field.findAnnotation(INJECT) == null &&
|
||||
(!ASSERTION_FIELD.equals(field.getName()) || targetClass.findField(ASSERTION_FIELD, Type.BOOLEAN) != null))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -204,9 +167,9 @@ public class MixinInjector extends AbstractInjector
|
||||
copy.setPublic();
|
||||
copy.setValue(field.getValue());
|
||||
|
||||
for (Annotation annotation : field.getAnnotations())
|
||||
if (!annotation.getType().toString().startsWith("Lnet/runelite/api/mixins"))
|
||||
copy.getAnnotations().addAnnotation(annotation);
|
||||
for (Map.Entry<Type, Annotation> e : field.getAnnotations().entrySet())
|
||||
if (!e.getKey().toString().startsWith("Lnet/runelite/api/mixins"))
|
||||
copy.addAnnotation(e.getValue());
|
||||
|
||||
targetClass.addField(copy);
|
||||
|
||||
@@ -224,7 +187,7 @@ public class MixinInjector extends AbstractInjector
|
||||
|
||||
for (final Field field : mixinClass.getFields())
|
||||
{
|
||||
Annotation shadow = field.getAnnotations().find(SHADOW);
|
||||
Annotation shadow = field.findAnnotation(SHADOW);
|
||||
|
||||
if (shadow == null)
|
||||
continue;
|
||||
@@ -232,7 +195,7 @@ public class MixinInjector extends AbstractInjector
|
||||
if (!field.isStatic())
|
||||
throw new InjectException("Shadowed fields must be static");
|
||||
|
||||
String shadowed = shadow.getElement().getString();
|
||||
String shadowed = shadow.getValueString();
|
||||
|
||||
Field targetField = injectedFields.get(shadowed);
|
||||
Number getter = null;
|
||||
@@ -267,11 +230,11 @@ public class MixinInjector extends AbstractInjector
|
||||
// Handle the copy mixins first, so all other mixins know of the copies
|
||||
for (Method mixinMethod : mixinClass.getMethods())
|
||||
{
|
||||
Annotation copyA = mixinMethod.getAnnotations().find(COPY);
|
||||
Annotation copyA = mixinMethod.findAnnotation(COPY);
|
||||
if (copyA == null)
|
||||
continue;
|
||||
String copiedName = copyA.getValueString();
|
||||
|
||||
String copiedName = copyA.getElement().getString();
|
||||
Signature deobSig = InjectUtil.apiToDeob(inject, mixinMethod.getDescriptor());
|
||||
boolean notStat = !mixinMethod.isStatic();
|
||||
|
||||
@@ -291,7 +254,8 @@ public class MixinInjector extends AbstractInjector
|
||||
copy.setAccessFlags(sourceMethod.getAccessFlags());
|
||||
copy.setPublic();
|
||||
copy.getExceptions().getExceptions().addAll(sourceMethod.getExceptions().getExceptions());
|
||||
copy.getAnnotations().getAnnotations().addAll(sourceMethod.getAnnotations().getAnnotations());
|
||||
for (var a : sourceMethod.getAnnotations().values())
|
||||
copy.addAnnotation(a);
|
||||
targetClass.addMethod(copy);
|
||||
++copied;
|
||||
|
||||
@@ -303,7 +267,7 @@ public class MixinInjector extends AbstractInjector
|
||||
boolean hasGarbageValue = mixinMethod.getDescriptor().size() != sourceMethod.getDescriptor().size()
|
||||
&& deobSourceMethod.getDescriptor().size() < copy.getDescriptor().size();
|
||||
|
||||
copiedMethods.put(mixinMethod.getPoolMethod(), new CopiedMethod(copy, hasGarbageValue));
|
||||
copiedMethods.put(mixinMethod.getPoolMethod(), new CopiedMethod(copy, !hasGarbageValue ? null : Integer.valueOf(DeobAnnotations.getDecoder(deobSourceMethod))));
|
||||
}
|
||||
|
||||
// Handle the rest of the mixin types
|
||||
@@ -311,7 +275,7 @@ public class MixinInjector extends AbstractInjector
|
||||
{
|
||||
boolean isClinit = "<clinit>".equals(mixinMethod.getName());
|
||||
boolean isInit = "<init>".equals(mixinMethod.getName());
|
||||
boolean hasInject = mixinMethod.getAnnotations().find(INJECT) != null;
|
||||
boolean hasInject = mixinMethod.findAnnotation(INJECT) != null;
|
||||
|
||||
// You can't annotate clinit, so its always injected
|
||||
if ((hasInject && isInit) || isClinit)
|
||||
@@ -345,7 +309,7 @@ public class MixinInjector extends AbstractInjector
|
||||
{
|
||||
Instructions instructions = copy.getCode().getInstructions();
|
||||
ListIterator<Instruction> listIter = instructions.listIterator();
|
||||
for (; listIter.hasNext(); )
|
||||
while (listIter.hasNext())
|
||||
{
|
||||
Instruction instr = listIter.next();
|
||||
if (instr instanceof InvokeSpecial)
|
||||
@@ -424,10 +388,10 @@ public class MixinInjector extends AbstractInjector
|
||||
log.debug("[DEBUG] Injected mixin method {} to {}", copy, targetClass);
|
||||
++injected;
|
||||
}
|
||||
else if (mixinMethod.getAnnotations().find(REPLACE) != null)
|
||||
else if (mixinMethod.findAnnotation(REPLACE) != null)
|
||||
{
|
||||
Annotation replaceAnnotation = mixinMethod.getAnnotations().find(REPLACE);
|
||||
String replacedName = (String) replaceAnnotation.getElement().getValue();
|
||||
Annotation replaceAnnotation = mixinMethod.findAnnotation(REPLACE);
|
||||
String replacedName = replaceAnnotation.getValueString();
|
||||
|
||||
ClassFile deobClass = inject.toDeob(targetClass.getName());
|
||||
Method deobMethod = findDeobMatching(deobClass, mixinMethod, replacedName);
|
||||
@@ -559,17 +523,13 @@ public class MixinInjector extends AbstractInjector
|
||||
CopiedMethod copiedMethod = copiedMethods.get(ii.getMethod());
|
||||
if (copiedMethod != null)
|
||||
{
|
||||
ii.setMethod(copiedMethod.obMethod.getPoolMethod());
|
||||
ii.setMethod(copiedMethod.copy.getPoolMethod());
|
||||
|
||||
// Pass through garbage value if the method has one
|
||||
if (copiedMethod.hasGarbageValue)
|
||||
if (copiedMethod.garbage != null)
|
||||
{
|
||||
int garbageIndex = copiedMethod.obMethod.isStatic()
|
||||
? copiedMethod.obMethod.getDescriptor().size() - 1
|
||||
: copiedMethod.obMethod.getDescriptor().size();
|
||||
|
||||
iterator.previous();
|
||||
iterator.add(new ILoad(method.getCode().getInstructions(), garbageIndex));
|
||||
iterator.add(new LDC(method.getCode().getInstructions(), copiedMethod.garbage));
|
||||
iterator.next();
|
||||
}
|
||||
}
|
||||
@@ -697,19 +657,53 @@ public class MixinInjector extends AbstractInjector
|
||||
}
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<ClassFile> getMixins(Annotated from)
|
||||
{
|
||||
final Annotation mixin = from.findAnnotation(MIXIN);
|
||||
if (mixin != null)
|
||||
{
|
||||
return List.of(InjectUtil.getVanillaClassFromAnnotationString(inject, mixin));
|
||||
}
|
||||
final Annotation mixins = from.findAnnotation(MIXINS);
|
||||
if (mixins != null)
|
||||
{
|
||||
return ((List<Annotation>) mixins.getValue()).stream()
|
||||
.map(mix -> InjectUtil.getVanillaClassFromAnnotationString(inject, mix))
|
||||
.collect(Collectors.toUnmodifiableList());
|
||||
}
|
||||
throw new IllegalArgumentException("No MIXIN or MIXINS found on " + from.toString());
|
||||
}
|
||||
|
||||
@Value
|
||||
private static class CopiedMethod
|
||||
{
|
||||
private Method obMethod;
|
||||
private boolean hasGarbageValue;
|
||||
@Nonnull Method copy;
|
||||
@Nullable Integer garbage;
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@Value
|
||||
private static class ShadowField
|
||||
{
|
||||
private Field targetField;
|
||||
@Nonnull Field targetField;
|
||||
@Nullable Number obfuscatedGetter;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Number obfuscatedGetter;
|
||||
private static Provider<ClassFile> mixinProvider(ClassFile mixin)
|
||||
{
|
||||
return new Provider<>()
|
||||
{
|
||||
byte[] bytes = null;
|
||||
|
||||
@Override
|
||||
public ClassFile get()
|
||||
{
|
||||
if (bytes != null)
|
||||
return JarUtil.loadClass(bytes);
|
||||
|
||||
bytes = JarUtil.writeClass(mixin.getGroup(), mixin);
|
||||
return mixin;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,11 +43,11 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import net.runelite.asm.Annotated;
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.Field;
|
||||
import net.runelite.asm.Method;
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.Annotated;
|
||||
import net.runelite.asm.signature.Signature;
|
||||
import net.runelite.deob.DeobAnnotations;
|
||||
import static com.openosrs.injector.rsapi.RSApi.API_BASE;
|
||||
|
||||
@@ -53,10 +53,7 @@ public class RSApi implements Iterable<RSApiClass>
|
||||
|
||||
final RSApiClass apiClass = new RSApiClass();
|
||||
|
||||
reader.accept(
|
||||
new RSApiClassVisitor(apiClass),
|
||||
ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES
|
||||
);
|
||||
reader.accept(apiClass, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
|
||||
|
||||
this.classes.add(apiClass);
|
||||
}
|
||||
|
||||
@@ -12,18 +12,22 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.Data;
|
||||
import net.runelite.asm.attributes.Annotations;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.runelite.asm.Annotation;
|
||||
import net.runelite.asm.pool.Class;
|
||||
import net.runelite.asm.pool.Method;
|
||||
import net.runelite.asm.signature.Signature;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import static com.openosrs.injector.rsapi.RSApi.CONSTRUCT;
|
||||
import static com.openosrs.injector.rsapi.RSApi.IMPORT;
|
||||
|
||||
@Data
|
||||
public class RSApiClass implements Iterable<RSApiMethod>
|
||||
@Getter
|
||||
@Setter
|
||||
public class RSApiClass extends ClassVisitor implements Iterable<RSApiMethod>
|
||||
{
|
||||
private Class clazz;
|
||||
private final List<Class> interfaces = new ArrayList<>();
|
||||
@@ -32,6 +36,11 @@ public class RSApiClass implements Iterable<RSApiMethod>
|
||||
|
||||
private final Map<String, List<RSApiMethod>> imports = new HashMap<>();
|
||||
|
||||
RSApiClass()
|
||||
{
|
||||
super(Opcodes.ASM5);
|
||||
}
|
||||
|
||||
void init(List<RSApiMethod> constructList)
|
||||
{
|
||||
for (RSApiMethod method : this)
|
||||
@@ -39,23 +48,18 @@ public class RSApiClass implements Iterable<RSApiMethod>
|
||||
if (method.isSynthetic())
|
||||
continue;
|
||||
|
||||
final Annotations annotations = method.getAnnotations();
|
||||
if (annotations.find(CONSTRUCT) != null)
|
||||
if (method.findAnnotation(CONSTRUCT) != null)
|
||||
{
|
||||
constructList.add(method);
|
||||
continue;
|
||||
}
|
||||
|
||||
final Annotation imported = annotations.find(IMPORT);
|
||||
final Annotation imported = method.findAnnotation(IMPORT);
|
||||
if (imported != null)
|
||||
{
|
||||
final String importStr = imported.getElement().getString();
|
||||
|
||||
imports.computeIfAbsent(
|
||||
importStr,
|
||||
imported.getValueString(),
|
||||
(str) -> new ArrayList<>()
|
||||
).add(method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,4 +89,17 @@ public class RSApiClass implements Iterable<RSApiMethod>
|
||||
{
|
||||
return this.methods.iterator();
|
||||
}
|
||||
|
||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
|
||||
{
|
||||
clazz = new Class(name);
|
||||
|
||||
for (String s : interfaces)
|
||||
this.interfaces.add(new Class(s));
|
||||
}
|
||||
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions)
|
||||
{
|
||||
return addMethod(name, new Signature(desc), access);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Lucas <https://github.com/Lucwousin>
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is licensed under GPL3, see the complete license in
|
||||
* the LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
package com.openosrs.injector.rsapi;
|
||||
|
||||
import net.runelite.asm.pool.Class;
|
||||
import net.runelite.asm.signature.Signature;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
public class RSApiClassVisitor extends ClassVisitor
|
||||
{
|
||||
private final RSApiClass apiClass;
|
||||
|
||||
RSApiClassVisitor(RSApiClass apiClass)
|
||||
{
|
||||
super(Opcodes.ASM5);
|
||||
this.apiClass = apiClass;
|
||||
}
|
||||
|
||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
|
||||
{
|
||||
apiClass.setClazz(new Class(name));
|
||||
|
||||
for (String s : interfaces)
|
||||
apiClass.getInterfaces().add(new Class(s));
|
||||
}
|
||||
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions)
|
||||
{
|
||||
final RSApiMethod method = apiClass.addMethod(name, new Signature(desc), access);
|
||||
return new RSApiMethodVisitor(method);
|
||||
}
|
||||
}
|
||||
@@ -7,25 +7,39 @@
|
||||
*/
|
||||
package com.openosrs.injector.rsapi;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.runelite.asm.Annotated;
|
||||
import lombok.Setter;
|
||||
import net.runelite.asm.Annotation;
|
||||
import net.runelite.asm.Named;
|
||||
import net.runelite.asm.attributes.Annotations;
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.Annotated;
|
||||
import net.runelite.asm.pool.Class;
|
||||
import net.runelite.asm.pool.Method;
|
||||
import net.runelite.asm.signature.Signature;
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
@Data
|
||||
@RequiredArgsConstructor
|
||||
public class RSApiMethod implements Annotated, Named
|
||||
@Getter
|
||||
@Setter
|
||||
public class RSApiMethod extends MethodVisitor implements Annotated, Named
|
||||
{
|
||||
private final Method method;
|
||||
private final int accessFlags;
|
||||
private final Annotations annotations = new Annotations();
|
||||
private final Map<Type, Annotation> annotations = new HashMap<>();
|
||||
private boolean injected;
|
||||
|
||||
RSApiMethod(Method method, int accesFlags)
|
||||
{
|
||||
super(Opcodes.ASM5);
|
||||
this.method = method;
|
||||
this.accessFlags = accesFlags;
|
||||
}
|
||||
|
||||
public Class getClazz()
|
||||
{
|
||||
return method.getClazz();
|
||||
@@ -50,4 +64,11 @@ public class RSApiMethod implements Annotated, Named
|
||||
{
|
||||
return (accessFlags & (Opcodes.ACC_ABSTRACT | Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC)) == 1;
|
||||
}
|
||||
|
||||
public AnnotationVisitor visitAnnotation(String descriptor, boolean visible)
|
||||
{
|
||||
final var annotation = new Annotation(new Type(descriptor), visible);
|
||||
this.addAnnotation(annotation);
|
||||
return annotation;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Lucas <https://github.com/Lucwousin>
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is licensed under GPL3, see the complete license in
|
||||
* the LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
package com.openosrs.injector.rsapi;
|
||||
|
||||
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 Annotation annotation;
|
||||
|
||||
RSApiMethodAnnotationVisitor(Annotation annotation)
|
||||
{
|
||||
super(Opcodes.ASM5);
|
||||
|
||||
this.annotation = annotation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(String name, Object value)
|
||||
{
|
||||
Element element = new SimpleElement(name, value);
|
||||
|
||||
annotation.addElement(element);
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Lucas <https://github.com/Lucwousin>
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is licensed under GPL3, see the complete license in
|
||||
* the LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
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;
|
||||
|
||||
public class RSApiMethodVisitor extends MethodVisitor
|
||||
{
|
||||
private final RSApiMethod method;
|
||||
|
||||
RSApiMethodVisitor(RSApiMethod method)
|
||||
{
|
||||
super(Opcodes.ASM5);
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
public AnnotationVisitor visitAnnotation(String descriptor, boolean visible)
|
||||
{
|
||||
Annotation annotation = new Annotation(new Type(descriptor));
|
||||
this.method.getAnnotations().addAnnotation(annotation);
|
||||
return new RSApiMethodAnnotationVisitor(annotation);
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ class DeobTarget
|
||||
|
||||
@ObfuscatedName("ob_foo3")
|
||||
@ObfuscatedSignature(
|
||||
signature = "(I)V",
|
||||
descriptor = "(I)V",
|
||||
garbageValue = "123"
|
||||
)
|
||||
private void foo3()
|
||||
@@ -108,14 +108,12 @@ abstract class Source
|
||||
}
|
||||
|
||||
@Copy("foo3")
|
||||
abstract void foo3();
|
||||
|
||||
@Replace("foo3")
|
||||
private void rl$foo3()
|
||||
private void copy$foo3()
|
||||
{
|
||||
System.out.println("replaced");
|
||||
System.out.println(foo4);
|
||||
foo3();
|
||||
copy$foo3();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user