Merge remote-tracking branch 'upstream/master' into slayer-v2

This commit is contained in:
Owain van Brakel
2019-07-26 00:59:39 +02:00
124 changed files with 1681 additions and 843 deletions
+3 -1
View File
@@ -12,7 +12,7 @@ allprojects {
gradle.projectsEvaluated { gradle.projectsEvaluated {
tasks.withType(JavaCompile) { tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint:deprecation" options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
} }
} }
} }
@@ -39,8 +39,10 @@ subprojects {
toolVersion = '6.4.1' toolVersion = '6.4.1'
sourceSets = [sourceSets.main] sourceSets = [sourceSets.main]
configFile = rootProject.file("./checkstyle/checkstyle.xml") configFile = rootProject.file("./checkstyle/checkstyle.xml")
configProperties = [ "suppressionFile" : rootProject.file("./checkstyle/suppressions.xml")]
showViolations = true showViolations = true
ignoreFailures = false ignoreFailures = false
maxWarnings = 0
} }
} }
@@ -56,7 +56,7 @@ public class ScriptLoader
int numSwitches = in.readUnsignedByte(); int numSwitches = in.readUnsignedByte();
if (numSwitches > 0) if (numSwitches > 0)
{ {
Map<Integer, Integer>[] switches = new Map[numSwitches]; @SuppressWarnings("unchecked") Map<Integer, Integer>[] switches = new Map[numSwitches];
def.setSwitches(switches); def.setSwitches(switches);
for (int i = 0; i < numSwitches; ++i) for (int i = 0; i < numSwitches; ++i)
@@ -36,6 +36,7 @@ import net.runelite.cache.region.Position;
public class WorldMapLoader public class WorldMapLoader
{ {
@SuppressWarnings("unchecked")
public WorldMapDefinition load(byte[] b, int fileId) public WorldMapDefinition load(byte[] b, int fileId)
{ {
WorldMapDefinition def = new WorldMapDefinition(); WorldMapDefinition def = new WorldMapDefinition();
@@ -29,7 +29,7 @@ import java.io.InputStream;
import net.runelite.cache.definitions.ScriptDefinition; import net.runelite.cache.definitions.ScriptDefinition;
import net.runelite.cache.script.Instructions; import net.runelite.cache.script.Instructions;
import net.runelite.cache.script.assembler.rs2asmParser.ProgContext; import net.runelite.cache.script.assembler.rs2asmParser.ProgContext;
import org.antlr.v4.runtime.ANTLRInputStream; import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTreeWalker; import org.antlr.v4.runtime.tree.ParseTreeWalker;
@@ -45,7 +45,7 @@ public class Assembler
public ScriptDefinition assemble(InputStream in) throws IOException public ScriptDefinition assemble(InputStream in) throws IOException
{ {
// Get our lexer // Get our lexer
rs2asmLexer lexer = new rs2asmLexer(new ANTLRInputStream(in)); rs2asmLexer lexer = new rs2asmLexer(CharStreams.fromStream(in));
LexerErrorListener errorListener = new LexerErrorListener(); LexerErrorListener errorListener = new LexerErrorListener();
lexer.addErrorListener(errorListener); lexer.addErrorListener(errorListener);
@@ -259,7 +259,7 @@ public class ScriptWriter extends rs2asmBaseListener
} }
int index = 0; int index = 0;
Map<Integer, Integer>[] maps = new Map[count]; @SuppressWarnings("unchecked") Map<Integer, Integer>[] maps = new Map[count];
for (LookupSwitch lswitch : switches) for (LookupSwitch lswitch : switches)
{ {
if (lswitch == null) if (lswitch == null)
@@ -24,6 +24,7 @@
*/ */
package net.runelite.cache; package net.runelite.cache;
import com.google.common.io.FileWriteMode;
import com.google.common.io.Files; import com.google.common.io.Files;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
@@ -81,7 +82,7 @@ public class SoundEffectsDumperTest
SoundEffectTrackLoader setLoader = new SoundEffectTrackLoader(); SoundEffectTrackLoader setLoader = new SoundEffectTrackLoader();
SoundEffectTrackDefinition soundEffect = setLoader.load(contents); SoundEffectTrackDefinition soundEffect = setLoader.load(contents);
Files.write(gson.toJson(soundEffect), new File(dumpDir, archive.getArchiveId() + ".json"), Charset.defaultCharset()); Files.asCharSink(new File(dumpDir, archive.getArchiveId() + ".json"), Charset.defaultCharset()).write(gson.toJson(soundEffect));
++count; ++count;
} }
} }
-63
View File
@@ -1,63 +0,0 @@
<?xml version="1.0"?>
<!--
Copyright (c) 2017, Adam <Adam@sigterm.info>
Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<!DOCTYPE module PUBLIC
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">
<module name="Checker">
<module name="TreeWalker">
<module name="LeftCurly">
<property name="option" value="nl"/>
</module>
<module name="RightCurly">
<property name="option" value="alone"/>
</module>
<!-- require tabs for indenting - https://stackoverflow.com/a/28550141 -->
<module name="RegexpSinglelineJava">
<property name="format" value="^\t* "/>
<property name="message" value="Indent must use tab characters"/>
<property name="ignoreComments" value="true"/>
</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="WhitespaceAfter">
<property name="tokens" value="COMMA"/>
</module>
<module name="UnusedImports"/>
<module name="SuppressionCommentFilter"/>
</module>
<module name="RegexpMultiline">
<property name="format" value="else[ \t]*[\r\n]+[ \t]*if"/>
<property name="message" value="Newline should not be between else and if"/>
</module>
<module name="SuppressionFilter">
<property name="file" value="suppressions.xml"/>
</module>
</module>
+1 -1
View File
@@ -58,6 +58,6 @@
<property name="message" value="Newline should not be between else and if"/> <property name="message" value="Newline should not be between else and if"/>
</module> </module>
<module name="SuppressionFilter"> <module name="SuppressionFilter">
<property name="file" value="suppressions.xml"/> <property name="file" value="${suppressionFile}"/>
</module> </module>
</module> </module>
@@ -66,6 +66,7 @@ public class InvokeDynamic extends Instruction implements InvokeInstruction
} }
@Override @Override
@SuppressWarnings("unchecked")
public List<net.runelite.asm.Method> getMethods() public List<net.runelite.asm.Method> getMethods()
{ {
return Collections.EMPTY_LIST; return Collections.EMPTY_LIST;
@@ -75,6 +75,7 @@ public class InvokeSpecial extends Instruction implements InvokeInstruction
} }
@Override @Override
@SuppressWarnings("unchecked")
public List<net.runelite.asm.Method> getMethods() public List<net.runelite.asm.Method> getMethods()
{ {
return myMethod != null ? Arrays.asList(myMethod) : Collections.EMPTY_LIST; return myMethod != null ? Arrays.asList(myMethod) : Collections.EMPTY_LIST;
@@ -83,6 +83,7 @@ public class InvokeStatic extends Instruction implements InvokeInstruction
} }
@Override @Override
@SuppressWarnings("unchecked")
public List<net.runelite.asm.Method> getMethods() public List<net.runelite.asm.Method> getMethods()
{ {
return myMethod != null ? Arrays.asList(myMethod) : Collections.EMPTY_LIST; return myMethod != null ? Arrays.asList(myMethod) : Collections.EMPTY_LIST;
@@ -70,6 +70,7 @@ public class MethodContext
return contexts.get(i); return contexts.get(i);
} }
@SuppressWarnings("unchecked")
public Collection<InstructionContext> getInstructionContexts() public Collection<InstructionContext> getInstructionContexts()
{ {
return (Collection) contexts.values(); return (Collection) contexts.values();
@@ -167,7 +167,7 @@ public class ModArith implements Deobfuscator
FieldInfo fieldInfo = getFieldInfo(fi.getMyField()); FieldInfo fieldInfo = getFieldInfo(fi.getMyField());
List<InstructionContext> l = getInsInExpr(ctx, new HashSet(), false); @SuppressWarnings("unchecked") List<InstructionContext> l = getInsInExpr(ctx, new HashSet(), false);
boolean other = false; // check if this contains another field boolean other = false; // check if this contains another field
boolean getter = false, setter = false; boolean getter = false, setter = false;
for (InstructionContext i : l) for (InstructionContext i : l)
@@ -272,7 +272,7 @@ public class ModArith implements Deobfuscator
// parse the full multiplication expression to // parse the full multiplication expression to
// get all associated constants // get all associated constants
List<InstructionContext> insInExpr = getInsInExpr(ctx, new HashSet(), true); @SuppressWarnings("unchecked") List<InstructionContext> insInExpr = getInsInExpr(ctx, new HashSet(), true);
for (InstructionContext ctx2 : insInExpr) for (InstructionContext ctx2 : insInExpr)
{ {
@@ -171,6 +171,7 @@ public class ConstantParameter implements Deobfuscator
findConstantParameter(methods, ins); findConstantParameter(methods, ins);
} }
@SuppressWarnings("unchecked")
private List<ConstantMethodParameter> findParametersForMethod(Method m) private List<ConstantMethodParameter> findParametersForMethod(Method m)
{ {
Collection<ConstantMethodParameter> c = mparams.get(m); Collection<ConstantMethodParameter> c = mparams.get(m);
@@ -52,7 +52,7 @@ public class CheckExports
@Before @Before
public void before() throws MalformedURLException, ClassNotFoundException public void before() throws MalformedURLException, ClassNotFoundException
{ {
ClassLoader loader = new URLClassLoader(new URL[]{CLIENT.toURL()}); ClassLoader loader = new URLClassLoader(new URL[]{CLIENT.toURI().toURL()});
Class c = loader.loadClass("net.runelite.rs.client.client"); Class c = loader.loadClass("net.runelite.rs.client.client");
classes.add(c); classes.add(c);
@@ -70,6 +70,7 @@ public class CheckExports
} }
} }
@SuppressWarnings("unchecked")
private Class<?> findClassWithObfuscatedName(String name) private Class<?> findClassWithObfuscatedName(String name)
{ {
for (Class c : classes) for (Class c : classes)
@@ -53,7 +53,7 @@ public class CheckMappings
@Before @Before
public void before() throws MalformedURLException, ClassNotFoundException public void before() throws MalformedURLException, ClassNotFoundException
{ {
ClassLoader loader = new URLClassLoader(new URL[]{CLIENT.toURL()}); ClassLoader loader = new URLClassLoader(new URL[]{CLIENT.toURI().toURL()});
Class c = loader.loadClass("client"); Class c = loader.loadClass("client");
classes.add(c); classes.add(c);
@@ -71,6 +71,7 @@ public class CheckMappings
} }
} }
@SuppressWarnings("unchecked")
private Class<?> findClassWithObfuscatedName(String name) private Class<?> findClassWithObfuscatedName(String name)
{ {
for (Class c : classes) for (Class c : classes)
@@ -3673,7 +3673,7 @@
"descriptor" : "(ILdy;Ldy;I)V" "descriptor" : "(ILdy;Ldy;I)V"
} ] } ]
}, { }, {
"class" : "GroundItem", "class" : "TileItem",
"name" : "ck", "name" : "ck",
"super" : "ex", "super" : "ex",
"access" : 49, "access" : 49,
@@ -3992,7 +3992,7 @@
"descriptor" : "()V" "descriptor" : "()V"
} ] } ]
}, { }, {
"class" : "GroundItemPile", "class" : "TileItemPile",
"name" : "dr", "name" : "dr",
"super" : "java.lang.Object", "super" : "java.lang.Object",
"access" : 49, "access" : 49,
@@ -10949,7 +10949,7 @@
"descriptor" : "I", "descriptor" : "I",
"decoder" : 1192947815 "decoder" : 1192947815
}, { }, {
"field" : "groundItemPile", "field" : "tileItemPile",
"owner" : "dj", "owner" : "dj",
"name" : "x", "name" : "x",
"access" : 0, "access" : 0,
@@ -57,8 +57,9 @@ public class AnimationClient
logger.debug("Built URI: {}", url); logger.debug("Built URI: {}", url);
RequestBody body = RequestBody.Companion.create(json, JSON);
Request request = new Request.Builder() Request request = new Request.Builder()
.post(RequestBody.create(JSON, json)) .post(body)
.url(url) .url(url)
.build(); .build();
@@ -38,6 +38,8 @@ import okhttp3.Response;
public class ChatClient public class ChatClient
{ {
private static final RequestBody body = RequestBody.Companion.create(new byte[0], null);
private static final Predicate<String> LAYOUT_VALIDATOR = Pattern private static final Predicate<String> LAYOUT_VALIDATOR = Pattern
.compile("\\[[A-Z]+]:(\\s*\\w+\\s*(\\([A-Za-z]+\\))?,?)+") .compile("\\[[A-Z]+]:(\\s*\\w+\\s*(\\([A-Za-z]+\\))?,?)+")
.asPredicate(); .asPredicate();
@@ -52,8 +54,9 @@ public class ChatClient
.addQueryParameter("kc", Integer.toString(kc)) .addQueryParameter("kc", Integer.toString(kc))
.build(); .build();
Request request = new Request.Builder() Request request = new Request.Builder()
.post(RequestBody.create(null, new byte[0])) .post(body)
.url(url) .url(url)
.build(); .build();
@@ -96,7 +99,7 @@ public class ChatClient
.build(); .build();
Request request = new Request.Builder() Request request = new Request.Builder()
.post(RequestBody.create(null, new byte[0])) .post(body)
.url(url) .url(url)
.build(); .build();
@@ -141,7 +144,7 @@ public class ChatClient
.build(); .build();
Request request = new Request.Builder() Request request = new Request.Builder()
.post(RequestBody.create(null, new byte[0])) .post(body)
.url(url) .url(url)
.build(); .build();
@@ -190,7 +193,7 @@ public class ChatClient
.build(); .build();
Request request = new Request.Builder() Request request = new Request.Builder()
.post(RequestBody.create(null, new byte[0])) .post(body)
.url(url) .url(url)
.build(); .build();
@@ -233,7 +236,7 @@ public class ChatClient
.build(); .build();
Request request = new Request.Builder() Request request = new Request.Builder()
.post(RequestBody.create(null, new byte[0])) .post(body)
.url(url) .url(url)
.build(); .build();
@@ -280,7 +283,7 @@ public class ChatClient
.build(); .build();
Request request = new Request.Builder() Request request = new Request.Builder()
.post(RequestBody.create(null, new byte[0])) .post(body)
.url(url) .url(url)
.build(); .build();
@@ -303,7 +306,7 @@ public class ChatClient
.build(); .build();
Request request = new Request.Builder() Request request = new Request.Builder()
.post(RequestBody.create(null, new byte[0])) .post(body)
.url(url) .url(url)
.build(); .build();
@@ -424,7 +427,7 @@ public class ChatClient
.build(); .build();
Request request = new Request.Builder() Request request = new Request.Builder()
.post(RequestBody.create(null, new byte[0])) .post(body)
.url(url) .url(url)
.build(); .build();
@@ -453,7 +456,7 @@ public class ChatClient
.build(); .build();
Request request = new Request.Builder() Request request = new Request.Builder()
.post(RequestBody.create(null, new byte[0])) .post(body)
.url(url) .url(url)
.build(); .build();
@@ -52,8 +52,9 @@ public class DiscordClient
private void message(HttpUrl url, DiscordMessage discordMessage, int retryAttempt, int maxAttempts) private void message(HttpUrl url, DiscordMessage discordMessage, int retryAttempt, int maxAttempts)
{ {
RequestBody body = RequestBody.Companion.create(gson.toJson(discordMessage), JSON);
Request request = new Request.Builder() Request request = new Request.Builder()
.post(RequestBody.create(JSON, gson.toJson(discordMessage))) .post(body)
.url(url) .url(url)
.build(); .build();
@@ -67,9 +67,10 @@ public class ExamineClient
logger.debug("Built URI: {}", url); logger.debug("Built URI: {}", url);
RequestBody body = RequestBody.Companion.create(text, TEXT);
Request request = new Request.Builder() Request request = new Request.Builder()
.url(url) .url(url)
.post(RequestBody.create(TEXT, text)) .post(body)
.build(); .build();
RuneLiteAPI.CLIENT.newCall(request).enqueue(new Callback() RuneLiteAPI.CLIENT.newCall(request).enqueue(new Callback()
@@ -53,9 +53,10 @@ public class GrandExchangeClient
.addPathSegment("ge") .addPathSegment("ge")
.build(); .build();
RequestBody body = RequestBody.Companion.create(GSON.toJson(grandExchangeTrade), JSON);
Request request = new Request.Builder() Request request = new Request.Builder()
.header(RuneLiteAPI.RUNELITE_AUTH, uuid.toString()) .header(RuneLiteAPI.RUNELITE_AUTH, uuid.toString())
.post(RequestBody.create(JSON, GSON.toJson(grandExchangeTrade))) .post(body)
.url(url) .url(url)
.build(); .build();
@@ -59,9 +59,10 @@ public class LootTrackerClient
.addPathSegment("loottracker") .addPathSegment("loottracker")
.build(); .build();
RequestBody body = RequestBody.Companion.create(GSON.toJson(lootRecord), JSON);
Request request = new Request.Builder() Request request = new Request.Builder()
.header(RuneLiteAPI.RUNELITE_AUTH, uuid.toString()) .header(RuneLiteAPI.RUNELITE_AUTH, uuid.toString())
.post(RequestBody.create(JSON, GSON.toJson(lootRecord))) .post(body)
.url(url) .url(url)
.build(); .build();
@@ -57,8 +57,9 @@ public class XteaClient
logger.debug("Built URI: {}", url); logger.debug("Built URI: {}", url);
RequestBody body = RequestBody.Companion.create(json, JSON);
Request request = new Request.Builder() Request request = new Request.Builder()
.post(RequestBody.create(JSON, json)) .post(body)
.url(url) .url(url)
.build(); .build();
@@ -33,11 +33,11 @@ import org.springframework.http.converter.json.GsonHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer; import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration @Configuration
@EnableWebMvc @EnableWebMvc
public class SpringWebMvcConfigurer extends WebMvcConfigurerAdapter public class SpringWebMvcConfigurer implements WebMvcConfigurer
{ {
/** /**
* Configure .js as application/json to trick Cloudflare into caching json responses * Configure .js as application/json to trick Cloudflare into caching json responses
@@ -31,6 +31,7 @@ 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 java.util.Set;
import javax.annotation.Nonnull;
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;
@@ -350,6 +351,7 @@ public interface Client extends GameShell
* @return the corresponding item composition * @return the corresponding item composition
* @see ItemID * @see ItemID
*/ */
@Nonnull
ItemDefinition getItemDefinition(int id); ItemDefinition getItemDefinition(int id);
/** /**
@@ -1725,4 +1727,9 @@ public interface Client extends GameShell
BigInteger getModulus(); BigInteger getModulus();
void setModulus(BigInteger modulus); void setModulus(BigInteger modulus);
/*
* Returns the max item index + 1 from cache
*/
int getItemCount();
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info> * Copyright (c) 2019, Adam <Adam@sigterm.info>
* 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
@@ -24,23 +24,11 @@
*/ */
package net.runelite.api; package net.runelite.api;
/** public interface Item
* Represents an item inside an {@link ItemContainer}.
*/
public interface Item extends Renderable
{ {
/** int id = -1;
* Gets the items ID. int quantity = -1;
*
* @return the ID of the item
* @see ItemID
*/
int getId();
/** int getId();
* Gets the items quantity.
*
* @return the items quantity
*/
int getQuantity(); int getQuantity();
} }
@@ -130,7 +130,7 @@ public interface Tile
* *
* @return the ground items * @return the ground items
*/ */
List<Item> getGroundItems(); List<TileItem> getGroundItems();
/** /**
* Return the tile under this one, if this tile is a bridge * Return the tile under this one, if this tile is a bridge
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, Adam <Adam@sigterm.info> * Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
* 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
@@ -22,19 +22,25 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.plugins.worldhopper.ping; package net.runelite.api;
import com.sun.jna.Library; /**
import com.sun.jna.Native; * Represents an item inside an {@link ItemLayer}.
import com.sun.jna.Pointer; */
public interface TileItem extends Renderable
interface IPHlpAPI extends Library
{ {
IPHlpAPI INSTANCE = Native.loadLibrary("IPHlpAPI", IPHlpAPI.class); /**
* Gets the items ID.
*
* @return the ID of the item
* @see ItemID
*/
int getId();
Pointer IcmpCreateFile(); /**
* Gets the items quantity.
boolean IcmpCloseHandle(Pointer handle); *
* @return the items quantity
int IcmpSendEcho(Pointer IcmpHandle, int DestinationAddress, Pointer RequestData, short RequestSize, Pointer RequestOptions, IcmpEchoReply ReplyBuffer, int ReplySize, int Timeout); */
int getQuantity();
} }
@@ -45,11 +45,24 @@ public enum VarClientInt
INPUT_TYPE(5), INPUT_TYPE(5),
MEMBERSHIP_STATUS(103), MEMBERSHIP_STATUS(103),
/**
* -1 = player inventory closed /**
* 3 = player inventory opened * 0 = Combat
*/ * 1 = Stats
PLAYER_INVENTORY_OPENED(171), * 2 = Quest
* 3 = Inventory
* 4 = Equipment
* 5 = Prayer
* 6 = Spellbook
* 7 = Clan
* 8 = Account Managment
* 9 = Friends
* 10 = Logout
* 11 = Options
* 12 = Emotes
* 13 = Music
*/
PLAYER_INTERFACE_CONTAINER_OPENED(171),
INVENTORY_TAB(171), INVENTORY_TAB(171),
@@ -24,7 +24,8 @@
*/ */
package net.runelite.api.events; package net.runelite.api.events;
import net.runelite.api.Item; import lombok.Value;
import net.runelite.api.TileItem;
import net.runelite.api.Tile; import net.runelite.api.Tile;
import lombok.Value; import lombok.Value;
@@ -36,5 +37,5 @@ import lombok.Value;
public class ItemDespawned public class ItemDespawned
{ {
private final Tile tile; private final Tile tile;
private final Item item; private final TileItem item;
} }
@@ -24,7 +24,8 @@
*/ */
package net.runelite.api.events; package net.runelite.api.events;
import net.runelite.api.Item; import lombok.Value;
import net.runelite.api.TileItem;
import net.runelite.api.Tile; import net.runelite.api.Tile;
import lombok.Value; import lombok.Value;
@@ -34,7 +35,7 @@ import lombok.Value;
@Value @Value
public class ItemQuantityChanged public class ItemQuantityChanged
{ {
private final Item item; private final TileItem item;
private final Tile tile; private final Tile tile;
private final int oldQuantity; private final int oldQuantity;
private final int newQuantity; private final int newQuantity;
@@ -24,7 +24,8 @@
*/ */
package net.runelite.api.events; package net.runelite.api.events;
import net.runelite.api.Item; import lombok.Value;
import net.runelite.api.TileItem;
import net.runelite.api.Tile; import net.runelite.api.Tile;
import lombok.Value; import lombok.Value;
@@ -36,5 +37,5 @@ import lombok.Value;
public class ItemSpawned public class ItemSpawned
{ {
private final Tile tile; private final Tile tile;
private final Item item; private final TileItem item;
} }
@@ -35,6 +35,9 @@ import net.runelite.http.api.RuneLiteAPI;
@Slf4j @Slf4j
public class RuneLiteProperties public class RuneLiteProperties
{ {
private static final String DISCORD_APP_ID = "409416265891971072";
private static final String DISCORD_APP_ID_PLUS = "560644885250572289";
private final Properties properties = new Properties(); private final Properties properties = new Properties();
private final RuneLitePlusConfig runeLitePlusConfig; private final RuneLitePlusConfig runeLitePlusConfig;
@@ -78,7 +81,19 @@ public class RuneLiteProperties
public String getDiscordAppId() public String getDiscordAppId()
{ {
return "560644885250572289"; if (this.runeLitePlusConfig == null)
{
return properties.getProperty(DISCORD_APP_ID);
}
if (this.runeLitePlusConfig.customPresence())
{
return properties.getProperty(DISCORD_APP_ID_PLUS);
}
else
{
return properties.getProperty(DISCORD_APP_ID);
}
} }
public String getDiscordInvite() public String getDiscordInvite()
@@ -43,7 +43,7 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.nio.channels.FileLock; import java.nio.channels.FileLock;
import java.nio.charset.Charset; import java.nio.charset.StandardCharsets;
import java.time.Duration; import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.util.ArrayList; import java.util.ArrayList;
@@ -108,7 +108,7 @@ public class ConfigManager
final Properties properties = new Properties(); final Properties properties = new Properties();
try (FileInputStream in = new FileInputStream(propertiesFile)) try (FileInputStream in = new FileInputStream(propertiesFile))
{ {
properties.load(new InputStreamReader(in, Charset.forName("UTF-8"))); properties.load(new InputStreamReader(in, StandardCharsets.UTF_8));
} }
catch (Exception e) catch (Exception e)
{ {
@@ -116,7 +116,7 @@ public class ConfigManager
return; return;
} }
final Map<String, String> copy = (Map) ImmutableMap.copyOf(this.properties); @SuppressWarnings("unchecked") final Map<String, String> copy = (Map) ImmutableMap.copyOf(this.properties);
copy.forEach((groupAndKey, value) -> copy.forEach((groupAndKey, value) ->
{ {
if (!properties.containsKey(groupAndKey)) if (!properties.containsKey(groupAndKey))
@@ -160,7 +160,7 @@ public class ConfigManager
try (FileInputStream in = new FileInputStream(SETTINGS_FILE)) try (FileInputStream in = new FileInputStream(SETTINGS_FILE))
{ {
properties.load(new InputStreamReader(in, Charset.forName("UTF-8"))); properties.load(new InputStreamReader(in, StandardCharsets.UTF_8));
} }
catch (FileNotFoundException ex) catch (FileNotFoundException ex)
{ {
@@ -174,7 +174,7 @@ public class ConfigManager
try try
{ {
Map<String, String> copy = (Map) ImmutableMap.copyOf(properties); @SuppressWarnings("unchecked") Map<String, String> copy = (Map) ImmutableMap.copyOf(properties);
copy.forEach((groupAndKey, value) -> copy.forEach((groupAndKey, value) ->
{ {
final String[] split = groupAndKey.split("\\.", 2); final String[] split = groupAndKey.split("\\.", 2);
@@ -212,7 +212,7 @@ public class ConfigManager
try try
{ {
properties.store(new OutputStreamWriter(out, Charset.forName("UTF-8")), "RuneLite configuration"); properties.store(new OutputStreamWriter(out, StandardCharsets.UTF_8), "RuneLite configuration");
} }
finally finally
{ {
@@ -235,6 +235,7 @@ public class ConfigManager
eventBus.post(ConfigChanged.class, configChanged); eventBus.post(ConfigChanged.class, configChanged);
} }
@SuppressWarnings("unchecked")
public <T> T getConfig(Class<T> clazz) public <T> T getConfig(Class<T> clazz)
{ {
if (!Modifier.isPublic(clazz.getModifiers())) if (!Modifier.isPublic(clazz.getModifiers()))
@@ -263,6 +264,7 @@ public class ConfigManager
return properties.getProperty(propertyKey); return properties.getProperty(propertyKey);
} }
@SuppressWarnings("unchecked")
public <T> T getConfiguration(String groupName, String key, Class<T> clazz) public <T> T getConfiguration(String groupName, String key, Class<T> clazz)
{ {
String value = getConfiguration(groupName, key); String value = getConfiguration(groupName, key);
@@ -464,6 +466,7 @@ public class ConfigManager
} }
} }
@SuppressWarnings("unchecked")
static Object stringToObject(String str, Class<?> type) static Object stringToObject(String str, Class<?> type)
{ {
if (type == boolean.class || type == Boolean.class) if (type == boolean.class || type == Boolean.class)
@@ -633,22 +636,34 @@ public class ConfigManager
newestFile = STANDARD_SETTINGS_FILE; newestFile = STANDARD_SETTINGS_FILE;
for (File profileDir : PROFILES_DIR.listFiles()) File[] profileDirFiles = PROFILES_DIR.listFiles();
{
if (!profileDir.isDirectory())
{
continue;
}
for (File settings : profileDir.listFiles()) if (profileDirFiles != null)
{
for (File profileDir : profileDirFiles)
{ {
if (!settings.getName().equals(STANDARD_SETTINGS_FILE_NAME) || if (!profileDir.isDirectory())
settings.lastModified() < newestFile.lastModified())
{ {
continue; continue;
} }
newestFile = settings; File[] settingsFiles = profileDir.listFiles();
if (settingsFiles == null)
{
continue;
}
for (File settings : settingsFiles)
{
if (!settings.getName().equals(STANDARD_SETTINGS_FILE_NAME) ||
settings.lastModified() < newestFile.lastModified())
{
continue;
}
newestFile = settings;
}
} }
} }
@@ -43,6 +43,7 @@ import java.util.Map;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
@@ -410,6 +411,7 @@ public class ItemManager
* @param itemId item id * @param itemId item id
* @return item composition * @return item composition
*/ */
@Nonnull
public ItemDefinition getItemDefinition(int itemId) public ItemDefinition getItemDefinition(int itemId)
{ {
assert client.isClientThread() : "getItemDefinition must be called on client thread"; assert client.isClientThread() : "getItemDefinition must be called on client thread";
@@ -38,7 +38,7 @@ import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.AnimationID; import net.runelite.api.AnimationID;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.Item; import net.runelite.api.TileItem;
import net.runelite.api.ItemID; import net.runelite.api.ItemID;
import net.runelite.api.NPC; import net.runelite.api.NPC;
import net.runelite.api.NpcID; import net.runelite.api.NpcID;
@@ -163,7 +163,7 @@ public class LootManager
private void onItemSpawned(ItemSpawned itemSpawned) private void onItemSpawned(ItemSpawned itemSpawned)
{ {
final Item item = itemSpawned.getItem(); final TileItem item = itemSpawned.getItem();
final Tile tile = itemSpawned.getTile(); final Tile tile = itemSpawned.getTile();
final LocalPoint location = tile.getLocalLocation(); final LocalPoint location = tile.getLocalLocation();
final int packed = location.getSceneX() << 8 | location.getSceneY(); final int packed = location.getSceneX() << 8 | location.getSceneY();
@@ -173,14 +173,14 @@ public class LootManager
private void onItemDespawned(ItemDespawned itemDespawned) private void onItemDespawned(ItemDespawned itemDespawned)
{ {
final Item item = itemDespawned.getItem(); final TileItem item = itemDespawned.getItem();
final LocalPoint location = itemDespawned.getTile().getLocalLocation(); final LocalPoint location = itemDespawned.getTile().getLocalLocation();
log.debug("Item despawn {} ({}) location {},{}", item.getId(), item.getQuantity(), location); log.debug("Item despawn {} ({}) location {},{}", item.getId(), item.getQuantity(), location);
} }
private void onItemQuantityChanged(ItemQuantityChanged itemQuantityChanged) private void onItemQuantityChanged(ItemQuantityChanged itemQuantityChanged)
{ {
final Item item = itemQuantityChanged.getItem(); final TileItem item = itemQuantityChanged.getItem();
final Tile tile = itemQuantityChanged.getTile(); final Tile tile = itemQuantityChanged.getTile();
final LocalPoint location = tile.getLocalLocation(); final LocalPoint location = tile.getLocalLocation();
final int packed = location.getSceneX() << 8 | location.getSceneY(); final int packed = location.getSceneX() << 8 | location.getSceneY();
@@ -0,0 +1,314 @@
/*
* Copyright (c) 2019, Ron Young <https://github.com/raiyni>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.game.chatbox;
import com.google.common.primitives.Ints;
import com.google.inject.Inject;
import java.awt.event.KeyEvent;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Consumer;
import javax.inject.Singleton;
import lombok.Getter;
import net.runelite.api.Client;
import net.runelite.api.ItemDefinition;
import net.runelite.api.widgets.ItemQuantityMode;
import net.runelite.api.widgets.JavaScriptCallback;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetPositionMode;
import net.runelite.api.widgets.WidgetSizeMode;
import net.runelite.api.widgets.WidgetTextAlignment;
import net.runelite.api.widgets.WidgetType;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.game.ItemManager;
@Singleton
public class ChatboxItemSearch extends ChatboxTextInput
{
private static final int ICON_HEIGHT = 32;
private static final int ICON_WIDTH = 36;
private static final int PADDING = 6;
private static final int MAX_RESULTS = 24;
private static final int FONT_SIZE = 16;
private static final int HOVERED_OPACITY = 128;
private final ChatboxPanelManager chatboxPanelManager;
private final ItemManager itemManager;
private final Client client;
private Map<Integer, ItemDefinition> results = new LinkedHashMap<>();
private String tooltipText;
private int index = -1;
@Getter
private Consumer<Integer> onItemSelected;
@Inject
private ChatboxItemSearch(ChatboxPanelManager chatboxPanelManager, ClientThread clientThread,
ItemManager itemManager, Client client)
{
super(chatboxPanelManager, clientThread);
this.chatboxPanelManager = chatboxPanelManager;
this.itemManager = itemManager;
this.client = client;
lines(1);
prompt("Item Search");
onChanged(searchString ->
clientThread.invokeLater(() ->
{
filterResults();
update();
}));
}
@Override
protected void update()
{
Widget container = chatboxPanelManager.getContainerWidget();
container.deleteAllChildren();
Widget promptWidget = container.createChild(-1, WidgetType.TEXT);
promptWidget.setText(getPrompt());
promptWidget.setTextColor(0x800000);
promptWidget.setFontId(getFontID());
promptWidget.setOriginalX(0);
promptWidget.setOriginalY(5);
promptWidget.setXPositionMode(WidgetPositionMode.ABSOLUTE_CENTER);
promptWidget.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP);
promptWidget.setOriginalHeight(FONT_SIZE);
promptWidget.setXTextAlignment(WidgetTextAlignment.CENTER);
promptWidget.setYTextAlignment(WidgetTextAlignment.CENTER);
promptWidget.setWidthMode(WidgetSizeMode.MINUS);
promptWidget.revalidate();
buildEdit(0, 5 + FONT_SIZE, container.getWidth(), FONT_SIZE);
Widget separator = container.createChild(-1, WidgetType.LINE);
separator.setOriginalX(0);
separator.setOriginalY(8 + (FONT_SIZE * 2));
separator.setXPositionMode(WidgetPositionMode.ABSOLUTE_CENTER);
separator.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP);
separator.setOriginalHeight(0);
separator.setOriginalWidth(16);
separator.setWidthMode(WidgetSizeMode.MINUS);
separator.setTextColor(0x666666);
separator.revalidate();
int x = PADDING;
int y = PADDING * 3;
int idx = 0;
for (ItemDefinition itemDefinition : results.values())
{
Widget item = container.createChild(-1, WidgetType.GRAPHIC);
item.setXPositionMode(WidgetPositionMode.ABSOLUTE_LEFT);
item.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP);
item.setOriginalX(x);
item.setOriginalY(y + FONT_SIZE * 2);
item.setOriginalHeight(ICON_HEIGHT);
item.setOriginalWidth(ICON_WIDTH);
item.setName("<col=ff9040>" + itemDefinition.getName());
item.setItemId(itemDefinition.getId());
item.setItemQuantity(10000);
item.setItemQuantityMode(ItemQuantityMode.NEVER);
item.setBorderType(1);
item.setAction(0, tooltipText);
item.setHasListener(true);
if (index == idx)
{
item.setOpacity(HOVERED_OPACITY);
}
else
{
item.setOnMouseOverListener((JavaScriptCallback) ev -> item.setOpacity(HOVERED_OPACITY));
item.setOnMouseLeaveListener((JavaScriptCallback) ev -> item.setOpacity(0));
}
item.setOnOpListener((JavaScriptCallback) ev ->
{
if (onItemSelected != null)
{
onItemSelected.accept(itemDefinition.getId());
}
chatboxPanelManager.close();
});
x += ICON_WIDTH + PADDING;
if (x + ICON_WIDTH >= container.getWidth())
{
y += ICON_HEIGHT + PADDING;
x = PADDING;
}
item.revalidate();
++idx;
}
}
@Override
public void keyPressed(KeyEvent ev)
{
switch (ev.getKeyCode())
{
case KeyEvent.VK_ENTER:
ev.consume();
if (index > -1)
{
if (onItemSelected != null)
{
onItemSelected.accept(results.keySet().toArray(new Integer[results.size()])[index]);
}
chatboxPanelManager.close();
}
break;
case KeyEvent.VK_TAB:
case KeyEvent.VK_RIGHT:
ev.consume();
if (!results.isEmpty())
{
index++;
if (index >= results.size())
{
index = 0;
}
clientThread.invokeLater(this::update);
}
break;
case KeyEvent.VK_LEFT:
ev.consume();
if (!results.isEmpty())
{
index--;
if (index < 0)
{
index = results.size() - 1;
}
clientThread.invokeLater(this::update);
}
break;
case KeyEvent.VK_UP:
ev.consume();
if (results.size() >= (MAX_RESULTS / 2))
{
index -= MAX_RESULTS / 2;
if (index < 0)
{
if (results.size() == MAX_RESULTS)
{
index += results.size();
}
else
{
index += MAX_RESULTS;
}
index = Ints.constrainToRange(index, 0, results.size() - 1);
}
clientThread.invokeLater(this::update);
}
break;
case KeyEvent.VK_DOWN:
ev.consume();
if (results.size() >= (MAX_RESULTS / 2))
{
index += MAX_RESULTS / 2;
if (index >= MAX_RESULTS)
{
if (results.size() == MAX_RESULTS)
{
index -= results.size();
}
else
{
index -= MAX_RESULTS;
}
index = Ints.constrainToRange(index, 0, results.size() - 1);
}
clientThread.invokeLater(this::update);
}
break;
default:
super.keyPressed(ev);
}
}
@Override
protected void close()
{
// Clear search string when closed
value("");
results.clear();
index = -1;
super.close();
}
@Override
@Deprecated
public ChatboxTextInput onDone(Consumer<String> onDone)
{
throw new UnsupportedOperationException();
}
private void filterResults()
{
results.clear();
index = -1;
String search = getValue().toLowerCase();
if (search.isEmpty())
{
return;
}
for (int i = 0; i < client.getItemCount() && results.size() < MAX_RESULTS; i++)
{
ItemDefinition itemComposition = itemManager.getItemDefinition(itemManager.canonicalize(i));
String name = itemComposition.getName();
// The client assigns "null" to item names of items it doesn't know about
if (!name.equals("null") && name.toLowerCase().contains(search))
{
// This may already be in the map due to canonicalize mapping the item to something we've already seen
results.putIfAbsent(itemComposition.getId(), itemComposition);
}
}
}
public ChatboxItemSearch onItemSelected(Consumer<Integer> onItemSelected)
{
this.onItemSelected = onItemSelected;
return this;
}
public ChatboxItemSearch tooltipText(final String text)
{
tooltipText = text;
return this;
}
}
@@ -67,7 +67,7 @@ public class ChatboxTextInput extends ChatboxInput implements KeyListener, Mouse
private static final Pattern BREAK_MATCHER = Pattern.compile("[^a-zA-Z0-9']"); private static final Pattern BREAK_MATCHER = Pattern.compile("[^a-zA-Z0-9']");
private final ChatboxPanelManager chatboxPanelManager; private final ChatboxPanelManager chatboxPanelManager;
private final ClientThread clientThread; protected final ClientThread clientThread;
private static IntPredicate getDefaultCharValidator() private static IntPredicate getDefaultCharValidator()
{ {
@@ -118,6 +118,9 @@ public class PluginManager
this.configManager = configManager; this.configManager = configManager;
this.executor = executor; this.executor = executor;
this.sceneTileManager = sceneTileManager; this.sceneTileManager = sceneTileManager;
eventBus.subscribe(SessionOpen.class, this, this::onSessionOpen);
eventBus.subscribe(SessionClose.class, this, this::onSessionClose);
} }
public void watch() public void watch()
@@ -171,7 +174,7 @@ public class PluginManager
return null; return null;
} }
public List<Config> getPluginConfigProxies() private List<Config> getPluginConfigProxies()
{ {
List<Injector> injectors = new ArrayList<>(); List<Injector> injectors = new ArrayList<>();
injectors.add(RuneLite.getInjector()); injectors.add(RuneLite.getInjector());
@@ -224,6 +227,7 @@ public class PluginManager
} }
} }
@SuppressWarnings("unchecked")
List<Plugin> scanAndInstantiate(ClassLoader classLoader, String packageName) throws IOException List<Plugin> scanAndInstantiate(ClassLoader classLoader, String packageName) throws IOException
{ {
MutableGraph<Class<? extends Plugin>> graph = GraphBuilder MutableGraph<Class<? extends Plugin>> graph = GraphBuilder
@@ -266,7 +270,7 @@ public class PluginManager
continue; continue;
} }
Class<Plugin> pluginClass = (Class<Plugin>) clazz; @SuppressWarnings("unchecked") Class<Plugin> pluginClass = (Class<Plugin>) clazz;
graph.addNode(pluginClass); graph.addNode(pluginClass);
} }
@@ -428,13 +432,14 @@ public class PluginManager
if (value != null) if (value != null)
{ {
return Boolean.valueOf(value); return Boolean.parseBoolean(value);
} }
final PluginDescriptor pluginDescriptor = plugin.getClass().getAnnotation(PluginDescriptor.class); final PluginDescriptor pluginDescriptor = plugin.getClass().getAnnotation(PluginDescriptor.class);
return pluginDescriptor == null || pluginDescriptor.enabledByDefault(); return pluginDescriptor == null || pluginDescriptor.enabledByDefault();
} }
@SuppressWarnings("unchecked")
private Plugin instantiate(List<Plugin> scannedPlugins, Class<Plugin> clazz) throws PluginInstantiationException private Plugin instantiate(List<Plugin> scannedPlugins, Class<Plugin> clazz) throws PluginInstantiationException
{ {
PluginDependency[] pluginDependencies = clazz.getAnnotationsByType(PluginDependency.class); PluginDependency[] pluginDependencies = clazz.getAnnotationsByType(PluginDependency.class);
@@ -37,7 +37,6 @@ 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;
import net.runelite.api.Item;
import net.runelite.api.ItemID; import net.runelite.api.ItemID;
import static net.runelite.api.ItemID.AGILITY_ARENA_TICKET; import static net.runelite.api.ItemID.AGILITY_ARENA_TICKET;
import net.runelite.api.MenuAction; import net.runelite.api.MenuAction;
@@ -46,6 +45,7 @@ import net.runelite.api.Player;
import net.runelite.api.Skill; import net.runelite.api.Skill;
import static net.runelite.api.Skill.AGILITY; import static net.runelite.api.Skill.AGILITY;
import net.runelite.api.Tile; import net.runelite.api.Tile;
import net.runelite.api.TileItem;
import net.runelite.api.TileObject; import net.runelite.api.TileObject;
import net.runelite.api.coords.WorldPoint; import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.BoostedLevelChanged; import net.runelite.api.events.BoostedLevelChanged;
@@ -321,7 +321,7 @@ public class AgilityPlugin extends Plugin
return; return;
} }
final Item item = itemSpawned.getItem(); final TileItem item = itemSpawned.getItem();
final Tile tile = itemSpawned.getTile(); final Tile tile = itemSpawned.getTile();
if (item.getId() == ItemID.MARK_OF_GRACE) if (item.getId() == ItemID.MARK_OF_GRACE)
@@ -85,7 +85,7 @@ public class BankSearch
// selecting/changing tab // selecting/changing tab
if (closeInput) if (closeInput)
{ {
client.runScript(ScriptID.RESET_CHATBOX_INPUT); client.runScript(ScriptID.RESET_CHATBOX_INPUT, 0, 0);
} }
client.setVar(VarClientInt.INPUT_TYPE, inputType.getType()); client.setVar(VarClientInt.INPUT_TYPE, inputType.getType());
@@ -78,6 +78,7 @@ import net.runelite.api.widgets.WidgetType;
import net.runelite.client.Notifier; import net.runelite.client.Notifier;
import net.runelite.client.callback.ClientThread; import net.runelite.client.callback.ClientThread;
import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemManager;
import net.runelite.client.game.chatbox.ChatboxItemSearch;
import net.runelite.client.game.chatbox.ChatboxPanelManager; import net.runelite.client.game.chatbox.ChatboxPanelManager;
import net.runelite.client.plugins.banktags.BankTagsConfig; import net.runelite.client.plugins.banktags.BankTagsConfig;
import net.runelite.client.plugins.banktags.BankTagsPlugin; import net.runelite.client.plugins.banktags.BankTagsPlugin;
@@ -113,6 +114,7 @@ public class TabInterface
private static final int SCROLL_TICK = 500; private static final int SCROLL_TICK = 500;
private static final int INCINERATOR_WIDTH = 48; private static final int INCINERATOR_WIDTH = 48;
private static final int INCINERATOR_HEIGHT = 39; private static final int INCINERATOR_HEIGHT = 39;
private static TagTab iconToSet;
private final Client client; private final Client client;
private final ClientThread clientThread; private final ClientThread clientThread;
@@ -126,10 +128,10 @@ public class TabInterface
private final Rectangle bounds = new Rectangle(); private final Rectangle bounds = new Rectangle();
private final Rectangle canvasBounds = new Rectangle(); private final Rectangle canvasBounds = new Rectangle();
private ChatboxItemSearch searchProvider;
private TagTab activeTab; private TagTab activeTab;
private int maxTabs; private int maxTabs;
private int currentTabIndex; private int currentTabIndex;
private TagTab iconToSet = null;
private Instant startScroll = Instant.now(); private Instant startScroll = Instant.now();
private String rememberedSearch; private String rememberedSearch;
private boolean waitSearchTick; private boolean waitSearchTick;
@@ -156,7 +158,8 @@ public class TabInterface
final ChatboxPanelManager chatboxPanelManager, final ChatboxPanelManager chatboxPanelManager,
final BankTagsConfig config, final BankTagsConfig config,
final Notifier notifier, final Notifier notifier,
final BankSearch bankSearch) final BankSearch bankSearch,
final ChatboxItemSearch searchProvider)
{ {
this.client = client; this.client = client;
this.clientThread = clientThread; this.clientThread = clientThread;
@@ -167,6 +170,7 @@ public class TabInterface
this.config = config; this.config = config;
this.notifier = notifier; this.notifier = notifier;
this.bankSearch = bankSearch; this.bankSearch = bankSearch;
this.searchProvider = searchProvider;
} }
public boolean isActive() public boolean isActive()
@@ -333,7 +337,7 @@ public class TabInterface
{ {
bankSearch.reset(true); bankSearch.reset(true);
clientThread.invokeLater(() -> client.runScript(ScriptID.RESET_CHATBOX_INPUT)); clientThread.invokeLater(() -> client.runScript(ScriptID.RESET_CHATBOX_INPUT, 0, 0));
} }
else else
{ {
@@ -343,7 +347,20 @@ public class TabInterface
client.playSoundEffect(SoundEffectID.UI_BOOP); client.playSoundEffect(SoundEffectID.UI_BOOP);
break; break;
case Tab.CHANGE_ICON: case Tab.CHANGE_ICON:
iconToSet = tabManager.find(Text.removeTags(event.getOpbase())); final String tag = Text.removeTags(event.getOpbase());
searchProvider
.tooltipText(CHANGE_ICON + " (" + tag + ")")
.onItemSelected((itemId) ->
{
TagTab iconToSet = tabManager.find(tag);
if (iconToSet != null)
{
iconToSet.setIconItemId(itemId);
iconToSet.getIcon().setItemId(itemId);
tabManager.setIcon(iconToSet.getTag(), itemId + "");
}
})
.build();
break; break;
case Tab.DELETE_TAB: case Tab.DELETE_TAB:
String target = Text.standardize(event.getOpbase()); String target = Text.standardize(event.getOpbase());
@@ -526,12 +543,6 @@ public class TabInterface
entries = createMenuEntry(event, REMOVE_TAG + " (" + activeTab.getTag() + ")", event.getTarget(), entries); entries = createMenuEntry(event, REMOVE_TAG + " (" + activeTab.getTag() + ")", event.getTarget(), entries);
client.setMenuEntries(entries); client.setMenuEntries(entries);
} }
else if (iconToSet != null && (entry.getOption().startsWith("Withdraw-") || entry.getOption().equals("Release")))
{
// TODO: Do not replace every withdraw option with change icon option
entry.setOption(CHANGE_ICON + " (" + iconToSet.getTag() + ")");
client.setMenuEntries(entries);
}
else if (event.getActionParam1() == WidgetInfo.BANK_DEPOSIT_INVENTORY.getId() else if (event.getActionParam1() == WidgetInfo.BANK_DEPOSIT_INVENTORY.getId()
&& event.getOption().equals("Deposit inventory")) && event.getOption().equals("Deposit inventory"))
{ {
@@ -27,12 +27,15 @@ package net.runelite.client.plugins.chatboxperformance;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.events.WidgetPositioned; import net.runelite.api.GameState;
import net.runelite.api.ScriptID;
import net.runelite.api.events.ScriptCallbackEvent;
import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetInfo;
import net.runelite.api.widgets.WidgetPositionMode; import net.runelite.api.widgets.WidgetPositionMode;
import net.runelite.api.widgets.WidgetSizeMode; import net.runelite.api.widgets.WidgetSizeMode;
import net.runelite.api.widgets.WidgetType; import net.runelite.api.widgets.WidgetType;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.EventBus;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginDescriptor;
@@ -47,50 +50,39 @@ public class ChatboxPerformancePlugin extends Plugin
@Inject @Inject
private Client client; private Client client;
@Inject
private ClientThread clientThread;
@Inject @Inject
private EventBus eventBus; private EventBus eventBus;
@Override @Override
protected void startUp() throws Exception public void startUp()
{ {
eventBus.subscribe(WidgetPositioned.class, this, this::onWidgetPositioned); eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent);
if (client.getGameState() == GameState.LOGGED_IN)
{
clientThread.invokeLater(() -> client.runScript(ScriptID.RESET_CHATBOX_INPUT));
}
} }
@Override @Override
protected void shutDown() throws Exception public void shutDown()
{ {
if (client.getGameState() == GameState.LOGGED_IN)
{
clientThread.invokeLater(() -> client.runScript(ScriptID.RESET_CHATBOX_INPUT));
}
eventBus.unregister(this); eventBus.unregister(this);
} }
private void onWidgetPositioned(WidgetPositioned event) private void onScriptCallbackEvent(ScriptCallbackEvent ev)
{ {
if (!areWidgetsFixed()) if (!"chatboxBackgroundBuilt".equals(ev.getEventName()))
{ {
fixChatbox(); return;
}
}
private boolean areWidgetsFixed()
{
Widget widget = client.getWidget(WidgetInfo.CHATBOX_TRANSPARENT_BACKGROUND);
if (widget == null)
{
return true;
} }
Widget[] widgets = widget.getChildren();
if (widgets != null && widgets.length > 0)
{
Widget last = widgets[widgets.length - 1];
return last != null && last.getOpacity() < 254;
}
return false;
}
private void fixChatbox()
{
fixDarkBackground(); fixDarkBackground();
fixWhiteLines(true); fixWhiteLines(true);
fixWhiteLines(false); fixWhiteLines(false);
@@ -34,6 +34,6 @@ class JagexPrintableCharMatcher extends CharMatcher
// Characters which are printable // Characters which are printable
return (c >= 32 && c <= 126) return (c >= 32 && c <= 126)
|| c == 128 || c == 128
|| (c >= 161 && c <= 255); || (c >= 160 && c <= 255);
} }
} }
@@ -119,6 +119,7 @@ public class ClanChatPlugin extends Plugin
private List<String> chats = new ArrayList<>(); private List<String> chats = new ArrayList<>();
@SuppressWarnings("unchecked")
public static CopyOnWriteArrayList<Player> getClanMembers() public static CopyOnWriteArrayList<Player> getClanMembers()
{ {
return (CopyOnWriteArrayList<Player>) clanMembers.clone(); return (CopyOnWriteArrayList<Player>) clanMembers.clone();
@@ -203,7 +203,7 @@ public class AnagramClue extends ClueScroll implements TextClueScroll, NpcClueSc
.leftColor(TITLED_CONTENT_COLOR) .leftColor(TITLED_CONTENT_COLOR)
.build()); .build());
panelComponent.getChildren().add(LineComponent.builder().left("Area:").build()); panelComponent.getChildren().add(LineComponent.builder().left("Location:").build());
panelComponent.getChildren().add(LineComponent.builder() panelComponent.getChildren().add(LineComponent.builder()
.left(getArea()) .left(getArea())
.leftColor(TITLED_CONTENT_COLOR) .leftColor(TITLED_CONTENT_COLOR)
@@ -85,7 +85,7 @@ public class CipherClue extends ClueScroll implements TextClueScroll, NpcClueScr
.leftColor(TITLED_CONTENT_COLOR) .leftColor(TITLED_CONTENT_COLOR)
.build()); .build());
panelComponent.getChildren().add(LineComponent.builder().left("Area:").build()); panelComponent.getChildren().add(LineComponent.builder().left("Location:").build());
panelComponent.getChildren().add(LineComponent.builder() panelComponent.getChildren().add(LineComponent.builder()
.left(getArea()) .left(getArea())
.leftColor(TITLED_CONTENT_COLOR) .leftColor(TITLED_CONTENT_COLOR)
@@ -160,7 +160,7 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat
else else
{ {
panelComponent.getChildren().add(LineComponent.builder() panelComponent.getChildren().add(LineComponent.builder()
.left("Possible areas:") .left("Possible locations:")
.build()); .build());
final Map<HotColdArea, Integer> locationCounts = new EnumMap<>(HotColdArea.class); final Map<HotColdArea, Integer> locationCounts = new EnumMap<>(HotColdArea.class);
@@ -61,7 +61,7 @@ public class MusicClue extends ClueScroll implements NpcClueScroll
.leftColor(TITLED_CONTENT_COLOR) .leftColor(TITLED_CONTENT_COLOR)
.build()); .build());
panelComponent.getChildren().add(LineComponent.builder().left("Area:").build()); panelComponent.getChildren().add(LineComponent.builder().left("Location:").build());
panelComponent.getChildren().add(LineComponent.builder() panelComponent.getChildren().add(LineComponent.builder()
.left("Falador Park") .left("Falador Park")
.leftColor(TITLED_CONTENT_COLOR) .leftColor(TITLED_CONTENT_COLOR)
@@ -526,6 +526,7 @@ public class ConfigPanel extends PluginPanel
openGroupConfigPanel(listItem, config, cd, false); openGroupConfigPanel(listItem, config, cd, false);
} }
@SuppressWarnings("unchecked")
private void openGroupConfigPanel(PluginListItem listItem, Config config, ConfigDescriptor cd, boolean refresh) private void openGroupConfigPanel(PluginListItem listItem, Config config, ConfigDescriptor cd, boolean refresh)
{ {
showingPluginList = false; showingPluginList = false;
@@ -657,10 +658,10 @@ public class ConfigPanel extends PluginPanel
} }
else if (cid2.getType().isEnum()) else if (cid2.getType().isEnum())
{ {
Class<? extends Enum> type = (Class<? extends Enum>) cid2.getType(); @SuppressWarnings("unchecked") Class<? extends Enum> type = (Class<? extends Enum>) cid2.getType();
try try
{ {
Enum selectedItem = Enum.valueOf(type, configManager.getConfiguration(cd.getGroup().value(), cid2.getItem().keyName())); @SuppressWarnings("unchecked") Enum selectedItem = Enum.valueOf(type, configManager.getConfiguration(cd.getGroup().value(), cid2.getItem().keyName()));
if (!cid.getItem().unhideValue().equals("")) if (!cid.getItem().unhideValue().equals(""))
{ {
show = selectedItem.toString().equals(cid.getItem().unhideValue()); show = selectedItem.toString().equals(cid.getItem().unhideValue());
@@ -1307,7 +1308,7 @@ public class ConfigPanel extends PluginPanel
return new Dimension(PANEL_WIDTH + SCROLLBAR_WIDTH, super.getPreferredSize().height); return new Dimension(PANEL_WIDTH + SCROLLBAR_WIDTH, super.getPreferredSize().height);
} }
private class FixedWidthPanel extends JPanel private static class FixedWidthPanel extends JPanel
{ {
@Override @Override
public Dimension getPreferredSize() public Dimension getPreferredSize()
@@ -44,8 +44,8 @@ import net.runelite.api.DecorativeObject;
import net.runelite.api.DynamicObject; import net.runelite.api.DynamicObject;
import net.runelite.api.GameObject; import net.runelite.api.GameObject;
import net.runelite.api.GraphicsObject; import net.runelite.api.GraphicsObject;
import net.runelite.api.TileItem;
import net.runelite.api.GroundObject; import net.runelite.api.GroundObject;
import net.runelite.api.Item;
import net.runelite.api.ItemLayer; import net.runelite.api.ItemLayer;
import net.runelite.api.NPC; import net.runelite.api.NPC;
import net.runelite.api.NPCDefinition; import net.runelite.api.NPCDefinition;
@@ -285,9 +285,9 @@ class DevToolsOverlay extends Overlay
if (player.getLocalLocation().distanceTo(itemLayer.getLocalLocation()) <= MAX_DISTANCE) if (player.getLocalLocation().distanceTo(itemLayer.getLocalLocation()) <= MAX_DISTANCE)
{ {
Node current = itemLayer.getBottom(); Node current = itemLayer.getBottom();
while (current instanceof Item) while (current instanceof TileItem)
{ {
Item item = (Item) current; TileItem item = (TileItem) current;
OverlayUtil.renderTileOverlay(graphics, itemLayer, "ID: " + item.getId() + " Qty:" + item.getQuantity(), RED); OverlayUtil.renderTileOverlay(graphics, itemLayer, "ID: " + item.getId() + " Qty:" + item.getQuantity(), RED);
current = current.getNext(); current = current.getNext();
} }
@@ -67,6 +67,7 @@ public class WidgetField<T>
return MessageFormatter.format("{}", value).getMessage(); return MessageFormatter.format("{}", value).getMessage();
} }
@SuppressWarnings("unchecked")
void setValue(Widget widget, Object inValue) void setValue(Widget widget, Object inValue)
{ {
Object value = null; Object value = null;
@@ -57,6 +57,7 @@ import net.runelite.client.util.ImageUtil;
public class EmojiPlugin extends Plugin public class EmojiPlugin extends Plugin
{ {
private static final Pattern TAG_REGEXP = Pattern.compile("<[^>]*>"); private static final Pattern TAG_REGEXP = Pattern.compile("<[^>]*>");
private static final Pattern WHITESPACE_REGEXP = Pattern.compile("[\\s\\u00A0]");
@Inject @Inject
private Client client; private Client client;
@@ -182,9 +183,9 @@ public class EmojiPlugin extends Plugin
} }
@Nullable @Nullable
private String updateMessage(final String message) String updateMessage(final String message)
{ {
final String[] messageWords = message.split(" "); final String[] messageWords = WHITESPACE_REGEXP.split(message);
boolean editedMessage = false; boolean editedMessage = false;
for (int i = 0; i < messageWords.length; i++) for (int i = 0; i < messageWords.length; i++)
@@ -281,6 +281,7 @@ public interface GroundItemsConfig extends Config
{ {
return false; return false;
} }
@ConfigItem( @ConfigItem(
keyName = "itemHighlightMode", keyName = "itemHighlightMode",
name = "Item Highlight Mode", name = "Item Highlight Mode",
@@ -616,11 +617,11 @@ public interface GroundItemsConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "showTimer", keyName = "showTimer",
name = "Show ground item tick countdown timer", name = "Show ground item tick countdown timer",
description = "Shows how many ticks left until disappearing.", description = "Shows how many ticks left until disappearing.",
position = 48, position = 48,
parent = "miscStub" parent = "miscStub"
) )
default boolean showTimer() default boolean showTimer()
{ {
@@ -52,7 +52,6 @@ import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.GameState; import net.runelite.api.GameState;
import net.runelite.api.Item;
import net.runelite.api.ItemDefinition; import net.runelite.api.ItemDefinition;
import net.runelite.api.ItemID; import net.runelite.api.ItemID;
import net.runelite.api.ItemLayer; import net.runelite.api.ItemLayer;
@@ -62,16 +61,17 @@ import net.runelite.api.Node;
import net.runelite.api.Player; import net.runelite.api.Player;
import net.runelite.api.Scene; import net.runelite.api.Scene;
import net.runelite.api.Tile; import net.runelite.api.Tile;
import net.runelite.api.TileItem;
import net.runelite.api.coords.WorldPoint; import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.ClientTick; import net.runelite.api.events.ClientTick;
import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.FocusChanged; import net.runelite.api.events.FocusChanged;
import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.GameTick;
import net.runelite.api.events.ItemDespawned; import net.runelite.api.events.ItemDespawned;
import net.runelite.api.events.ItemQuantityChanged; import net.runelite.api.events.ItemQuantityChanged;
import net.runelite.api.events.ItemSpawned; import net.runelite.api.events.ItemSpawned;
import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuEntryAdded;
import net.runelite.api.events.GameTick;
import net.runelite.client.Notifier; import net.runelite.client.Notifier;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.EventBus;
@@ -105,9 +105,10 @@ import net.runelite.client.util.Text;
@Singleton @Singleton
public class GroundItemsPlugin extends Plugin public class GroundItemsPlugin extends Plugin
{ {
@Getter(AccessLevel.PUBLIC)
public static final Map<GroundItem.GroundItemKey, GroundItem> collectedGroundItems = new LinkedHashMap<>();
// ItemID for coins // ItemID for coins
private static final int COINS = ItemID.COINS_995; private static final int COINS = ItemID.COINS_995;
// items stay on the ground for 30 mins in an instance // items stay on the ground for 30 mins in an instance
private static final int INSTANCE_DURATION_MILLIS = 45 * 60 * 1000; private static final int INSTANCE_DURATION_MILLIS = 45 * 60 * 1000;
private static final int INSTANCE_DURATION_TICKS = (int) floor(30 * 60 / 0.6); private static final int INSTANCE_DURATION_TICKS = (int) floor(30 * 60 / 0.6);
@@ -119,7 +120,6 @@ public class GroundItemsPlugin extends Plugin
private static final int DEATH_DURATION_TICKS = (int) floor(60 * 60 / 0.6); private static final int DEATH_DURATION_TICKS = (int) floor(60 * 60 / 0.6);
private static final int NORMAL_DURATION_MILLIS = 60 * 1000; private static final int NORMAL_DURATION_MILLIS = 60 * 1000;
private static final int NORMAL_DURATION_TICKS = (int) floor(60 / 0.6); private static final int NORMAL_DURATION_TICKS = (int) floor(60 / 0.6);
// Ground item menu options // Ground item menu options
private static final int FIRST_OPTION = MenuAction.GROUND_ITEM_FIRST_OPTION.getId(); private static final int FIRST_OPTION = MenuAction.GROUND_ITEM_FIRST_OPTION.getId();
private static final int SECOND_OPTION = MenuAction.GROUND_ITEM_SECOND_OPTION.getId(); private static final int SECOND_OPTION = MenuAction.GROUND_ITEM_SECOND_OPTION.getId();
@@ -129,65 +129,45 @@ public class GroundItemsPlugin extends Plugin
private static final int EXAMINE_ITEM = MenuAction.EXAMINE_ITEM_GROUND.getId(); private static final int EXAMINE_ITEM = MenuAction.EXAMINE_ITEM_GROUND.getId();
private static final int WALK = MenuAction.WALK.getId(); private static final int WALK = MenuAction.WALK.getId();
private static final int CAST_ON_ITEM = MenuAction.SPELL_CAST_ON_GROUND_ITEM.getId(); private static final int CAST_ON_ITEM = MenuAction.SPELL_CAST_ON_GROUND_ITEM.getId();
private static final String TELEGRAB_TEXT = ColorUtil.wrapWithColorTag("Telekinetic Grab", Color.GREEN) + ColorUtil.prependColorTag(" -> ", Color.WHITE); private static final String TELEGRAB_TEXT = ColorUtil.wrapWithColorTag("Telekinetic Grab", Color.GREEN) + ColorUtil.prependColorTag(" -> ", Color.WHITE);
private final Map<Integer, Color> priceChecks = new LinkedHashMap<>();
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
@Setter(AccessLevel.PACKAGE) @Setter(AccessLevel.PACKAGE)
private Map.Entry<Rectangle, GroundItem> textBoxBounds; private Map.Entry<Rectangle, GroundItem> textBoxBounds;
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
@Setter(AccessLevel.PACKAGE) @Setter(AccessLevel.PACKAGE)
private Map.Entry<Rectangle, GroundItem> hiddenBoxBounds; private Map.Entry<Rectangle, GroundItem> hiddenBoxBounds;
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
@Setter(AccessLevel.PACKAGE) @Setter(AccessLevel.PACKAGE)
private Map.Entry<Rectangle, GroundItem> highlightBoxBounds; private Map.Entry<Rectangle, GroundItem> highlightBoxBounds;
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
@Setter(AccessLevel.PACKAGE) @Setter(AccessLevel.PACKAGE)
private boolean hotKeyPressed; private boolean hotKeyPressed;
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
@Setter(AccessLevel.PACKAGE) @Setter(AccessLevel.PACKAGE)
private boolean hideAll; private boolean hideAll;
private List<String> hiddenItemList = new CopyOnWriteArrayList<>(); private List<String> hiddenItemList = new CopyOnWriteArrayList<>();
private List<String> highlightedItemsList = new CopyOnWriteArrayList<>(); private List<String> highlightedItemsList = new CopyOnWriteArrayList<>();
@Inject @Inject
private GroundItemInputListener inputListener; private GroundItemInputListener inputListener;
@Inject @Inject
private MouseManager mouseManager; private MouseManager mouseManager;
@Inject @Inject
private KeyManager keyManager; private KeyManager keyManager;
@Inject @Inject
private Client client; private Client client;
@Inject @Inject
private ItemManager itemManager; private ItemManager itemManager;
@Inject @Inject
private OverlayManager overlayManager; private OverlayManager overlayManager;
@Inject @Inject
private GroundItemsConfig config; private GroundItemsConfig config;
@Inject @Inject
private GroundItemsOverlay overlay; private GroundItemsOverlay overlay;
@Inject @Inject
private Notifier notifier; private Notifier notifier;
@Inject @Inject
private EventBus eventBus; private EventBus eventBus;
@Getter(AccessLevel.PUBLIC)
public static final Map<GroundItem.GroundItemKey, GroundItem> collectedGroundItems = new LinkedHashMap<>();
private final Map<Integer, Color> priceChecks = new LinkedHashMap<>();
private LoadingCache<String, Boolean> highlightedItems; private LoadingCache<String, Boolean> highlightedItems;
private LoadingCache<String, Boolean> hiddenItems; private LoadingCache<String, Boolean> hiddenItems;
@@ -323,7 +303,7 @@ public class GroundItemsPlugin extends Plugin
private void onItemSpawned(ItemSpawned itemSpawned) private void onItemSpawned(ItemSpawned itemSpawned)
{ {
Item item = itemSpawned.getItem(); TileItem item = itemSpawned.getItem();
Tile tile = itemSpawned.getTile(); Tile tile = itemSpawned.getTile();
GroundItem groundItem = buildGroundItem(tile, item); GroundItem groundItem = buildGroundItem(tile, item);
@@ -348,7 +328,7 @@ public class GroundItemsPlugin extends Plugin
private void onItemDespawned(ItemDespawned itemDespawned) private void onItemDespawned(ItemDespawned itemDespawned)
{ {
Item item = itemDespawned.getItem(); TileItem item = itemDespawned.getItem();
Tile tile = itemDespawned.getTile(); Tile tile = itemDespawned.getTile();
GroundItem.GroundItemKey groundItemKey = new GroundItem.GroundItemKey(item.getId(), tile.getWorldLocation()); GroundItem.GroundItemKey groundItemKey = new GroundItem.GroundItemKey(item.getId(), tile.getWorldLocation());
@@ -370,7 +350,7 @@ public class GroundItemsPlugin extends Plugin
private void onItemQuantityChanged(ItemQuantityChanged itemQuantityChanged) private void onItemQuantityChanged(ItemQuantityChanged itemQuantityChanged)
{ {
Item item = itemQuantityChanged.getItem(); TileItem item = itemQuantityChanged.getItem();
Tile tile = itemQuantityChanged.getTile(); Tile tile = itemQuantityChanged.getTile();
int oldQuantity = itemQuantityChanged.getOldQuantity(); int oldQuantity = itemQuantityChanged.getOldQuantity();
int newQuantity = itemQuantityChanged.getNewQuantity(); int newQuantity = itemQuantityChanged.getNewQuantity();
@@ -441,7 +421,7 @@ public class GroundItemsPlugin extends Plugin
} }
} }
private void sendLootNotification(String itemName, String message) private void sendLootNotification(String itemName, String message)
{ {
String notification = "[" + client.getLocalPlayer().getName() + "] " + String notification = "[" + client.getLocalPlayer().getName() + "] " +
"Received a " + message + " item: " + itemName; "Received a " + message + " item: " + itemName;
@@ -462,7 +442,7 @@ public class GroundItemsPlugin extends Plugin
{ {
int menuType = menuEntry.getType(); int menuType = menuEntry.getType();
if (menuType == FIRST_OPTION || menuType == SECOND_OPTION || menuType == THIRD_OPTION if (menuType == FIRST_OPTION || menuType == SECOND_OPTION || menuType == THIRD_OPTION
|| menuType == FOURTH_OPTION || menuType == FIFTH_OPTION || menuType == EXAMINE_ITEM) || menuType == FOURTH_OPTION || menuType == FIFTH_OPTION || menuType == EXAMINE_ITEM)
{ {
for (MenuEntryWithCount entryWCount : newEntries) for (MenuEntryWithCount entryWCount : newEntries)
{ {
@@ -484,13 +464,13 @@ public class GroundItemsPlugin extends Plugin
{ {
final int aMenuType = a.getEntry().getType(); final int aMenuType = a.getEntry().getType();
if (aMenuType == FIRST_OPTION || aMenuType == SECOND_OPTION || aMenuType == THIRD_OPTION if (aMenuType == FIRST_OPTION || aMenuType == SECOND_OPTION || aMenuType == THIRD_OPTION
|| aMenuType == FOURTH_OPTION || aMenuType == FIFTH_OPTION || aMenuType == EXAMINE_ITEM || aMenuType == FOURTH_OPTION || aMenuType == FIFTH_OPTION || aMenuType == EXAMINE_ITEM
|| aMenuType == WALK) || aMenuType == WALK)
{ // only check for item related menu types, so we don't sort other stuff { // only check for item related menu types, so we don't sort other stuff
final int bMenuType = b.getEntry().getType(); final int bMenuType = b.getEntry().getType();
if (bMenuType == FIRST_OPTION || bMenuType == SECOND_OPTION || bMenuType == THIRD_OPTION if (bMenuType == FIRST_OPTION || bMenuType == SECOND_OPTION || bMenuType == THIRD_OPTION
|| bMenuType == FOURTH_OPTION || bMenuType == FIFTH_OPTION || bMenuType == EXAMINE_ITEM || bMenuType == FOURTH_OPTION || bMenuType == FIFTH_OPTION || bMenuType == EXAMINE_ITEM
|| bMenuType == WALK) || bMenuType == WALK)
{ {
final MenuEntry aEntry = a.getEntry(); final MenuEntry aEntry = a.getEntry();
final int aId = aEntry.getIdentifier(); final int aId = aEntry.getIdentifier();
@@ -579,7 +559,7 @@ public class GroundItemsPlugin extends Plugin
} }
} }
private GroundItem buildGroundItem(final Tile tile, final Item item) private GroundItem buildGroundItem(final Tile tile, final TileItem item)
{ {
// Collect the data for the item // Collect the data for the item
final int itemId = item.getId(); final int itemId = item.getId();
@@ -711,9 +691,9 @@ public class GroundItemsPlugin extends Plugin
int quantity = 1; int quantity = 1;
Node current = itemLayer.getBottom(); Node current = itemLayer.getBottom();
while (current instanceof Item) while (current instanceof TileItem)
{ {
Item item = (Item) current; TileItem item = (TileItem) current;
if (item.getId() == itemId) if (item.getId() == itemId)
{ {
quantity = item.getQuantity(); quantity = item.getQuantity();
@@ -878,8 +858,8 @@ public class GroundItemsPlugin extends Plugin
// Explicit highlight takes priority over implicit hide // Explicit highlight takes priority over implicit hide
return isExplicitHidden || (!isExplicitHighlight && canBeHidden && underGe && underHa) return isExplicitHidden || (!isExplicitHighlight && canBeHidden && underGe && underHa)
? this.hiddenColor ? this.hiddenColor
: null; : null;
} }
private int getGePriceFromItemId(int itemId) private int getGePriceFromItemId(int itemId)
@@ -34,5 +34,5 @@ public enum PriceDisplayMode
HA, HA,
GE, GE,
BOTH, BOTH,
OFF; OFF
} }
@@ -34,5 +34,5 @@ public enum ValueCalculationMode
{ {
HA, // calc highlight by HA value HA, // calc highlight by HA value
GE, // calc by GE GE, // calc by GE
HIGHEST; HIGHEST
} }
@@ -190,6 +190,7 @@ public class GroundMarkerPlugin extends Plugin
* @param points * @param points
* @return * @return
*/ */
@SuppressWarnings("unchecked")
private Collection<GroundMarkerWorldPoint> translateToWorld(Collection<GroundMarkerPoint> points) private Collection<GroundMarkerWorldPoint> translateToWorld(Collection<GroundMarkerPoint> points)
{ {
if (points.isEmpty()) if (points.isEmpty())
@@ -299,38 +300,38 @@ public class GroundMarkerPlugin extends Plugin
if (hotKeyPressed && event.getOption().equals(WALK_HERE)) if (hotKeyPressed && event.getOption().equals(WALK_HERE))
{ {
MenuEntry[] menuEntries = client.getMenuEntries(); MenuEntry[] menuEntries = client.getMenuEntries();
int lastIndex = menuEntries.length; int lastIndex = menuEntries.length;
menuEntries = Arrays.copyOf(menuEntries, lastIndex + 4); menuEntries = Arrays.copyOf(menuEntries, lastIndex + 4);
final Tile tile = client.getSelectedSceneTile(); final Tile tile = client.getSelectedSceneTile();
if (tile == null) if (tile == null)
{ {
return; return;
} }
final WorldPoint loc = WorldPoint.fromLocalInstance(client, tile.getLocalLocation()); final WorldPoint loc = WorldPoint.fromLocalInstance(client, tile.getLocalLocation());
final int regionId = loc.getRegionID(); final int regionId = loc.getRegionID();
for (int i = 4; i > 0; i--) for (int i = 4; i > 0; i--)
{ {
MenuEntry menuEntry = menuEntries[lastIndex] = new MenuEntry(); MenuEntry menuEntry = menuEntries[lastIndex] = new MenuEntry();
final GroundMarkerPoint point = new GroundMarkerPoint(regionId, loc.getRegionX(), loc.getRegionY(), client.getPlane(), i); final GroundMarkerPoint point = new GroundMarkerPoint(regionId, loc.getRegionX(), loc.getRegionY(), client.getPlane(), i);
final Optional<GroundMarkerPoint> stream = getPoints(regionId).stream().filter(x -> x.equals(point)).findAny(); final Optional<GroundMarkerPoint> stream = getPoints(regionId).stream().filter(x -> x.equals(point)).findAny();
final String option = (stream.isPresent() && stream.get().getGroup() == i) ? UNMARK : MARK; final String option = (stream.isPresent() && stream.get().getGroup() == i) ? UNMARK : MARK;
menuEntry.setOption(ColorUtil.prependColorTag(Text.removeTags(option + (i == 1 ? "" : " (Group " + i + ")")), getColor(i))); menuEntry.setOption(ColorUtil.prependColorTag(Text.removeTags(option + (i == 1 ? "" : " (Group " + i + ")")), getColor(i)));
menuEntry.setTarget(event.getTarget()); menuEntry.setTarget(event.getTarget());
menuEntry.setType(MenuAction.RUNELITE.getId()); menuEntry.setType(MenuAction.RUNELITE.getId());
lastIndex++;
}
lastIndex++;
}
client.setMenuEntries(menuEntries); client.setMenuEntries(menuEntries);
} }
} }
private void onMenuOptionClicked(MenuOptionClicked event) private void onMenuOptionClicked(MenuOptionClicked event)
{ {
if (event.getMenuAction().getId() != MenuAction.RUNELITE.getId() || (!event.getOption().contains(MARK) && !event.getOption().contains(UNMARK))) if (event.getMenuAction().getId() != MenuAction.RUNELITE.getId() ||
!(event.getOption().equals(MARK) || event.getOption().equals(UNMARK)))
{ {
return; return;
} }
@@ -53,14 +53,6 @@ enum HealthbarOverride implements SpriteOverride
FRONT_140PX(HEALTHBAR_DEFAULT_FRONT_140PX, "front_90px.png"), FRONT_140PX(HEALTHBAR_DEFAULT_FRONT_140PX, "front_90px.png"),
FRONT_160PX(HEALTHBAR_DEFAULT_FRONT_160PX, "front_90px.png"); FRONT_160PX(HEALTHBAR_DEFAULT_FRONT_160PX, "front_90px.png");
@Getter(AccessLevel.PUBLIC)
private final int spriteId;
private final String fileName;
@Getter(AccessLevel.PACKAGE)
private int padding = 1;
private static final Map<Integer, HealthbarOverride> MAP; private static final Map<Integer, HealthbarOverride> MAP;
static static
@@ -75,6 +67,12 @@ enum HealthbarOverride implements SpriteOverride
MAP = builder.build(); MAP = builder.build();
} }
@Getter(AccessLevel.PUBLIC)
private final int spriteId;
private final String fileName;
@Getter(AccessLevel.PACKAGE)
private int padding = 1;
static HealthbarOverride get(int spriteID) static HealthbarOverride get(int spriteID)
{ {
return MAP.get(spriteID); return MAP.get(spriteID);
@@ -34,8 +34,8 @@ import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.GameState; import net.runelite.api.GameState;
import net.runelite.api.HealthBar; import net.runelite.api.HealthBar;
import net.runelite.api.SpriteID;
import net.runelite.api.Sprite; import net.runelite.api.Sprite;
import net.runelite.api.SpriteID;
import net.runelite.api.events.BeforeMenuRender; import net.runelite.api.events.BeforeMenuRender;
import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameStateChanged;
@@ -98,7 +98,7 @@ class InventoryViewerOverlay extends Overlay
public Dimension render(Graphics2D graphics) public Dimension render(Graphics2D graphics)
{ {
if (plugin.isHideWhenInvOpen() if (plugin.isHideWhenInvOpen()
&& client.getVar(VarClientInt.PLAYER_INVENTORY_OPENED) == 3) && client.getVar(VarClientInt.PLAYER_INTERFACE_CONTAINER_OPENED) == 3)
{ {
return null; return null;
} }
@@ -714,7 +714,7 @@ public class LootTrackerPlugin extends Plugin
break; break;
} }
int killCount = Integer.valueOf(m.group(1)); int killCount = Integer.parseInt(m.group(1));
killCountMap.put(eventType.toUpperCase(), killCount); killCountMap.put(eventType.toUpperCase(), killCount);
return; return;
} }
@@ -755,11 +755,12 @@ public class LootTrackerPlugin extends Plugin
if (boss.find()) if (boss.find())
{ {
String bossName = boss.group(1); String bossName = boss.group(1);
int killCount = Integer.valueOf(boss.group(2)); int killCount = Integer.parseInt(boss.group(2));
killCountMap.put(bossName.toUpperCase(), killCount); killCountMap.put(bossName.toUpperCase(), killCount);
} }
} }
@SuppressWarnings("unchecked")
public void onItemContainerChanged(ItemContainerChanged event) public void onItemContainerChanged(ItemContainerChanged event)
{ {
if (pvpDeath && RESPAWN_REGIONS.contains(client.getLocalPlayer().getWorldLocation().getRegionID())) if (pvpDeath && RESPAWN_REGIONS.contains(client.getLocalPlayer().getWorldLocation().getRegionID()))
@@ -849,7 +850,7 @@ public class LootTrackerPlugin extends Plugin
} }
} }
public void deleteLocalRecords() void deleteLocalRecords()
{ {
try try
{ {
@@ -960,7 +961,7 @@ public class LootTrackerPlugin extends Plugin
* @param name - The String name of the record to toggle the hidden status of * @param name - The String name of the record to toggle the hidden status of
* @param ignore - true to ignore, false to remove * @param ignore - true to ignore, false to remove
*/ */
public void toggleNPC(String name, boolean ignore) void toggleNPC(String name, boolean ignore)
{ {
final Set<String> ignoredNPCSet = new HashSet<>(ignoredNPCs); final Set<String> ignoredNPCSet = new HashSet<>(ignoredNPCs);
if (ignore) if (ignore)
@@ -981,7 +982,7 @@ public class LootTrackerPlugin extends Plugin
* @param name - The String of the name to check * @param name - The String of the name to check
* @return - true if it is being ignored, false otherwise * @return - true if it is being ignored, false otherwise
*/ */
public boolean isIgnoredNPC(String name) boolean isIgnoredNPC(String name)
{ {
return ignoredNPCs.contains(name); return ignoredNPCs.contains(name);
} }
@@ -291,6 +291,78 @@ public class AlchemyRoom extends MTARoom
&& player.getWorldLocation().getPlane() == 2; && player.getWorldLocation().getPlane() == 2;
} }
@Override
public void under(Graphics2D graphics)
{
if (!getConfig().alchemy() || best == null || !inside())
{
return;
}
boolean found = false;
for (Cupboard cupboard : cupboards)
{
if (cupboard == null)
{
continue;
}
GameObject object = cupboard.gameObject;
AlchemyItem alchemyItem = cupboard.alchemyItem;
if (alchemyItem == AlchemyItem.EMPTY)
{
continue;
}
if (alchemyItem.equals(best))
{
client.setHintArrow(object.getWorldLocation());
found = true;
}
BufferedImage image = itemManager.getImage(alchemyItem.getId());
Point canvasLoc = Perspective.getCanvasImageLocation(client, object.getLocalLocation(), image, IMAGE_Z_OFFSET);
if (canvasLoc != null)
{
graphics.drawImage(image, canvasLoc.getX(), canvasLoc.getY(), null);
}
}
if (!found && suggestion != null)
{
client.setHintArrow(suggestion.gameObject.getWorldLocation());
}
}
@Override
public void over(Graphics2D graphics)
{
if (!inside() || !config.alchemy() || best == null)
{
return;
}
Widget inventory = client.getWidget(WidgetInfo.INVENTORY);
if (inventory.isHidden())
{
return;
}
for (WidgetItem item : inventory.getWidgetItems())
{
if (item.getId() != best.getId())
{
continue;
}
drawItem(graphics, item);
}
}
private AlchemyItem getBest() private AlchemyItem getBest()
{ {
for (int i = 0; i < INFO_LENGTH; i++) for (int i = 0; i < INFO_LENGTH; i++)
@@ -357,53 +429,6 @@ public class AlchemyRoom extends MTARoom
} }
} }
@Override
public void under(Graphics2D graphics)
{
if (!getConfig().alchemy() || best == null || !inside())
{
return;
}
boolean found = false;
for (Cupboard cupboard : cupboards)
{
if (cupboard == null)
{
continue;
}
GameObject object = cupboard.gameObject;
AlchemyItem alchemyItem = cupboard.alchemyItem;
if (alchemyItem == AlchemyItem.EMPTY)
{
continue;
}
if (alchemyItem.equals(best))
{
client.setHintArrow(object.getWorldLocation());
found = true;
}
BufferedImage image = itemManager.getImage(alchemyItem.getId());
Point canvasLoc = Perspective.getCanvasImageLocation(client, object.getLocalLocation(), image, IMAGE_Z_OFFSET);
if (canvasLoc != null)
{
graphics.drawImage(image, canvasLoc.getX(), canvasLoc.getY(), null);
}
}
if (!found && suggestion != null)
{
client.setHintArrow(suggestion.gameObject.getWorldLocation());
}
}
private Cupboard getSuggestion() private Cupboard getSuggestion()
{ {
// check if a cupboard has the best item in it // check if a cupboard has the best item in it
@@ -443,32 +468,6 @@ public class AlchemyRoom extends MTARoom
return nearest; return nearest;
} }
@Override
public void over(Graphics2D graphics)
{
if (!inside() || !config.alchemy() || best == null)
{
return;
}
Widget inventory = client.getWidget(WidgetInfo.INVENTORY);
if (inventory.isHidden())
{
return;
}
for (WidgetItem item : inventory.getWidgetItems())
{
if (item.getId() != best.getId())
{
continue;
}
drawItem(graphics, item);
}
}
private void drawItem(Graphics2D graphics, WidgetItem item) private void drawItem(Graphics2D graphics, WidgetItem item)
{ {
Rectangle bounds = item.getCanvasBounds(); Rectangle bounds = item.getCanvasBounds();
@@ -30,10 +30,10 @@ import javax.inject.Inject;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.GameState; import net.runelite.api.GameState;
import net.runelite.api.Item;
import net.runelite.api.ItemID; import net.runelite.api.ItemID;
import net.runelite.api.Player; import net.runelite.api.Player;
import net.runelite.api.Tile; import net.runelite.api.Tile;
import net.runelite.api.TileItem;
import net.runelite.api.coords.WorldPoint; import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameStateChanged;
@@ -121,7 +121,7 @@ public class EnchantmentRoom extends MTARoom
private void onItemSpawned(ItemSpawned itemSpawned) private void onItemSpawned(ItemSpawned itemSpawned)
{ {
final Item item = itemSpawned.getItem(); final TileItem item = itemSpawned.getItem();
final Tile tile = itemSpawned.getTile(); final Tile tile = itemSpawned.getTile();
if (item.getId() == ItemID.DRAGONSTONE_6903) if (item.getId() == ItemID.DRAGONSTONE_6903)
@@ -134,7 +134,7 @@ public class EnchantmentRoom extends MTARoom
private void onItemDespawned(ItemDespawned itemDespawned) private void onItemDespawned(ItemDespawned itemDespawned)
{ {
final Item item = itemDespawned.getItem(); final TileItem item = itemDespawned.getItem();
final Tile tile = itemDespawned.getTile(); final Tile tile = itemDespawned.getTile();
if (item.getId() == ItemID.DRAGONSTONE_6903) if (item.getId() == ItemID.DRAGONSTONE_6903)
@@ -47,10 +47,8 @@ import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
public class GraveyardRoom extends MTARoom public class GraveyardRoom extends MTARoom
{ {
private static final int MTA_GRAVEYARD_REGION = 13462;
static final int MIN_SCORE = 16; static final int MIN_SCORE = 16;
private static final int MTA_GRAVEYARD_REGION = 13462;
private final Client client; private final Client client;
private final MTAPlugin plugin; private final MTAPlugin plugin;
private final ItemManager itemManager; private final ItemManager itemManager;
@@ -93,6 +93,11 @@ public class TelekineticRoom extends MTARoom
addSubscriptions(); addSubscriptions();
} }
private static int manhattan(WorldPoint point1, WorldPoint point2)
{
return Math.abs(point1.getX() - point2.getX()) + Math.abs(point2.getY() - point1.getY());
}
private void addSubscriptions() private void addSubscriptions()
{ {
eventBus.subscribe(GameTick.class, this, this::onGameTick); eventBus.subscribe(GameTick.class, this, this::onGameTick);
@@ -142,8 +147,8 @@ public class TelekineticRoom extends MTARoom
private void onGameTick(GameTick event) private void onGameTick(GameTick event)
{ {
if (!config.telekinetic() if (!config.telekinetic()
|| !inside() || !inside()
|| client.getGameState() != GameState.LOGGED_IN) || client.getGameState() != GameState.LOGGED_IN)
{ {
maze = null; maze = null;
moves.clear(); moves.clear();
@@ -285,11 +290,6 @@ public class TelekineticRoom extends MTARoom
return nearest(areaNext, nearestAfter); return nearest(areaNext, nearestAfter);
} }
private static int manhattan(WorldPoint point1, WorldPoint point2)
{
return Math.abs(point1.getX() - point2.getX()) + Math.abs(point2.getY() - point1.getY());
}
private WorldPoint nearest(WorldArea area, WorldPoint worldPoint) private WorldPoint nearest(WorldArea area, WorldPoint worldPoint)
{ {
int dist = Integer.MAX_VALUE; int dist = Integer.MAX_VALUE;
@@ -372,7 +372,7 @@ public class TelekineticRoom extends MTARoom
WorldPoint nghbWorld = WorldPoint.fromLocal(client, neighbour); WorldPoint nghbWorld = WorldPoint.fromLocal(client, neighbour);
if (!nghbWorld.equals(next) if (!nghbWorld.equals(next)
&& !closed.contains(nghbWorld)) && !closed.contains(nghbWorld))
{ {
int score = scores.get(next) + 1; int score = scores.get(next) + 1;
@@ -424,10 +424,10 @@ public class TelekineticRoom extends MTARoom
private LocalPoint[] neighbours(LocalPoint point) private LocalPoint[] neighbours(LocalPoint point)
{ {
return new LocalPoint[] return new LocalPoint[]
{ {
neighbour(point, Direction.NORTH), neighbour(point, Direction.SOUTH), neighbour(point, Direction.NORTH), neighbour(point, Direction.SOUTH),
neighbour(point, Direction.EAST), neighbour(point, Direction.WEST) neighbour(point, Direction.EAST), neighbour(point, Direction.WEST)
}; };
} }
private LocalPoint neighbour(LocalPoint point, Direction direction) private LocalPoint neighbour(LocalPoint point, Direction direction)
@@ -35,11 +35,17 @@ import net.runelite.api.Constants;
public class MapLocations public class MapLocations
{ {
@SuppressWarnings("unchecked")
private static final List<Shape>[] MULTICOMBAT = new List[Constants.MAX_Z]; private static final List<Shape>[] MULTICOMBAT = new List[Constants.MAX_Z];
@SuppressWarnings("unchecked")
private static final List<Shape>[] NOT_MULTICOMBAT = new List[Constants.MAX_Z]; private static final List<Shape>[] NOT_MULTICOMBAT = new List[Constants.MAX_Z];
@SuppressWarnings("unchecked")
private static final List<Shape>[] ROUGH_WILDERNESS = new List[Constants.MAX_Z]; private static final List<Shape>[] ROUGH_WILDERNESS = new List[Constants.MAX_Z];
@SuppressWarnings("unchecked")
private static final List<Shape>[] WILDERNESS_LEVEL_LINES = new List[Constants.MAX_Z]; private static final List<Shape>[] WILDERNESS_LEVEL_LINES = new List[Constants.MAX_Z];
@SuppressWarnings("unchecked")
private static final List<Shape>[] DEADMAN_SAFE_ZONES = new List[Constants.MAX_Z]; private static final List<Shape>[] DEADMAN_SAFE_ZONES = new List[Constants.MAX_Z];
@SuppressWarnings("unchecked")
private static final List<Shape>[] PVP_WORLD_SAFE_ZONES = new List[Constants.MAX_Z]; private static final List<Shape>[] PVP_WORLD_SAFE_ZONES = new List[Constants.MAX_Z];
private static Area getArea(List<Shape> shapes) private static Area getArea(List<Shape> shapes)
@@ -87,7 +87,7 @@ public class NpcIndicatorsPlugin extends Plugin
// Option added to NPC menu // Option added to NPC menu
private static final String TAG = "Tag"; private static final String TAG = "Tag";
private static final String UNTAG = "Untag"; private static final String UNTAG = "Un-tag";
private static final Set<MenuAction> NPC_MENU_ACTIONS = ImmutableSet.of(MenuAction.NPC_FIRST_OPTION, MenuAction.NPC_SECOND_OPTION, private static final Set<MenuAction> NPC_MENU_ACTIONS = ImmutableSet.of(MenuAction.NPC_FIRST_OPTION, MenuAction.NPC_SECOND_OPTION,
MenuAction.NPC_THIRD_OPTION, MenuAction.NPC_FOURTH_OPTION, MenuAction.NPC_FIFTH_OPTION); MenuAction.NPC_THIRD_OPTION, MenuAction.NPC_FOURTH_OPTION, MenuAction.NPC_FIFTH_OPTION);
@@ -316,7 +316,7 @@ public class NpcIndicatorsPlugin extends Plugin
// Add tag option // Add tag option
menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1);
final MenuEntry tagEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); final MenuEntry tagEntry = menuEntries[menuEntries.length - 1] = new MenuEntry();
tagEntry.setOption(npcTags.contains(event.getIdentifier()) ? UNTAG : TAG); tagEntry.setOption(highlightedNpcs.stream().anyMatch(npc -> npc.getIndex() == event.getIdentifier()) ? UNTAG : TAG);
tagEntry.setTarget(event.getTarget()); tagEntry.setTarget(event.getTarget());
tagEntry.setParam0(event.getActionParam0()); tagEntry.setParam0(event.getActionParam0());
tagEntry.setParam1(event.getActionParam1()); tagEntry.setParam1(event.getActionParam1());
@@ -328,9 +328,8 @@ public class NpcIndicatorsPlugin extends Plugin
private void onMenuOptionClicked(MenuOptionClicked click) private void onMenuOptionClicked(MenuOptionClicked click)
{ {
if (click.getMenuAction() != MenuAction.RUNELITE if (click.getMenuAction() != MenuAction.RUNELITE ||
|| (!click.getOption().equals(TAG) !(click.getOption().equals(TAG) || click.getOption().equals(UNTAG)))
&& !click.getOption().equals(UNTAG)))
{ {
return; return;
} }
@@ -247,47 +247,13 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener
return; return;
} }
final Tile tile = client.getScene().getTiles()[client.getPlane()][event.getActionParam0()][event.getActionParam1()];
MenuEntry[] menuEntries = client.getMenuEntries(); MenuEntry[] menuEntries = client.getMenuEntries();
menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1);
MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry();
String option = MARK; menuEntry.setOption(objects.contains(findTileObject(tile, event.getIdentifier())) ? UNMARK : MARK);
Scene scene = client.getScene();
Tile[][][] tiles = scene.getTiles();
final int x = event.getActionParam0();
final int y = event.getActionParam1();
final int z = client.getPlane();
final Tile tile = tiles[z][x][y];
final TileObject object = findTileObject(tile, event.getIdentifier());
if (object != null)
{
final ObjectDefinition objectDefinition = client.getObjectDefinition(object.getId());
final String name = objectDefinition.getName();
if (!Strings.isNullOrEmpty(name))
{
final WorldPoint loc = WorldPoint.fromLocalInstance(client, tile.getLocalLocation());
final int regionId = loc.getRegionID();
final ObjectPoint point = new ObjectPoint(
name,
regionId,
loc.getX() & (REGION_SIZE - 1),
loc.getY() & (REGION_SIZE - 1),
client.getPlane());
final Set<ObjectPoint> objectPoints = points.get(regionId);
if (objectPoints != null && objectPoints.contains(point))
{
option = UNMARK;
}
}
}
menuEntry.setOption(option);
menuEntry.setTarget(event.getTarget()); menuEntry.setTarget(event.getTarget());
menuEntry.setParam0(event.getActionParam0()); menuEntry.setParam0(event.getActionParam0());
menuEntry.setParam1(event.getActionParam1()); menuEntry.setParam1(event.getActionParam1());
@@ -299,8 +265,7 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener
private void onMenuOptionClicked(MenuOptionClicked event) private void onMenuOptionClicked(MenuOptionClicked event)
{ {
if (event.getMenuAction() != MenuAction.RUNELITE if (event.getMenuAction() != MenuAction.RUNELITE
|| (!event.getOption().equals(MARK) || !(event.getOption().equals(MARK) || event.getOption().equals(UNMARK)))
&& !event.getOption().equals(UNMARK)))
{ {
return; return;
} }
@@ -824,10 +824,11 @@ public class ScreenshotPlugin extends Plugin
Request request = null; Request request = null;
if (IMGUR_IMAGE_UPLOAD_URL != null) if (IMGUR_IMAGE_UPLOAD_URL != null)
{ {
RequestBody body = RequestBody.Companion.create(json, JSON);
request = new Request.Builder() request = new Request.Builder()
.url(IMGUR_IMAGE_UPLOAD_URL) .url(IMGUR_IMAGE_UPLOAD_URL)
.addHeader("Authorization", "Client-ID " + IMGUR_CLIENT_ID) .addHeader("Authorization", "Client-ID " + IMGUR_CLIENT_ID)
.post(RequestBody.create(JSON, json)) .post(body)
.build(); .build();
} }
@@ -219,6 +219,7 @@ public class ModifyPanel extends JPanel
labelContainer.repaint(); labelContainer.repaint();
} }
@SuppressWarnings("unchecked")
private void updateAdjustContainer() private void updateAdjustContainer()
{ {
adjustContainer.removeAll(); adjustContainer.removeAll();
@@ -76,13 +76,13 @@ import net.runelite.client.eventbus.EventBus;
import net.runelite.client.input.KeyManager; import net.runelite.client.input.KeyManager;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.worldhopper.ping.Ping;
import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.ClientToolbar;
import net.runelite.client.ui.NavigationButton; import net.runelite.client.ui.NavigationButton;
import net.runelite.client.util.ExecutorServiceExceptionLogger; import net.runelite.client.util.ExecutorServiceExceptionLogger;
import net.runelite.client.util.HotkeyListener; import net.runelite.client.util.HotkeyListener;
import net.runelite.client.util.Text; import net.runelite.client.util.Text;
import net.runelite.client.util.WorldUtil; import net.runelite.client.util.WorldUtil;
import net.runelite.client.util.ping.Ping;
import net.runelite.http.api.worlds.World; import net.runelite.http.api.worlds.World;
import net.runelite.http.api.worlds.WorldClient; import net.runelite.http.api.worlds.WorldClient;
import net.runelite.http.api.worlds.WorldResult; import net.runelite.http.api.worlds.WorldResult;
@@ -1,101 +0,0 @@
/*
* Copyright (c) 2018, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.worldhopper.ping;
import com.sun.jna.Memory;
import com.sun.jna.Pointer;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import lombok.extern.slf4j.Slf4j;
import net.runelite.client.util.OSType;
import net.runelite.http.api.worlds.World;
@Slf4j
public class Ping
{
private static final String RUNELITE_PING = "RuneLitePing";
private static final int TIMEOUT = 2000;
private static final int PORT = 43594;
public static int ping(World world)
{
try
{
if (OSType.getOSType() == OSType.Windows)
{
return windowsPing(world);
}
return tcpPing(world);
}
catch (IOException ex)
{
log.warn("error pinging", ex);
return -1;
}
}
private static int windowsPing(World world) throws UnknownHostException
{
IPHlpAPI ipHlpAPI = IPHlpAPI.INSTANCE;
Pointer ptr = ipHlpAPI.IcmpCreateFile();
InetAddress inetAddress = InetAddress.getByName(world.getAddress());
byte[] address = inetAddress.getAddress();
String dataStr = RUNELITE_PING;
int dataLength = dataStr.length() + 1;
Pointer data = new Memory(dataLength);
data.setString(0L, dataStr);
IcmpEchoReply icmpEchoReply = new IcmpEchoReply(new Memory(IcmpEchoReply.SIZE + dataLength));
assert icmpEchoReply.size() == IcmpEchoReply.SIZE;
int packed = (address[0] & 0xff) | ((address[1] & 0xff) << 8) | ((address[2] & 0xff) << 16) | ((address[3] & 0xff) << 24);
int ret = ipHlpAPI.IcmpSendEcho(ptr, packed, data, (short) (dataLength), Pointer.NULL, icmpEchoReply, IcmpEchoReply.SIZE + dataLength, TIMEOUT);
if (ret != 1)
{
ipHlpAPI.IcmpCloseHandle(ptr);
return -1;
}
int rtt = Math.toIntExact(icmpEchoReply.roundTripTime.longValue());
ipHlpAPI.IcmpCloseHandle(ptr);
return rtt;
}
private static int tcpPing(World world) throws IOException
{
try (Socket socket = new Socket())
{
socket.setSoTimeout(TIMEOUT);
InetAddress inetAddress = InetAddress.getByName(world.getAddress());
long start = System.nanoTime();
socket.connect(new InetSocketAddress(inetAddress, PORT));
long end = System.nanoTime();
return (int) ((end - start) / 1000000L);
}
}
}
@@ -67,7 +67,7 @@ public class ClientLoader
{ {
try try
{ {
URL localInjected = new File("./injected-client/target/injected-client-" + RuneLiteAPI.getVersion() + ".jar").toURI().toURL(); URL localInjected = new File("./injected-client/build/libs/injected-client-" + RuneLiteAPI.getVersion() + ".jar").toURI().toURL();
log.info("Using local injected-client"); log.info("Using local injected-client");
URLClassLoader classLoader = new URLClassLoader(new URL[]{localInjected}); URLClassLoader classLoader = new URLClassLoader(new URL[]{localInjected});
Class<?> clientClass = classLoader.loadClass("client"); Class<?> clientClass = classLoader.loadClass("client");
@@ -39,6 +39,7 @@ import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.GameState; import net.runelite.api.GameState;
import net.runelite.api.MenuAction; import net.runelite.api.MenuAction;
@@ -61,6 +62,7 @@ import net.runelite.client.util.ColorUtil;
import net.runelite.client.util.MiscUtils; import net.runelite.client.util.MiscUtils;
@Singleton @Singleton
@Slf4j
public class OverlayRenderer extends MouseAdapter implements KeyListener public class OverlayRenderer extends MouseAdapter implements KeyListener
{ {
private static final int BORDER = 5; private static final int BORDER = 5;
@@ -496,8 +498,23 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
} }
subGraphics.translate(point.x, point.y); subGraphics.translate(point.x, point.y);
final Dimension dimension = MoreObjects.firstNonNull(overlay.render(subGraphics), new Dimension());
subGraphics.dispose(); final Dimension overlayDimension;
try
{
overlayDimension = overlay.render(subGraphics);
}
catch (Exception ex)
{
log.warn("Error during overlay rendering", ex);
return;
}
finally
{
subGraphics.dispose();
}
final Dimension dimension = MoreObjects.firstNonNull(overlayDimension, new Dimension());
overlay.setBounds(new Rectangle(point, dimension)); overlay.setBounds(new Rectangle(point, dimension));
} }
@@ -24,6 +24,7 @@
*/ */
package net.runelite.client.ui.overlay.components; package net.runelite.client.ui.overlay.components;
import com.google.common.annotations.VisibleForTesting;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.FontMetrics; import java.awt.FontMetrics;
@@ -96,6 +97,7 @@ public class TooltipComponent implements RenderableEntity
char[] chars = line.toCharArray(); char[] chars = line.toCharArray();
int begin = 0; int begin = 0;
boolean inTag = false;
for (int j = 0; j < chars.length; j++) for (int j = 0; j < chars.length; j++)
{ {
if (chars[j] == '<') if (chars[j] == '<')
@@ -110,8 +112,9 @@ public class TooltipComponent implements RenderableEntity
lineX += metrics.stringWidth(text); lineX += metrics.stringWidth(text);
begin = j; begin = j;
inTag = true;
} }
else if (chars[j] == '>') else if (chars[j] == '>' && inTag)
{ {
String subLine = line.substring(begin + 1, j); String subLine = line.substring(begin + 1, j);
@@ -148,6 +151,7 @@ public class TooltipComponent implements RenderableEntity
} }
begin = j + 1; begin = j + 1;
inTag = false;
} }
} }
@@ -162,12 +166,14 @@ public class TooltipComponent implements RenderableEntity
return new Dimension(tooltipWidth + OFFSET * 2, tooltipHeight + OFFSET * 2); return new Dimension(tooltipWidth + OFFSET * 2, tooltipHeight + OFFSET * 2);
} }
private static int calculateTextWidth(FontMetrics metrics, String line) @VisibleForTesting
static int calculateTextWidth(FontMetrics metrics, String line)
{ {
char[] chars = line.toCharArray(); char[] chars = line.toCharArray();
int textWidth = 0; int textWidth = 0;
int begin = 0; int begin = 0;
boolean inTag = false;
for (int j = 0; j < chars.length; j++) for (int j = 0; j < chars.length; j++)
{ {
if (chars[j] == '<') if (chars[j] == '<')
@@ -175,8 +181,9 @@ public class TooltipComponent implements RenderableEntity
textWidth += metrics.stringWidth(line.substring(begin, j)); textWidth += metrics.stringWidth(line.substring(begin, j));
begin = j; begin = j;
inTag = true;
} }
else if (chars[j] == '>') else if (chars[j] == '>' && inTag)
{ {
String subLine = line.substring(begin + 1, j); String subLine = line.substring(begin + 1, j);
@@ -190,6 +197,7 @@ public class TooltipComponent implements RenderableEntity
} }
begin = j + 1; begin = j + 1;
inTag = false;
} }
} }
@@ -66,6 +66,19 @@ public class TooltipOverlay extends Overlay
return null; return null;
} }
try
{
return renderTooltips(graphics, tooltips);
}
finally
{
// Tooltips must always be cleared each frame
tooltipManager.clear();
}
}
private Dimension renderTooltips(Graphics2D graphics, List<Tooltip> tooltips)
{
final Rectangle clientCanvasBounds = new Rectangle(client.getRealDimensions()); final Rectangle clientCanvasBounds = new Rectangle(client.getRealDimensions());
final net.runelite.api.Point mouseCanvasPosition = client.getMouseCanvasPosition(); final net.runelite.api.Point mouseCanvasPosition = client.getMouseCanvasPosition();
final Point mousePosition = new Point(mouseCanvasPosition.getX(), mouseCanvasPosition.getY() + OFFSET); final Point mousePosition = new Point(mouseCanvasPosition.getX(), mouseCanvasPosition.getY() + OFFSET);
@@ -113,7 +126,6 @@ public class TooltipOverlay extends Overlay
newBounds.width = Math.max(newBounds.width, dimension.width); newBounds.width = Math.max(newBounds.width, dimension.width);
} }
tooltipManager.clear();
return newBounds.getSize(); return newBounds.getSize();
} }
} }
@@ -51,6 +51,7 @@ public class DeferredEventBus extends EventBus
pendingEvents.add(new ImmutablePair<>(eventClass, event)); pendingEvents.add(new ImmutablePair<>(eventClass, event));
} }
@SuppressWarnings("unchecked")
public void replay() public void replay()
{ {
int size = pendingEvents.size(); int size = pendingEvents.size();
@@ -33,8 +33,8 @@ import javax.inject.Singleton;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.Constants; import net.runelite.api.Constants;
import net.runelite.api.GameState; import net.runelite.api.GameState;
import net.runelite.api.TileItem;
import net.runelite.api.InventoryID; import net.runelite.api.InventoryID;
import net.runelite.api.Item;
import net.runelite.api.ItemContainer; import net.runelite.api.ItemContainer;
import net.runelite.api.NPC; import net.runelite.api.NPC;
import net.runelite.api.Node; import net.runelite.api.Node;
@@ -180,9 +180,9 @@ public class GameEventManager
{ {
Node current = itemLayer.getBottom(); Node current = itemLayer.getBottom();
while (current instanceof Item) while (current instanceof TileItem)
{ {
final Item item = (Item) current; final TileItem item = (TileItem) current;
current = current.getNext(); current = current.getNext();
@@ -52,6 +52,11 @@ import net.runelite.api.Sprite;
@Slf4j @Slf4j
public class ImageUtil public class ImageUtil
{ {
static
{
ImageIO.setUseCache(false);
}
/** /**
* Creates a {@link BufferedImage} from an {@link Image}. * Creates a {@link BufferedImage} from an {@link Image}.
* *
@@ -30,7 +30,7 @@ import com.sun.jna.Pointer;
interface IPHlpAPI extends Library interface IPHlpAPI extends Library
{ {
IPHlpAPI INSTANCE = Native.loadLibrary("IPHlpAPI", IPHlpAPI.class); IPHlpAPI INSTANCE = Native.load("IPHlpAPI", IPHlpAPI.class);
Pointer IcmpCreateFile(); Pointer IcmpCreateFile();
@@ -0,0 +1 @@
975C2E20F49CD83A72B6A7BA4CF34F9B476F26DCD2649B0CE79B3F93CBB892DD
@@ -0,0 +1,426 @@
.id 923
.int_stack_count 0
.string_stack_count 0
.int_var_count 5
.string_var_count 0
; callback "chatboxBackgroundBuilt"
; used by the ChatboxPerformancePlugin to know when it needs to rebuild.
; Unmark the plugin as hidden and toggle it. The chatbox should change opacity
; slightly
iconst 10616834
cc_deleteall
iconst 0
istore 0
get_varc_int 41
iconst 1337
if_icmpeq LABEL8
jump LABEL24
LABEL8:
invoke 922
iconst 1
if_icmpeq LABEL12
jump LABEL15
LABEL12:
iconst 1
istore 0
jump LABEL24
LABEL15:
getwindowmode
iconst 1
if_icmpeq LABEL19
jump LABEL24
LABEL19:
iconst 0
set_varc_int 41
iconst 0
iconst 0
invoke 183
LABEL24:
iload 0
iconst 10616869
if_sethide
get_varbit 6374
iconst 1
if_icmpeq LABEL31
jump LABEL48
LABEL31:
getwindowmode
iconst 1
if_icmpne LABEL35
jump LABEL48
LABEL35:
iconst 1
iconst 0
iconst 2
iconst 0
iconst 10616890
if_setposition
iconst -1
iconst 0
iconst 0
iconst 0
iconst 10617391
if_setposition
jump LABEL60
LABEL48:
iconst 0
iconst 0
iconst 0
iconst 0
iconst 10616890
if_setposition
iconst 0
iconst 0
iconst 2
iconst 0
iconst 10617391
if_setposition
LABEL60:
iconst 10616870
cc_deleteall
iconst 10616888
cc_deleteall
iconst 0
istore 1
clientclock
get_varc_int 223
if_icmplt LABEL70
jump LABEL82
LABEL70:
invoke 900
iconst 1129
if_icmpne LABEL74
jump LABEL82
LABEL74:
iconst 1
istore 1
iconst 2155
get_varc_int 223
sconst "i"
iconst 10616870
if_setontimer
jump LABEL86
LABEL82:
iconst -1
sconst ""
iconst 10616870
if_setontimer
LABEL86:
invoke 921
iconst 0
if_icmpeq LABEL90
jump LABEL156
LABEL90:
iconst 1
iconst 10616870
if_setnoclickthrough
iload 1
iconst 0
if_icmpeq LABEL97
jump LABEL135
LABEL97:
iconst 10616870
iconst 5
iconst 0
cc_create
iconst 0
iconst 0
iconst 1
iconst 1
cc_setsize
iconst 0
iconst 0
iconst 1
iconst 1
cc_setposition
iconst 1017
cc_setgraphic
iconst 0
cc_settiling
iconst 0
cc_settrans
iconst 10616888
iconst 3
iconst 0
cc_create
iconst 0
iconst 1
iconst 1
iconst 0
cc_setsize
iconst 0
iconst 15
iconst 1
iconst 2
cc_setposition
iconst 8418912
cc_setcolour
iconst 1
cc_setfill
LABEL135:
iconst 10617391
iconst 792
iconst 789
iconst 790
iconst 791
iconst 773
iconst 788
iconst 0
invoke 838
invoke 2373
iconst 1
if_icmpeq LABEL148
jump LABEL152
LABEL148:
iconst 255
iconst 10616835
if_settrans
jump LABEL155
LABEL152:
iconst 0
iconst 10616835
if_settrans
LABEL155:
return
LABEL156:
iconst 16384
iconst 25
div
istore 2
iconst 16384
istore 3
get_varbit 2570
iconst 1
if_icmpeq LABEL166
jump LABEL170
LABEL166:
iconst 1
iconst 10616870
if_setnoclickthrough
jump LABEL176
LABEL170:
iconst 0
iconst 10616870
if_setnoclickthrough
iconst 1
iconst 10616870
2006
LABEL176:
iconst 0
istore 4
iload 1
iconst 0
if_icmpeq LABEL182
jump LABEL332
LABEL182:
invoke 1972
iconst 0
if_icmpeq LABEL186
jump LABEL266
LABEL186:
iload 4
iconst 20
if_icmplt LABEL190
jump LABEL265
LABEL190:
iconst 10616870
iconst 3
iload 4
cc_create
iconst 0
iload 3
iconst 1
iconst 2
cc_setsize
iconst 0
iconst 0
iconst 1
iconst 2
cc_setposition
iconst 0
cc_setcolour
iconst 1
cc_setfill
iconst 254
cc_settrans
iconst 10616888
iconst 3
iload 4
iconst 2
multiply
cc_create
iconst 10616888
iconst 3
iload 4
iconst 2
multiply
iconst 1
add
cc_create 1
iload 3
iconst 1
iconst 2
iconst 0
cc_setsize
iload 3
iconst 1
iconst 2
iconst 0
cc_setsize 1
iconst 0
iconst 0
iconst 0
iconst 0
cc_setposition
iconst 0
iconst 15
iconst 0
iconst 2
cc_setposition 1
iconst 16777215
cc_setcolour
iconst 16777215
cc_setcolour 1
iconst 1
cc_setfill
iconst 1
cc_setfill 1
iconst 251
cc_settrans
iconst 250
cc_settrans 1
iload 4
iconst 1
add
iload 3
iload 2
sub
istore 3
istore 4
jump LABEL186
LABEL265:
sconst "chatboxBackgroundBuilt"
runelite_callback
jump LABEL332
LABEL266:
iconst 10616870
iconst 3
iload 4
cc_create
iconst 0
iload 3
iconst 1
iconst 2
cc_setsize
iconst 0
iconst 0
iconst 1
iconst 2
cc_setposition
iconst 0
cc_setcolour
iconst 1
cc_setfill
iconst 225
cc_settrans
iconst 10616888
iconst 3
iload 4
iconst 2
multiply
cc_create
iconst 10616888
iconst 3
iload 4
iconst 2
multiply
iconst 1
add
cc_create 1
iload 3
iconst 1
iconst 2
iconst 0
cc_setsize
iload 3
iconst 1
iconst 2
iconst 0
cc_setsize 1
iconst 0
iconst 0
iconst 0
iconst 0
cc_setposition
iconst 0
iconst 15
iconst 0
iconst 2
cc_setposition 1
iconst 16777215
cc_setcolour
iconst 16777215
cc_setcolour 1
iconst 1
cc_setfill
iconst 1
cc_setfill 1
iconst 200
cc_settrans
iconst 130
cc_settrans 1
LABEL332:
iconst 10617391
iconst 1190
iconst 1187
iconst 1188
iconst 1189
iconst 1185
iconst 1186
iconst 1
invoke 838
iload 0
iconst 1
if_icmpeq LABEL345
jump LABEL349
LABEL345:
iconst 255
iconst 10616835
if_settrans
jump LABEL380
LABEL349:
invoke 1972
iconst 0
if_icmpeq LABEL353
jump LABEL357
LABEL353:
iconst 155
iconst 10616835
if_settrans
jump LABEL380
LABEL357:
iconst 255
iconst 10616835
if_settrans
iconst 10616834
iconst 3
iconst 0
cc_create
iconst 0
iconst 0
iconst 1
iconst 1
cc_setsize
iconst 0
iconst 0
iconst 1
iconst 1
cc_setposition
iconst 0
cc_setcolour
iconst 1
cc_setfill
iconst 225
cc_settrans
LABEL380:
return
@@ -67,17 +67,9 @@ public class ContainerCalculationTest
@Test @Test
public void testCalculate() public void testCalculate()
{ {
Item coins = mock(Item.class); Item coins = new Item(ItemID.COINS_995, Integer.MAX_VALUE);
when(coins.getId())
.thenReturn(ItemID.COINS_995);
when(coins.getQuantity())
.thenReturn(Integer.MAX_VALUE);
Item whip = mock(Item.class); Item whip = new Item(ItemID.ABYSSAL_WHIP, 1_000_000_000);
when(whip.getId())
.thenReturn(ItemID.ABYSSAL_WHIP);
when(whip.getQuantity())
.thenReturn(1_000_000_000);
Item[] items = ImmutableList.of( Item[] items = ImmutableList.of(
coins, coins,
@@ -54,7 +54,6 @@ public class ChatFilterPluginTest
private ChatFilterConfig chatFilterConfig; private ChatFilterConfig chatFilterConfig;
@Mock @Mock
@Bind
private Player localPlayer; private Player localPlayer;
@Inject @Inject
@@ -121,6 +120,16 @@ public class ChatFilterPluginTest
assertNull(chatFilterPlugin.censorMessage("te\u008Cst")); assertNull(chatFilterPlugin.censorMessage("te\u008Cst"));
} }
@Test
public void testReplayedMessage()
{
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.REMOVE_MESSAGE);
when(chatFilterConfig.filteredWords()).thenReturn("hello osrs");
chatFilterPlugin.updateFilteredPatterns();
assertNull(chatFilterPlugin.censorMessage("hello\u00A0osrs"));
}
@Test @Test
public void testMessageFromFriendIsFiltered() public void testMessageFromFriendIsFiltered()
{ {
@@ -44,6 +44,8 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import org.mockito.runners.MockitoJUnitRunner; import org.mockito.runners.MockitoJUnitRunner;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)
public class EmojiPluginTest public class EmojiPluginTest
@@ -113,4 +115,17 @@ public class EmojiPluginTest
verify(messageNode).setRuneLiteFormatMessage("<img=10>"); verify(messageNode).setRuneLiteFormatMessage("<img=10>");
} }
@Test
public void testEmojiUpdateMessage()
{
String PARTY_POPPER = "<img=" + (-1 + Emoji.getEmoji("@@@").ordinal()) + '>';
String OPEN_MOUTH = "<img=" + (-1 + Emoji.getEmoji(":O").ordinal()) + '>';
assertNull(emojiPlugin.updateMessage("@@@@@"));
assertEquals(PARTY_POPPER, emojiPlugin.updateMessage("@@@"));
assertEquals(PARTY_POPPER + ' ' + PARTY_POPPER, emojiPlugin.updateMessage("@@@ @@@"));
assertEquals(PARTY_POPPER + ' ' + OPEN_MOUTH, emojiPlugin.updateMessage("@@@\u00A0:O"));
assertEquals(PARTY_POPPER + ' ' + OPEN_MOUTH + ' ' + PARTY_POPPER, emojiPlugin.updateMessage("@@@\u00A0:O @@@"));
assertEquals(PARTY_POPPER + " Hello World " + PARTY_POPPER, emojiPlugin.updateMessage("@@@\u00A0Hello World\u00A0@@@"));
}
} }
@@ -135,8 +135,7 @@ public class ItemChargePluginTest
when(client.getItemContainer(eq(InventoryID.EQUIPMENT))).thenReturn(equipmentItemContainer); when(client.getItemContainer(eq(InventoryID.EQUIPMENT))).thenReturn(equipmentItemContainer);
Item[] items = new Item[EquipmentInventorySlot.RING.getSlotIdx() + 1]; Item[] items = new Item[EquipmentInventorySlot.RING.getSlotIdx() + 1];
when(equipmentItemContainer.getItems()).thenReturn(items); when(equipmentItemContainer.getItems()).thenReturn(items);
Item ring = mock(Item.class); Item ring = new Item(ItemID.RING_OF_FORGING, 1);
when(ring.getId()).thenReturn(ItemID.RING_OF_FORGING);
items[EquipmentInventorySlot.RING.getSlotIdx()] = ring; items[EquipmentInventorySlot.RING.getSlotIdx()] = ring;
// Run message // Run message
chatMessage = new ChatMessage(null, ChatMessageType.GAMEMESSAGE, "", USED_RING_OF_FORGING, "", 0); chatMessage = new ChatMessage(null, ChatMessageType.GAMEMESSAGE, "", USED_RING_OF_FORGING, "", 0);
@@ -100,18 +100,13 @@ public class ItemsKeptOnDeathPluginTest
when(itemManager.canonicalize(id)).thenReturn(id); when(itemManager.canonicalize(id)).thenReturn(id);
when(itemManager.getItemPrice(id, true)).thenReturn(price); when(itemManager.getItemPrice(id, true)).thenReturn(price);
return mockItem(id, qty); return item(id, qty);
} }
// Creates a mocked item // Creates a new item
private Item mockItem(final int id, final int qty) private static Item item(final int id, final int qty)
{ {
Item item = mock(Item.class); return new Item(id, qty);
when(item.getId()).thenReturn(id);
when(item.getQuantity()).thenReturn(qty);
return item;
} }
@Test @Test
@@ -126,12 +126,12 @@ public class MotherlodePluginTest
// Create before inventory // Create before inventory
ItemContainer inventory = mock(ItemContainer.class); ItemContainer inventory = mock(ItemContainer.class);
Item[] items = new Item[]{ Item[] items = new Item[]{
mockItem(ItemID.RUNITE_ORE, 1), item(ItemID.RUNITE_ORE, 1),
mockItem(ItemID.GOLDEN_NUGGET, 4), item(ItemID.GOLDEN_NUGGET, 4),
mockItem(ItemID.COAL, 1), item(ItemID.COAL, 1),
mockItem(ItemID.COAL, 1), item(ItemID.COAL, 1),
mockItem(ItemID.COAL, 1), item(ItemID.COAL, 1),
mockItem(ItemID.COAL, 1), item(ItemID.COAL, 1),
}; };
when(inventory.getItems()) when(inventory.getItems())
@@ -145,16 +145,16 @@ public class MotherlodePluginTest
inventory = mock(ItemContainer.class); inventory = mock(ItemContainer.class);
// +1 rune, +4 nugget, +2 coal, +1 addy // +1 rune, +4 nugget, +2 coal, +1 addy
items = new Item[]{ items = new Item[]{
mockItem(ItemID.RUNITE_ORE, 1), item(ItemID.RUNITE_ORE, 1),
mockItem(ItemID.RUNITE_ORE, 1), item(ItemID.RUNITE_ORE, 1),
mockItem(ItemID.GOLDEN_NUGGET, 8), item(ItemID.GOLDEN_NUGGET, 8),
mockItem(ItemID.COAL, 1), item(ItemID.COAL, 1),
mockItem(ItemID.COAL, 1), item(ItemID.COAL, 1),
mockItem(ItemID.COAL, 1), item(ItemID.COAL, 1),
mockItem(ItemID.COAL, 1), item(ItemID.COAL, 1),
mockItem(ItemID.COAL, 1), item(ItemID.COAL, 1),
mockItem(ItemID.COAL, 1), item(ItemID.COAL, 1),
mockItem(ItemID.ADAMANTITE_ORE, 1), item(ItemID.ADAMANTITE_ORE, 1),
}; };
when(inventory.getItems()) when(inventory.getItems())
@@ -171,11 +171,8 @@ public class MotherlodePluginTest
verifyNoMoreInteractions(motherlodeSession); verifyNoMoreInteractions(motherlodeSession);
} }
private static Item mockItem(int itemId, int quantity) private static Item item(int itemId, int quantity)
{ {
Item item = mock(Item.class); return new Item(itemId, quantity);
when(item.getId()).thenReturn(itemId);
when(item.getQuantity()).thenReturn(quantity);
return item;
} }
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, Adam <Adam@sigterm.info> * Copyright (c) 2019, Adam <Adam@sigterm.info>
* 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
@@ -22,40 +22,24 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.plugins.worldhopper.ping; package net.runelite.client.ui.overlay.components;
import com.sun.jna.Native; import java.awt.FontMetrics;
import com.sun.jna.Pointer; import static net.runelite.client.ui.overlay.components.TooltipComponent.calculateTextWidth;
import com.sun.jna.Structure; import static org.junit.Assert.assertEquals;
import com.sun.jna.platform.win32.WinDef; import org.junit.Test;
import java.util.Arrays; import static org.mockito.Matchers.anyString;
import java.util.List; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class IcmpEchoReply extends Structure public class TooltipComponentTest
{ {
private static final int IP_OPTION_INFO_SIZE = 1 + 1 + 1 + 1 + (Native.POINTER_SIZE == 8 ? 12 : 4); // on 64bit vms add 4 byte padding @Test
public static final int SIZE = 4 + 4 + 4 + 2 + 2 + Native.POINTER_SIZE + IP_OPTION_INFO_SIZE; public void testCalculateTextWidth()
public WinDef.ULONG address;
public WinDef.ULONG status;
public WinDef.ULONG roundTripTime;
public WinDef.USHORT dataSize;
public WinDef.USHORT reserved;
public WinDef.PVOID data;
public WinDef.UCHAR ttl;
public WinDef.UCHAR tos;
public WinDef.UCHAR flags;
public WinDef.UCHAR optionsSize;
public WinDef.PVOID optionsData;
IcmpEchoReply(final Pointer p)
{ {
super(p); FontMetrics fontMetics = mock(FontMetrics.class);
} when(fontMetics.stringWidth(anyString())).thenAnswer((invocation) -> ((String) invocation.getArguments()[0]).length());
@Override assertEquals(11, calculateTextWidth(fontMetics, "line1<col=ff0000>>line2"));
protected List<String> getFieldOrder()
{
return Arrays.asList("address", "status", "roundTripTime", "dataSize", "reserved", "data", "ttl", "tos", "flags", "optionsSize", "optionsData");
} }
} }
@@ -122,7 +122,7 @@ import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSEnumDefinition; import net.runelite.rs.api.RSEnumDefinition;
import net.runelite.rs.api.RSFriendSystem; import net.runelite.rs.api.RSFriendSystem;
import net.runelite.rs.api.RSFriendsList; import net.runelite.rs.api.RSFriendsList;
import net.runelite.rs.api.RSGroundItem; import net.runelite.rs.api.RSTileItem;
import net.runelite.rs.api.RSIgnoreList; import net.runelite.rs.api.RSIgnoreList;
import net.runelite.rs.api.RSIndexedSprite; import net.runelite.rs.api.RSIndexedSprite;
import net.runelite.rs.api.RSItemContainer; import net.runelite.rs.api.RSItemContainer;
@@ -180,7 +180,7 @@ public abstract class RSClientMixin implements RSClient
private static int oldMenuEntryCount; private static int oldMenuEntryCount;
@Inject @Inject
private static RSGroundItem lastItemDespawn; private static RSTileItem lastItemDespawn;
@Inject @Inject
private boolean gpu; private boolean gpu;
@@ -1410,7 +1410,7 @@ public abstract class RSClientMixin implements RSClient
} }
// Get the message node which was added // Get the message node which was added
Map<Integer, RSChatChannel> chatLineMap = client.getChatLineMap(); @SuppressWarnings("unchecked") Map<Integer, RSChatChannel> chatLineMap = client.getChatLineMap();
RSChatChannel chatLineBuffer = chatLineMap.get(type); RSChatChannel chatLineBuffer = chatLineMap.get(type);
MessageNode messageNode = chatLineBuffer.getLines()[0]; MessageNode messageNode = chatLineBuffer.getLines()[0];
@@ -1431,7 +1431,7 @@ public abstract class RSClientMixin implements RSClient
public static void renderWidgetLayer(Widget[] widgets, int parentId, int minX, int minY, int maxX, int maxY, int x, int y, int var8) public static void renderWidgetLayer(Widget[] widgets, int parentId, int minX, int minY, int maxX, int maxY, int x, int y, int var8)
{ {
Callbacks callbacks = client.getCallbacks(); Callbacks callbacks = client.getCallbacks();
HashTable<WidgetNode> componentTable = client.getComponentTable(); @SuppressWarnings("unchecked") HashTable<WidgetNode> componentTable = client.getComponentTable();
for (Widget rlWidget : widgets) for (Widget rlWidget : widgets)
{ {
@@ -1489,14 +1489,14 @@ public abstract class RSClientMixin implements RSClient
@Inject @Inject
@Override @Override
public RSGroundItem getLastItemDespawn() public RSTileItem getLastItemDespawn()
{ {
return lastItemDespawn; return lastItemDespawn;
} }
@Inject @Inject
@Override @Override
public void setLastItemDespawn(RSGroundItem lastItemDespawn) public void setLastItemDespawn(RSTileItem lastItemDespawn)
{ {
RSClientMixin.lastItemDespawn = lastItemDespawn; RSClientMixin.lastItemDespawn = lastItemDespawn;
} }
@@ -33,7 +33,7 @@ import net.runelite.api.mixins.Mixin;
import net.runelite.api.mixins.Replace; import net.runelite.api.mixins.Replace;
import net.runelite.api.mixins.Shadow; import net.runelite.api.mixins.Shadow;
import net.runelite.rs.api.RSClient; import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSGroundItem; import net.runelite.rs.api.RSTileItem;
import net.runelite.rs.api.RSItemContainer; import net.runelite.rs.api.RSItemContainer;
@Mixin(RSItemContainer.class) @Mixin(RSItemContainer.class)
@@ -58,7 +58,7 @@ public abstract class RSItemContainerMixin implements RSItemContainer
for (int i = 0; i < itemIds.length; ++i) for (int i = 0; i < itemIds.length; ++i)
{ {
RSGroundItem item = client.createItem(); RSTileItem item = client.createItem();
item.setId(itemIds[i]); item.setId(itemIds[i]);
item.setQuantity(stackSizes[i]); item.setQuantity(stackSizes[i]);
items[i] = item; items[i] = item;
@@ -38,7 +38,7 @@ import net.runelite.api.mixins.Shadow;
import net.runelite.rs.api.RSBoundaryObject; import net.runelite.rs.api.RSBoundaryObject;
import net.runelite.rs.api.RSClient; import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSFloorDecoration; import net.runelite.rs.api.RSFloorDecoration;
import net.runelite.rs.api.RSGroundItemPile; import net.runelite.rs.api.RSTileItemPile;
import net.runelite.rs.api.RSScene; import net.runelite.rs.api.RSScene;
import net.runelite.rs.api.RSTile; import net.runelite.rs.api.RSTile;
import net.runelite.rs.api.RSTileModel; import net.runelite.rs.api.RSTileModel;
@@ -418,7 +418,7 @@ public abstract class RSSceneMixin implements RSScene
Tile tile = getTiles()[plane][x][y]; Tile tile = getTiles()[plane][x][y];
if (tile != null) if (tile != null)
{ {
RSGroundItemPile itemLayer = (RSGroundItemPile) tile.getItemLayer(); RSTileItemPile itemLayer = (RSTileItemPile) tile.getItemLayer();
if (itemLayer != null) if (itemLayer != null)
{ {
itemLayer.setPlane(plane); itemLayer.setPlane(plane);
@@ -7,10 +7,10 @@ import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin; import net.runelite.api.mixins.Mixin;
import net.runelite.api.mixins.Shadow; import net.runelite.api.mixins.Shadow;
import net.runelite.rs.api.RSClient; import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSGroundItem; import net.runelite.rs.api.RSTileItem;
@Mixin(RSGroundItem.class) @Mixin(RSTileItem.class)
public abstract class RSGroundItemMixin implements RSGroundItem public abstract class RSTileItemMixin implements RSTileItem
{ {
@Shadow("client") @Shadow("client")
private static RSClient client; private static RSClient client;
@@ -22,7 +22,7 @@ public abstract class RSGroundItemMixin implements RSGroundItem
private int rl$sceneY = -1; private int rl$sceneY = -1;
@Inject @Inject
RSGroundItemMixin() RSTileItemMixin()
{ {
} }
@@ -5,10 +5,10 @@ import net.runelite.api.Model;
import net.runelite.api.Renderable; import net.runelite.api.Renderable;
import net.runelite.api.mixins.Inject; import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin; import net.runelite.api.mixins.Mixin;
import net.runelite.rs.api.RSGroundItemPile; import net.runelite.rs.api.RSTileItemPile;
@Mixin(RSGroundItemPile.class) @Mixin(RSTileItemPile.class)
public abstract class RSGroundItemPileMixin implements RSGroundItemPile public abstract class RSTileItemPileMixin implements RSTileItemPile
{ {
@Inject @Inject
private int itemLayerPlane; private int itemLayerPlane;
@@ -24,16 +24,18 @@
*/ */
package net.runelite.mixins; package net.runelite.mixins;
import java.util.ArrayList;
import java.util.List;
import net.runelite.api.CollisionData; import net.runelite.api.CollisionData;
import net.runelite.api.CollisionDataFlag; import net.runelite.api.CollisionDataFlag;
import net.runelite.api.Constants; import net.runelite.api.Constants;
import net.runelite.api.DecorativeObject; import net.runelite.api.DecorativeObject;
import net.runelite.api.GroundObject; import net.runelite.api.GroundObject;
import net.runelite.api.Item;
import net.runelite.api.ItemLayer; import net.runelite.api.ItemLayer;
import net.runelite.api.Node; import net.runelite.api.Node;
import net.runelite.api.Point; import net.runelite.api.Point;
import net.runelite.api.Tile; import net.runelite.api.Tile;
import net.runelite.api.TileItem;
import net.runelite.api.WallObject; import net.runelite.api.WallObject;
import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.LocalPoint;
import net.runelite.api.coords.WorldPoint; import net.runelite.api.coords.WorldPoint;
@@ -51,8 +53,6 @@ import net.runelite.api.events.ItemSpawned;
import net.runelite.api.events.WallObjectChanged; import net.runelite.api.events.WallObjectChanged;
import net.runelite.api.events.WallObjectDespawned; import net.runelite.api.events.WallObjectDespawned;
import net.runelite.api.events.WallObjectSpawned; import net.runelite.api.events.WallObjectSpawned;
import java.util.ArrayList;
import java.util.List;
import net.runelite.api.mixins.FieldHook; import net.runelite.api.mixins.FieldHook;
import net.runelite.api.mixins.Inject; import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin; import net.runelite.api.mixins.Mixin;
@@ -62,12 +62,12 @@ import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSEntity; import net.runelite.rs.api.RSEntity;
import net.runelite.rs.api.RSGameObject; import net.runelite.rs.api.RSGameObject;
import net.runelite.rs.api.RSGraphicsObject; import net.runelite.rs.api.RSGraphicsObject;
import net.runelite.rs.api.RSGroundItem; import net.runelite.rs.api.RSTileItemPile;
import net.runelite.rs.api.RSGroundItemPile;
import net.runelite.rs.api.RSNode; import net.runelite.rs.api.RSNode;
import net.runelite.rs.api.RSNodeDeque; import net.runelite.rs.api.RSNodeDeque;
import net.runelite.rs.api.RSProjectile; import net.runelite.rs.api.RSProjectile;
import net.runelite.rs.api.RSTile; import net.runelite.rs.api.RSTile;
import net.runelite.rs.api.RSTileItem;
import org.slf4j.Logger; import org.slf4j.Logger;
@Mixin(RSTile.class) @Mixin(RSTile.class)
@@ -115,6 +115,142 @@ public abstract class RSTileMixin implements RSTile
return LocalPoint.fromScene(getX(), getY()); return LocalPoint.fromScene(getX(), getY());
} }
@Inject
@Override
public boolean hasLineOfSightTo(Tile other)
{
// Thanks to Henke for this method :)
if (this.getPlane() != other.getPlane())
{
return false;
}
CollisionData[] collisionData = client.getCollisionMaps();
if (collisionData == null)
{
return false;
}
int z = this.getPlane();
int[][] collisionDataFlags = collisionData[z].getFlags();
Point p1 = this.getSceneLocation();
Point p2 = other.getSceneLocation();
if (p1.getX() == p2.getX() && p1.getY() == p2.getY())
{
return true;
}
int dx = p2.getX() - p1.getX();
int dy = p2.getY() - p1.getY();
int dxAbs = Math.abs(dx);
int dyAbs = Math.abs(dy);
int xFlags = CollisionDataFlag.BLOCK_LINE_OF_SIGHT_FULL;
int yFlags = CollisionDataFlag.BLOCK_LINE_OF_SIGHT_FULL;
if (dx < 0)
{
xFlags |= CollisionDataFlag.BLOCK_LINE_OF_SIGHT_EAST;
}
else
{
xFlags |= CollisionDataFlag.BLOCK_LINE_OF_SIGHT_WEST;
}
if (dy < 0)
{
yFlags |= CollisionDataFlag.BLOCK_LINE_OF_SIGHT_NORTH;
}
else
{
yFlags |= CollisionDataFlag.BLOCK_LINE_OF_SIGHT_SOUTH;
}
if (dxAbs > dyAbs)
{
int x = p1.getX();
int yBig = p1.getY() << 16; // The y position is represented as a bigger number to handle rounding
int slope = (dy << 16) / dxAbs;
yBig += 0x8000; // Add half of a tile
if (dy < 0)
{
yBig--; // For correct rounding
}
int direction = dx < 0 ? -1 : 1;
while (x != p2.getX())
{
x += direction;
int y = yBig >>> 16;
if ((collisionDataFlags[x][y] & xFlags) != 0)
{
// Collision while traveling on the x axis
return false;
}
yBig += slope;
int nextY = yBig >>> 16;
if (nextY != y && (collisionDataFlags[x][nextY] & yFlags) != 0)
{
// Collision while traveling on the y axis
return false;
}
}
}
else
{
int y = p1.getY();
int xBig = p1.getX() << 16; // The x position is represented as a bigger number to handle rounding
int slope = (dx << 16) / dyAbs;
xBig += 0x8000; // Add half of a tile
if (dx < 0)
{
xBig--; // For correct rounding
}
int direction = dy < 0 ? -1 : 1;
while (y != p2.getY())
{
y += direction;
int x = xBig >>> 16;
if ((collisionDataFlags[x][y] & yFlags) != 0)
{
// Collision while traveling on the y axis
return false;
}
xBig += slope;
int nextX = xBig >>> 16;
if (nextX != x && (collisionDataFlags[nextX][y] & xFlags) != 0)
{
// Collision while traveling on the x axis
return false;
}
}
}
// No collision
return true;
}
@Inject
@Override
public List<TileItem> getGroundItems()
{
ItemLayer layer = this.getItemLayer();
if (layer == null)
{
return null;
}
List<TileItem> result = new ArrayList<TileItem>();
Node node = layer.getBottom();
while (node instanceof TileItem)
{
result.add((TileItem) node);
node = node.getNext();
}
return result;
}
@FieldHook("boundaryObject") @FieldHook("boundaryObject")
@Inject @Inject
public void wallObjectChanged(int idx) public void wallObjectChanged(int idx)
@@ -318,7 +454,7 @@ public abstract class RSTileMixin implements RSTile
} }
} }
@FieldHook("groundItemPile") @FieldHook("tileItemPile")
@Inject @Inject
public void itemLayerChanged(int idx) public void itemLayerChanged(int idx)
{ {
@@ -338,7 +474,7 @@ public abstract class RSTileMixin implements RSTile
RSNode head = oldQueue.getHead(); RSNode head = oldQueue.getHead();
for (RSNode cur = head.getNext(); cur != head; cur = cur.getNext()) for (RSNode cur = head.getNext(); cur != head; cur = cur.getNext())
{ {
RSGroundItem item = (RSGroundItem) cur; RSTileItem item = (RSTileItem) cur;
ItemDespawned itemDespawned = new ItemDespawned(this, item); ItemDespawned itemDespawned = new ItemDespawned(this, item);
client.getCallbacks().post(ItemDespawned.class, itemDespawned); client.getCallbacks().post(ItemDespawned.class, itemDespawned);
} }
@@ -346,13 +482,13 @@ public abstract class RSTileMixin implements RSTile
lastGroundItems[z][x][y] = newQueue; lastGroundItems[z][x][y] = newQueue;
} }
RSGroundItem lastUnlink = client.getLastItemDespawn(); RSTileItem lastUnlink = client.getLastItemDespawn();
if (lastUnlink != null) if (lastUnlink != null)
{ {
client.setLastItemDespawn(null); client.setLastItemDespawn(null);
} }
RSGroundItemPile itemLayer = (RSGroundItemPile) getItemLayer(); RSTileItemPile itemLayer = (RSTileItemPile) getItemLayer();
if (itemLayer == null) if (itemLayer == null)
{ {
if (lastUnlink != null) if (lastUnlink != null)
@@ -382,7 +518,7 @@ public abstract class RSTileMixin implements RSTile
boolean forward = false; boolean forward = false;
if (head != previous) if (head != previous)
{ {
RSGroundItem prev = (RSGroundItem) previous; RSTileItem prev = (RSTileItem) previous;
if (x != prev.getX() || y != prev.getY()) if (x != prev.getX() || y != prev.getY())
{ {
current = prev; current = prev;
@@ -392,7 +528,7 @@ public abstract class RSTileMixin implements RSTile
RSNode next = head.getNext(); RSNode next = head.getNext();
if (current == null && head != next) if (current == null && head != next)
{ {
RSGroundItem n = (RSGroundItem) next; RSTileItem n = (RSTileItem) next;
if (x != n.getX() || y != n.getY()) if (x != n.getX() || y != n.getY())
{ {
current = n; current = n;
@@ -413,7 +549,7 @@ public abstract class RSTileMixin implements RSTile
do do
{ {
RSGroundItem item = (RSGroundItem) current; RSTileItem item = (RSTileItem) current;
item.setX(x); item.setX(x);
item.setY(y); item.setY(y);
@@ -424,142 +560,6 @@ public abstract class RSTileMixin implements RSTile
// Send spawn events for anything on this tile which is at the wrong location, which happens // Send spawn events for anything on this tile which is at the wrong location, which happens
// when the scene base changes // when the scene base changes
} while (current != head && (((RSGroundItem) current).getX() != x || ((RSGroundItem) current).getY() != y)); } while (current != head && (((RSTileItem) current).getX() != x || ((RSTileItem) current).getY() != y));
}
@Inject
@Override
public boolean hasLineOfSightTo(Tile other)
{
// Thanks to Henke for this method :)
if (this.getPlane() != other.getPlane())
{
return false;
}
CollisionData[] collisionData = client.getCollisionMaps();
if (collisionData == null)
{
return false;
}
int z = this.getPlane();
int[][] collisionDataFlags = collisionData[z].getFlags();
Point p1 = this.getSceneLocation();
Point p2 = other.getSceneLocation();
if (p1.getX() == p2.getX() && p1.getY() == p2.getY())
{
return true;
}
int dx = p2.getX() - p1.getX();
int dy = p2.getY() - p1.getY();
int dxAbs = Math.abs(dx);
int dyAbs = Math.abs(dy);
int xFlags = CollisionDataFlag.BLOCK_LINE_OF_SIGHT_FULL;
int yFlags = CollisionDataFlag.BLOCK_LINE_OF_SIGHT_FULL;
if (dx < 0)
{
xFlags |= CollisionDataFlag.BLOCK_LINE_OF_SIGHT_EAST;
}
else
{
xFlags |= CollisionDataFlag.BLOCK_LINE_OF_SIGHT_WEST;
}
if (dy < 0)
{
yFlags |= CollisionDataFlag.BLOCK_LINE_OF_SIGHT_NORTH;
}
else
{
yFlags |= CollisionDataFlag.BLOCK_LINE_OF_SIGHT_SOUTH;
}
if (dxAbs > dyAbs)
{
int x = p1.getX();
int yBig = p1.getY() << 16; // The y position is represented as a bigger number to handle rounding
int slope = (dy << 16) / dxAbs;
yBig += 0x8000; // Add half of a tile
if (dy < 0)
{
yBig--; // For correct rounding
}
int direction = dx < 0 ? -1 : 1;
while (x != p2.getX())
{
x += direction;
int y = yBig >>> 16;
if ((collisionDataFlags[x][y] & xFlags) != 0)
{
// Collision while traveling on the x axis
return false;
}
yBig += slope;
int nextY = yBig >>> 16;
if (nextY != y && (collisionDataFlags[x][nextY] & yFlags) != 0)
{
// Collision while traveling on the y axis
return false;
}
}
}
else
{
int y = p1.getY();
int xBig = p1.getX() << 16; // The x position is represented as a bigger number to handle rounding
int slope = (dx << 16) / dyAbs;
xBig += 0x8000; // Add half of a tile
if (dx < 0)
{
xBig--; // For correct rounding
}
int direction = dy < 0 ? -1 : 1;
while (y != p2.getY())
{
y += direction;
int x = xBig >>> 16;
if ((collisionDataFlags[x][y] & yFlags) != 0)
{
// Collision while traveling on the y axis
return false;
}
xBig += slope;
int nextX = xBig >>> 16;
if (nextX != x && (collisionDataFlags[nextX][y] & xFlags) != 0)
{
// Collision while traveling on the x axis
return false;
}
}
}
// No collision
return true;
}
@Inject
@Override
public List<Item> getGroundItems()
{
ItemLayer layer = this.getItemLayer();
if (layer == null)
{
return null;
}
List<Item> result = new ArrayList<Item>();
Node node = layer.getBottom();
while (node instanceof Item)
{
result.add((Item) node);
node = node.getNext();
}
return result;
} }
} }
@@ -15,14 +15,14 @@ import net.runelite.rs.api.RSBoundaryObject;
import net.runelite.rs.api.RSClient; import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSFloorDecoration; import net.runelite.rs.api.RSFloorDecoration;
import net.runelite.rs.api.RSGameObject; import net.runelite.rs.api.RSGameObject;
import net.runelite.rs.api.RSGroundItemPile; import net.runelite.rs.api.RSTileItemPile;
import net.runelite.rs.api.RSWallDecoration; import net.runelite.rs.api.RSWallDecoration;
@Mixins({ @Mixins({
@Mixin(RSWallDecoration.class), @Mixin(RSWallDecoration.class),
@Mixin(RSGameObject.class), @Mixin(RSGameObject.class),
@Mixin(RSFloorDecoration.class), @Mixin(RSFloorDecoration.class),
@Mixin(RSGroundItemPile.class), @Mixin(RSTileItemPile.class),
@Mixin(RSBoundaryObject.class) @Mixin(RSBoundaryObject.class)
}) })
public abstract class RSTileObjectMixin implements TileObject public abstract class RSTileObjectMixin implements TileObject
@@ -143,7 +143,7 @@ public abstract class RSWidgetMixin implements RSWidget
// parent id potentially incorrect // parent id potentially incorrect
// check the parent in the component table // check the parent in the component table
HashTable<WidgetNode> componentTable = client.getComponentTable(); @SuppressWarnings("unchecked") HashTable<WidgetNode> componentTable = client.getComponentTable();
WidgetNode widgetNode = componentTable.get(parentId); WidgetNode widgetNode = componentTable.get(parentId);
if (widgetNode == null || widgetNode.getId() != TO_GROUP(id)) if (widgetNode == null || widgetNode.getId() != TO_GROUP(id))
{ {
@@ -380,7 +380,7 @@ public abstract class RSWidgetMixin implements RSWidget
return new Widget[0]; return new Widget[0];
} }
HashTable<WidgetNode> componentTable = client.getComponentTable(); @SuppressWarnings("unchecked") HashTable<WidgetNode> componentTable = client.getComponentTable();
WidgetNode wn = componentTable.get(getId()); WidgetNode wn = componentTable.get(getId());
if (wn == null) if (wn == null)

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