@@ -1,13 +1,13 @@
|
|||||||
language: java
|
language: java
|
||||||
sudo: false
|
sudo: false
|
||||||
dist: xenial
|
dist: trusty
|
||||||
cache:
|
cache:
|
||||||
directories:
|
directories:
|
||||||
- $HOME/.m2
|
- $HOME/.m2
|
||||||
jdk:
|
jdk:
|
||||||
- openjdk8
|
- oraclejdk8
|
||||||
- openjdk11
|
|
||||||
install: true
|
install: true
|
||||||
script: ./travis/build.sh
|
script: ./travis/build.sh
|
||||||
before_install:
|
before_install:
|
||||||
- chmod +x ./travis/build.sh
|
- chmod +x ./travis/build.sh
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import java.util.Properties;
|
|||||||
|
|
||||||
public class CacheProperties
|
public class CacheProperties
|
||||||
{
|
{
|
||||||
private static Properties getProperies() throws IOException
|
private static Properties getProperties() throws IOException
|
||||||
{
|
{
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
InputStream resourceAsStream = StoreLocation.class.getResourceAsStream("/cache.properties");
|
InputStream resourceAsStream = StoreLocation.class.getResourceAsStream("/cache.properties");
|
||||||
@@ -40,11 +40,11 @@ public class CacheProperties
|
|||||||
|
|
||||||
public static int getRsVersion() throws IOException
|
public static int getRsVersion() throws IOException
|
||||||
{
|
{
|
||||||
return Integer.parseInt(getProperies().getProperty("rs.version"));
|
return Integer.parseInt(getProperties().getProperty("rs.version"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getCacheVersion() throws IOException
|
public static int getCacheVersion() throws IOException
|
||||||
{
|
{
|
||||||
return Integer.parseInt(getProperies().getProperty("cache.version"));
|
return Integer.parseInt(getProperties().getProperty("cache.version"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ public class MapDumperTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
@Ignore
|
||||||
public void dunpJson() throws IOException
|
public void dumpJson() throws IOException
|
||||||
{
|
{
|
||||||
File base = StoreLocation.LOCATION,
|
File base = StoreLocation.LOCATION,
|
||||||
outDir = folder.newFolder();
|
outDir = folder.newFolder();
|
||||||
|
|||||||
@@ -203,9 +203,16 @@ public class Method
|
|||||||
return (accessFlags & ACC_STATIC) != 0;
|
return (accessFlags & ACC_STATIC) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStatic()
|
public void setStatic(boolean s)
|
||||||
{
|
{
|
||||||
accessFlags |= ACC_STATIC;
|
if (s)
|
||||||
|
{
|
||||||
|
accessFlags |= ACC_STATIC;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
accessFlags &= ~ACC_STATIC;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSynchronized()
|
public boolean isSynchronized()
|
||||||
|
|||||||
@@ -27,14 +27,10 @@ package net.runelite.deob;
|
|||||||
import com.google.common.base.Stopwatch;
|
import com.google.common.base.Stopwatch;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import net.runelite.asm.ClassFile;
|
|
||||||
import net.runelite.asm.ClassGroup;
|
import net.runelite.asm.ClassGroup;
|
||||||
import net.runelite.asm.Field;
|
|
||||||
import net.runelite.asm.Method;
|
|
||||||
import net.runelite.asm.Type;
|
|
||||||
import net.runelite.asm.attributes.Annotations;
|
|
||||||
import net.runelite.asm.execution.Execution;
|
import net.runelite.asm.execution.Execution;
|
||||||
import net.runelite.deob.deobfuscators.CastNull;
|
import net.runelite.deob.deobfuscators.CastNull;
|
||||||
|
import net.runelite.deob.deobfuscators.StaticShouldBeInstance;
|
||||||
import net.runelite.deob.deobfuscators.constparam.ConstantParameter;
|
import net.runelite.deob.deobfuscators.constparam.ConstantParameter;
|
||||||
import net.runelite.deob.deobfuscators.EnumDeobfuscator;
|
import net.runelite.deob.deobfuscators.EnumDeobfuscator;
|
||||||
import net.runelite.deob.deobfuscators.FieldInliner;
|
import net.runelite.deob.deobfuscators.FieldInliner;
|
||||||
@@ -85,85 +81,70 @@ public class Deob
|
|||||||
|
|
||||||
ClassGroup group = JarUtil.loadJar(new File(args[0]));
|
ClassGroup group = JarUtil.loadJar(new File(args[0]));
|
||||||
|
|
||||||
for (ClassFile f : group.getClasses())
|
if (args.length > 2 && args[2].equals("rl"))
|
||||||
{
|
{
|
||||||
f.getAnnotations().clearAnnotations();
|
run(group, new StaticShouldBeInstance());
|
||||||
for (Method m : f.getMethods())
|
|
||||||
{
|
|
||||||
Annotations an = m.getAnnotations();
|
|
||||||
an.clearAnnotations();
|
|
||||||
}
|
|
||||||
for (Field fi : f.getFields())
|
|
||||||
{
|
|
||||||
Annotations an = fi.getAnnotations();
|
|
||||||
if (an.find(new Type("Ljavax/inject/Inject;")) == null)
|
|
||||||
{
|
|
||||||
an.clearAnnotations();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logger.info("Class {}, field {} has inject", f.getClassName(), fi.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// remove except RuntimeException
|
||||||
|
run(group, new RuntimeExceptions());
|
||||||
|
|
||||||
// remove except RuntimeException
|
run(group, new ControlFlowDeobfuscator());
|
||||||
run(group, new RuntimeExceptions());
|
|
||||||
|
|
||||||
run(group, new ControlFlowDeobfuscator());
|
run(group, new RenameUnique());
|
||||||
|
|
||||||
run(group, new RenameUnique());
|
// remove unused methods - this leaves Code with no instructions,
|
||||||
|
// which is not valid, so unused methods is run after
|
||||||
|
run(group, new UnreachedCode());
|
||||||
|
run(group, new UnusedMethods());
|
||||||
|
|
||||||
// remove unused methods - this leaves Code with no instructions,
|
// remove illegal state exceptions, frees up some parameters
|
||||||
// which is not valid, so unused methods is run after
|
run(group, new IllegalStateExceptions());
|
||||||
run(group, new UnreachedCode());
|
|
||||||
run(group, new UnusedMethods());
|
|
||||||
|
|
||||||
// remove illegal state exceptions, frees up some parameters
|
// remove constant logically dead parameters
|
||||||
run(group, new IllegalStateExceptions());
|
run(group, new ConstantParameter());
|
||||||
|
|
||||||
// remove constant logically dead parameters
|
// remove unhit blocks
|
||||||
run(group, new ConstantParameter());
|
run(group, new UnreachedCode());
|
||||||
|
run(group, new UnusedMethods());
|
||||||
|
|
||||||
// remove unhit blocks
|
// remove unused parameters
|
||||||
run(group, new UnreachedCode());
|
run(group, new UnusedParameters());
|
||||||
run(group, new UnusedMethods());
|
|
||||||
|
|
||||||
// remove unused parameters
|
// remove unused fields
|
||||||
run(group, new UnusedParameters());
|
run(group, new UnusedFields());
|
||||||
|
|
||||||
// remove unused fields
|
run(group, new FieldInliner());
|
||||||
run(group, new UnusedFields());
|
|
||||||
|
|
||||||
run(group, new FieldInliner());
|
// order uses class name order for sorting fields/methods,
|
||||||
|
// so run it before removing classes below
|
||||||
|
run(group, new Order());
|
||||||
|
|
||||||
// order uses class name order for sorting fields/methods,
|
run(group, new UnusedClass());
|
||||||
// so run it before removing classes below
|
|
||||||
run(group, new Order());
|
|
||||||
|
|
||||||
run(group, new UnusedClass());
|
runMath(group);
|
||||||
|
|
||||||
runMath(group);
|
run(group, new ExprArgOrder());
|
||||||
|
|
||||||
run(group, new ExprArgOrder());
|
run(group, new Lvt());
|
||||||
|
|
||||||
run(group, new Lvt());
|
run(group, new CastNull());
|
||||||
|
|
||||||
run(group, new CastNull());
|
run(group, new EnumDeobfuscator());
|
||||||
|
|
||||||
run(group, new EnumDeobfuscator());
|
new OpcodesTransformer().transform(group);
|
||||||
|
//run(group, new PacketHandlerOrder());
|
||||||
|
//run(group, new PacketWriteDeobfuscator());
|
||||||
|
|
||||||
new OpcodesTransformer().transform(group);
|
run(group, new MenuActionDeobfuscator());
|
||||||
//run(group, new PacketHandlerOrder());
|
|
||||||
//run(group, new PacketWriteDeobfuscator());
|
|
||||||
|
|
||||||
run(group, new MenuActionDeobfuscator());
|
new GetPathTransformer().transform(group);
|
||||||
|
new ClientErrorTransformer().transform(group);
|
||||||
new GetPathTransformer().transform(group);
|
new ReflectionTransformer().transform(group);
|
||||||
new ClientErrorTransformer().transform(group);
|
new MaxMemoryTransformer().transform(group);
|
||||||
new ReflectionTransformer().transform(group);
|
//new RuneliteBufferTransformer().transform(group);
|
||||||
new MaxMemoryTransformer().transform(group);
|
}
|
||||||
//new RuneliteBufferTransformer().transform(group);
|
|
||||||
|
|
||||||
JarUtil.saveJar(group, new File(args[1]));
|
JarUtil.saveJar(group, new File(args[1]));
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,171 @@
|
|||||||
|
package net.runelite.deob.deobfuscators;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ListIterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import net.runelite.asm.ClassFile;
|
||||||
|
import net.runelite.asm.ClassGroup;
|
||||||
|
import net.runelite.asm.Field;
|
||||||
|
import net.runelite.asm.Type;
|
||||||
|
import net.runelite.asm.attributes.Annotations;
|
||||||
|
import net.runelite.asm.attributes.Code;
|
||||||
|
import net.runelite.asm.attributes.code.Instruction;
|
||||||
|
import net.runelite.asm.attributes.code.Instructions;
|
||||||
|
import net.runelite.asm.attributes.code.instruction.types.ReturnInstruction;
|
||||||
|
import net.runelite.asm.attributes.code.instructions.InvokeStatic;
|
||||||
|
import net.runelite.asm.attributes.code.instructions.InvokeVirtual;
|
||||||
|
import net.runelite.asm.pool.Method;
|
||||||
|
import net.runelite.asm.signature.Signature;
|
||||||
|
import net.runelite.deob.Deobfuscator;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class StaticShouldBeInstance implements Deobfuscator
|
||||||
|
{
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(StaticShouldBeInstance.class);
|
||||||
|
private static Map<Method, Method> methods = new HashMap<>();
|
||||||
|
|
||||||
|
public void run(ClassGroup group)
|
||||||
|
{
|
||||||
|
int replacedCalls = 0;
|
||||||
|
int removedInstructions = 0;
|
||||||
|
int removedMethods = 0;
|
||||||
|
int removedAnnotations = 0;
|
||||||
|
List<net.runelite.asm.Method> obfuscatedMethods = new ArrayList<>();
|
||||||
|
|
||||||
|
for (ClassFile cf : group.getClasses())
|
||||||
|
{
|
||||||
|
// Remove unused annotations
|
||||||
|
Annotations a = cf.getAnnotations();
|
||||||
|
removedAnnotations += a.getAnnotations().size();
|
||||||
|
a.clearAnnotations();
|
||||||
|
|
||||||
|
Type type = new Type('L' + cf.getClassName() + ';');
|
||||||
|
obfuscatedMethods.clear();
|
||||||
|
|
||||||
|
for (net.runelite.asm.Method m : cf.getMethods())
|
||||||
|
{
|
||||||
|
// Remove unused annotations
|
||||||
|
a = m.getAnnotations();
|
||||||
|
removedAnnotations += a.size();
|
||||||
|
a.clearAnnotations();
|
||||||
|
|
||||||
|
if (m.isStatic() && m.getCode() != null)
|
||||||
|
{
|
||||||
|
if (checkIfObf(m, type, cf))
|
||||||
|
{
|
||||||
|
removedMethods++;
|
||||||
|
obfuscatedMethods.add(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (net.runelite.asm.Method m : obfuscatedMethods)
|
||||||
|
{
|
||||||
|
Signature sig = m.getDescriptor();
|
||||||
|
Signature.Builder builder = new Signature.Builder();
|
||||||
|
builder.setReturnType(sig.getReturnValue());
|
||||||
|
if (sig.getArguments().size() > 1)
|
||||||
|
{
|
||||||
|
builder.addArguments(sig.getArguments().subList(1, sig.getArguments().size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Signature toFind = builder.build();
|
||||||
|
|
||||||
|
net.runelite.asm.Method notStatic = cf.findMethod(m.getName(), toFind);
|
||||||
|
net.runelite.asm.pool.Method oldPool = m.getPoolMethod();
|
||||||
|
cf.removeMethod(notStatic);
|
||||||
|
|
||||||
|
m.setDescriptor(toFind);
|
||||||
|
m.setStatic(false);
|
||||||
|
Code c = m.getCode();
|
||||||
|
Instructions ins = c.getInstructions();
|
||||||
|
int startLength = ins.getInstructions().size();
|
||||||
|
ListIterator<Instruction> it = ins.getInstructions().listIterator();
|
||||||
|
assert it.hasNext();
|
||||||
|
Instruction i = it.next();
|
||||||
|
while (!(i instanceof ReturnInstruction))
|
||||||
|
{
|
||||||
|
it.remove();
|
||||||
|
i = it.next();
|
||||||
|
}
|
||||||
|
it.remove();
|
||||||
|
net.runelite.asm.pool.Method newPool = m.getPoolMethod();
|
||||||
|
|
||||||
|
methods.put(oldPool, newPool);
|
||||||
|
|
||||||
|
removedInstructions += startLength - ins.getInstructions().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Field fi : cf.getFields())
|
||||||
|
{
|
||||||
|
a = fi.getAnnotations();
|
||||||
|
if (a.find(new Type("Ljavax/inject/Inject;")) == null)
|
||||||
|
{
|
||||||
|
removedAnnotations += a.size();
|
||||||
|
a.clearAnnotations();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.info("Class {}, field {} has inject", cf.getClassName(), fi.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ClassFile cf : group.getClasses())
|
||||||
|
{
|
||||||
|
for (net.runelite.asm.Method m : cf.getMethods())
|
||||||
|
{
|
||||||
|
if (m.getCode() == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Instructions ins = m.getCode().getInstructions();
|
||||||
|
List<Instruction> instructions = ins.getInstructions();
|
||||||
|
for (int i1 = 0, instructionsSize = instructions.size(); i1 < instructionsSize; i1++)
|
||||||
|
{
|
||||||
|
Instruction i = instructions.get(i1);
|
||||||
|
if (!(i instanceof InvokeStatic))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (methods.containsKey(((InvokeStatic) i).getMethod()))
|
||||||
|
{
|
||||||
|
InvokeVirtual invoke = new InvokeVirtual(ins, methods.get(((InvokeStatic) i).getMethod()));
|
||||||
|
ins.replace(i, invoke);
|
||||||
|
replacedCalls++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("Made {} methods not static, removed {} instructions, replaced {} invokes, and removed {} annotations", removedMethods, removedInstructions, replacedCalls, removedAnnotations);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean checkIfObf(net.runelite.asm.Method m, Type type, ClassFile cf)
|
||||||
|
{
|
||||||
|
Signature sig = m.getDescriptor();
|
||||||
|
if (sig.getArguments().size() < 1 || !sig.getTypeOfArg(0).equals(type))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Signature.Builder builder = new Signature.Builder();
|
||||||
|
builder.setReturnType(sig.getReturnValue());
|
||||||
|
if (sig.getArguments().size() > 1)
|
||||||
|
{
|
||||||
|
builder.addArguments(sig.getArguments().subList(1, sig.getArguments().size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Signature toFind = builder.build();
|
||||||
|
|
||||||
|
net.runelite.asm.Method notStatic = cf.findMethod(m.getName(), toFind);
|
||||||
|
|
||||||
|
return notStatic != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -60,7 +60,7 @@ public class OpcodesTransformer implements Transformer
|
|||||||
if (clinit == null)
|
if (clinit == null)
|
||||||
{
|
{
|
||||||
clinit = new Method(runeliteOpcodes, "<clinit>", new Signature("()V"));
|
clinit = new Method(runeliteOpcodes, "<clinit>", new Signature("()V"));
|
||||||
clinit.setStatic();
|
clinit.setStatic(true);
|
||||||
Code code = new Code(clinit);
|
Code code = new Code(clinit);
|
||||||
code.setMaxStack(1);
|
code.setMaxStack(1);
|
||||||
clinit.setCode(code);
|
clinit.setCode(code);
|
||||||
|
|||||||
@@ -26,19 +26,24 @@ package net.runelite.deob.updater;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
import net.runelite.asm.ClassGroup;
|
import net.runelite.asm.ClassGroup;
|
||||||
|
import net.runelite.asm.Field;
|
||||||
|
import net.runelite.asm.Method;
|
||||||
|
import net.runelite.deob.deobfuscators.Renamer;
|
||||||
import net.runelite.deob.deobfuscators.mapping.AnnotationIntegrityChecker;
|
import net.runelite.deob.deobfuscators.mapping.AnnotationIntegrityChecker;
|
||||||
import net.runelite.deob.deobfuscators.mapping.AnnotationMapper;
|
import net.runelite.deob.deobfuscators.mapping.AnnotationMapper;
|
||||||
import net.runelite.deob.deobfuscators.mapping.Mapper;
|
import net.runelite.deob.deobfuscators.mapping.Mapper;
|
||||||
import net.runelite.deob.deobfuscators.mapping.ParallelExecutorMapping;
|
import net.runelite.deob.deobfuscators.mapping.ParallelExecutorMapping;
|
||||||
import net.runelite.deob.util.JarUtil;
|
import net.runelite.deob.util.JarUtil;
|
||||||
|
import net.runelite.deob.util.NameMappings;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class UpdateMappings
|
public class UpdateMappings
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(UpdateMappings.class);
|
private static final Logger logger = LoggerFactory.getLogger(UpdateMappings.class);
|
||||||
|
private static boolean renameRL = true;
|
||||||
private final ClassGroup group1, group2;
|
private final ClassGroup group1, group2;
|
||||||
|
|
||||||
public UpdateMappings(ClassGroup group1, ClassGroup group2)
|
public UpdateMappings(ClassGroup group1, ClassGroup group2)
|
||||||
@@ -74,6 +79,32 @@ public class UpdateMappings
|
|||||||
pr.run();
|
pr.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateRL()
|
||||||
|
{
|
||||||
|
Mapper mapper = new Mapper(group1, group2);
|
||||||
|
mapper.run();
|
||||||
|
ParallelExecutorMapping mapping = mapper.getMapping();
|
||||||
|
NameMappings names = new NameMappings();
|
||||||
|
|
||||||
|
for (Map.Entry<Object, Object> e : mapping.getMap().entrySet())
|
||||||
|
{
|
||||||
|
Object k = e.getKey();
|
||||||
|
Object v = e.getValue();
|
||||||
|
|
||||||
|
if (k instanceof Field)
|
||||||
|
{
|
||||||
|
names.map(((Field) v).getPoolField(), ((Field) k).getName());
|
||||||
|
}
|
||||||
|
else if (k instanceof Method)
|
||||||
|
{
|
||||||
|
names.map(((Method) v).getPoolMethod(), ((Method) k).getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Renamer renamer = new Renamer(names);
|
||||||
|
renamer.run(group2);
|
||||||
|
}
|
||||||
|
|
||||||
public void save(File out) throws IOException
|
public void save(File out) throws IOException
|
||||||
{
|
{
|
||||||
JarUtil.saveJar(group2, out);
|
JarUtil.saveJar(group2, out);
|
||||||
@@ -90,7 +121,14 @@ public class UpdateMappings
|
|||||||
JarUtil.loadJar(new File(args[0])),
|
JarUtil.loadJar(new File(args[0])),
|
||||||
JarUtil.loadJar(new File(args[1]))
|
JarUtil.loadJar(new File(args[1]))
|
||||||
);
|
);
|
||||||
u.update();
|
if (renameRL)
|
||||||
|
{
|
||||||
|
u.updateRL();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u.update();
|
||||||
|
}
|
||||||
u.save(new File(args[2]));
|
u.save(new File(args[2]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public class ClassGroupFactory
|
|||||||
private static void addVoidMethod(ClassFile cf, String name)
|
private static void addVoidMethod(ClassFile cf, String name)
|
||||||
{
|
{
|
||||||
Method method = new Method(cf, name, new Signature("()V"));
|
Method method = new Method(cf, name, new Signature("()V"));
|
||||||
method.setStatic();
|
method.setStatic(true);
|
||||||
cf.addMethod(method);
|
cf.addMethod(method);
|
||||||
|
|
||||||
Code code = new Code(method);
|
Code code = new Code(method);
|
||||||
@@ -63,7 +63,7 @@ public class ClassGroupFactory
|
|||||||
cf.addField(field);
|
cf.addField(field);
|
||||||
|
|
||||||
Method method = new Method(cf, "func", new Signature("()V"));
|
Method method = new Method(cf, "func", new Signature("()V"));
|
||||||
method.setStatic();
|
method.setStatic(true);
|
||||||
cf.addMethod(method);
|
cf.addMethod(method);
|
||||||
|
|
||||||
Code code = new Code(method);
|
Code code = new Code(method);
|
||||||
@@ -71,7 +71,7 @@ public class ClassGroupFactory
|
|||||||
|
|
||||||
{
|
{
|
||||||
method = new Method(cf, "func2", new Signature("(III)V"));
|
method = new Method(cf, "func2", new Signature("(III)V"));
|
||||||
method.setStatic();
|
method.setStatic(true);
|
||||||
cf.addMethod(method);
|
cf.addMethod(method);
|
||||||
|
|
||||||
code = new Code(method);
|
code = new Code(method);
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ public class UpdateMappingsTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Ignore
|
||||||
public void testRun() throws IOException
|
public void testRun() throws IOException
|
||||||
{
|
{
|
||||||
File client = new File(properties.getRsClient());
|
File client = new File(properties.getRsClient());
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ import net.runelite.deob.util.JarUtil;
|
|||||||
import net.runelite.deob.util.NameMappings;
|
import net.runelite.deob.util.NameMappings;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.Ignore;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.TemporaryFolder;
|
import org.junit.rules.TemporaryFolder;
|
||||||
@@ -87,12 +88,13 @@ public class HookImporter
|
|||||||
@After
|
@After
|
||||||
public void after() throws IOException
|
public void after() throws IOException
|
||||||
{
|
{
|
||||||
File out = new File("C:/Users/Lucas/Desktop/client.jar");
|
File out = folder.newFile("client.jar");
|
||||||
JarUtil.saveJar(group, out);
|
JarUtil.saveJar(group, out);
|
||||||
logger.info("Wrote to {}", out);
|
logger.info("Wrote to {}", out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Ignore
|
||||||
public void importHooks()
|
public void importHooks()
|
||||||
{
|
{
|
||||||
int classes = 0, fields = 0, methods = 0, access = 0;
|
int classes = 0, fields = 0, methods = 0, access = 0;
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
rs.client=C:/Users/Lucas/Desktop/gamepack180_deob.jar
|
rs.client=${net.runelite.rs:rs-client:jar}
|
||||||
rs.version=180
|
rs.version=180
|
||||||
vanilla.client=${net.runelite.rs:vanilla:jar}
|
vanilla.client=${net.runelite.rs:vanilla:jar}
|
||||||
@@ -96,7 +96,7 @@ public class AccountClient
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean sesssionCheck()
|
public boolean sessionCheck()
|
||||||
{
|
{
|
||||||
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder()
|
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder()
|
||||||
.addPathSegment("account")
|
.addPathSegment("account")
|
||||||
|
|||||||
@@ -23,7 +23,8 @@
|
|||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
-->
|
-->
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
@@ -58,7 +59,7 @@
|
|||||||
<artifactId>runescape-api</artifactId>
|
<artifactId>runescape-api</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.maven</groupId>
|
<groupId>org.apache.maven</groupId>
|
||||||
<artifactId>maven-plugin-api</artifactId>
|
<artifactId>maven-plugin-api</artifactId>
|
||||||
|
|||||||
@@ -47,23 +47,21 @@ import net.runelite.deob.DeobAnnotations;
|
|||||||
import net.runelite.deob.deobfuscators.arithmetic.DMath;
|
import net.runelite.deob.deobfuscators.arithmetic.DMath;
|
||||||
import net.runelite.injector.raw.ClearColorBuffer;
|
import net.runelite.injector.raw.ClearColorBuffer;
|
||||||
import net.runelite.injector.raw.DrawAfterWidgets;
|
import net.runelite.injector.raw.DrawAfterWidgets;
|
||||||
|
import net.runelite.injector.raw.DrawMenu;
|
||||||
import net.runelite.injector.raw.RasterizerHook;
|
import net.runelite.injector.raw.RasterizerHook;
|
||||||
import net.runelite.injector.raw.RenderDraw;
|
import net.runelite.injector.raw.RenderDraw;
|
||||||
import net.runelite.injector.raw.ScriptVM;
|
import net.runelite.injector.raw.ScriptVM;
|
||||||
import net.runelite.mapping.Import;
|
import net.runelite.mapping.Import;
|
||||||
|
import net.runelite.rs.api.RSClient;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import net.runelite.rs.api.RSClient;
|
|
||||||
|
|
||||||
public class Inject
|
public class Inject
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(Inject.class);
|
|
||||||
|
|
||||||
public static final java.lang.Class<?> CLIENT_CLASS = RSClient.class;
|
public static final java.lang.Class<?> CLIENT_CLASS = RSClient.class;
|
||||||
|
|
||||||
public static final String API_PACKAGE_BASE = "net.runelite.rs.api.RS";
|
public static final String API_PACKAGE_BASE = "net.runelite.rs.api.RS";
|
||||||
public static final String RL_API_PACKAGE_BASE = "net.runelite.api.";
|
public static final String RL_API_PACKAGE_BASE = "net.runelite.api.";
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(Inject.class);
|
||||||
private final InjectHookMethod hookMethod = new InjectHookMethod(this);
|
private final InjectHookMethod hookMethod = new InjectHookMethod(this);
|
||||||
|
|
||||||
private final InjectGetter getters = new InjectGetter(this);
|
private final InjectGetter getters = new InjectGetter(this);
|
||||||
@@ -71,6 +69,7 @@ public class Inject
|
|||||||
private final InjectInvoker invokes = new InjectInvoker(this);
|
private final InjectInvoker invokes = new InjectInvoker(this);
|
||||||
private final InjectConstruct construct = new InjectConstruct(this);
|
private final InjectConstruct construct = new InjectConstruct(this);
|
||||||
|
|
||||||
|
private final DrawMenu drawMenu = new DrawMenu(this);
|
||||||
private final RasterizerHook rasterizerHook = new RasterizerHook(this);
|
private final RasterizerHook rasterizerHook = new RasterizerHook(this);
|
||||||
private final MixinInjector mixinInjector = new MixinInjector(this);
|
private final MixinInjector mixinInjector = new MixinInjector(this);
|
||||||
private final DrawAfterWidgets drawAfterWidgets = new DrawAfterWidgets(this);
|
private final DrawAfterWidgets drawAfterWidgets = new DrawAfterWidgets(this);
|
||||||
@@ -87,34 +86,6 @@ public class Inject
|
|||||||
this.vanilla = vanilla;
|
this.vanilla = vanilla;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type getFieldType(Field f)
|
|
||||||
{
|
|
||||||
Type type = f.getType();
|
|
||||||
|
|
||||||
Annotation obfSignature = f.getAnnotations().find(DeobAnnotations.OBFUSCATED_SIGNATURE);
|
|
||||||
if (obfSignature != null)
|
|
||||||
{
|
|
||||||
//Annotation exists. Type was updated by us during deobfuscation
|
|
||||||
type = DeobAnnotations.getObfuscatedType(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Signature getMethodSignature(Method m)
|
|
||||||
{
|
|
||||||
Signature signature = m.getDescriptor();
|
|
||||||
|
|
||||||
Annotation obfSignature = m.getAnnotations().find(DeobAnnotations.OBFUSCATED_SIGNATURE);
|
|
||||||
if (obfSignature != null)
|
|
||||||
{
|
|
||||||
//Annotation exists. Signature was updated by us during deobfuscation
|
|
||||||
signature = DeobAnnotations.getObfuscatedSignature(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
return signature;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a java.lang.Class to a Type
|
* Convert a java.lang.Class to a Type
|
||||||
*
|
*
|
||||||
@@ -173,6 +144,34 @@ public class Inject
|
|||||||
return Type.getType("L" + c.getName().replace('.', '/') + ";", dimms);
|
return Type.getType("L" + c.getName().replace('.', '/') + ";", dimms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Type getFieldType(Field f)
|
||||||
|
{
|
||||||
|
Type type = f.getType();
|
||||||
|
|
||||||
|
Annotation obfSignature = f.getAnnotations().find(DeobAnnotations.OBFUSCATED_SIGNATURE);
|
||||||
|
if (obfSignature != null)
|
||||||
|
{
|
||||||
|
//Annotation exists. Type was updated by us during deobfuscation
|
||||||
|
type = DeobAnnotations.getObfuscatedType(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Signature getMethodSignature(Method m)
|
||||||
|
{
|
||||||
|
Signature signature = m.getDescriptor();
|
||||||
|
|
||||||
|
Annotation obfSignature = m.getAnnotations().find(DeobAnnotations.OBFUSCATED_SIGNATURE);
|
||||||
|
if (obfSignature != null)
|
||||||
|
{
|
||||||
|
//Annotation exists. Signature was updated by us during deobfuscation
|
||||||
|
signature = DeobAnnotations.getObfuscatedSignature(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
return signature;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build a Signature from a java method
|
* Build a Signature from a java method
|
||||||
*
|
*
|
||||||
@@ -284,7 +283,7 @@ public class Inject
|
|||||||
assert !f.isStatic();
|
assert !f.isStatic();
|
||||||
|
|
||||||
// non static field exported on non exported interface
|
// non static field exported on non exported interface
|
||||||
// logger.debug("Non static exported field {} on non exported interface", exportedName);
|
// logger.debug("Non static exported field {} on non exported interface", exportedName);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,7 +302,7 @@ public class Inject
|
|||||||
apiMethod = findImportMethodOnApi(targetApiClass, exportedName, false);
|
apiMethod = findImportMethodOnApi(targetApiClass, exportedName, false);
|
||||||
if (apiMethod == null)
|
if (apiMethod == null)
|
||||||
{
|
{
|
||||||
// logger.debug("Unable to find import method on api class {} with imported name {}, not injecting getter", targetApiClass, exportedName);
|
//logger.debug("Unable to find import method on api class {} with imported name {}, not injecting getter", targetApiClass, exportedName);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,7 +324,7 @@ public class Inject
|
|||||||
invokes.process(m, other, implementingClass);
|
invokes.process(m, other, implementingClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("Injected {} getters, {} setters, {} invokers",
|
logger.info("Injected {} getters, {} setters, {} invokers",
|
||||||
getters.getInjectedGetters(),
|
getters.getInjectedGetters(),
|
||||||
setters.getInjectedSetters(), invokes.getInjectedInvokers());
|
setters.getInjectedSetters(), invokes.getInjectedInvokers());
|
||||||
@@ -334,6 +333,7 @@ public class Inject
|
|||||||
scriptVM.inject();
|
scriptVM.inject();
|
||||||
clearColorBuffer.inject();
|
clearColorBuffer.inject();
|
||||||
renderDraw.inject();
|
renderDraw.inject();
|
||||||
|
drawMenu.inject();
|
||||||
}
|
}
|
||||||
|
|
||||||
private java.lang.Class injectInterface(ClassFile cf, ClassFile other)
|
private java.lang.Class injectInterface(ClassFile cf, ClassFile other)
|
||||||
@@ -514,10 +514,10 @@ public class Inject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (rlApiType == null)
|
// if (rlApiType == null)
|
||||||
// {
|
// {
|
||||||
// throw new InjectionException("RS API type " + rsApiType + " does not extend RL API interface");
|
// throw new InjectionException("RS API type " + rsApiType + " does not extend RL API interface");
|
||||||
// }
|
// }
|
||||||
|
|
||||||
final java.lang.Class<?> finalType = rlApiType == null ? rsApiType : rlApiType;
|
final java.lang.Class<?> finalType = rlApiType == null ? rsApiType : rlApiType;
|
||||||
|
|
||||||
@@ -539,7 +539,7 @@ public class Inject
|
|||||||
|
|
||||||
return Type.getType("L" + type.getInternalName().substring(API_PACKAGE_BASE.length()) + ";", type.getDimensions());
|
return Type.getType("L" + type.getInternalName().substring(API_PACKAGE_BASE.length()) + ";", type.getDimensions());
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassFile findVanillaForInterface(java.lang.Class<?> clazz)
|
ClassFile findVanillaForInterface(java.lang.Class<?> clazz)
|
||||||
{
|
{
|
||||||
String className = clazz.getName().replace('.', '/');
|
String className = clazz.getName().replace('.', '/');
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class InjectConstruct
|
|||||||
|
|
||||||
private final Inject inject;
|
private final Inject inject;
|
||||||
|
|
||||||
public InjectConstruct(Inject inject)
|
InjectConstruct(Inject inject)
|
||||||
{
|
{
|
||||||
this.inject = inject;
|
this.inject = inject;
|
||||||
}
|
}
|
||||||
@@ -99,7 +99,7 @@ public class InjectConstruct
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void injectConstruct(ClassFile targetClass, java.lang.reflect.Method apiMethod) throws InjectionException
|
void injectConstruct(ClassFile targetClass, java.lang.reflect.Method apiMethod) throws InjectionException
|
||||||
{
|
{
|
||||||
logger.info("Injecting construct for {}", apiMethod);
|
logger.info("Injecting construct for {}", apiMethod);
|
||||||
|
|
||||||
@@ -115,19 +115,19 @@ public class InjectConstruct
|
|||||||
Signature sig = inject.javaMethodToSignature(apiMethod);
|
Signature sig = inject.javaMethodToSignature(apiMethod);
|
||||||
|
|
||||||
Signature constructorSig = new Signature.Builder()
|
Signature constructorSig = new Signature.Builder()
|
||||||
.addArguments(Stream.of(apiMethod.getParameterTypes())
|
.addArguments(Stream.of(apiMethod.getParameterTypes())
|
||||||
.map(arg ->
|
.map(arg ->
|
||||||
{
|
{
|
||||||
ClassFile vanilla = inject.findVanillaForInterface(arg);
|
ClassFile vanilla = inject.findVanillaForInterface(arg);
|
||||||
if (vanilla != null)
|
if (vanilla != null)
|
||||||
{
|
{
|
||||||
return new Type("L" + vanilla.getName() + ";");
|
return new Type("L" + vanilla.getName() + ";");
|
||||||
}
|
}
|
||||||
return Inject.classToType(arg);
|
return Inject.classToType(arg);
|
||||||
})
|
})
|
||||||
.collect(Collectors.toList()))
|
.collect(Collectors.toList()))
|
||||||
.setReturnType(Type.VOID)
|
.setReturnType(Type.VOID)
|
||||||
.build();
|
.build();
|
||||||
Method vanillaConstructor = vanillaClass.findMethod("<init>", constructorSig);
|
Method vanillaConstructor = vanillaClass.findMethod("<init>", constructorSig);
|
||||||
if (vanillaConstructor == null)
|
if (vanillaConstructor == null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -44,20 +44,20 @@ import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class InjectGetter
|
class InjectGetter
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(InjectGetter.class);
|
private static final Logger logger = LoggerFactory.getLogger(InjectGetter.class);
|
||||||
|
|
||||||
private final Inject inject;
|
private final Inject inject;
|
||||||
|
|
||||||
private int injectedGetters;
|
private int injectedGetters;
|
||||||
|
|
||||||
public InjectGetter(Inject inject)
|
InjectGetter(Inject inject)
|
||||||
{
|
{
|
||||||
this.inject = inject;
|
this.inject = inject;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void injectGetter(ClassFile clazz, java.lang.reflect.Method method, Field field, Number getter)
|
void injectGetter(ClassFile clazz, java.lang.reflect.Method method, Field field, Number getter)
|
||||||
{
|
{
|
||||||
// clazz = class file we're injecting the method into.
|
// clazz = class file we're injecting the method into.
|
||||||
// method = api method (java reflect) that we're overriding
|
// method = api method (java reflect) that we're overriding
|
||||||
@@ -148,7 +148,7 @@ public class InjectGetter
|
|||||||
++injectedGetters;
|
++injectedGetters;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getInjectedGetters()
|
int getInjectedGetters()
|
||||||
{
|
{
|
||||||
return injectedGetters;
|
return injectedGetters;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,9 +41,11 @@ import net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction;
|
|||||||
import net.runelite.asm.attributes.code.instructions.ArrayStore;
|
import net.runelite.asm.attributes.code.instructions.ArrayStore;
|
||||||
import net.runelite.asm.attributes.code.instructions.CheckCast;
|
import net.runelite.asm.attributes.code.instructions.CheckCast;
|
||||||
import net.runelite.asm.attributes.code.instructions.Dup;
|
import net.runelite.asm.attributes.code.instructions.Dup;
|
||||||
|
import net.runelite.asm.attributes.code.instructions.IMul;
|
||||||
import net.runelite.asm.attributes.code.instructions.InvokeStatic;
|
import net.runelite.asm.attributes.code.instructions.InvokeStatic;
|
||||||
import net.runelite.asm.attributes.code.instructions.InvokeVirtual;
|
import net.runelite.asm.attributes.code.instructions.InvokeVirtual;
|
||||||
import net.runelite.asm.attributes.code.instructions.LDC;
|
import net.runelite.asm.attributes.code.instructions.LDC;
|
||||||
|
import net.runelite.asm.attributes.code.instructions.LMul;
|
||||||
import net.runelite.asm.attributes.code.instructions.PutField;
|
import net.runelite.asm.attributes.code.instructions.PutField;
|
||||||
import net.runelite.asm.attributes.code.instructions.Swap;
|
import net.runelite.asm.attributes.code.instructions.Swap;
|
||||||
import net.runelite.asm.execution.Execution;
|
import net.runelite.asm.execution.Execution;
|
||||||
@@ -53,28 +55,16 @@ import net.runelite.asm.signature.Signature;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class InjectHook
|
class InjectHook
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(InjectHook.class);
|
private static final Logger logger = LoggerFactory.getLogger(InjectHook.class);
|
||||||
|
|
||||||
static class HookInfo
|
|
||||||
{
|
|
||||||
String fieldName;
|
|
||||||
String clazz;
|
|
||||||
Method method;
|
|
||||||
boolean before;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String HOOK_METHOD_SIGNATURE = "(I)V";
|
private static final String HOOK_METHOD_SIGNATURE = "(I)V";
|
||||||
|
|
||||||
private static final String CLINIT = "<clinit>";
|
private static final String CLINIT = "<clinit>";
|
||||||
|
|
||||||
private final Inject inject;
|
private final Inject inject;
|
||||||
private final Map<Field, HookInfo> hooked = new HashMap<>();
|
private final Map<Field, HookInfo> hooked = new HashMap<>();
|
||||||
|
|
||||||
private int injectedHooks;
|
private int injectedHooks;
|
||||||
|
|
||||||
public InjectHook(Inject inject)
|
InjectHook(Inject inject)
|
||||||
{
|
{
|
||||||
this.inject = inject;
|
this.inject = inject;
|
||||||
}
|
}
|
||||||
@@ -84,7 +74,7 @@ public class InjectHook
|
|||||||
hooked.put(field, hookInfo);
|
hooked.put(field, hookInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run()
|
void run()
|
||||||
{
|
{
|
||||||
Execution e = new Execution(inject.getVanilla());
|
Execution e = new Execution(inject.getVanilla());
|
||||||
e.populateInitialMethods();
|
e.populateInitialMethods();
|
||||||
@@ -139,8 +129,7 @@ public class InjectHook
|
|||||||
StackContext objectStackContext = null;
|
StackContext objectStackContext = null;
|
||||||
if (sfi instanceof PutField)
|
if (sfi instanceof PutField)
|
||||||
{
|
{
|
||||||
StackContext objectStack = ic.getPops().get(1); // Object being set on
|
objectStackContext = ic.getPops().get(1);
|
||||||
objectStackContext = objectStack;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int idx = ins.getInstructions().indexOf(sfi);
|
int idx = ins.getInstructions().indexOf(sfi);
|
||||||
@@ -154,7 +143,7 @@ public class InjectHook
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// idx + 1 to insert after the set
|
// idx + 1 to insert after the set
|
||||||
injectCallback(ins, idx + 1, hookInfo, null, objectStackContext);
|
injectCallback(ins, idx + 1, hookInfo, null, objectStackContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,8 +205,7 @@ public class InjectHook
|
|||||||
StackContext objectStackContext = null;
|
StackContext objectStackContext = null;
|
||||||
if (arrayReferencePushed.getInstruction().getType() == InstructionType.GETFIELD)
|
if (arrayReferencePushed.getInstruction().getType() == InstructionType.GETFIELD)
|
||||||
{
|
{
|
||||||
StackContext objectReference = arrayReferencePushed.getPops().get(0);
|
objectStackContext = arrayReferencePushed.getPops().get(0);
|
||||||
objectStackContext = objectReference;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// inject hook after 'i'
|
// inject hook after 'i'
|
||||||
@@ -262,6 +250,21 @@ public class InjectHook
|
|||||||
ins.getInstructions().add(idx++, new Dup(ins)); // dup value
|
ins.getInstructions().add(idx++, new Dup(ins)); // dup value
|
||||||
idx = recursivelyPush(ins, idx, object);
|
idx = recursivelyPush(ins, idx, object);
|
||||||
ins.getInstructions().add(idx++, new Swap(ins));
|
ins.getInstructions().add(idx++, new Swap(ins));
|
||||||
|
if (hookInfo.getter != null)
|
||||||
|
{
|
||||||
|
assert hookInfo.getter instanceof Integer || hookInfo.getter instanceof Long;
|
||||||
|
|
||||||
|
if (hookInfo.getter instanceof Integer)
|
||||||
|
{
|
||||||
|
ins.getInstructions().add(idx++, new LDC(ins, (int) hookInfo.getter));
|
||||||
|
ins.getInstructions().add(idx++, new IMul(ins));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ins.getInstructions().add(idx++, new LDC(ins, (long) hookInfo.getter));
|
||||||
|
ins.getInstructions().add(idx++, new LMul(ins));
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!value.type.equals(methodArgumentType))
|
if (!value.type.equals(methodArgumentType))
|
||||||
{
|
{
|
||||||
CheckCast checkCast = new CheckCast(ins);
|
CheckCast checkCast = new CheckCast(ins);
|
||||||
@@ -377,8 +380,17 @@ public class InjectHook
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getInjectedHooks()
|
int getInjectedHooks()
|
||||||
{
|
{
|
||||||
return injectedHooks;
|
return injectedHooks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class HookInfo
|
||||||
|
{
|
||||||
|
String fieldName;
|
||||||
|
String clazz;
|
||||||
|
Method method;
|
||||||
|
boolean before;
|
||||||
|
Number getter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,18 +49,16 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
public class InjectHookMethod
|
public class InjectHookMethod
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(InjectHookMethod.class);
|
|
||||||
|
|
||||||
public static final String HOOKS = "net/runelite/client/callback/Hooks";
|
public static final String HOOKS = "net/runelite/client/callback/Hooks";
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(InjectHookMethod.class);
|
||||||
private final Inject inject;
|
private final Inject inject;
|
||||||
|
|
||||||
public InjectHookMethod(Inject inject)
|
InjectHookMethod(Inject inject)
|
||||||
{
|
{
|
||||||
this.inject = inject;
|
this.inject = inject;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void process(Method method) throws InjectionException
|
void process(Method method) throws InjectionException
|
||||||
{
|
{
|
||||||
Annotations an = method.getAnnotations();
|
Annotations an = method.getAnnotations();
|
||||||
if (an == null)
|
if (an == null)
|
||||||
@@ -115,7 +113,7 @@ public class InjectHookMethod
|
|||||||
Instructions instructions = vanillaMethod.getCode().getInstructions();
|
Instructions instructions = vanillaMethod.getCode().getInstructions();
|
||||||
|
|
||||||
Signature.Builder builder = new Signature.Builder()
|
Signature.Builder builder = new Signature.Builder()
|
||||||
.setReturnType(Type.VOID); // Hooks always return void
|
.setReturnType(Type.VOID); // Hooks always return void
|
||||||
|
|
||||||
for (Type type : deobMethod.getDescriptor().getArguments())
|
for (Type type : deobMethod.getDescriptor().getArguments())
|
||||||
{
|
{
|
||||||
@@ -164,11 +162,11 @@ public class InjectHookMethod
|
|||||||
{
|
{
|
||||||
// Invoke callback
|
// Invoke callback
|
||||||
invoke = new InvokeStatic(instructions,
|
invoke = new InvokeStatic(instructions,
|
||||||
new net.runelite.asm.pool.Method(
|
new net.runelite.asm.pool.Method(
|
||||||
new net.runelite.asm.pool.Class(HOOKS),
|
new net.runelite.asm.pool.Class(HOOKS),
|
||||||
hookName,
|
hookName,
|
||||||
signature
|
signature
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -179,11 +177,11 @@ public class InjectHookMethod
|
|||||||
if (vanillaMethod.isStatic())
|
if (vanillaMethod.isStatic())
|
||||||
{
|
{
|
||||||
invoke = new InvokeStatic(instructions,
|
invoke = new InvokeStatic(instructions,
|
||||||
new net.runelite.asm.pool.Method(
|
new net.runelite.asm.pool.Method(
|
||||||
new net.runelite.asm.pool.Class("client"), // Static methods are in client
|
new net.runelite.asm.pool.Class("client"), // Static methods are in client
|
||||||
hookMethod.getName(),
|
hookMethod.getName(),
|
||||||
signature
|
signature
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -191,11 +189,11 @@ public class InjectHookMethod
|
|||||||
// otherwise invoke member function
|
// otherwise invoke member function
|
||||||
//instructions.addInstruction(insertPos++, new ALoad(instructions, 0));
|
//instructions.addInstruction(insertPos++, new ALoad(instructions, 0));
|
||||||
invoke = new InvokeVirtual(instructions,
|
invoke = new InvokeVirtual(instructions,
|
||||||
new net.runelite.asm.pool.Method(
|
new net.runelite.asm.pool.Method(
|
||||||
new net.runelite.asm.pool.Class(vanillaMethod.getClassFile().getName()),
|
new net.runelite.asm.pool.Class(vanillaMethod.getClassFile().getName()),
|
||||||
hookMethod.getName(),
|
hookMethod.getName(),
|
||||||
signature
|
signature
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class InjectInvoker
|
class InjectInvoker
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(InjectInvoker.class);
|
private static final Logger logger = LoggerFactory.getLogger(InjectInvoker.class);
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ public class InjectInvoker
|
|||||||
|
|
||||||
private int injectedInvokers;
|
private int injectedInvokers;
|
||||||
|
|
||||||
public InjectInvoker(Inject inject)
|
InjectInvoker(Inject inject)
|
||||||
{
|
{
|
||||||
this.inject = inject;
|
this.inject = inject;
|
||||||
}
|
}
|
||||||
@@ -67,13 +67,13 @@ public class InjectInvoker
|
|||||||
/**
|
/**
|
||||||
* Inject an invoker for a method
|
* Inject an invoker for a method
|
||||||
*
|
*
|
||||||
* @param m Method in the deobfuscated client to inject an invoker for
|
* @param m Method in the deobfuscated client to inject an invoker for
|
||||||
* @param other Class in the vanilla client of the same class m is a
|
* @param other Class in the vanilla client of the same class m is a
|
||||||
* member of
|
* member of
|
||||||
* @param implementingClass Java class for the API interface the class
|
* @param implementingClass Java class for the API interface the class
|
||||||
* will implement
|
* will implement
|
||||||
*/
|
*/
|
||||||
public void process(Method m, ClassFile other, java.lang.Class<?> implementingClass)
|
void process(Method m, ClassFile other, java.lang.Class<?> implementingClass)
|
||||||
{
|
{
|
||||||
Annotations an = m.getAnnotations();
|
Annotations an = m.getAnnotations();
|
||||||
|
|
||||||
@@ -108,14 +108,14 @@ public class InjectInvoker
|
|||||||
assert !m.isStatic();
|
assert !m.isStatic();
|
||||||
|
|
||||||
// non static exported method on non exported interface, weird.
|
// non static exported method on non exported interface, weird.
|
||||||
// logger.debug("Non static exported method {} on non exported interface", exportedName);
|
// logger.debug("Non static exported method {} on non exported interface", exportedName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
java.lang.reflect.Method apiMethod = inject.findImportMethodOnApi(targetClassJava, exportedName, null); // api method to invoke 'otherm'
|
java.lang.reflect.Method apiMethod = inject.findImportMethodOnApi(targetClassJava, exportedName, null); // api method to invoke 'otherm'
|
||||||
if (apiMethod == null)
|
if (apiMethod == null)
|
||||||
{
|
{
|
||||||
// logger.debug("Unable to find api method on {} with imported name {}, not injecting invoker", targetClassJava, exportedName);
|
// logger.debug("Unable to find api method on {} with imported name {}, not injecting invoker", targetClassJava, exportedName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,7 +284,7 @@ public class InjectInvoker
|
|||||||
clazz.addMethod(invokerMethodSignature);
|
clazz.addMethod(invokerMethodSignature);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getInjectedInvokers()
|
int getInjectedInvokers()
|
||||||
{
|
{
|
||||||
return injectedInvokers;
|
return injectedInvokers;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,17 +45,14 @@ import org.apache.maven.plugins.annotations.Parameter;
|
|||||||
)
|
)
|
||||||
public class InjectMojo extends AbstractMojo
|
public class InjectMojo extends AbstractMojo
|
||||||
{
|
{
|
||||||
|
private final Log log = getLog();
|
||||||
@Parameter(defaultValue = "${project.build.outputDirectory}")
|
@Parameter(defaultValue = "${project.build.outputDirectory}")
|
||||||
private File outputDirectory;
|
private File outputDirectory;
|
||||||
|
|
||||||
@Parameter(defaultValue = "./runescape-client/target/rs-client-${project.version}.jar", readonly = true, required = true)
|
@Parameter(defaultValue = "./runescape-client/target/rs-client-${project.version}.jar", readonly = true, required = true)
|
||||||
private String rsClientPath;
|
private String rsClientPath;
|
||||||
|
|
||||||
@Parameter(defaultValue = "${net.runelite.rs:vanilla:jar}", readonly = true, required = true)
|
@Parameter(defaultValue = "${net.runelite.rs:vanilla:jar}", readonly = true, required = true)
|
||||||
private String vanillaPath;
|
private String vanillaPath;
|
||||||
|
|
||||||
private final Log log = getLog();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() throws MojoExecutionException, MojoFailureException
|
public void execute() throws MojoExecutionException, MojoFailureException
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -45,15 +45,15 @@ import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class InjectSetter
|
class InjectSetter
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(InjectSetter.class);
|
private static final Logger logger = LoggerFactory.getLogger(InjectSetter.class);
|
||||||
|
|
||||||
private final Inject inject;
|
private final Inject inject;
|
||||||
|
|
||||||
private int injectedSetters;
|
private int injectedSetters;
|
||||||
|
|
||||||
public InjectSetter(Inject inject)
|
InjectSetter(Inject inject)
|
||||||
{
|
{
|
||||||
this.inject = inject;
|
this.inject = inject;
|
||||||
}
|
}
|
||||||
@@ -61,15 +61,14 @@ public class InjectSetter
|
|||||||
/**
|
/**
|
||||||
* inject a setter into the vanilla classgroup
|
* inject a setter into the vanilla classgroup
|
||||||
*
|
*
|
||||||
* @param targetClass Class where to inject the setter (field's class,
|
* @param targetClass Class where to inject the setter (field's class,
|
||||||
* or client)
|
* or client)
|
||||||
* @param targetApiClass API targetClass implements, which may have the
|
* @param targetApiClass API targetClass implements, which may have the
|
||||||
* setter declared
|
* setter declared
|
||||||
* @param field Field of vanilla that will be set
|
* @param field Field of vanilla that will be set
|
||||||
* @param exportedName exported name of field
|
* @param exportedName exported name of field
|
||||||
* @param setter
|
|
||||||
*/
|
*/
|
||||||
public void injectSetter(ClassFile targetClass, Class<?> targetApiClass, Field field, String exportedName, Number setter)
|
void injectSetter(ClassFile targetClass, Class<?> targetApiClass, Field field, String exportedName, Number setter)
|
||||||
{
|
{
|
||||||
java.lang.reflect.Method method = inject.findImportMethodOnApi(targetApiClass, exportedName, true);
|
java.lang.reflect.Method method = inject.findImportMethodOnApi(targetApiClass, exportedName, true);
|
||||||
if (method == null)
|
if (method == null)
|
||||||
@@ -114,7 +113,7 @@ public class InjectSetter
|
|||||||
// load argument
|
// load argument
|
||||||
Type argumentType = sig.getTypeOfArg(0);
|
Type argumentType = sig.getTypeOfArg(0);
|
||||||
ins.add(inject.createLoadForTypeIndex(instructions, argumentType, 1));
|
ins.add(inject.createLoadForTypeIndex(instructions, argumentType, 1));
|
||||||
|
|
||||||
// cast argument to field type
|
// cast argument to field type
|
||||||
Type fieldType = field.getType();
|
Type fieldType = field.getType();
|
||||||
if (!argumentType.equals(fieldType))
|
if (!argumentType.equals(fieldType))
|
||||||
@@ -152,7 +151,7 @@ public class InjectSetter
|
|||||||
ins.add(new VReturn(instructions));
|
ins.add(new VReturn(instructions));
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getInjectedSetters()
|
int getInjectedSetters()
|
||||||
{
|
{
|
||||||
return injectedSetters;
|
return injectedSetters;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,130 @@
|
|||||||
|
package net.runelite.injector;
|
||||||
|
|
||||||
|
import net.runelite.asm.ClassFile;
|
||||||
|
import net.runelite.asm.Field;
|
||||||
|
import net.runelite.asm.Method;
|
||||||
|
import net.runelite.asm.signature.Signature;
|
||||||
|
import net.runelite.deob.DeobAnnotations;
|
||||||
|
|
||||||
|
public class InjectUtil
|
||||||
|
{
|
||||||
|
public static Method findStaticObMethod(Inject inject, String name) throws InjectionException
|
||||||
|
{
|
||||||
|
for (ClassFile c : inject.getVanilla().getClasses())
|
||||||
|
{
|
||||||
|
for (Method m : c.getMethods())
|
||||||
|
{
|
||||||
|
if (!m.getName().equals(name))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InjectionException(String.format("Method \"%s\" could not be found.", name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Method findMethod(Inject inject, String name) throws InjectionException
|
||||||
|
{
|
||||||
|
for (ClassFile c : inject.getDeobfuscated().getClasses())
|
||||||
|
{
|
||||||
|
for (Method m : c.getMethods())
|
||||||
|
{
|
||||||
|
if (!m.getName().equals(name))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations());
|
||||||
|
Signature obfuscatedSignature = DeobAnnotations.getObfuscatedSignature(m);
|
||||||
|
|
||||||
|
ClassFile c2 = inject.toObClass(c);
|
||||||
|
|
||||||
|
return c2.findMethod(obfuscatedName, (obfuscatedSignature != null) ? obfuscatedSignature : m.getDescriptor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InjectionException("Couldn't find method " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Method findStaticMethod(Inject inject, String name) throws InjectionException
|
||||||
|
{
|
||||||
|
for (ClassFile c : inject.getDeobfuscated().getClasses())
|
||||||
|
{
|
||||||
|
for (Method m : c.getMethods())
|
||||||
|
{
|
||||||
|
if (!m.isStatic() || !m.getName().equals(name))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations());
|
||||||
|
Signature obfuscatedSignature = DeobAnnotations.getObfuscatedSignature(m);
|
||||||
|
|
||||||
|
ClassFile c2 = inject.toObClass(c);
|
||||||
|
|
||||||
|
return c2.findMethod(obfuscatedName, (obfuscatedSignature != null) ? obfuscatedSignature : m.getDescriptor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InjectionException("Couldn't find static method " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Field findObField(Inject inject, String name) throws InjectionException
|
||||||
|
{
|
||||||
|
for (ClassFile c : inject.getVanilla().getClasses())
|
||||||
|
{
|
||||||
|
for (Field f : c.getFields())
|
||||||
|
{
|
||||||
|
if (!f.getName().equals(name))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InjectionException(String.format("Field \"%s\" could not be found.", name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Field findDeobField(Inject inject, String name) throws InjectionException
|
||||||
|
{
|
||||||
|
for (ClassFile c : inject.getDeobfuscated().getClasses())
|
||||||
|
{
|
||||||
|
for (Field f : c.getFields())
|
||||||
|
{
|
||||||
|
if (!f.getName().equals(name))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String obfuscatedName = DeobAnnotations.getObfuscatedName(f.getAnnotations());
|
||||||
|
|
||||||
|
ClassFile c2 = inject.toObClass(c);
|
||||||
|
return c2.findField(obfuscatedName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InjectionException(String.format("Mapped field \"%s\" could not be found.", name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Field findDeobFieldButUseless(Inject inject, String name) throws InjectionException
|
||||||
|
{
|
||||||
|
for (ClassFile c : inject.getDeobfuscated().getClasses())
|
||||||
|
{
|
||||||
|
for (Field f : c.getFields())
|
||||||
|
{
|
||||||
|
if (!f.getName().equals(name))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InjectionException(String.format("Mapped field \"%s\" could not be found.", name));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -39,17 +39,6 @@ public class Injector
|
|||||||
this.vanilla = vanilla;
|
this.vanilla = vanilla;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void inject() throws InjectionException
|
|
||||||
{
|
|
||||||
Inject instance = new Inject(deobfuscated, vanilla);
|
|
||||||
instance.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void save(File out) throws IOException
|
|
||||||
{
|
|
||||||
JarUtil.saveJar(vanilla, out);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException, InjectionException
|
public static void main(String[] args) throws IOException, InjectionException
|
||||||
{
|
{
|
||||||
if (args.length < 3)
|
if (args.length < 3)
|
||||||
@@ -72,5 +61,16 @@ public class Injector
|
|||||||
u.save(new File(args[2]));
|
u.save(new File(args[2]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void inject() throws InjectionException
|
||||||
|
{
|
||||||
|
Inject instance = new Inject(deobfuscated, vanilla);
|
||||||
|
instance.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void save(File out) throws IOException
|
||||||
|
{
|
||||||
|
JarUtil.saveJar(vanilla, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
*
|
*
|
||||||
* @author Adam
|
* @author Adam
|
||||||
*/
|
*/
|
||||||
public class InjectorValidator
|
class InjectorValidator
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(InjectorValidator.class);
|
private static final Logger logger = LoggerFactory.getLogger(InjectorValidator.class);
|
||||||
|
|
||||||
@@ -49,12 +49,12 @@ public class InjectorValidator
|
|||||||
|
|
||||||
private int error, missing, okay;
|
private int error, missing, okay;
|
||||||
|
|
||||||
public InjectorValidator(ClassGroup group)
|
InjectorValidator(ClassGroup group)
|
||||||
{
|
{
|
||||||
this.group = group;
|
this.group = group;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void validate()
|
void validate()
|
||||||
{
|
{
|
||||||
for (ClassFile cf : group.getClasses())
|
for (ClassFile cf : group.getClasses())
|
||||||
{
|
{
|
||||||
@@ -131,17 +131,17 @@ public class InjectorValidator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getError()
|
int getError()
|
||||||
{
|
{
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMissing()
|
int getMissing()
|
||||||
{
|
{
|
||||||
return missing;
|
return missing;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getOkay()
|
int getOkay()
|
||||||
{
|
{
|
||||||
return okay;
|
return okay;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ public class MixinInjector
|
|||||||
// Use net.runelite.asm.pool.Field instead of Field because the pool version has hashcode implemented
|
// Use net.runelite.asm.pool.Field instead of Field because the pool version has hashcode implemented
|
||||||
private final Map<net.runelite.asm.pool.Field, Field> shadowFields = new HashMap<>();
|
private final Map<net.runelite.asm.pool.Field, Field> shadowFields = new HashMap<>();
|
||||||
|
|
||||||
public MixinInjector(Inject inject)
|
MixinInjector(Inject inject)
|
||||||
{
|
{
|
||||||
this.inject = inject;
|
this.inject = inject;
|
||||||
}
|
}
|
||||||
@@ -165,9 +165,6 @@ public class MixinInjector
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds fields that are marked @Inject and inject them into the target
|
* Finds fields that are marked @Inject and inject them into the target
|
||||||
*
|
|
||||||
* @param mixinClasses
|
|
||||||
* @throws InjectionException
|
|
||||||
*/
|
*/
|
||||||
private void injectFields(Map<Class<?>, List<ClassFile>> mixinClasses) throws InjectionException
|
private void injectFields(Map<Class<?>, List<ClassFile>> mixinClasses) throws InjectionException
|
||||||
{
|
{
|
||||||
@@ -245,9 +242,6 @@ public class MixinInjector
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Find fields which are marked @Shadow, and what they shadow
|
* Find fields which are marked @Shadow, and what they shadow
|
||||||
*
|
|
||||||
* @param mixinClasses
|
|
||||||
* @throws InjectionException
|
|
||||||
*/
|
*/
|
||||||
private void findShadowFields(Map<Class<?>, List<ClassFile>> mixinClasses) throws InjectionException
|
private void findShadowFields(Map<Class<?>, List<ClassFile>> mixinClasses) throws InjectionException
|
||||||
{
|
{
|
||||||
@@ -287,7 +281,7 @@ public class MixinInjector
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Shadow a field already in the gamepack
|
// Shadow a field already in the gamepack
|
||||||
Field shadowField = findDeobField(shadowName);
|
Field shadowField = InjectUtil.findDeobFieldButUseless(inject, shadowName);
|
||||||
|
|
||||||
if (shadowField == null)
|
if (shadowField == null)
|
||||||
{
|
{
|
||||||
@@ -316,21 +310,6 @@ public class MixinInjector
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Field findDeobField(String name)
|
|
||||||
{
|
|
||||||
for (ClassFile cf : inject.getDeobfuscated().getClasses())
|
|
||||||
{
|
|
||||||
for (Field f : cf.getFields())
|
|
||||||
{
|
|
||||||
if (f.getName().equals(name) && f.isStatic())
|
|
||||||
{
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void injectMethods(ClassFile mixinCf, ClassFile cf, Map<net.runelite.asm.pool.Field, Field> shadowFields)
|
private void injectMethods(ClassFile mixinCf, ClassFile cf, Map<net.runelite.asm.pool.Field, Field> shadowFields)
|
||||||
throws InjectionException
|
throws InjectionException
|
||||||
{
|
{
|
||||||
@@ -404,7 +383,7 @@ public class MixinInjector
|
|||||||
care of the garbage parameter itself.
|
care of the garbage parameter itself.
|
||||||
*/
|
*/
|
||||||
boolean hasGarbageValue = method.getDescriptor().size() != obMethod.getDescriptor().size()
|
boolean hasGarbageValue = method.getDescriptor().size() != obMethod.getDescriptor().size()
|
||||||
&& deobMethod.getDescriptor().size() < obMethodSignature.size();
|
&& deobMethod.getDescriptor().size() < obMethodSignature.size();
|
||||||
copiedMethods.put(method.getPoolMethod(), new CopiedMethod(copy, hasGarbageValue));
|
copiedMethods.put(method.getPoolMethod(), new CopiedMethod(copy, hasGarbageValue));
|
||||||
|
|
||||||
logger.debug("Injected copy of {} to {}", obMethod, copy);
|
logger.debug("Injected copy of {} to {}", obMethod, copy);
|
||||||
@@ -577,7 +556,7 @@ public class MixinInjector
|
|||||||
if (!returnType.equals(deobReturnType))
|
if (!returnType.equals(deobReturnType))
|
||||||
{
|
{
|
||||||
ClassFile deobReturnTypeClassFile = inject.getDeobfuscated()
|
ClassFile deobReturnTypeClassFile = inject.getDeobfuscated()
|
||||||
.findClass(deobReturnType.getInternalName());
|
.findClass(deobReturnType.getInternalName());
|
||||||
if (deobReturnTypeClassFile != null)
|
if (deobReturnTypeClassFile != null)
|
||||||
{
|
{
|
||||||
ClassFile obReturnTypeClass = inject.toObClass(deobReturnTypeClassFile);
|
ClassFile obReturnTypeClass = inject.toObClass(deobReturnTypeClassFile);
|
||||||
@@ -601,13 +580,13 @@ public class MixinInjector
|
|||||||
moveCode(obMethod, method.getCode());
|
moveCode(obMethod, method.getCode());
|
||||||
|
|
||||||
boolean hasGarbageValue = method.getDescriptor().size() != obMethod.getDescriptor().size()
|
boolean hasGarbageValue = method.getDescriptor().size() != obMethod.getDescriptor().size()
|
||||||
&& deobMethod.getDescriptor().size() < obMethodSignature.size();
|
&& deobMethod.getDescriptor().size() < obMethodSignature.size();
|
||||||
|
|
||||||
if (hasGarbageValue)
|
if (hasGarbageValue)
|
||||||
{
|
{
|
||||||
int garbageIndex = obMethod.isStatic()
|
int garbageIndex = obMethod.isStatic()
|
||||||
? obMethod.getDescriptor().size() - 1
|
? obMethod.getDescriptor().size() - 1
|
||||||
: obMethod.getDescriptor().size();
|
: obMethod.getDescriptor().size();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If the mixin method doesn't have the garbage parameter,
|
If the mixin method doesn't have the garbage parameter,
|
||||||
@@ -645,8 +624,8 @@ public class MixinInjector
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setOwnersToTargetClass(ClassFile mixinCf, ClassFile cf, Method method,
|
private void setOwnersToTargetClass(ClassFile mixinCf, ClassFile cf, Method method,
|
||||||
Map<net.runelite.asm.pool.Field, Field> shadowFields,
|
Map<net.runelite.asm.pool.Field, Field> shadowFields,
|
||||||
Map<net.runelite.asm.pool.Method, CopiedMethod> copiedMethods)
|
Map<net.runelite.asm.pool.Method, CopiedMethod> copiedMethods)
|
||||||
throws InjectionException
|
throws InjectionException
|
||||||
{
|
{
|
||||||
ListIterator<Instruction> iterator = method.getCode().getInstructions().getInstructions().listIterator();
|
ListIterator<Instruction> iterator = method.getCode().getInstructions().getInstructions().listIterator();
|
||||||
@@ -901,7 +880,7 @@ public class MixinInjector
|
|||||||
if (targetField == null)
|
if (targetField == null)
|
||||||
{
|
{
|
||||||
// first try non static fields, then static
|
// first try non static fields, then static
|
||||||
targetField = findDeobField(hookName);
|
targetField = InjectUtil.findDeobFieldButUseless(inject, hookName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targetField == null)
|
if (targetField == null)
|
||||||
@@ -909,6 +888,13 @@ public class MixinInjector
|
|||||||
throw new InjectionException("Field hook for nonexistent field " + hookName + " on " + method);
|
throw new InjectionException("Field hook for nonexistent field " + hookName + " on " + method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Annotation an = targetField.getAnnotations().find(DeobAnnotations.OBFUSCATED_GETTER);
|
||||||
|
Number getter = null;
|
||||||
|
if (an != null)
|
||||||
|
{
|
||||||
|
getter = (Number) an.getElement().getValue();
|
||||||
|
}
|
||||||
|
|
||||||
Field obField = inject.toObField(targetField);
|
Field obField = inject.toObField(targetField);
|
||||||
|
|
||||||
if (method.isStatic() != targetField.isStatic())
|
if (method.isStatic() != targetField.isStatic())
|
||||||
@@ -922,6 +908,7 @@ public class MixinInjector
|
|||||||
hookInfo.fieldName = hookName;
|
hookInfo.fieldName = hookName;
|
||||||
hookInfo.method = method;
|
hookInfo.method = method;
|
||||||
hookInfo.before = before;
|
hookInfo.before = before;
|
||||||
|
hookInfo.getter = getter;
|
||||||
injectHook.hook(obField, hookInfo);
|
injectHook.hook(obField, hookInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ import net.runelite.asm.attributes.code.instructions.InvokeStatic;
|
|||||||
import net.runelite.asm.attributes.code.instructions.LDC;
|
import net.runelite.asm.attributes.code.instructions.LDC;
|
||||||
import net.runelite.asm.pool.Class;
|
import net.runelite.asm.pool.Class;
|
||||||
import net.runelite.asm.signature.Signature;
|
import net.runelite.asm.signature.Signature;
|
||||||
import net.runelite.deob.DeobAnnotations;
|
|
||||||
import net.runelite.injector.Inject;
|
import net.runelite.injector.Inject;
|
||||||
|
import net.runelite.injector.InjectUtil;
|
||||||
import net.runelite.injector.InjectionException;
|
import net.runelite.injector.InjectionException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -39,7 +39,7 @@ public class ClearColorBuffer
|
|||||||
|
|
||||||
private void injectColorBufferHooks() throws InjectionException
|
private void injectColorBufferHooks() throws InjectionException
|
||||||
{
|
{
|
||||||
net.runelite.asm.pool.Method fillRectangle = findStaticMethod("Rasterizer2D_fillRectangle").getPoolMethod();
|
net.runelite.asm.pool.Method fillRectangle = InjectUtil.findStaticMethod(inject, "Rasterizer2D_fillRectangle").getPoolMethod();
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int replaced = 0;
|
int replaced = 0;
|
||||||
@@ -79,7 +79,7 @@ public class ClearColorBuffer
|
|||||||
if (current instanceof LDC && ((LDC) current).getConstantAsInt() == 0)
|
if (current instanceof LDC && ((LDC) current).getConstantAsInt() == 0)
|
||||||
{
|
{
|
||||||
int varIdx = 0;
|
int varIdx = 0;
|
||||||
for (; ;)
|
for (; ; )
|
||||||
{
|
{
|
||||||
current = it.previous();
|
current = it.previous();
|
||||||
if (current instanceof ILoad && ((ILoad) current).getVariableIndex() == 3 - varIdx)
|
if (current instanceof ILoad && ((ILoad) current).getVariableIndex() == 3 - varIdx)
|
||||||
@@ -119,28 +119,4 @@ public class ClearColorBuffer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Method findStaticMethod(String name) throws InjectionException
|
|
||||||
{
|
|
||||||
for (ClassFile c : inject.getDeobfuscated().getClasses())
|
|
||||||
{
|
|
||||||
for (Method m : c.getMethods())
|
|
||||||
{
|
|
||||||
if (!m.getName().equals(name))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations());
|
|
||||||
Signature obfuscatedSignature = DeobAnnotations.getObfuscatedSignature(m);
|
|
||||||
|
|
||||||
ClassFile c2 = inject.toObClass(c);
|
|
||||||
|
|
||||||
return c2.findMethod(obfuscatedName, (obfuscatedSignature != null) ? obfuscatedSignature : m.getDescriptor());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InjectionException("Couldn't find static method " + name);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -38,9 +38,9 @@ import net.runelite.asm.attributes.code.instructions.GetStatic;
|
|||||||
import net.runelite.asm.attributes.code.instructions.IMul;
|
import net.runelite.asm.attributes.code.instructions.IMul;
|
||||||
import net.runelite.asm.attributes.code.instructions.InvokeStatic;
|
import net.runelite.asm.attributes.code.instructions.InvokeStatic;
|
||||||
import net.runelite.asm.signature.Signature;
|
import net.runelite.asm.signature.Signature;
|
||||||
import net.runelite.deob.DeobAnnotations;
|
|
||||||
import net.runelite.injector.Inject;
|
import net.runelite.injector.Inject;
|
||||||
import static net.runelite.injector.InjectHookMethod.HOOKS;
|
import static net.runelite.injector.InjectHookMethod.HOOKS;
|
||||||
|
import static net.runelite.injector.InjectUtil.findStaticMethod;
|
||||||
import net.runelite.injector.InjectionException;
|
import net.runelite.injector.InjectionException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -107,7 +107,7 @@ public class DrawAfterWidgets
|
|||||||
|
|
||||||
boolean injected = false;
|
boolean injected = false;
|
||||||
|
|
||||||
Method noClip = findStaticMethod("Rasterizer2D_resetClip"); // !!!!!
|
Method noClip = findStaticMethod(inject, "Rasterizer2D_resetClip"); // !!!!!
|
||||||
|
|
||||||
if (noClip == null)
|
if (noClip == null)
|
||||||
{
|
{
|
||||||
@@ -166,7 +166,7 @@ public class DrawAfterWidgets
|
|||||||
{
|
{
|
||||||
// If we get here, we're either in the wrong method
|
// If we get here, we're either in the wrong method
|
||||||
// or Jagex has removed the "if (535573958 * kl != -1)"
|
// or Jagex has removed the "if (535573958 * kl != -1)"
|
||||||
// logger.debug("Could not find the label for jumping to the " + noClip + " call in " + m);
|
// logger.debug("Could not find the label for jumping to the " + noClip + " call in " + m);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,27 +261,4 @@ public class DrawAfterWidgets
|
|||||||
throw new InjectionException("injectDrawAfterWidgets failed to inject!");
|
throw new InjectionException("injectDrawAfterWidgets failed to inject!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Method findStaticMethod(String name)
|
|
||||||
{
|
|
||||||
for (ClassFile c : inject.getDeobfuscated().getClasses())
|
|
||||||
{
|
|
||||||
for (Method m : c.getMethods())
|
|
||||||
{
|
|
||||||
if (!m.getName().equals(name))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations());
|
|
||||||
Signature obfuscatedSignature = DeobAnnotations.getObfuscatedSignature(m);
|
|
||||||
|
|
||||||
ClassFile c2 = inject.toObClass(c);
|
|
||||||
|
|
||||||
return c2.findMethod(obfuscatedName, (obfuscatedSignature != null) ? obfuscatedSignature : m.getDescriptor());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,193 +1,135 @@
|
|||||||
/*
|
|
||||||
package net.runelite.injector.raw;
|
package net.runelite.injector.raw;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
import java.util.ListIterator;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import net.runelite.asm.ClassFile;
|
import net.runelite.asm.ClassFile;
|
||||||
import net.runelite.asm.Method;
|
import net.runelite.asm.Method;
|
||||||
import net.runelite.asm.Type;
|
|
||||||
import net.runelite.asm.attributes.Annotations;
|
|
||||||
import net.runelite.asm.attributes.Code;
|
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.Instruction;
|
||||||
import net.runelite.asm.attributes.code.Instructions;
|
import net.runelite.asm.attributes.code.Instructions;
|
||||||
import net.runelite.asm.attributes.code.Label;
|
import net.runelite.asm.attributes.code.Label;
|
||||||
import net.runelite.asm.attributes.code.instruction.types.ComparisonInstruction;
|
|
||||||
import net.runelite.asm.attributes.code.instruction.types.JumpingInstruction;
|
import net.runelite.asm.attributes.code.instruction.types.JumpingInstruction;
|
||||||
import net.runelite.asm.attributes.code.instruction.types.ReturnInstruction;
|
|
||||||
import net.runelite.asm.attributes.code.instructions.GetStatic;
|
import net.runelite.asm.attributes.code.instructions.GetStatic;
|
||||||
import net.runelite.asm.attributes.code.instructions.IfACmpEq;
|
|
||||||
import net.runelite.asm.attributes.code.instructions.IfACmpNe;
|
|
||||||
import net.runelite.asm.attributes.code.instructions.IfEq;
|
import net.runelite.asm.attributes.code.instructions.IfEq;
|
||||||
import net.runelite.asm.attributes.code.instructions.IfNe;
|
import net.runelite.asm.attributes.code.instructions.IfNe;
|
||||||
import net.runelite.asm.attributes.code.instructions.InvokeStatic;
|
import net.runelite.asm.attributes.code.instructions.InvokeStatic;
|
||||||
import net.runelite.asm.execution.Execution;
|
|
||||||
import net.runelite.asm.execution.InstructionContext;
|
|
||||||
import net.runelite.asm.pool.Class;
|
import net.runelite.asm.pool.Class;
|
||||||
import net.runelite.asm.pool.Field;
|
import net.runelite.asm.pool.Field;
|
||||||
import net.runelite.asm.signature.Signature;
|
import net.runelite.asm.signature.Signature;
|
||||||
import net.runelite.deob.DeobAnnotations;
|
|
||||||
import net.runelite.injector.Inject;
|
import net.runelite.injector.Inject;
|
||||||
|
import static net.runelite.injector.InjectUtil.findDeobField;
|
||||||
|
import static net.runelite.injector.InjectUtil.findStaticMethod;
|
||||||
import net.runelite.injector.InjectionException;
|
import net.runelite.injector.InjectionException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class DrawMenu
|
public class DrawMenu
|
||||||
{
|
{
|
||||||
|
private final Logger log = LoggerFactory.getLogger(DrawMenu.class);
|
||||||
private final Inject inject;
|
private final Inject inject;
|
||||||
private static final Field isMenuOpen = new Field(
|
|
||||||
new Class("Client"),
|
|
||||||
"isMenuOpen",
|
|
||||||
Type.BOOLEAN
|
|
||||||
);
|
|
||||||
private static final net.runelite.asm.pool.Method hook = new net.runelite.asm.pool.Method(
|
private static final net.runelite.asm.pool.Method hook = new net.runelite.asm.pool.Method(
|
||||||
new Class("net.runelite.client.callback.Hooks"),
|
new Class("net.runelite.client.callback.Hooks"),
|
||||||
"drawMenu",
|
"drawMenu",
|
||||||
new Signature("()Z")
|
new Signature("()Z")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//Label Getstatic client.isMenuOpen
|
||||||
|
//Ifne -> Label Drawmenu
|
||||||
|
//Jump -> Label Drawtext
|
||||||
|
|
||||||
|
//Label drawtext
|
||||||
|
//Ldc xxx
|
||||||
|
//Getstatic client. something with viewport size?
|
||||||
|
//Imul
|
||||||
|
//Iconst_m1
|
||||||
|
//Ifne -> Label after draw menu <- info we need
|
||||||
|
//Getstatic / LDC (same getstatic and LDC before)
|
||||||
|
//Getstatic / LDC
|
||||||
|
|
||||||
public DrawMenu(Inject inject)
|
public DrawMenu(Inject inject)
|
||||||
{
|
{
|
||||||
this.inject =inject;
|
this.inject = inject;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void inject() throws InjectionException
|
public void inject() throws InjectionException
|
||||||
{
|
{
|
||||||
Method drawLoggedIn = findDeobThing("drawLoggedIn", "Client", false);
|
Field isMenuOpen = findDeobField(inject, "isMenuOpen").getPoolField();
|
||||||
Instructions ins = drawLoggedIn.getCode().getInstructions();
|
net.runelite.asm.pool.Method topLeftText = findStaticMethod(inject, "drawMenuActionTextAt").getPoolMethod();
|
||||||
|
|
||||||
int menuOpenIdx = -1;
|
for (ClassFile cf : inject.getVanilla().getClasses())
|
||||||
Field field = toObField(isMenuOpen).getPoolField();
|
|
||||||
|
|
||||||
for (Instruction i : ins.getInstructions())
|
|
||||||
{
|
|
||||||
if (!(i instanceof GetStatic))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((GetStatic) i).getField().equals(field))
|
|
||||||
{
|
|
||||||
menuOpenIdx = ins.getInstructions().indexOf(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (menuOpenIdx == -1)
|
|
||||||
{
|
|
||||||
throw new InjectionException("Couldn't find the isMenuOpen check!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is where the IFEQ or IFNE will be
|
|
||||||
final Instruction jump = ins.getInstructions().get(menuOpenIdx + 1);
|
|
||||||
// We want to inject if it's false so
|
|
||||||
if (jump instanceof IfEq)
|
|
||||||
{
|
|
||||||
// Not this one, but we gotta find out where the paths will intersect
|
|
||||||
Set<Label> labels = getLabels(jump);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private Set<Label> getLabels(Instruction i)
|
|
||||||
{
|
|
||||||
Set<Label> labels = new HashSet<>();
|
|
||||||
Execution ex = new Execution(inject.getVanilla());
|
|
||||||
ex.addMethod(i.getInstructions().getCode().getMethod());
|
|
||||||
ex.noInvoke = true;
|
|
||||||
|
|
||||||
ex.addExecutionVisitor((InstructionContext ic) ->
|
|
||||||
{
|
|
||||||
Instruction in = ic.getInstruction();
|
|
||||||
Instructions ins = in.getInstructions();
|
|
||||||
Code code = ins.getCode();
|
|
||||||
Method method = code.getMethod();
|
|
||||||
//ic.
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private Set<Label> findLabels(Instructions ins, int idx)
|
|
||||||
{
|
|
||||||
Set<Label> labels = new HashSet<>();
|
|
||||||
Instruction i = null;
|
|
||||||
while (labels.size() < 10 || !(i instanceof ReturnInstruction))
|
|
||||||
{
|
|
||||||
i = ins.getInstructions().get(idx);
|
|
||||||
if (i instanceof JumpingInstruction)
|
|
||||||
{
|
|
||||||
Label cur = ((JumpingInstruction) i).getJumps().get(0);
|
|
||||||
labels.add((Label) cur);
|
|
||||||
|
|
||||||
idx = ins.getInstructions().indexOf(cur) + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return labels;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Method findDeobThing(String name, String hint, boolean isStatic) throws InjectionException
|
|
||||||
{
|
|
||||||
if (!Strings.isNullOrEmpty(hint))
|
|
||||||
{
|
|
||||||
ClassFile hintCf = inject.getDeobfuscated().findClass(hint);
|
|
||||||
if (hintCf != null)
|
|
||||||
{
|
|
||||||
for (Method m : hintCf.getMethods())
|
|
||||||
{
|
|
||||||
if (isStatic != m.isStatic())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m.getName().equals(name))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Annotations an = m.getAnnotations();
|
|
||||||
if (an == null || an.find(DeobAnnotations.EXPORT) == null)
|
|
||||||
{
|
|
||||||
continue; // not an exported field
|
|
||||||
}
|
|
||||||
|
|
||||||
String obfuscatedName = DeobAnnotations.getObfuscatedName(an);
|
|
||||||
return inject.toObClass(hintCf).findMethod(obfuscatedName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ClassFile cf : inject.getDeobfuscated().getClasses())
|
|
||||||
{
|
{
|
||||||
for (Method m : cf.getMethods())
|
for (Method m : cf.getMethods())
|
||||||
{
|
{
|
||||||
if (isStatic != m.isStatic())
|
Code c = m.getCode();
|
||||||
|
if (c == null)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Annotations an = m.getAnnotations();
|
Instructions ins = c.getInstructions();
|
||||||
if (an == null || an.find(DeobAnnotations.EXPORT) == null)
|
ListIterator<Instruction> it = ins.getInstructions().listIterator();
|
||||||
|
int injectIndex = -1;
|
||||||
|
Label after = null;
|
||||||
|
boolean foundBefore = false;
|
||||||
|
boolean foundAfter = false;
|
||||||
|
|
||||||
|
while (it.hasNext())
|
||||||
{
|
{
|
||||||
continue; // not an exported field
|
Instruction i = it.next();
|
||||||
|
|
||||||
|
if (!(i instanceof GetStatic) && !(i instanceof InvokeStatic))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foundBefore && i instanceof GetStatic)
|
||||||
|
{
|
||||||
|
if (!((GetStatic) i).getField().equals(isMenuOpen))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = it.next();
|
||||||
|
if (!(i instanceof IfEq) && !(i instanceof IfNe))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i instanceof IfEq)
|
||||||
|
{
|
||||||
|
injectIndex = it.nextIndex();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
injectIndex = ins.getInstructions().indexOf(((IfNe) i).getJumps().get(0)) + 1;
|
||||||
|
}
|
||||||
|
foundBefore = true;
|
||||||
|
}
|
||||||
|
else if (!foundAfter && i instanceof InvokeStatic
|
||||||
|
&& ((InvokeStatic) i).getMethod().equals(topLeftText))
|
||||||
|
{
|
||||||
|
i = it.next();
|
||||||
|
assert i instanceof JumpingInstruction;
|
||||||
|
after = ((JumpingInstruction) i).getJumps().get(0);
|
||||||
|
foundAfter = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (foundBefore && foundAfter)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String obfuscatedName = DeobAnnotations.getObfuscatedName(an);
|
if (!foundBefore || !foundAfter || injectIndex == -1)
|
||||||
return inject.toObClass(cf).findMethod(obfuscatedName);
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ins.addInstruction(injectIndex, new IfNe(ins, after));
|
||||||
|
ins.addInstruction(injectIndex, new InvokeStatic(ins, hook));
|
||||||
|
log.info("Injected drawmenu hook in {} at index {}", m, injectIndex);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new InjectionException("Method not found!");
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private net.runelite.asm.Field toObField(Field field) throws InjectionException
|
|
||||||
{
|
|
||||||
ClassFile cf = inject.getDeobfuscated().findClass(field.getClazz().getName());
|
|
||||||
for (net.runelite.asm.Field f : cf.getFields())
|
|
||||||
{
|
|
||||||
if (f.getPoolField().equals(field))
|
|
||||||
{
|
|
||||||
return inject.toObField(f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new InjectionException("Field not found!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
@@ -4,7 +4,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import net.runelite.asm.ClassFile;
|
|
||||||
import net.runelite.asm.Field;
|
import net.runelite.asm.Field;
|
||||||
import net.runelite.asm.Method;
|
import net.runelite.asm.Method;
|
||||||
import net.runelite.asm.attributes.Code;
|
import net.runelite.asm.attributes.Code;
|
||||||
@@ -27,8 +26,9 @@ import net.runelite.asm.execution.Execution;
|
|||||||
import net.runelite.asm.execution.InstructionContext;
|
import net.runelite.asm.execution.InstructionContext;
|
||||||
import net.runelite.asm.pool.Class;
|
import net.runelite.asm.pool.Class;
|
||||||
import net.runelite.asm.signature.Signature;
|
import net.runelite.asm.signature.Signature;
|
||||||
import net.runelite.deob.DeobAnnotations;
|
|
||||||
import net.runelite.injector.Inject;
|
import net.runelite.injector.Inject;
|
||||||
|
import static net.runelite.injector.InjectUtil.findDeobField;
|
||||||
|
import static net.runelite.injector.InjectUtil.findStaticMethod;
|
||||||
import net.runelite.injector.InjectionException;
|
import net.runelite.injector.InjectionException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -101,8 +101,8 @@ public class RasterizerHook
|
|||||||
|
|
||||||
private void runR3DAlpha(String methodName, int req, String fieldName) throws InjectionException
|
private void runR3DAlpha(String methodName, int req, String fieldName) throws InjectionException
|
||||||
{
|
{
|
||||||
Method meth = findStaticMethod(methodName);
|
Method meth = findStaticMethod(inject, methodName);
|
||||||
Field field = findDeobField(fieldName);
|
Field field = findDeobField(inject, fieldName);
|
||||||
Instructions ins = meth.getCode().getInstructions();
|
Instructions ins = meth.getCode().getInstructions();
|
||||||
int varIdx = 0; // This is obviously dumb but I cba making this better
|
int varIdx = 0; // This is obviously dumb but I cba making this better
|
||||||
int added = 0;
|
int added = 0;
|
||||||
@@ -118,8 +118,6 @@ public class RasterizerHook
|
|||||||
throw new InjectionException("Couldn't find hook location in " + methodName);
|
throw new InjectionException("Couldn't find hook location in " + methodName);
|
||||||
}
|
}
|
||||||
|
|
||||||
int oldCount = count;
|
|
||||||
|
|
||||||
for (int i : indices)
|
for (int i : indices)
|
||||||
{
|
{
|
||||||
for (int codeIndex = i + added; codeIndex < ins.getInstructions().size(); codeIndex++)
|
for (int codeIndex = i + added; codeIndex < ins.getInstructions().size(); codeIndex++)
|
||||||
@@ -146,8 +144,8 @@ public class RasterizerHook
|
|||||||
|
|
||||||
private void runAlpha(String methodName, int req, int extraArg, int varIndex) throws InjectionException
|
private void runAlpha(String methodName, int req, int extraArg, int varIndex) throws InjectionException
|
||||||
{
|
{
|
||||||
final net.runelite.asm.pool.Field pixels = findDeobField("Rasterizer2D_pixels").getPoolField();
|
final net.runelite.asm.pool.Field pixels = findDeobField(inject, "Rasterizer2D_pixels").getPoolField();
|
||||||
Method meth = findStaticMethod(methodName);
|
Method meth = findStaticMethod(inject, methodName);
|
||||||
if (meth == null)
|
if (meth == null)
|
||||||
{
|
{
|
||||||
throw new InjectionException(methodName + " couldnt be found");
|
throw new InjectionException(methodName + " couldnt be found");
|
||||||
@@ -215,8 +213,7 @@ public class RasterizerHook
|
|||||||
|
|
||||||
private void runFontAlpha(String methodName, int req, int extraArg) throws InjectionException
|
private void runFontAlpha(String methodName, int req, int extraArg) throws InjectionException
|
||||||
{
|
{
|
||||||
final net.runelite.asm.pool.Field pixels = findDeobField("Rasterizer2D_pixels").getPoolField();
|
Method meth = findStaticMethod(inject, methodName);
|
||||||
Method meth = findStaticMethod(methodName);
|
|
||||||
Instructions ins = meth.getCode().getInstructions();
|
Instructions ins = meth.getCode().getInstructions();
|
||||||
int varIdx = 0; // This is obviously dumb but I cba making this better
|
int varIdx = 0; // This is obviously dumb but I cba making this better
|
||||||
int added = 0;
|
int added = 0;
|
||||||
@@ -252,13 +249,9 @@ public class RasterizerHook
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count - oldCount > req)
|
if (count - req != oldCount)
|
||||||
{
|
{
|
||||||
throw new InjectionException("Too many drawAlpha's were injected into " + methodName);
|
throw new InjectionException(req != oldCount ? req > count - oldCount ? "Not enough" : "Too many" : "No" + " drawAlpha's were injected into " + methodName);
|
||||||
}
|
|
||||||
if (count == oldCount)
|
|
||||||
{
|
|
||||||
throw new InjectionException("Couldn't find any drawAlpha positions in " + methodName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,7 +275,7 @@ public class RasterizerHook
|
|||||||
private void run() throws InjectionException
|
private void run() throws InjectionException
|
||||||
{
|
{
|
||||||
final int startCount = count; // Cause you can't just count shit ty
|
final int startCount = count; // Cause you can't just count shit ty
|
||||||
final net.runelite.asm.pool.Field pixels = findDeobField("Rasterizer2D_pixels").getPoolField();
|
final net.runelite.asm.pool.Field pixels = findDeobField(inject, "Rasterizer2D_pixels").getPoolField();
|
||||||
|
|
||||||
Execution ex = new Execution(inject.getVanilla());
|
Execution ex = new Execution(inject.getVanilla());
|
||||||
ex.populateInitialMethods();
|
ex.populateInitialMethods();
|
||||||
@@ -341,7 +334,7 @@ public class RasterizerHook
|
|||||||
|
|
||||||
private void runOnMethodWithVar(String meth, int varIndex) throws InjectionException
|
private void runOnMethodWithVar(String meth, int varIndex) throws InjectionException
|
||||||
{
|
{
|
||||||
Method method = findStaticMethod(meth);
|
Method method = findStaticMethod(inject, meth);
|
||||||
|
|
||||||
Instructions ins = method.getCode().getInstructions();
|
Instructions ins = method.getCode().getInstructions();
|
||||||
List<Integer> indices = new ArrayList<>();
|
List<Integer> indices = new ArrayList<>();
|
||||||
@@ -374,48 +367,4 @@ public class RasterizerHook
|
|||||||
|
|
||||||
logger.info("Added {} instructions in {}. {} total", added >>> 1, meth, count);
|
logger.info("Added {} instructions in {}. {} total", added >>> 1, meth, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Method findStaticMethod(String name) throws InjectionException
|
|
||||||
{
|
|
||||||
for (ClassFile c : inject.getDeobfuscated().getClasses())
|
|
||||||
{
|
|
||||||
for (Method m : c.getMethods())
|
|
||||||
{
|
|
||||||
if (!m.getName().equals(name))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations());
|
|
||||||
Signature obfuscatedSignature = DeobAnnotations.getObfuscatedSignature(m);
|
|
||||||
|
|
||||||
ClassFile c2 = inject.toObClass(c);
|
|
||||||
|
|
||||||
return c2.findMethod(obfuscatedName, (obfuscatedSignature != null) ? obfuscatedSignature : m.getDescriptor());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InjectionException("Couldn't find static method " + name);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Field findDeobField(String name) throws InjectionException
|
|
||||||
{
|
|
||||||
for (ClassFile c : inject.getDeobfuscated().getClasses())
|
|
||||||
{
|
|
||||||
for (Field f : c.getFields())
|
|
||||||
{
|
|
||||||
if (!f.getName().equals(name))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String obfuscatedName = DeobAnnotations.getObfuscatedName(f.getAnnotations());
|
|
||||||
|
|
||||||
ClassFile c2 = inject.toObClass(c);
|
|
||||||
return c2.findField(obfuscatedName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InjectionException(String.format("Mapped field \"%s\" could not be found.", name));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package net.runelite.injector.raw;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import net.runelite.asm.ClassFile;
|
|
||||||
import net.runelite.asm.attributes.code.Instruction;
|
import net.runelite.asm.attributes.code.Instruction;
|
||||||
import net.runelite.asm.attributes.code.Instructions;
|
import net.runelite.asm.attributes.code.Instructions;
|
||||||
import net.runelite.asm.attributes.code.instructions.InvokeStatic;
|
import net.runelite.asm.attributes.code.instructions.InvokeStatic;
|
||||||
@@ -10,8 +9,8 @@ import net.runelite.asm.attributes.code.instructions.InvokeVirtual;
|
|||||||
import net.runelite.asm.pool.Class;
|
import net.runelite.asm.pool.Class;
|
||||||
import net.runelite.asm.pool.Method;
|
import net.runelite.asm.pool.Method;
|
||||||
import net.runelite.asm.signature.Signature;
|
import net.runelite.asm.signature.Signature;
|
||||||
import net.runelite.deob.DeobAnnotations;
|
|
||||||
import net.runelite.injector.Inject;
|
import net.runelite.injector.Inject;
|
||||||
|
import static net.runelite.injector.InjectUtil.findMethod;
|
||||||
import net.runelite.injector.InjectionException;
|
import net.runelite.injector.InjectionException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -38,8 +37,8 @@ public class RenderDraw
|
|||||||
|
|
||||||
private void injectColorBufferHooks() throws InjectionException
|
private void injectColorBufferHooks() throws InjectionException
|
||||||
{
|
{
|
||||||
net.runelite.asm.Method obmethod = findObMethod("drawTile");
|
net.runelite.asm.Method obmethod = findMethod(inject, "drawTile");
|
||||||
Method renderDraw = findObMethod("renderDraw").getPoolMethod();
|
Method renderDraw = findMethod(inject, "renderDraw").getPoolMethod();
|
||||||
Instructions ins = obmethod.getCode().getInstructions();
|
Instructions ins = obmethod.getCode().getInstructions();
|
||||||
replace(ins, renderDraw);
|
replace(ins, renderDraw);
|
||||||
}
|
}
|
||||||
@@ -69,24 +68,4 @@ public class RenderDraw
|
|||||||
ins.replace(i, invoke);
|
ins.replace(i, invoke);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private net.runelite.asm.Method findObMethod(String name) throws InjectionException
|
|
||||||
{
|
|
||||||
for (ClassFile cf : inject.getDeobfuscated().getClasses())
|
|
||||||
{
|
|
||||||
for (net.runelite.asm.Method m : cf.getMethods())
|
|
||||||
{
|
|
||||||
if (!m.getName().equals(name))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
String obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations());
|
|
||||||
|
|
||||||
ClassFile c2 = inject.toObClass(cf);
|
|
||||||
return c2.findMethod(obfuscatedName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InjectionException(String.format("Method \"%s\" could not be found.", name));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import java.util.HashSet;
|
|||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import net.runelite.asm.ClassFile;
|
|
||||||
import net.runelite.asm.Field;
|
import net.runelite.asm.Field;
|
||||||
import net.runelite.asm.Method;
|
import net.runelite.asm.Method;
|
||||||
import net.runelite.asm.Type;
|
import net.runelite.asm.Type;
|
||||||
@@ -54,6 +53,9 @@ import net.runelite.asm.execution.MethodContext;
|
|||||||
import net.runelite.asm.execution.StackContext;
|
import net.runelite.asm.execution.StackContext;
|
||||||
import net.runelite.deob.DeobAnnotations;
|
import net.runelite.deob.DeobAnnotations;
|
||||||
import net.runelite.injector.Inject;
|
import net.runelite.injector.Inject;
|
||||||
|
import net.runelite.injector.InjectUtil;
|
||||||
|
import static net.runelite.injector.InjectUtil.findDeobField;
|
||||||
|
import static net.runelite.injector.InjectUtil.findObField;
|
||||||
import net.runelite.injector.InjectionException;
|
import net.runelite.injector.InjectionException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -104,12 +106,12 @@ public class ScriptVM
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
String scriptObName = DeobAnnotations.getObfuscatedName(inject.getDeobfuscated().findClass("Script").getAnnotations());
|
String scriptObName = DeobAnnotations.getObfuscatedName(inject.getDeobfuscated().findClass("Script").getAnnotations());
|
||||||
Method runScript = findObMethod("copy$runScript0");
|
Method runScript = InjectUtil.findStaticObMethod(inject, "copy$runScript0");
|
||||||
Method vmExecuteOpcode = findObMethod("vmExecuteOpcode");
|
Method vmExecuteOpcode = InjectUtil.findStaticObMethod(inject, "vmExecuteOpcode");
|
||||||
Field scriptInstructions = findDeobField("opcodes");
|
Field scriptInstructions = findDeobField(inject, "opcodes");
|
||||||
Field scriptStatePC = findDeobField("pc");
|
Field scriptStatePC = findDeobField(inject, "pc");
|
||||||
Field currentScriptField = findObField("currentScript");
|
Field currentScriptField = findObField(inject, "currentScript");
|
||||||
Field currentScriptPCField = findObField("currentScriptPC");
|
Field currentScriptPCField = findObField(inject, "currentScriptPC");
|
||||||
|
|
||||||
Execution e = new Execution(inject.getVanilla());
|
Execution e = new Execution(inject.getVanilla());
|
||||||
e.addMethod(runScript);
|
e.addMethod(runScript);
|
||||||
@@ -295,59 +297,4 @@ public class ScriptVM
|
|||||||
instrs.addInstruction(istorepc + 2, new InvokeStatic(instrs, vmExecuteOpcode.getPoolMethod()));
|
instrs.addInstruction(istorepc + 2, new InvokeStatic(instrs, vmExecuteOpcode.getPoolMethod()));
|
||||||
instrs.addInstruction(istorepc + 3, new IfNe(instrs, nextIteration));
|
instrs.addInstruction(istorepc + 3, new IfNe(instrs, nextIteration));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Method findObMethod(String name) throws InjectionException
|
|
||||||
{
|
|
||||||
for (ClassFile c : inject.getVanilla().getClasses())
|
|
||||||
{
|
|
||||||
for (Method m : c.getMethods())
|
|
||||||
{
|
|
||||||
if (!m.getName().equals(name))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InjectionException(String.format("Method \"%s\" could not be found.", name));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Field findObField(String name) throws InjectionException
|
|
||||||
{
|
|
||||||
for (ClassFile c : inject.getVanilla().getClasses())
|
|
||||||
{
|
|
||||||
for (Field f : c.getFields())
|
|
||||||
{
|
|
||||||
if (!f.getName().equals(name))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InjectionException(String.format("Field \"%s\" could not be found.", name));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Field findDeobField(String name) throws InjectionException
|
|
||||||
{
|
|
||||||
for (ClassFile c : inject.getDeobfuscated().getClasses())
|
|
||||||
{
|
|
||||||
for (Field f : c.getFields())
|
|
||||||
{
|
|
||||||
if (!f.getName().equals(name))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String obfuscatedName = DeobAnnotations.getObfuscatedName(f.getAnnotations());
|
|
||||||
|
|
||||||
ClassFile c2 = inject.toObClass(c);
|
|
||||||
return c2.findField(obfuscatedName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InjectionException(String.format("Mapped field \"%s\" could not be found.", name));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,11 +35,6 @@ import static org.mockito.Mockito.when;
|
|||||||
|
|
||||||
public class InjectConstructTest
|
public class InjectConstructTest
|
||||||
{
|
{
|
||||||
interface APIClass
|
|
||||||
{
|
|
||||||
APIClass create();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInjectConstruct() throws Exception
|
public void testInjectConstruct() throws Exception
|
||||||
{
|
{
|
||||||
@@ -60,4 +55,9 @@ public class InjectConstructTest
|
|||||||
assertNotNull(targetClass.findMethod("create"));
|
assertNotNull(targetClass.findMethod("create"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface APIClass
|
||||||
|
{
|
||||||
|
APIClass create();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,13 +44,6 @@ import static org.mockito.Mockito.when;
|
|||||||
|
|
||||||
public class InjectSetterTest
|
public class InjectSetterTest
|
||||||
{
|
{
|
||||||
interface APIClass
|
|
||||||
{
|
|
||||||
void setTest(int i);
|
|
||||||
|
|
||||||
void setTestObject(Object str);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInjectSetterInt() throws NoSuchMethodException
|
public void testInjectSetterInt() throws NoSuchMethodException
|
||||||
{
|
{
|
||||||
@@ -113,4 +106,11 @@ public class InjectSetterTest
|
|||||||
.isPresent());
|
.isPresent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface APIClass
|
||||||
|
{
|
||||||
|
void setTest(int i);
|
||||||
|
|
||||||
|
void setTestObject(Object str);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,9 @@ import static org.objectweb.asm.Opcodes.ACC_STATIC;
|
|||||||
@ObfuscatedName("net/runelite/injector/VanillaTarget")
|
@ObfuscatedName("net/runelite/injector/VanillaTarget")
|
||||||
class DeobTarget
|
class DeobTarget
|
||||||
{
|
{
|
||||||
|
@ObfuscatedName("ob_foo4")
|
||||||
|
private static int foo4;
|
||||||
|
|
||||||
@ObfuscatedName("ob_foo3")
|
@ObfuscatedName("ob_foo3")
|
||||||
@ObfuscatedSignature(
|
@ObfuscatedSignature(
|
||||||
signature = "(I)V",
|
signature = "(I)V",
|
||||||
@@ -63,13 +66,12 @@ class DeobTarget
|
|||||||
// De-obfuscated foo3
|
// De-obfuscated foo3
|
||||||
System.out.println("foo3");
|
System.out.println("foo3");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ObfuscatedName("ob_foo4")
|
|
||||||
private static int foo4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class VanillaTarget
|
class VanillaTarget
|
||||||
{
|
{
|
||||||
|
private static int ob_foo4;
|
||||||
|
|
||||||
private void ob_foo3(int garbageValue)
|
private void ob_foo3(int garbageValue)
|
||||||
{
|
{
|
||||||
// Obfuscated foo3
|
// Obfuscated foo3
|
||||||
@@ -79,14 +81,14 @@ class VanillaTarget
|
|||||||
}
|
}
|
||||||
System.out.println("foo3");
|
System.out.println("foo3");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int ob_foo4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class Source
|
abstract class Source
|
||||||
{
|
{
|
||||||
@net.runelite.api.mixins.Inject
|
@net.runelite.api.mixins.Inject
|
||||||
private static int foo;
|
private static int foo;
|
||||||
|
@Shadow("foo4")
|
||||||
|
private static int foo4;
|
||||||
|
|
||||||
@net.runelite.api.mixins.Inject
|
@net.runelite.api.mixins.Inject
|
||||||
private void foo2()
|
private void foo2()
|
||||||
@@ -103,9 +105,6 @@ abstract class Source
|
|||||||
System.out.println(foo4);
|
System.out.println(foo4);
|
||||||
foo3();
|
foo3();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Shadow("foo4")
|
|
||||||
private static int foo4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test shadowing the "foo" field injected by Source
|
// Test shadowing the "foo" field injected by Source
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class RuneLite
|
public class RuneLite
|
||||||
{
|
{
|
||||||
public static final String RUNELIT_VERSION = "0.1.2";
|
public static final String RUNELIT_VERSION = "2.0.0";
|
||||||
public static final File RUNELITE_DIR = new File(System.getProperty("user.home"), ".runelite");
|
public static final File RUNELITE_DIR = new File(System.getProperty("user.home"), ".runelite");
|
||||||
public static final File PROFILES_DIR = new File(RUNELITE_DIR, "profiles");
|
public static final File PROFILES_DIR = new File(RUNELITE_DIR, "profiles");
|
||||||
public static final File PLUGIN_DIR = new File(RUNELITE_DIR, "plugins");
|
public static final File PLUGIN_DIR = new File(RUNELITE_DIR, "plugins");
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ public class SessionManager
|
|||||||
|
|
||||||
// Check if session is still valid
|
// Check if session is still valid
|
||||||
AccountClient accountClient = new AccountClient(session.getUuid());
|
AccountClient accountClient = new AccountClient(session.getUuid());
|
||||||
if (!accountClient.sesssionCheck())
|
if (!accountClient.sessionCheck())
|
||||||
{
|
{
|
||||||
log.debug("Loaded session {} is invalid", session.getUuid());
|
log.debug("Loaded session {} is invalid", session.getUuid());
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ public class AnagramClue extends ClueScroll implements TextClueScroll, NpcClueSc
|
|||||||
new AnagramClue("HE DO POSE. IT IS CULTRRL, MK?", "Riki the sculptor's model", new WorldPoint(2904, 10206, 0), "East Keldagrim, south of kebab seller."),
|
new AnagramClue("HE DO POSE. IT IS CULTRRL, MK?", "Riki the sculptor's model", new WorldPoint(2904, 10206, 0), "East Keldagrim, south of kebab seller."),
|
||||||
new AnagramClue("HEORIC", "Eohric", new WorldPoint(2900, 3565, 0), "Top floor of Burthorpe Castle", "36"),
|
new AnagramClue("HEORIC", "Eohric", new WorldPoint(2900, 3565, 0), "Top floor of Burthorpe Castle", "36"),
|
||||||
new AnagramClue("HIS PHOR", "Horphis", new WorldPoint(1639, 3812, 0), "Arceuus Library, Zeah", "1"),
|
new AnagramClue("HIS PHOR", "Horphis", new WorldPoint(1639, 3812, 0), "Arceuus Library, Zeah", "1"),
|
||||||
new AnagramClue("I AM SIR", "Marisi", new WorldPoint(1813, 3488, 0), "Allotment patch, South coast Zeah", "5"),
|
new AnagramClue("I AM SIR", "Marisi", new WorldPoint(1737, 3557, 0), "Allotment patch, South of Hosidius chapel", "5"),
|
||||||
new AnagramClue("ICY FE", "Fycie", new WorldPoint(2630, 2997, 0), "East Feldip Hills"),
|
new AnagramClue("ICY FE", "Fycie", new WorldPoint(2630, 2997, 0), "East Feldip Hills"),
|
||||||
new AnagramClue("I DOOM ICON INN", "Dominic Onion", new WorldPoint(2609, 3116, 0), "Nightmare Zone", "9,500"),
|
new AnagramClue("I DOOM ICON INN", "Dominic Onion", new WorldPoint(2609, 3116, 0), "Nightmare Zone", "9,500"),
|
||||||
new AnagramClue("I EAT ITS CHART HINTS DO U", "Shiratti the Custodian", new WorldPoint(3427, 2927, 0), "North of fountain, Nardah"),
|
new AnagramClue("I EAT ITS CHART HINTS DO U", "Shiratti the Custodian", new WorldPoint(3427, 2927, 0), "North of fountain, Nardah"),
|
||||||
|
|||||||
@@ -166,6 +166,7 @@ public class CoordinateClue extends ClueScroll implements TextClueScroll, Locati
|
|||||||
.put(new WorldPoint(3380, 3963, 0), "Wilderness. North of Volcano.")
|
.put(new WorldPoint(3380, 3963, 0), "Wilderness. North of Volcano.")
|
||||||
.put(new WorldPoint(3051, 3736, 0), "East of the Wilderness Obelisk in 28 Wilderness.")
|
.put(new WorldPoint(3051, 3736, 0), "East of the Wilderness Obelisk in 28 Wilderness.")
|
||||||
.put(new WorldPoint(2316, 3814, 0), "West of Neitiznot, near the bridge.")
|
.put(new WorldPoint(2316, 3814, 0), "West of Neitiznot, near the bridge.")
|
||||||
|
.put(new WorldPoint(2872, 3937, 0), "Weiss.")
|
||||||
// Master
|
// Master
|
||||||
.put(new WorldPoint(2178, 3209, 0), "South of Elf Camp.")
|
.put(new WorldPoint(2178, 3209, 0), "South of Elf Camp.")
|
||||||
.put(new WorldPoint(2155, 3100, 0), "South of Port Tyras (BJS).")
|
.put(new WorldPoint(2155, 3100, 0), "South of Port Tyras (BJS).")
|
||||||
@@ -181,7 +182,7 @@ public class CoordinateClue extends ClueScroll implements TextClueScroll, Locati
|
|||||||
.put(new WorldPoint(3085, 3569, 0), "Wilderness. Obelisk of Air.")
|
.put(new WorldPoint(3085, 3569, 0), "Wilderness. Obelisk of Air.")
|
||||||
.put(new WorldPoint(2934, 2727, 0), "Eastern shore of Crash Island.")
|
.put(new WorldPoint(2934, 2727, 0), "Eastern shore of Crash Island.")
|
||||||
.put(new WorldPoint(1451, 3695, 0), "West side of Lizardman Canyon with Lizardman shaman.")
|
.put(new WorldPoint(1451, 3695, 0), "West side of Lizardman Canyon with Lizardman shaman.")
|
||||||
.put(new WorldPoint(2538, 3739, 0), "Waterbirth Island.")
|
.put(new WorldPoint(2538, 3739, 0), "Waterbirth Island. Bring a pet rock and rune thrownaxe.")
|
||||||
.put(new WorldPoint(1698, 3792, 0), "Arceuus church.")
|
.put(new WorldPoint(1698, 3792, 0), "Arceuus church.")
|
||||||
.put(new WorldPoint(2951, 3820, 0), "Wilderness. Chaos Temple (level 38).")
|
.put(new WorldPoint(2951, 3820, 0), "Wilderness. Chaos Temple (level 38).")
|
||||||
.put(new WorldPoint(2202, 3825, 0), "Pirates' Cove, between Lunar Isle and Rellekka.")
|
.put(new WorldPoint(2202, 3825, 0), "Pirates' Cove, between Lunar Isle and Rellekka.")
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public class SceneOverlay extends Overlay
|
|||||||
private static final int MAP_SQUARE_SIZE = CHUNK_SIZE * CHUNK_SIZE; // 64
|
private static final int MAP_SQUARE_SIZE = CHUNK_SIZE * CHUNK_SIZE; // 64
|
||||||
private static final int CULL_CHUNK_BORDERS_RANGE = 16;
|
private static final int CULL_CHUNK_BORDERS_RANGE = 16;
|
||||||
private static final int STROKE_WIDTH = 4;
|
private static final int STROKE_WIDTH = 4;
|
||||||
private static final int CULL_LINE_OF_SIGHT_RANGE = 10;
|
private static final int CULL_LINE_OF_SIGHT_RANGE = 20;
|
||||||
private static final int INTERACTING_SHIFT = -16;
|
private static final int INTERACTING_SHIFT = -16;
|
||||||
|
|
||||||
private static final Polygon ARROW_HEAD = new Polygon(
|
private static final Polygon ARROW_HEAD = new Polygon(
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ enum DiscordGameEventType
|
|||||||
TRAINING_COOKING(Skill.COOKING),
|
TRAINING_COOKING(Skill.COOKING),
|
||||||
TRAINING_WOODCUTTING(Skill.WOODCUTTING),
|
TRAINING_WOODCUTTING(Skill.WOODCUTTING),
|
||||||
TRAINING_FLETCHING(Skill.FLETCHING),
|
TRAINING_FLETCHING(Skill.FLETCHING),
|
||||||
TRAINING_FISHING(Skill.FISHING),
|
TRAINING_FISHING(Skill.FISHING, 1),
|
||||||
TRAINING_FIREMAKING(Skill.FIREMAKING),
|
TRAINING_FIREMAKING(Skill.FIREMAKING),
|
||||||
TRAINING_CRAFTING(Skill.CRAFTING),
|
TRAINING_CRAFTING(Skill.CRAFTING),
|
||||||
TRAINING_SMITHING(Skill.SMITHING),
|
TRAINING_SMITHING(Skill.SMITHING),
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package net.runelite.client.plugins.implings;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.client.ui.overlay.Overlay;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||||
|
import net.runelite.client.ui.overlay.components.table.TableAlignment;
|
||||||
|
import net.runelite.client.ui.overlay.components.table.TableComponent;
|
||||||
|
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||||
|
|
||||||
|
public class ImplingCounterOverlay extends Overlay
|
||||||
|
{
|
||||||
|
private final Client client;
|
||||||
|
private final ImplingsPlugin plugin;
|
||||||
|
private final ImplingsConfig config;
|
||||||
|
|
||||||
|
private final PanelComponent panelComponent = new PanelComponent();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ImplingCounterOverlay(Client client, ImplingsConfig config, ImplingsPlugin plugin)
|
||||||
|
{
|
||||||
|
this.client = client;
|
||||||
|
this.config = config;
|
||||||
|
this.plugin = plugin;
|
||||||
|
setPosition(OverlayPosition.TOP_LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension render(Graphics2D graphics)
|
||||||
|
{
|
||||||
|
if (!config.showCounter() || plugin.getImplings().isEmpty())
|
||||||
|
return null;
|
||||||
|
|
||||||
|
panelComponent.getChildren().clear();
|
||||||
|
|
||||||
|
TableComponent tableComponent = new TableComponent();
|
||||||
|
tableComponent.setColumnAlignments(TableAlignment.LEFT, TableAlignment.RIGHT);
|
||||||
|
|
||||||
|
for (Map.Entry<ImplingType, Integer> entry : plugin.getImplingCounterMap().entrySet())
|
||||||
|
{
|
||||||
|
if (plugin.showImplingType(entry.getKey()) && entry.getValue() != 0)
|
||||||
|
{
|
||||||
|
tableComponent.addRow(entry.getKey().getName(), entry.getValue().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panelComponent.getChildren().add(tableComponent);
|
||||||
|
return panelComponent.render(graphics);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -320,4 +320,15 @@ public interface ImplingsConfig extends Config
|
|||||||
{
|
{
|
||||||
return Color.WHITE;
|
return Color.WHITE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
position = 26,
|
||||||
|
keyName = "showCounter",
|
||||||
|
name = "Show impling counter overlay",
|
||||||
|
description = "Shows how many of each impling there is nearby"
|
||||||
|
)
|
||||||
|
default boolean showCounter()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,11 +30,13 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.HashMap;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.runelite.api.GameState;
|
import net.runelite.api.GameState;
|
||||||
import net.runelite.api.NPC;
|
import net.runelite.api.NPC;
|
||||||
|
import net.runelite.api.events.GameTick;
|
||||||
import net.runelite.api.events.GameStateChanged;
|
import net.runelite.api.events.GameStateChanged;
|
||||||
import net.runelite.api.events.NpcDespawned;
|
import net.runelite.api.events.NpcDespawned;
|
||||||
import net.runelite.api.events.NpcSpawned;
|
import net.runelite.api.events.NpcSpawned;
|
||||||
@@ -58,6 +60,9 @@ public class ImplingsPlugin extends Plugin
|
|||||||
private static final int DYNAMIC_SPAWN_ECLECTIC = 1633;
|
private static final int DYNAMIC_SPAWN_ECLECTIC = 1633;
|
||||||
private static final int DYNAMIC_SPAWN_BABY_ESSENCE = 1634;
|
private static final int DYNAMIC_SPAWN_BABY_ESSENCE = 1634;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private Map<ImplingType, Integer> implingCounterMap = new HashMap<>();
|
||||||
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
@Getter(AccessLevel.PACKAGE)
|
||||||
private final List<NPC> implings = new ArrayList<>();
|
private final List<NPC> implings = new ArrayList<>();
|
||||||
|
|
||||||
@@ -67,6 +72,10 @@ public class ImplingsPlugin extends Plugin
|
|||||||
@Inject
|
@Inject
|
||||||
private ImplingsOverlay overlay;
|
private ImplingsOverlay overlay;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ImplingCounterOverlay implingCounterOverlay;
|
||||||
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private OverlayManager overlayManager;
|
private OverlayManager overlayManager;
|
||||||
|
|
||||||
@@ -91,6 +100,7 @@ public class ImplingsPlugin extends Plugin
|
|||||||
|
|
||||||
overlayManager.add(overlay);
|
overlayManager.add(overlay);
|
||||||
overlayManager.add(minimapOverlay);
|
overlayManager.add(minimapOverlay);
|
||||||
|
overlayManager.add(implingCounterOverlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -98,6 +108,27 @@ public class ImplingsPlugin extends Plugin
|
|||||||
{
|
{
|
||||||
overlayManager.remove(overlay);
|
overlayManager.remove(overlay);
|
||||||
overlayManager.remove(minimapOverlay);
|
overlayManager.remove(minimapOverlay);
|
||||||
|
overlayManager.remove(implingCounterOverlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onGameTick(GameTick event)
|
||||||
|
{
|
||||||
|
implingCounterMap.clear();
|
||||||
|
for (NPC npc : implings)
|
||||||
|
{
|
||||||
|
Impling impling = Impling.findImpling(npc.getId());
|
||||||
|
|
||||||
|
ImplingType type = impling.getImplingType();
|
||||||
|
if (implingCounterMap.containsKey(type))
|
||||||
|
{
|
||||||
|
implingCounterMap.put(type, implingCounterMap.get(type) + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
implingCounterMap.put(type, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
@@ -118,6 +149,7 @@ public class ImplingsPlugin extends Plugin
|
|||||||
if (event.getGameState() == GameState.LOGIN_SCREEN || event.getGameState() == GameState.HOPPING)
|
if (event.getGameState() == GameState.LOGIN_SCREEN || event.getGameState() == GameState.HOPPING)
|
||||||
{
|
{
|
||||||
implings.clear();
|
implings.clear();
|
||||||
|
implingCounterMap.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,6 +163,7 @@ public class ImplingsPlugin extends Plugin
|
|||||||
|
|
||||||
NPC npc = npcDespawned.getNpc();
|
NPC npc = npcDespawned.getNpc();
|
||||||
implings.remove(npc);
|
implings.remove(npc);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean showNpc(NPC npc)
|
boolean showNpc(NPC npc)
|
||||||
@@ -183,7 +216,12 @@ public class ImplingsPlugin extends Plugin
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (impling.getImplingType())
|
return typeToColor(impling.getImplingType());
|
||||||
|
}
|
||||||
|
|
||||||
|
Color typeToColor(ImplingType type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
{
|
{
|
||||||
|
|
||||||
case BABY:
|
case BABY:
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Jacky <liangj97@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.plugins.inferno;
|
||||||
|
|
||||||
|
import net.runelite.client.config.Config;
|
||||||
|
import net.runelite.client.config.ConfigGroup;
|
||||||
|
import net.runelite.client.config.ConfigItem;
|
||||||
|
|
||||||
|
@ConfigGroup("inferno")
|
||||||
|
public interface InfernoConfig extends Config
|
||||||
|
{
|
||||||
|
@ConfigItem(
|
||||||
|
position = 0,
|
||||||
|
keyName = "Nibbler Overlay",
|
||||||
|
name = "Nibbler Overlay",
|
||||||
|
description = "Shows if there are any Nibblers left"
|
||||||
|
)
|
||||||
|
default boolean displayNibblerOverlay()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
position = 1,
|
||||||
|
keyName = "Prayer Helper",
|
||||||
|
name = "Prayer Helper",
|
||||||
|
description = "Tells you what to flick in how many ticks"
|
||||||
|
)
|
||||||
|
default boolean showPrayerHelp()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Jacky <liangj97@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.plugins.inferno;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.client.ui.overlay.Overlay;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||||
|
import net.runelite.client.ui.overlay.components.table.TableAlignment;
|
||||||
|
import net.runelite.client.ui.overlay.components.table.TableComponent;
|
||||||
|
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||||
|
|
||||||
|
public class InfernoInfobox extends Overlay
|
||||||
|
{
|
||||||
|
private final Client client;
|
||||||
|
private final InfernoPlugin plugin;
|
||||||
|
private final InfernoConfig config;
|
||||||
|
|
||||||
|
private final PanelComponent panelComponent = new PanelComponent();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public InfernoInfobox(Client client, InfernoConfig config, InfernoPlugin plugin)
|
||||||
|
{
|
||||||
|
this.client = client;
|
||||||
|
this.config = config;
|
||||||
|
this.plugin = plugin;
|
||||||
|
setPosition(OverlayPosition.TOP_LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension render(Graphics2D graphics)
|
||||||
|
{
|
||||||
|
if (!config.showPrayerHelp() || client.getMapRegions()[0] != 9043) return null;
|
||||||
|
|
||||||
|
panelComponent.getChildren().clear();
|
||||||
|
TableComponent tableComponent = new TableComponent();
|
||||||
|
tableComponent.setColumnAlignments(TableAlignment.LEFT, TableAlignment.RIGHT);
|
||||||
|
|
||||||
|
for (int i = plugin.getPriorityNPC().length; i > 0; i--)
|
||||||
|
{
|
||||||
|
if (plugin.getPriorityNPC()[i - 1] == null)
|
||||||
|
{
|
||||||
|
tableComponent.addRow(Integer.toString(i), "-");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tableComponent.addRow(plugin.getPriorityNPC()[i - 1].getName(), plugin.getPriorityNPC()[i - 1 ].getAttackstyle().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panelComponent.getChildren().add(tableComponent);
|
||||||
|
return panelComponent.render(graphics);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,185 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Jacky <liangj97@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.plugins.inferno;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import net.runelite.api.NPC;
|
||||||
|
import net.runelite.api.NpcID;
|
||||||
|
|
||||||
|
public class InfernoNPC
|
||||||
|
{
|
||||||
|
public enum Attackstyle
|
||||||
|
{
|
||||||
|
MAGE("Mage", Color.CYAN),
|
||||||
|
RANGE("Range", Color.GREEN),
|
||||||
|
MELEE("Melee", Color.WHITE),
|
||||||
|
RANDOM("Random", Color.ORANGE);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private String name = "";
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private Color color;
|
||||||
|
|
||||||
|
Attackstyle(String s, Color c)
|
||||||
|
{
|
||||||
|
this.name = s;
|
||||||
|
this.color = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private NPC npc;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private Attackstyle attackstyle;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private int attackTicks;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private int priority;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private int ticksTillAttack = -1;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private boolean attacking = false;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private int attackAnimation;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private boolean isMidAttack = false;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private int distanceToPlayer = 0;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
int textLocHeight;
|
||||||
|
|
||||||
|
public InfernoNPC(NPC npc)
|
||||||
|
{
|
||||||
|
this.npc = npc;
|
||||||
|
textLocHeight = npc.getLogicalHeight() + 40;
|
||||||
|
switch (npc.getId())
|
||||||
|
{
|
||||||
|
case NpcID.JALAKREKKET:
|
||||||
|
attackTicks = 4;
|
||||||
|
name = "lil mel";
|
||||||
|
attackAnimation = 7582;
|
||||||
|
attackstyle = Attackstyle.MELEE;
|
||||||
|
priority = 7;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NpcID.JALAKREKXIL:
|
||||||
|
attackTicks = 4;
|
||||||
|
name = "lil range";
|
||||||
|
attackAnimation = 7583;
|
||||||
|
attackstyle = Attackstyle.RANGE;
|
||||||
|
priority = 6;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NpcID.JALAKREKMEJ:
|
||||||
|
attackTicks = 4;
|
||||||
|
name = "lil mage";
|
||||||
|
attackAnimation = 7581;
|
||||||
|
attackstyle = Attackstyle.MAGE;
|
||||||
|
priority = 5;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NpcID.JALMEJRAH:
|
||||||
|
attackTicks = 3;
|
||||||
|
name = "bat";
|
||||||
|
attackAnimation = 7578;
|
||||||
|
attackstyle = Attackstyle.RANGE;
|
||||||
|
priority = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NpcID.JALAK:
|
||||||
|
attackTicks = 6;
|
||||||
|
name = "blob";
|
||||||
|
attackAnimation = 7583; // also 7581
|
||||||
|
attackstyle = Attackstyle.RANDOM;
|
||||||
|
priority = 3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NpcID.JALIMKOT:
|
||||||
|
attackTicks = 4;
|
||||||
|
name = "meleer";
|
||||||
|
attackAnimation = 7597;
|
||||||
|
attackstyle = Attackstyle.MELEE;
|
||||||
|
priority = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NpcID.JALXIL:
|
||||||
|
attackTicks = 4;
|
||||||
|
name = "ranger";
|
||||||
|
attackAnimation = 7605;
|
||||||
|
attackstyle = Attackstyle.RANGE;
|
||||||
|
priority = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NpcID.JALZEK:
|
||||||
|
attackTicks = 4;
|
||||||
|
name = "mager";
|
||||||
|
attackAnimation = 7610;
|
||||||
|
attackstyle = Attackstyle.MAGE;
|
||||||
|
priority = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
attackTicks = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String info()
|
||||||
|
{
|
||||||
|
String info = "";
|
||||||
|
|
||||||
|
if (attacking)
|
||||||
|
{
|
||||||
|
info += ticksTillAttack;
|
||||||
|
}
|
||||||
|
//info += " D: " + distanceToPlayer;
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void attacked()
|
||||||
|
{
|
||||||
|
ticksTillAttack = attackTicks;
|
||||||
|
attacking = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Jacky <liangj97@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.plugins.inferno;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.client.ui.overlay.Overlay;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||||
|
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||||
|
import net.runelite.client.ui.overlay.components.table.TableAlignment;
|
||||||
|
import net.runelite.client.ui.overlay.components.table.TableComponent;
|
||||||
|
|
||||||
|
public class InfernoNibblerOverlay extends Overlay
|
||||||
|
{
|
||||||
|
private final Client client;
|
||||||
|
private final InfernoPlugin plugin;
|
||||||
|
private final InfernoConfig config;
|
||||||
|
|
||||||
|
private final PanelComponent panelComponent = new PanelComponent();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public InfernoNibblerOverlay(Client client, InfernoConfig config, InfernoPlugin plugin)
|
||||||
|
{
|
||||||
|
this.client = client;
|
||||||
|
this.config = config;
|
||||||
|
this.plugin = plugin;
|
||||||
|
setPosition(OverlayPosition.TOP_LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension render(Graphics2D graphics)
|
||||||
|
{
|
||||||
|
if (!config.displayNibblerOverlay() || plugin.getNibblers().size() == 0 || client.getMapRegions()[0] != 9043)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
panelComponent.getChildren().clear();
|
||||||
|
TableComponent tableComponent = new TableComponent();
|
||||||
|
tableComponent.setColumnAlignments(TableAlignment.LEFT, TableAlignment.RIGHT);
|
||||||
|
|
||||||
|
tableComponent.addRow("Nibblers Left: ", Integer.toString(plugin.getNibblers().size()));
|
||||||
|
|
||||||
|
panelComponent.getChildren().add(tableComponent);
|
||||||
|
|
||||||
|
return panelComponent.render(graphics);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Jacky <liangj97@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.plugins.inferno;
|
||||||
|
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.NPC;
|
||||||
|
import net.runelite.api.Perspective;
|
||||||
|
import net.runelite.api.Point;
|
||||||
|
import net.runelite.api.coords.LocalPoint;
|
||||||
|
import net.runelite.client.ui.overlay.Overlay;
|
||||||
|
|
||||||
|
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||||
|
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||||
|
|
||||||
|
public class InfernoOverlay extends Overlay
|
||||||
|
{
|
||||||
|
private final Client client;
|
||||||
|
private final InfernoPlugin plugin;
|
||||||
|
private final InfernoConfig config;
|
||||||
|
private final PanelComponent panelComponent = new PanelComponent();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public InfernoOverlay(Client client, InfernoConfig config, InfernoPlugin plugin)
|
||||||
|
{
|
||||||
|
setPosition(OverlayPosition.DYNAMIC);
|
||||||
|
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||||
|
this.client = client;
|
||||||
|
this.config = config;
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension render(Graphics2D graphics)
|
||||||
|
{
|
||||||
|
if (!client.isInInstancedRegion() || client.getMapRegions()[0] != 9043) return null;
|
||||||
|
|
||||||
|
for (InfernoNPC monster : plugin.getMonsters().values())
|
||||||
|
{
|
||||||
|
NPC npc = monster.getNpc();
|
||||||
|
//if (npc == null || !config.showPrayer()) return;
|
||||||
|
LocalPoint lp = npc.getLocalLocation();
|
||||||
|
if (lp != null)
|
||||||
|
{
|
||||||
|
Point point = Perspective.localToCanvas(client, lp, client.getPlane(), npc.getLogicalHeight());
|
||||||
|
if (point != null)
|
||||||
|
{
|
||||||
|
if (monster.getTicksTillAttack() == 1 || (monster.getName().equals("blob") && monster.getTicksTillAttack() <= 3))
|
||||||
|
{
|
||||||
|
renderTextLocation(graphics, monster, monster.info(), Color.GREEN);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
renderTextLocation(graphics, monster, monster.info(), Color.RED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// renders text location
|
||||||
|
public static void renderTextLocation(Graphics2D graphics, InfernoNPC actor, String text, Color color)
|
||||||
|
{
|
||||||
|
graphics.setFont(new Font("Arial", Font.BOLD, 15));
|
||||||
|
Point textLocation = actor.getNpc().getCanvasTextLocation(graphics, text, actor.textLocHeight + 40);
|
||||||
|
if (Strings.isNullOrEmpty(text))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int x = textLocation.getX();
|
||||||
|
int y = textLocation.getY();
|
||||||
|
|
||||||
|
graphics.setColor(Color.BLACK);
|
||||||
|
graphics.drawString(text, x + 1, y + 1);
|
||||||
|
|
||||||
|
graphics.setColor(color);
|
||||||
|
graphics.drawString(text, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,275 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Jacky <liangj97@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.plugins.inferno;
|
||||||
|
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import lombok.Getter;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.HeadIcon;
|
||||||
|
import net.runelite.api.NPC;
|
||||||
|
import net.runelite.api.NpcID;
|
||||||
|
import net.runelite.api.events.GameTick;
|
||||||
|
import net.runelite.api.events.NpcDespawned;
|
||||||
|
import net.runelite.api.events.NpcSpawned;
|
||||||
|
import net.runelite.client.config.ConfigManager;
|
||||||
|
import net.runelite.client.eventbus.Subscribe;
|
||||||
|
import net.runelite.client.plugins.Plugin;
|
||||||
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
|
import net.runelite.client.plugins.PluginType;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayManager;
|
||||||
|
|
||||||
|
@PluginDescriptor(
|
||||||
|
name = "Inferno",
|
||||||
|
description = "Inferno helper",
|
||||||
|
tags = {"combat", "overlay", "pve", "pvm"},
|
||||||
|
type = PluginType.PVM
|
||||||
|
)
|
||||||
|
public class InfernoPlugin extends Plugin
|
||||||
|
{
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Client client;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private OverlayManager overlayManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private InfernoOverlay infernoOverlay;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private InfernoInfobox infernoInfobox;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private InfernoNibblerOverlay nibblerOverlay;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private InfernoConfig config;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private Map<NPC, InfernoNPC> monsters;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private Map<Integer, ArrayList<InfernoNPC>> monsterCurrentAttackMap;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private List<NPC> nibblers;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private InfernoNPC[] priorityNPC;
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
InfernoConfig provideConfig(ConfigManager configManager)
|
||||||
|
{
|
||||||
|
return configManager.getConfig(InfernoConfig.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void startUp() throws Exception
|
||||||
|
{
|
||||||
|
overlayManager.add(infernoOverlay);
|
||||||
|
overlayManager.add(infernoInfobox);
|
||||||
|
overlayManager.add(nibblerOverlay);
|
||||||
|
monsters = new HashMap<>();
|
||||||
|
monsterCurrentAttackMap = new HashMap<>(6);
|
||||||
|
for (int i = 1; i <= 6; i++)
|
||||||
|
{
|
||||||
|
monsterCurrentAttackMap.put(i, new ArrayList<>());
|
||||||
|
}
|
||||||
|
nibblers = new ArrayList<>();
|
||||||
|
priorityNPC = new InfernoNPC[4];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void shutDown() throws Exception
|
||||||
|
{
|
||||||
|
overlayManager.remove(infernoInfobox);
|
||||||
|
overlayManager.remove(infernoOverlay);
|
||||||
|
overlayManager.remove(nibblerOverlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onNpcSpawned(NpcSpawned event)
|
||||||
|
{
|
||||||
|
if (client.getMapRegions()[0] != 9043) return;
|
||||||
|
|
||||||
|
NPC npc = event.getNpc();
|
||||||
|
if (isValidInfernoMob(npc))
|
||||||
|
{
|
||||||
|
monsters.put(npc, new InfernoNPC(npc));
|
||||||
|
System.out.println(monsters.size());
|
||||||
|
}
|
||||||
|
if (npc.getId() == NpcID.JALNIB)
|
||||||
|
{
|
||||||
|
nibblers.add(npc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onNpcDespawned(NpcDespawned event)
|
||||||
|
{
|
||||||
|
if (client.getMapRegions()[0] != 9043) return;
|
||||||
|
|
||||||
|
NPC npc = event.getNpc();
|
||||||
|
if (monsters.containsKey(npc))
|
||||||
|
{
|
||||||
|
monsters.remove(npc);
|
||||||
|
System.out.println(monsters.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (npc.getId() == NpcID.JALNIB)
|
||||||
|
{
|
||||||
|
nibblers.remove(npc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onGameTick(GameTick event)
|
||||||
|
{
|
||||||
|
if (client.getMapRegions()[0] != 9043) return;
|
||||||
|
|
||||||
|
clearMapAndPriority();
|
||||||
|
|
||||||
|
for (InfernoNPC monster : monsters.values())
|
||||||
|
{
|
||||||
|
calculateDistanceToPlayer(monster);
|
||||||
|
|
||||||
|
NPC npc = monster.getNpc();
|
||||||
|
|
||||||
|
// if they are not attacking but are still attacking
|
||||||
|
if (monster.isAttacking())
|
||||||
|
{
|
||||||
|
monster.setTicksTillAttack(monster.getTicksTillAttack() - 1);
|
||||||
|
|
||||||
|
// sets the blobs attack style
|
||||||
|
if (monster.getName().equals("blob") && monster.getTicksTillAttack() == 3 && monster.getDistanceToPlayer() <= 15)
|
||||||
|
{
|
||||||
|
if (client.getLocalPlayer().getOverheadIcon() == null)
|
||||||
|
{
|
||||||
|
monster.setAttackstyle(InfernoNPC.Attackstyle.RANDOM);
|
||||||
|
}
|
||||||
|
else if (client.getLocalPlayer().getOverheadIcon().equals(HeadIcon.MAGIC))
|
||||||
|
{
|
||||||
|
monster.setAttackstyle(InfernoNPC.Attackstyle.RANGE);
|
||||||
|
}
|
||||||
|
else if (client.getLocalPlayer().getOverheadIcon().equals(HeadIcon.RANGED))
|
||||||
|
{
|
||||||
|
monster.setAttackstyle(InfernoNPC.Attackstyle.MAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we know the monster is not attacking because it should have attacked and is idling
|
||||||
|
if (monster.getTicksTillAttack() == 0)
|
||||||
|
{
|
||||||
|
if (npc.getAnimation() == -1)
|
||||||
|
{
|
||||||
|
monster.setAttacking(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// want to reset the monsters attack back to attacking
|
||||||
|
monster.attacked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// they've just attacked
|
||||||
|
if (npc.getAnimation() == monster.getAttackAnimation() || npc.getAnimation() == 7581) // special case for blob
|
||||||
|
{
|
||||||
|
monster.attacked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (monster.getTicksTillAttack() >= 1)
|
||||||
|
{
|
||||||
|
monsterCurrentAttackMap.get(monster.getTicksTillAttack()).add(monster);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
calculatePriorityNPC();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void calculatePriorityNPC()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < priorityNPC.length; i++)
|
||||||
|
{
|
||||||
|
ArrayList<InfernoNPC> monsters = monsterCurrentAttackMap.get(i + 1);
|
||||||
|
|
||||||
|
if ( monsters.size() == 0) continue;
|
||||||
|
|
||||||
|
int priority = monsters.get(0).getPriority();
|
||||||
|
|
||||||
|
InfernoNPC infernoNPC = monsters.get(0);
|
||||||
|
|
||||||
|
for (InfernoNPC npc : monsters)
|
||||||
|
{
|
||||||
|
if (npc.getPriority() < priority)
|
||||||
|
{
|
||||||
|
priority = npc.getPriority();
|
||||||
|
infernoNPC = npc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
priorityNPC[i] = infernoNPC;
|
||||||
|
System.out.println("i: " + i + " " + infernoNPC.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: blob calculator
|
||||||
|
private void calculateDistanceToPlayer(InfernoNPC monster)
|
||||||
|
{
|
||||||
|
monster.setDistanceToPlayer(client.getLocalPlayer().getWorldLocation().distanceTo(monster.getNpc().getWorldArea()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearMapAndPriority()
|
||||||
|
{
|
||||||
|
for (List<InfernoNPC> l : monsterCurrentAttackMap.values())
|
||||||
|
{
|
||||||
|
l.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < priorityNPC.length; i++)
|
||||||
|
{
|
||||||
|
priorityNPC[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValidInfernoMob(NPC npc)
|
||||||
|
{
|
||||||
|
// we only want the bat, blob, melee, ranger and mager
|
||||||
|
if (npc.getId() == NpcID.JALMEJRAH ||
|
||||||
|
npc.getId() == NpcID.JALAK ||
|
||||||
|
npc.getId() == NpcID.JALIMKOT ||
|
||||||
|
npc.getId() == NpcID.JALXIL ||
|
||||||
|
npc.getId() == NpcID.JALZEK) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -107,7 +107,10 @@ class KeyRemappingListener extends MouseAdapter implements KeyListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.fkeyRemap())
|
// In addition to the above checks, the F-key remapping shouldn't
|
||||||
|
// activate when dialogs are open which listen for number keys
|
||||||
|
// to select options
|
||||||
|
if (config.fkeyRemap() && !plugin.isDialogOpen())
|
||||||
{
|
{
|
||||||
if (ONE.matches(e))
|
if (ONE.matches(e))
|
||||||
{
|
{
|
||||||
@@ -188,23 +191,18 @@ class KeyRemappingListener extends MouseAdapter implements KeyListener
|
|||||||
switch (e.getKeyCode())
|
switch (e.getKeyCode())
|
||||||
{
|
{
|
||||||
case KeyEvent.VK_ENTER:
|
case KeyEvent.VK_ENTER:
|
||||||
|
case KeyEvent.VK_ESCAPE:
|
||||||
plugin.setTyping(false);
|
plugin.setTyping(false);
|
||||||
clientThread.invoke(plugin::lockChat);
|
clientThread.invoke(plugin::lockChat);
|
||||||
break;
|
break;
|
||||||
case KeyEvent.VK_ESCAPE:
|
|
||||||
plugin.setTyping(false);
|
|
||||||
clientThread.invoke(() ->
|
|
||||||
{
|
|
||||||
client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, "");
|
|
||||||
plugin.lockChat();
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case KeyEvent.VK_BACK_SPACE:
|
case KeyEvent.VK_BACK_SPACE:
|
||||||
|
// Only lock chat on backspace when the typed text is now empty
|
||||||
if (Strings.isNullOrEmpty(client.getVar(VarClientStr.CHATBOX_TYPED_TEXT)))
|
if (Strings.isNullOrEmpty(client.getVar(VarClientStr.CHATBOX_TYPED_TEXT)))
|
||||||
{
|
{
|
||||||
plugin.setTyping(false);
|
plugin.setTyping(false);
|
||||||
clientThread.invoke(plugin::lockChat);
|
clientThread.invoke(plugin::lockChat);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,6 +135,26 @@ public class KeyRemappingPlugin extends Plugin
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a dialog is open that will grab numerical input, to prevent F-key remapping
|
||||||
|
* from triggering.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean isDialogOpen()
|
||||||
|
{
|
||||||
|
// Most chat dialogs with numerical input are added without the chatbox or its key listener being removed,
|
||||||
|
// so chatboxFocused() is true. The chatbox onkey script uses the following logic to ignore key presses,
|
||||||
|
// so we will use it too to not remap F-keys.
|
||||||
|
return isHidden(WidgetInfo.CHATBOX_MESSAGES) || isHidden(WidgetInfo.CHATBOX_TRANSPARENT_LINES);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isHidden(WidgetInfo widgetInfo)
|
||||||
|
{
|
||||||
|
Widget w = client.getWidget(widgetInfo);
|
||||||
|
return w == null || w.isSelfHidden();
|
||||||
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onScriptCallbackEvent(ScriptCallbackEvent scriptCallbackEvent)
|
public void onScriptCallbackEvent(ScriptCallbackEvent scriptCallbackEvent)
|
||||||
{
|
{
|
||||||
@@ -163,31 +183,25 @@ public class KeyRemappingPlugin extends Plugin
|
|||||||
|
|
||||||
void lockChat()
|
void lockChat()
|
||||||
{
|
{
|
||||||
Widget chatboxParent = client.getWidget(WidgetInfo.CHATBOX_PARENT);
|
Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT);
|
||||||
if (chatboxParent != null && chatboxParent.getOnKeyListener() != null)
|
if (chatboxInput != null)
|
||||||
{
|
{
|
||||||
Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT);
|
chatboxInput.setText(getPlayerNameWithIcon() + ": " + PRESS_ENTER_TO_CHAT);
|
||||||
if (chatboxInput != null)
|
// Typed text can be non-empty on plugin start, so clear it now
|
||||||
{
|
client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, "");
|
||||||
chatboxInput.setText(getPlayerNameWithIcon() + ": " + PRESS_ENTER_TO_CHAT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void unlockChat()
|
void unlockChat()
|
||||||
{
|
{
|
||||||
Widget chatboxParent = client.getWidget(WidgetInfo.CHATBOX_PARENT);
|
Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT);
|
||||||
if (chatboxParent != null)
|
if (chatboxInput != null)
|
||||||
{
|
{
|
||||||
Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT);
|
if (client.getGameState() == GameState.LOGGED_IN)
|
||||||
if (chatboxInput != null)
|
|
||||||
{
|
{
|
||||||
if (client.getGameState() == GameState.LOGGED_IN)
|
final boolean isChatboxTransparent = client.isResized() && client.getVar(Varbits.TRANSPARENT_CHATBOX) == 1;
|
||||||
{
|
final Color textColor = isChatboxTransparent ? JagexColors.CHAT_TYPED_TEXT_TRANSPARENT_BACKGROUND : JagexColors.CHAT_TYPED_TEXT_OPAQUE_BACKGROUND;
|
||||||
final boolean isChatboxTransparent = client.isResized() && client.getVar(Varbits.TRANSPARENT_CHATBOX) == 1;
|
chatboxInput.setText(getPlayerNameWithIcon() + ": " + ColorUtil.wrapWithColorTag(client.getVar(VarClientStr.CHATBOX_TYPED_TEXT) + "*", textColor));
|
||||||
final Color textColor = isChatboxTransparent ? JagexColors.CHAT_TYPED_TEXT_TRANSPARENT_BACKGROUND : JagexColors.CHAT_TYPED_TEXT_OPAQUE_BACKGROUND;
|
|
||||||
chatboxInput.setText(getPlayerNameWithIcon() + ": " + ColorUtil.wrapWithColorTag(client.getVar(VarClientStr.CHATBOX_TYPED_TEXT) + "*", textColor));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ import static net.runelite.api.ObjectID.ROCKS_11374;
|
|||||||
import static net.runelite.api.ObjectID.ROCKS_11375;
|
import static net.runelite.api.ObjectID.ROCKS_11375;
|
||||||
import static net.runelite.api.ObjectID.ROCKS_11376;
|
import static net.runelite.api.ObjectID.ROCKS_11376;
|
||||||
import static net.runelite.api.ObjectID.ROCKS_11377;
|
import static net.runelite.api.ObjectID.ROCKS_11377;
|
||||||
|
import static net.runelite.api.ObjectID.ROCKS_11386;
|
||||||
|
import static net.runelite.api.ObjectID.ROCKS_11387;
|
||||||
|
|
||||||
enum Rock
|
enum Rock
|
||||||
{
|
{
|
||||||
@@ -65,7 +67,9 @@ enum Rock
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
SILVER(Duration.ofMinutes(1), ROCKS_11369),
|
SILVER(Duration.ofMinutes(1), ROCKS_11369),
|
||||||
|
SANDSTONE(Duration.ofMillis(5400), ROCKS_11386),
|
||||||
GOLD(Duration.ofMinutes(1), ROCKS_11370, ROCKS_11371),
|
GOLD(Duration.ofMinutes(1), ROCKS_11370, ROCKS_11371),
|
||||||
|
GRANITE(Duration.ofMillis(5400), ROCKS_11387),
|
||||||
MITHRIL(Duration.ofMinutes(2), ROCKS_11372, ROCKS_11373)
|
MITHRIL(Duration.ofMinutes(2), ROCKS_11372, ROCKS_11373)
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -448,9 +448,7 @@ public class SpellbookPlugin extends Plugin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CHECKSTYLE:OFF
|
// CHECKSTYLE:OFF
|
||||||
Collection<Spell> gson = GSON.fromJson(cfg, new TypeToken<List<Spell>>()
|
Collection<Spell> gson = GSON.fromJson(cfg, new TypeToken<List<Spell>>() {}.getType());
|
||||||
{
|
|
||||||
}.getType());
|
|
||||||
// CHECKSTYLE:ON
|
// CHECKSTYLE:ON
|
||||||
gson.stream().filter(Objects::nonNull).forEach(s -> spells.put(s.getWidget(), s));
|
gson.stream().filter(Objects::nonNull).forEach(s -> spells.put(s.getWidget(), s));
|
||||||
|
|
||||||
@@ -465,7 +463,7 @@ public class SpellbookPlugin extends Plugin
|
|||||||
|
|
||||||
private void saveSpells()
|
private void saveSpells()
|
||||||
{
|
{
|
||||||
if (spells.isEmpty())
|
if (spells.isEmpty() || tmp == null || tmp.isEmpty())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ public class ClientLoader
|
|||||||
|
|
||||||
if (rs instanceof Client)
|
if (rs instanceof Client)
|
||||||
{
|
{
|
||||||
log.info("client-patch {}", "420 blaze it RL pricks");
|
log.info("client-patch 420 blaze it RL pricks");
|
||||||
}
|
}
|
||||||
|
|
||||||
return rs;
|
return rs;
|
||||||
@@ -274,7 +274,7 @@ public class ClientLoader
|
|||||||
{
|
{
|
||||||
FileOutputStream fileOutputStream = new FileOutputStream(INJECTED_CLIENT);
|
FileOutputStream fileOutputStream = new FileOutputStream(INJECTED_CLIENT);
|
||||||
fileOutputStream.getChannel()
|
fileOutputStream.getChannel()
|
||||||
.transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
|
.transferFrom(readableByteChannel, 0, Integer.MAX_VALUE);
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ public class RuneLiteSplashScreen
|
|||||||
panel.add(version, versionConstraints);
|
panel.add(version, versionConstraints);
|
||||||
|
|
||||||
// version
|
// version
|
||||||
final JLabel litVersion = new JLabel("Plus Version : PRE-" + RuneLite.RUNELIT_VERSION);
|
final JLabel litVersion = new JLabel("Plus Version : " + RuneLite.RUNELIT_VERSION);
|
||||||
litVersion.setForeground(Color.GREEN);
|
litVersion.setForeground(Color.GREEN);
|
||||||
litVersion.setFont(FontManager.getRunescapeSmallFont());
|
litVersion.setFont(FontManager.getRunescapeSmallFont());
|
||||||
litVersion.setForeground(litVersion.getForeground().darker());
|
litVersion.setForeground(litVersion.getForeground().darker());
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
package net.runelite.client.util.bootstrap;
|
package net.runelite.client.util.bootstrap;
|
||||||
|
|
||||||
public class Artifact {
|
public class Artifact
|
||||||
|
{
|
||||||
String hash;
|
String hash;
|
||||||
String name;
|
String name;
|
||||||
String path;
|
String path;
|
||||||
String size;
|
String size;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,328 +1,345 @@
|
|||||||
package net.runelite.client.util.bootstrap;
|
package net.runelite.client.util.bootstrap;
|
||||||
|
|
||||||
import net.runelite.http.api.RuneLiteAPI;
|
|
||||||
import sun.misc.BASE64Encoder;
|
|
||||||
|
|
||||||
import javax.xml.bind.DatatypeConverter;
|
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.ObjectOutputStream;
|
import java.io.ObjectOutputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.security.DigestInputStream;
|
import java.security.DigestInputStream;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import javax.xml.bind.DatatypeConverter;
|
||||||
|
import net.runelite.http.api.RuneLiteAPI;
|
||||||
|
|
||||||
public class Bootstrap {
|
public class Bootstrap
|
||||||
|
{
|
||||||
|
Artifact[] artifacts = getArtifacts();
|
||||||
|
Client client = new Client();
|
||||||
|
String[] clientJvm9Arguments = new String[]{
|
||||||
|
"-XX:+DisableAttachMechanism",
|
||||||
|
"-Xmx512m",
|
||||||
|
"-Xss2m",
|
||||||
|
"-XX:CompileThreshold=1500",
|
||||||
|
"-Djna.nosys=true"
|
||||||
|
};
|
||||||
|
String[] clientJvmArguments = new String[]{
|
||||||
|
"-XX:+DisableAttachMechanism",
|
||||||
|
"-Xmx512m",
|
||||||
|
"-Xss2m",
|
||||||
|
"-XX:CompileThreshold=1500",
|
||||||
|
"-Xincgc",
|
||||||
|
"-XX:+UseConcMarkSweepGC",
|
||||||
|
"-XX:+UseParNewGC",
|
||||||
|
"-Djna.nosys=true"};
|
||||||
|
String[] dependencyHashes;
|
||||||
|
String[] launcherArguments = new String[]{
|
||||||
|
"-XX:+DisableAttachMechanism",
|
||||||
|
"-Drunelite.launcher.nojvm=true",
|
||||||
|
"-Xmx512m",
|
||||||
|
"-Xss2m",
|
||||||
|
"-XX:CompileThreshold=1500",
|
||||||
|
"-Xincgc",
|
||||||
|
"-XX:+UseConcMarkSweepGC",
|
||||||
|
"-XX:+UseParNewGC",
|
||||||
|
"-Djna.nosys=true"};
|
||||||
|
|
||||||
Artifact[] artifacts = getArtifacts();
|
public Bootstrap()
|
||||||
Client client = new Client();
|
{
|
||||||
String[] clientJvm9Arguments = new String[]{
|
}
|
||||||
"-XX:+DisableAttachMechanism",
|
|
||||||
"-Xmx512m",
|
|
||||||
"-Xss2m",
|
|
||||||
"-XX:CompileThreshold=1500",
|
|
||||||
"-Djna.nosys=true"
|
|
||||||
};
|
|
||||||
String[] clientJvmArguments = new String[]{
|
|
||||||
"-XX:+DisableAttachMechanism",
|
|
||||||
"-Xmx512m",
|
|
||||||
"-Xss2m",
|
|
||||||
"-XX:CompileThreshold=1500",
|
|
||||||
"-Xincgc",
|
|
||||||
"-XX:+UseConcMarkSweepGC",
|
|
||||||
"-XX:+UseParNewGC",
|
|
||||||
"-Djna.nosys=true"};
|
|
||||||
String[] dependencyHashes;
|
|
||||||
String[] launcherArguments = new String[]{
|
|
||||||
"-XX:+DisableAttachMechanism",
|
|
||||||
"-Drunelite.launcher.nojvm=true",
|
|
||||||
"-Xmx512m",
|
|
||||||
"-Xss2m",
|
|
||||||
"-XX:CompileThreshold=1500",
|
|
||||||
"-Xincgc",
|
|
||||||
"-XX:+UseConcMarkSweepGC",
|
|
||||||
"-XX:+UseParNewGC",
|
|
||||||
"-Djna.nosys=true"};
|
|
||||||
|
|
||||||
public Bootstrap(){}
|
public static String getChecksumObject(Serializable object) throws IOException, NoSuchAlgorithmException
|
||||||
|
{
|
||||||
|
ByteArrayOutputStream baos = null;
|
||||||
|
ObjectOutputStream oos = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
baos = new ByteArrayOutputStream();
|
||||||
|
oos = new ObjectOutputStream(baos);
|
||||||
|
oos.writeObject(object);
|
||||||
|
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||||
|
byte[] thedigest = md.digest(baos.toByteArray());
|
||||||
|
return DatatypeConverter.printHexBinary(thedigest);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
oos.close();
|
||||||
|
baos.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Artifact[] getArtifacts() {
|
private static String getChecksumFile(String filepath) throws IOException
|
||||||
try {
|
{
|
||||||
artifacts = new Artifact[42];
|
System.out.println("Generating Hash for " + filepath);
|
||||||
|
MessageDigest md = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
md = MessageDigest.getInstance("SHA-256");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try (DigestInputStream dis = new DigestInputStream(new FileInputStream(filepath), md))
|
||||||
|
{
|
||||||
|
while (dis.read() != -1)
|
||||||
|
{
|
||||||
|
//empty loop to clear the data
|
||||||
|
}
|
||||||
|
md = dis.getMessageDigest();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
//Static artifacts
|
return bytesToHex(md.digest());
|
||||||
artifacts[0] = new Artifact();
|
|
||||||
artifacts[0].hash = "b12331da8683e5f107d294adeebb83ecf9124abc1db533554d2a8d3c62832d75";
|
|
||||||
artifacts[0].name = "asm-all-6.0_BETA.jar";
|
|
||||||
artifacts[0].path = "https://mvn.runelite.net/org/ow2/asm/asm-all/6.0_BETA/asm-all-6.0_BETA.jar";
|
|
||||||
artifacts[0].size = "265176";
|
|
||||||
artifacts[1] = new Artifact();
|
|
||||||
artifacts[1].hash = "37abf0103ce5318bfda004fabc004c75ed0dc6d392a8459175692ab7eac97083";
|
|
||||||
artifacts[1].name = "naturalmouse-2.0.0.jar";
|
|
||||||
artifacts[1].path = "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/artifacts/naturalmouse-2.0.0.jar";
|
|
||||||
artifacts[1].size = "3168921";
|
|
||||||
artifacts[2] = new Artifact();
|
|
||||||
artifacts[2].hash = "50d1e07f11827672249dee9ce8a23691fc59f663deed084bb7b52a4f778d5fbc";
|
|
||||||
artifacts[2].name = "jcl-core-2.9-SNAPSHOT.jar";
|
|
||||||
artifacts[2].path = "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/artifacts/jcl-core-2.9-SNAPSHOT.jar";
|
|
||||||
artifacts[2].size = "3168921";
|
|
||||||
artifacts[4] = new Artifact();
|
|
||||||
artifacts[4].hash = "18c4a0095d5c1da6b817592e767bb23d29dd2f560ad74df75ff3961dbde25b79";
|
|
||||||
artifacts[4].name = "slf4j-api-1.7.25.jar";
|
|
||||||
artifacts[4].path = "https://mvn.runelite.net/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar";
|
|
||||||
artifacts[4].size = "41203";
|
|
||||||
artifacts[5] = new Artifact();
|
|
||||||
artifacts[5].hash = "fb53f8539e7fcb8f093a56e138112056ec1dc809ebb020b59d8a36a5ebac37e0";
|
|
||||||
artifacts[5].name = "logback-classic-1.2.3.jar";
|
|
||||||
artifacts[5].path = "https://mvn.runelite.net/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar";
|
|
||||||
artifacts[5].size = "290339";
|
|
||||||
artifacts[6] = new Artifact();
|
|
||||||
artifacts[6].hash = "5946d837fe6f960c02a53eda7a6926ecc3c758bbdd69aa453ee429f858217f22";
|
|
||||||
artifacts[6].name = "logback-core-1.2.3.jar";
|
|
||||||
artifacts[6].path = "https://mvn.runelite.net/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3.jar";
|
|
||||||
artifacts[6].size = "471901";
|
|
||||||
artifacts[7] = new Artifact();
|
|
||||||
artifacts[7].hash = "9f0c8d50fa4b79b6ff1502dbec8502179d6b9497cacbe17a13074001aed537ec";
|
|
||||||
artifacts[7].name = "jopt-simple-5.0.1.jar";
|
|
||||||
artifacts[7].path = "https://mvn.runelite.net/net/sf/jopt-simple/jopt-simple/5.0.1/jopt-simple-5.0.1.jar";
|
|
||||||
artifacts[7].size = "78826";
|
|
||||||
artifacts[8] = new Artifact();
|
|
||||||
artifacts[8].hash = "5be9a7d05ba0ccd74708bc8018ae412255f85843c0b92302e9b9befa6ed52564";
|
|
||||||
artifacts[8].name = "guava-23.2-jre.jar";
|
|
||||||
artifacts[8].path = "https://mvn.runelite.net/com/google/guava/guava/23.2-jre/guava-23.2-jre.jar";
|
|
||||||
artifacts[8].size = "2649860";
|
|
||||||
artifacts[9] = new Artifact();
|
|
||||||
artifacts[9].hash = "905721a0eea90a81534abb7ee6ef4ea2e5e645fa1def0a5cd88402df1b46c9ed";
|
|
||||||
artifacts[9].name = "jsr305-1.3.9.jar";
|
|
||||||
artifacts[9].path = "https://mvn.runelite.net/com/google/code/findbugs/jsr305/1.3.9/jsr305-1.3.9.jar";
|
|
||||||
artifacts[9].size = "33015";
|
|
||||||
artifacts[10] = new Artifact();
|
|
||||||
artifacts[10].hash = "cb4cfad870bf563a07199f3ebea5763f0dec440fcda0b318640b1feaa788656b";
|
|
||||||
artifacts[10].name = "error_prone_annotations-2.0.18.jar";
|
|
||||||
artifacts[10].path = "https://mvn.runelite.net/com/google/errorprone/error_prone_annotations/2.0.18/error_prone_annotations-2.0.18.jar";
|
|
||||||
artifacts[10].size = "12078";
|
|
||||||
artifacts[11] = new Artifact();
|
|
||||||
artifacts[11].hash = "2994a7eb78f2710bd3d3bfb639b2c94e219cedac0d4d084d516e78c16dddecf6";
|
|
||||||
artifacts[11].name = "j2objc-annotations-1.1.jar";
|
|
||||||
artifacts[11].path = "https://mvn.runelite.net/com/google/j2objc/j2objc-annotations/1.1/j2objc-annotations-1.1.jar";
|
|
||||||
artifacts[11].size = "8782";
|
|
||||||
artifacts[12] = new Artifact();
|
|
||||||
artifacts[12].hash = "2068320bd6bad744c3673ab048f67e30bef8f518996fa380033556600669905d";
|
|
||||||
artifacts[12].name = "animal-sniffer-annotations-1.14.jar";
|
|
||||||
artifacts[12].path = "https://mvn.runelite.net/org/codehaus/mojo/animal-sniffer-annotations/1.14/animal-sniffer-annotations-1.14.jar";
|
|
||||||
artifacts[12].size = "3482";
|
|
||||||
artifacts[13] = new Artifact();
|
|
||||||
artifacts[13].hash = "9264c6931c431e928dc64adc842584d5f57d17b2f3aff29221f2b3fdea673dad";
|
|
||||||
artifacts[13].name = "guice-4.1.0-no_aop.jar";
|
|
||||||
artifacts[13].path = "https://mvn.runelite.net/com/google/inject/guice/4.1.0/guice-4.1.0-no_aop.jar";
|
|
||||||
artifacts[13].size = "428603";
|
|
||||||
artifacts[14] = new Artifact();
|
|
||||||
artifacts[14].hash = "91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff";
|
|
||||||
artifacts[14].name = "javax.inject-1.jar";
|
|
||||||
artifacts[14].path = "https://mvn.runelite.net/javax/inject/javax.inject/1/javax.inject-1.jar";
|
|
||||||
artifacts[14].size = "2497";
|
|
||||||
artifacts[15] = new Artifact();
|
|
||||||
artifacts[15].hash = "0addec670fedcd3f113c5c8091d783280d23f75e3acb841b61a9cdb079376a08";
|
|
||||||
artifacts[15].name = "aopalliance-1.0.jar";
|
|
||||||
artifacts[15].path = "https://mvn.runelite.net/aopalliance/aopalliance/1.0/aopalliance-1.0.jar";
|
|
||||||
artifacts[15].size = "4467";
|
|
||||||
artifacts[16] = new Artifact();
|
|
||||||
artifacts[16].hash = "233a0149fc365c9f6edbd683cfe266b19bdc773be98eabdaf6b3c924b48e7d81";
|
|
||||||
artifacts[16].name = "gson-2.8.5.jar";
|
|
||||||
artifacts[16].path = "https://mvn.runelite.net/com/google/code/gson/gson/2.8.5/gson-2.8.5.jar";
|
|
||||||
artifacts[16].size = "241622";
|
|
||||||
artifacts[17] = new Artifact();
|
|
||||||
artifacts[17].hash = "0467d25f408428824d5c9c09ec60ee1f0bc341d9bf48971a77fd14939a826c83";
|
|
||||||
artifacts[17].name = "substance-8.0.02.jar";
|
|
||||||
artifacts[17].path = "https://repo.runelite.net/net/runelite/pushingpixels/substance/8.0.02/substance-8.0.02.jar";
|
|
||||||
artifacts[17].size = "1589195";
|
|
||||||
artifacts[18] = new Artifact();
|
|
||||||
artifacts[18].hash = "3214e1c23d549d5d67c91da4da1ef33c5248470bb824f91cbe8f9e0beea59eef";
|
|
||||||
artifacts[18].name = "trident-1.5.00.jar";
|
|
||||||
artifacts[18].path = "https://repo.runelite.net/net/runelite/pushingpixels/trident/1.5.00/trident-1.5.00.jar";
|
|
||||||
artifacts[18].size = "79726";
|
|
||||||
artifacts[19] = new Artifact();
|
|
||||||
artifacts[19].hash = "d4a57bbc1627da7c391308fd0fe910b83170fb66afd117236a5b111d2db1590b";
|
|
||||||
artifacts[19].name = "commons-text-1.2.jar";
|
|
||||||
artifacts[19].path = "https://mvn.runelite.net/org/apache/commons/commons-text/1.2/commons-text-1.2.jar";
|
|
||||||
artifacts[19].size = "136544";
|
|
||||||
artifacts[20] = new Artifact();
|
|
||||||
artifacts[20].hash = "6e8dc31e046508d9953c96534edf0c2e0bfe6f468966b5b842b3f87e43b6a847";
|
|
||||||
artifacts[20].name = "commons-lang3-3.7.jar";
|
|
||||||
artifacts[20].path = "https://mvn.runelite.net/org/apache/commons/commons-lang3/3.7/commons-lang3-3.7.jar";
|
|
||||||
artifacts[20].size = "499634";
|
|
||||||
artifacts[21] = new Artifact();
|
|
||||||
artifacts[21].hash = "e74603dc77b4183f108480279dbbf7fed3ac206069478636406c1fb45e83b31a";
|
|
||||||
artifacts[21].name = "jogl-all-2.3.2.jar";
|
|
||||||
artifacts[21].path = "https://mvn.runelite.net/org/jogamp/jogl/jogl-all/2.3.2/jogl-all-2.3.2.jar";
|
|
||||||
artifacts[21].size = "3414448";
|
|
||||||
artifacts[22] = new Artifact();
|
|
||||||
artifacts[22].hash = "8c53b1884cef19309d34fd10a94b010136d9d6de9a88c386f46006fb47acab5d";
|
|
||||||
artifacts[22].name = "jogl-all-2.3.2-natives-windows-amd64.jar";
|
|
||||||
artifacts[22].path = "https://mvn.runelite.net/org/jogamp/jogl/jogl-all/2.3.2/jogl-all-2.3.2-natives-windows-amd64.jar";
|
|
||||||
artifacts[22].size = "240721";
|
|
||||||
artifacts[23] = new Artifact();
|
|
||||||
artifacts[23].hash = "507a0e6bd1ee4e81c3dfb287783af93775864eec742988d4162f98ce0cbac9d6";
|
|
||||||
artifacts[23].name = "jogl-all-2.3.2-natives-windows-i586.jar";
|
|
||||||
artifacts[23].path = "https://mvn.runelite.net/org/jogamp/jogl/jogl-all/2.3.2/jogl-all-2.3.2-natives-windows-i586.jar";
|
|
||||||
artifacts[23].size = "209445";
|
|
||||||
artifacts[24] = new Artifact();
|
|
||||||
artifacts[24].hash = "82637302ae9effdf7d6f302e1050ad6aee3b13019914ddda5b502b9faa980216";
|
|
||||||
artifacts[24].name = "jogl-all-2.3.2-natives-linux-amd64.jar";
|
|
||||||
artifacts[24].path = "https://mvn.runelite.net/org/jogamp/jogl/jogl-all/2.3.2/jogl-all-2.3.2-natives-linux-amd64.jar";
|
|
||||||
artifacts[24].size = "224010";
|
|
||||||
artifacts[25] = new Artifact();
|
|
||||||
artifacts[25].hash = "f474ef2ef01be24ec811d3858b0f4bc5659076975f4a58ddd79abd787e9305c7";
|
|
||||||
artifacts[25].name = "jogl-all-2.3.2-natives-linux-i586.jar";
|
|
||||||
artifacts[25].path = "https://mvn.runelite.net/org/jogamp/jogl/jogl-all/2.3.2/jogl-all-2.3.2-natives-linux-i586.jar";
|
|
||||||
artifacts[25].size = "217274";
|
|
||||||
artifacts[26] = new Artifact();
|
|
||||||
artifacts[26].hash = "084844543b18f7ff71b4c0437852bd22f0cb68d7e44c2c611c1bbea76f8c6fdf";
|
|
||||||
artifacts[26].name = "gluegen-rt-2.3.2.jar";
|
|
||||||
artifacts[26].path = "https://mvn.runelite.net/org/jogamp/gluegen/gluegen-rt/2.3.2/gluegen-rt-2.3.2.jar";
|
|
||||||
artifacts[26].size = "345605";
|
|
||||||
artifacts[27] = new Artifact();
|
|
||||||
artifacts[27].hash = "3474017422eff384db466bdb56c96c61220c43133a9da6329cf1781bea16c6b6";
|
|
||||||
artifacts[27].name = "gluegen-rt-2.3.2-natives-windows-amd64.jar";
|
|
||||||
artifacts[27].path = "https://mvn.runelite.net/org/jogamp/gluegen/gluegen-rt/2.3.2/gluegen-rt-2.3.2-natives-windows-amd64.jar";
|
|
||||||
artifacts[27].size = "8159";
|
|
||||||
artifacts[28] = new Artifact();
|
|
||||||
artifacts[28].hash = "4eeed9fc2ebea5b9dc48a342b9478d127e989a2e1aa7129b512a98ec75cde338";
|
|
||||||
artifacts[28].name = "gluegen-rt-2.3.2-natives-windows-i586.jar";
|
|
||||||
artifacts[28].path = "https://mvn.runelite.net/org/jogamp/gluegen/gluegen-rt/2.3.2/gluegen-rt-2.3.2-natives-windows-i586.jar";
|
|
||||||
artifacts[28].size = "7577";
|
|
||||||
artifacts[29] = new Artifact();
|
|
||||||
artifacts[29].hash = "f2dfd1800202059cf7e0294db5d57755147304e6eb220a9277526dbe6842bde2";
|
|
||||||
artifacts[29].name = "gluegen-rt-2.3.2-natives-linux-amd64.jar";
|
|
||||||
artifacts[29].path = "https://mvn.runelite.net/org/jogamp/gluegen/gluegen-rt/2.3.2/gluegen-rt-2.3.2-natives-linux-amd64.jar";
|
|
||||||
artifacts[29].size = "4149";
|
|
||||||
artifacts[30] = new Artifact();
|
|
||||||
artifacts[30].hash = "1365d463f98c0abec92f3ad6b35aa4b53a9599a517800cf99fdabea6712ca7ec";
|
|
||||||
artifacts[30].name = "gluegen-rt-2.3.2-natives-linux-i586.jar";
|
|
||||||
artifacts[30].path = "https://mvn.runelite.net/org/jogamp/gluegen/gluegen-rt/2.3.2/gluegen-rt-2.3.2-natives-linux-i586.jar";
|
|
||||||
artifacts[30].size = "4130";
|
|
||||||
artifacts[31] = new Artifact();
|
|
||||||
artifacts[31].hash = "7b7ae00e2aa98c3b2b5ac76e793e2c9b752bf51c86c54654dbd473843a25f1aa";
|
|
||||||
artifacts[31].name = "jbsdiff-1.0.jar";
|
|
||||||
artifacts[31].path = "https://mvn.runelite.net/io/sigpipe/jbsdiff/1.0/jbsdiff-1.0.jar";
|
|
||||||
artifacts[31].size = "24589";
|
|
||||||
artifacts[32] = new Artifact();
|
|
||||||
artifacts[32].hash = "55bbfe26cee9296fd5b7c0d47ce6a00ea4dd572e235b63e9bb4eaf6f802315e4";
|
|
||||||
artifacts[32].name = "commons-compress-1.5.jar";
|
|
||||||
artifacts[32].path = "https://mvn.runelite.net/org/apache/commons/commons-compress/1.5/commons-compress-1.5.jar";
|
|
||||||
artifacts[32].size = "256241";
|
|
||||||
artifacts[33] = new Artifact();
|
|
||||||
artifacts[33].hash = "fbc9de96a0cc193a125b4008dbc348e9ed54e5e13fc67b8ed40e645d303cc51b";
|
|
||||||
artifacts[33].name = "jna-4.5.1.jar";
|
|
||||||
artifacts[33].path = "https://mvn.runelite.net/net/java/dev/jna/jna/4.5.1/jna-4.5.1.jar";
|
|
||||||
artifacts[33].size = "1440662";
|
|
||||||
artifacts[34] = new Artifact();
|
|
||||||
artifacts[34].hash = "84c8667555ee8dd91fef44b451419f6f16f71f727d5fc475a10c2663eba83abb";
|
|
||||||
artifacts[34].name = "jna-platform-4.5.1.jar";
|
|
||||||
artifacts[34].path = "https://mvn.runelite.net/net/java/dev/jna/jna-platform/4.5.1/jna-platform-4.5.1.jar";
|
|
||||||
artifacts[34].size = "2327547";
|
|
||||||
artifacts[38] = new Artifact();
|
|
||||||
artifacts[38].hash = "f55abda036da75e1af45bd43b9dfa79b2a3d90905be9cb38687c6621597a8165";
|
|
||||||
artifacts[38].name = "okhttp-3.7.0.jar";
|
|
||||||
artifacts[38].path = "https://mvn.runelite.net/com/squareup/okhttp3/okhttp/3.7.0/okhttp-3.7.0.jar";
|
|
||||||
artifacts[38].size = "394987";
|
|
||||||
artifacts[39] = new Artifact();
|
|
||||||
artifacts[39].hash = "bfe7dfe483c37137966a1690f0c7d0b448ba217902c1fed202aaffdbba3291ae";
|
|
||||||
artifacts[39].name = "okio-1.12.0.jar";
|
|
||||||
artifacts[39].path = "https://mvn.runelite.net/com/squareup/okio/okio/1.12.0/okio-1.12.0.jar";
|
|
||||||
artifacts[39].size = "81088";
|
|
||||||
artifacts[40] = new Artifact();
|
|
||||||
artifacts[40].hash = "9d4924588d6280c7516db3a4b7298306db5b6f0d1cdf568ce738309b5660f008";
|
|
||||||
artifacts[40].name = "commons-csv-1.4.jar";
|
|
||||||
artifacts[40].path = "https://mvn.runelite.net/org/apache/commons/commons-csv/1.4/commons-csv-1.4.jar";
|
|
||||||
artifacts[40].size = "39978";
|
|
||||||
artifacts[41] = new Artifact();
|
|
||||||
artifacts[41].hash = "7e26a8d043418f2f22d5f6a3083a9a131817009ee8cd72c004e83b50d1849a7c";
|
|
||||||
artifacts[41].name = "discord-1.1.jar";
|
|
||||||
artifacts[41].path = "https://repo.runelite.net/net/runelite/discord/1.1/discord-1.1.jar";
|
|
||||||
artifacts[41].size = "617294";
|
|
||||||
|
|
||||||
//Dynamic artifacts
|
}
|
||||||
artifacts[3] = new Artifact();
|
|
||||||
artifacts[3].name = "client-"+ RuneLiteAPI.getVersion()+".jar";
|
|
||||||
artifacts[3].hash = getChecksumFile("./runelite-client/target/"+artifacts[3].name);
|
|
||||||
artifacts[3].path = "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/"+artifacts[3].name;
|
|
||||||
artifacts[3].size = Long.toString(getFileSize("./runelite-client/target/"+artifacts[3].name));
|
|
||||||
artifacts[35] = new Artifact();
|
|
||||||
artifacts[35].name = "runelite-api-"+ RuneLiteAPI.getVersion()+".jar";
|
|
||||||
artifacts[35].hash = getChecksumFile("./runelite-api/target/"+artifacts[35].name);
|
|
||||||
artifacts[35].path = "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/"+artifacts[35].name;
|
|
||||||
artifacts[35].size = Long.toString(getFileSize("./runelite-api/target/"+artifacts[35].name));
|
|
||||||
artifacts[36] = new Artifact();
|
|
||||||
artifacts[36].name = "runescape-api-"+ RuneLiteAPI.getVersion()+".jar";
|
|
||||||
artifacts[36].hash = getChecksumFile("./runescape-api/target/"+artifacts[36].name);
|
|
||||||
artifacts[36].path = "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/"+artifacts[36].name;
|
|
||||||
artifacts[36].size = Long.toString(getFileSize("./runescape-api/target/"+artifacts[36].name));
|
|
||||||
artifacts[37] = new Artifact();
|
|
||||||
artifacts[37].name = "http-api-"+ RuneLiteAPI.getVersion()+".jar";
|
|
||||||
artifacts[37].hash = getChecksumFile("./http-api/target/"+artifacts[37].name);
|
|
||||||
artifacts[37].path = "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/"+artifacts[37].name;
|
|
||||||
artifacts[37].size = Long.toString(getFileSize("./http-api/target/"+artifacts[37].name));
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return artifacts;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
private static String bytesToHex(byte[] hashInBytes)
|
||||||
|
{
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (byte b : hashInBytes)
|
||||||
|
{
|
||||||
|
sb.append(String.format("%02x", b));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
|
||||||
public static String getChecksumObject(Serializable object) throws IOException, NoSuchAlgorithmException {
|
}
|
||||||
ByteArrayOutputStream baos = null;
|
|
||||||
ObjectOutputStream oos = null;
|
|
||||||
try {
|
|
||||||
baos = new ByteArrayOutputStream();
|
|
||||||
oos = new ObjectOutputStream(baos);
|
|
||||||
oos.writeObject(object);
|
|
||||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
|
||||||
byte[] thedigest = md.digest(baos.toByteArray());
|
|
||||||
return DatatypeConverter.printHexBinary(thedigest);
|
|
||||||
} finally {
|
|
||||||
oos.close();
|
|
||||||
baos.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private static String getChecksumFile(String filepath) throws IOException {
|
|
||||||
System.out.println("Generating Hash for "+filepath);
|
|
||||||
MessageDigest md = null;
|
|
||||||
try {
|
|
||||||
md = MessageDigest.getInstance("SHA-256");
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
try (DigestInputStream dis = new DigestInputStream(new FileInputStream(filepath), md)) {
|
|
||||||
while (dis.read() != -1) ; //empty loop to clear the data
|
|
||||||
md = dis.getMessageDigest();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
return bytesToHex(md.digest());
|
public Artifact[] getArtifacts()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
artifacts = new Artifact[42];
|
||||||
|
|
||||||
}
|
//Static artifacts
|
||||||
|
artifacts[0] = new Artifact();
|
||||||
|
artifacts[0].hash = "b12331da8683e5f107d294adeebb83ecf9124abc1db533554d2a8d3c62832d75";
|
||||||
|
artifacts[0].name = "asm-all-6.0_BETA.jar";
|
||||||
|
artifacts[0].path = "https://mvn.runelite.net/org/ow2/asm/asm-all/6.0_BETA/asm-all-6.0_BETA.jar";
|
||||||
|
artifacts[0].size = "265176";
|
||||||
|
artifacts[1] = new Artifact();
|
||||||
|
artifacts[1].hash = "37abf0103ce5318bfda004fabc004c75ed0dc6d392a8459175692ab7eac97083";
|
||||||
|
artifacts[1].name = "naturalmouse-2.0.0.jar";
|
||||||
|
artifacts[1].path = "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/artifacts/naturalmouse-2.0.0.jar";
|
||||||
|
artifacts[1].size = "3168921";
|
||||||
|
artifacts[2] = new Artifact();
|
||||||
|
artifacts[2].hash = "50d1e07f11827672249dee9ce8a23691fc59f663deed084bb7b52a4f778d5fbc";
|
||||||
|
artifacts[2].name = "jcl-core-2.9-SNAPSHOT.jar";
|
||||||
|
artifacts[2].path = "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/artifacts/jcl-core-2.9-SNAPSHOT.jar";
|
||||||
|
artifacts[2].size = "3168921";
|
||||||
|
artifacts[4] = new Artifact();
|
||||||
|
artifacts[4].hash = "18c4a0095d5c1da6b817592e767bb23d29dd2f560ad74df75ff3961dbde25b79";
|
||||||
|
artifacts[4].name = "slf4j-api-1.7.25.jar";
|
||||||
|
artifacts[4].path = "https://mvn.runelite.net/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar";
|
||||||
|
artifacts[4].size = "41203";
|
||||||
|
artifacts[5] = new Artifact();
|
||||||
|
artifacts[5].hash = "fb53f8539e7fcb8f093a56e138112056ec1dc809ebb020b59d8a36a5ebac37e0";
|
||||||
|
artifacts[5].name = "logback-classic-1.2.3.jar";
|
||||||
|
artifacts[5].path = "https://mvn.runelite.net/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar";
|
||||||
|
artifacts[5].size = "290339";
|
||||||
|
artifacts[6] = new Artifact();
|
||||||
|
artifacts[6].hash = "5946d837fe6f960c02a53eda7a6926ecc3c758bbdd69aa453ee429f858217f22";
|
||||||
|
artifacts[6].name = "logback-core-1.2.3.jar";
|
||||||
|
artifacts[6].path = "https://mvn.runelite.net/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3.jar";
|
||||||
|
artifacts[6].size = "471901";
|
||||||
|
artifacts[7] = new Artifact();
|
||||||
|
artifacts[7].hash = "9f0c8d50fa4b79b6ff1502dbec8502179d6b9497cacbe17a13074001aed537ec";
|
||||||
|
artifacts[7].name = "jopt-simple-5.0.1.jar";
|
||||||
|
artifacts[7].path = "https://mvn.runelite.net/net/sf/jopt-simple/jopt-simple/5.0.1/jopt-simple-5.0.1.jar";
|
||||||
|
artifacts[7].size = "78826";
|
||||||
|
artifacts[8] = new Artifact();
|
||||||
|
artifacts[8].hash = "5be9a7d05ba0ccd74708bc8018ae412255f85843c0b92302e9b9befa6ed52564";
|
||||||
|
artifacts[8].name = "guava-23.2-jre.jar";
|
||||||
|
artifacts[8].path = "https://mvn.runelite.net/com/google/guava/guava/23.2-jre/guava-23.2-jre.jar";
|
||||||
|
artifacts[8].size = "2649860";
|
||||||
|
artifacts[9] = new Artifact();
|
||||||
|
artifacts[9].hash = "905721a0eea90a81534abb7ee6ef4ea2e5e645fa1def0a5cd88402df1b46c9ed";
|
||||||
|
artifacts[9].name = "jsr305-1.3.9.jar";
|
||||||
|
artifacts[9].path = "https://mvn.runelite.net/com/google/code/findbugs/jsr305/1.3.9/jsr305-1.3.9.jar";
|
||||||
|
artifacts[9].size = "33015";
|
||||||
|
artifacts[10] = new Artifact();
|
||||||
|
artifacts[10].hash = "cb4cfad870bf563a07199f3ebea5763f0dec440fcda0b318640b1feaa788656b";
|
||||||
|
artifacts[10].name = "error_prone_annotations-2.0.18.jar";
|
||||||
|
artifacts[10].path = "https://mvn.runelite.net/com/google/errorprone/error_prone_annotations/2.0.18/error_prone_annotations-2.0.18.jar";
|
||||||
|
artifacts[10].size = "12078";
|
||||||
|
artifacts[11] = new Artifact();
|
||||||
|
artifacts[11].hash = "2994a7eb78f2710bd3d3bfb639b2c94e219cedac0d4d084d516e78c16dddecf6";
|
||||||
|
artifacts[11].name = "j2objc-annotations-1.1.jar";
|
||||||
|
artifacts[11].path = "https://mvn.runelite.net/com/google/j2objc/j2objc-annotations/1.1/j2objc-annotations-1.1.jar";
|
||||||
|
artifacts[11].size = "8782";
|
||||||
|
artifacts[12] = new Artifact();
|
||||||
|
artifacts[12].hash = "2068320bd6bad744c3673ab048f67e30bef8f518996fa380033556600669905d";
|
||||||
|
artifacts[12].name = "animal-sniffer-annotations-1.14.jar";
|
||||||
|
artifacts[12].path = "https://mvn.runelite.net/org/codehaus/mojo/animal-sniffer-annotations/1.14/animal-sniffer-annotations-1.14.jar";
|
||||||
|
artifacts[12].size = "3482";
|
||||||
|
artifacts[13] = new Artifact();
|
||||||
|
artifacts[13].hash = "9264c6931c431e928dc64adc842584d5f57d17b2f3aff29221f2b3fdea673dad";
|
||||||
|
artifacts[13].name = "guice-4.1.0-no_aop.jar";
|
||||||
|
artifacts[13].path = "https://mvn.runelite.net/com/google/inject/guice/4.1.0/guice-4.1.0-no_aop.jar";
|
||||||
|
artifacts[13].size = "428603";
|
||||||
|
artifacts[14] = new Artifact();
|
||||||
|
artifacts[14].hash = "91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff";
|
||||||
|
artifacts[14].name = "javax.inject-1.jar";
|
||||||
|
artifacts[14].path = "https://mvn.runelite.net/javax/inject/javax.inject/1/javax.inject-1.jar";
|
||||||
|
artifacts[14].size = "2497";
|
||||||
|
artifacts[15] = new Artifact();
|
||||||
|
artifacts[15].hash = "0addec670fedcd3f113c5c8091d783280d23f75e3acb841b61a9cdb079376a08";
|
||||||
|
artifacts[15].name = "aopalliance-1.0.jar";
|
||||||
|
artifacts[15].path = "https://mvn.runelite.net/aopalliance/aopalliance/1.0/aopalliance-1.0.jar";
|
||||||
|
artifacts[15].size = "4467";
|
||||||
|
artifacts[16] = new Artifact();
|
||||||
|
artifacts[16].hash = "233a0149fc365c9f6edbd683cfe266b19bdc773be98eabdaf6b3c924b48e7d81";
|
||||||
|
artifacts[16].name = "gson-2.8.5.jar";
|
||||||
|
artifacts[16].path = "https://mvn.runelite.net/com/google/code/gson/gson/2.8.5/gson-2.8.5.jar";
|
||||||
|
artifacts[16].size = "241622";
|
||||||
|
artifacts[17] = new Artifact();
|
||||||
|
artifacts[17].hash = "0467d25f408428824d5c9c09ec60ee1f0bc341d9bf48971a77fd14939a826c83";
|
||||||
|
artifacts[17].name = "substance-8.0.02.jar";
|
||||||
|
artifacts[17].path = "https://repo.runelite.net/net/runelite/pushingpixels/substance/8.0.02/substance-8.0.02.jar";
|
||||||
|
artifacts[17].size = "1589195";
|
||||||
|
artifacts[18] = new Artifact();
|
||||||
|
artifacts[18].hash = "3214e1c23d549d5d67c91da4da1ef33c5248470bb824f91cbe8f9e0beea59eef";
|
||||||
|
artifacts[18].name = "trident-1.5.00.jar";
|
||||||
|
artifacts[18].path = "https://repo.runelite.net/net/runelite/pushingpixels/trident/1.5.00/trident-1.5.00.jar";
|
||||||
|
artifacts[18].size = "79726";
|
||||||
|
artifacts[19] = new Artifact();
|
||||||
|
artifacts[19].hash = "d4a57bbc1627da7c391308fd0fe910b83170fb66afd117236a5b111d2db1590b";
|
||||||
|
artifacts[19].name = "commons-text-1.2.jar";
|
||||||
|
artifacts[19].path = "https://mvn.runelite.net/org/apache/commons/commons-text/1.2/commons-text-1.2.jar";
|
||||||
|
artifacts[19].size = "136544";
|
||||||
|
artifacts[20] = new Artifact();
|
||||||
|
artifacts[20].hash = "6e8dc31e046508d9953c96534edf0c2e0bfe6f468966b5b842b3f87e43b6a847";
|
||||||
|
artifacts[20].name = "commons-lang3-3.7.jar";
|
||||||
|
artifacts[20].path = "https://mvn.runelite.net/org/apache/commons/commons-lang3/3.7/commons-lang3-3.7.jar";
|
||||||
|
artifacts[20].size = "499634";
|
||||||
|
artifacts[21] = new Artifact();
|
||||||
|
artifacts[21].hash = "e74603dc77b4183f108480279dbbf7fed3ac206069478636406c1fb45e83b31a";
|
||||||
|
artifacts[21].name = "jogl-all-2.3.2.jar";
|
||||||
|
artifacts[21].path = "https://mvn.runelite.net/org/jogamp/jogl/jogl-all/2.3.2/jogl-all-2.3.2.jar";
|
||||||
|
artifacts[21].size = "3414448";
|
||||||
|
artifacts[22] = new Artifact();
|
||||||
|
artifacts[22].hash = "8c53b1884cef19309d34fd10a94b010136d9d6de9a88c386f46006fb47acab5d";
|
||||||
|
artifacts[22].name = "jogl-all-2.3.2-natives-windows-amd64.jar";
|
||||||
|
artifacts[22].path = "https://mvn.runelite.net/org/jogamp/jogl/jogl-all/2.3.2/jogl-all-2.3.2-natives-windows-amd64.jar";
|
||||||
|
artifacts[22].size = "240721";
|
||||||
|
artifacts[23] = new Artifact();
|
||||||
|
artifacts[23].hash = "507a0e6bd1ee4e81c3dfb287783af93775864eec742988d4162f98ce0cbac9d6";
|
||||||
|
artifacts[23].name = "jogl-all-2.3.2-natives-windows-i586.jar";
|
||||||
|
artifacts[23].path = "https://mvn.runelite.net/org/jogamp/jogl/jogl-all/2.3.2/jogl-all-2.3.2-natives-windows-i586.jar";
|
||||||
|
artifacts[23].size = "209445";
|
||||||
|
artifacts[24] = new Artifact();
|
||||||
|
artifacts[24].hash = "82637302ae9effdf7d6f302e1050ad6aee3b13019914ddda5b502b9faa980216";
|
||||||
|
artifacts[24].name = "jogl-all-2.3.2-natives-linux-amd64.jar";
|
||||||
|
artifacts[24].path = "https://mvn.runelite.net/org/jogamp/jogl/jogl-all/2.3.2/jogl-all-2.3.2-natives-linux-amd64.jar";
|
||||||
|
artifacts[24].size = "224010";
|
||||||
|
artifacts[25] = new Artifact();
|
||||||
|
artifacts[25].hash = "f474ef2ef01be24ec811d3858b0f4bc5659076975f4a58ddd79abd787e9305c7";
|
||||||
|
artifacts[25].name = "jogl-all-2.3.2-natives-linux-i586.jar";
|
||||||
|
artifacts[25].path = "https://mvn.runelite.net/org/jogamp/jogl/jogl-all/2.3.2/jogl-all-2.3.2-natives-linux-i586.jar";
|
||||||
|
artifacts[25].size = "217274";
|
||||||
|
artifacts[26] = new Artifact();
|
||||||
|
artifacts[26].hash = "084844543b18f7ff71b4c0437852bd22f0cb68d7e44c2c611c1bbea76f8c6fdf";
|
||||||
|
artifacts[26].name = "gluegen-rt-2.3.2.jar";
|
||||||
|
artifacts[26].path = "https://mvn.runelite.net/org/jogamp/gluegen/gluegen-rt/2.3.2/gluegen-rt-2.3.2.jar";
|
||||||
|
artifacts[26].size = "345605";
|
||||||
|
artifacts[27] = new Artifact();
|
||||||
|
artifacts[27].hash = "3474017422eff384db466bdb56c96c61220c43133a9da6329cf1781bea16c6b6";
|
||||||
|
artifacts[27].name = "gluegen-rt-2.3.2-natives-windows-amd64.jar";
|
||||||
|
artifacts[27].path = "https://mvn.runelite.net/org/jogamp/gluegen/gluegen-rt/2.3.2/gluegen-rt-2.3.2-natives-windows-amd64.jar";
|
||||||
|
artifacts[27].size = "8159";
|
||||||
|
artifacts[28] = new Artifact();
|
||||||
|
artifacts[28].hash = "4eeed9fc2ebea5b9dc48a342b9478d127e989a2e1aa7129b512a98ec75cde338";
|
||||||
|
artifacts[28].name = "gluegen-rt-2.3.2-natives-windows-i586.jar";
|
||||||
|
artifacts[28].path = "https://mvn.runelite.net/org/jogamp/gluegen/gluegen-rt/2.3.2/gluegen-rt-2.3.2-natives-windows-i586.jar";
|
||||||
|
artifacts[28].size = "7577";
|
||||||
|
artifacts[29] = new Artifact();
|
||||||
|
artifacts[29].hash = "f2dfd1800202059cf7e0294db5d57755147304e6eb220a9277526dbe6842bde2";
|
||||||
|
artifacts[29].name = "gluegen-rt-2.3.2-natives-linux-amd64.jar";
|
||||||
|
artifacts[29].path = "https://mvn.runelite.net/org/jogamp/gluegen/gluegen-rt/2.3.2/gluegen-rt-2.3.2-natives-linux-amd64.jar";
|
||||||
|
artifacts[29].size = "4149";
|
||||||
|
artifacts[30] = new Artifact();
|
||||||
|
artifacts[30].hash = "1365d463f98c0abec92f3ad6b35aa4b53a9599a517800cf99fdabea6712ca7ec";
|
||||||
|
artifacts[30].name = "gluegen-rt-2.3.2-natives-linux-i586.jar";
|
||||||
|
artifacts[30].path = "https://mvn.runelite.net/org/jogamp/gluegen/gluegen-rt/2.3.2/gluegen-rt-2.3.2-natives-linux-i586.jar";
|
||||||
|
artifacts[30].size = "4130";
|
||||||
|
artifacts[31] = new Artifact();
|
||||||
|
artifacts[31].hash = "7b7ae00e2aa98c3b2b5ac76e793e2c9b752bf51c86c54654dbd473843a25f1aa";
|
||||||
|
artifacts[31].name = "jbsdiff-1.0.jar";
|
||||||
|
artifacts[31].path = "https://mvn.runelite.net/io/sigpipe/jbsdiff/1.0/jbsdiff-1.0.jar";
|
||||||
|
artifacts[31].size = "24589";
|
||||||
|
artifacts[32] = new Artifact();
|
||||||
|
artifacts[32].hash = "55bbfe26cee9296fd5b7c0d47ce6a00ea4dd572e235b63e9bb4eaf6f802315e4";
|
||||||
|
artifacts[32].name = "commons-compress-1.5.jar";
|
||||||
|
artifacts[32].path = "https://mvn.runelite.net/org/apache/commons/commons-compress/1.5/commons-compress-1.5.jar";
|
||||||
|
artifacts[32].size = "256241";
|
||||||
|
artifacts[33] = new Artifact();
|
||||||
|
artifacts[33].hash = "fbc9de96a0cc193a125b4008dbc348e9ed54e5e13fc67b8ed40e645d303cc51b";
|
||||||
|
artifacts[33].name = "jna-4.5.1.jar";
|
||||||
|
artifacts[33].path = "https://mvn.runelite.net/net/java/dev/jna/jna/4.5.1/jna-4.5.1.jar";
|
||||||
|
artifacts[33].size = "1440662";
|
||||||
|
artifacts[34] = new Artifact();
|
||||||
|
artifacts[34].hash = "84c8667555ee8dd91fef44b451419f6f16f71f727d5fc475a10c2663eba83abb";
|
||||||
|
artifacts[34].name = "jna-platform-4.5.1.jar";
|
||||||
|
artifacts[34].path = "https://mvn.runelite.net/net/java/dev/jna/jna-platform/4.5.1/jna-platform-4.5.1.jar";
|
||||||
|
artifacts[34].size = "2327547";
|
||||||
|
artifacts[38] = new Artifact();
|
||||||
|
artifacts[38].hash = "f55abda036da75e1af45bd43b9dfa79b2a3d90905be9cb38687c6621597a8165";
|
||||||
|
artifacts[38].name = "okhttp-3.7.0.jar";
|
||||||
|
artifacts[38].path = "https://mvn.runelite.net/com/squareup/okhttp3/okhttp/3.7.0/okhttp-3.7.0.jar";
|
||||||
|
artifacts[38].size = "394987";
|
||||||
|
artifacts[39] = new Artifact();
|
||||||
|
artifacts[39].hash = "bfe7dfe483c37137966a1690f0c7d0b448ba217902c1fed202aaffdbba3291ae";
|
||||||
|
artifacts[39].name = "okio-1.12.0.jar";
|
||||||
|
artifacts[39].path = "https://mvn.runelite.net/com/squareup/okio/okio/1.12.0/okio-1.12.0.jar";
|
||||||
|
artifacts[39].size = "81088";
|
||||||
|
artifacts[40] = new Artifact();
|
||||||
|
artifacts[40].hash = "9d4924588d6280c7516db3a4b7298306db5b6f0d1cdf568ce738309b5660f008";
|
||||||
|
artifacts[40].name = "commons-csv-1.4.jar";
|
||||||
|
artifacts[40].path = "https://mvn.runelite.net/org/apache/commons/commons-csv/1.4/commons-csv-1.4.jar";
|
||||||
|
artifacts[40].size = "39978";
|
||||||
|
artifacts[41] = new Artifact();
|
||||||
|
artifacts[41].hash = "7e26a8d043418f2f22d5f6a3083a9a131817009ee8cd72c004e83b50d1849a7c";
|
||||||
|
artifacts[41].name = "discord-1.1.jar";
|
||||||
|
artifacts[41].path = "https://repo.runelite.net/net/runelite/discord/1.1/discord-1.1.jar";
|
||||||
|
artifacts[41].size = "617294";
|
||||||
|
|
||||||
private static String bytesToHex(byte[] hashInBytes) {
|
//Dynamic artifacts
|
||||||
|
artifacts[3] = new Artifact();
|
||||||
|
artifacts[3].name = "client-" + RuneLiteAPI.getVersion() + ".jar";
|
||||||
|
artifacts[3].hash = getChecksumFile("./runelite-client/target/" + artifacts[3].name);
|
||||||
|
artifacts[3].path = "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/" + artifacts[3].name;
|
||||||
|
artifacts[3].size = Long.toString(getFileSize("./runelite-client/target/" + artifacts[3].name));
|
||||||
|
artifacts[35] = new Artifact();
|
||||||
|
artifacts[35].name = "runelite-api-" + RuneLiteAPI.getVersion() + ".jar";
|
||||||
|
artifacts[35].hash = getChecksumFile("./runelite-api/target/" + artifacts[35].name);
|
||||||
|
artifacts[35].path = "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/" + artifacts[35].name;
|
||||||
|
artifacts[35].size = Long.toString(getFileSize("./runelite-api/target/" + artifacts[35].name));
|
||||||
|
artifacts[36] = new Artifact();
|
||||||
|
artifacts[36].name = "runescape-api-" + RuneLiteAPI.getVersion() + ".jar";
|
||||||
|
artifacts[36].hash = getChecksumFile("./runescape-api/target/" + artifacts[36].name);
|
||||||
|
artifacts[36].path = "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/" + artifacts[36].name;
|
||||||
|
artifacts[36].size = Long.toString(getFileSize("./runescape-api/target/" + artifacts[36].name));
|
||||||
|
artifacts[37] = new Artifact();
|
||||||
|
artifacts[37].name = "http-api-" + RuneLiteAPI.getVersion() + ".jar";
|
||||||
|
artifacts[37].hash = getChecksumFile("./http-api/target/" + artifacts[37].name);
|
||||||
|
artifacts[37].path = "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/" + artifacts[37].name;
|
||||||
|
artifacts[37].size = Long.toString(getFileSize("./http-api/target/" + artifacts[37].name));
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return artifacts;
|
||||||
|
}
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
private long getFileSize(String fileLocation)
|
||||||
for (byte b : hashInBytes) {
|
{
|
||||||
sb.append(String.format("%02x", b));
|
File f = new File(fileLocation);
|
||||||
}
|
return f.length();
|
||||||
return sb.toString();
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private long getFileSize(String fileLocation) {
|
|
||||||
File f = new File(fileLocation);
|
|
||||||
return f.length();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,24 +2,24 @@ package net.runelite.client.util.bootstrap;
|
|||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class Bootstrapper {
|
public class Bootstrapper
|
||||||
|
{
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args)
|
||||||
Gson gson = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create();
|
{
|
||||||
try {
|
Gson gson = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create();
|
||||||
FileWriter fw = new FileWriter("./bootstrap.json");
|
try
|
||||||
gson.toJson(new Bootstrap(), fw);
|
{
|
||||||
fw.close();
|
FileWriter fw = new FileWriter("./bootstrap.json");
|
||||||
} catch (Exception e) {
|
gson.toJson(new Bootstrap(), fw);
|
||||||
e.printStackTrace();
|
fw.close();
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
package net.runelite.client.util.bootstrap;
|
package net.runelite.client.util.bootstrap;
|
||||||
|
|
||||||
public class Client {
|
public class Client
|
||||||
|
{
|
||||||
|
|
||||||
String artifactId = "client";
|
String artifactId = "client";
|
||||||
String classifier = "";
|
String classifier = "";
|
||||||
String extension = "jar";
|
String extension = "jar";
|
||||||
String groupId = "net.runelite";
|
String groupId = "net.runelite";
|
||||||
String properties = "";
|
String properties = "";
|
||||||
String version = "1.5.27";
|
String version = "1.5.27";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -322,8 +322,11 @@ LABEL241:
|
|||||||
iconst 0 ;
|
iconst 0 ;
|
||||||
sconst "blockChatInput" ;
|
sconst "blockChatInput" ;
|
||||||
runelite_callback ;
|
runelite_callback ;
|
||||||
if_icmpeq LABEL247 ; don't add to input varcstr
|
if_icmpeq SKIPSETVARC ; skip setting varc with input
|
||||||
set_varc_string 335
|
set_varc_string 335
|
||||||
|
jump LABEL247 ; jump over SKIPSETVARC
|
||||||
|
SKIPSETVARC:
|
||||||
|
pop_string ; pop message
|
||||||
LABEL247:
|
LABEL247:
|
||||||
invoke 223
|
invoke 223
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
package net.runelite.mixins;
|
package net.runelite.mixins;
|
||||||
|
|
||||||
import net.runelite.api.Model;
|
|
||||||
import net.runelite.api.Perspective;
|
|
||||||
import net.runelite.api.mixins.Inject;
|
import net.runelite.api.mixins.Inject;
|
||||||
import net.runelite.api.mixins.Mixin;
|
import net.runelite.api.mixins.Mixin;
|
||||||
import net.runelite.api.mixins.Shadow;
|
import net.runelite.api.mixins.Shadow;
|
||||||
import net.runelite.rs.api.RSClient;
|
import net.runelite.rs.api.RSClient;
|
||||||
import net.runelite.rs.api.RSModel;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to check clickboxes of models. Mostly refactored code from the client.
|
* Class to check clickboxes of models. Mostly refactored code from the client.
|
||||||
@@ -14,19 +11,40 @@ import net.runelite.rs.api.RSModel;
|
|||||||
@Mixin(RSClient.class)
|
@Mixin(RSClient.class)
|
||||||
public abstract class ClickboxMixin implements RSClient
|
public abstract class ClickboxMixin implements RSClient
|
||||||
{
|
{
|
||||||
@Shadow("client")
|
|
||||||
private static RSClient client;
|
|
||||||
|
|
||||||
private static final int MAX_ENTITES_AT_MOUSE = 1000;
|
private static final int MAX_ENTITES_AT_MOUSE = 1000;
|
||||||
private static final int CLICKBOX_CLOSE = 50;
|
private static final int CLICKBOX_CLOSE = 50;
|
||||||
private static final int CLICKBOX_FAR = 10000;
|
private static final int CLICKBOX_FAR = 10000;
|
||||||
private static final int OBJECT_INTERACTION_FAR = 100; // Max distance, in tiles, from camera
|
private static final int OBJECT_INTERACTION_FAR = 100; // Max distance, in tiles, from camera
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private static final int[] rl$modelViewportXs = new int[4700];
|
private static final int[] rl$modelViewportXs = new int[4700];
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private static final int[] rl$modelViewportYs = new int[4700];
|
private static final int[] rl$modelViewportYs = new int[4700];
|
||||||
|
@Shadow("client")
|
||||||
|
private static RSClient client;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private static int rl$rot1(int var0, int var1, int var2, int var3)
|
||||||
|
{
|
||||||
|
return var0 * var2 + var3 * var1 >> 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private static int rl$rot2(int var0, int var1, int var2, int var3)
|
||||||
|
{
|
||||||
|
return var2 * var1 - var3 * var0 >> 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private static int rl$rot3(int var0, int var1, int var2, int var3)
|
||||||
|
{
|
||||||
|
return var0 * var2 - var3 * var1 >> 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private static int rl$rot4(int var0, int var1, int var2, int var3)
|
||||||
|
{
|
||||||
|
return var3 * var0 + var2 * var1 >> 16;
|
||||||
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public void checkClickbox(net.runelite.api.Model model, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int n9, long l2)
|
public void checkClickbox(net.runelite.api.Model model, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int n9, long l2)
|
||||||
@@ -118,11 +136,8 @@ public abstract class ClickboxMixin implements RSClient
|
|||||||
int n28 = rl$modelViewportXs[n12];
|
int n28 = rl$modelViewportXs[n12];
|
||||||
int n29 = rl$modelViewportXs[n10];
|
int n29 = rl$modelViewportXs[n10];
|
||||||
int n30 = rl$modelViewportXs[n24];
|
int n30 = rl$modelViewportXs[n24];
|
||||||
if (n25 != -5000 && n26 != -5000 && n27 != -5000 && (bl5 = (n23 = (n22 = rSModel.isClickable() ? 20
|
if (n25 != -5000 && n26 != -5000 && n27 != -5000 && (bl5 = ((n23 = (n22 = rSModel.isClickable() ? 20
|
||||||
: 5) + n11) < n28 && n23 < n29 && n23 < n30 ? false
|
: 5) + n11) >= n28 || n23 >= n29 || n23 >= n30) && (((n23 = n11 - n22) <= n28 || n23 <= n29 || n23 <= n30) && (((n23 = n22 + n14) >= n25 || n23 >= n26 || n23 >= n27) && ((n23 = n14 - n22) <= n25 || n23 <= n26 || n23 <= n27)))))
|
||||||
: ((n23 = n11 - n22) > n28 && n23 > n29 && n23 > n30 ? false
|
|
||||||
: ((n23 = n22 + n14) < n25 && n23 < n26 && n23 < n27 ? false
|
|
||||||
: (n23 = n14 - n22) <= n25 || n23 <= n26 || n23 <= n27))))
|
|
||||||
{
|
{
|
||||||
this.addHashAtMouse(l2);
|
this.addHashAtMouse(l2);
|
||||||
return;
|
return;
|
||||||
@@ -211,34 +226,6 @@ public abstract class ClickboxMixin implements RSClient
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (Math.abs(n39 * n23 - n38 * n24) <= n33 * n26 + n32 * n27)
|
return Math.abs(n39 * n23 - n38 * n24) <= n33 * n26 + n32 * n27;
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private static int rl$rot1(int var0, int var1, int var2, int var3)
|
|
||||||
{
|
|
||||||
return var0 * var2 + var3 * var1 >> 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private static int rl$rot2(int var0, int var1, int var2, int var3)
|
|
||||||
{
|
|
||||||
return var2 * var1 - var3 * var0 >> 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private static int rl$rot3(int var0, int var1, int var2, int var3)
|
|
||||||
{
|
|
||||||
return var0 * var2 - var3 * var1 >> 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private static int rl$rot4(int var0, int var1, int var2, int var3)
|
|
||||||
{
|
|
||||||
return var3 * var0 + var2 * var1 >> 16;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,21 +24,21 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.mixins;
|
package net.runelite.mixins;
|
||||||
|
|
||||||
import net.runelite.api.Model;
|
|
||||||
import net.runelite.api.Perspective;
|
|
||||||
import net.runelite.api.Point;
|
|
||||||
import net.runelite.api.model.Jarvis;
|
|
||||||
import net.runelite.api.model.Triangle;
|
|
||||||
import net.runelite.api.model.Vertex;
|
|
||||||
import java.awt.Polygon;
|
import java.awt.Polygon;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import net.runelite.api.Model;
|
||||||
|
import net.runelite.api.Perspective;
|
||||||
|
import net.runelite.api.Point;
|
||||||
import net.runelite.api.mixins.Copy;
|
import net.runelite.api.mixins.Copy;
|
||||||
import net.runelite.api.mixins.Inject;
|
import net.runelite.api.mixins.Inject;
|
||||||
import net.runelite.api.mixins.MethodHook;
|
import net.runelite.api.mixins.MethodHook;
|
||||||
import net.runelite.api.mixins.Mixin;
|
import net.runelite.api.mixins.Mixin;
|
||||||
import net.runelite.api.mixins.Replace;
|
import net.runelite.api.mixins.Replace;
|
||||||
import net.runelite.api.mixins.Shadow;
|
import net.runelite.api.mixins.Shadow;
|
||||||
|
import net.runelite.api.model.Jarvis;
|
||||||
|
import net.runelite.api.model.Triangle;
|
||||||
|
import net.runelite.api.model.Vertex;
|
||||||
import net.runelite.rs.api.RSAnimation;
|
import net.runelite.rs.api.RSAnimation;
|
||||||
import net.runelite.rs.api.RSClient;
|
import net.runelite.rs.api.RSClient;
|
||||||
import net.runelite.rs.api.RSFrames;
|
import net.runelite.rs.api.RSFrames;
|
||||||
@@ -77,9 +77,112 @@ public abstract class RSModelMixin implements RSModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public boolean isClickable() {
|
public boolean isClickable()
|
||||||
|
{
|
||||||
return isClickable;
|
return isClickable;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public void interpolateFrames(RSFrames frames, int frameId, RSFrames nextFrames, int nextFrameId, int interval, int intervalCount)
|
||||||
|
{
|
||||||
|
if (getVertexGroups() != null)
|
||||||
|
{
|
||||||
|
if (frameId != -1)
|
||||||
|
{
|
||||||
|
RSAnimation frame = frames.getFrames()[frameId];
|
||||||
|
RSSkeleton skin = frame.getSkin();
|
||||||
|
RSAnimation nextFrame = null;
|
||||||
|
if (nextFrames != null)
|
||||||
|
{
|
||||||
|
nextFrame = nextFrames.getFrames()[nextFrameId];
|
||||||
|
if (nextFrame.getSkin() != skin)
|
||||||
|
{
|
||||||
|
nextFrame = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
client.setAnimOffsetX(0);
|
||||||
|
client.setAnimOffsetY(0);
|
||||||
|
client.setAnimOffsetZ(0);
|
||||||
|
|
||||||
|
interpolateFrames(skin, frame, nextFrame, interval, intervalCount);
|
||||||
|
resetBounds();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Inject
|
||||||
|
public Polygon getConvexHull(int localX, int localY, int orientation, int tileHeight)
|
||||||
|
{
|
||||||
|
List<Vertex> vertices = getVertices();
|
||||||
|
|
||||||
|
// rotate vertices
|
||||||
|
for (int i = 0; i < vertices.size(); ++i)
|
||||||
|
{
|
||||||
|
Vertex v = vertices.get(i);
|
||||||
|
vertices.set(i, v.rotate(orientation));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Point> points = new ArrayList<Point>();
|
||||||
|
|
||||||
|
for (Vertex v : vertices)
|
||||||
|
{
|
||||||
|
// Compute canvas location of vertex
|
||||||
|
Point p = Perspective.localToCanvas(client,
|
||||||
|
localX - v.getX(),
|
||||||
|
localY - v.getZ(),
|
||||||
|
tileHeight + v.getY());
|
||||||
|
if (p != null)
|
||||||
|
{
|
||||||
|
points.add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run Jarvis march algorithm
|
||||||
|
points = Jarvis.convexHull(points);
|
||||||
|
if (points == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to a polygon
|
||||||
|
Polygon p = new Polygon();
|
||||||
|
for (Point point : points)
|
||||||
|
{
|
||||||
|
p.addPoint(point.getX(), point.getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Override
|
||||||
|
public float[][] getFaceTextureUCoordinates()
|
||||||
|
{
|
||||||
|
return rl$faceTextureUCoordinates;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Override
|
||||||
|
public void setFaceTextureUCoordinates(float[][] faceTextureUCoordinates)
|
||||||
|
{
|
||||||
|
this.rl$faceTextureUCoordinates = faceTextureUCoordinates;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Override
|
||||||
|
public float[][] getFaceTextureVCoordinates()
|
||||||
|
{
|
||||||
|
return rl$faceTextureVCoordinates;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Override
|
||||||
|
public void setFaceTextureVCoordinates(float[][] faceTextureVCoordinates)
|
||||||
|
{
|
||||||
|
this.rl$faceTextureVCoordinates = faceTextureVCoordinates;
|
||||||
|
}
|
||||||
|
|
||||||
@MethodHook(value = "<init>", end = true)
|
@MethodHook(value = "<init>", end = true)
|
||||||
@Inject
|
@Inject
|
||||||
@@ -174,6 +277,48 @@ public abstract class RSModelMixin implements RSModel
|
|||||||
return triangles;
|
return triangles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Override
|
||||||
|
public int getSceneId()
|
||||||
|
{
|
||||||
|
return rl$sceneId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Override
|
||||||
|
public void setSceneId(int sceneId)
|
||||||
|
{
|
||||||
|
this.rl$sceneId = sceneId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Override
|
||||||
|
public int getBufferOffset()
|
||||||
|
{
|
||||||
|
return rl$bufferOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Override
|
||||||
|
public void setBufferOffset(int bufferOffset)
|
||||||
|
{
|
||||||
|
rl$bufferOffset = bufferOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Override
|
||||||
|
public int getUvBufferOffset()
|
||||||
|
{
|
||||||
|
return rl$uvBufferOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Override
|
||||||
|
public void setUvBufferOffset(int bufferOffset)
|
||||||
|
{
|
||||||
|
rl$uvBufferOffset = bufferOffset;
|
||||||
|
}
|
||||||
|
|
||||||
@Copy("contourGround")
|
@Copy("contourGround")
|
||||||
public abstract Model rs$contourGround(int[][] tileHeights, int packedX, int height, int packedY, boolean copy, int contouredGround);
|
public abstract Model rs$contourGround(int[][] tileHeights, int packedX, int height, int packedY, boolean copy, int contouredGround);
|
||||||
|
|
||||||
@@ -201,36 +346,6 @@ public abstract class RSModelMixin implements RSModel
|
|||||||
rsModel.setFaceTextureVCoordinates(rl$faceTextureVCoordinates);
|
rsModel.setFaceTextureVCoordinates(rl$faceTextureVCoordinates);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject
|
|
||||||
public void interpolateFrames(RSFrames frames, int frameId, RSFrames nextFrames, int nextFrameId, int interval,
|
|
||||||
int intervalCount)
|
|
||||||
{
|
|
||||||
if (getVertexGroups() != null)
|
|
||||||
{
|
|
||||||
if (frameId != -1)
|
|
||||||
{
|
|
||||||
RSAnimation frame = frames.getFrames()[frameId];
|
|
||||||
RSSkeleton skin = frame.getSkin();
|
|
||||||
RSAnimation nextFrame = null;
|
|
||||||
if (nextFrames != null)
|
|
||||||
{
|
|
||||||
nextFrame = nextFrames.getFrames()[nextFrameId];
|
|
||||||
if (nextFrame.getSkin() != skin)
|
|
||||||
{
|
|
||||||
nextFrame = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
client.setAnimOffsetX(0);
|
|
||||||
client.setAnimOffsetY(0);
|
|
||||||
client.setAnimOffsetZ(0);
|
|
||||||
|
|
||||||
interpolateFrames(skin, frame, nextFrame, interval, intervalCount);
|
|
||||||
resetBounds();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public void interpolateFrames(RSSkeleton skin, RSAnimation frame, RSAnimation nextFrame, int interval, int intervalCount)
|
public void interpolateFrames(RSSkeleton skin, RSAnimation frame, RSAnimation nextFrame, int interval, int intervalCount)
|
||||||
{
|
{
|
||||||
@@ -334,119 +449,4 @@ public abstract class RSModelMixin implements RSModel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@Inject
|
|
||||||
public Polygon getConvexHull(int localX, int localY, int orientation, int tileHeight)
|
|
||||||
{
|
|
||||||
List<Vertex> vertices = getVertices();
|
|
||||||
|
|
||||||
// rotate vertices
|
|
||||||
for (int i = 0; i < vertices.size(); ++i)
|
|
||||||
{
|
|
||||||
Vertex v = vertices.get(i);
|
|
||||||
vertices.set(i, v.rotate(orientation));
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Point> points = new ArrayList<Point>();
|
|
||||||
|
|
||||||
for (Vertex v : vertices)
|
|
||||||
{
|
|
||||||
// Compute canvas location of vertex
|
|
||||||
Point p = Perspective.localToCanvas(client,
|
|
||||||
localX - v.getX(),
|
|
||||||
localY - v.getZ(),
|
|
||||||
tileHeight + v.getY());
|
|
||||||
if (p != null)
|
|
||||||
{
|
|
||||||
points.add(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run Jarvis march algorithm
|
|
||||||
points = Jarvis.convexHull(points);
|
|
||||||
if (points == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert to a polygon
|
|
||||||
Polygon p = new Polygon();
|
|
||||||
for (Point point : points)
|
|
||||||
{
|
|
||||||
p.addPoint(point.getX(), point.getY());
|
|
||||||
}
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
@Override
|
|
||||||
public int getSceneId()
|
|
||||||
{
|
|
||||||
return rl$sceneId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
@Override
|
|
||||||
public void setSceneId(int sceneId)
|
|
||||||
{
|
|
||||||
this.rl$sceneId = sceneId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
@Override
|
|
||||||
public int getBufferOffset()
|
|
||||||
{
|
|
||||||
return rl$bufferOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
@Override
|
|
||||||
public void setBufferOffset(int bufferOffset)
|
|
||||||
{
|
|
||||||
rl$bufferOffset = bufferOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
@Override
|
|
||||||
public int getUvBufferOffset()
|
|
||||||
{
|
|
||||||
return rl$uvBufferOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
@Override
|
|
||||||
public void setUvBufferOffset(int bufferOffset)
|
|
||||||
{
|
|
||||||
rl$uvBufferOffset = bufferOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
@Override
|
|
||||||
public float[][] getFaceTextureUCoordinates()
|
|
||||||
{
|
|
||||||
return rl$faceTextureUCoordinates;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
@Override
|
|
||||||
public void setFaceTextureUCoordinates(float[][] faceTextureUCoordinates)
|
|
||||||
{
|
|
||||||
this.rl$faceTextureUCoordinates = faceTextureUCoordinates;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
@Override
|
|
||||||
public float[][] getFaceTextureVCoordinates()
|
|
||||||
{
|
|
||||||
return rl$faceTextureVCoordinates;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
@Override
|
|
||||||
public void setFaceTextureVCoordinates(float[][] faceTextureVCoordinates)
|
|
||||||
{
|
|
||||||
this.rl$faceTextureVCoordinates = faceTextureVCoordinates;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import net.runelite.api.Renderable;
|
|||||||
import net.runelite.api.SceneTileModel;
|
import net.runelite.api.SceneTileModel;
|
||||||
import net.runelite.api.SceneTilePaint;
|
import net.runelite.api.SceneTilePaint;
|
||||||
import net.runelite.api.Tile;
|
import net.runelite.api.Tile;
|
||||||
import net.runelite.api.coords.LocalPoint;
|
|
||||||
import net.runelite.api.hooks.DrawCallbacks;
|
import net.runelite.api.hooks.DrawCallbacks;
|
||||||
import net.runelite.api.mixins.Copy;
|
import net.runelite.api.mixins.Copy;
|
||||||
import net.runelite.api.mixins.Inject;
|
import net.runelite.api.mixins.Inject;
|
||||||
@@ -702,26 +701,7 @@ public abstract class RSSceneMixin implements RSScene
|
|||||||
@Inject
|
@Inject
|
||||||
static void setTargetTile(int targetX, int targetY)
|
static void setTargetTile(int targetX, int targetY)
|
||||||
{
|
{
|
||||||
final LocalPoint current = client.getLocalPlayer().getLocalLocation();
|
client.setSelectedSceneTileX(targetX);
|
||||||
|
client.setSelectedSceneTileY(targetY);
|
||||||
// Limit walk distance - https://math.stackexchange.com/a/85582
|
|
||||||
final int a = current.getSceneX();
|
|
||||||
final int b = current.getSceneY();
|
|
||||||
final int c = targetX;
|
|
||||||
final int d = targetY;
|
|
||||||
|
|
||||||
final int r = MAX_TARGET_DISTANCE;
|
|
||||||
final int t = (int) Math.hypot(a - c, b - d) - r;
|
|
||||||
int x = targetX;
|
|
||||||
int y = targetY;
|
|
||||||
|
|
||||||
if (t > 0)
|
|
||||||
{
|
|
||||||
x = (r * c + t * a) / (r + t);
|
|
||||||
y = (r * d + t * b) / (r + t);
|
|
||||||
}
|
|
||||||
|
|
||||||
client.setSelectedSceneTileX(x);
|
|
||||||
client.setSelectedSceneTileY(y);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -258,6 +258,11 @@ public abstract class RSWidgetMixin implements RSWidget
|
|||||||
|
|
||||||
for (int i = 0; i < itemIds.length; ++i)
|
for (int i = 0; i < itemIds.length; ++i)
|
||||||
{
|
{
|
||||||
|
if (itemIds[i] <= 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
WidgetItem item = getWidgetItem(i);
|
WidgetItem item = getWidgetItem(i);
|
||||||
|
|
||||||
if (item != null)
|
if (item != null)
|
||||||
@@ -287,19 +292,17 @@ public abstract class RSWidgetMixin implements RSWidget
|
|||||||
int itemId = itemIds[index];
|
int itemId = itemIds[index];
|
||||||
int itemQuantity = itemQuantities[index];
|
int itemQuantity = itemQuantities[index];
|
||||||
|
|
||||||
Point widgetCanvasLocation = getCanvasLocation();
|
if (columns <= 0)
|
||||||
|
|
||||||
if (itemId <= 0 || itemQuantity <= 0 || columns <= 0)
|
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
int row = index / columns;
|
int row = index / columns;
|
||||||
int col = index % columns;
|
int col = index % columns;
|
||||||
int itemX = widgetCanvasLocation.getX() + ((ITEM_SLOT_SIZE + xPitch) * col);
|
int itemX = rl$x + ((ITEM_SLOT_SIZE + xPitch) * col);
|
||||||
int itemY = widgetCanvasLocation.getY() + ((ITEM_SLOT_SIZE + yPitch) * row);
|
int itemY = rl$y + ((ITEM_SLOT_SIZE + yPitch) * row);
|
||||||
|
|
||||||
Rectangle bounds = new Rectangle(itemX - 1, itemY - 1, ITEM_SLOT_SIZE, ITEM_SLOT_SIZE);
|
Rectangle bounds = new Rectangle(itemX, itemY, ITEM_SLOT_SIZE, ITEM_SLOT_SIZE);
|
||||||
return new WidgetItem(itemId - 1, itemQuantity, index, bounds, this);
|
return new WidgetItem(itemId - 1, itemQuantity, index, bounds, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -529,11 +529,11 @@ public interface RSClient extends RSGameShell, Client
|
|||||||
@Import("mapDotSprites")
|
@Import("mapDotSprites")
|
||||||
RSSprite[] getMapDots();
|
RSSprite[] getMapDots();
|
||||||
|
|
||||||
@Import("modIconSprites")
|
@Import("AbstractFont_modIconSprites")
|
||||||
@Override
|
@Override
|
||||||
RSIndexedSprite[] getModIcons();
|
RSIndexedSprite[] getModIcons();
|
||||||
|
|
||||||
@Import("modIconSprites")
|
@Import("AbstractFont_modIconSprites")
|
||||||
void setRSModIcons(RSIndexedSprite[] modIcons);
|
void setRSModIcons(RSIndexedSprite[] modIcons);
|
||||||
|
|
||||||
@Construct
|
@Construct
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public interface RSItemDefinition extends ItemDefinition
|
|||||||
@Override
|
@Override
|
||||||
int getNote();
|
int getNote();
|
||||||
|
|
||||||
@Import("notedId")
|
@Import("note")
|
||||||
@Override
|
@Override
|
||||||
int getLinkedNoteId();
|
int getLinkedNoteId();
|
||||||
|
|
||||||
|
|||||||
@@ -12,19 +12,19 @@ public interface RSMessage extends MessageNode
|
|||||||
@Import("type")
|
@Import("type")
|
||||||
int getRSType();
|
int getRSType();
|
||||||
|
|
||||||
@Import("prefix")
|
@Import("sender")
|
||||||
@Override
|
@Override
|
||||||
String getName();
|
String getName();
|
||||||
|
|
||||||
@Import("prefix")
|
@Import("sender")
|
||||||
@Override
|
@Override
|
||||||
void setName(String name);
|
void setName(String name);
|
||||||
|
|
||||||
@Import("sender")
|
@Import("prefix")
|
||||||
@Override
|
@Override
|
||||||
String getSender();
|
String getSender();
|
||||||
|
|
||||||
@Import("sender")
|
@Import("prefix")
|
||||||
@Override
|
@Override
|
||||||
void setSender(String sender);
|
void setSender(String sender);
|
||||||
|
|
||||||
|
|||||||
@@ -4710,7 +4710,7 @@ public final class Client extends GameShell implements Usernamed {
|
|||||||
int var8;
|
int var8;
|
||||||
if(!isMenuOpen) {
|
if(!isMenuOpen) {
|
||||||
if(__client_lq != -1) {
|
if(__client_lq != -1) {
|
||||||
class39.method741(__client_lq, __client_ln);
|
class39.drawMenuActionTextAt(__client_lq, __client_ln);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var1 = class25.menuX;
|
var1 = class25.menuX;
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ public class Skills {
|
|||||||
var1.__g_428(getItemDefinition(var1.placeholderTemplate), getItemDefinition(var1.placeholder));
|
var1.__g_428(getItemDefinition(var1.placeholderTemplate), getItemDefinition(var1.placeholder));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!class30.__ar_l && var1.isMembersOnly) {
|
if(!class30.inMembersWorld && var1.isMembersOnly) {
|
||||||
var1.name = "Members object";
|
var1.name = "Members object";
|
||||||
var1.isTradable = false;
|
var1.isTradable = false;
|
||||||
var1.groundActions = null;
|
var1.groundActions = null;
|
||||||
|
|||||||
@@ -251,7 +251,7 @@ public class class171 {
|
|||||||
Font var6 = ScriptEvent.fontPlain11;
|
Font var6 = ScriptEvent.fontPlain11;
|
||||||
ItemDefinition.ItemDefinition_indexCache = var3;
|
ItemDefinition.ItemDefinition_indexCache = var3;
|
||||||
ItemDefinition.ItemDefinition_modelIndexCache = var4;
|
ItemDefinition.ItemDefinition_modelIndexCache = var4;
|
||||||
class30.__ar_l = var5;
|
class30.inMembersWorld = var5;
|
||||||
class83.__cm_e = ItemDefinition.ItemDefinition_indexCache.__s_396(10);
|
class83.__cm_e = ItemDefinition.ItemDefinition_indexCache.__s_396(10);
|
||||||
class204.__gx_n = var6;
|
class204.__gx_n = var6;
|
||||||
IndexCache var7 = ObjectSound.indexCache2;
|
IndexCache var7 = ObjectSound.indexCache2;
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ public class class30 {
|
|||||||
@Export("musicTrackArchiveId")
|
@Export("musicTrackArchiveId")
|
||||||
public static int musicTrackArchiveId;
|
public static int musicTrackArchiveId;
|
||||||
@ObfuscatedName("l")
|
@ObfuscatedName("l")
|
||||||
@Export("__ar_l")
|
@Export("inMembersWorld")
|
||||||
public static boolean __ar_l;
|
public static boolean inMembersWorld;
|
||||||
@ObfuscatedName("bd")
|
@ObfuscatedName("bd")
|
||||||
@ObfuscatedSignature(
|
@ObfuscatedSignature(
|
||||||
signature = "[Lln;"
|
signature = "[Lln;"
|
||||||
|
|||||||
@@ -40,9 +40,9 @@ public class class31 {
|
|||||||
if(var0.__e_144() != Client.isMembersWorld) {
|
if(var0.__e_144() != Client.isMembersWorld) {
|
||||||
Client.isMembersWorld = var0.__e_144();
|
Client.isMembersWorld = var0.__e_144();
|
||||||
boolean var1 = var0.__e_144();
|
boolean var1 = var0.__e_144();
|
||||||
if(var1 != class30.__ar_l) {
|
if(var1 != class30.inMembersWorld) {
|
||||||
class72.method1780();
|
class72.method1780();
|
||||||
class30.__ar_l = var1;
|
class30.inMembersWorld = var1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -767,7 +767,8 @@ public class class39 extends class21 {
|
|||||||
signature = "(IIB)V",
|
signature = "(IIB)V",
|
||||||
garbageValue = "3"
|
garbageValue = "3"
|
||||||
)
|
)
|
||||||
static final void method741(int var0, int var1) {
|
@Export("drawMenuActionTextAt")
|
||||||
|
static final void drawMenuActionTextAt(int var0, int var1) {
|
||||||
if(Client.menuOptionsCount >= 2 || Client.isItemSelected != 0 || Client.isSpellSelected) {
|
if(Client.menuOptionsCount >= 2 || Client.isItemSelected != 0 || Client.isSpellSelected) {
|
||||||
if(Client.showMouseOverText) {
|
if(Client.showMouseOverText) {
|
||||||
int var2 = Client.menuOptionsCount - 1;
|
int var2 = Client.menuOptionsCount - 1;
|
||||||
@@ -790,10 +791,10 @@ public class class39 extends class21 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(Client.menuOptionsCount > 2) {
|
if(Client.menuOptionsCount > 2) {
|
||||||
var4 = var4 + BufferedFile.colorStartTag(16777215) + " " + '/' + " " + (Client.menuOptionsCount - 2) + " more options";
|
var4 = var4 + BufferedFile.colorStartTag(0xffffff) + " " + '/' + " " + (Client.menuOptionsCount - 2) + " more options";
|
||||||
}
|
}
|
||||||
|
|
||||||
class2.fontBold12.drawRandomAlphaAndSpacing(var4, var0 + 4, var1 + 15, 16777215, 0, Client.cycle / 1000);
|
class2.fontBold12.drawRandomAlphaAndSpacing(var4, var0 + 4, var1 + 15, 0xffffff, 0, Client.cycle / 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
mvn clean install --settings travis/settings.xml
|
mvn clean install -DskipTests --settings travis/settings.xml
|
||||||
|
|||||||
@@ -259,7 +259,8 @@ under the License.
|
|||||||
<properties>
|
<properties>
|
||||||
<maven.javadoc.skip>true</maven.javadoc.skip>
|
<maven.javadoc.skip>true</maven.javadoc.skip>
|
||||||
<checkstyle.skip>false</checkstyle.skip>
|
<checkstyle.skip>false</checkstyle.skip>
|
||||||
<archetype.test.skip>false</archetype.test.skip>
|
<archetype.test.skip>true</archetype.test.skip>
|
||||||
|
<test.skip>true</test.skip>
|
||||||
</properties>
|
</properties>
|
||||||
</profile>
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
|
|||||||
Reference in New Issue
Block a user