This commit is contained in:
PKLite
2019-07-26 19:02:38 -04:00
141 changed files with 2293 additions and 968 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
@@ -321,4 +321,8 @@ public final class AnimationID
// Combat counter // Combat counter
public static final int BARRAGE_ANIMATION = 1979; public static final int BARRAGE_ANIMATION = 1979;
public static final int CHIN_ANIMATION = 7618; public static final int CHIN_ANIMATION = 7618;
// Gauntlet Hunleff
public static final int HUNLEFF_ATTACK = 8419;
public static final int HUNLEFF_TORNADO = 8418;
} }
@@ -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
{ {
/**
* Gets the items ID.
*
* @return the ID of the item
* @see ItemID
*/
int getId(); int getId();
/**
* Gets the items quantity.
*
* @return the items quantity
*/
int getQuantity(); int getQuantity();
void setId(int id);
void setQuantity(int quantity);
} }
@@ -51,7 +51,7 @@ public class ProjectileID
public static final int OLM_FIRE_LINE = 1347; public static final int OLM_FIRE_LINE = 1347;
public static final int OLM_MAGE_ATTACK = 1339; public static final int OLM_MAGE_ATTACK = 1339;
public static final int OLM_RANGE_ATTACK = 1340; public static final int OLM_RANGE_ATTACK = 1340;
public static final int VORKATH_BOMB_AOE = 1481; public static final int VORKATH_BOMB_AOE = 1481;
public static final int VORKATH_POISON_POOL_AOE = 1483; public static final int VORKATH_POISON_POOL_AOE = 1483;
public static final int VORKATH_TICK_FIRE_AOE = 1482; public static final int VORKATH_TICK_FIRE_AOE = 1482;
@@ -101,4 +101,10 @@ public class ProjectileID
public static final int HYDRA_LIGHTNING = 1664; public static final int HYDRA_LIGHTNING = 1664;
public static final int HYDRA_LIGHTNING_2 = 1665; public static final int HYDRA_LIGHTNING_2 = 1665;
public static final int DRAKE_BREATH = 1637; public static final int DRAKE_BREATH = 1637;
public static final int HUNLEFF_MAGE_ATTACK = 1707;
public static final int HUNLEFF_CORRUPTED_MAGE_ATTACK = 1708;
public static final int HUNLEFF_RANGE_ATTACK = 1711;
public static final int HUNLEFF_CORRUPTED_RANGE_ATTACK = 1712;
} }
@@ -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,8 @@ import net.runelite.http.api.RuneLiteAPI;
@Slf4j @Slf4j
public class RuneLiteProperties public class RuneLiteProperties
{ {
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 +80,7 @@ public class RuneLiteProperties
public String getDiscordAppId() public String getDiscordAppId()
{ {
return "560644885250572289"; return DISCORD_APP_ID_PLUS;
} }
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;
}
} }
} }
@@ -34,22 +34,11 @@ import net.runelite.client.config.Range;
@ConfigGroup("runeliteplus") @ConfigGroup("runeliteplus")
public interface RuneLitePlusConfig extends Config public interface RuneLitePlusConfig extends Config
{ {
@ConfigItem(
position = 0,
keyName = "customPresence",
name = "RL+ Presence",
description = "Represent RL+ with a custom icon and discord presence."
)
default boolean customPresence()
{
return false;
}
@ConfigItem( @ConfigItem(
keyName = "enableOpacity", keyName = "enableOpacity",
name = "Enable opacity", name = "Enable opacity",
description = "Enables opacity for the whole window.<br>NOTE: This only stays enabled if your pc supports this!", description = "Enables opacity for the whole window.<br>NOTE: This only stays enabled if your pc supports this!",
position = 1 position = 0
) )
default boolean enableOpacity() default boolean enableOpacity()
{ {
@@ -64,7 +53,7 @@ public interface RuneLitePlusConfig extends Config
keyName = "opacityPercentage", keyName = "opacityPercentage",
name = "Opacity percentage", name = "Opacity percentage",
description = "Changes the opacity of the window if opacity is enabled", description = "Changes the opacity of the window if opacity is enabled",
position = 2 position = 1
) )
default int opacityPercentage() default int opacityPercentage()
{ {
@@ -75,7 +64,7 @@ public interface RuneLitePlusConfig extends Config
keyName = "keyboardPin", keyName = "keyboardPin",
name = "Keyboard bank pin", name = "Keyboard bank pin",
description = "Enables you to type your bank pin", description = "Enables you to type your bank pin",
position = 3 position = 2
) )
default boolean keyboardPin() default boolean keyboardPin()
{ {
@@ -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++)
@@ -0,0 +1,133 @@
/*
* Copyright (c) 2019, lyzrds <https://discord.gg/5eb9Fe>
* Copyright (c) 2019, ganom <https://github.com/Ganom>
* 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.gauntlet;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.Prayer;
import net.runelite.api.SpriteID;
import net.runelite.client.game.SpriteManager;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayPriority;
import net.runelite.client.ui.overlay.components.ComponentConstants;
import net.runelite.client.ui.overlay.components.InfoBoxComponent;
import net.runelite.client.ui.overlay.components.PanelComponent;
@Singleton
@Slf4j
public class GauntletInfoBox extends Overlay
{
private static final Color NOT_ACTIVATED_BACKGROUND_COLOR = new Color(150, 0, 0, 150);
private final Client client;
private final GauntletPlugin plugin;
private final PanelComponent panelComponent = new PanelComponent();
private final SpriteManager spriteManager;
@Inject
GauntletInfoBox(final @Nullable Client client, final GauntletPlugin plugin, final SpriteManager spriteManager)
{
this.client = client;
this.plugin = plugin;
this.spriteManager = spriteManager;
setPosition(OverlayPosition.BOTTOM_RIGHT);
setPriority(OverlayPriority.HIGH);
}
@Override
public Dimension render(Graphics2D graphics)
{
panelComponent.getChildren().clear();
if (plugin.getHunllef() == null)
{
return null;
}
Prayer prayer = plugin.getNextPrayer();
if (prayer == null)
{
return null;
}
InfoBoxComponent prayComponent = new InfoBoxComponent();
BufferedImage prayImg = scaleImg(getPrayerImage(prayer));
prayComponent.setImage(prayImg);
prayComponent.setColor(Color.WHITE);
prayComponent.setBackgroundColor(client.isPrayerActive(prayer)
? ComponentConstants.STANDARD_BACKGROUND_COLOR
: NOT_ACTIVATED_BACKGROUND_COLOR);
prayComponent.setPreferredSize(new Dimension(40, 40));
panelComponent.getChildren().add(prayComponent);
panelComponent.setPreferredSize(new Dimension(40, 40));
panelComponent.setBorder(new Rectangle(0, 0, 0, 0));
return panelComponent.render(graphics);
}
private BufferedImage getPrayerImage(Prayer prayer)
{
switch (prayer)
{
case PROTECT_FROM_MAGIC:
return spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MAGIC, 0);
case PROTECT_FROM_MELEE:
return spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MELEE, 0);
case PROTECT_FROM_MISSILES:
return spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MISSILES, 0);
}
return null;
}
private static BufferedImage scaleImg(final BufferedImage img)
{
if (img == null)
{
return null;
}
final double width = img.getWidth(null);
final double height = img.getHeight(null);
final double size = 36; // Limit size to 2 as that is minimum size not causing breakage
final double scalex = size / width;
final double scaley = size / height;
final double scale = Math.min(scalex, scaley);
final int newWidth = (int) (width * scale);
final int newHeight = (int) (height * scale);
final BufferedImage scaledImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
final Graphics g = scaledImage.createGraphics();
g.drawImage(img, 0, 0, newWidth, newHeight, null);
g.dispose();
return scaledImage;
}
}
@@ -0,0 +1,208 @@
/*
* Copyright (c) 2019, xperiaclash <https://github.com/xperiaclash>
* Copyright (c) 2019, ganom <https://github.com/Ganom>
* 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.gauntlet;
import com.google.common.collect.ImmutableSet;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.AnimationID;
import net.runelite.api.HeadIcon;
import net.runelite.api.NPC;
import net.runelite.api.NPCDefinition;
import net.runelite.api.Prayer;
import net.runelite.api.ProjectileID;
import net.runelite.api.events.AnimationChanged;
import net.runelite.api.events.NpcDespawned;
import net.runelite.api.events.NpcSpawned;
import net.runelite.api.events.ProjectileSpawned;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.PluginType;
import net.runelite.client.ui.overlay.OverlayManager;
@PluginDescriptor(
name = "Gauntlet Boss Helper",
description = "Prayer Overlay For The Gauntlet Boss",
tags = {"gauntlet"},
type = PluginType.PVM,
enabledByDefault = false
)
@Singleton
@Slf4j
public class GauntletPlugin extends Plugin
{
private static final Set<Integer> HUNLEFF_ANIMATIONS = ImmutableSet.of(AnimationID.HUNLEFF_ATTACK, AnimationID.HUNLEFF_TORNADO);
private static final Set<Integer> HUNLEFF_MAGE_PROJECTILES = ImmutableSet.of(ProjectileID.HUNLEFF_MAGE_ATTACK, ProjectileID.HUNLEFF_CORRUPTED_MAGE_ATTACK);
private static final Set<Integer> HUNLEFF_RANGE_PROJECTILES = ImmutableSet.of(ProjectileID.HUNLEFF_RANGE_ATTACK, ProjectileID.HUNLEFF_CORRUPTED_RANGE_ATTACK);
@Inject
private EventBus eventBus;
@Inject
private OverlayManager overlayManager;
@Inject
private GauntletInfoBox GauntletInfoBox;
@Getter(AccessLevel.PACKAGE)
@Setter(AccessLevel.PACKAGE)
private int attacks = 0;
@Getter(AccessLevel.PACKAGE)
@Setter(AccessLevel.PACKAGE)
private Prayer nextPrayer;
@Getter(AccessLevel.PACKAGE)
@Setter(AccessLevel.PACKAGE)
private NPC hunllef;
@Getter(AccessLevel.PRIVATE)
@Setter(AccessLevel.PRIVATE)
private boolean firstHitDetected;
@Override
protected void startUp() throws Exception
{
addSubscriptions();
overlayManager.add(GauntletInfoBox);
}
@Override
protected void shutDown() throws Exception
{
eventBus.unregister(this);
overlayManager.remove(GauntletInfoBox);
reset();
}
private void addSubscriptions()
{
eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned);
eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned);
}
private void onNpcSpawned(NpcSpawned event)
{
final NPC npc = event.getNpc();
if (npc.getName() == null || !npc.getName().toLowerCase().contains("hunllef"))
{
return;
}
setHunllef(npc);
eventBus.subscribe(AnimationChanged.class, "gauntlet", this::onAnimationChanged);
eventBus.subscribe(ProjectileSpawned.class, "gauntlet", this::onProjectileSpawned);
}
private void onNpcDespawned(NpcDespawned event)
{
final NPC npc = event.getNpc();
if (npc.getName() == null || !npc.getName().toLowerCase().contains("hunllef"))
{
return;
}
eventBus.unregister("gauntlet");
reset();
}
private void onProjectileSpawned(ProjectileSpawned event)
{
if (getHunllef() == null || isFirstHitDetected())
{
return;
}
final int projectileID = event.getProjectile().getId();
if (HUNLEFF_MAGE_PROJECTILES.contains(projectileID))
{
setNextPrayer(Prayer.PROTECT_FROM_MAGIC);
setFirstHitDetected(true);
}
else if (HUNLEFF_RANGE_PROJECTILES.contains(projectileID))
{
setNextPrayer(Prayer.PROTECT_FROM_MISSILES);
setFirstHitDetected(true);
}
}
private void onAnimationChanged(AnimationChanged event)
{
if (hunllef == null)
{
return;
}
final int anim = event.getActor().getAnimation();
if (!HUNLEFF_ANIMATIONS.contains(anim))
{
return;
}
setAttacks(getAttacks() + 1);
if (getAttacks() == 4)
{
if (getNextPrayer() == Prayer.PROTECT_FROM_MISSILES)
{
log.debug("Attacks are: {}, switching to prot mage", getAttacks());
setNextPrayer(Prayer.PROTECT_FROM_MAGIC);
}
else if (getNextPrayer() == Prayer.PROTECT_FROM_MAGIC)
{
log.debug("Attacks are: {}, switching to prot missiles", getAttacks());
setNextPrayer(Prayer.PROTECT_FROM_MISSILES);
}
setAttacks(0);
}
}
private void reset()
{
setHunllef(null);
setNextPrayer(null);
setFirstHitDetected(false);
setAttacks(0);
}
private HeadIcon getOverheadIcon(NPC npc)
{
NPCDefinition composition = npc.getDefinition();
if (composition != null)
{
return composition.getOverheadIcon();
}
return null;
}
}
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2019, xperiaclash <https://github.com/xperiaclash>
* Copyright (c) 2019, ganom <https://github.com/Ganom>
* 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.gauntlet;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigItem;
public interface GauntletPluginConfig extends Config
{
@ConfigItem(
position = 0,
keyName = "gauntletEnable",
name = "Enable gauntlet",
description = "gauntlet boss prayer"
)
default boolean enableGauntlet()
{
return true;
}
}
@@ -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);
} }
@@ -1091,6 +1091,7 @@ public class MenuEntrySwapperPlugin extends Plugin
} }
} }
break; break;
case "crystal impling jar":
case "dragon impling jar": case "dragon impling jar":
if (client.getItemContainer(InventoryID.INVENTORY) != null) if (client.getItemContainer(InventoryID.INVENTORY) != null)
{ {
@@ -1350,10 +1351,6 @@ public class MenuEntrySwapperPlugin extends Plugin
swap(client, "empty", option, target, true); swap(client, "empty", option, target, true);
} }
else if (this.swapQuick && option.equals("enter"))
{
swap(client, "quick-enter", option, target, true);
}
else if (this.swapQuick && option.equals("ring")) else if (this.swapQuick && option.equals("ring"))
{ {
swap(client, "quick-start", option, target, true); swap(client, "quick-start", option, target, true);
@@ -1368,14 +1365,17 @@ public class MenuEntrySwapperPlugin extends Plugin
{ {
swap(client, "quick-open", option, target, true); swap(client, "quick-open", option, target, true);
} }
else if (this.swapQuick && option.equals("enter"))
else if (this.swapQuick && (option.equals("enter") || option.equals("enter-crypt")))
{ {
swap(client, "quick-enter", option, target, true); swap(client, "quick-enter", option, target, true);
} }
else if (this.swapQuick && option.equals("leave tomb")) else if (this.swapQuick && option.equals("leave tomb"))
{ {
swap(client, "quick-leave", option, target, true); swap(client, "quick-leave", option, target, true);
} }
else if (this.swapAdmire && option.equals("admire")) else if (this.swapAdmire && option.equals("admire"))
{ {
swap(client, "teleport", option, target, true); swap(client, "teleport", option, target, true);
@@ -150,6 +150,7 @@ public class MiningPlugin extends Plugin
eventBus.subscribe(WallObjectSpawned.class, this, this::onWallObjectSpawned); eventBus.subscribe(WallObjectSpawned.class, this, this::onWallObjectSpawned);
eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked);
eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); eventBus.subscribe(ChatMessage.class, this, this::onChatMessage);
eventBus.subscribe(GameTick.class, this, this::onGameTick);
} }
@Provides @Provides
@@ -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;
} }
@@ -277,6 +277,54 @@ public interface PlayerIndicatorsConfig extends Config
@ConfigItem( @ConfigItem(
position = 19, position = 19,
keyName = "showAgility",
name = "Show Agility Levels",
description = "Show the agility level of attackable players next to their name while in the wilderness.",
group = "Target Indicator"
)
default boolean showAgilityLevel()
{
return false;
}
@ConfigItem(
position = 20,
keyName = "agilityFormat",
name = "Format",
description = "Whether to show the agility level as text, or as icons (1 skull >= 1st threshold, 2 skulls >= 2nd threshold).",
group = "Target Indicator"
)
default PlayerIndicatorsPlugin.AgilityFormats agilityFormat()
{
return PlayerIndicatorsPlugin.AgilityFormats.TEXT;
}
@ConfigItem(
position = 21,
keyName = "agilityFirstThreshold",
name = "Format",
description = "When showing agility as icons, show one icon for agility >= this level.",
group = "Target Indicator"
)
default int agilityFirstThreshold()
{
return 70;
}
@ConfigItem(
position = 22,
keyName = "agilitySecondThreshold",
name = "Format",
description = "When showing agility as icons, show two icons for agility >= this level.",
group = "Target Indicator"
)
default int agilitySecondThreshold()
{
return 84;
}
@ConfigItem(
position = 23,
keyName = "playerSkull", keyName = "playerSkull",
name = "Show Skull Information", name = "Show Skull Information",
description = "Indicate of the player is skulled.", description = "Indicate of the player is skulled.",
@@ -288,7 +336,7 @@ public interface PlayerIndicatorsConfig extends Config
} }
@ConfigItem( @ConfigItem(
position = 19, position = 24,
keyName = "minimapSkullLocation", keyName = "minimapSkullLocation",
name = "Skull Icon Location", name = "Skull Icon Location",
description = "The location of the skull icon for skulled players", description = "The location of the skull icon for skulled players",
@@ -300,7 +348,7 @@ public interface PlayerIndicatorsConfig extends Config
} }
@ConfigItem( @ConfigItem(
position = 19, position = 25,
keyName = "skulledTargetsOnly", keyName = "skulledTargetsOnly",
name = "Tag Skulls Only", name = "Tag Skulls Only",
description = "Only indicate skulled targets (which are also attackable)", description = "Only indicate skulled targets (which are also attackable)",
@@ -312,7 +360,7 @@ public interface PlayerIndicatorsConfig extends Config
} }
@ConfigItem( @ConfigItem(
position = 19, position = 26,
keyName = "targetRisk", keyName = "targetRisk",
name = "Indicate Target Risk", name = "Indicate Target Risk",
description = "Indicates the risk (in K GP) of the target", description = "Indicates the risk (in K GP) of the target",
@@ -335,11 +383,11 @@ public interface PlayerIndicatorsConfig extends Config
}*/ }*/
@ConfigItem( @ConfigItem(
position = 27,
keyName = "useClanchatRanks", keyName = "useClanchatRanks",
name = "Use Ranks as Callers", name = "Use Ranks as Callers",
description = "Uses clanchat ranks as the list of callers", description = "Uses clanchat ranks as the list of callers",
group = "Callers", group = "Callers"
position = 24
) )
default boolean useClanchatRanks() default boolean useClanchatRanks()
{ {
@@ -347,11 +395,11 @@ public interface PlayerIndicatorsConfig extends Config
} }
@ConfigItem( @ConfigItem(
position = 28,
keyName = "callerRank", keyName = "callerRank",
name = "Minimum rank for Clan Caller", name = "Minimum rank for Clan Caller",
description = "Chooses the minimum rank to use as clanchat callers.", description = "Chooses the minimum rank to use as clanchat callers.",
group = "Callers", group = "Callers"
position = 25
) )
default ClanMemberRank callerRank() default ClanMemberRank callerRank()
{ {
@@ -359,6 +407,7 @@ public interface PlayerIndicatorsConfig extends Config
} }
@ConfigItem( @ConfigItem(
position = 29,
keyName = "callers", keyName = "callers",
name = "List of callers to highlight", name = "List of callers to highlight",
description = "Highlights callers, only highlights one at a time. Separate each entry with a comma and enter" + description = "Highlights callers, only highlights one at a time. Separate each entry with a comma and enter" +
@@ -371,6 +420,7 @@ public interface PlayerIndicatorsConfig extends Config
} }
@ConfigItem( @ConfigItem(
position = 30,
keyName = "highlightCallers", keyName = "highlightCallers",
name = "Highlight Callers", name = "Highlight Callers",
description = "Highlights Callers Onscreen", description = "Highlights Callers Onscreen",
@@ -382,7 +432,7 @@ public interface PlayerIndicatorsConfig extends Config
} }
@ConfigItem( @ConfigItem(
position = 26, position = 31,
keyName = "callerColor", keyName = "callerColor",
name = "Caller Color", name = "Caller Color",
description = "Color of Indicated Callers", description = "Color of Indicated Callers",
@@ -394,7 +444,7 @@ public interface PlayerIndicatorsConfig extends Config
} }
@ConfigItem( @ConfigItem(
position = 27, position = 32,
keyName = "unchargedGlory", keyName = "unchargedGlory",
name = "Uncharged Glory Indication", name = "Uncharged Glory Indication",
description = "Indicates if players have an uncharged glory" description = "Indicates if players have an uncharged glory"
@@ -37,8 +37,11 @@ import net.runelite.api.ItemDefinition;
import net.runelite.api.Player; import net.runelite.api.Player;
import net.runelite.api.Point; import net.runelite.api.Point;
import net.runelite.api.SkullIcon; import net.runelite.api.SkullIcon;
import net.runelite.api.Varbits;
import net.runelite.api.WorldType;
import net.runelite.api.kit.KitType; import net.runelite.api.kit.KitType;
import net.runelite.client.game.ClanManager; import net.runelite.client.game.ClanManager;
import net.runelite.client.game.HiscoreManager;
import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemManager;
import net.runelite.client.plugins.friendtagging.FriendTaggingPlugin; import net.runelite.client.plugins.friendtagging.FriendTaggingPlugin;
import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.Overlay;
@@ -47,6 +50,9 @@ import net.runelite.client.ui.overlay.OverlayPriority;
import net.runelite.client.ui.overlay.OverlayUtil; import net.runelite.client.ui.overlay.OverlayUtil;
import net.runelite.client.util.ImageUtil; import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.PvPUtil; import net.runelite.client.util.PvPUtil;
import net.runelite.http.api.hiscore.HiscoreResult;
import net.runelite.http.api.hiscore.HiscoreSkill;
import net.runelite.http.api.hiscore.HiscoreEndpoint;
import static net.runelite.client.util.StackFormatter.formatNumber; import static net.runelite.client.util.StackFormatter.formatNumber;
import net.runelite.client.util.Text; import net.runelite.client.util.Text;
@@ -58,7 +64,12 @@ public class PlayerIndicatorsOverlay extends Overlay
private final PlayerIndicatorsService playerIndicatorsService; private final PlayerIndicatorsService playerIndicatorsService;
private final ClanManager clanManager; private final ClanManager clanManager;
private final HiscoreManager hiscoreManager;
private final PlayerIndicatorsPlugin plugin; private final PlayerIndicatorsPlugin plugin;
private final BufferedImage agilityIcon = ImageUtil.getResourceStreamFromClass(PlayerIndicatorsPlugin.class,
"agility.png");
private final BufferedImage noAgilityIcon = ImageUtil.getResourceStreamFromClass(PlayerIndicatorsPlugin.class,
"no-agility.png");
private final BufferedImage skullIcon = ImageUtil.getResourceStreamFromClass(PlayerIndicatorsPlugin.class, private final BufferedImage skullIcon = ImageUtil.getResourceStreamFromClass(PlayerIndicatorsPlugin.class,
"skull.png"); "skull.png");
@Inject @Inject
@@ -70,11 +81,12 @@ public class PlayerIndicatorsOverlay extends Overlay
@Inject @Inject
private PlayerIndicatorsOverlay(final PlayerIndicatorsPlugin plugin, final PlayerIndicatorsService playerIndicatorsService, private PlayerIndicatorsOverlay(final PlayerIndicatorsPlugin plugin, final PlayerIndicatorsService playerIndicatorsService,
final ClanManager clanManager) final ClanManager clanManager, final HiscoreManager hiscoreManager)
{ {
this.plugin = plugin; this.plugin = plugin;
this.playerIndicatorsService = playerIndicatorsService; this.playerIndicatorsService = playerIndicatorsService;
this.clanManager = clanManager; this.clanManager = clanManager;
this.hiscoreManager = hiscoreManager;
setPosition(OverlayPosition.DYNAMIC); setPosition(OverlayPosition.DYNAMIC);
setPriority(OverlayPriority.MED); setPriority(OverlayPriority.MED);
} }
@@ -174,10 +186,7 @@ public class PlayerIndicatorsOverlay extends Overlay
} }
if (plugin.isShowCombatLevel()) if (plugin.isShowCombatLevel())
{ {
name += " (" + actor.getCombatLevel() + ")";
OverlayUtil.renderTextLocation(graphics, textLocation, name + " (" + actor.getCombatLevel() + ")",
color);
} }
if (plugin.isTargetRisk() && PvPUtil.isAttackable(client, actor) && actor.getPlayerAppearance() != null) if (plugin.isTargetRisk() && PvPUtil.isAttackable(client, actor) && actor.getPlayerAppearance() != null)
{ {
@@ -232,6 +241,58 @@ public class PlayerIndicatorsOverlay extends Overlay
textLocation.getY()); textLocation.getY());
} }
} }
if (plugin.isShowAgilityLevel() && checkWildy())
{
final HiscoreResult hiscoreResult = hiscoreManager.lookupAsync(actor.getName(), HiscoreEndpoint.NORMAL);
if (hiscoreResult != null)
{
int level = hiscoreResult.getSkill(HiscoreSkill.AGILITY).getLevel();
if (plugin.getAgilityFormat() == PlayerIndicatorsPlugin.AgilityFormats.ICONS)
{
int width = graphics.getFontMetrics().stringWidth(name);
int height = graphics.getFontMetrics().getHeight();
if (level >= plugin.getAgilityFirstThreshold())
{
OverlayUtil.renderImageLocation(graphics,
new Point(textLocation.getX() + 5 + width,
textLocation.getY() - height),
ImageUtil.resizeImage(agilityIcon, height, height));
}
if (level >= plugin.getAgilitySecondThreshold())
{
OverlayUtil.renderImageLocation(graphics,
new Point(textLocation.getX() + agilityIcon.getWidth() + width,
textLocation.getY() - height),
ImageUtil.resizeImage(agilityIcon, height, height));
}
if (level < plugin.getAgilityFirstThreshold())
{
OverlayUtil.renderImageLocation(graphics,
new Point(textLocation.getX() + 5 + width,
textLocation.getY() - height),
ImageUtil.resizeImage(noAgilityIcon, height, height));
}
}
else
{
name += " " + level;
int width = graphics.getFontMetrics().stringWidth(name);
int height = graphics.getFontMetrics().getHeight();
OverlayUtil.renderImageLocation(graphics,
new Point(textLocation.getX() + 5 + width,
textLocation.getY() - height),
ImageUtil.resizeImage(agilityIcon, height, height));
}
}
}
OverlayUtil.renderTextLocation(graphics, textLocation, name, color); OverlayUtil.renderTextLocation(graphics, textLocation, name, color);
} }
private boolean checkWildy()
{
return client.getVar(Varbits.IN_WILDERNESS) == 1 || WorldType.isAllPvpWorld(client.getWorldType());
}
} }
@@ -135,6 +135,14 @@ public class PlayerIndicatorsPlugin extends Plugin
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
private Color getTargetColor; private Color getTargetColor;
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
private boolean showAgilityLevel;
@Getter(AccessLevel.PACKAGE)
private int agilityFirstThreshold;
@Getter(AccessLevel.PACKAGE)
private int agilitySecondThreshold;
@Getter(AccessLevel.PACKAGE)
private PlayerIndicatorsPlugin.AgilityFormats agilityFormat;
@Getter(AccessLevel.PACKAGE)
private boolean showCombatLevel; private boolean showCombatLevel;
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
private boolean playerSkull; private boolean playerSkull;
@@ -404,6 +412,12 @@ public class PlayerIndicatorsPlugin extends Plugin
BEFORE_NAME, BEFORE_NAME,
AFTER_NAME AFTER_NAME
} }
public enum AgilityFormats
{
TEXT,
ICONS
}
private void updateConfig() private void updateConfig()
{ {
@@ -427,6 +441,10 @@ public class PlayerIndicatorsPlugin extends Plugin
this.highlightTargets = config.highlightTargets(); this.highlightTargets = config.highlightTargets();
this.getTargetColor = config.getTargetColor(); this.getTargetColor = config.getTargetColor();
this.showCombatLevel = config.showCombatLevel(); this.showCombatLevel = config.showCombatLevel();
this.showAgilityLevel = config.showAgilityLevel();
this.agilityFirstThreshold = config.agilityFirstThreshold();
this.agilitySecondThreshold = config.agilitySecondThreshold();
this.agilityFormat = config.agilityFormat();
this.playerSkull = config.playerSkull(); this.playerSkull = config.playerSkull();
this.skullLocation = config.skullLocation(); this.skullLocation = config.skullLocation();
this.skulledTargetsOnly = config.skulledTargetsOnly(); this.skulledTargetsOnly = config.skulledTargetsOnly();
@@ -55,41 +55,7 @@ import net.runelite.client.ui.ClientUI;
@Slf4j @Slf4j
public class RuneLitePlusPlugin extends Plugin public class RuneLitePlusPlugin extends Plugin
{ {
private class RuneLitePlusKeyListener implements KeyListener private final RuneLitePlusKeyListener keyListener = new RuneLitePlusKeyListener();
{
private int lastKeyCycle;
@Override
public void keyTyped(KeyEvent keyEvent)
{
if (!Character.isDigit(keyEvent.getKeyChar()))
{
return;
}
if (client.getGameCycle() - lastKeyCycle <= 5)
{
keyEvent.consume();
return;
}
lastKeyCycle = client.getGameCycle();
clientThread.invoke(() -> handleKey(keyEvent.getKeyChar()));
keyEvent.consume();
}
@Override
public void keyPressed(KeyEvent keyEvent)
{
}
@Override
public void keyReleased(KeyEvent keyEvent)
{
}
}
@Inject @Inject
private RuneLitePlusConfig config; private RuneLitePlusConfig config;
@@ -107,8 +73,6 @@ public class RuneLitePlusPlugin extends Plugin
@Inject @Inject
private EventBus eventbus; private EventBus eventbus;
private final RuneLitePlusKeyListener keyListener = new RuneLitePlusKeyListener();
private int entered = -1; private int entered = -1;
private int enterIdx; private int enterIdx;
private boolean expectInput; private boolean expectInput;
@@ -117,55 +81,14 @@ public class RuneLitePlusPlugin extends Plugin
protected void startUp() throws Exception protected void startUp() throws Exception
{ {
addSubscriptions(); addSubscriptions();
ClientUI.currentPresenceName = ("RuneLitePlus");
if (config.customPresence()) ClientUI.frame.setTitle(ClientUI.currentPresenceName);
{
ClientUI.currentPresenceName = ("RuneLitePlus");
ClientUI.frame.setTitle(ClientUI.currentPresenceName);
}
discordService.close();
discordService.init();
entered = -1; entered = -1;
enterIdx = 0; enterIdx = 0;
expectInput = false; expectInput = false;
} }
private void onConfigChanged(ConfigChanged event)
{
if (!event.getGroup().equals("runeliteplus"))
{
return;
}
if (event.getKey().equals("customPresence"))
{
if (config.customPresence())
{
ClientUI.currentPresenceName = ("RuneLitePlus");
ClientUI.frame.setTitle(ClientUI.currentPresenceName);
discordService.close();
discordService.init();
}
else
{
ClientUI.currentPresenceName = ("RuneLite");
ClientUI.frame.setTitle(ClientUI.currentPresenceName);
discordService.close();
discordService.init();
}
}
else if (!config.keyboardPin())
{
entered = 0;
enterIdx = 0;
expectInput = false;
keyManager.unregisterKeyListener(keyListener);
}
}
@Override @Override
protected void shutDown() throws Exception protected void shutDown() throws Exception
{ {
@@ -177,6 +100,22 @@ public class RuneLitePlusPlugin extends Plugin
keyManager.unregisterKeyListener(keyListener); keyManager.unregisterKeyListener(keyListener);
} }
private void onConfigChanged(ConfigChanged event)
{
if (!event.getGroup().equals("runeliteplus"))
{
return;
}
else if (!config.keyboardPin())
{
entered = 0;
enterIdx = 0;
expectInput = false;
keyManager.unregisterKeyListener(keyListener);
}
}
private void addSubscriptions() private void addSubscriptions()
{ {
eventbus.subscribe(ConfigChanged.class, this, this::onConfigChanged); eventbus.subscribe(ConfigChanged.class, this, this::onConfigChanged);
@@ -221,10 +160,10 @@ public class RuneLitePlusPlugin extends Plugin
private void handleKey(char c) private void handleKey(char c)
{ {
if (client.getWidget(WidgetID.BANK_PIN_GROUP_ID, BANK_PIN_INSTRUCTION_TEXT.getChildId()) == null if (client.getWidget(WidgetID.BANK_PIN_GROUP_ID, BANK_PIN_INSTRUCTION_TEXT.getChildId()) == null
|| !client.getWidget(BANK_PIN_INSTRUCTION_TEXT).getText().equals("First click the FIRST digit.") || !client.getWidget(BANK_PIN_INSTRUCTION_TEXT).getText().equals("First click the FIRST digit.")
&& !client.getWidget(BANK_PIN_INSTRUCTION_TEXT).getText().equals("Now click the SECOND digit.") && !client.getWidget(BANK_PIN_INSTRUCTION_TEXT).getText().equals("Now click the SECOND digit.")
&& !client.getWidget(BANK_PIN_INSTRUCTION_TEXT).getText().equals("Time for the THIRD digit.") && !client.getWidget(BANK_PIN_INSTRUCTION_TEXT).getText().equals("Time for the THIRD digit.")
&& !client.getWidget(BANK_PIN_INSTRUCTION_TEXT).getText().equals("Finally, the FOURTH digit.")) && !client.getWidget(BANK_PIN_INSTRUCTION_TEXT).getText().equals("Finally, the FOURTH digit."))
{ {
entered = 0; entered = 0;
@@ -261,4 +200,39 @@ public class RuneLitePlusPlugin extends Plugin
entered += num * 10; entered += num * 10;
} }
} }
private class RuneLitePlusKeyListener implements KeyListener
{
private int lastKeyCycle;
@Override
public void keyTyped(KeyEvent keyEvent)
{
if (!Character.isDigit(keyEvent.getKeyChar()))
{
return;
}
if (client.getGameCycle() - lastKeyCycle <= 5)
{
keyEvent.consume();
return;
}
lastKeyCycle = client.getGameCycle();
clientThread.invoke(() -> handleKey(keyEvent.getKeyChar()));
keyEvent.consume();
}
@Override
public void keyPressed(KeyEvent keyEvent)
{
}
@Override
public void keyReleased(KeyEvent keyEvent)
{
}
}
} }
@@ -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();
@@ -293,15 +293,18 @@ public class SlayerPlugin extends Plugin
private int initialAmount; private int initialAmount;
private int lastCertainAmount; private int lastCertainAmount;
private boolean weaknessOverlayAttached;
@Override @Override
protected void startUp() throws Exception protected void startUp() throws Exception
{ {
updateConfig(); updateConfig();
addSubscriptions(); addSubscriptions();
weaknessOverlayAttached = false;
overlayManager.add(overlay); overlayManager.add(overlay);
overlayManager.add(targetClickboxOverlay); overlayManager.add(targetClickboxOverlay);
overlayManager.add(targetWeaknessOverlay);
overlayManager.add(targetMinimapOverlay); overlayManager.add(targetMinimapOverlay);
if (slayerXpDropLookup == null) if (slayerXpDropLookup == null)
@@ -439,7 +442,7 @@ public class SlayerPlugin extends Plugin
} }
} }
void onVarbitChanged(VarbitChanged event) public void onVarbitChanged(VarbitChanged event)
{ {
if (client.getVar(Varbits.SLAYER_REWARD_POINTS) == cachedPoints) if (client.getVar(Varbits.SLAYER_REWARD_POINTS) == cachedPoints)
{ {
@@ -553,7 +556,7 @@ public class SlayerPlugin extends Plugin
private static final int FORCED_WAIT = 2; private static final int FORCED_WAIT = 2;
private int forcedWait = -1; private int forcedWait = -1;
void onGameTick(GameTick tick) public void onGameTick(GameTick tick)
{ {
loginTick = false; loginTick = false;
@@ -634,7 +637,7 @@ public class SlayerPlugin extends Plugin
} }
} }
void onChatMessage(ChatMessage event) public void onChatMessage(ChatMessage event)
{ {
if (event.getType() != ChatMessageType.GAMEMESSAGE && event.getType() != ChatMessageType.SPAM) if (event.getType() != ChatMessageType.GAMEMESSAGE && event.getType() != ChatMessageType.SPAM)
{ {
@@ -719,7 +722,7 @@ public class SlayerPlugin extends Plugin
} }
} }
void onExperienceChanged(ExperienceChanged event) public void onExperienceChanged(ExperienceChanged event)
{ {
if (event.getSkill() != SLAYER) if (event.getSkill() != SLAYER)
{ {
@@ -1002,7 +1005,7 @@ public class SlayerPlugin extends Plugin
} }
} }
void setTask(String name, int amt, int initAmt, boolean isNewAssignment, int lastCertainAmt) public void setTask(String name, int amt, int initAmt, boolean isNewAssignment, int lastCertainAmt)
{ {
setTask(name, amt, initAmt, isNewAssignment, null, lastCertainAmt); setTask(name, amt, initAmt, isNewAssignment, null, lastCertainAmt);
} }
@@ -1030,6 +1033,17 @@ public class SlayerPlugin extends Plugin
rebuildTargetIds(task); rebuildTargetIds(task);
rebuildCheckAsTokens(task); rebuildCheckAsTokens(task);
rebuildTargetList(); rebuildTargetList();
if (!weaknessOverlayAttached && task.getWeaknessItem() != -1 && task.getWeaknessThreshold() != -1)
{
overlayManager.add(targetWeaknessOverlay);
weaknessOverlayAttached = true;
}
else if (weaknessOverlayAttached && task.getWeaknessItem() == -1 && task.getWeaknessThreshold() == -1)
{
overlayManager.remove(targetWeaknessOverlay);
weaknessOverlayAttached = false;
}
} }
AsyncBufferedImage getImageForTask(Task task) AsyncBufferedImage getImageForTask(Task task)
@@ -1293,4 +1307,4 @@ public class SlayerPlugin extends Plugin
this.lastCertainAmount = config.lastCertainAmount(); this.lastCertainAmount = config.lastCertainAmount();
this.taskLocation = config.taskLocation(); this.taskLocation = config.taskLocation();
} }
} }
@@ -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();
Binary file not shown.

After

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 B

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