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:
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user