Update injector for new Annotations

cleanup mixininjector kinda
change replaced methods to just ldc the garbage
make rsapi objects extend their respective visitors
This commit is contained in:
Lucwousin
2020-07-19 03:14:27 +02:00
parent e7d62c3c33
commit 3a66a43986
22 changed files with 165 additions and 233 deletions

View File

@@ -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()

View File

@@ -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));
}

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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,49 +138,12 @@ 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()))
{
final List<ClassFile> ret = getMixins(mixinClass);
builder.put(
() -> mixinClass,
ImmutableList.of(InjectUtil.getVanillaClassFromAnnotationString(inject, annotation))
(ret.size() > 1 ? mixinProvider(mixinClass) : () -> mixinClass),
ret
);
}
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());
}
}
}
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;
}
};
}
}

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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,25 +48,20 @@ 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);
}
}
}
RSApiMethod addMethod(String name, Signature sig, int access)
{
@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}