Merge pull request #1 from runelite-extended/master

build update
This commit is contained in:
se7enAte9
2019-06-10 17:19:38 -04:00
committed by GitHub
76 changed files with 2218 additions and 1243 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -44,7 +44,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 InjectGetter class InjectGetter
{ {
private static final Logger logger = LoggerFactory.getLogger(InjectGetter.class); private static final Logger logger = LoggerFactory.getLogger(InjectGetter.class);
@@ -52,12 +52,12 @@ public class InjectGetter
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;
} }

View File

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

View File

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

View File

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

View File

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

View File

@@ -45,7 +45,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 InjectSetter class InjectSetter
{ {
private static final Logger logger = LoggerFactory.getLogger(InjectSetter.class); private static final Logger logger = LoggerFactory.getLogger(InjectSetter.class);
@@ -53,7 +53,7 @@ public class InjectSetter
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)
@@ -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;
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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!");
} }
} }
*/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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"),

View File

@@ -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.")

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,3 +1,3 @@
#!/bin/bash #!/bin/bash
mvn clean install --settings travis/settings.xml mvn clean install -DskipTests --settings travis/settings.xml

View File

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