Merge branch 'master' into loot-tracker-reset

This commit is contained in:
Tyler Bochard
2019-07-08 19:36:32 -04:00
committed by GitHub
1232 changed files with 51400 additions and 46135 deletions
+3
View File
@@ -0,0 +1,3 @@
# These are supported funding model platforms
patreon: RuneLitePlus
+1
View File
@@ -13,3 +13,4 @@ git
classes/artifacts/client_jar/run.bat classes/artifacts/client_jar/run.bat
classes/artifacts/client_jar/client.jar classes/artifacts/client_jar/client.jar
*.jar *.jar
.live/
+1 -1
View File
@@ -29,7 +29,7 @@
<parent> <parent>
<groupId>net.runelite</groupId> <groupId>net.runelite</groupId>
<artifactId>runelite-parent</artifactId> <artifactId>runelite-parent</artifactId>
<version>1.5.28-SNAPSHOT</version> <version>1.5.29-SNAPSHOT</version>
</parent> </parent>
<artifactId>cache-client</artifactId> <artifactId>cache-client</artifactId>
+1 -1
View File
@@ -28,7 +28,7 @@
<parent> <parent>
<groupId>net.runelite</groupId> <groupId>net.runelite</groupId>
<artifactId>runelite-parent</artifactId> <artifactId>runelite-parent</artifactId>
<version>1.5.28-SNAPSHOT</version> <version>1.5.29-SNAPSHOT</version>
</parent> </parent>
<name>Cache Updater</name> <name>Cache Updater</name>
+1 -1
View File
@@ -29,7 +29,7 @@
<parent> <parent>
<groupId>net.runelite</groupId> <groupId>net.runelite</groupId>
<artifactId>runelite-parent</artifactId> <artifactId>runelite-parent</artifactId>
<version>1.5.28-SNAPSHOT</version> <version>1.5.29-SNAPSHOT</version>
</parent> </parent>
<artifactId>cache</artifactId> <artifactId>cache</artifactId>
@@ -78,6 +78,7 @@ public class Instructions
add(CC_SETSIZE, "cc_setsize"); add(CC_SETSIZE, "cc_setsize");
add(CC_SETHIDE, "cc_sethide"); add(CC_SETHIDE, "cc_sethide");
add(CC_SETNOCLICKTHROUGH, "cc_setnoclickthrough"); add(CC_SETNOCLICKTHROUGH, "cc_setnoclickthrough");
add(CC_SETNOSCROLLTHROUGH, "cc_setnoscrollthrough");
add(CC_SETSCROLLPOS, "cc_setscrollpos"); add(CC_SETSCROLLPOS, "cc_setscrollpos");
add(CC_SETCOLOUR, "cc_setcolour"); add(CC_SETCOLOUR, "cc_setcolour");
add(CC_SETFILL, "cc_setfill"); add(CC_SETFILL, "cc_setfill");
@@ -287,11 +288,14 @@ public class Instructions
add(SETSHOWLOADINGMESSAGES, "setshowloadingmessages"); add(SETSHOWLOADINGMESSAGES, "setshowloadingmessages");
add(SETTAPTODROP, "settaptodrop"); add(SETTAPTODROP, "settaptodrop");
add(GETTAPTODROP, "gettaptodrop"); add(GETTAPTODROP, "gettaptodrop");
add(SETOCULUSORBSPEED, "setoculusorbspeed");
add(GETCANVASSIZE, "getcanvassize"); add(GETCANVASSIZE, "getcanvassize");
add(SETHIDEUSERNAME, "sethideusername"); add(SETHIDEUSERNAME, "sethideusername");
add(GETHIDEUSERNAME, "gethideusername"); add(GETHIDEUSERNAME, "gethideusername");
add(SETREMEMBERUSERNAME, "setrememberusername"); add(SETREMEMBERUSERNAME, "setrememberusername");
add(GETREMEMBERUSERNAME, "getrememberusername"); add(GETREMEMBERUSERNAME, "getrememberusername");
add(SETTITLEMUSICENABLED, "settitlemusicenabled");
add(GETTITLEMUSICENABLED, "gettitlemusicenabled");
add(SOUND_SYNTH, "sound_synth"); add(SOUND_SYNTH, "sound_synth");
add(SOUND_SONG, "sound_song"); add(SOUND_SONG, "sound_song");
add(SOUND_JINGLE, "sound_jingle"); add(SOUND_JINGLE, "sound_jingle");
@@ -411,6 +415,7 @@ public class Instructions
add(REMOVETAGS, "removetags"); add(REMOVETAGS, "removetags");
add(STRING_INDEXOF_CHAR, "string_indexof_char"); add(STRING_INDEXOF_CHAR, "string_indexof_char");
add(STRING_INDEXOF_STRING, "string_indexof_string"); add(STRING_INDEXOF_STRING, "string_indexof_string");
add(UPPERCASE, "uppercase");
add(OC_NAME, "oc_name"); add(OC_NAME, "oc_name");
add(OC_OP, "oc_op"); add(OC_OP, "oc_op");
add(OC_IOP, "oc_iop"); add(OC_IOP, "oc_iop");
@@ -461,6 +466,7 @@ public class Instructions
add(WORLDLIST_NEXT, "worldlist_next"); add(WORLDLIST_NEXT, "worldlist_next");
add(WORLDLIST_SPECIFIC, "worldlist_specific"); add(WORLDLIST_SPECIFIC, "worldlist_specific");
add(WORLDLIST_SORT, "worldlist_sort"); add(WORLDLIST_SORT, "worldlist_sort");
add(GETWORLDINFO, "getworldinfo");
add(SETFOLLOWEROPSLOWPRIORITY, "setfolloweropslowpriority"); add(SETFOLLOWEROPSLOWPRIORITY, "setfolloweropslowpriority");
add(NC_PARAM, "nc_param"); add(NC_PARAM, "nc_param");
add(LC_PARAM, "lc_param"); add(LC_PARAM, "lc_param");
@@ -69,6 +69,7 @@ public class Opcodes
public static final int CC_SETSIZE = 1001; public static final int CC_SETSIZE = 1001;
public static final int CC_SETHIDE = 1003; public static final int CC_SETHIDE = 1003;
public static final int CC_SETNOCLICKTHROUGH = 1005; public static final int CC_SETNOCLICKTHROUGH = 1005;
public static final int CC_SETNOSCROLLTHROUGH = 1006;
public static final int CC_SETSCROLLPOS = 1100; public static final int CC_SETSCROLLPOS = 1100;
public static final int CC_SETCOLOUR = 1101; public static final int CC_SETCOLOUR = 1101;
public static final int CC_SETFILL = 1102; public static final int CC_SETFILL = 1102;
@@ -278,11 +279,14 @@ public class Opcodes
public static final int SETSHOWLOADINGMESSAGES = 3126; public static final int SETSHOWLOADINGMESSAGES = 3126;
public static final int SETTAPTODROP = 3127; public static final int SETTAPTODROP = 3127;
public static final int GETTAPTODROP = 3128; public static final int GETTAPTODROP = 3128;
public static final int SETOCULUSORBSPEED = 3129;
public static final int GETCANVASSIZE = 3132; public static final int GETCANVASSIZE = 3132;
public static final int SETHIDEUSERNAME = 3141; public static final int SETHIDEUSERNAME = 3141;
public static final int GETHIDEUSERNAME = 3142; public static final int GETHIDEUSERNAME = 3142;
public static final int SETREMEMBERUSERNAME = 3143; public static final int SETREMEMBERUSERNAME = 3143;
public static final int GETREMEMBERUSERNAME = 3144; public static final int GETREMEMBERUSERNAME = 3144;
public static final int SETTITLEMUSICENABLED = 3146;
public static final int GETTITLEMUSICENABLED = 3147;
public static final int SOUND_SYNTH = 3200; public static final int SOUND_SYNTH = 3200;
public static final int SOUND_SONG = 3201; public static final int SOUND_SONG = 3201;
public static final int SOUND_JINGLE = 3202; public static final int SOUND_JINGLE = 3202;
@@ -402,6 +406,7 @@ public class Opcodes
public static final int REMOVETAGS = 4119; public static final int REMOVETAGS = 4119;
public static final int STRING_INDEXOF_CHAR = 4120; public static final int STRING_INDEXOF_CHAR = 4120;
public static final int STRING_INDEXOF_STRING = 4121; public static final int STRING_INDEXOF_STRING = 4121;
public static final int UPPERCASE = 4122;
public static final int OC_NAME = 4200; public static final int OC_NAME = 4200;
public static final int OC_OP = 4201; public static final int OC_OP = 4201;
public static final int OC_IOP = 4202; public static final int OC_IOP = 4202;
@@ -452,6 +457,7 @@ public class Opcodes
public static final int WORLDLIST_NEXT = 6502; public static final int WORLDLIST_NEXT = 6502;
public static final int WORLDLIST_SPECIFIC = 6506; public static final int WORLDLIST_SPECIFIC = 6506;
public static final int WORLDLIST_SORT = 6507; public static final int WORLDLIST_SORT = 6507;
public static final int GETWORLDINFO = 6511;
public static final int SETFOLLOWEROPSLOWPRIORITY = 6512; public static final int SETFOLLOWEROPSLOWPRIORITY = 6512;
public static final int NC_PARAM = 6513; public static final int NC_PARAM = 6513;
public static final int LC_PARAM = 6514; public static final int LC_PARAM = 6514;
+1 -1
View File
@@ -88,7 +88,7 @@ public class FrameDumper
int framemapArchiveId = (contents[0] & 0xff) << 8 | contents[1] & 0xff; int framemapArchiveId = (contents[0] & 0xff) << 8 | contents[1] & 0xff;
Archive framemapArchive = framemapIndex.getArchives().get(framemapArchiveId); Archive framemapArchive = framemapIndex.getArchive(framemapArchiveId);
archiveData = storage.loadArchive(framemapArchive); archiveData = storage.loadArchive(framemapArchive);
byte[] framemapContents = framemapArchive.decompress(archiveData); byte[] framemapContents = framemapArchive.decompress(archiveData);
+6
View File
@@ -1,6 +1,7 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!-- <!--
Copyright (c) 2017, Adam <Adam@sigterm.info> Copyright (c) 2017, Adam <Adam@sigterm.info>
Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -40,6 +41,11 @@
<property name="message" value="Indent must use tab characters"/> <property name="message" value="Indent must use tab characters"/>
<property name="ignoreComments" value="true"/> <property name="ignoreComments" value="true"/>
</module> </module>
<module name="RegexpSinglelineJava">
<property name="format" value="import (?!static|java\.awt).*\*"/>
<property name="message" value="Multiline imports are disallowed if they are not static"/>
<property name="ignoreComments" value="true"/>
</module>
<module name="WhitespaceAround"/> <module name="WhitespaceAround"/>
<module name="WhitespaceAfter"> <module name="WhitespaceAfter">
<property name="tokens" value="COMMA"/> <property name="tokens" value="COMMA"/>
+2 -1
View File
@@ -29,7 +29,7 @@
<parent> <parent>
<groupId>net.runelite</groupId> <groupId>net.runelite</groupId>
<artifactId>runelite-parent</artifactId> <artifactId>runelite-parent</artifactId>
<version>1.5.28-SNAPSHOT</version> <version>1.5.29-SNAPSHOT</version>
</parent> </parent>
<artifactId>deobfuscator</artifactId> <artifactId>deobfuscator</artifactId>
@@ -65,6 +65,7 @@
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId> <artifactId>slf4j-simple</artifactId>
<version>1.7.12</version> <version>1.7.12</version>
<scope>runtime</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.google.code.gson</groupId> <groupId>com.google.code.gson</groupId>
@@ -110,7 +110,7 @@ public class Type
{ {
s = s.substring(1); s = s.substring(1);
} }
if (s.startsWith("L")) if (s.startsWith("L") && s.endsWith(";"))
{ {
return s.substring(1, s.length() - 1); return s.substring(1, s.length() - 1);
} }
@@ -31,6 +31,7 @@ import net.runelite.asm.Field;
import net.runelite.asm.Method; import net.runelite.asm.Method;
import net.runelite.asm.signature.util.VirtualMethods; import net.runelite.asm.signature.util.VirtualMethods;
import net.runelite.deob.Deob; import net.runelite.deob.Deob;
import net.runelite.deob.DeobAnnotations;
import net.runelite.deob.Deobfuscator; import net.runelite.deob.Deobfuscator;
import net.runelite.deob.util.NameMappings; import net.runelite.deob.util.NameMappings;
@@ -60,7 +61,7 @@ public class RenameUnique implements Deobfuscator
for (ClassFile cf : group.getClasses()) for (ClassFile cf : group.getClasses())
for (Field field : cf.getFields()) for (Field field : cf.getFields())
{ {
if (field.getName().length() > Deob.OBFUSCATED_NAME_MAX_LEN) if (field.getName().length() > Deob.OBFUSCATED_NAME_MAX_LEN && !field.getName().startsWith("__") || field.getName().equals(DeobAnnotations.getExportedName(field.getAnnotations())))
continue; continue;
map.map(field.getPoolField(), "field" + i++); map.map(field.getPoolField(), "field" + i++);
@@ -74,7 +75,7 @@ public class RenameUnique implements Deobfuscator
for (ClassFile cf : group.getClasses()) for (ClassFile cf : group.getClasses())
for (Method method : cf.getMethods()) for (Method method : cf.getMethods())
{ {
if (method.getName().length() > Deob.OBFUSCATED_NAME_MAX_LEN) if (method.getName().length() > Deob.OBFUSCATED_NAME_MAX_LEN && !method.getName().startsWith("__") || method.getName().equals(DeobAnnotations.getExportedName(method.getAnnotations())))
continue; continue;
List<Method> virtualMethods = VirtualMethods.getVirtualMethods(method); List<Method> virtualMethods = VirtualMethods.getVirtualMethods(method);
@@ -216,6 +216,8 @@ public class Renamer implements Deobfuscator
field.getAnnotations().addAnnotation(DeobAnnotations.OBFUSCATED_NAME, "value", field.getName()); field.getAnnotations().addAnnotation(DeobAnnotations.OBFUSCATED_NAME, "value", field.getName());
} }
assert DeobAnnotations.getExportedName(field.getAnnotations()) == null || DeobAnnotations.getExportedName(field.getAnnotations()).equals(newName) : "Tried changing field name to something other than the exported name!";
field.setName(newName); field.setName(newName);
++fields; ++fields;
} }
@@ -0,0 +1,152 @@
package net.runelite.deob.deobfuscators.transformers;
import java.util.ListIterator;
import net.runelite.asm.ClassFile;
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.Code;
import net.runelite.asm.attributes.code.Instruction;
import net.runelite.asm.attributes.code.Instructions;
import net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction;
import net.runelite.asm.attributes.code.instructions.GetStatic;
import net.runelite.asm.attributes.code.instructions.ILoad;
import net.runelite.asm.attributes.code.instructions.IfICmpEq;
import net.runelite.asm.attributes.code.instructions.IfICmpNe;
import net.runelite.asm.attributes.code.instructions.LDC;
import net.runelite.asm.attributes.code.instructions.PutStatic;
import net.runelite.asm.attributes.code.instructions.VReturn;
import net.runelite.asm.pool.Class;
import net.runelite.asm.signature.Signature;
import net.runelite.deob.Transformer;
import net.runelite.deob.deobfuscators.transformers.scriptopcodes.ScriptOpcode;
import org.objectweb.asm.Opcodes;
import static org.objectweb.asm.Opcodes.ACC_FINAL;
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
import static org.objectweb.asm.Opcodes.ACC_STATIC;
public class ScriptOpcodesTransformer implements Transformer // robots in disguise
{
private static final String SCRIPT_OPCODES = "net/runelite/rs/ScriptOpcodes";
@Override
public void transform(ClassGroup group)
{
initializeOpcodesClassFile(group);
for (ClassFile cf : group.getClasses())
{
if (cf.getName().startsWith("net/runelite/rs"))
{
continue;
}
for (Method m : cf.getMethods())
{
if (!m.isStatic())
{
continue;
}
if (!m.getDescriptor().getArguments().contains(new Type("LScript;")) && !m.getDescriptor().getArguments().contains(new Type("LScriptEvent;")))
{
continue;
}
boolean varIndexIsKnownAnd0 = m.getDescriptor().getArguments().contains(new Type("LScript;"));
Code code = m.getCode();
Instructions ins = code.getInstructions();
ListIterator<Instruction> it = ins.getInstructions().listIterator();
Instruction i;
while (it.hasNext())
{
i = it.next();
if (!(i instanceof ILoad) || (varIndexIsKnownAnd0 && ((ILoad) i).getVariableIndex() != 0))
{
continue;
}
i = it.next();
if (!(i instanceof PushConstantInstruction) ||
!(((PushConstantInstruction) i).getConstant() instanceof Number))
{
continue;
}
int val = ((Number) ((PushConstantInstruction) i).getConstant()).intValue();
String name = ScriptOpcode.nameFromID(val);
i = it.next();
if (name == null || !(i instanceof IfICmpNe || i instanceof IfICmpEq))
{
continue;
}
it.previous();
it.previous();
net.runelite.asm.pool.Field pool = new net.runelite.asm.pool.Field(
new Class(SCRIPT_OPCODES),
name,
Type.INT
);
GetStatic getStatic = new GetStatic(ins, pool);
it.set(getStatic);
}
}
}
}
private static void initializeOpcodesClassFile(ClassGroup group)
{
ClassFile scriptOpcodes = group.findClass(SCRIPT_OPCODES);
if (scriptOpcodes == null)
{
scriptOpcodes = new ClassFile(group);
scriptOpcodes.setName(SCRIPT_OPCODES);
scriptOpcodes.setSuperName(Type.OBJECT.getInternalName());
scriptOpcodes.setAccess(Opcodes.ACC_PUBLIC);
group.addClass(scriptOpcodes);
}
else
{
scriptOpcodes.getFields().clear();
}
Method clinit = scriptOpcodes.findMethod("<clinit>");
if (clinit == null)
{
clinit = new Method(scriptOpcodes, "<clinit>", new Signature("()V"));
clinit.setStatic(true);
Code code = new Code(clinit);
code.setMaxStack(1);
clinit.setCode(code);
scriptOpcodes.addMethod(clinit);
}
Code code = clinit.getCode();
Instructions ins = code.getInstructions();
for (ScriptOpcode opcode : ScriptOpcode.values())
{
Field field = new Field(scriptOpcodes, opcode.name(), Type.INT);
field.setAccessFlags(ACC_PUBLIC | ACC_STATIC | ACC_FINAL);
field.setValue(opcode.opcode);
scriptOpcodes.addField(field);
LDC ldc = new LDC(ins, opcode.opcode);
PutStatic put = new PutStatic(ins, field);
ins.addInstruction(0, ldc);
ins.addInstruction(1, put);
}
ins.addInstruction(new VReturn(ins));
}
}
@@ -0,0 +1,517 @@
package net.runelite.deob.deobfuscators.transformers.scriptopcodes;
import com.google.common.collect.ImmutableMap;
import java.util.Map;
public enum ScriptOpcode
{
// This class is pretty much the same as net.runelite.cache.script.Opcodes, and should be updated alongside that
ICONST(0),
GET_VARP(1),
SET_VARP(2),
SCONST(3),
JUMP(6),
IF_ICMPNE(7),
IF_ICMPEQ(8),
IF_ICMPLT(9),
IF_ICMPGT(10),
RETURN(21),
GET_VARBIT(25),
SET_VARBIT(27),
IF_ICMPLE(31),
IF_ICMPGE(32),
ILOAD(33),
ISTORE(34),
SLOAD(35),
SSTORE(36),
JOIN_STRING(37),
POP_INT(38),
POP_STRING(39),
INVOKE(40),
GET_VARC_INT(42),
SET_VARC_INT(43),
DEFINE_ARRAY(44),
GET_ARRAY_INT(45),
SET_ARRAY_INT(46),
GET_VARC_STRING_OLD(47),
SET_VARC_STRING_OLD(48),
GET_VARC_STRING(49),
SET_VARC_STRING(50),
SWITCH(60),
CC_CREATE(100),
CC_DELETE(101),
CC_DELETEALL(102),
CC_FIND(200),
IF_FIND(201),
CC_SETPOSITION(1000),
CC_SETSIZE(1001),
CC_SETHIDE(1003),
CC_SETNOCLICKTHROUGH(1005),
CC_SETNOSCROLLTHROUGH(1006),
CC_SETSCROLLPOS(1100),
CC_SETCOLOUR(1101),
CC_SETFILL(1102),
CC_SETTRANS(1103),
CC_SETLINEWID(1104),
CC_SETGRAPHIC(1105),
CC_SET2DANGLE(1106),
CC_SETTILING(1107),
CC_SETMODEL(1108),
CC_SETMODELANGLE(1109),
CC_SETMODELANIM(1110),
CC_SETMODELORTHOG(1111),
CC_SETTEXT(1112),
CC_SETTEXTFONT(1113),
CC_SETTEXTALIGN(1114),
CC_SETTEXTSHADOW(1115),
CC_SETOUTLINE(1116),
CC_SETGRAPHICSHADOW(1117),
CC_SETVFLIP(1118),
CC_SETHFLIP(1119),
CC_SETSCROLLSIZE(1120),
CC_RESUME_PAUSEBUTTON(1121),
CC_SETFILLCOLOUR(1123),
CC_SETLINEDIRECTION(1126),
CC_SETOBJECT(1200),
CC_SETNPCHEAD(1201),
CC_SETPLAYERHEAD_SELF(1202),
CC_SETOBJECT_NONUM(1205),
CC_SETOBJECT_ALWAYS_NUM(1212),
CC_SETOP(1300),
CC_SETDRAGGABLE(1301),
CC_SETDRAGGABLEBEHAVIOR(1302),
CC_SETDRAGDEADZONE(1303),
CC_SETDRAGDEADTIME(1304),
CC_SETOPBASE(1305),
CC_SETTARGETVERB(1306),
CC_CLEAROPS(1307),
CC_SETONCLICK(1400),
CC_SETONHOLD(1401),
CC_SETONRELEASE(1402),
CC_SETONMOUSEOVER(1403),
CC_SETONMOUSELEAVE(1404),
CC_SETONDRAG(1405),
CC_SETONTARGETLEAVE(1406),
CC_SETONVARTRANSMIT(1407),
CC_SETONTIMER(1408),
CC_SETONOP(1409),
CC_SETONDRAGCOMPLETE(1410),
CC_SETONCLICKREPEAT(1411),
CC_SETONMOUSEREPEAT(1412),
CC_SETONINVTRANSMIT(1414),
CC_SETONSTATTRANSMIT(1415),
CC_SETONTARGETENTER(1416),
CC_SETONSCROLLWHEEL(1417),
CC_SETONCHATTRANSMIT(1418),
CC_SETONKEY(1419),
CC_SETONFRIENDTRANSMIT(1420),
CC_SETONCLANTRANSMIT(1421),
CC_SETONMISCTRANSMIT(1422),
CC_SETONDIALOGABORT(1423),
CC_SETONSUBCHANGE(1424),
CC_SETONSTOCKTRANSMIT(1425),
CC_SETONRESIZE(1427),
CC_GETX(1500),
CC_GETY(1501),
CC_GETWIDTH(1502),
CC_GETHEIGHT(1503),
CC_GETHIDE(1504),
CC_GETLAYER(1505),
CC_GETSCROLLX(1600),
CC_GETSCROLLY(1601),
CC_GETTEXT(1602),
CC_GETSCROLLWIDTH(1603),
CC_GETSCROLLHEIGHT(1604),
CC_GETMODELZOOM(1605),
CC_GETMODELANGLE_X(1606),
CC_GETMODELANGLE_Z(1607),
CC_GETMODELANGLE_Y(1608),
CC_GETTRANS(1609),
CC_GETCOLOUR(1611),
CC_GETFILLCOLOUR(1612),
CC_GETINVOBJECT(1700),
CC_GETINVCOUNT(1701),
CC_GETID(1702),
CC_GETTARGETMASK(1800),
CC_GETOP(1801),
CC_GETOPBASE(1802),
CC_CALLONRESIZE(1927),
IF_SETPOSITION(2000),
IF_SETSIZE(2001),
IF_SETHIDE(2003),
IF_SETNOCLICKTHROUGH(2005),
IF_SETSCROLLPOS(2100),
IF_SETCOLOUR(2101),
IF_SETFILL(2102),
IF_SETTRANS(2103),
IF_SETLINEWID(2104),
IF_SETGRAPHIC(2105),
IF_SET2DANGLE(2106),
IF_SETTILING(2107),
IF_SETMODEL(2108),
IF_SETMODELANGLE(2109),
IF_SETMODELANIM(2110),
IF_SETMODELORTHOG(2111),
IF_SETTEXT(2112),
IF_SETTEXTFONT(2113),
IF_SETTEXTALIGN(2114),
IF_SETTEXTSHADOW(2115),
IF_SETOUTLINE(2116),
IF_SETGRAPHICSHADOW(2117),
IF_SETVFLIP(2118),
IF_SETHFLIP(2119),
IF_SETSCROLLSIZE(2120),
IF_RESUME_PAUSEBUTTON(2121),
IF_SETFILLCOLOUR(2123),
IF_SETLINEDIRECTION(2126),
IF_SETOBJECT(2200),
IF_SETNPCHEAD(2201),
IF_SETPLAYERHEAD_SELF(2202),
IF_SETOBJECT_NONUM(2205),
IF_SETOBJECT_ALWAYS_NUM(2212),
IF_SETOP(2300),
IF_SETDRAGGABLE(2301),
IF_SETDRAGGABLEBEHAVIOR(2302),
IF_SETDRAGDEADZONE(2303),
IF_SETDRAGDEADTIME(2304),
IF_SETOPBASE(2305),
IF_SETTARGETVERB(2306),
IF_CLEAROPS(2307),
IF_SETOPKEY(2350),
IF_SETOPTKEY(2351),
IF_SETOPKEYRATE(2352),
IF_SETOPTKEYRATE(2353),
IF_SETOPKEYIGNOREHELD(2354),
IF_SETOPTKEYIGNOREHELD(2355),
IF_SETONCLICK(2400),
IF_SETONHOLD(2401),
IF_SETONRELEASE(2402),
IF_SETONMOUSEOVER(2403),
IF_SETONMOUSELEAVE(2404),
IF_SETONDRAG(2405),
IF_SETONTARGETLEAVE(2406),
IF_SETONVARTRANSMIT(2407),
IF_SETONTIMER(2408),
IF_SETONOP(2409),
IF_SETONDRAGCOMPLETE(2410),
IF_SETONCLICKREPEAT(2411),
IF_SETONMOUSEREPEAT(2412),
IF_SETONINVTRANSMIT(2414),
IF_SETONSTATTRANSMIT(2415),
IF_SETONTARGETENTER(2416),
IF_SETONSCROLLWHEEL(2417),
IF_SETONCHATTRANSMIT(2418),
IF_SETONKEY(2419),
IF_SETONFRIENDTRANSMIT(2420),
IF_SETONCLANTRANSMIT(2421),
IF_SETONMISCTRANSMIT(2422),
IF_SETONDIALOGABORT(2423),
IF_SETONSUBCHANGE(2424),
IF_SETONSTOCKTRANSMIT(2425),
IF_SETONRESIZE(2427),
IF_GETX(2500),
IF_GETY(2501),
IF_GETWIDTH(2502),
IF_GETHEIGHT(2503),
IF_GETHIDE(2504),
IF_GETLAYER(2505),
IF_GETSCROLLX(2600),
IF_GETSCROLLY(2601),
IF_GETTEXT(2602),
IF_GETSCROLLWIDTH(2603),
IF_GETSCROLLHEIGHT(2604),
IF_GETMODELZOOM(2605),
IF_GETMODELANGLE_X(2606),
IF_GETMODELANGLE_Z(2607),
IF_GETMODELANGLE_Y(2608),
IF_GETTRANS(2609),
IF_GETCOLOUR(2611),
IF_GETFILLCOLOUR(2612),
IF_GETINVOBJECT(2700),
IF_GETINVCOUNT(2701),
IF_HASSUB(2702),
IF_GETTOP(2706),
IF_GETTARGETMASK(2800),
IF_GETOP(2801),
IF_GETOPBASE(2802),
IF_CALLONRESIZE(2927),
MES(3100),
ANIM(3101),
IF_CLOSE(3103),
RESUME_COUNTDIALOG(3104),
RESUME_NAMEDIALOG(3105),
RESUME_STRINGDIALOG(3106),
OPPLAYER(3107),
IF_DRAGPICKUP(3108),
CC_DRAGPICKUP(3109),
MOUSECAM(3110),
GETREMOVEROOFS(3111),
SETREMOVEROOFS(3112),
OPENURL(3113),
RESUME_OBJDIALOG(3115),
BUG_REPORT(3116),
SETSHIFTCLICKDROP(3117),
SETSHOWMOUSEOVERTEXT(3118),
RENDERSELF(3119),
SETSHOWMOUSECROSS(3125),
SETSHOWLOADINGMESSAGES(3126),
SETTAPTODROP(3127),
GETTAPTODROP(3128),
SETOCULUSORBSPEED(3129),
GETCANVASSIZE(3132),
SETHIDEUSERNAME(3141),
GETHIDEUSERNAME(3142),
SETREMEMBERUSERNAME(3143),
GETREMEMBERUSERNAME(3144),
SETTITLEMUSICENABLED(3146),
GETTITLEMUSICENABLED(3147),
SOUND_SYNTH(3200),
SOUND_SONG(3201),
SOUND_JINGLE(3202),
CLIENTCLOCK(3300),
INV_GETOBJ(3301),
INV_GETNUM(3302),
INV_TOTAL(3303),
INV_SIZE(3304),
STAT(3305),
STAT_BASE(3306),
STAT_XP(3307),
COORD(3308),
COORDX(3309),
COORDZ(3310),
COORDY(3311),
MAP_MEMBERS(3312),
INVOTHER_GETOBJ(3313),
INVOTHER_GETNUM(3314),
INVOTHER_TOTAL(3315),
STAFFMODLEVEL(3316),
REBOOTTIMER(3317),
MAP_WORLD(3318),
RUNENERGY_VISIBLE(3321),
RUNWEIGHT_VISIBLE(3322),
PLAYERMOD(3323),
WORLDFLAGS(3324),
MOVECOORD(3325),
ENUM_STRING(3400),
ENUM(3408),
ENUM_GETOUTPUTCOUNT(3411),
FRIEND_COUNT(3600),
FRIEND_GETNAME(3601),
FRIEND_GETWORLD(3602),
FRIEND_GETRANK(3603),
FRIEND_SETRANK(3604),
FRIEND_ADD(3605),
FRIEND_DEL(3606),
IGNORE_ADD(3607),
IGNORE_DEL(3608),
FRIEND_TEST(3609),
CLAN_GETCHATDISPLAYNAME(3611),
CLAN_GETCHATCOUNT(3612),
CLAN_GETCHATUSERNAME(3613),
CLAN_GETCHATUSERWORLD(3614),
CLAN_GETCHATUSERRANK(3615),
CLAN_GETCHATMINKICK(3616),
CLAN_KICKUSER(3617),
CLAN_GETCHATRANK(3618),
CLAN_JOINCHAT(3619),
CLAN_LEAVECHAT(3620),
IGNORE_COUNT(3621),
IGNORE_GETNAME(3622),
IGNORE_TEST(3623),
CLAN_ISSELF(3624),
CLAN_GETCHATOWNERNAME(3625),
CLAN_ISFRIEND(3626),
CLAN_ISIGNORE(3627),
STOCKMARKET_GETOFFERTYPE(3903),
STOCKMARKET_GETOFFERITEM(3904),
STOCKMARKET_GETOFFERPRICE(3905),
STOCKMARKET_GETOFFERCOUNT(3906),
STOCKMARKET_GETOFFERCOMPLETEDCOUNT(3907),
STOCKMARKET_GETOFFERCOMPLETEDGOLD(3908),
STOCKMARKET_ISOFFEREMPTY(3910),
STOCKMARKET_ISOFFERSTABLE(3911),
STOCKMARKET_ISOFFERFINISHED(3912),
STOCKMARKET_ISOFFERADDING(3913),
TRADINGPOST_SORTBY_NAME(3914),
TRADINGPOST_SORTBY_PRICE(3915),
TRADINGPOST_SORTFILTERBY_WORLD(3916),
TRADINGPOST_SORTBY_AGE(3917),
TRADINGPOST_SORTBY_COUNT(3918),
TRADINGPOST_GETTOTALOFFERS(3919),
TRADINGPOST_GETOFFERWORLD(3920),
TRADINGPOST_GETOFFERNAME(3921),
TRADINGPOST_GETOFFERPREVIOUSNAME(3922),
TRADINGPOST_GETOFFERAGE(3923),
TRADINGPOST_GETOFFERCOUNT(3924),
TRADINGPOST_GETOFFERPRICE(3925),
TRADINGPOST_GETOFFERITEM(3926),
ADD(4000),
SUB(4001),
MULTIPLY(4002),
DIV(4003),
RANDOM(4004),
RANDOMINC(4005),
INTERPOLATE(4006),
ADDPERCENT(4007),
SETBIT(4008),
CLEARBIT(4009),
TESTBIT(4010),
MOD(4011),
POW(4012),
INVPOW(4013),
AND(4014),
OR(4015),
SCALE(4018),
APPEND_NUM(4100),
APPEND(4101),
APPEND_SIGNNUM(4102),
LOWERCASE(4103),
FROMDATE(4104),
TEXT_GENDER(4105),
TOSTRING(4106),
COMPARE(4107),
PARAHEIGHT(4108),
PARAWIDTH(4109),
TEXT_SWITCH(4110),
ESCAPE(4111),
APPEND_CHAR(4112),
CHAR_ISPRINTABLE(4113),
CHAR_ISALPHANUMERIC(4114),
CHAR_ISALPHA(4115),
CHAR_ISNUMERIC(4116),
STRING_LENGTH(4117),
SUBSTRING(4118),
REMOVETAGS(4119),
STRING_INDEXOF_CHAR(4120),
STRING_INDEXOF_STRING(4121),
UPPERCASE(4122),
OC_NAME(4200),
OC_OP(4201),
OC_IOP(4202),
OC_COST(4203),
OC_STACKABLE(4204),
OC_CERT(4205),
OC_UNCERT(4206),
OC_MEMBERS(4207),
OC_PLACEHOLDER(4208),
OC_UNPLACEHOLDER(4209),
OC_FIND(4210),
OC_FINDNEXT(4211),
OC_FINDRESET(4212),
CHAT_GETFILTER_PUBLIC(5000),
CHAT_SETFILTER(5001),
CHAT_SENDABUSEREPORT(5002),
CHAT_GETHISTORY_BYTYPEANDLINE(5003),
CHAT_GETHISTORY_BYUID(5004),
CHAT_GETFILTER_PRIVATE(5005),
CHAT_SENDPUBLIC(5008),
CHAT_SENDPRIVATE(5009),
CHAT_PLAYERNAME(5015),
CHAT_GETFILTER_TRADE(5016),
CHAT_GETHISTORYLENGTH(5017),
CHAT_GETNEXTUID(5018),
CHAT_GETPREVUID(5019),
DOCHEAT(5020),
CHAT_SETMESSAGEFILTER(5021),
CHAT_GETMESSAGEFILTER(5022),
GETWINDOWMODE(5306),
SETWINDOWMODE(5307),
GETDEFAULTWINDOWMODE(5308),
SETDEFAULTWINDOWMODE(5309),
CAM_FORCEANGLE(5504),
CAM_GETANGLE_XA(5505),
CAM_GETANGLE_YA(5506),
CAM_SETFOLLOWHEIGHT(5530),
CAM_GETFOLLOWHEIGHT(5531),
LOGOUT(5630),
VIEWPORT_SETFOV(6200),
VIEWPORT_SETZOOM(6201),
VIEWPORT_CLAMPFOV(6202),
VIEWPORT_GETEFFECTIVESIZE(6203),
VIEWPORT_GETZOOM(6204),
VIEWPORT_GETFOV(6205),
WORLDLIST_FETCH(6500),
WORLDLIST_START(6501),
WORLDLIST_NEXT(6502),
WORLDLIST_SPECIFIC(6506),
WORLDLIST_SORT(6507),
GETWORLDINFO(6511),
SETFOLLOWEROPSLOWPRIORITY(6512),
NC_PARAM(6513),
LC_PARAM(6514),
OC_PARAM(6515),
STRUCT_PARAM(6516),
ON_MOBILE(6518),
CLIENTTYPE(6519),
BATTERYLEVEL(6524),
BATTERYCHARGING(6525),
WIFIAVAILABLE(6526),
WORLDMAP_GETMAPNAME(6601),
WORLDMAP_SETMAP(6602),
WORLDMAP_GETZOOM(6603),
WORLDMAP_SETZOOM(6604),
WORLDMAP_ISLOADED(6605),
WORLDMAP_JUMPTODISPLAYCOORD(6606),
WORLDMAP_JUMPTODISPLAYCOORD_INSTANT(6607),
WORLDMAP_JUMPTOSOURCECOORD(6608),
WORLDMAP_JUMPTOSOURCECOORD_INSTANT(6609),
WORLDMAP_GETDISPLAYPOSITION(6610),
WORLDMAP_GETCONFIGORIGIN(6611),
WORLDMAP_GETCONFIGSIZE(6612),
WORLDMAP_GETCONFIGBOUNDS(6613),
WORLDMAP_GETCONFIGZOOM(6614),
WORLDMAP_GETCURRENTMAP(6616),
WORLDMAP_GETDISPLAYCOORD(6617),
WORLDMAP_COORDINMAP(6621),
WORLDMAP_GETSIZE(6622),
WORLDMAP_PERPETUALFLASH(6628),
WORLDMAP_FLASHELEMENT(6629),
WORLDMAP_FLASHELEMENTCATEGORY(6630),
WORLDMAP_STOPCURRENTFLASHES(6631),
WORLDMAP_DISABLEELEMENTS(6632),
WORLDMAP_DISABLEELEMENT(6633),
WORLDMAP_DISABLEELEMENTCATEGORY(6634),
WORLDMAP_GETDISABLEELEMENTS(6635),
WORLDMAP_GETDISABLEELEMENT(6636),
WORLDMAP_GETDISABLEELEMENTCATEGORY(6637),
WORLDMAP_LISTELEMENT_START(6639),
WORLDMAP_LISTELEMENT_NEXT(6640),
MEC_TEXT(6693),
MEC_TEXTSIZE(6694),
MEC_CATEGORY(6695),
MEC_SPRITE(6696);
public final int opcode;
ScriptOpcode(int opcode)
{
this.opcode = opcode;
}
private static final Map<Integer, ScriptOpcode> map;
static
{
ImmutableMap.Builder<Integer, ScriptOpcode> builder = ImmutableMap.builder();
for (ScriptOpcode value : values())
{
builder.put(value.opcode, value);
}
map = builder.build();
}
public static String nameFromID(int opcode)
{
ScriptOpcode op = map.get(opcode);
if (op == null)
{
return null;
}
return op.name();
}
}
@@ -24,9 +24,12 @@
*/ */
package net.runelite.deob.updater; package net.runelite.deob.updater;
import java.util.List;
import net.runelite.asm.ClassFile; import net.runelite.asm.ClassFile;
import net.runelite.asm.ClassGroup; import net.runelite.asm.ClassGroup;
import net.runelite.asm.Method; import net.runelite.asm.Method;
import net.runelite.asm.attributes.code.LocalVariable;
import net.runelite.asm.attributes.code.Parameter;
import net.runelite.deob.deobfuscators.mapping.ParallelExecutorMapping; import net.runelite.deob.deobfuscators.mapping.ParallelExecutorMapping;
public class ParameterRenamer public class ParameterRenamer
@@ -49,9 +52,39 @@ public class ParameterRenamer
for (Method sourceM : sourceCF.getMethods()) for (Method sourceM : sourceCF.getMethods())
{ {
Method destM = (Method) mapping.get(sourceM); Method destM = (Method) mapping.get(sourceM);
if (destM != null) if (sourceM.getParameters() != null && !sourceM.getParameters().isEmpty() && destM.getParameters().size() >= 1)
{ {
destM.setParameters(sourceM.getParameters()); List<Parameter> oldParams = destM.getParameters();
for (int i = 0; i < sourceM.getParameters().size(); i++)
{
String name = sourceM.getParameters().get(i).getName();
if (name.matches("arg[0-9]") || name.length() <= 2 && (name.charAt(0) != 'x' || name.charAt(0) != 'y'))
{
continue;
}
Parameter oldParam = oldParams.get(i);
LocalVariable oldVar = oldParam.getLocalVariable();
Parameter newParam = new Parameter(name, oldParam.getAccess());
oldParams.set(i, newParam);
if (oldVar == null)
{
continue;
}
LocalVariable newVar = new LocalVariable(
name,
oldVar.getDesc(),
oldVar.getSignature(),
oldVar.getStart(),
oldVar.getEnd(),
oldVar.getIndex()
);
newParam.setLocalVariable(newVar);
}
} }
} }
} }
@@ -26,24 +26,20 @@ 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.deobfuscators.transformers.ScriptOpcodesTransformer;
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)
@@ -77,32 +73,8 @@ public class UpdateMappings
ParameterRenamer pr = new ParameterRenamer(group1, group2, mapping); ParameterRenamer pr = new ParameterRenamer(group1, group2, mapping);
pr.run(); pr.run();
}
public void updateRL() new ScriptOpcodesTransformer().transform(group2);
{
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
@@ -121,14 +93,7 @@ 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]))
); );
if (renameRL)
{
u.updateRL();
}
else
{
u.update(); u.update();
}
u.save(new File(args[2])); u.save(new File(args[2]));
} }
} }
@@ -1,5 +1,6 @@
package net.runelite.deob.updater; package net.runelite.deob.updater;
import com.google.common.base.Strings;
import java.io.File; import java.io.File;
import net.runelite.asm.ClassFile; import net.runelite.asm.ClassFile;
import net.runelite.asm.ClassGroup; import net.runelite.asm.ClassGroup;
@@ -39,6 +40,16 @@ public class AnnotationCleaner
log.debug("Checking {}", c.toString()); log.debug("Checking {}", c.toString());
String implementingName = DeobAnnotations.getImplements(c);
if (!Strings.isNullOrEmpty(implementingName))
{
assertEquals(c + " implements " + implementingName + " but is called " + c.getClassName(), implementingName, c.getClassName());
}
else
{
assertTrue(c + " isn't obfuscated but doesn't have @Implements", Deob.isObfuscated(c.getClassName()));
}
for (Field f : c.getFields()) for (Field f : c.getFields())
{ {
Annotations an = f.getAnnotations(); Annotations an = f.getAnnotations();
@@ -48,11 +59,11 @@ public class AnnotationCleaner
if (exportedName == null) if (exportedName == null)
{ {
assertTrue("Field " + fieldName + " isn't obfuscated but doesn't have @Export.", Deob.isObfuscated(fieldName) || fieldName.contains("$")); assertTrue("Field " + c.getClassName() + '.' + fieldName + " isn't obfuscated but doesn't have @Export.", Deob.isObfuscated(fieldName) || fieldName.equals(DeobAnnotations.getObfuscatedName(an)) || DeobAnnotations.getObfuscatedName(an) == null);
continue; continue;
} }
assertEquals("Field " + fieldName + " has " + exportedName + " in @Export", fieldName, exportedName); assertEquals("Field " + c.getClassName() + '.' + fieldName + " has " + exportedName + " in @Export", fieldName, exportedName);
} }
for (Method m : c.getMethods()) for (Method m : c.getMethods())
@@ -64,11 +75,11 @@ public class AnnotationCleaner
if (exportedName == null) if (exportedName == null)
{ {
assertTrue("Method " + fieldName + " isn't obfuscated but doesn't have @Export.", Deob.isObfuscated(fieldName) || fieldName.endsWith("init>") || fieldName.equals("values") || fieldName.equals("valueOf") || fieldName.startsWith("compareTo") || fieldName.equals("equals") || fieldName.equals("hashCode") || fieldName.equals("compare")); assertTrue("Method " + c.getClassName() + '.' + fieldName + " isn't obfuscated but doesn't have @Export.", Deob.isObfuscated(fieldName) || fieldName.equals(DeobAnnotations.getObfuscatedName(an)) || DeobAnnotations.getObfuscatedName(an) == null);
continue; continue;
} }
assertEquals("Method " + fieldName + " has " + exportedName + " in @Export", fieldName, exportedName); assertEquals("Method " + c.getClassName() + '.' + fieldName + " has " + exportedName + " in @Export", fieldName, exportedName);
} }
} }
} }
@@ -37,6 +37,7 @@ 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.deobfuscators.transformers.ScriptOpcodesTransformer;
import net.runelite.deob.util.JarUtil; import net.runelite.deob.util.JarUtil;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Ignore; import org.junit.Ignore;
@@ -87,6 +88,19 @@ public class UpdateMappingsTest
check(group1, group2); check(group1, group2);
} }
@Test
@Ignore
public void testScriptopcodes() throws Exception
{
File client = new File("C:\\Users\\Lucas\\IdeaProjects\\runelitexxx\\client.jar");
ClassGroup group = JarUtil.loadJar(client);
new ScriptOpcodesTransformer().transform(group);
JarUtil.saveJar(group, new File("C:/Users/Lucas/Desktop/Apapapapapap.jar"));
}
private void unannotate(ClassGroup group) private void unannotate(ClassGroup group)
{ {
for (ClassFile cf : group.getClasses()) for (ClassFile cf : group.getClasses())
@@ -8,7 +8,6 @@ public class HookClass
@SerializedName("class") @SerializedName("class")
String clazz; String clazz;
String name; String name;
int access;
List<HookField> fields; List<HookField> fields;
List<HookMethod> methods; List<HookMethod> methods;
} }
@@ -5,7 +5,6 @@ public class HookField
String field; String field;
String owner; String owner;
String name; String name;
int access;
@Override @Override
public String toString() public String toString()
@@ -39,6 +39,8 @@ import net.runelite.asm.Type;
import net.runelite.asm.attributes.Annotations; import net.runelite.asm.attributes.Annotations;
import net.runelite.asm.attributes.annotation.Annotation; import net.runelite.asm.attributes.annotation.Annotation;
import net.runelite.asm.attributes.annotation.Element; import net.runelite.asm.attributes.annotation.Element;
import net.runelite.asm.attributes.code.LocalVariable;
import net.runelite.asm.attributes.code.Parameter;
import net.runelite.asm.signature.Signature; import net.runelite.asm.signature.Signature;
import net.runelite.asm.signature.util.VirtualMethods; import net.runelite.asm.signature.util.VirtualMethods;
import static net.runelite.deob.DeobAnnotations.EXPORT; import static net.runelite.deob.DeobAnnotations.EXPORT;
@@ -97,7 +99,7 @@ public class HookImporter
@Ignore @Ignore
public void importHooks() public void importHooks()
{ {
int classes = 0, fields = 0, methods = 0, access = 0; int classes = 0, fields = 0, methods = 0, params = 0;
NameMappings mappings = new NameMappings(); NameMappings mappings = new NameMappings();
for (HookClass hc : hooks) for (HookClass hc : hooks)
@@ -107,12 +109,6 @@ public class HookImporter
assert cf != null; assert cf != null;
if (cf.getAccess() != hc.access)
{
cf.setAccess(hc.access);
++access;
}
String implementsName = getAnnotation(cf.getAnnotations(), IMPLEMENTS); String implementsName = getAnnotation(cf.getAnnotations(), IMPLEMENTS);
if (implementsName.isEmpty()) if (implementsName.isEmpty())
{ {
@@ -122,23 +118,28 @@ public class HookImporter
++classes; ++classes;
} }
if (!implementsName.isEmpty() && !implementsName.equals(hc.clazz))
{
logger.info("Runestar calls class {} {}, while we call it {}", hc.name, hc.clazz, implementsName);
}
for (HookField fh : hc.fields) for (HookField fh : hc.fields)
{ {
if (fh.field.startsWith("__"))
{
continue;
}
ClassFile cf2 = findClassWithObfuscatedName(fh.owner); ClassFile cf2 = findClassWithObfuscatedName(fh.owner);
assert cf2 != null; assert cf2 != null;
Field f = findFieldWithObfuscatedName(cf2, fh.name); Field f = findFieldWithObfuscatedName(cf2, fh.name);
if (f == null) if (f == null)
{ {
logger.warn("Missing field {}", fh); // inlined constant maybe?
continue; continue;
} }
if (f.getAccessFlags() != fh.access)
{
f.setAccessFlags(fh.access);
++access;
}
String exportedName = getAnnotation(f.getAnnotations(), EXPORT); String exportedName = getAnnotation(f.getAnnotations(), EXPORT);
if (exportedName.isEmpty()) if (exportedName.isEmpty())
{ {
@@ -155,11 +156,20 @@ public class HookImporter
mappings.map(f.getPoolField(), deobfuscatedFieldName); mappings.map(f.getPoolField(), deobfuscatedFieldName);
++fields; ++fields;
} }
if (!exportedName.isEmpty() && !exportedName.equals(fh.field))
{
logger.info("Runestar calls field {}.{} {}, while we call it {}", fh.owner, fh.name, fh.field, exportedName);
}
} }
outer: outer:
for (HookMethod hm : hc.methods) for (HookMethod hm : hc.methods)
{ {
if (hm.method.startsWith("__"))
{
continue;
}
ClassFile cf2 = findClassWithObfuscatedName(hm.owner); ClassFile cf2 = findClassWithObfuscatedName(hm.owner);
assert cf2 != null; assert cf2 != null;
@@ -171,10 +181,40 @@ public class HookImporter
continue; continue;
} }
if (m.getAccessFlags() != hm.access) if (hm.parameters != null && !hm.parameters.isEmpty() && m.getParameters().size() >= 1)
{ {
m.setAccessFlags(hm.access); List<Parameter> oldParams = m.getParameters();
++access; for (int i = 0; i < hm.parameters.size(); i++)
{
String name = hm.parameters.get(i);
if (name.matches("arg[0-9]") || name.length() <= 2 && (name.charAt(0) != 'x' && name.charAt(0) != 'y'))
{
continue;
}
Parameter oldParam = oldParams.get(i);
LocalVariable oldVar = oldParam.getLocalVariable();
Parameter newParam = new Parameter(name, oldParam.getAccess());
oldParams.set(i, newParam);
params++;
if (oldVar == null)
{
continue;
}
LocalVariable newVar = new LocalVariable(
name,
oldVar.getDesc(),
oldVar.getSignature(),
oldVar.getStart(),
oldVar.getEnd(),
oldVar.getIndex()
);
newParam.setLocalVariable(newVar);
}
} }
// maybe only the base class method is exported // maybe only the base class method is exported
@@ -184,6 +224,10 @@ public class HookImporter
String exportedName = getAnnotation(method.getAnnotations(), EXPORT); String exportedName = getAnnotation(method.getAnnotations(), EXPORT);
if (!exportedName.isEmpty()) if (!exportedName.isEmpty())
{ {
if (!exportedName.equals(hm.method))
{
logger.info("Runestar calls {}.{} {}, while we call it {}", hm.owner, hm.name, hm.method, exportedName);
}
continue outer; continue outer;
} }
} }
@@ -198,7 +242,7 @@ public class HookImporter
Renamer renamer = new Renamer(mappings); Renamer renamer = new Renamer(mappings);
renamer.run(group); renamer.run(group);
logger.info("Imported {} classes, {} fields, {} methods, {} access levels", classes, fields, methods, access); logger.info("Imported {} classes, {} fields, {} methods, {} params", classes, fields, methods, params);
} }
private ClassFile findClassWithObfuscatedName(String name) private ClassFile findClassWithObfuscatedName(String name)
@@ -259,8 +303,7 @@ public class HookImporter
{ {
for (Element e : a.getElements()) for (Element e : a.getElements())
{ {
String str = (String) e.getValue(); return (String) e.getValue();
return str;
} }
} }
@@ -270,13 +313,13 @@ public class HookImporter
private Signature getObfuscatedMethodSignature(Method method) private Signature getObfuscatedMethodSignature(Method method)
{ {
String sig = getAnnotation(method.getAnnotations(), OBFUSCATED_SIGNATURE); String sig = getAnnotation(method.getAnnotations(), OBFUSCATED_SIGNATURE);
if (sig.isEmpty() == false) if (sig.isEmpty())
{
return new Signature(sig); // if it is annotated, use that
}
else
{ {
return method.getDescriptor(); return method.getDescriptor();
} }
else
{
return new Signature(sig); // if it is annotated, use that
}
} }
} }
@@ -1,12 +1,13 @@
package net.runelite.runesuite; package net.runelite.runesuite;
import java.util.List;
public class HookMethod public class HookMethod
{ {
String method; String method;
String owner; String owner;
String name; String name;
int access; List<String> parameters;
String[] parameters;
String descriptor; String descriptor;
@Override @Override
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -28,7 +28,7 @@
<parent> <parent>
<groupId>net.runelite</groupId> <groupId>net.runelite</groupId>
<artifactId>runelite-parent</artifactId> <artifactId>runelite-parent</artifactId>
<version>1.5.28-SNAPSHOT</version> <version>1.5.29-SNAPSHOT</version>
</parent> </parent>
<name>Web API</name> <name>Web API</name>
@@ -103,8 +103,8 @@ public class RuneLiteAPI
CLIENT = new OkHttpClient.Builder() CLIENT = new OkHttpClient.Builder()
.pingInterval(30, TimeUnit.SECONDS) .pingInterval(30, TimeUnit.SECONDS)
.connectTimeout(5655, TimeUnit.MILLISECONDS) .connectTimeout(8655, TimeUnit.MILLISECONDS)
.writeTimeout(5655, TimeUnit.MILLISECONDS) .writeTimeout(8655, TimeUnit.MILLISECONDS)
.addNetworkInterceptor(new Interceptor() .addNetworkInterceptor(new Interceptor()
{ {
@Override @Override
+1 -1
View File
@@ -28,7 +28,7 @@
<parent> <parent>
<groupId>net.runelite</groupId> <groupId>net.runelite</groupId>
<artifactId>runelite-parent</artifactId> <artifactId>runelite-parent</artifactId>
<version>1.5.28-SNAPSHOT</version> <version>1.5.29-SNAPSHOT</version>
</parent> </parent>
<name>Web Service</name> <name>Web Service</name>
+1 -1
View File
@@ -29,7 +29,7 @@
<parent> <parent>
<groupId>net.runelite</groupId> <groupId>net.runelite</groupId>
<artifactId>runelite-parent</artifactId> <artifactId>runelite-parent</artifactId>
<version>1.5.28-SNAPSHOT</version> <version>1.5.29-SNAPSHOT</version>
</parent> </parent>
<artifactId>injected-client</artifactId> <artifactId>injected-client</artifactId>
+1 -1
View File
@@ -30,7 +30,7 @@
<parent> <parent>
<groupId>net.runelite</groupId> <groupId>net.runelite</groupId>
<artifactId>runelite-parent</artifactId> <artifactId>runelite-parent</artifactId>
<version>1.5.28-SNAPSHOT</version> <version>1.5.29-SNAPSHOT</version>
</parent> </parent>
<groupId>net.runelite.rs</groupId> <groupId>net.runelite.rs</groupId>
@@ -33,6 +33,7 @@ import net.runelite.asm.ClassGroup;
import net.runelite.asm.Method; import net.runelite.asm.Method;
import net.runelite.asm.Type; import net.runelite.asm.Type;
import net.runelite.asm.attributes.Annotations; import net.runelite.asm.attributes.Annotations;
import net.runelite.asm.attributes.Code;
import net.runelite.asm.attributes.annotation.Annotation; 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.InstructionType; import net.runelite.asm.attributes.code.InstructionType;
@@ -89,9 +90,9 @@ public class InjectHookMethod
obfuscatedClassName = DeobAnnotations.getObfuscatedName(cf.getAnnotations()); obfuscatedClassName = DeobAnnotations.getObfuscatedName(cf.getAnnotations());
// might be a constructor // might be a constructor
if (obfuscatedMethodName == null && method.getName().equals("<init>")) if (obfuscatedMethodName == null)
{ {
obfuscatedMethodName = "<init>"; obfuscatedMethodName = method.getName();
} }
assert obfuscatedClassName != null : "hook on method in class with no obfuscated name"; assert obfuscatedClassName != null : "hook on method in class with no obfuscated name";
@@ -110,7 +111,12 @@ public class InjectHookMethod
private void injectHookMethod(Method hookMethod, String hookName, boolean end, Method deobMethod, Method vanillaMethod, boolean useHooks) throws InjectionException private void injectHookMethod(Method hookMethod, String hookName, boolean end, Method deobMethod, Method vanillaMethod, boolean useHooks) throws InjectionException
{ {
Instructions instructions = vanillaMethod.getCode().getInstructions(); Code code = vanillaMethod.getCode();
if (code == null)
{
logger.warn(vanillaMethod + " code is null");
}
Instructions instructions = code.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
@@ -27,6 +27,33 @@ public class InjectUtil
public static Method findMethod(Inject inject, String name) throws InjectionException public static Method findMethod(Inject inject, String name) throws InjectionException
{ {
return findMethod(inject, name, null);
}
public static Method findMethod(Inject inject, String name, String hint) throws InjectionException
{
if (hint != null)
{
ClassFile c = inject.getDeobfuscated().findClass(hint);
if (c == null)
{
throw new InjectionException("Class " + hint + " doesn't exist. (check capitalization)");
}
Method deob = c.findMethod(name);
if (deob != null)
{
String obfuscatedName = DeobAnnotations.getObfuscatedName(deob.getAnnotations());
Signature obfuscatedSignature = DeobAnnotations.getObfuscatedSignature(deob);
ClassFile ob = inject.toObClass(c);
return ob.findMethod(obfuscatedName, (obfuscatedSignature != null) ? obfuscatedSignature : deob.getDescriptor());
}
}
for (ClassFile c : inject.getDeobfuscated().getClasses()) for (ClassFile c : inject.getDeobfuscated().getClasses())
{ {
for (Method m : c.getMethods()) for (Method m : c.getMethods())
@@ -76,8 +76,8 @@ public class DrawAfterWidgets
@Export("drawLoggedIn") @Export("drawLoggedIn")
final void drawLoggedIn() { final void drawLoggedIn() {
if(rootWidgetGroup != -1) { if(rootInterface != -1) {
ClientPreferences.method1809(rootWidgetGroup); ClientPreferences.method1809(rootInterface);
} }
int var1; int var1;
@@ -94,9 +94,9 @@ public class DrawAfterWidgets
__client_lq = -1; __client_lq = -1;
__client_ln = -1; __client_ln = -1;
UserComparator6.__fg_jh = null; UserComparator6.__fg_jh = null;
if(rootWidgetGroup != -1) { if(rootInterface != -1) {
rootWidgetCount = 0; rootWidgetCount = 0;
Interpreter.method1977(rootWidgetGroup, 0, 0, SoundCache.canvasWidth, Huffman.canvasHeight, 0, 0, -1); Interpreter.method1977(rootInterface, 0, 0, SoundCache.canvasWidth, Huffman.canvasHeight, 0, 0, -1);
} }
< -- here appearantly < -- here appearantly
@@ -2,6 +2,7 @@ package net.runelite.injector.raw;
import com.google.common.base.Stopwatch; import com.google.common.base.Stopwatch;
import java.util.Iterator; import java.util.Iterator;
import java.util.ListIterator;
import net.runelite.asm.Method; import net.runelite.asm.Method;
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;
@@ -9,9 +10,12 @@ import net.runelite.asm.attributes.code.Label;
import net.runelite.asm.attributes.code.instruction.types.ComparisonInstruction; 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.instructions.ALoad; import net.runelite.asm.attributes.code.instructions.ALoad;
import net.runelite.asm.attributes.code.instructions.BiPush;
import net.runelite.asm.attributes.code.instructions.GetStatic; import net.runelite.asm.attributes.code.instructions.GetStatic;
import net.runelite.asm.attributes.code.instructions.IAnd;
import net.runelite.asm.attributes.code.instructions.IfACmpEq; import net.runelite.asm.attributes.code.instructions.IfACmpEq;
import net.runelite.asm.attributes.code.instructions.IfACmpNe; import net.runelite.asm.attributes.code.instructions.IfACmpNe;
import net.runelite.asm.attributes.code.instructions.IfICmpNe;
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.pool.Field; import net.runelite.asm.pool.Field;
@@ -31,14 +35,28 @@ public class HidePlayerAttacks
this.inject = inject; this.inject = inject;
} }
private Method addPlayerOptions;
private net.runelite.asm.pool.Method shouldHideAttackOptionFor;
public void inject() throws InjectionException public void inject() throws InjectionException
{ {
Stopwatch stopwatch = Stopwatch.createStarted(); Stopwatch stopwatch = Stopwatch.createStarted();
final Method addPlayerOptions = InjectUtil.findStaticMethod(inject, "addPlayerToMenu"); addPlayerOptions = InjectUtil.findStaticMethod(inject, "addPlayerToMenu");
shouldHideAttackOptionFor = inject.getVanilla().findClass("client").findMethod("shouldHideAttackOptionFor").getPoolMethod();
injectHideAttack();
injectHideCast();
stopwatch.stop();
log.info("HidePlayerAttacks took {}", stopwatch.toString());
}
private void injectHideAttack() throws InjectionException
{
final Field AttackOption_hidden = InjectUtil.findDeobField(inject, "AttackOption_hidden", "AttackOption").getPoolField(); final Field AttackOption_hidden = InjectUtil.findDeobField(inject, "AttackOption_hidden", "AttackOption").getPoolField();
final Field attackOption = InjectUtil.findDeobField(inject, "playerAttackOption", "Client").getPoolField(); final Field attackOption = InjectUtil.findDeobField(inject, "playerAttackOption", "Client").getPoolField();
final net.runelite.asm.pool.Method shouldHideAttackOptionFor = inject.getVanilla().findClass("client").findMethod("shouldHideAttackOptionFor").getPoolMethod();
// GETSTATIC GETSTATIC // GETSTATIC GETSTATIC
// GETSTATIC GETSTATIC // GETSTATIC GETSTATIC
@@ -123,9 +141,65 @@ public class HidePlayerAttacks
IfNe i3 = new IfNe(ins, label); IfNe i3 = new IfNe(ins, label);
ins.addInstruction(injectIdx, i3); ins.addInstruction(injectIdx, i3);
}
stopwatch.stop(); private void injectHideCast() throws InjectionException
{
// LABEL before
// BIPUSH 8
// LDC (garbage)
// GETSTATIC selectedSpellFlags
// IMUL
// BIPUSH 8
// IAND
// IF_ICMPNE -> skip adding option
//
// <--- Inject call here
// <--- Inject comparison here (duh)
//
// add option n such
log.info("HidePlayerAttacks took {}", stopwatch.toString()); Instructions ins = addPlayerOptions.getCode().getInstructions();
ListIterator<Instruction> iterator = ins.getInstructions().listIterator();
while (iterator.hasNext())
{
Instruction i = iterator.next();
if (!(i instanceof BiPush) || (byte) ((BiPush) i).getConstant() != 8)
{
continue;
}
i = iterator.next();
while (!(i instanceof BiPush) || (byte) ((BiPush) i).getConstant() != 8)
{
i = iterator.next();
}
i = iterator.next();
if (!(i instanceof IAnd))
{
throw new InjectionException("Yikes I didn't expect this");
}
i = iterator.next();
if (!(i instanceof IfICmpNe))
{
throw new InjectionException("Yikes I didn't expect this");
}
Label target = ((IfICmpNe) i).getJumps().get(0);
// Load the player
ALoad i1 = new ALoad(ins, 0);
// Get the boolean
InvokeStatic i2 = new InvokeStatic(ins, shouldHideAttackOptionFor);
// Compare n such
IfNe i3 = new IfNe(ins, target);
iterator.add(i1);
iterator.add(i2);
iterator.add(i3);
return;
}
} }
} }
@@ -36,7 +36,7 @@ public class RenderDraw
Stopwatch stopwatch = Stopwatch.createStarted(); Stopwatch stopwatch = Stopwatch.createStarted();
net.runelite.asm.Method obmethod = findMethod(inject, "drawTile"); net.runelite.asm.Method obmethod = findMethod(inject, "drawTile");
Method renderDraw = findMethod(inject, "renderDraw").getPoolMethod(); Method renderDraw = findMethod(inject, "draw", "Entity").getPoolMethod();
Instructions ins = obmethod.getCode().getInstructions(); Instructions ins = obmethod.getCode().getInstructions();
replace(ins, renderDraw); replace(ins, renderDraw);
@@ -69,7 +69,7 @@ public class RenderDraw
} }
else if (count != 21) else if (count != 21)
{ {
log.warn("Found {} renderDraws while 21 were expected. Rev update?", count); log.warn("Found {} draws while 21 were expected. Rev update?", count);
} }
else else
{ {
+21 -21
View File
@@ -1,5 +1,5 @@
{ {
"buildCommit": "2d0c2b8eb66a8088b41b29d42ec2a58ead460581", "buildCommit": "b82c8903c64695d44b255d45b449440e4eaa17ef",
"artifacts": [ "artifacts": [
{ {
"hash": "b12331da8683e5f107d294adeebb83ecf9124abc1db533554d2a8d3c62832d75", "hash": "b12331da8683e5f107d294adeebb83ecf9124abc1db533554d2a8d3c62832d75",
@@ -20,10 +20,10 @@
"size": "3168921" "size": "3168921"
}, },
{ {
"hash": "4c388a85fb538bbb8cb6e0fd93e0ba0666605123d77b976764818be6f090bbe5", "hash": "bc9ad97e68f88e53d6e5844a5b02e8b874cb7f0bbdd08a99c4529caf9148e99f",
"name": "client-1.5.28-SNAPSHOT.jar", "name": "client-1.5.29-SNAPSHOT.jar",
"path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/client-1.5.28-SNAPSHOT.jar", "path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/client-1.5.29-SNAPSHOT.jar",
"size": "5871886" "size": "6018354"
}, },
{ {
"hash": "18c4a0095d5c1da6b817592e767bb23d29dd2f560ad74df75ff3961dbde25b79", "hash": "18c4a0095d5c1da6b817592e767bb23d29dd2f560ad74df75ff3961dbde25b79",
@@ -212,22 +212,22 @@
"size": "2327547" "size": "2327547"
}, },
{ {
"hash": "440c629bec3905eb21dc5965fa38464f160a4cb8f87ca76806cdecc18b2c5992", "hash": "aa603ad557917ad4c14f0683195c481e84760e2c12cf7564f4ad9a22f66fe9d6",
"name": "runelite-api-1.5.28-SNAPSHOT.jar", "name": "runelite-api-1.5.29-SNAPSHOT.jar",
"path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/runelite-api-1.5.28-SNAPSHOT.jar", "path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/runelite-api-1.5.29-SNAPSHOT.jar",
"size": "1019717" "size": "1027726"
}, },
{ {
"hash": "45e3bcec9e7bae4ca2facd0fbee1f3da5e0700584e8419deed784a95255552c1", "hash": "051f8c8fb6dfbcdf35c6b266bf4dddbfb1eca44ea3e5319b622dda57a83b0eea",
"name": "runescape-api-1.5.28-SNAPSHOT.jar", "name": "runescape-api-1.5.29-SNAPSHOT.jar",
"path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/runescape-api-1.5.28-SNAPSHOT.jar", "path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/runescape-api-1.5.29-SNAPSHOT.jar",
"size": "56079" "size": "58029"
}, },
{ {
"hash": "811aadce9ce35ac638712da86123d4cb99570a9550614931471295cb26f91c36", "hash": "9084498c38d640206ec099578ec21f0e52ff1afab5d77580e12e27f59b9987c8",
"name": "http-api-1.5.28-SNAPSHOT.jar", "name": "http-api-1.5.29-SNAPSHOT.jar",
"path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/http-api-1.5.28-SNAPSHOT.jar", "path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/http-api-1.5.29-SNAPSHOT.jar",
"size": "101785" "size": "115763"
}, },
{ {
"hash": "f55abda036da75e1af45bd43b9dfa79b2a3d90905be9cb38687c6621597a8165", "hash": "f55abda036da75e1af45bd43b9dfa79b2a3d90905be9cb38687c6621597a8165",
@@ -254,10 +254,10 @@
"size": "617294" "size": "617294"
}, },
{ {
"hash": "a3cab9293960d1d61968ce1591c87859ddcaa6cb2faca554cc938961c8fb3d3a", "hash": "48bfa99ac87f3c3b8d555efd2ac3a84f636e8f9fd282284f87df77cd9feacfa6",
"name": "injected-client-1.5.28-SNAPSHOT.jar", "name": "injected-client-1.5.29-SNAPSHOT.jar",
"path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/injected-client-1.5.28-SNAPSHOT.jar", "path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/injected-client-1.5.29-SNAPSHOT.jar",
"size": "2193046" "size": "2196574"
} }
], ],
"client": { "client": {
+3 -2
View File
@@ -28,7 +28,7 @@
<groupId>net.runelite</groupId> <groupId>net.runelite</groupId>
<artifactId>runelite-parent</artifactId> <artifactId>runelite-parent</artifactId>
<version>1.5.28-SNAPSHOT</version> <version>1.5.29-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>RuneLite</name> <name>RuneLite</name>
@@ -37,6 +37,7 @@
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.useIncrementalCompilation>false</maven.compiler.useIncrementalCompilation>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<lombok.version>1.18.4</lombok.version> <lombok.version>1.18.4</lombok.version>
<checkstyle.version>8.3</checkstyle.version> <checkstyle.version>8.3</checkstyle.version>
@@ -53,7 +54,7 @@
<zlika.reproducible.build.maven.plugin.version>0.7</zlika.reproducible.build.maven.plugin.version> <zlika.reproducible.build.maven.plugin.version>0.7</zlika.reproducible.build.maven.plugin.version>
<maven.jar.plugin.version>3.0.2</maven.jar.plugin.version> <maven.jar.plugin.version>3.0.2</maven.jar.plugin.version>
<maven.compiler.plugin.version>3.6.1</maven.compiler.plugin.version> <maven.compiler.plugin.version>3.8.1</maven.compiler.plugin.version>
<maven.checkstyle.plugin.version>2.17</maven.checkstyle.plugin.version> <maven.checkstyle.plugin.version>2.17</maven.checkstyle.plugin.version>
<maven.javadoc.plugin.version>3.0.0-M1</maven.javadoc.plugin.version> <maven.javadoc.plugin.version>3.0.0-M1</maven.javadoc.plugin.version>
<maven.release.plugin.version>2.5.3</maven.release.plugin.version> <maven.release.plugin.version>2.5.3</maven.release.plugin.version>
+1 -1
View File
@@ -29,7 +29,7 @@
<parent> <parent>
<groupId>net.runelite</groupId> <groupId>net.runelite</groupId>
<artifactId>runelite-parent</artifactId> <artifactId>runelite-parent</artifactId>
<version>1.5.28-SNAPSHOT</version> <version>1.5.29-SNAPSHOT</version>
</parent> </parent>
<artifactId>protocol-api</artifactId> <artifactId>protocol-api</artifactId>
+1 -1
View File
@@ -29,7 +29,7 @@
<parent> <parent>
<groupId>net.runelite</groupId> <groupId>net.runelite</groupId>
<artifactId>runelite-parent</artifactId> <artifactId>runelite-parent</artifactId>
<version>1.5.28-SNAPSHOT</version> <version>1.5.29-SNAPSHOT</version>
</parent> </parent>
<artifactId>protocol</artifactId> <artifactId>protocol</artifactId>
+1 -1
View File
@@ -29,7 +29,7 @@
<parent> <parent>
<groupId>net.runelite</groupId> <groupId>net.runelite</groupId>
<artifactId>runelite-parent</artifactId> <artifactId>runelite-parent</artifactId>
<version>1.5.28-SNAPSHOT</version> <version>1.5.29-SNAPSHOT</version>
</parent> </parent>
<artifactId>runelite-api</artifactId> <artifactId>runelite-api</artifactId>
@@ -164,6 +164,7 @@ public final class AnimationID
public static final int BLOCK_SHIELD = 1156; public static final int BLOCK_SHIELD = 1156;
public static final int BLOCK_SWORD = 388; public static final int BLOCK_SWORD = 388;
public static final int BLOCK_UNARMED = 424; // Same Animation as failed pickpocked public static final int BLOCK_UNARMED = 424; // Same Animation as failed pickpocked
public static final int DRAGONFIRE_SHIELD_SPECIAL = 6696;
// NPC animations // NPC animations
public static final int TZTOK_JAD_RANGE_ATTACK = 2652; public static final int TZTOK_JAD_RANGE_ATTACK = 2652;
@@ -312,4 +313,11 @@ public final class AnimationID
public static final int DAG_REX = 2853; public static final int DAG_REX = 2853;
public static final int DAG_PRIME = 2854; public static final int DAG_PRIME = 2854;
public static final int DAG_SUPREME = 2855; public static final int DAG_SUPREME = 2855;
// Lizardman shaman
public static final int LIZARDMAN_SHAMAN_SPAWN = 2855;
// Combat counter
public static final int BARRAGE_ANIMATION = 1979;
public static final int CHIN_ANIMATION = 7618;
} }
@@ -29,6 +29,7 @@ import java.awt.Dimension;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.LocalPoint;
import net.runelite.api.coords.WorldPoint; import net.runelite.api.coords.WorldPoint;
@@ -1661,17 +1662,36 @@ public interface Client extends GameShell
String getSelectedSpellName(); String getSelectedSpellName();
boolean getIsSpellSelected(); boolean isSpellSelected();
/** /**
* Set whether or not player attack options will be hidden for clanmembers/friends * Set whether or not player attack options will be hidden for clanmembers/friends
*/ */
void setHideFriendAttackOptions(boolean yes); void setHideFriendAttackOptions(boolean yes);
/**
* Set whether or not player cast options will be hidden for clanmembers/friends
*/
void setHideFriendCastOptions(boolean yes);
/**
* Set spells excluded from above hiding
*/
void setUnhiddenCasts(Set<String> casts);
/** /**
* Sorts the current menu entries in the same way the client does this. * Sorts the current menu entries in the same way the client does this.
* The last entry will be the left click one after this. * The last entry will be the left click one after this.
*/ */
void sortMenuEntries(); void sortMenuEntries();
/**
* Add player to friendlist
*/
void addFriend(String name);
/**
* Remove player from friendlist
*/
void removeFriend(String name);
} }
@@ -24,6 +24,11 @@
*/ */
package net.runelite.api; package net.runelite.api;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/** /**
* An enumeration of game states the client is in. * An enumeration of game states the client is in.
*/ */
@@ -66,6 +71,10 @@ public enum GameState
*/ */
HOPPING(45); HOPPING(45);
private static final Map<Integer, GameState> stateValueMap =
Arrays.stream(GameState.values())
.collect(Collectors.toMap(gs -> gs.state, Function.identity()));
/** /**
* The raw state value. * The raw state value.
*/ */
@@ -85,13 +94,6 @@ public enum GameState
*/ */
public static GameState of(int state) public static GameState of(int state)
{ {
for (GameState gs : GameState.values()) return stateValueMap.getOrDefault(state, UNKNOWN);
{
if (gs.state == state)
{
return gs;
}
}
return UNKNOWN;
} }
} }
@@ -10821,5 +10821,21 @@ public final class ItemID
public static final int HEALER_ICON_23486 = 23486; public static final int HEALER_ICON_23486 = 23486;
public static final int WINE_OF_ZAMORAK_23489 = 23489; public static final int WINE_OF_ZAMORAK_23489 = 23489;
public static final int LARRANS_KEY = 23490; public static final int LARRANS_KEY = 23490;
public static final int SRARACHA = 23495;
public static final int TEMPLE_COIN = 23497;
public static final int GRUBBY_KEY = 23499;
public static final int TEMPLE_KEY = 23502;
public static final int TOME_OF_THE_MOON = 23504;
public static final int TOME_OF_THE_SUN = 23506;
public static final int TOME_OF_THE_TEMPLE = 23508;
public static final int TATTERED_MOON_PAGE = 23510;
public static final int TATTERED_SUN_PAGE = 23512;
public static final int TATTERED_TEMPLE_PAGE = 23514;
public static final int LAMP_OF_KNOWLEDGE = 23516;
public static final int GIANT_EGG_SACFULL = 23517;
public static final int GIANT_EGG_SAC = 23520;
public static final int MASK_OF_RANUL = 23522;
public static final int JAR_OF_EYES = 23525;
public static final int SARACHNIS_CUDGEL = 23528;
/* This file is automatically generated. Do not edit. */ /* This file is automatically generated. Do not edit. */
} }
@@ -1992,9 +1992,9 @@ public final class NpcID
public static final int CYCLOPS_2140 = 2140; public static final int CYCLOPS_2140 = 2140;
public static final int CYCLOPS_2141 = 2141; public static final int CYCLOPS_2141 = 2141;
public static final int CYCLOPS_2142 = 2142; public static final int CYCLOPS_2142 = 2142;
public static final int GIANT_FROG_2143 = 2143; public static final int SRARACHA = 2143;
public static final int BIG_FROG_2144 = 2144; public static final int SRARACHA_2144 = 2144;
public static final int FROG_2145 = 2145; public static final int UNDEAD_DRUID = 2145;
public static final int FISHING_SPOT_2146 = 2146; public static final int FISHING_SPOT_2146 = 2146;
public static final int VEOS = 2147; public static final int VEOS = 2147;
public static final int GRAND_EXCHANGE_CLERK = 2148; public static final int GRAND_EXCHANGE_CLERK = 2148;
@@ -7866,5 +7866,21 @@ public final class NpcID
public static final int LEKE_QUO_KERAN = 8697; public static final int LEKE_QUO_KERAN = 8697;
public static final int MONK_OF_ZAMORAK_8698 = 8698; public static final int MONK_OF_ZAMORAK_8698 = 8698;
public static final int LARRAN = 8699; public static final int LARRAN = 8699;
public static final int GIANT_FROG_8700 = 8700;
public static final int BIG_FROG_8701 = 8701;
public static final int FROG_8702 = 8702;
public static final int TEMPLE_SPIDER = 8703;
public static final int BROTHER_AIMERI = 8704;
public static final int BROTHER_AIMERI_8705 = 8705;
public static final int OLBERTUS = 8706;
public static final int OLBERTUS_8707 = 8707;
public static final int OLBERTUS_8708 = 8708;
public static final int SHAEDED_BEAST = 8709;
public static final int SHAEDED_BEAST_8710 = 8710;
public static final int EODAN = 8711;
public static final int KNIGHT_OF_VARLAMORE_8712 = 8712;
public static final int SARACHNIS = 8713;
public static final int SPAWN_OF_SARACHNIS = 8714;
public static final int SPAWN_OF_SARACHNIS_8715 = 8715;
/* This file is automatically generated. Do not edit. */ /* This file is automatically generated. Do not edit. */
} }
@@ -12463,5 +12463,25 @@ public final class NullItemID
public static final int NULL_23492 = 23492; public static final int NULL_23492 = 23492;
public static final int NULL_23493 = 23493; public static final int NULL_23493 = 23493;
public static final int NULL_23494 = 23494; public static final int NULL_23494 = 23494;
public static final int NULL_23496 = 23496;
public static final int NULL_23498 = 23498;
public static final int NULL_23500 = 23500;
public static final int NULL_23501 = 23501;
public static final int NULL_23503 = 23503;
public static final int NULL_23505 = 23505;
public static final int NULL_23507 = 23507;
public static final int NULL_23509 = 23509;
public static final int NULL_23511 = 23511;
public static final int NULL_23513 = 23513;
public static final int NULL_23515 = 23515;
public static final int NULL_23518 = 23518;
public static final int NULL_23519 = 23519;
public static final int NULL_23521 = 23521;
public static final int NULL_23523 = 23523;
public static final int NULL_23524 = 23524;
public static final int NULL_23526 = 23526;
public static final int NULL_23527 = 23527;
public static final int NULL_23529 = 23529;
public static final int NULL_23530 = 23530;
/* This file is automatically generated. Do not edit. */ /* This file is automatically generated. Do not edit. */
} }
@@ -16211,5 +16211,33 @@ public final class NullObjectID
public static final int NULL_34825 = 34825; public static final int NULL_34825 = 34825;
public static final int NULL_34831 = 34831; public static final int NULL_34831 = 34831;
public static final int NULL_34832 = 34832; public static final int NULL_34832 = 34832;
public static final int NULL_34841 = 34841;
public static final int NULL_34869 = 34869;
public static final int NULL_34875 = 34875;
public static final int NULL_34876 = 34876;
public static final int NULL_34877 = 34877;
public static final int NULL_34878 = 34878;
public static final int NULL_34879 = 34879;
public static final int NULL_34880 = 34880;
public static final int NULL_34881 = 34881;
public static final int NULL_34882 = 34882;
public static final int NULL_34883 = 34883;
public static final int NULL_34884 = 34884;
public static final int NULL_34885 = 34885;
public static final int NULL_34886 = 34886;
public static final int NULL_34887 = 34887;
public static final int NULL_34888 = 34888;
public static final int NULL_34889 = 34889;
public static final int NULL_34890 = 34890;
public static final int NULL_34891 = 34891;
public static final int NULL_34892 = 34892;
public static final int NULL_34893 = 34893;
public static final int NULL_34894 = 34894;
public static final int NULL_34895 = 34895;
public static final int NULL_34900 = 34900;
public static final int NULL_34901 = 34901;
public static final int NULL_34902 = 34902;
public static final int NULL_34903 = 34903;
public static final int NULL_34904 = 34904;
/* This file is automatically generated. Do not edit. */ /* This file is automatically generated. Do not edit. */
} }
@@ -15241,11 +15241,11 @@ public final class ObjectID
public static final int ROCKS_28890 = 28890; public static final int ROCKS_28890 = 28890;
public static final int CRACK_28892 = 28892; public static final int CRACK_28892 = 28892;
public static final int STONE_28893 = 28893; public static final int STONE_28893 = 28893;
public static final int ROPE_LADDER_28894 = 28894; public static final int VINE_LADDER = 28894;
public static final int ROPE_28895 = 28895; public static final int VINE_28895 = 28895;
public static final int ROPE_28896 = 28896; public static final int VINE_28896 = 28896;
public static final int ROPE_28897 = 28897; public static final int VINE_28897 = 28897;
public static final int ROPE_28898 = 28898; public static final int VINE_28898 = 28898;
public static final int ALTAR_28900 = 28900; public static final int ALTAR_28900 = 28900;
public static final int BOULDER_28901 = 28901; public static final int BOULDER_28901 = 28901;
public static final int BOULDER_28904 = 28904; public static final int BOULDER_28904 = 28904;
@@ -16846,7 +16846,7 @@ public final class ObjectID
public static final int ROCK_31787 = 31787; public static final int ROCK_31787 = 31787;
public static final int ROCK_31788 = 31788; public static final int ROCK_31788 = 31788;
public static final int ROCK_31789 = 31789; public static final int ROCK_31789 = 31789;
public static final int VINE_LADDER = 31790; public static final int VINE_LADDER_31790 = 31790;
public static final int HOLE_31791 = 31791; public static final int HOLE_31791 = 31791;
public static final int ROOTS_31792 = 31792; public static final int ROOTS_31792 = 31792;
public static final int ROOT_31796 = 31796; public static final int ROOT_31796 = 31796;
@@ -18610,5 +18610,49 @@ public final class ObjectID
public static final int LARRANS_SMALL_CHEST_34828 = 34828; public static final int LARRANS_SMALL_CHEST_34828 = 34828;
public static final int LARRANS_BIG_CHEST = 34829; public static final int LARRANS_BIG_CHEST = 34829;
public static final int LARRANS_BIG_CHEST_34830 = 34830; public static final int LARRANS_BIG_CHEST_34830 = 34830;
public static final int SARACHNIS_DISPLAY = 34833;
public static final int STRANGE_FLOOR_34834 = 34834;
public static final int ANCIENT_FIRE = 34835;
public static final int CURSED_ALTAR = 34836;
public static final int ALTAR_34837 = 34837;
public static final int GRUBBY_CHEST = 34838;
public static final int GRUBBY_CHEST_34839 = 34839;
public static final int GRUBBY_DOOR = 34840;
public static final int TEMPLE_DOOR_34842 = 34842;
public static final int TEMPLE_DOOR_34843 = 34843;
public static final int DOOR_34844 = 34844;
public static final int LEVER_34845 = 34845;
public static final int LEVER_34846 = 34846;
public static final int MUSTY_BOOKSHELF = 34847;
public static final int MUSTY_BOOKSHELF_34848 = 34848;
public static final int MUSTY_BOOKSHELF_34849 = 34849;
public static final int MUSTY_BOOKSHELF_34850 = 34850;
public static final int STONE_RELIEF = 34851;
public static final int STONE_RELIEF_34852 = 34852;
public static final int PASSAGE_34853 = 34853;
public static final int WALL_34854 = 34854;
public static final int SACRED_BONE_BURNER = 34855;
public static final int TORCH_34856 = 34856;
public static final int DRAGON_EGG_34857 = 34857;
public static final int THICK_WEB = 34858;
public static final int THICK_WEB_34859 = 34859;
public static final int STRANGE_PASSAGE = 34860;
public static final int STRANGE_WALL_34861 = 34861;
public static final int LADDER_34862 = 34862;
public static final int LADDER_34863 = 34863;
public static final int STAIRCASE_34864 = 34864;
public static final int STAIRCASE_34865 = 34865;
public static final int CAULDRON_34866 = 34866;
public static final int EGG_SAC = 34867;
public static final int EMPTY_SAC = 34868;
public static final int STONE_PILE_34870 = 34870;
public static final int STONE_PILE_34871 = 34871;
public static final int BROKEN_SUN_ALTAR = 34872;
public static final int EMPTY_SARCOPHAGUS = 34873;
public static final int FLOOR_TILE = 34874;
public static final int BLOOD_34896 = 34896;
public static final int WEB_34897 = 34897;
public static final int WEB_34898 = 34898;
public static final int SLASHED_WEB_34899 = 34899;
/* This file is automatically generated. Do not edit. */ /* This file is automatically generated. Do not edit. */
} }
@@ -24,6 +24,7 @@
*/ */
package net.runelite.api; package net.runelite.api;
import java.awt.geom.Path2D;
import static net.runelite.api.Constants.TILE_FLAG_BRIDGE; import static net.runelite.api.Constants.TILE_FLAG_BRIDGE;
import java.awt.FontMetrics; import java.awt.FontMetrics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
@@ -316,12 +317,6 @@ public class Perspective
final int neX = localLocation.getX() + (size * LOCAL_TILE_SIZE / 2); final int neX = localLocation.getX() + (size * LOCAL_TILE_SIZE / 2);
final int neY = localLocation.getY() + (size * LOCAL_TILE_SIZE / 2); final int neY = localLocation.getY() + (size * LOCAL_TILE_SIZE / 2);
final int seX = swX;
final int seY = neY;
final int nwX = neX;
final int nwY = swY;
final byte[][][] tileSettings = client.getTileSettings(); final byte[][][] tileSettings = client.getTileSettings();
final int sceneX = localLocation.getSceneX(); final int sceneX = localLocation.getSceneX();
@@ -339,14 +334,14 @@ public class Perspective
} }
final int swHeight = getHeight(client, swX, swY, tilePlane); final int swHeight = getHeight(client, swX, swY, tilePlane);
final int nwHeight = getHeight(client, nwX, nwY, tilePlane); final int nwHeight = getHeight(client, neX, swY, tilePlane);
final int neHeight = getHeight(client, neX, neY, tilePlane); final int neHeight = getHeight(client, neX, neY, tilePlane);
final int seHeight = getHeight(client, seX, seY, tilePlane); final int seHeight = getHeight(client, swX, neY, tilePlane);
Point p1 = localToCanvas(client, swX, swY, swHeight); Point p1 = localToCanvas(client, swX, swY, swHeight);
Point p2 = localToCanvas(client, nwX, nwY, nwHeight); Point p2 = localToCanvas(client, neX, swY, nwHeight);
Point p3 = localToCanvas(client, neX, neY, neHeight); Point p3 = localToCanvas(client, neX, neY, neHeight);
Point p4 = localToCanvas(client, seX, seY, seHeight); Point p4 = localToCanvas(client, swX, neY, seHeight);
if (p1 == null || p2 == null || p3 == null || p4 == null) if (p1 == null || p2 == null || p3 == null || p4 == null)
{ {
@@ -549,7 +544,7 @@ public class Perspective
) )
{ {
int radius = 5; int radius = 5;
Area geometry = new Area(); Path2D.Double geometry = new Path2D.Double();
final int tileHeight = getTileHeight(client, point, client.getPlane()); final int tileHeight = getTileHeight(client, point, client.getPlane());
@@ -607,10 +602,10 @@ public class Perspective
continue; continue;
} }
geometry.add(new Area(clickableRect)); geometry.append(clickableRect, false);
} }
return geometry; return new Area(geometry);
} }
private static Area getAABB( private static Area getAABB(
@@ -104,10 +104,6 @@ public class Point
{ {
return false; return false;
} }
if (this.y != other.y) return this.y == other.y;
{
return false;
}
return true;
} }
} }
@@ -95,11 +95,6 @@ public final class ScriptID
*/ */
public static final int CHAT_PROMPT_INIT = 223; public static final int CHAT_PROMPT_INIT = 223;
/**
* Joins the corresponding minigame chat
*/
public static final int FORCE_JOIN_CC = 437;
/** /**
* Displays the game messages when clicking on an item inside the Items Kept on Death interface * Displays the game messages when clicking on an item inside the Items Kept on Death interface
* <ul> * <ul>
@@ -200,4 +195,14 @@ public final class ScriptID
* Join a clan, duh * Join a clan, duh
*/ */
public static final int CUSTOM_JOIN_CLAN = 10690; public static final int CUSTOM_JOIN_CLAN = 10690;
/**
* Send a public message
*/
public static final int PUBLICMSG = 13337;
/**
* Clicking bank pin buttons runs this
*/
public static final int BANK_PIN_OP = 685;
} }
@@ -651,7 +651,9 @@ public enum Varbits
/** /**
* POH Building mode (1 = yes, 0 = no) * POH Building mode (1 = yes, 0 = no)
*/ */
BUILDING_MODE(2176); BUILDING_MODE(2176),
WINTERTODT_TIMER(7980);
/** /**
* The raw varbit ID. * The raw varbit ID.
@@ -271,8 +271,16 @@ public class WorldArea
LocalPoint lp = LocalPoint.fromWorld(client, x, y); LocalPoint lp = LocalPoint.fromWorld(client, x, y);
int startX = lp.getSceneX() + dx; int startX = 0;
int startY = lp.getSceneY() + dy; if (lp != null)
{
startX = lp.getSceneX() + dx;
}
int startY = 0;
if (lp != null)
{
startY = lp.getSceneY() + dy;
}
int checkX = startX + (dx > 0 ? width - 1 : 0); int checkX = startX + (dx > 0 ? width - 1 : 0);
int checkY = startY + (dy > 0 ? height - 1 : 0); int checkY = startY + (dy > 0 ? height - 1 : 0);
int endX = startX + width - 1; int endX = startX + width - 1;
@@ -427,11 +435,8 @@ public class WorldArea
} }
if (height == 1) if (height == 1)
{ {
if ((collisionDataFlags[checkX - dx][checkY] & yFlags) != 0 && return (collisionDataFlags[checkX - dx][checkY] & yFlags) == 0 ||
extraCondition.test(WorldPoint.fromScene(client, startX, checkY, client.getPlane()))) !extraCondition.test(WorldPoint.fromScene(client, startX, checkY, client.getPlane()));
{
return false;
}
} }
} }
@@ -370,16 +370,12 @@ public class WorldPoint
*/ */
public static boolean isInZone(WorldPoint lowerBound, WorldPoint upperBound, WorldPoint userLocation) public static boolean isInZone(WorldPoint lowerBound, WorldPoint upperBound, WorldPoint userLocation)
{ {
if (userLocation.getX() < lowerBound.getX() return userLocation.getX() >= lowerBound.getX()
|| userLocation.getX() > upperBound.getX() && userLocation.getX() <= upperBound.getX()
|| userLocation.getY() < lowerBound.getY() && userLocation.getY() >= lowerBound.getY()
|| userLocation.getY() > upperBound.getY() && userLocation.getY() <= upperBound.getY()
|| userLocation.getPlane() < lowerBound.getPlane() && userLocation.getPlane() >= lowerBound.getPlane()
|| userLocation.getPlane() > upperBound.getPlane()) && userLocation.getPlane() <= upperBound.getPlane();
{
return false;
}
return true;
} }
/** /**
@@ -29,4 +29,10 @@ package net.runelite.api.events;
*/ */
public class BeforeRender public class BeforeRender
{ {
public static final BeforeRender INSTANCE = new BeforeRender();
private BeforeRender()
{
// noop
}
} }
@@ -29,4 +29,10 @@ package net.runelite.api.events;
*/ */
public class CannonballFired public class CannonballFired
{ {
public static final CannonballFired INSTANCE = new CannonballFired();
private CannonballFired()
{
// noop
}
} }
@@ -29,4 +29,10 @@ package net.runelite.api.events;
*/ */
public class CanvasSizeChanged public class CanvasSizeChanged
{ {
public static final CanvasSizeChanged INSTANCE = new CanvasSizeChanged();
private CanvasSizeChanged()
{
// noop
}
} }
@@ -29,4 +29,10 @@ package net.runelite.api.events;
*/ */
public class ClientTick public class ClientTick
{ {
public static final ClientTick INSTANCE = new ClientTick();
private ClientTick()
{
// noop
}
} }
@@ -0,0 +1,16 @@
package net.runelite.api.events;
import lombok.Data;
@Data
public class DynamicObjectAnimationChanged
{
/**
* The object that has entered a new animation.
*/
private int object;
/**
* The id of the animation animation.
*/
private int animation;
}
@@ -0,0 +1,15 @@
package net.runelite.api.events;
import lombok.Value;
/**
* An event where a request to add a friend is sent to the server.
*/
@Value
public class FriendAdded
{
/**
* The name of the added friend.
*/
private final String name;
}
@@ -30,7 +30,7 @@ import lombok.Value;
* An event where a request to remove a friend is sent to the server. * An event where a request to remove a friend is sent to the server.
*/ */
@Value @Value
public class RemovedFriend public class FriendRemoved
{ {
/** /**
* The name of the removed friend. * The name of the removed friend.
@@ -24,8 +24,6 @@
*/ */
package net.runelite.api.events; package net.runelite.api.events;
import lombok.Data;
// The NPC update event seem to run every server tick, // The NPC update event seem to run every server tick,
// but having the game tick event after all packets // but having the game tick event after all packets
// have been processed is typically more useful. // have been processed is typically more useful.
@@ -43,7 +41,12 @@ import lombok.Data;
* Note that occurrences that take place purely on the client, such as right * Note that occurrences that take place purely on the client, such as right
* click menus, are independent of the game tick. * click menus, are independent of the game tick.
*/ */
@Data
public class GameTick public class GameTick
{ {
public static final GameTick INSTANCE = new GameTick();
private GameTick()
{
// noop
}
} }
@@ -29,4 +29,10 @@ package net.runelite.api.events;
*/ */
public class LocalPlayerDeath public class LocalPlayerDeath
{ {
public static final LocalPlayerDeath INSTANCE = new LocalPlayerDeath();
private LocalPlayerDeath()
{
// noop
}
} }
@@ -24,7 +24,9 @@
*/ */
package net.runelite.api.events; package net.runelite.api.events;
import lombok.AccessLevel;
import lombok.Data; import lombok.Data;
import lombok.Setter;
import net.runelite.api.MenuAction; import net.runelite.api.MenuAction;
import net.runelite.api.MenuEntry; import net.runelite.api.MenuEntry;
@@ -45,6 +47,13 @@ public class MenuOptionClicked
public MenuOptionClicked(MenuEntry entry) public MenuOptionClicked(MenuEntry entry)
{ {
menuEntry = entry; menuEntry = entry;
authentic = true;
}
public MenuOptionClicked(MenuEntry entry, boolean authentic)
{
menuEntry = entry;
this.authentic = authentic;
} }
/** /**
@@ -129,4 +138,10 @@ public class MenuOptionClicked
{ {
this.consumed = true; this.consumed = true;
} }
/**
* Whether or not the event is authentic.
*/
@Setter(AccessLevel.PRIVATE)
private boolean authentic;
} }
@@ -32,4 +32,10 @@ package net.runelite.api.events;
*/ */
public class UsernameChanged public class UsernameChanged
{ {
public static final UsernameChanged INSTANCE = new UsernameChanged();
private UsernameChanged()
{
// noop
}
} }
@@ -24,13 +24,16 @@
*/ */
package net.runelite.api.events; package net.runelite.api.events;
import lombok.Value;
/** /**
* An event where the position of a {@link net.runelite.api.widgets.Widget} * An event where the position of a {@link net.runelite.api.widgets.Widget}
* relative to its parent has changed. * relative to its parent has changed.
*/ */
@Value
public class WidgetPositioned public class WidgetPositioned
{ {
public static final WidgetPositioned INSTANCE = new WidgetPositioned();
private WidgetPositioned()
{
// noop
}
} }
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2019, 7ate9 <https://github.com/se7enAte9>
* Copyright (c) 2019, https://runelitepl.us
* 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.api.events;
import lombok.Data;
/**
* An event where a draggable widget has been pressed.
*/
@Data
public class WidgetPressed
{
public static final WidgetPressed INSTANCE = new WidgetPressed();
private WidgetPressed()
{
// noop
}
}
@@ -125,8 +125,7 @@ public class Jarvis
private static long crossProduct(Point p, Point q, Point r) private static long crossProduct(Point p, Point q, Point r)
{ {
long val = (long)(q.getY() - p.getY()) * (r.getX() - q.getX()) return (long)(q.getY() - p.getY()) * (r.getX() - q.getX())
- (long)(q.getX() - p.getX()) * (r.getY() - q.getY()); - (long)(q.getX() - p.getX()) * (r.getY() - q.getY());
return val;
} }
} }
@@ -151,6 +151,7 @@ public class WidgetID
public static final int BEGINNER_CLUE_MAP_WIZARDS_TOWER = 356; public static final int BEGINNER_CLUE_MAP_WIZARDS_TOWER = 356;
public static final int SEED_BOX_GROUP_ID = 128; public static final int SEED_BOX_GROUP_ID = 128;
public static final int ITEMS_KEPT_ON_DEATH_GROUP_ID = 4; public static final int ITEMS_KEPT_ON_DEATH_GROUP_ID = 4;
public static final int TRADING_SCREEN = 335;
static class WorldMap static class WorldMap
{ {
@@ -253,6 +254,7 @@ public class WidgetID
static final int INVENTORY_ITEM_CONTAINER = 3; static final int INVENTORY_ITEM_CONTAINER = 3;
static final int BANK_TITLE_BAR = 4; static final int BANK_TITLE_BAR = 4;
static final int CONTENT_CONTAINER = 10; static final int CONTENT_CONTAINER = 10;
static final int TAB_CONTAINER = 11;
static final int ITEM_CONTAINER = 13; static final int ITEM_CONTAINER = 13;
static final int SEARCH_BUTTON_BACKGROUND = 40; static final int SEARCH_BUTTON_BACKGROUND = 40;
static final int DEPOSIT_INVENTORY = 42; static final int DEPOSIT_INVENTORY = 42;
@@ -665,6 +667,7 @@ public class WidgetID
static class TheatreOfBlood static class TheatreOfBlood
{ {
static final int RAIDING_PARTY = 9;
static final int ORB_BOX = 10; static final int ORB_BOX = 10;
static final int BOSS_HEALTH_BAR = 35; static final int BOSS_HEALTH_BAR = 35;
} }
@@ -140,6 +140,7 @@ public enum WidgetInfo
BANK_CONTENT_CONTAINER(WidgetID.BANK_GROUP_ID, WidgetID.Bank.CONTENT_CONTAINER), BANK_CONTENT_CONTAINER(WidgetID.BANK_GROUP_ID, WidgetID.Bank.CONTENT_CONTAINER),
BANK_DEPOSIT_EQUIPMENT(WidgetID.BANK_GROUP_ID, WidgetID.Bank.DEPOSIT_EQUIPMENT), BANK_DEPOSIT_EQUIPMENT(WidgetID.BANK_GROUP_ID, WidgetID.Bank.DEPOSIT_EQUIPMENT),
BANK_DEPOSIT_INVENTORY(WidgetID.BANK_GROUP_ID, WidgetID.Bank.DEPOSIT_INVENTORY), BANK_DEPOSIT_INVENTORY(WidgetID.BANK_GROUP_ID, WidgetID.Bank.DEPOSIT_INVENTORY),
BANK_TAB_CONTAINER(WidgetID.BANK_GROUP_ID, WidgetID.Bank.TAB_CONTAINER),
GRAND_EXCHANGE_WINDOW_CONTAINER(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.WINDOW_CONTAINER), GRAND_EXCHANGE_WINDOW_CONTAINER(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.WINDOW_CONTAINER),
GRAND_EXCHANGE_OFFER_CONTAINER(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER_CONTAINER), GRAND_EXCHANGE_OFFER_CONTAINER(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER_CONTAINER),
@@ -444,6 +445,7 @@ public enum WidgetInfo
THEATRE_OF_BLOOD_HEALTH_ORBS(WidgetID.THEATRE_OF_BLOOD_GROUP_ID, WidgetID.TheatreOfBlood.ORB_BOX), THEATRE_OF_BLOOD_HEALTH_ORBS(WidgetID.THEATRE_OF_BLOOD_GROUP_ID, WidgetID.TheatreOfBlood.ORB_BOX),
THEATRE_OF_BLOOD_BOSS_HEALTH(WidgetID.THEATRE_OF_BLOOD_GROUP_ID, WidgetID.TheatreOfBlood.BOSS_HEALTH_BAR), THEATRE_OF_BLOOD_BOSS_HEALTH(WidgetID.THEATRE_OF_BLOOD_GROUP_ID, WidgetID.TheatreOfBlood.BOSS_HEALTH_BAR),
THEATRE_OF_BLOOD_RAIDING_PARTY(WidgetID.THEATRE_OF_BLOOD_GROUP_ID, WidgetID.TheatreOfBlood.RAIDING_PARTY),
BLAST_FURNACE_COFFER(WidgetID.BLAST_FURNACE_GROUP_ID, 2), BLAST_FURNACE_COFFER(WidgetID.BLAST_FURNACE_GROUP_ID, 2),
@@ -35,4 +35,10 @@ public final class WidgetType
public static final int TEXT_INVENTORY = 7; public static final int TEXT_INVENTORY = 7;
public static final int IF1_TOOLTIP = 8; public static final int IF1_TOOLTIP = 8;
public static final int LINE = 9; public static final int LINE = 9;
public static final int FPS = 1336;
public static final int VIEWPORT = 1337;
public static final int MINIMAP = 1338;
public static final int COMPASS = 1339;
public static final int WORLD_MAP = 1400;
public static final int WORLD_MAP_OVERVIEW = 1401;
} }
+7 -6
View File
@@ -29,7 +29,7 @@
<parent> <parent>
<groupId>net.runelite</groupId> <groupId>net.runelite</groupId>
<artifactId>runelite-parent</artifactId> <artifactId>runelite-parent</artifactId>
<version>1.5.28-SNAPSHOT</version> <version>1.5.29-SNAPSHOT</version>
</parent> </parent>
<artifactId>client</artifactId> <artifactId>client</artifactId>
@@ -284,11 +284,12 @@
<artifactId>asm-all</artifactId> <artifactId>asm-all</artifactId>
<version>6.0_BETA</version> <version>6.0_BETA</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.json</groupId> <groupId>org.codehaus.plexus</groupId>
<artifactId>json</artifactId> <artifactId>plexus-utils</artifactId>
<version>20180813</version> <version>3.0.21</version>
</dependency> <scope>compile</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>
@@ -83,13 +83,13 @@ import org.slf4j.LoggerFactory;
@Slf4j @Slf4j
public class RuneLite public class RuneLite
{ {
public static final String RUNELIT_VERSION = "2.0.1-1"; public static final String RUNELIT_VERSION = "2.0.2";
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");
public static final File SCREENSHOT_DIR = new File(RUNELITE_DIR, "screenshots"); public static final File SCREENSHOT_DIR = new File(RUNELITE_DIR, "screenshots");
static final RuneLiteSplashScreen splashScreen = new RuneLiteSplashScreen(); public static final File LOGS_DIR = new File(RUNELITE_DIR, "logs");
private static final RuneLiteSplashScreen splashScreen = new RuneLiteSplashScreen();
@Getter @Getter
private static Injector injector; private static Injector injector;
@@ -41,6 +41,7 @@ import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.config.ChatColorConfig; import net.runelite.client.config.ChatColorConfig;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.config.RuneLiteConfig;
import net.runelite.client.config.RuneLitePlusConfig;
import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.EventBus;
import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemManager;
import net.runelite.client.menus.MenuManager; import net.runelite.client.menus.MenuManager;
@@ -117,6 +118,13 @@ public class RuneLiteModule extends AbstractModule
return configManager.getConfig(RuneLiteConfig.class); return configManager.getConfig(RuneLiteConfig.class);
} }
@Provides
@Singleton
RuneLitePlusConfig providePlusConfig(ConfigManager configManager)
{
return configManager.getConfig(RuneLitePlusConfig.class);
}
@Provides @Provides
@Singleton @Singleton
ChatColorConfig provideChatColorConfig(ConfigManager configManager) ChatColorConfig provideChatColorConfig(ConfigManager configManager)
@@ -31,17 +31,18 @@ import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.client.plugins.runeliteplus.RuneLitePlusPlugin; import net.runelite.client.config.RuneLitePlusConfig;
@Singleton @Singleton
@Slf4j @Slf4j
public class RuneLiteProperties public class RuneLiteProperties
{ {
public static String discordAppID = "409416265891971072";
private static final String RUNELITE_TITLE = "runelite.title"; private static final String RUNELITE_TITLE = "runelite.title";
private static final String RUNELITE_VERSION = "runelite.version"; private static final String RUNELITE_VERSION = "runelite.version";
private static final String RUNELIT_VERSION = "runelit.version";
private static final String RUNESCAPE_VERSION = "runescape.version"; private static final String RUNESCAPE_VERSION = "runescape.version";
private static final String DISCORD_APP_ID = "runelite.discord.appid"; private static final String DISCORD_APP_ID = "runelite.discord.appid";
private static final String DISCORD_APP_ID_PLUS = "runelite.plus.discord.appid";
private static final String DISCORD_INVITE = "runelite.discord.invite"; private static final String DISCORD_INVITE = "runelite.discord.invite";
private static final String GITHUB_LINK = "runelite.github.link"; private static final String GITHUB_LINK = "runelite.github.link";
private static final String WIKI_LINK = "runelite.wiki.link"; private static final String WIKI_LINK = "runelite.wiki.link";
@@ -50,9 +51,26 @@ public class RuneLiteProperties
private final Properties properties = new Properties(); private final Properties properties = new Properties();
private final RuneLitePlusConfig runeLitePlusConfig;
@Inject @Inject
public RuneLiteProperties(final RuneLitePlusConfig runeLiteConfig)
{
this.runeLitePlusConfig = runeLiteConfig;
try (InputStream in = getClass().getResourceAsStream("runelite.properties"))
{
properties.load(in);
}
catch (IOException ex)
{
log.warn("unable to load propertries", ex);
}
}
public RuneLiteProperties() public RuneLiteProperties()
{ {
runeLitePlusConfig = null;
try (InputStream in = getClass().getResourceAsStream("runelite.properties")) try (InputStream in = getClass().getResourceAsStream("runelite.properties"))
{ {
properties.load(in); properties.load(in);
@@ -79,6 +97,11 @@ public class RuneLiteProperties
return properties.getProperty(RUNELITE_VERSION); return properties.getProperty(RUNELITE_VERSION);
} }
public String getRunelitVersion()
{
return properties.getProperty(RUNELIT_VERSION);
}
public String getRunescapeVersion() public String getRunescapeVersion()
{ {
return properties.getProperty(RUNESCAPE_VERSION); return properties.getProperty(RUNESCAPE_VERSION);
@@ -86,9 +109,14 @@ public class RuneLiteProperties
public String getDiscordAppId() public String getDiscordAppId()
{ {
if (RuneLitePlusPlugin.customPresenceEnabled) if (this.runeLitePlusConfig == null)
{ {
return properties.getProperty(RuneLitePlusPlugin.rlPlusDiscordApp); return properties.getProperty(DISCORD_APP_ID);
}
if (this.runeLitePlusConfig.customPresence())
{
return properties.getProperty(DISCORD_APP_ID_PLUS);
} }
else else
{ {
@@ -36,7 +36,7 @@ import net.runelite.api.Client;
@Slf4j @Slf4j
public class ClientThread public class ClientThread
{ {
private ConcurrentLinkedQueue<BooleanSupplier> invokes = new ConcurrentLinkedQueue<>(); private final ConcurrentLinkedQueue<BooleanSupplier> invokes = new ConcurrentLinkedQueue<>();
@Inject @Inject
private Client client; private Client client;
@@ -87,9 +87,6 @@ public class Hooks implements Callbacks
private static final OverlayRenderer renderer = injector.getInstance(OverlayRenderer.class); private static final OverlayRenderer renderer = injector.getInstance(OverlayRenderer.class);
private static final OverlayManager overlayManager = injector.getInstance(OverlayManager.class); private static final OverlayManager overlayManager = injector.getInstance(OverlayManager.class);
private static final GameTick GAME_TICK = new GameTick();
private static final BeforeRender BEFORE_RENDER = new BeforeRender();
@Inject @Inject
private EventBus eventBus; private EventBus eventBus;
@@ -151,13 +148,13 @@ public class Hooks implements Callbacks
deferredEventBus.replay(); deferredEventBus.replay();
eventBus.post(GAME_TICK); eventBus.post(GameTick.INSTANCE);
int tick = client.getTickCount(); int tick = client.getTickCount();
client.setTickCount(tick + 1); client.setTickCount(tick + 1);
} }
eventBus.post(BEFORE_RENDER); eventBus.post(BeforeRender.INSTANCE);
clientThread.invoke(); clientThread.invoke();
@@ -115,7 +115,7 @@ public class ChatMessageManager
boolean isChatboxTransparent = client.isResized() && client.getVar(Varbits.TRANSPARENT_CHATBOX) == 1; boolean isChatboxTransparent = client.isResized() && client.getVar(Varbits.TRANSPARENT_CHATBOX) == 1;
Color usernameColor = null; Color usernameColor = null;
Color senderColor = null; Color senderColor;
switch (chatMessageType) switch (chatMessageType)
{ {
@@ -53,10 +53,7 @@ public class ConfigDescriptor
Collection<ConfigItemDescriptor> allItems = new ArrayList<>(); Collection<ConfigItemDescriptor> allItems = new ArrayList<>();
for (ConfigItemsGroup g : itemGroups) for (ConfigItemsGroup g : itemGroups)
{ {
for (ConfigItemDescriptor item : g.getItems()) allItems.addAll(g.getItems());
{
allItems.add(item);
}
} }
return allItems; return allItems;
} }
@@ -81,7 +81,6 @@ public class ConfigManager
@Inject @Inject
EventBus eventBus; EventBus eventBus;
private final ScheduledExecutorService executor;
private final ConfigInvocationHandler handler = new ConfigInvocationHandler(this); private final ConfigInvocationHandler handler = new ConfigInvocationHandler(this);
private final Properties properties = new Properties(); private final Properties properties = new Properties();
private final Map<String, Object> configObjectCache = new HashMap<>(); private final Map<String, Object> configObjectCache = new HashMap<>();
@@ -90,9 +89,8 @@ public class ConfigManager
@Inject @Inject
public ConfigManager(ScheduledExecutorService scheduledExecutorService) public ConfigManager(ScheduledExecutorService scheduledExecutorService)
{ {
this.executor = scheduledExecutorService;
executor.scheduleWithFixedDelay(this::sendConfig, 30, 30, TimeUnit.SECONDS); scheduledExecutorService.scheduleWithFixedDelay(this::sendConfig, 30, 30, TimeUnit.SECONDS);
} }
public final void switchSession() public final void switchSession()
@@ -245,12 +243,10 @@ public class ConfigManager
throw new RuntimeException("Non-public configuration classes can't have default methods invoked"); throw new RuntimeException("Non-public configuration classes can't have default methods invoked");
} }
T t = (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class<?>[] return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class<?>[]
{ {
clazz clazz
}, handler); }, handler);
return t;
} }
public List<String> getConfigurationKeys(String prefix) public List<String> getConfigurationKeys(String prefix)
@@ -60,7 +60,7 @@ public class Keybind
private final int keyCode; private final int keyCode;
private final int modifiers; private final int modifiers;
protected Keybind(int keyCode, int modifiers, boolean ignoreModifiers) Keybind(int keyCode, int modifiers, boolean ignoreModifiers)
{ {
modifiers &= KEYBOARD_MODIFIER_MASK; modifiers &= KEYBOARD_MODIFIER_MASK;
@@ -108,7 +108,7 @@ public class Keybind
return matches(e, false); return matches(e, false);
} }
protected boolean matches(KeyEvent e, boolean ignoreModifiers) boolean matches(KeyEvent e, boolean ignoreModifiers)
{ {
if (NOT_SET.equals(this)) if (NOT_SET.equals(this))
{ {
@@ -177,7 +177,7 @@ public class Keybind
return mod; return mod;
} }
public static String getModifiersExText(int modifiers) private static String getModifiersExText(int modifiers)
{ {
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder();
if ((modifiers & InputEvent.META_DOWN_MASK) != 0) if ((modifiers & InputEvent.META_DOWN_MASK) != 0)
@@ -33,10 +33,10 @@ import net.runelite.client.ui.FontManager;
public interface RuneLiteConfig extends Config public interface RuneLiteConfig extends Config
{ {
@ConfigItem( @ConfigItem(
keyName = "gameSize", keyName = "gameSize",
name = "Game size", name = "Game size",
description = "The game will resize to this resolution upon starting the client", description = "The game will resize to this resolution upon starting the client",
position = 10 position = 10
) )
default Dimension gameSize() default Dimension gameSize()
{ {
@@ -44,10 +44,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "automaticResizeType", keyName = "automaticResizeType",
name = "Resize type", name = "Resize type",
description = "Choose how the window should resize when opening and closing panels", description = "Choose how the window should resize when opening and closing panels",
position = 11 position = 11
) )
default ExpandResizeType automaticResizeType() default ExpandResizeType automaticResizeType()
{ {
@@ -55,10 +55,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "lockWindowSize", keyName = "lockWindowSize",
name = "Lock window size", name = "Lock window size",
description = "Determines if the window resizing is allowed or not", description = "Determines if the window resizing is allowed or not",
position = 12 position = 12
) )
default boolean lockWindowSize() default boolean lockWindowSize()
{ {
@@ -66,21 +66,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "enablePlugins", keyName = "containInScreen",
name = "Enable loading of external plugins", name = "Contain in screen",
description = "Enable loading of external plugins", description = "Makes the client stay contained in the screen when attempted to move out of it.<br>Note: Only works if custom chrome is enabled.",
position = 10 position = 13
)
default boolean enablePlugins()
{
return true;
}
@ConfigItem(
keyName = "containInScreen",
name = "Contain in screen",
description = "Makes the client stay contained in the screen when attempted to move out of it.<br>Note: Only works if custom chrome is enabled.",
position = 13
) )
default boolean containInScreen() default boolean containInScreen()
{ {
@@ -88,10 +77,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "rememberScreenBounds", keyName = "rememberScreenBounds",
name = "Remember client position", name = "Remember client position",
description = "Save the position and size of the client after exiting", description = "Save the position and size of the client after exiting",
position = 14 position = 14
) )
default boolean rememberScreenBounds() default boolean rememberScreenBounds()
{ {
@@ -99,11 +88,11 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "uiEnableCustomChrome", keyName = "uiEnableCustomChrome",
name = "Enable custom window chrome", name = "Enable custom window chrome",
description = "Use Runelite's custom window title and borders.", description = "Use Runelite's custom window title and borders.",
warning = "Please restart your client after changing this setting", warning = "Please restart your client after changing this setting",
position = 15 position = 15
) )
default boolean enableCustomChrome() default boolean enableCustomChrome()
{ {
@@ -111,10 +100,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "gameAlwaysOnTop", keyName = "gameAlwaysOnTop",
name = "Enable client always on top", name = "Enable client always on top",
description = "The game will always be on the top of the screen", description = "The game will always be on the top of the screen",
position = 16 position = 16
) )
default boolean gameAlwaysOnTop() default boolean gameAlwaysOnTop()
{ {
@@ -122,10 +111,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "warningOnExit", keyName = "warningOnExit",
name = "Display warning on exit", name = "Display warning on exit",
description = "Toggles a warning popup when trying to exit the client", description = "Toggles a warning popup when trying to exit the client",
position = 17 position = 17
) )
default WarningOnExit warningOnExit() default WarningOnExit warningOnExit()
{ {
@@ -133,10 +122,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "usernameInTitle", keyName = "usernameInTitle",
name = "Show display name in title", name = "Show display name in title",
description = "Toggles displaying of local player's display name in client title", description = "Toggles displaying of local player's display name in client title",
position = 18 position = 18
) )
default boolean usernameInTitle() default boolean usernameInTitle()
{ {
@@ -144,10 +133,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "notificationTray", keyName = "notificationTray",
name = "Enable tray notifications", name = "Enable tray notifications",
description = "Enables tray notifications", description = "Enables tray notifications",
position = 20 position = 20
) )
default boolean enableTrayNotifications() default boolean enableTrayNotifications()
{ {
@@ -155,10 +144,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "notificationRequestFocus", keyName = "notificationRequestFocus",
name = "Request focus on notification", name = "Request focus on notification",
description = "Toggles window focus request", description = "Toggles window focus request",
position = 21 position = 21
) )
default boolean requestFocusOnNotification() default boolean requestFocusOnNotification()
{ {
@@ -166,10 +155,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "notificationSound", keyName = "notificationSound",
name = "Enable sound on notifications", name = "Enable sound on notifications",
description = "Enables the playing of a beep sound when notifications are displayed", description = "Enables the playing of a beep sound when notifications are displayed",
position = 22 position = 22
) )
default boolean enableNotificationSound() default boolean enableNotificationSound()
{ {
@@ -177,10 +166,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "notificationGameMessage", keyName = "notificationGameMessage",
name = "Enable game message notifications", name = "Enable game message notifications",
description = "Puts a notification message in the chatbox", description = "Puts a notification message in the chatbox",
position = 23 position = 23
) )
default boolean enableGameMessageNotification() default boolean enableGameMessageNotification()
{ {
@@ -188,10 +177,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "notificationFlash", keyName = "notificationFlash",
name = "Enable flash notification", name = "Enable flash notification",
description = "Flashes the game frame as a notification", description = "Flashes the game frame as a notification",
position = 24 position = 24
) )
default FlashNotification flashNotification() default FlashNotification flashNotification()
{ {
@@ -199,10 +188,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "notificationFocused", keyName = "notificationFocused",
name = "Send notifications when focused", name = "Send notifications when focused",
description = "Toggles all notifications for when the client is focused", description = "Toggles all notifications for when the client is focused",
position = 25 position = 25
) )
default boolean sendNotificationsWhenFocused() default boolean sendNotificationsWhenFocused()
{ {
@@ -221,10 +210,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "fontType", keyName = "fontType",
name = "Dynamic Overlay Font", name = "Dynamic Overlay Font",
description = "Configures what font type is used for in-game overlays such as player name, ground items, etc.", description = "Configures what font type is used for in-game overlays such as player name, ground items, etc.",
position = 30 position = 30
) )
default FontType fontType() default FontType fontType()
{ {
@@ -232,10 +221,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "tooltipFontType", keyName = "tooltipFontType",
name = "Tooltip Font", name = "Tooltip Font",
description = "Configures what font type is used for in-game tooltips such as food stats, NPC names, etc.", description = "Configures what font type is used for in-game tooltips such as food stats, NPC names, etc.",
position = 31 position = 31
) )
default FontType tooltipFontType() default FontType tooltipFontType()
{ {
@@ -243,10 +232,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "interfaceFontType", keyName = "interfaceFontType",
name = "Interface Overlay Font", name = "Interface Overlay Font",
description = "Configures what font type is used for in-game interface overlays such as panels, opponent info, clue scrolls etc.", description = "Configures what font type is used for in-game interface overlays such as panels, opponent info, clue scrolls etc.",
position = 32 position = 32
) )
default FontType interfaceFontType() default FontType interfaceFontType()
{ {
@@ -254,10 +243,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "menuEntryShift", keyName = "menuEntryShift",
name = "Require Shift for overlay menu", name = "Require Shift for overlay menu",
description = "Overlay right-click menu will require shift to be added", description = "Overlay right-click menu will require shift to be added",
position = 33 position = 33
) )
default boolean menuEntryShift() default boolean menuEntryShift()
{ {
@@ -265,10 +254,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "infoBoxVertical", keyName = "infoBoxVertical",
name = "Display infoboxes vertically", name = "Display infoboxes vertically",
description = "Toggles the infoboxes to display vertically", description = "Toggles the infoboxes to display vertically",
position = 40 position = 40
) )
default boolean infoBoxVertical() default boolean infoBoxVertical()
{ {
@@ -276,10 +265,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "infoBoxWrap", keyName = "infoBoxWrap",
name = "Infobox wrap count", name = "Infobox wrap count",
description = "Configures the amount of infoboxes shown before wrapping", description = "Configures the amount of infoboxes shown before wrapping",
position = 41 position = 41
) )
default int infoBoxWrap() default int infoBoxWrap()
{ {
@@ -287,22 +276,22 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "infoBoxSize", keyName = "infoBoxSize",
name = "Infobox size (px)", name = "Infobox size (px)",
description = "Configures the size of each infobox in pixels", description = "Configures the size of each infobox in pixels",
position = 42 position = 42
) )
default int infoBoxSize() default int infoBoxSize()
{ {
return 35; return 35;
} }
@Range( max = 100, min = 0 ) @Range(max = 100, min = 0)
@ConfigItem( @ConfigItem(
keyName = "volume", keyName = "volume",
name = "Runelite Volume", name = "Runelite Volume",
description = "Sets the volume of custom Runelite sounds (not the client sounds)", description = "Sets the volume of custom Runelite sounds (not the client sounds)",
position = 43 position = 43
) )
default int volume() default int volume()
{ {
@@ -24,7 +24,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
package net.runelite.client.plugins.runeliteplus; package net.runelite.client.config;
import net.runelite.client.config.Config; import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigGroup;
@@ -81,4 +81,15 @@ public interface RuneLitePlusConfig extends Config
{ {
return false; return false;
} }
@ConfigItem(
keyName = "enablePlugins",
name = "Enable loading of external plugins",
description = "Enable loading of external plugins",
position = 10
)
default boolean enablePlugins()
{
return false;
}
} }
@@ -49,7 +49,7 @@ import net.runelite.discord.DiscordUser;
public class DiscordService implements AutoCloseable public class DiscordService implements AutoCloseable
{ {
private final EventBus eventBus; private final EventBus eventBus;
public final RuneLiteProperties runeLiteProperties; private final RuneLiteProperties runeLiteProperties;
private final ScheduledExecutorService executorService; private final ScheduledExecutorService executorService;
private final DiscordRPC discordRPC; private final DiscordRPC discordRPC;
@@ -106,7 +106,7 @@ public class DiscordService implements AutoCloseable
discordEventHandlers.joinGame = this::joinGame; discordEventHandlers.joinGame = this::joinGame;
discordEventHandlers.spectateGame = this::spectateGame; discordEventHandlers.spectateGame = this::spectateGame;
discordEventHandlers.joinRequest = this::joinRequest; discordEventHandlers.joinRequest = this::joinRequest;
discordRPC.Discord_Initialize(RuneLiteProperties.discordAppID, discordEventHandlers, true, null); discordRPC.Discord_Initialize(runeLiteProperties.getDiscordAppId(), discordEventHandlers, true, null);
executorService.scheduleAtFixedRate(discordRPC::Discord_RunCallbacks, 0, 2, TimeUnit.SECONDS); executorService.scheduleAtFixedRate(discordRPC::Discord_RunCallbacks, 0, 2, TimeUnit.SECONDS);
} }
@@ -36,6 +36,7 @@ import static net.runelite.client.game.HiscoreManager.NONE;
import net.runelite.http.api.hiscore.HiscoreClient; import net.runelite.http.api.hiscore.HiscoreClient;
import net.runelite.http.api.hiscore.HiscoreEndpoint; import net.runelite.http.api.hiscore.HiscoreEndpoint;
import net.runelite.http.api.hiscore.HiscoreResult; import net.runelite.http.api.hiscore.HiscoreResult;
import org.jetbrains.annotations.NotNull;
@Slf4j @Slf4j
class HiscoreLoader extends CacheLoader<HiscoreManager.HiscoreKey, HiscoreResult> class HiscoreLoader extends CacheLoader<HiscoreManager.HiscoreKey, HiscoreResult>
@@ -50,7 +51,7 @@ class HiscoreLoader extends CacheLoader<HiscoreManager.HiscoreKey, HiscoreResult
} }
@Override @Override
public HiscoreResult load(HiscoreManager.HiscoreKey hiscoreKey) throws Exception public HiscoreResult load(@NotNull HiscoreManager.HiscoreKey hiscoreKey) throws Exception
{ {
return EMPTY; return EMPTY;
} }
@@ -168,6 +168,7 @@ import net.runelite.client.eventbus.Subscribe;
import net.runelite.http.api.item.ItemClient; import net.runelite.http.api.item.ItemClient;
import net.runelite.http.api.item.ItemPrice; import net.runelite.http.api.item.ItemPrice;
import net.runelite.http.api.item.ItemStats; import net.runelite.http.api.item.ItemStats;
import org.jetbrains.annotations.NotNull;
@Singleton @Singleton
@Slf4j @Slf4j
@@ -279,7 +280,7 @@ public class ItemManager
.build(new CacheLoader<ImageKey, AsyncBufferedImage>() .build(new CacheLoader<ImageKey, AsyncBufferedImage>()
{ {
@Override @Override
public AsyncBufferedImage load(ImageKey key) throws Exception public AsyncBufferedImage load(@NotNull ImageKey key) throws Exception
{ {
return loadImage(key.itemId, key.itemQuantity, key.stackable); return loadImage(key.itemId, key.itemQuantity, key.stackable);
} }
@@ -291,7 +292,7 @@ public class ItemManager
.build(new CacheLoader<Integer, ItemDefinition>() .build(new CacheLoader<Integer, ItemDefinition>()
{ {
@Override @Override
public ItemDefinition load(Integer key) throws Exception public ItemDefinition load(@NotNull Integer key) throws Exception
{ {
return client.getItemDefinition(key); return client.getItemDefinition(key);
} }
@@ -303,7 +304,7 @@ public class ItemManager
.build(new CacheLoader<OutlineKey, BufferedImage>() .build(new CacheLoader<OutlineKey, BufferedImage>()
{ {
@Override @Override
public BufferedImage load(OutlineKey key) throws Exception public BufferedImage load(@NotNull OutlineKey key) throws Exception
{ {
return loadItemOutline(key.itemId, key.itemQuantity, key.outlineColor); return loadItemOutline(key.itemId, key.itemQuantity, key.outlineColor);
} }
@@ -40,7 +40,7 @@ public class SkillIconManager
public BufferedImage getSkillImage(Skill skill, boolean small) public BufferedImage getSkillImage(Skill skill, boolean small)
{ {
int skillIdx = skill.ordinal() + (small ? Skill.values().length : 0); int skillIdx = skill.ordinal() + (small ? Skill.values().length : 0);
BufferedImage skillImage = null; BufferedImage skillImage;
if (imgCache[skillIdx] != null) if (imgCache[skillIdx] != null)
{ {
@@ -20,10 +20,10 @@ public enum Sound
RESTORED_SPECIAL_ATTACK(16, "net/runelite/client/game/sounds/restorespec.wav"), RESTORED_SPECIAL_ATTACK(16, "net/runelite/client/game/sounds/restorespec.wav"),
IDLE(17, "net/runelite/client/game/sounds/idle.wav"); IDLE(17, "net/runelite/client/game/sounds/idle.wav");
private String filePath; private final String filePath;
private int id; private final int id;
private Sound(int id, String filePath) Sound(int id, String filePath)
{ {
this.id = id; this.id = id;
this.filePath = filePath; this.filePath = filePath;
@@ -54,7 +54,7 @@ public class SpriteManager
@Inject @Inject
private ClientThread clientThread; private ClientThread clientThread;
public Cache<Long, BufferedImage> cache = CacheBuilder.newBuilder() private final Cache<Long, BufferedImage> cache = CacheBuilder.newBuilder()
.maximumSize(128L) .maximumSize(128L)
.expireAfterAccess(1, TimeUnit.HOURS) .expireAfterAccess(1, TimeUnit.HOURS)
.build(); .build();
@@ -110,12 +110,8 @@ public class SpriteManager
public void addSpriteTo(JButton c, int archive, int file) public void addSpriteTo(JButton c, int archive, int file)
{ {
getSpriteAsync(archive, file, img -> getSpriteAsync(archive, file, img ->
{
SwingUtilities.invokeLater(() -> SwingUtilities.invokeLater(() ->
{ c.setIcon(new ImageIcon(img))));
c.setIcon(new ImageIcon(img));
});
});
} }
/** /**
@@ -124,12 +120,8 @@ public class SpriteManager
public void addSpriteTo(JLabel c, int archive, int file) public void addSpriteTo(JLabel c, int archive, int file)
{ {
getSpriteAsync(archive, file, img -> getSpriteAsync(archive, file, img ->
{
SwingUtilities.invokeLater(() -> SwingUtilities.invokeLater(() ->
{ c.setIcon(new ImageIcon(img))));
c.setIcon(new ImageIcon(img));
});
});
} }
public void addSpriteOverrides(SpriteOverride[] add) public void addSpriteOverrides(SpriteOverride[] add)
@@ -27,13 +27,13 @@ package net.runelite.client.game.chatbox;
/** /**
* A modal input that lives in the chatbox panel. * A modal input that lives in the chatbox panel.
*/ */
public abstract class ChatboxInput abstract class ChatboxInput
{ {
protected void open() void open()
{ {
} }
protected void close() void close()
{ {
} }
} }
@@ -156,12 +156,12 @@ public class ChatboxTextInput extends ChatboxInput implements KeyListener, Mouse
return this; return this;
} }
public ChatboxTextInput cursorAt(int index) private ChatboxTextInput cursorAt(int index)
{ {
return cursorAt(index, index); return cursorAt(index, index);
} }
public ChatboxTextInput cursorAt(int indexA, int indexB) private ChatboxTextInput cursorAt(int indexA, int indexB)
{ {
if (indexA < 0) if (indexA < 0)
{ {
@@ -722,9 +722,6 @@ public class ChatboxTextInput extends ChatboxInput implements KeyListener, Mouse
newPos++; newPos++;
break; break;
case KeyEvent.VK_UP: case KeyEvent.VK_UP:
ev.consume();
newPos = getLineOffset.applyAsInt(code);
break;
case KeyEvent.VK_DOWN: case KeyEvent.VK_DOWN:
ev.consume(); ev.consume();
newPos = getLineOffset.applyAsInt(code); newPos = getLineOffset.applyAsInt(code);
@@ -27,6 +27,7 @@ package net.runelite.client.menus;
import joptsimple.internal.Strings; import joptsimple.internal.Strings;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
import net.runelite.api.MenuEntry; import net.runelite.api.MenuEntry;
import static net.runelite.client.menus.MenuManager.LEVEL_PATTERN; import static net.runelite.client.menus.MenuManager.LEVEL_PATTERN;
import net.runelite.client.util.Text; import net.runelite.client.util.Text;
@@ -52,6 +53,16 @@ public class ComparableEntry
@Getter @Getter
private boolean strictTarget; private boolean strictTarget;
/**
* If two entries are both suppose to be left click,
* the entry with the higher priority will be selected.
* This only effects left click priority entries.
*/
@Getter
@Setter
@EqualsAndHashCode.Exclude
private int priority;
public ComparableEntry(String option, String target) public ComparableEntry(String option, String target)
{ {
this(option, target, -1, -1, true, true); this(option, target, -1, -1, true, true);
@@ -70,6 +81,7 @@ public class ComparableEntry
this.type = type; this.type = type;
this.strictOption = strictOption; this.strictOption = strictOption;
this.strictTarget = strictTarget; this.strictTarget = strictTarget;
this.priority = 0;
} }
// This is only used for type checking, which is why it has everything but target // This is only used for type checking, which is why it has everything but target
@@ -80,6 +92,7 @@ public class ComparableEntry
this.id = e.getIdentifier(); this.id = e.getIdentifier();
this.type = e.getType(); this.type = e.getType();
this.strictOption = true; this.strictOption = true;
this.priority = 0;
} }
boolean matches(MenuEntry entry) boolean matches(MenuEntry entry)
@@ -31,17 +31,20 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
@@ -60,6 +63,7 @@ import net.runelite.api.events.NpcActionChanged;
import net.runelite.api.events.PlayerMenuOptionClicked; import net.runelite.api.events.PlayerMenuOptionClicked;
import net.runelite.api.events.PlayerMenuOptionsChanged; import net.runelite.api.events.PlayerMenuOptionsChanged;
import net.runelite.api.events.WidgetMenuOptionClicked; import net.runelite.api.events.WidgetMenuOptionClicked;
import net.runelite.api.events.WidgetPressed;
import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.EventBus;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
@@ -78,7 +82,6 @@ public class MenuManager
private final Client client; private final Client client;
private final EventBus eventBus; private final EventBus eventBus;
private final Prioritizer prioritizer;
//Maps the indexes that are being used to the menu option. //Maps the indexes that are being used to the menu option.
private final Map<Integer, String> playerMenuIndexMap = new HashMap<>(); private final Map<Integer, String> playerMenuIndexMap = new HashMap<>();
@@ -86,24 +89,23 @@ public class MenuManager
private final Multimap<Integer, WidgetMenuOption> managedMenuOptions = HashMultimap.create(); private final Multimap<Integer, WidgetMenuOption> managedMenuOptions = HashMultimap.create();
private final Set<String> npcMenuOptions = new HashSet<>(); private final Set<String> npcMenuOptions = new HashSet<>();
private final Set<ComparableEntry> priorityEntries = new HashSet<>(); private final HashSet<ComparableEntry> priorityEntries = new HashSet<>();
private final Set<MenuEntry> currentPriorityEntries = new HashSet<>(); private HashMap<MenuEntry, ComparableEntry> currentPriorityEntries = new HashMap<>();
private final Set<ComparableEntry> hiddenEntries = new HashSet<>(); private final ConcurrentHashMap<MenuEntry, ComparableEntry> safeCurrentPriorityEntries = new ConcurrentHashMap<>();
private final Set<MenuEntry> currentHiddenEntries = new HashSet<>(); private final HashSet<ComparableEntry> hiddenEntries = new HashSet<>();
private final Map<ComparableEntry, ComparableEntry> swaps = new HashMap<>(); private HashSet<MenuEntry> currentHiddenEntries = new HashSet<>();
private final Map<ComparableEntry, MenuEntry> currentSwaps = new HashMap<>(); private final HashMap<ComparableEntry, ComparableEntry> swaps = new HashMap<>();
private final LinkedHashSet<MenuEntry> entries = Sets.newLinkedHashSet(); private final LinkedHashSet<MenuEntry> entries = Sets.newLinkedHashSet();
private MenuEntry leftClickEntry = null; private MenuEntry leftClickEntry = null;
private int leftClickType = -1; private MenuEntry firstEntry = null;
@Inject @Inject
private MenuManager(Client client, EventBus eventBus) private MenuManager(Client client, EventBus eventBus)
{ {
this.client = client; this.client = client;
this.eventBus = eventBus; this.eventBus = eventBus;
this.prioritizer = new Prioritizer();
} }
/** /**
@@ -147,22 +149,11 @@ public class MenuManager
public void onMenuOpened(MenuOpened event) public void onMenuOpened(MenuOpened event)
{ {
currentPriorityEntries.clear(); currentPriorityEntries.clear();
currentHiddenEntries.clear();
// Need to reorder the list to normal, then rebuild with swaps // Need to reorder the list to normal, then rebuild with swaps
MenuEntry[] oldEntries = event.getMenuEntries(); MenuEntry[] oldEntries = event.getMenuEntries();
for (MenuEntry entry : oldEntries) firstEntry = null;
{
if (entry == leftClickEntry)
{
entry.setType(leftClickType);
break;
}
}
leftClickEntry = null;
leftClickType = -1;
client.sortMenuEntries(); client.sortMenuEntries();
@@ -192,7 +183,7 @@ public class MenuManager
{ {
shouldDeprioritize = true; shouldDeprioritize = true;
} }
currentPriorityEntries.add(entry); currentPriorityEntries.put(entry, p);
newEntries.remove(entry); newEntries.remove(entry);
continue prioritizer; continue prioritizer;
} }
@@ -221,8 +212,8 @@ public class MenuManager
} }
} }
// Do not need to swap with itself // Do not need to swap with itself or if the swapFrom is already the first entry
if (swapFrom != null && swapFrom != entry) if (swapFrom != null && swapFrom != entry && swapFrom != Iterables.getLast(newEntries))
{ {
// Deprioritize entries if the swaps are not in similar type groups // Deprioritize entries if the swaps are not in similar type groups
if ((swapFrom.getType() >= 1000 && entry.getType() < 1000) || (entry.getType() >= 1000 && swapFrom.getType() < 1000) && !shouldDeprioritize) if ((swapFrom.getType() >= 1000 && entry.getType() < 1000) || (entry.getType() >= 1000 && swapFrom.getType() < 1000) && !shouldDeprioritize)
@@ -250,12 +241,19 @@ public class MenuManager
} }
} }
if (!priorityEntries.isEmpty()) if (!currentPriorityEntries.isEmpty())
{ {
newEntries.addAll(currentPriorityEntries); newEntries.addAll(currentPriorityEntries.entrySet().stream()
.sorted(Comparator.comparingInt(e -> e.getValue().getPriority()))
.map(Map.Entry::getKey)
.collect(Collectors.toList()));
} }
event.setMenuEntries(newEntries.toArray(new MenuEntry[0])); MenuEntry[] arrayEntries = newEntries.toArray(new MenuEntry[0]);
// Need to set the event entries to prevent conflicts
event.setMenuEntries(arrayEntries);
client.setMenuEntries(arrayEntries);
} }
@Subscribe @Subscribe
@@ -282,77 +280,63 @@ public class MenuManager
} }
} }
@Subscribe @Subscribe
public void onBeforeRender(BeforeRender event) public void onBeforeRender(BeforeRender event)
{ {
leftClickEntry = null; rebuildLeftClickMenu();
leftClickType = -1; }
private MenuEntry rebuildLeftClickMenu()
{
if (client.isMenuOpen()) if (client.isMenuOpen())
{ {
return; return null;
} }
firstEntry = null;
entries.clear(); entries.clear();
entries.addAll(Arrays.asList(client.getMenuEntries())); entries.addAll(Arrays.asList(client.getMenuEntries()));
if (entries.size() < 2) if (entries.size() < 2)
{ {
return; return null;
} }
currentPriorityEntries.clear(); if (!hiddenEntries.isEmpty())
currentHiddenEntries.clear();
currentSwaps.clear();
prioritizer.prioritize();
while (prioritizer.isRunning())
{ {
// wait currentHiddenEntries.clear();
} indexHiddenEntries(entries);
entries.removeAll(currentHiddenEntries); if (!currentHiddenEntries.isEmpty())
for (MenuEntry entry : currentPriorityEntries)
{
if (entries.contains(entry))
{ {
leftClickEntry = entry; entries.removeAll(currentHiddenEntries);
leftClickType = entry.getType();
entries.remove(leftClickEntry);
leftClickEntry.setType(MenuAction.WIDGET_DEFAULT.getId());
entries.add(leftClickEntry);
break;
} }
} }
if (!priorityEntries.isEmpty())
if (leftClickEntry == null)
{ {
MenuEntry first = Iterables.getLast(entries); indexPriorityEntries(entries);
}
for (ComparableEntry swap : currentSwaps.keySet()) if (firstEntry == null && !swaps.isEmpty())
{ {
if (swap.matches(first)) indexSwapEntries(entries);
{ }
leftClickEntry = currentSwaps.get(swap);
leftClickType = leftClickEntry.getType(); if (firstEntry != null)
entries.remove(leftClickEntry); {
leftClickEntry.setType(MenuAction.WIDGET_DEFAULT.getId()); entries.remove(firstEntry);
entries.add(leftClickEntry); entries.add(firstEntry);
break; }
} else if (!currentHiddenEntries.isEmpty())
} {
firstEntry = Iterables.getLast(entries, null);
} }
client.setMenuEntries(entries.toArray(new MenuEntry[0])); client.setMenuEntries(entries.toArray(new MenuEntry[0]));
}
return firstEntry;
}
public void addPlayerMenuItem(String menuText) public void addPlayerMenuItem(String menuText)
{ {
@@ -455,14 +439,29 @@ public class MenuManager
} }
} }
@Subscribe
public void onWidgetPressed(WidgetPressed event)
{
leftClickEntry = rebuildLeftClickMenu();
}
@Subscribe @Subscribe
public void onMenuOptionClicked(MenuOptionClicked event) public void onMenuOptionClicked(MenuOptionClicked event)
{ {
if (leftClickEntry != null && leftClickType != -1) if (!client.isMenuOpen() && event.isAuthentic())
{ {
leftClickEntry.setType(leftClickType); // The mouse button will not be 0 if a non draggable widget was clicked,
event.setMenuEntry(leftClickEntry); // otherwise the left click entry will have been set in onWidgetPressed
leftClickEntry = null; if (client.getMouseCurrentButton() != 0)
{
leftClickEntry = rebuildLeftClickMenu();
}
if (leftClickEntry != null)
{
event.setMenuEntry(leftClickEntry);
leftClickEntry = null;
}
} }
if (event.getMenuAction() != MenuAction.RUNELITE) if (event.getMenuAction() != MenuAction.RUNELITE)
@@ -534,7 +533,7 @@ public class MenuManager
/** /**
* Adds to the set of menu entries which when present, will remove all entries except for this one * Adds to the set of menu entries which when present, will remove all entries except for this one
*/ */
public void addPriorityEntry(String option, String target) public ComparableEntry addPriorityEntry(String option, String target)
{ {
option = Text.standardize(option); option = Text.standardize(option);
target = Text.standardize(target); target = Text.standardize(target);
@@ -542,6 +541,8 @@ public class MenuManager
ComparableEntry entry = new ComparableEntry(option, target); ComparableEntry entry = new ComparableEntry(option, target);
priorityEntries.add(entry); priorityEntries.add(entry);
return entry;
} }
public void removePriorityEntry(String option, String target) public void removePriorityEntry(String option, String target)
@@ -559,13 +560,15 @@ public class MenuManager
* Adds to the set of menu entries which when present, will remove all entries except for this one * Adds to the set of menu entries which when present, will remove all entries except for this one
* This method will add one with strict option, but not-strict target (contains for target, equals for option) * This method will add one with strict option, but not-strict target (contains for target, equals for option)
*/ */
public void addPriorityEntry(String option) public ComparableEntry addPriorityEntry(String option)
{ {
option = Text.standardize(option); option = Text.standardize(option);
ComparableEntry entry = new ComparableEntry(option, "", false); ComparableEntry entry = new ComparableEntry(option, "", false);
priorityEntries.add(entry); priorityEntries.add(entry);
return entry;
} }
public void removePriorityEntry(String option) public void removePriorityEntry(String option)
@@ -789,115 +792,67 @@ public class MenuManager
hiddenEntries.remove(entry); hiddenEntries.remove(entry);
} }
private class Prioritizer private void indexHiddenEntries(Set<MenuEntry> entries)
{ {
private MenuEntry[] entries; currentHiddenEntries = entries.parallelStream().filter(entry ->
private AtomicInteger state = new AtomicInteger(0);
boolean isRunning()
{ {
return state.get() != 0; for (ComparableEntry p : hiddenEntries)
} {
if (p.matches(entry))
{
return true;
}
}
return false;
}).collect(Collectors.toCollection(HashSet::new));
}
void prioritize() // This could use some optimization
private void indexPriorityEntries(Set<MenuEntry> entries)
{
safeCurrentPriorityEntries.clear();
entries.parallelStream().forEach(entry ->
{ {
if (state.get() != 0) for (ComparableEntry p : priorityEntries)
{ {
return; if (p.matches(entry))
{
safeCurrentPriorityEntries.put(entry, p);
break;
}
} }
});
entries = client.getMenuEntries(); firstEntry = Iterables.getLast(safeCurrentPriorityEntries.entrySet().stream()
.sorted(Comparator.comparingInt(e -> e.getValue().getPriority()))
.map(Map.Entry::getKey)
.collect(Collectors.toList()), null);
}
state.set(3); private void indexSwapEntries(Set<MenuEntry> entries)
{
MenuEntry first = Iterables.getLast(entries);
if (!hiddenEntries.isEmpty()) List<ComparableEntry> values = new ArrayList<>();
{
hiddenFinder.run();
}
else
{
state.decrementAndGet();
}
if (!priorityEntries.isEmpty()) for (Map.Entry<ComparableEntry, ComparableEntry> pair : swaps.entrySet())
{
if (pair.getKey().matches(first))
{ {
priorityFinder.run(); values.add(pair.getValue());
}
else
{
state.decrementAndGet();
}
if (!swaps.isEmpty())
{
swapFinder.run();
}
else
{
state.decrementAndGet();
} }
} }
private Thread hiddenFinder = new Thread() firstEntry = entries.parallelStream().filter(entry ->
{ {
@Override for (ComparableEntry value : values)
public void run()
{ {
Arrays.stream(entries).parallel().forEach(entry -> if (value.matches(entry))
{ {
for (ComparableEntry p : hiddenEntries) return true;
{ }
if (p.matches(entry))
{
currentHiddenEntries.add(entry);
return;
}
}
});
state.decrementAndGet();
} }
}; return false;
}).findFirst().orElse(null);
private Thread priorityFinder = new Thread()
{
@Override
public void run()
{
Arrays.stream(entries).parallel().forEach(entry ->
{
for (ComparableEntry p : priorityEntries)
{
if (p.matches(entry))
{
currentPriorityEntries.add(entry);
return;
}
}
});
state.decrementAndGet();
}
};
private Thread swapFinder = new Thread()
{
@Override
public void run()
{
Arrays.stream(entries).parallel().forEach(entry ->
{
for (Map.Entry<ComparableEntry, ComparableEntry> p : swaps.entrySet())
{
if (p.getValue().matches(entry))
{
currentSwaps.put(p.getKey(), entry);
return;
}
}
});
state.decrementAndGet();
}
};
} }
} }
@@ -43,11 +43,16 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.inject.Inject; import javax.inject.Inject;
@@ -228,7 +233,6 @@ public class PluginManager
.directed() .directed()
.build(); .build();
List<Plugin> scannedPlugins = new ArrayList<>();
ClassPath classPath = ClassPath.from(classLoader); ClassPath classPath = ClassPath.from(classLoader);
ImmutableSet<ClassInfo> classes = packageName == null ? classPath.getAllClasses() ImmutableSet<ClassInfo> classes = packageName == null ? classPath.getAllClasses()
@@ -285,24 +289,47 @@ public class PluginManager
throw new RuntimeException("Plugin dependency graph contains a cycle!"); throw new RuntimeException("Plugin dependency graph contains a cycle!");
} }
List<Class<? extends Plugin>> sortedPlugins = topologicalSort(graph); List<List<Class<? extends Plugin>>> sortedPlugins = topologicalGroupSort(graph);
sortedPlugins = Lists.reverse(sortedPlugins); sortedPlugins = Lists.reverse(sortedPlugins);
for (Class<? extends Plugin> pluginClazz : sortedPlugins) final long start = System.currentTimeMillis();
{
Plugin plugin;
try
{
plugin = instantiate(scannedPlugins, (Class<Plugin>) pluginClazz);
}
catch (PluginInstantiationException ex)
{
log.warn("Error instantiating plugin!", ex);
continue;
}
scannedPlugins.add(plugin); // some plugins get stuck on IO, so add some extra threads
} ExecutorService exec = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
List<Plugin> scannedPlugins = new CopyOnWriteArrayList<>();
sortedPlugins.forEach(group ->
{
List<Future<?>> curGroup = new ArrayList<>();
group.forEach(pluginClazz ->
curGroup.add(exec.submit(() ->
{
Plugin plugin;
try
{
plugin = instantiate(scannedPlugins, (Class<Plugin>) pluginClazz);
}
catch (PluginInstantiationException e)
{
log.warn("Error instantiating plugin!", e);
return;
}
scannedPlugins.add(plugin);
})));
curGroup.forEach(future ->
{
try
{
future.get();
}
catch (InterruptedException | ExecutionException e)
{
e.printStackTrace();
}
});
});
log.info("Plugin instantiation took {}ms", System.currentTimeMillis() - start);
return scannedPlugins; return scannedPlugins;
} }
@@ -515,40 +542,54 @@ public class PluginManager
} }
/** /**
* Topologically sort a graph. Uses Kahn's algorithm. * Topologically sort a graph into separate groups.
* * Each group represents the dependency level of the plugins.
* Plugins in group (index) 0 has no dependents.
* Plugins in group 1 has dependents in group 0.
* Plugins in group 2 has dependents in group 1, etc.
* This allows for loading dependent groups serially, starting from the last group,
* while loading plugins within each group in parallel.
* @param graph * @param graph
* @param <T> * @param <T>
* @return * @return
*/ */
private <T> List<T> topologicalSort(Graph<T> graph) private <T> List<List<T>> topologicalGroupSort(Graph<T> graph)
{ {
MutableGraph<T> graphCopy = Graphs.copyOf(graph); final Set<T> root = graph.nodes().stream()
List<T> l = new ArrayList<>(); .filter(node -> graph.inDegree(node) == 0)
Set<T> s = graphCopy.nodes().stream()
.filter(node -> graphCopy.inDegree(node) == 0)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
while (!s.isEmpty()) final Map<T, Integer> dependencyCount = new HashMap<>();
{
Iterator<T> it = s.iterator();
T n = it.next();
it.remove();
l.add(n); root.forEach(n -> dependencyCount.put(n, 0));
root.forEach(n -> graph.successors(n)
.forEach(m -> incrementChildren(graph, dependencyCount, m, dependencyCount.get(n) + 1)));
for (T m : graphCopy.successors(n)) // create list<list> dependency grouping
final List<List<T>> dependencyGroups = new ArrayList<>();
final int[] curGroup = {-1};
dependencyCount.entrySet().stream()
.sorted(Map.Entry.comparingByValue())
.forEach(entry ->
{ {
graphCopy.removeEdge(n, m); if (entry.getValue() != curGroup[0])
if (graphCopy.inDegree(m) == 0)
{ {
s.add(m); curGroup[0] = entry.getValue();
dependencyGroups.add(new ArrayList<>());
} }
} dependencyGroups.get(dependencyGroups.size() - 1).add(entry.getKey());
} });
if (!graphCopy.edges().isEmpty())
return dependencyGroups;
}
private <T> void incrementChildren(Graph<T> graph, Map<T, Integer> dependencyCount, T n, int val)
{
if (!dependencyCount.containsKey(n) || dependencyCount.get(n) < val)
{ {
throw new RuntimeException("Graph has at least one cycle"); dependencyCount.put(n, val);
graph.successors(n).forEach(m ->
incrementChildren(graph, dependencyCount, m, val + 1));
} }
return l;
} }
} }
@@ -45,7 +45,7 @@ import lombok.extern.slf4j.Slf4j;
import net.runelite.client.RuneLite; import net.runelite.client.RuneLite;
import net.runelite.client.config.Config; import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.config.RuneLitePlusConfig;
@Singleton @Singleton
@Slf4j @Slf4j
@@ -53,7 +53,7 @@ public class PluginWatcher extends Thread
{ {
private static final File BASE = RuneLite.PLUGIN_DIR; private static final File BASE = RuneLite.PLUGIN_DIR;
private final RuneLiteConfig runeliteConfig; private final RuneLitePlusConfig runelitePlusConfig;
private final PluginManager pluginManager; private final PluginManager pluginManager;
private final WatchService watchService; private final WatchService watchService;
private final WatchKey watchKey; private final WatchKey watchKey;
@@ -62,9 +62,9 @@ public class PluginWatcher extends Thread
private ConfigManager configManager; private ConfigManager configManager;
@Inject @Inject
public PluginWatcher(RuneLiteConfig runeliteConfig, PluginManager pluginManager) throws IOException public PluginWatcher(RuneLitePlusConfig runelitePlusConfig, PluginManager pluginManager) throws IOException
{ {
this.runeliteConfig = runeliteConfig; this.runelitePlusConfig = runelitePlusConfig;
this.pluginManager = pluginManager; this.pluginManager = pluginManager;
setName("Plugin Watcher"); setName("Plugin Watcher");
@@ -84,7 +84,7 @@ public class PluginWatcher extends Thread
@Override @Override
public void run() public void run()
{ {
if (runeliteConfig.enablePlugins()) if (runelitePlusConfig.enablePlugins())
{ {
scan(); scan();
} }
@@ -96,7 +96,7 @@ public class PluginWatcher extends Thread
WatchKey key = watchService.take(); WatchKey key = watchService.take();
Thread.sleep(50); Thread.sleep(50);
if (!runeliteConfig.enablePlugins()) if (!runelitePlusConfig.enablePlugins())
{ {
key.reset(); key.reset();
continue; continue;
@@ -27,6 +27,7 @@ package net.runelite.client.plugins.account;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.client.account.AccountSession; import net.runelite.client.account.AccountSession;
@@ -47,6 +48,7 @@ import net.runelite.client.util.ImageUtil;
loadWhenOutdated = true loadWhenOutdated = true
) )
@Slf4j @Slf4j
@Singleton
public class AccountPlugin extends Plugin public class AccountPlugin extends Plugin
{ {
@Inject @Inject
@@ -32,6 +32,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.FontTypeFace; import net.runelite.api.FontTypeFace;
@@ -66,6 +67,7 @@ import net.runelite.client.util.Text;
description = "Display level requirements in Achievement Diary interface", description = "Display level requirements in Achievement Diary interface",
tags = {"achievements", "tasks"} tags = {"achievements", "tasks"}
) )
@Singleton
public class DiaryRequirementsPlugin extends Plugin public class DiaryRequirementsPlugin extends Plugin
{ {
private static final String AND_JOINER = ", "; private static final String AND_JOINER = ", ";
@@ -122,10 +124,6 @@ public class DiaryRequirementsPlugin extends Plugin
} }
Map<String, String> skillRequirements = buildRequirements(requirements.getRequirements()); Map<String, String> skillRequirements = buildRequirements(requirements.getRequirements());
if (skillRequirements == null)
{
return;
}
int offset = 0; int offset = 0;
String taskBuffer = ""; String taskBuffer = "";
@@ -32,6 +32,7 @@ import java.awt.Polygon;
import java.awt.geom.Area; import java.awt.geom.Area;
import java.util.List; import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.Point; import net.runelite.api.Point;
import net.runelite.api.Tile; import net.runelite.api.Tile;
@@ -42,23 +43,23 @@ import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayUtil; import net.runelite.client.ui.overlay.OverlayUtil;
@Singleton
class AgilityOverlay extends Overlay class AgilityOverlay extends Overlay
{ {
private static final int MAX_DISTANCE = 2350;
private static final Color SHORTCUT_HIGH_LEVEL_COLOR = Color.ORANGE; private static final Color SHORTCUT_HIGH_LEVEL_COLOR = Color.ORANGE;
private final Client client; private final Client client;
private final AgilityPlugin plugin; private final AgilityPlugin plugin;
private final AgilityConfig config;
@Inject @Inject
private AgilityOverlay(Client client, AgilityPlugin plugin, AgilityConfig config) private AgilityOverlay(final Client client, final AgilityPlugin plugin)
{ {
super(plugin); super(plugin);
setPosition(OverlayPosition.DYNAMIC); setPosition(OverlayPosition.DYNAMIC);
setLayer(OverlayLayer.ABOVE_SCENE); setLayer(OverlayLayer.ABOVE_SCENE);
this.client = client; this.client = client;
this.plugin = plugin; this.plugin = plugin;
this.config = config;
} }
@Override @Override
@@ -69,14 +70,15 @@ class AgilityOverlay extends Overlay
final List<Tile> marksOfGrace = plugin.getMarksOfGrace(); final List<Tile> marksOfGrace = plugin.getMarksOfGrace();
plugin.getObstacles().forEach((object, obstacle) -> plugin.getObstacles().forEach((object, obstacle) ->
{ {
if (Obstacles.SHORTCUT_OBSTACLE_IDS.containsKey(object.getId()) && !config.highlightShortcuts() || if (Obstacles.SHORTCUT_OBSTACLE_IDS.containsKey(object.getId()) && !plugin.isHighlightShortcuts() ||
Obstacles.TRAP_OBSTACLE_IDS.contains(object.getId()) && !config.showTrapOverlay()) Obstacles.TRAP_OBSTACLE_IDS.contains(object.getId()) && !plugin.isShowTrapOverlay())
{ {
return; return;
} }
Tile tile = obstacle.getTile(); Tile tile = obstacle.getTile();
if (tile.getPlane() == client.getPlane()) if (tile.getPlane() == client.getPlane()
&& object.getLocalLocation().distanceTo(playerLocation) < MAX_DISTANCE)
{ {
// This assumes that the obstacle is not clickable. // This assumes that the obstacle is not clickable.
if (Obstacles.TRAP_OBSTACLE_IDS.contains(object.getId())) if (Obstacles.TRAP_OBSTACLE_IDS.contains(object.getId()))
@@ -84,7 +86,7 @@ class AgilityOverlay extends Overlay
Polygon polygon = object.getCanvasTilePoly(); Polygon polygon = object.getCanvasTilePoly();
if (polygon != null) if (polygon != null)
{ {
OverlayUtil.renderPolygon(graphics, polygon, config.getTrapColor()); OverlayUtil.renderPolygon(graphics, polygon, plugin.getTrapColor());
} }
return; return;
} }
@@ -92,10 +94,10 @@ class AgilityOverlay extends Overlay
if (objectClickbox != null) if (objectClickbox != null)
{ {
AgilityShortcut agilityShortcut = obstacle.getShortcut(); AgilityShortcut agilityShortcut = obstacle.getShortcut();
Color configColor = agilityShortcut == null || agilityShortcut.getLevel() <= plugin.getAgilityLevel() ? config.getOverlayColor() : SHORTCUT_HIGH_LEVEL_COLOR; Color configColor = agilityShortcut == null || agilityShortcut.getLevel() <= plugin.getAgilityLevel() ? plugin.getOverlayColor() : SHORTCUT_HIGH_LEVEL_COLOR;
if (config.highlightMarks() && !marksOfGrace.isEmpty()) if (plugin.isHighlightMarks() && !marksOfGrace.isEmpty())
{ {
configColor = config.getMarkColor(); configColor = plugin.getMarkColor();
} }
if (objectClickbox.contains(mousePosition.getX(), mousePosition.getY())) if (objectClickbox.contains(mousePosition.getX(), mousePosition.getY()))
@@ -115,11 +117,12 @@ class AgilityOverlay extends Overlay
}); });
if (config.highlightMarks() && !marksOfGrace.isEmpty()) if (plugin.isHighlightMarks() && !marksOfGrace.isEmpty())
{ {
for (Tile markOfGraceTile : marksOfGrace) for (Tile markOfGraceTile : marksOfGrace)
{ {
if (markOfGraceTile.getPlane() == client.getPlane() && markOfGraceTile.getItemLayer() != null) if (markOfGraceTile.getPlane() == client.getPlane() && markOfGraceTile.getItemLayer() != null
&& markOfGraceTile.getLocalLocation().distanceTo(playerLocation) < MAX_DISTANCE)
{ {
final Polygon poly = markOfGraceTile.getItemLayer().getCanvasTilePoly(); final Polygon poly = markOfGraceTile.getItemLayer().getCanvasTilePoly();
@@ -128,7 +131,7 @@ class AgilityOverlay extends Overlay
continue; continue;
} }
OverlayUtil.renderPolygon(graphics, poly, config.getMarkColor()); OverlayUtil.renderPolygon(graphics, poly, plugin.getMarkColor());
} }
} }
} }
@@ -32,6 +32,8 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton;
import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client; import net.runelite.api.Client;
@@ -83,14 +85,15 @@ import net.runelite.client.util.ColorUtil;
tags = {"grace", "marks", "overlay", "shortcuts", "skilling", "traps"} tags = {"grace", "marks", "overlay", "shortcuts", "skilling", "traps"}
) )
@Slf4j @Slf4j
@Singleton
public class AgilityPlugin extends Plugin public class AgilityPlugin extends Plugin
{ {
private static final int AGILITY_ARENA_REGION_ID = 11157; private static final int AGILITY_ARENA_REGION_ID = 11157;
@Getter @Getter(AccessLevel.PACKAGE)
private final Map<TileObject, Obstacle> obstacles = new HashMap<>(); private final Map<TileObject, Obstacle> obstacles = new HashMap<>();
@Getter @Getter(AccessLevel.PACKAGE)
private final List<Tile> marksOfGrace = new ArrayList<>(); private final List<Tile> marksOfGrace = new ArrayList<>();
@Inject @Inject
@@ -117,13 +120,13 @@ public class AgilityPlugin extends Plugin
@Inject @Inject
private ItemManager itemManager; private ItemManager itemManager;
@Getter @Getter(AccessLevel.PACKAGE)
private AgilitySession session; private AgilitySession session;
private int lastAgilityXp; private int lastAgilityXp;
private WorldPoint lastArenaTicketPosition; private WorldPoint lastArenaTicketPosition;
@Getter @Getter(AccessLevel.PACKAGE)
private int agilityLevel; private int agilityLevel;
@Provides @Provides
@@ -132,9 +135,36 @@ public class AgilityPlugin extends Plugin
return configManager.getConfig(AgilityConfig.class); return configManager.getConfig(AgilityConfig.class);
} }
// Config values
@Getter(AccessLevel.PACKAGE)
private boolean showLapCount;
@Getter(AccessLevel.PACKAGE)
private int lapTimeout;
@Getter(AccessLevel.PACKAGE)
private boolean lapsToLevel;
@Getter(AccessLevel.PACKAGE)
private boolean lapsToGoal;
@Getter(AccessLevel.PACKAGE)
private Color overlayColor;
@Getter(AccessLevel.PACKAGE)
private boolean highlightMarks;
@Getter(AccessLevel.PACKAGE)
private Color markColor;
@Getter(AccessLevel.PACKAGE)
private boolean highlightShortcuts;
@Getter(AccessLevel.PACKAGE)
private boolean showTrapOverlay;
@Getter(AccessLevel.PACKAGE)
private Color trapColor;
private boolean notifyAgilityArena;
private boolean showAgilityArenaTimer;
private boolean showShortcutLevel;
@Override @Override
protected void startUp() throws Exception protected void startUp() throws Exception
{ {
updateConfig();
overlayManager.add(agilityOverlay); overlayManager.add(agilityOverlay);
overlayManager.add(lapCounterOverlay); overlayManager.add(lapCounterOverlay);
agilityLevel = client.getBoostedSkillLevel(Skill.AGILITY); agilityLevel = client.getBoostedSkillLevel(Skill.AGILITY);
@@ -179,16 +209,40 @@ public class AgilityPlugin extends Plugin
@Subscribe @Subscribe
public void onConfigChanged(ConfigChanged event) public void onConfigChanged(ConfigChanged event)
{ {
if (!config.showAgilityArenaTimer()) if (!event.getGroup().equals("agility"))
{
return;
}
updateConfig();
if (!this.showAgilityArenaTimer)
{ {
removeAgilityArenaTimer(); removeAgilityArenaTimer();
} }
} }
public void updateConfig()
{
this.showLapCount = config.showLapCount();
this.lapTimeout = config.lapTimeout();
this.lapsToLevel = config.lapsToLevel();
this.lapsToGoal = config.lapsToGoal();
this.overlayColor = config.getOverlayColor();
this.highlightMarks = config.highlightMarks();
this.markColor = config.getMarkColor();
this.highlightShortcuts = config.highlightShortcuts();
this.showTrapOverlay = config.showTrapOverlay();
this.trapColor = config.getTrapColor();
this.notifyAgilityArena = config.notifyAgilityArena();
this.showAgilityArenaTimer = config.showAgilityArenaTimer();
this.showShortcutLevel = config.showShortcutLevel();
}
@Subscribe @Subscribe
public void onExperienceChanged(ExperienceChanged event) public void onExperienceChanged(ExperienceChanged event)
{ {
if (event.getSkill() != AGILITY || !config.showLapCount()) if (event.getSkill() != AGILITY || !this.showLapCount)
{ {
return; return;
} }
@@ -272,12 +326,12 @@ public class AgilityPlugin extends Plugin
{ {
log.debug("Ticked position moved from {} to {}", oldTickPosition, newTicketPosition); log.debug("Ticked position moved from {} to {}", oldTickPosition, newTicketPosition);
if (config.notifyAgilityArena()) if (this.notifyAgilityArena)
{ {
notifier.notify("Ticket location changed"); notifier.notify("Ticket location changed");
} }
if (config.showAgilityArenaTimer()) if (this.showAgilityArenaTimer)
{ {
showNewAgilityArenaTimer(); showNewAgilityArenaTimer();
} }
@@ -430,7 +484,7 @@ public class AgilityPlugin extends Plugin
@Subscribe @Subscribe
public void onMenuEntryAdded(MenuEntryAdded event) public void onMenuEntryAdded(MenuEntryAdded event)
{ {
if (!config.showShortcutLevel()) if (!this.showShortcutLevel)
{ {
return; return;
} }
@@ -42,7 +42,7 @@ class AgilitySession
private int lapsTillLevel; private int lapsTillLevel;
private int lapsTillGoal; private int lapsTillGoal;
AgilitySession(Courses course) AgilitySession(final Courses course)
{ {
this.course = course; this.course = course;
} }
@@ -26,6 +26,7 @@ package net.runelite.client.plugins.agility;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import java.util.Map; import java.util.Map;
import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import net.runelite.api.coords.WorldPoint; import net.runelite.api.coords.WorldPoint;
@@ -50,16 +51,16 @@ enum Courses
private final static Map<Integer, Courses> coursesByRegion; private final static Map<Integer, Courses> coursesByRegion;
@Getter @Getter(AccessLevel.PACKAGE)
private final double totalXp; private final double totalXp;
@Getter @Getter(AccessLevel.PACKAGE)
private final int lastObstacleXp; private final int lastObstacleXp;
@Getter @Getter(AccessLevel.PACKAGE)
private final int regionId; private final int regionId;
@Getter @Getter(AccessLevel.PACKAGE)
private final WorldPoint[] courseEndWorldPoints; private final WorldPoint[] courseEndWorldPoints;
static static

Some files were not shown because too many files have changed in this diff Show More