Merge branch 'master' into party-time

This commit is contained in:
Kyle
2020-01-11 23:18:00 +00:00
committed by GitHub
299 changed files with 5164 additions and 2652 deletions
+4
View File
@@ -12,6 +12,10 @@ jobs:
- uses: actions/checkout@v1 - uses: actions/checkout@v1
- name: Make gradlew executable - name: Make gradlew executable
run: chmod +x ./gradlew run: chmod +x ./gradlew
- name: Set up JDK 11
uses: actions/setup-java@v1
with:
java-version: 11
- name: Update Gradle Wrapper - name: Update Gradle Wrapper
run: ./gradlew wrapper --gradle-version $(curl -s https://api.github.com/repos/gradle/gradle/releases/latest | grep -Po '"name":.*?[^\\]",' | sed -r 's/[\"name:, ]+//g') --distribution-type all --console=plain run: ./gradlew wrapper --gradle-version $(curl -s https://api.github.com/repos/gradle/gradle/releases/latest | grep -Po '"name":.*?[^\\]",' | sed -r 's/[\"name:, ]+//g') --distribution-type all --console=plain
- name: Create Gradle wrapper update Pull Request - name: Create Gradle wrapper update Pull Request
+2
View File
@@ -21,3 +21,5 @@ classes/artifacts/client_jar/client.jar
runelite-client/src/main/resources/runelite/* runelite-client/src/main/resources/runelite/*
runelite-client/dependencies.txt runelite-client/dependencies.txt
.staging/ .staging/
.vscode
.factorypath
-3
View File
@@ -49,7 +49,6 @@ plugins {
val grgit = Grgit.open(mapOf("dir" to rootProject.projectDir.absolutePath)) val grgit = Grgit.open(mapOf("dir" to rootProject.projectDir.absolutePath))
val localGitCommit = grgit.head().id val localGitCommit = grgit.head().id
val localGitCommitShort = grgit.head().getAbbreviatedId(7)
fun isNonStable(version: String): Boolean { fun isNonStable(version: String): Boolean {
return listOf("ALPHA", "BETA", "RC").any { return listOf("ALPHA", "BETA", "RC").any {
@@ -77,8 +76,6 @@ subprojects {
apply(plugin = Plugins.testLogger.first) apply(plugin = Plugins.testLogger.first)
project.extra["gitCommit"] = localGitCommit project.extra["gitCommit"] = localGitCommit
project.extra["gitCommitShort"] = localGitCommitShort
project.extra["rootPath"] = rootDir.toString().replace("\\", "/") project.extra["rootPath"] = rootDir.toString().replace("\\", "/")
if (this.name != "runescape-client") { if (this.name != "runescape-client") {
+22 -23
View File
@@ -25,22 +25,22 @@
object ProjectVersions { object ProjectVersions {
const val launcherVersion = "2.0.4" const val launcherVersion = "2.0.4"
const val rlVersion = "1.5.44-SNAPSHOT" const val rlVersion = "1.6.2-SNAPSHOT"
const val openosrsVersion = "2.1.19-SNAPSHOT" const val openosrsVersion = "2.1.21-SNAPSHOT"
const val rsversion = 187 const val rsversion = 187
const val cacheversion = 165 const val cacheversion = 165
} }
object Plugins { object Plugins {
val grgitPlugin = "org.ajoberstar:grgit:2.3.0" val grgitPlugin = "org.ajoberstar.grgit:grgit-core:4.0.1"
val versionsPlugin = "com.github.ben-manes:gradle-versions-plugin:0.27.0" val versionsPlugin = "com.github.ben-manes:gradle-versions-plugin:0.27.0"
val injectorPlugin = "com.openosrs:injector-plugin:1.0.3.0" val injectorPlugin = "com.openosrs:injector-plugin:1.0.3.0"
val testLogger = Pair("com.adarshr.test-logger", "2.0.0") val testLogger = Pair("com.adarshr.test-logger", "2.0.0")
val versions = Pair("com.github.ben-manes.versions", "0.27.0") val versions = Pair("com.github.ben-manes.versions", "0.27.0")
val latestVersion = Pair("se.patrikerdes.use-latest-versions", "0.2.13") val latestVersion = Pair("se.patrikerdes.use-latest-versions", "0.2.13")
val grgit = Pair("org.ajoberstar.grgit", "4.0.0-rc.1") val grgit = Pair("org.ajoberstar.grgit", "4.0.1")
val jarTest = Pair("com.github.hauner.jarTest", "1.0.1") val jarTest = Pair("com.github.hauner.jarTest", "1.0.1")
val shadow = Pair("com.github.johnrengelman.shadow", "5.2.0") val shadow = Pair("com.github.johnrengelman.shadow", "5.2.0")
} }
@@ -58,46 +58,45 @@ object Libraries {
const val fernflower = "07082019" const val fernflower = "07082019"
const val findbugs = "3.0.2" const val findbugs = "3.0.2"
const val gson = "2.8.6" const val gson = "2.8.6"
const val guava = "28.1-jre" const val guava = "28.2-jre"
const val guice = "4.2.2" const val guice = "4.2.2"
const val h2 = "1.4.200" const val h2 = "1.4.200"
const val hamcrest = "2.2" const val hamcrest = "2.2"
const val javax = "1.3.2" const val javax = "1.3.2"
const val javaxInject = "1" const val javaxInject = "1"
const val jedis = "3.1.0" const val jedis = "3.2.0"
const val jna = "5.5.0" const val jna = "5.5.0"
const val jogamp = "2.3.2" const val jogamp = "2.3.2"
const val jopt = "5.0.4" const val jopt = "5.0.4"
const val jooq = "3.12.3" const val jooq = "3.12.3"
const val junit = "4.12" const val junit = "4.13"
const val jupiter = "5.6.0-M1" const val jupiter = "5.6.0-M1"
const val logback = "1.2.3" const val logback = "1.2.3"
const val lombok = "1.18.10" const val lombok = "1.18.10"
const val mapstruct = "1.3.1.Final" const val mapstruct = "1.3.1.Final"
const val mariadbJdbc = "2.5.1" const val mariadbJdbc = "2.5.2"
const val mavenPluginAnnotations = "3.6.0" const val mavenPluginAnnotations = "3.6.0"
const val mavenPluginApi = "3.6.2" const val mavenPluginApi = "3.6.3"
const val minio = "6.0.11" const val minio = "6.0.11"
const val mockito = "3.1.0" const val mockito = "3.2.4"
const val mongodbDriverSync = "3.11.2" const val mongodbDriverSync = "3.12.0"
const val mysqlConnectorJava = "8.0.18" const val mysqlConnectorJava = "8.0.18"
const val naturalMouse = "2.0.2" const val naturalMouse = "2.0.2"
const val netty = "4.1.43.Final" const val netty = "4.1.44.Final"
const val okhttp3 = "4.2.2" const val okhttp3 = "4.3.0"
const val orangeExtensions = "1.0" const val orangeExtensions = "1.0"
const val petitparser = "2.2.0" const val petitparser = "2.3.1"
const val plexus = "3.3.0" const val plexus = "3.3.0"
const val rxjava = "2.2.14" const val radiance = "2.5.1"
const val rxjava = "2.2.16"
const val rxrelay = "2.1.1" const val rxrelay = "2.1.1"
const val scribejava = "6.9.0" const val scribejava = "6.9.0"
const val sisu = "0.3.4" const val sisu = "0.3.4"
const val sentry = "1.7.28" const val sentry = "1.7.29"
const val slf4j = "1.7.29" const val slf4j = "1.7.30"
const val springJdbc = "5.2.1.RELEASE" const val springJdbc = "5.2.2.RELEASE"
const val springboot = "2.2.1.RELEASE" const val springboot = "2.2.2.RELEASE"
const val sql2o = "1.6.0" const val sql2o = "1.6.0"
const val substance = "8.0.02"
const val trident = "1.5.00"
} }
const val annotations = "org.jetbrains:annotations:${Versions.annotations}" const val annotations = "org.jetbrains:annotations:${Versions.annotations}"
@@ -175,7 +174,7 @@ object Libraries {
const val springbootStarterTomcat = "org.springframework.boot:spring-boot-starter-tomcat:${Versions.springboot}" const val springbootStarterTomcat = "org.springframework.boot:spring-boot-starter-tomcat:${Versions.springboot}"
const val springbootJdbc = "org.springframework:spring-jdbc:${Versions.springJdbc}" const val springbootJdbc = "org.springframework:spring-jdbc:${Versions.springJdbc}"
const val sql2o = "org.sql2o:sql2o:${Versions.sql2o}" const val sql2o = "org.sql2o:sql2o:${Versions.sql2o}"
const val substance = "net.runelite.pushingpixels:substance:${Versions.substance}" const val substance = "org.pushing-pixels:radiance-substance:${Versions.radiance}"
const val trident = "net.runelite.pushingpixels:trident:${Versions.trident}" const val trident = "org.pushing-pixels:radiance-trident:${Versions.radiance}"
const val vanilla = "net.runelite.rs:vanilla:${ProjectVersions.rsversion}" const val vanilla = "net.runelite.rs:vanilla:${ProjectVersions.rsversion}"
} }
+4 -1
View File
@@ -46,9 +46,12 @@ dependencies {
implementation(Libraries.apacheCommonsCompress) implementation(Libraries.apacheCommonsCompress)
implementation(Libraries.slf4jApi) implementation(Libraries.slf4jApi)
testAnnotationProcessor(Libraries.lombok)
testCompileOnly(Libraries.lombok)
testImplementation(Libraries.junit) testImplementation(Libraries.junit)
testImplementation(group = "net.runelite.rs", name = "cache", version = "${ProjectVersions.cacheversion}") testImplementation(group = "net.runelite.rs", name = "cache", version = "${ProjectVersions.cacheversion}")
testImplementation(Libraries.slf4jSimple)
} }
tasks { tasks {
@@ -36,6 +36,7 @@ public enum ConfigType
ENUM(8), ENUM(8),
NPC(9), NPC(9),
ITEM(10), ITEM(10),
PARAMS(11),
SEQUENCE(12), SEQUENCE(12),
SPOTANIM(13), SPOTANIM(13),
VARBIT(14), VARBIT(14),
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, Adam <Adam@sigterm.info> * Copyright (c) 2020, 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,14 +22,16 @@
* (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.chat; package net.runelite.cache.definitions;
import net.runelite.client.events.ChatboxInput; import lombok.Data;
import net.runelite.client.events.PrivateMessageInput; import net.runelite.cache.util.ScriptVarType;
public interface ChatboxInputListener @Data
public class ParamDefinition
{ {
boolean onChatboxInput(ChatboxInput chatboxInput); private ScriptVarType type;
private boolean isMembers = true;
boolean onPrivateMessageInput(PrivateMessageInput privateMessageInput); private int defaultInt;
private String defaultString;
} }
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2020, 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.cache.definitions.loaders;
import net.runelite.cache.definitions.ParamDefinition;
import net.runelite.cache.io.InputStream;
import net.runelite.cache.util.ScriptVarType;
public class ParamLoader
{
public ParamDefinition load(byte[] data)
{
ParamDefinition def = new ParamDefinition();
InputStream b = new InputStream(data);
for (; ; )
{
int opcode = b.readUnsignedByte();
switch (opcode)
{
case 0:
return def;
case 1:
{
int idx = b.readByte();
def.setType(ScriptVarType.forCharKey((char) idx));
break;
}
case 2:
def.setDefaultInt(b.readInt());
break;
case 4:
def.setMembers(false);
break;
case 5:
def.setDefaultString(b.readString());
break;
}
}
}
}
+88
View File
@@ -0,0 +1,88 @@
/*
* Copyright (c) 2020, 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.cache;
import com.google.common.io.Files;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import lombok.extern.slf4j.Slf4j;
import net.runelite.cache.definitions.ParamDefinition;
import net.runelite.cache.definitions.loaders.ParamLoader;
import net.runelite.cache.fs.Archive;
import net.runelite.cache.fs.ArchiveFiles;
import net.runelite.cache.fs.FSFile;
import net.runelite.cache.fs.Index;
import net.runelite.cache.fs.Storage;
import net.runelite.cache.fs.Store;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
@Slf4j
public class ParamDumper
{
private Gson gson = new GsonBuilder().setPrettyPrinting().create();
@Rule
public TemporaryFolder folder = StoreLocation.getTemporaryFolder();
@Test
@Ignore
public void test() throws IOException
{
File dumpDir = folder.newFolder();
int count = 0;
try (Store store = new Store(StoreLocation.LOCATION))
{
store.load();
Storage storage = store.getStorage();
Index index = store.getIndex(IndexType.CONFIGS);
Archive archive = index.getArchive(ConfigType.PARAMS.getId());
ParamLoader loader = new ParamLoader();
byte[] archiveData = storage.loadArchive(archive);
ArchiveFiles files = archive.getFiles(archiveData);
for (FSFile file : files.getFiles())
{
byte[] b = file.getContents();
ParamDefinition def = loader.load(b);
Files.asCharSink(new File(dumpDir, file.getFileId() + ".json"), Charset.defaultCharset()).write(gson.toJson(def));
++count;
}
}
log.info("Dumped {} params to {}", count, dumpDir);
}
}
@@ -203,7 +203,7 @@ public class HiscoreResult
return chaosElemental; return chaosElemental;
case CHAOS_FANATIC: case CHAOS_FANATIC:
return chaosFanatic; return chaosFanatic;
case COMMMANDER_ZILYANA: case COMMANDER_ZILYANA:
return commanderZilyana; return commanderZilyana;
case CORPOREAL_BEAST: case CORPOREAL_BEAST:
return corporealBeast; return corporealBeast;
@@ -94,8 +94,8 @@ class HiscoreResultBuilder
hiscoreResult.setAlchemicalHydra(skills.get(index++)); hiscoreResult.setAlchemicalHydra(skills.get(index++));
hiscoreResult.setBarrowsChests(skills.get(index++)); hiscoreResult.setBarrowsChests(skills.get(index++));
hiscoreResult.setBryophyta(skills.get(index++)); hiscoreResult.setBryophyta(skills.get(index++));
// hiscoreResult.setCallisto(skills.get(index++)); hiscoreResult.setCallisto(skills.get(index++));
// hiscoreResult.setCerberus(skills.get(index++)); hiscoreResult.setCerberus(skills.get(index++));
hiscoreResult.setChambersOfXeric(skills.get(index++)); hiscoreResult.setChambersOfXeric(skills.get(index++));
hiscoreResult.setChambersOfXericChallengeMode(skills.get(index++)); hiscoreResult.setChambersOfXericChallengeMode(skills.get(index++));
hiscoreResult.setChaosElemental(skills.get(index++)); hiscoreResult.setChaosElemental(skills.get(index++));
@@ -26,89 +26,93 @@ package net.runelite.http.api.hiscore;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import static net.runelite.http.api.hiscore.HiscoreSkillType.SKILL;
import static net.runelite.http.api.hiscore.HiscoreSkillType.ACTIVITY;
import static net.runelite.http.api.hiscore.HiscoreSkillType.BOSS;
@AllArgsConstructor @AllArgsConstructor
@Getter @Getter
public enum HiscoreSkill public enum HiscoreSkill
{ {
OVERALL("Overall"), OVERALL("Overall", HiscoreSkillType.OVERALL),
ATTACK("Attack"), ATTACK("Attack", SKILL),
DEFENCE("Defence"), DEFENCE("Defence", SKILL),
STRENGTH("Strength"), STRENGTH("Strength", SKILL),
HITPOINTS("Hitpoints"), HITPOINTS("Hitpoints", SKILL),
RANGED("Ranged"), RANGED("Ranged", SKILL),
PRAYER("Prayer"), PRAYER("Prayer", SKILL),
MAGIC("Magic"), MAGIC("Magic", SKILL),
COOKING("Cooking"), COOKING("Cooking", SKILL),
WOODCUTTING("Woodcutting"), WOODCUTTING("Woodcutting", SKILL),
FLETCHING("Fletching"), FLETCHING("Fletching", SKILL),
FISHING("Fishing"), FISHING("Fishing", SKILL),
FIREMAKING("Firemaking"), FIREMAKING("Firemaking", SKILL),
CRAFTING("Crafting"), CRAFTING("Crafting", SKILL),
SMITHING("Smithing"), SMITHING("Smithing", SKILL),
MINING("Mining"), MINING("Mining", SKILL),
HERBLORE("Herblore"), HERBLORE("Herblore", SKILL),
AGILITY("Agility"), AGILITY("Agility", SKILL),
THIEVING("Thieving"), THIEVING("Thieving", SKILL),
SLAYER("Slayer"), SLAYER("Slayer", SKILL),
FARMING("Farming"), FARMING("Farming", SKILL),
RUNECRAFT("Runecraft"), RUNECRAFT("Runecraft", SKILL),
HUNTER("Hunter"), HUNTER("Hunter", SKILL),
CONSTRUCTION("Construction"), CONSTRUCTION("Construction", SKILL),
LEAGUE_POINTS("League Points"), LEAGUE_POINTS("League Points", ACTIVITY),
BOUNTY_HUNTER_HUNTER("Bounty Hunter - Hunter"), BOUNTY_HUNTER_HUNTER("Bounty Hunter - Hunter", ACTIVITY),
BOUNTY_HUNTER_ROGUE("Bounty Hunter - Rogue"), BOUNTY_HUNTER_ROGUE("Bounty Hunter - Rogue", ACTIVITY),
CLUE_SCROLL_ALL("Clue Scrolls (all)"), CLUE_SCROLL_ALL("Clue Scrolls (all)", ACTIVITY),
CLUE_SCROLL_BEGINNER("Clue Scrolls (beginner)"), CLUE_SCROLL_BEGINNER("Clue Scrolls (beginner)", ACTIVITY),
CLUE_SCROLL_EASY("Clue Scrolls (easy)"), CLUE_SCROLL_EASY("Clue Scrolls (easy)", ACTIVITY),
CLUE_SCROLL_MEDIUM("Clue Scrolls (medium)"), CLUE_SCROLL_MEDIUM("Clue Scrolls (medium)", ACTIVITY),
CLUE_SCROLL_HARD("Clue Scrolls (hard)"), CLUE_SCROLL_HARD("Clue Scrolls (hard)", ACTIVITY),
CLUE_SCROLL_ELITE("Clue Scrolls (elite)"), CLUE_SCROLL_ELITE("Clue Scrolls (elite)", ACTIVITY),
CLUE_SCROLL_MASTER("Clue Scrolls (master)"), CLUE_SCROLL_MASTER("Clue Scrolls (master)", ACTIVITY),
LAST_MAN_STANDING("Last Man Standing"), LAST_MAN_STANDING("Last Man Standing", ACTIVITY),
ABYSSAL_SIRE("Abyssal Sire"), ABYSSAL_SIRE("Abyssal Sire", BOSS),
ALCHEMICAL_HYDRA("Alchemical Hydra"), ALCHEMICAL_HYDRA("Alchemical Hydra", BOSS),
BARROWS_CHESTS("Barrows Chests"), BARROWS_CHESTS("Barrows Chests", BOSS),
BRYOPHYTA("Bryophyta"), BRYOPHYTA("Bryophyta", BOSS),
CALLISTO("Callisto"), CALLISTO("Callisto", BOSS),
CERBERUS("Cerberus"), CERBERUS("Cerberus", BOSS),
CHAMBERS_OF_XERIC("Chambers of Xeric"), CHAMBERS_OF_XERIC("Chambers of Xeric", BOSS),
CHAMBERS_OF_XERIC_CHALLENGE_MODE("Chambers of Xeric: Challenge Mode"), CHAMBERS_OF_XERIC_CHALLENGE_MODE("Chambers of Xeric: Challenge Mode", BOSS),
CHAOS_ELEMENTAL("Chaos Elemental"), CHAOS_ELEMENTAL("Chaos Elemental", BOSS),
CHAOS_FANATIC("Chaos Fanatic"), CHAOS_FANATIC("Chaos Fanatic", BOSS),
COMMMANDER_ZILYANA("Commander Zilyana"), COMMANDER_ZILYANA("Commander Zilyana", BOSS),
CORPOREAL_BEAST("Corporeal Beast"), CORPOREAL_BEAST("Corporeal Beast", BOSS),
CRAZY_ARCHAEOLOGIST("Crazy Archaeologist"), CRAZY_ARCHAEOLOGIST("Crazy Archaeologist", BOSS),
DAGANNOTH_PRIME("Dagannoth Prime"), DAGANNOTH_PRIME("Dagannoth Prime", BOSS),
DAGANNOTH_REX("Dagannoth Rex"), DAGANNOTH_REX("Dagannoth Rex", BOSS),
DAGANNOTH_SUPREME("Dagannoth Supreme"), DAGANNOTH_SUPREME("Dagannoth Supreme", BOSS),
DERANGED_ARCHAEOLOGIST("Deranged Archaeologist"), DERANGED_ARCHAEOLOGIST("Deranged Archaeologist", BOSS),
GENERAL_GRAARDOR("General Graardor"), GENERAL_GRAARDOR("General Graardor", BOSS),
GIANT_MOLE("Giant Mole"), GIANT_MOLE("Giant Mole", BOSS),
GROTESQUE_GUARDIANS("Grotesque Guardians"), GROTESQUE_GUARDIANS("Grotesque Guardians", BOSS),
HESPORI("Hespori"), HESPORI("Hespori", BOSS),
KALPHITE_QUEEN("Kalphite Queen"), KALPHITE_QUEEN("Kalphite Queen", BOSS),
KING_BLACK_DRAGON("King Black Dragon"), KING_BLACK_DRAGON("King Black Dragon", BOSS),
KRAKEN("Kraken"), KRAKEN("Kraken", BOSS),
KREEARRA("Kree'Arra"), KREEARRA("Kree'Arra", BOSS),
KRIL_TSUTSAROTH("K'ril Tsutsaroth"), KRIL_TSUTSAROTH("K'ril Tsutsaroth", BOSS),
MIMIC("Mimic"), MIMIC("Mimic", BOSS),
OBOR("Obor"), OBOR("Obor", BOSS),
SARACHNIS("Sarachnis"), SARACHNIS("Sarachnis", BOSS),
SCORPIA("Scorpia"), SCORPIA("Scorpia", BOSS),
SKOTIZO("Skotizo"), SKOTIZO("Skotizo", BOSS),
THE_GAUNTLET("The Gauntlet"), THE_GAUNTLET("The Gauntlet", BOSS),
THE_CORRUPTED_GAUNTLET("The Corrupted Gauntlet"), THE_CORRUPTED_GAUNTLET("The Corrupted Gauntlet", BOSS),
THEATRE_OF_BLOOD("Theatre of Blood"), THEATRE_OF_BLOOD("Theatre of Blood", BOSS),
THERMONUCLEAR_SMOKE_DEVIL("Thermonuclear Smoke Devil"), THERMONUCLEAR_SMOKE_DEVIL("Thermonuclear Smoke Devil", BOSS),
TZKAL_ZUK("TzKal-Zuk"), TZKAL_ZUK("TzKal-Zuk", BOSS),
TZTOK_JAD("TzTok-Jad"), TZTOK_JAD("TzTok-Jad", BOSS),
VENENATIS("Venenatis"), VENENATIS("Venenatis", BOSS),
VETION("Vet'ion"), VETION("Vet'ion", BOSS),
VORKATH("Vorkath"), VORKATH("Vorkath", BOSS),
WINTERTODT("Wintertodt"), WINTERTODT("Wintertodt", BOSS),
ZALCANO("Zalcano"), ZALCANO("Zalcano", BOSS),
ZULRAH("Zulrah"); ZULRAH("Zulrah", BOSS);
private final String name; private final String name;
private final HiscoreSkillType type;
} }
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2019, Bram91 <https://github.com/bram91>
* 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.http.api.hiscore;
public enum HiscoreSkillType
{
OVERALL,
SKILL,
ACTIVITY,
BOSS
}
@@ -27,7 +27,6 @@ package net.runelite.http.service.feed;
import com.google.common.hash.HashCode; import com.google.common.hash.HashCode;
import com.google.common.hash.Hasher; import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing; import com.google.common.hash.Hashing;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@@ -92,27 +91,27 @@ public class FeedController
{ {
items.addAll(blogService.getBlogPosts()); items.addAll(blogService.getBlogPosts());
} }
catch (IOException e) catch (Exception e)
{ {
log.warn(e.getMessage()); log.warn("unable to fetch blogs", e);
} }
try try
{ {
items.addAll(twitterService.getTweets()); items.addAll(twitterService.getTweets());
} }
catch (IOException e) catch (Exception e)
{ {
log.warn(e.getMessage()); log.warn("unable to fetch tweets", e);
} }
try try
{ {
items.addAll(osrsNewsService.getNews()); items.addAll(osrsNewsService.getNews());
} }
catch (IOException e) catch (Exception e)
{ {
log.warn(e.getMessage()); log.warn("unable to fetch news", e);
} }
memoizedFeed = new MemoizedFeed(new FeedResult(items)); memoizedFeed = new MemoizedFeed(new FeedResult(items));
@@ -37,40 +37,83 @@ import org.junit.Test;
public class HiscoreServiceTest public class HiscoreServiceTest
{ {
private static final String RESPONSE = "654683,705,1304518\n" private static final String RESPONSE = "654683,705,1304518\n"
+ "679419,50,107181\n" + "679419,50,107181\n"
+ "550667,48,85764\n" + "550667,48,85764\n"
+ "861497,50,101366\n" + "861497,50,101366\n"
+ "891591,48,87843\n" + "891591,48,87843\n"
+ "-1,1,4\n" + "-1,1,4\n"
+ "840255,27,10073\n" + "840255,27,10073\n"
+ "1371912,10,1310\n" + "1371912,10,1310\n"
+ "432193,56,199795\n" + "432193,56,199795\n"
+ "495638,56,198304\n" + "495638,56,198304\n"
+ "514466,37,27502\n" + "514466,37,27502\n"
+ "456981,54,159727\n" + "456981,54,159727\n"
+ "459159,49,93010\n" + "459159,49,93010\n"
+ "1028855,8,823\n" + "1028855,8,823\n"
+ "862906,29,12749\n" + "862906,29,12749\n"
+ "795020,31,16097\n" + "795020,31,16097\n"
+ "673591,5,495\n" + "673591,5,495\n"
+ "352676,51,112259\n" + "352676,51,112259\n"
+ "428419,40,37235\n" + "428419,40,37235\n"
+ "461887,43,51971\n" + "461887,43,51971\n"
+ "598582,1,10\n" + "598582,1,10\n"
+ "638177,1,0\n" + "638177,1,0\n"
+ "516239,9,1000\n" + "516239,9,1000\n"
+ "492790,1,0\n" + "492790,1,0\n"
+ "2,2460\n" // leagues + "2,2460\n" // leagues
+ "-1,-1\n" + "-1,-1\n"
+ "73,1738\n" + "73,1738\n"
+ "531,1432\n" + "531,1432\n"
+ "324,212\n" + "324,212\n"
+ "8008,131\n" + "8008,131\n"
+ "1337,911\n" + "1337,911\n"
+ "42,14113\n" + "42,14113\n"
+ "1,777\n" + "1,777\n"
+ "254,92\n" + "254,92\n"
+ "-1,-1\n"; // lms + "-1,-1\n" // lms
+ "24870,37\n"
+ "15020,388\n"
+ "50463,147\n"
+ "-1,-1\n"
+ "92357,1\n"
+ "22758,637\n"
+ "22744,107\n"
+ "-1,-1\n"
+ "20150,17\n"
+ "29400,18\n"
+ "13465,172\n"
+ "1889,581\n"
+ "42891,11\n"
+ "1624,1957\n"
+ "1243,2465\n"
+ "1548,2020\n"
+ "-1,-1\n"
+ "16781,327\n"
+ "19004,149\n"
+ "-1,-1\n"
+ "72046,5\n"
+ "5158,374\n"
+ "20902,279\n"
+ "702,6495\n"
+ "10170,184\n"
+ "8064,202\n"
+ "6936,2\n"
+ "-1,-1\n"
+ "-1,-1\n"
+ "19779,22\n"
+ "58283,10\n"
+ "-1,-1\n"
+ "-1,-1\n"
+ "-1,-1\n"
+ "29347,130\n"
+ "723,4\n"
+ "1264,38\n"
+ "44595,4\n"
+ "24820,4\n"
+ "12116,782\n"
+ "2299,724\n"
+ "19301,62\n"
+ "1498,5847\n";
private final MockWebServer server = new MockWebServer(); private final MockWebServer server = new MockWebServer();
@@ -107,6 +150,8 @@ public class HiscoreServiceTest
Assert.assertEquals(254, result.getClueScrollMaster().getRank()); Assert.assertEquals(254, result.getClueScrollMaster().getRank());
Assert.assertEquals(-1, result.getLastManStanding().getLevel()); Assert.assertEquals(-1, result.getLastManStanding().getLevel());
Assert.assertEquals(2460, result.getLeaguePoints().getLevel()); Assert.assertEquals(2460, result.getLeaguePoints().getLevel());
Assert.assertEquals(37, result.getAbyssalSire().getLevel());
Assert.assertEquals(92357, result.getCallisto().getRank());
Assert.assertEquals(5847, result.getZulrah().getLevel());
} }
} }
@@ -11367,5 +11367,20 @@ public final class ItemID
public static final int VOLATILE_NIGHTMARE_STAFF = 24424; public static final int VOLATILE_NIGHTMARE_STAFF = 24424;
public static final int ELDRITCH_NIGHTMARE_STAFF = 24425; public static final int ELDRITCH_NIGHTMARE_STAFF = 24425;
public static final int CABBAGE_24426 = 24426; public static final int CABBAGE_24426 = 24426;
public static final int GREEN_GINGERBREAD_SHIELD = 24428;
public static final int RED_GINGERBREAD_SHIELD = 24430;
public static final int BLUE_GINGERBREAD_SHIELD = 24431;
public static final int FESTIVE_CINNAMON_STICK = 24432;
public static final int FESTIVE_GINGER_POWDER = 24433;
public static final int FESTIVE_EGG = 24434;
public static final int FESTIVE_POT = 24435;
public static final int FESTIVE_FLOUR = 24436;
public static final int GINGERBREAD_SHIELD = 24437;
public static final int ICED_GINGERBREAD_SHIELD = 24438;
public static final int ICED_GINGERBREAD_SHIELD_24439 = 24439;
public static final int ICED_GINGERBREAD_SHIELD_24440 = 24440;
public static final int SCAPERUNE_TELEPORT = 24441;
public static final int BAKERY_STORAGE_KEY = 24442;
public static final int GINGERBREAD_GNOME = 24443;
/* This file is automatically generated. Do not edit. */ /* This file is automatically generated. Do not edit. */
} }
@@ -98,7 +98,8 @@ public final class NpcID
public static final int GHOST_95 = 95; public static final int GHOST_95 = 95;
public static final int GHOST_96 = 96; public static final int GHOST_96 = 96;
public static final int GHOST_97 = 97; public static final int GHOST_97 = 97;
public static final int DEATH_WING = 99; public static final int GHOST_98 = 98;
public static final int GHOST_99 = 99;
public static final int ROCK_CRAB = 100; public static final int ROCK_CRAB = 100;
public static final int ROCKS = 101; public static final int ROCKS = 101;
public static final int ROCK_CRAB_102 = 102; public static final int ROCK_CRAB_102 = 102;
@@ -459,9 +460,9 @@ public final class NpcID
public static final int SKELETAL_WYVERN_468 = 468; public static final int SKELETAL_WYVERN_468 = 468;
public static final int KILLERWATT = 469; public static final int KILLERWATT = 469;
public static final int KILLERWATT_470 = 470; public static final int KILLERWATT_470 = 470;
public static final int DARK_WIZARD = 472; public static final int GHOST_472 = 472;
public static final int INVRIGAR_THE_NECROMANCER = 473; public static final int GHOST_473 = 473;
public static final int DARK_WIZARD_474 = 474; public static final int GHOST_474 = 474;
public static final int HOLE_IN_THE_WALL = 475; public static final int HOLE_IN_THE_WALL = 475;
public static final int WALL_BEAST = 476; public static final int WALL_BEAST = 476;
public static final int GIANT_FROG = 477; public static final int GIANT_FROG = 477;
@@ -491,32 +492,34 @@ public final class NpcID
public static final int VANESSA = 502; public static final int VANESSA = 502;
public static final int RICHARD = 503; public static final int RICHARD = 503;
public static final int ALICE = 504; public static final int ALICE = 504;
public static final int MUGGER = 505; public static final int GHOST_505 = 505;
public static final int WITCH = 506; public static final int GHOST_506 = 506;
public static final int WITCH_507 = 507; public static final int GHOST_507 = 507;
public static final int BLACK_KNIGHT = 508; public static final int SOULLESS = 508;
public static final int BLACK_KNIGHT_509 = 509; public static final int DEATH_WING = 509;
public static final int HIGHWAYMAN = 510; public static final int DARK_WIZARD = 510;
public static final int HIGHWAYMAN_511 = 511; public static final int INVRIGAR_THE_NECROMANCER = 511;
public static final int CHAOS_DRUID = 512; public static final int DARK_WIZARD_512 = 512;
public static final int PIRATE = 513; public static final int MUGGER = 513;
public static final int PIRATE_514 = 514; public static final int WITCH = 514;
public static final int PIRATE_515 = 515; public static final int WITCH_515 = 515;
public static final int PIRATE_516 = 516; public static final int BLACK_KNIGHT = 516;
public static final int THUG = 517; public static final int BLACK_KNIGHT_517 = 517;
public static final int ROGUE = 518; public static final int HIGHWAYMAN = 518;
public static final int MONK_OF_ZAMORAK = 519; public static final int HIGHWAYMAN_519 = 519;
public static final int MONK_OF_ZAMORAK_520 = 520; public static final int CHAOS_DRUID = 520;
public static final int MONK_OF_ZAMORAK_521 = 521; public static final int PIRATE = 521;
public static final int TRIBESMAN = 522; public static final int PIRATE_522 = 522;
public static final int DARK_WARRIOR = 523; public static final int PIRATE_523 = 523;
public static final int CHAOS_DRUID_WARRIOR = 524; public static final int PIRATE_524 = 524;
public static final int NECROMANCER = 525; public static final int THUG = 525;
public static final int BANDIT = 526; public static final int ROGUE = 526;
public static final int GUARD_BANDIT = 527; public static final int MONK_OF_ZAMORAK = 527;
public static final int BARBARIAN_GUARD = 528; public static final int MONK_OF_ZAMORAK_528 = 528;
public static final int PORTAL = 530; public static final int MONK_OF_ZAMORAK_529 = 529;
public static final int PORTAL_532 = 532; public static final int TRIBESMAN = 530;
public static final int DARK_WARRIOR = 531;
public static final int CHAOS_DRUID_WARRIOR = 532;
public static final int FUNGI = 533; public static final int FUNGI = 533;
public static final int THESSALIA = 534; public static final int THESSALIA = 534;
public static final int FUNGI_535 = 535; public static final int FUNGI_535 = 535;
@@ -672,7 +675,7 @@ public final class NpcID
public static final int BARTENDER = 687; public static final int BARTENDER = 687;
public static final int EBLIS = 688; public static final int EBLIS = 688;
public static final int EBLIS_689 = 689; public static final int EBLIS_689 = 689;
public static final int BANDIT_690 = 690; public static final int BANDIT = 690;
public static final int BANDIT_691 = 691; public static final int BANDIT_691 = 691;
public static final int BANDIT_692 = 692; public static final int BANDIT_692 = 692;
public static final int BANDIT_693 = 693; public static final int BANDIT_693 = 693;
@@ -986,16 +989,10 @@ public final class NpcID
public static final int RAT_1021 = 1021; public static final int RAT_1021 = 1021;
public static final int RAT_1022 = 1022; public static final int RAT_1022 = 1022;
public static final int ZYGOMITE_1024 = 1024; public static final int ZYGOMITE_1024 = 1024;
public static final int BANKER_1027 = 1027; public static final int NECROMANCER = 1025;
public static final int BANKER_1028 = 1028; public static final int BANDIT_1026 = 1026;
public static final int BANKER_1029 = 1029; public static final int GUARD_BANDIT = 1027;
public static final int BANKER_1030 = 1030; public static final int BARBARIAN_GUARD = 1028;
public static final int BANKER_1031 = 1031;
public static final int BANKER_1032 = 1032;
public static final int BANKER_1033 = 1033;
public static final int BANKER_1034 = 1034;
public static final int BANKER_1035 = 1035;
public static final int BANKER_1036 = 1036;
public static final int SNAKE = 1037; public static final int SNAKE = 1037;
public static final int MONKEY_1038 = 1038; public static final int MONKEY_1038 = 1038;
public static final int ALBINO_BAT = 1039; public static final int ALBINO_BAT = 1039;
@@ -1258,13 +1255,6 @@ public final class NpcID
public static final int HARI = 1325; public static final int HARI = 1325;
public static final int BARFY_BILL = 1326; public static final int BARFY_BILL = 1326;
public static final int TYRAS_GUARD_1327 = 1327; public static final int TYRAS_GUARD_1327 = 1327;
public static final int TRADER_STAN = 1328;
public static final int TRADER_CREWMEMBER = 1329;
public static final int TRADER_CREWMEMBER_1330 = 1330;
public static final int TRADER_CREWMEMBER_1331 = 1331;
public static final int TRADER_CREWMEMBER_1332 = 1332;
public static final int TRADER_CREWMEMBER_1333 = 1333;
public static final int TRADER_CREWMEMBER_1334 = 1334;
public static final int JACK_SEAGULL = 1335; public static final int JACK_SEAGULL = 1335;
public static final int LONGBOW_BEN = 1336; public static final int LONGBOW_BEN = 1336;
public static final int AHAB = 1337; public static final int AHAB = 1337;
@@ -1525,10 +1515,12 @@ public final class NpcID
public static final int BATTLE_MAGE = 1610; public static final int BATTLE_MAGE = 1610;
public static final int BATTLE_MAGE_1611 = 1611; public static final int BATTLE_MAGE_1611 = 1611;
public static final int BATTLE_MAGE_1612 = 1612; public static final int BATTLE_MAGE_1612 = 1612;
public static final int BANKER_1613 = 1613;
public static final int PHIALS = 1614; public static final int PHIALS = 1614;
public static final int BANKNOTE_EXCHANGE_MERCHANT = 1615; public static final int BANKNOTE_EXCHANGE_MERCHANT = 1615;
public static final int HIGH_PRIESTESS_ZULHARCINQA = 1616; public static final int HIGH_PRIESTESS_ZULHARCINQA = 1616;
public static final int PRIESTESS_ZULGWENWYNIG = 1617; public static final int PRIESTESS_ZULGWENWYNIG = 1617;
public static final int BANKER_1618 = 1618;
public static final int CAT_1619 = 1619; public static final int CAT_1619 = 1619;
public static final int CAT_1620 = 1620; public static final int CAT_1620 = 1620;
public static final int CAT_1621 = 1621; public static final int CAT_1621 = 1621;
@@ -1543,6 +1535,8 @@ public final class NpcID
public static final int LAZY_CAT_1630 = 1630; public static final int LAZY_CAT_1630 = 1630;
public static final int LAZY_CAT_1631 = 1631; public static final int LAZY_CAT_1631 = 1631;
public static final int LAZY_HELLCAT = 1632; public static final int LAZY_HELLCAT = 1632;
public static final int BANKER_1633 = 1633;
public static final int BANKER_1634 = 1634;
public static final int BABY_IMPLING = 1635; public static final int BABY_IMPLING = 1635;
public static final int YOUNG_IMPLING = 1636; public static final int YOUNG_IMPLING = 1636;
public static final int GOURMET_IMPLING = 1637; public static final int GOURMET_IMPLING = 1637;
@@ -1647,7 +1641,7 @@ public final class NpcID
public static final int BRAWLER_1736 = 1736; public static final int BRAWLER_1736 = 1736;
public static final int BRAWLER_1737 = 1737; public static final int BRAWLER_1737 = 1737;
public static final int BRAWLER_1738 = 1738; public static final int BRAWLER_1738 = 1738;
public static final int PORTAL_1739 = 1739; public static final int PORTAL = 1739;
public static final int PORTAL_1740 = 1740; public static final int PORTAL_1740 = 1740;
public static final int PORTAL_1741 = 1741; public static final int PORTAL_1741 = 1741;
public static final int PORTAL_1742 = 1742; public static final int PORTAL_1742 = 1742;
@@ -2882,44 +2876,33 @@ public final class NpcID
public static final int GOBLIN_3074 = 3074; public static final int GOBLIN_3074 = 3074;
public static final int GOBLIN_3075 = 3075; public static final int GOBLIN_3075 = 3075;
public static final int GOBLIN_3076 = 3076; public static final int GOBLIN_3076 = 3076;
public static final int HANS = 3077; public static final int PORTAL_3086 = 3086;
public static final int MAN_3078 = 3078; public static final int PORTAL_3088 = 3088;
public static final int MAN_3079 = 3079; public static final int BANKER_3089 = 3089;
public static final int MAN_3080 = 3080; public static final int BANKER_3090 = 3090;
public static final int MAN_3081 = 3081; public static final int BANKER_3091 = 3091;
public static final int MAN_3082 = 3082; public static final int BANKER_3092 = 3092;
public static final int WOMAN_3083 = 3083; public static final int BANKER_3093 = 3093;
public static final int WOMAN_3084 = 3084; public static final int BANKER_3094 = 3094;
public static final int WOMAN_3085 = 3085; public static final int CHIEF_SERVANT = 3095;
public static final int FARMER = 3086; public static final int TAXIDERMIST = 3096;
public static final int FARMER_3087 = 3087; public static final int ESTATE_AGENT = 3097;
public static final int FARMER_3088 = 3088; public static final int STONEMASON = 3098;
public static final int FARMER_3089 = 3089;
public static final int FARMER_3090 = 3090;
public static final int FARMER_3091 = 3091;
public static final int THIEF_3092 = 3092;
public static final int THIEF_3093 = 3093;
public static final int GUARD_3094 = 3094;
public static final int TRAMP_3095 = 3095;
public static final int BARBARIAN_3096 = 3096;
public static final int WIZARD_3097 = 3097;
public static final int DRUID = 3098;
public static final int HELLPUPPY_3099 = 3099; public static final int HELLPUPPY_3099 = 3099;
public static final int WARRIOR_WOMAN = 3100; public static final int SIR_RENITEE = 3100;
public static final int MAN_3101 = 3101; public static final int SAWMILL_OPERATOR = 3101;
public static final int BARBARIAN_3102 = 3102; public static final int GARDEN_SUPPLIER = 3102;
public static final int ALKHARID_WARRIOR = 3103; public static final int GARDEN_SUPPLIER_3103 = 3103;
public static final int PALADIN_3104 = 3104; public static final int HANS = 3105;
public static final int PALADIN_3105 = 3105; public static final int MAN_3106 = 3106;
public static final int HERO = 3106; public static final int MAN_3107 = 3107;
public static final int FORESTER = 3107; public static final int MAN_3108 = 3108;
public static final int KNIGHT_OF_ARDOUGNE = 3108;
public static final int MAN_3109 = 3109; public static final int MAN_3109 = 3109;
public static final int WOMAN_3110 = 3110; public static final int MAN_3110 = 3110;
public static final int KNIGHT_OF_ARDOUGNE_3111 = 3111; public static final int WOMAN_3111 = 3111;
public static final int ARCHER_3112 = 3112; public static final int WOMAN_3112 = 3112;
public static final int ZOO_KEEPER = 3113; public static final int WOMAN_3113 = 3113;
public static final int CHUCK = 3114; public static final int FARMER = 3114;
public static final int FARID_MORRISANE_ORES_AND_BARS = 3115; public static final int FARID_MORRISANE_ORES_AND_BARS = 3115;
public static final int TZKIH_3116 = 3116; public static final int TZKIH_3116 = 3116;
public static final int TZKIH_3117 = 3117; public static final int TZKIH_3117 = 3117;
@@ -3039,26 +3022,26 @@ public final class NpcID
public static final int TREE = 3240; public static final int TREE = 3240;
public static final int BLANDEBIR = 3241; public static final int BLANDEBIR = 3241;
public static final int METARIALUS = 3242; public static final int METARIALUS = 3242;
public static final int BARMAN_3243 = 3243; public static final int FARMER_3243 = 3243;
public static final int PRIEST_3244 = 3244; public static final int FARMER_3244 = 3244;
public static final int GUARD_3245 = 3245; public static final int FARMER_3245 = 3245;
public static final int WIZARD_FRUMSCONE = 3246; public static final int WIZARD_FRUMSCONE = 3246;
public static final int WIZARD_AKUTHA = 3247; public static final int WIZARD_AKUTHA = 3247;
public static final int WIZARD_DISTENTOR = 3248; public static final int WIZARD_DISTENTOR = 3248;
public static final int WIZARD_SININA = 3249; public static final int WIZARD_SININA = 3249;
public static final int DOOR_MAN = 3250; public static final int FARMER_3250 = 3250;
public static final int WATCHMAN = 3251; public static final int FARMER_3251 = 3251;
public static final int SOLDIER = 3252; public static final int THIEF_3252 = 3252;
public static final int WYSON_THE_GARDENER = 3253; public static final int THIEF_3253 = 3253;
public static final int SIGBERT_THE_ADVENTURER = 3254; public static final int GUARD_3254 = 3254;
public static final int SHIPYARD_WORKER_3255 = 3255; public static final int TRAMP_3255 = 3255;
public static final int SHIPYARD_WORKER_3256 = 3256; public static final int BARBARIAN_3256 = 3256;
public static final int MASTER_FARMER = 3257; public static final int WIZARD_3257 = 3257;
public static final int MASTER_FARMER_3258 = 3258; public static final int DRUID = 3258;
public static final int MARKET_GUARD_3259 = 3259; public static final int DRUID_3259 = 3259;
public static final int MAN_3260 = 3260; public static final int WARRIOR_WOMAN = 3260;
public static final int GEE = 3261; public static final int MAN_3261 = 3261;
public static final int DONIE = 3262; public static final int BARBARIAN_3262 = 3262;
public static final int DRUNKEN_MAN = 3263; public static final int DRUNKEN_MAN = 3263;
public static final int MAN_3264 = 3264; public static final int MAN_3264 = 3264;
public static final int MAN_3265 = 3265; public static final int MAN_3265 = 3265;
@@ -3088,6 +3071,19 @@ public final class NpcID
public static final int HOBGOBLIN_3289 = 3289; public static final int HOBGOBLIN_3289 = 3289;
public static final int FROG_3290 = 3290; public static final int FROG_3290 = 3290;
public static final int POSTIE_PETE = 3291; public static final int POSTIE_PETE = 3291;
public static final int ALKHARID_WARRIOR = 3292;
public static final int PALADIN_3293 = 3293;
public static final int PALADIN_3294 = 3294;
public static final int HERO = 3295;
public static final int FORESTER = 3296;
public static final int KNIGHT_OF_ARDOUGNE = 3297;
public static final int MAN_3298 = 3298;
public static final int WOMAN_3299 = 3299;
public static final int KNIGHT_OF_ARDOUGNE_3300 = 3300;
public static final int ARCHER_3301 = 3301;
public static final int ZOO_KEEPER = 3302;
public static final int CHUCK = 3303;
public static final int BARMAN_3304 = 3304;
public static final int MASTER_CHEF = 3305; public static final int MASTER_CHEF = 3305;
public static final int HENJA = 3306; public static final int HENJA = 3306;
public static final int COMBAT_INSTRUCTOR = 3307; public static final int COMBAT_INSTRUCTOR = 3307;
@@ -3837,7 +3833,7 @@ public final class NpcID
public static final int DENULTH = 4083; public static final int DENULTH = 4083;
public static final int SERGEANT = 4084; public static final int SERGEANT = 4084;
public static final int SERGEANT_4085 = 4085; public static final int SERGEANT_4085 = 4085;
public static final int SOLDIER_4086 = 4086; public static final int SOLDIER = 4086;
public static final int SOLDIER_4087 = 4087; public static final int SOLDIER_4087 = 4087;
public static final int SOLDIER_4088 = 4088; public static final int SOLDIER_4088 = 4088;
public static final int SOLDIER_4089 = 4089; public static final int SOLDIER_4089 = 4089;
@@ -5067,13 +5063,13 @@ public final class NpcID
public static final int COMBAT_STONE_5414 = 5414; public static final int COMBAT_STONE_5414 = 5414;
public static final int COMBAT_STONE_5415 = 5415; public static final int COMBAT_STONE_5415 = 5415;
public static final int COMBAT_STONE_5416 = 5416; public static final int COMBAT_STONE_5416 = 5416;
public static final int CHIEF_SERVANT = 5417; public static final int PRIEST_5417 = 5417;
public static final int TAXIDERMIST = 5418; public static final int GUARD_5418 = 5418;
public static final int ESTATE_AGENT = 5419; public static final int DOOR_MAN = 5419;
public static final int STONEMASON = 5420; public static final int WATCHMAN = 5420;
public static final int SIR_RENITEE = 5421; public static final int SOLDIER_5421 = 5421;
public static final int SAWMILL_OPERATOR = 5422; public static final int WYSON_THE_GARDENER = 5422;
public static final int GARDEN_SUPPLIER = 5423; public static final int SIGBERT_THE_ADVENTURER = 5423;
public static final int CAPT_ARNAV = 5426; public static final int CAPT_ARNAV = 5426;
public static final int FLIPPA = 5427; public static final int FLIPPA = 5427;
public static final int TILT = 5428; public static final int TILT = 5428;
@@ -5104,7 +5100,7 @@ public final class NpcID
public static final int THUMPY = 5454; public static final int THUMPY = 5454;
public static final int THOMDRIL = 5455; public static final int THOMDRIL = 5455;
public static final int KENDALL = 5456; public static final int KENDALL = 5456;
public static final int DRUID_5457 = 5457; public static final int SHIPYARD_WORKER_5457 = 5457;
public static final int SUSPECT_5458 = 5458; public static final int SUSPECT_5458 = 5458;
public static final int SUSPECT_5459 = 5459; public static final int SUSPECT_5459 = 5459;
public static final int SUSPECT_5460 = 5460; public static final int SUSPECT_5460 = 5460;
@@ -5365,6 +5361,10 @@ public final class NpcID
public static final int SHEEP_5726 = 5726; public static final int SHEEP_5726 = 5726;
public static final int RABBIT_5727 = 5727; public static final int RABBIT_5727 = 5727;
public static final int IMP_5728 = 5728; public static final int IMP_5728 = 5728;
public static final int SHIPYARD_WORKER_5729 = 5729;
public static final int MASTER_FARMER = 5730;
public static final int MASTER_FARMER_5731 = 5731;
public static final int MARKET_GUARD_5732 = 5732;
public static final int ELNOCK_INQUISITOR = 5734; public static final int ELNOCK_INQUISITOR = 5734;
public static final int IMPLING = 5735; public static final int IMPLING = 5735;
public static final int FAIRY_AERYKA = 5736; public static final int FAIRY_AERYKA = 5736;
@@ -6160,14 +6160,10 @@ public final class NpcID
public static final int AWOWOGEI_6812 = 6812; public static final int AWOWOGEI_6812 = 6812;
public static final int MONKEY_ARCHER_6813 = 6813; public static final int MONKEY_ARCHER_6813 = 6813;
public static final int LAMMY_LANGLE = 6814; public static final int LAMMY_LANGLE = 6814;
public static final int GHOST_6815 = 6815; public static final int MAN_6815 = 6815;
public static final int GHOST_6816 = 6816; public static final int GEE = 6816;
public static final int GHOST_6817 = 6817; public static final int DONIE = 6817;
public static final int GHOST_6818 = 6818; public static final int MAN_6818 = 6818;
public static final int GHOST_6819 = 6819;
public static final int GHOST_6820 = 6820;
public static final int GHOST_6821 = 6821;
public static final int GHOST_6822 = 6822;
public static final int TOWN_CRIER_6823 = 6823; public static final int TOWN_CRIER_6823 = 6823;
public static final int GIANT_BAT_6824 = 6824; public static final int GIANT_BAT_6824 = 6824;
public static final int ROD_FISHING_SPOT_6825 = 6825; public static final int ROD_FISHING_SPOT_6825 = 6825;
@@ -6818,7 +6814,6 @@ public final class NpcID
public static final int TEKTON_ENRAGED_7544 = 7544; public static final int TEKTON_ENRAGED_7544 = 7544;
public static final int TEKTON_7545 = 7545; public static final int TEKTON_7545 = 7545;
public static final int BARTENDER_7546 = 7546; public static final int BARTENDER_7546 = 7546;
public static final int MAN_7547 = 7547;
public static final int SCAVENGER_BEAST = 7548; public static final int SCAVENGER_BEAST = 7548;
public static final int SCAVENGER_BEAST_7549 = 7549; public static final int SCAVENGER_BEAST_7549 = 7549;
public static final int GREAT_OLM_RIGHT_CLAW = 7550; public static final int GREAT_OLM_RIGHT_CLAW = 7550;
@@ -7650,7 +7645,6 @@ public final class NpcID
public static final int TORMENTED_SOUL_8513 = 8513; public static final int TORMENTED_SOUL_8513 = 8513;
public static final int TRAPPED_SOUL = 8514; public static final int TRAPPED_SOUL = 8514;
public static final int ALYSSA = 8515; public static final int ALYSSA = 8515;
public static final int GARDEN_SUPPLIER_8516 = 8516;
public static final int IKKLE_HYDRA_8517 = 8517; public static final int IKKLE_HYDRA_8517 = 8517;
public static final int IKKLE_HYDRA_8518 = 8518; public static final int IKKLE_HYDRA_8518 = 8518;
public static final int IKKLE_HYDRA_8519 = 8519; public static final int IKKLE_HYDRA_8519 = 8519;
@@ -7822,7 +7816,6 @@ public final class NpcID
public static final int SMOLCANO = 8731; public static final int SMOLCANO = 8731;
public static final int MUGGER_8732 = 8732; public static final int MUGGER_8732 = 8732;
public static final int CRAB_8733 = 8733; public static final int CRAB_8733 = 8733;
public static final int SOULLESS = 8734;
public static final int MOSS_GIANT_8736 = 8736; public static final int MOSS_GIANT_8736 = 8736;
public static final int YOUNGLLEF_8737 = 8737; public static final int YOUNGLLEF_8737 = 8737;
public static final int CORRUPTED_YOUNGLLEF_8738 = 8738; public static final int CORRUPTED_YOUNGLLEF_8738 = 8738;
@@ -8318,5 +8311,89 @@ public final class NpcID
public static final int TYPHOR_9296 = 9296; public static final int TYPHOR_9296 = 9296;
public static final int VRITRA = 9297; public static final int VRITRA = 9297;
public static final int MAZ = 9298; public static final int MAZ = 9298;
public static final int TRADER_STAN = 9299;
public static final int TRADER_STAN_9300 = 9300;
public static final int TRADER_STAN_9301 = 9301;
public static final int TRADER_STAN_9302 = 9302;
public static final int TRADER_STAN_9303 = 9303;
public static final int TRADER_STAN_9304 = 9304;
public static final int TRADER_STAN_9305 = 9305;
public static final int TRADER_STAN_9307 = 9307;
public static final int TRADER_STAN_9308 = 9308;
public static final int TRADER_STAN_9309 = 9309;
public static final int TRADER_STAN_9310 = 9310;
public static final int TRADER_STAN_9311 = 9311;
public static final int TRADER_CREWMEMBER = 9312;
public static final int TRADER_CREWMEMBER_9313 = 9313;
public static final int TRADER_CREWMEMBER_9314 = 9314;
public static final int TRADER_CREWMEMBER_9315 = 9315;
public static final int TRADER_CREWMEMBER_9316 = 9316;
public static final int TRADER_CREWMEMBER_9317 = 9317;
public static final int TRADER_CREWMEMBER_9318 = 9318;
public static final int TRADER_CREWMEMBER_9319 = 9319;
public static final int TRADER_CREWMEMBER_9320 = 9320;
public static final int TRADER_CREWMEMBER_9321 = 9321;
public static final int TRADER_CREWMEMBER_9322 = 9322;
public static final int TRADER_CREWMEMBER_9323 = 9323;
public static final int TRADER_CREWMEMBER_9324 = 9324;
public static final int TRADER_CREWMEMBER_9325 = 9325;
public static final int TRADER_CREWMEMBER_9326 = 9326;
public static final int TRADER_CREWMEMBER_9327 = 9327;
public static final int TRADER_CREWMEMBER_9328 = 9328;
public static final int TRADER_CREWMEMBER_9329 = 9329;
public static final int TRADER_CREWMEMBER_9330 = 9330;
public static final int TRADER_CREWMEMBER_9331 = 9331;
public static final int TRADER_CREWMEMBER_9332 = 9332;
public static final int TRADER_CREWMEMBER_9333 = 9333;
public static final int TRADER_CREWMEMBER_9334 = 9334;
public static final int TRADER_CREWMEMBER_9335 = 9335;
public static final int TRADER_CREWMEMBER_9336 = 9336;
public static final int TRADER_CREWMEMBER_9337 = 9337;
public static final int TRADER_CREWMEMBER_9338 = 9338;
public static final int TRADER_CREWMEMBER_9339 = 9339;
public static final int TRADER_CREWMEMBER_9340 = 9340;
public static final int TRADER_CREWMEMBER_9341 = 9341;
public static final int TRADER_CREWMEMBER_9342 = 9342;
public static final int TRADER_CREWMEMBER_9343 = 9343;
public static final int TRADER_CREWMEMBER_9344 = 9344;
public static final int TRADER_CREWMEMBER_9345 = 9345;
public static final int TRADER_CREWMEMBER_9346 = 9346;
public static final int TRADER_CREWMEMBER_9347 = 9347;
public static final int TRADER_CREWMEMBER_9348 = 9348;
public static final int TRADER_CREWMEMBER_9349 = 9349;
public static final int TRADER_CREWMEMBER_9350 = 9350;
public static final int TRADER_CREWMEMBER_9351 = 9351;
public static final int TRADER_CREWMEMBER_9352 = 9352;
public static final int TRADER_CREWMEMBER_9353 = 9353;
public static final int TRADER_CREWMEMBER_9354 = 9354;
public static final int TRADER_CREWMEMBER_9355 = 9355;
public static final int TRADER_CREWMEMBER_9356 = 9356;
public static final int TRADER_CREWMEMBER_9357 = 9357;
public static final int TRADER_CREWMEMBER_9358 = 9358;
public static final int TRADER_CREWMEMBER_9359 = 9359;
public static final int TRADER_CREWMEMBER_9360 = 9360;
public static final int TRADER_CREWMEMBER_9361 = 9361;
public static final int TRADER_CREWMEMBER_9362 = 9362;
public static final int TRADER_CREWMEMBER_9363 = 9363;
public static final int TRADER_CREWMEMBER_9364 = 9364;
public static final int TRADER_CREWMEMBER_9365 = 9365;
public static final int TRADER_CREWMEMBER_9366 = 9366;
public static final int TRADER_CREWMEMBER_9367 = 9367;
public static final int TRADER_CREWMEMBER_9368 = 9368;
public static final int TRADER_CREWMEMBER_9369 = 9369;
public static final int TRADER_CREWMEMBER_9370 = 9370;
public static final int TRADER_CREWMEMBER_9371 = 9371;
public static final int TRADER_CREWMEMBER_9372 = 9372;
public static final int TRADER_CREWMEMBER_9373 = 9373;
public static final int TRADER_CREWMEMBER_9374 = 9374;
public static final int TRADER_CREWMEMBER_9375 = 9375;
public static final int TRADER_CREWMEMBER_9376 = 9376;
public static final int TRADER_CREWMEMBER_9377 = 9377;
public static final int TRADER_CREWMEMBER_9378 = 9378;
public static final int TRADER_CREWMEMBER_9379 = 9379;
public static final int TRADER_CREWMEMBER_9380 = 9380;
public static final int TRADER_CREWMEMBER_9381 = 9381;
public static final int TRADER_CREWMEMBER_9382 = 9382;
public static final int TRADER_CREWMEMBER_9383 = 9383;
/* This file is automatically generated. Do not edit. */ /* This file is automatically generated. Do not edit. */
} }
@@ -12852,5 +12852,6 @@ public final class NullItemID
public static final int NULL_24414 = 24414; public static final int NULL_24414 = 24414;
public static final int NULL_24415 = 24415; public static final int NULL_24415 = 24415;
public static final int NULL_24427 = 24427; public static final int NULL_24427 = 24427;
public static final int NULL_24429 = 24429;
/* This file is automatically generated. Do not edit. */ /* This file is automatically generated. Do not edit. */
} }
@@ -12856,7 +12856,6 @@ public final class NullObjectID
public static final int NULL_27103 = 27103; public static final int NULL_27103 = 27103;
public static final int NULL_27104 = 27104; public static final int NULL_27104 = 27104;
public static final int NULL_27105 = 27105; public static final int NULL_27105 = 27105;
public static final int NULL_27106 = 27106;
public static final int NULL_27111 = 27111; public static final int NULL_27111 = 27111;
public static final int NULL_27112 = 27112; public static final int NULL_27112 = 27112;
public static final int NULL_27113 = 27113; public static final int NULL_27113 = 27113;
@@ -14234,7 +14234,6 @@ public final class ObjectID
public static final int LIGHT_27093 = 27093; public static final int LIGHT_27093 = 27093;
public static final int CLAN_CUP_PORTAL = 27095; public static final int CLAN_CUP_PORTAL = 27095;
public static final int EXIT_PORTAL_27096 = 27096; public static final int EXIT_PORTAL_27096 = 27096;
public static final int ANTISANTA = 27097;
public static final int SOFA = 27098; public static final int SOFA = 27098;
public static final int CRATE_27100 = 27100; public static final int CRATE_27100 = 27100;
public static final int CRATES_27101 = 27101; public static final int CRATES_27101 = 27101;
@@ -1,99 +1,99 @@
/* ///*
* Copyright (c) 2017, Devin French <https://github.com/devinfrench> // * Copyright (c) 2017, Devin French <https://github.com/devinfrench>
* 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
* modification, are permitted provided that the following conditions are met: // * modification, are permitted provided that the following conditions are met:
* // *
* 1. Redistributions of source code must retain the above copyright notice, this // * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. // * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, // * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation // * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. // * and/or other materials provided with the distribution.
* // *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // * 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 // * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR // * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // * 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 // * (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.api.queries; //package net.runelite.api.queries;
//
import java.awt.Rectangle; //import java.awt.Rectangle;
import java.util.ArrayList; //import java.util.ArrayList;
import java.util.Arrays; //import java.util.Arrays;
import java.util.Collection; //import java.util.Collection;
import java.util.Objects; //import java.util.Objects;
import java.util.stream.Collectors; //import java.util.stream.Collectors;
import net.runelite.api.Client; //import net.runelite.api.Client;
import net.runelite.api.QueryResults; //import net.runelite.api.QueryResults;
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.WidgetItem; //import net.runelite.api.widgets.WidgetItem;
//
public class EquipmentItemQuery extends WidgetItemQuery //public class EquipmentItemQuery extends WidgetItemQuery
{ //{
private static final WidgetInfo[] ALL_EQUIPMENT_WIDGET_INFOS = // private static final WidgetInfo[] ALL_EQUIPMENT_WIDGET_INFOS =
{ // {
WidgetInfo.EQUIPMENT_HELMET, // WidgetInfo.EQUIPMENT_HELMET,
WidgetInfo.EQUIPMENT_CAPE, // WidgetInfo.EQUIPMENT_CAPE,
WidgetInfo.EQUIPMENT_AMULET, // WidgetInfo.EQUIPMENT_AMULET,
WidgetInfo.EQUIPMENT_WEAPON, // WidgetInfo.EQUIPMENT_WEAPON,
WidgetInfo.EQUIPMENT_BODY, // WidgetInfo.EQUIPMENT_BODY,
WidgetInfo.EQUIPMENT_SHIELD, // WidgetInfo.EQUIPMENT_SHIELD,
WidgetInfo.EQUIPMENT_LEGS, // WidgetInfo.EQUIPMENT_LEGS,
WidgetInfo.EQUIPMENT_GLOVES, // WidgetInfo.EQUIPMENT_GLOVES,
WidgetInfo.EQUIPMENT_BOOTS, // WidgetInfo.EQUIPMENT_BOOTS,
WidgetInfo.EQUIPMENT_RING, // WidgetInfo.EQUIPMENT_RING,
WidgetInfo.EQUIPMENT_AMMO, // WidgetInfo.EQUIPMENT_AMMO,
}; // };
//
private final Collection<WidgetInfo> slots = new ArrayList<>(); // private final Collection<WidgetInfo> slots = new ArrayList<>();
//
public EquipmentItemQuery slotEquals(WidgetInfo... slotWidgetInfo) // public EquipmentItemQuery slotEquals(WidgetInfo... slotWidgetInfo)
{ // {
slots.addAll(Arrays.asList(slotWidgetInfo)); // slots.addAll(Arrays.asList(slotWidgetInfo));
return this; // return this;
} // }
//
@Override // @Override
public QueryResults<WidgetItem> result(Client client) // public QueryResults<WidgetItem> result(Client client)
{ // {
Collection<WidgetItem> widgetItems = getEquippedItems(client); // Collection<WidgetItem> widgetItems = getEquippedItems(client);
return new QueryResults<>(widgetItems.stream() // return new QueryResults<>(widgetItems.stream()
.filter(Objects::nonNull) // .filter(Objects::nonNull)
.filter(predicate) // .filter(predicate)
.collect(Collectors.toList())); // .collect(Collectors.toList()));
} // }
//
private Collection<WidgetItem> getEquippedItems(Client client) // private Collection<WidgetItem> getEquippedItems(Client client)
{ // {
Collection<WidgetItem> widgetItems = new ArrayList<>(); // Collection<WidgetItem> widgetItems = new ArrayList<>();
Widget equipment = client.getWidget(WidgetInfo.EQUIPMENT); // Widget equipment = client.getWidget(WidgetInfo.EQUIPMENT);
if (equipment != null && !equipment.isHidden()) // if (equipment != null && !equipment.isHidden())
{ // {
if (slots.isEmpty()) // if (slots.isEmpty())
{ // {
slots.addAll(Arrays.asList(ALL_EQUIPMENT_WIDGET_INFOS)); // slots.addAll(Arrays.asList(ALL_EQUIPMENT_WIDGET_INFOS));
} // }
for (WidgetInfo slot : slots) // for (WidgetInfo slot : slots)
{ // {
Widget parentWidget = client.getWidget(slot); // Widget parentWidget = client.getWidget(slot);
Widget itemWidget = parentWidget.getChild(1); // Widget itemWidget = parentWidget.getChild(1);
// Check if background icon is hidden. if hidden, item is equipped. // // Check if background icon is hidden. if hidden, item is equipped.
boolean equipped = parentWidget.getChild(2).isSelfHidden(); // boolean equipped = parentWidget.getChild(2).isSelfHidden();
// set bounds to same size as default inventory // // set bounds to same size as default inventory
Rectangle bounds = itemWidget.getBounds(); // Rectangle bounds = itemWidget.getBounds();
bounds.setBounds(bounds.x - 1, bounds.y - 1, 32, 32); // bounds.setBounds(bounds.x - 1, bounds.y - 1, 32, 32);
// Index is set to 0 because there is no set in stone order of equipment slots // // Index is set to 0 because there is no set in stone order of equipment slots
widgetItems.add(new WidgetItem(equipped ? itemWidget.getItemId() : -1, itemWidget.getItemQuantity(), 0, bounds, itemWidget)); // widgetItems.add(new WidgetItem(equipped ? itemWidget.getItemId() : -1, itemWidget.getItemQuantity(), 0, bounds, itemWidget));
} // }
} // }
return widgetItems; // return widgetItems;
} // }
} //}
@@ -264,14 +264,14 @@ public class WidgetID
static final int BANK_CONTAINER = 1; static final int BANK_CONTAINER = 1;
static final int INVENTORY_ITEM_CONTAINER = 3; static final int INVENTORY_ITEM_CONTAINER = 3;
static final int BANK_TITLE_BAR = 4; static final int BANK_TITLE_BAR = 4;
static final int CONTENT_CONTAINER = 10; static final int CONTENT_CONTAINER = 9;
static final int TAB_CONTAINER = 11; static final int TAB_CONTAINER = 10;
static final int ITEM_CONTAINER = 13; static final int ITEM_CONTAINER = 12;
static final int SEARCH_BUTTON_BACKGROUND = 40; static final int SEARCH_BUTTON_BACKGROUND = 39;
static final int DEPOSIT_INVENTORY = 42; static final int DEPOSIT_INVENTORY = 41;
static final int DEPOSIT_EQUIPMENT = 44; static final int DEPOSIT_EQUIPMENT = 43;
static final int INCINERATOR = 46; static final int INCINERATOR = 45;
static final int INCINERATOR_CONFIRM = 47; static final int INCINERATOR_CONFIRM = 46;
} }
static class GrandExchange static class GrandExchange
@@ -315,17 +315,6 @@ public class WidgetID
static class Equipment static class Equipment
{ {
static final int HELMET = 6;
static final int CAPE = 7;
static final int AMULET = 8;
static final int WEAPON = 9;
static final int BODY = 10;
static final int SHIELD = 11;
static final int LEGS = 12;
static final int GLOVES = 13;
static final int BOOTS = 14;
static final int RING = 15;
static final int AMMO = 16;
static final int INVENTORY_ITEM_CONTAINER = 0; static final int INVENTORY_ITEM_CONTAINER = 0;
} }
@@ -45,6 +45,7 @@ public enum WidgetInfo
INVENTORY(WidgetID.INVENTORY_GROUP_ID, 0), INVENTORY(WidgetID.INVENTORY_GROUP_ID, 0),
FRIENDS_LIST(WidgetID.FRIENDS_LIST_GROUP_ID, 0), FRIENDS_LIST(WidgetID.FRIENDS_LIST_GROUP_ID, 0),
IGNORE_LIST(WidgetID.IGNORE_LIST_GROUP_ID, 0),
CLAN_CHAT(WidgetID.CLAN_CHAT_GROUP_ID, 0), CLAN_CHAT(WidgetID.CLAN_CHAT_GROUP_ID, 0),
RAIDING_PARTY(WidgetID.RAIDING_PARTY_GROUP_ID, 0), RAIDING_PARTY(WidgetID.RAIDING_PARTY_GROUP_ID, 0),
@@ -62,18 +63,6 @@ public enum WidgetInfo
EQUIPMENT(WidgetID.EQUIPMENT_GROUP_ID, 0), EQUIPMENT(WidgetID.EQUIPMENT_GROUP_ID, 0),
EQUIPMENT_INVENTORY_ITEMS_CONTAINER(WidgetID.EQUIPMENT_INVENTORY_GROUP_ID, WidgetID.Equipment.INVENTORY_ITEM_CONTAINER), EQUIPMENT_INVENTORY_ITEMS_CONTAINER(WidgetID.EQUIPMENT_INVENTORY_GROUP_ID, WidgetID.Equipment.INVENTORY_ITEM_CONTAINER),
EQUIPMENT_HELMET(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.HELMET),
EQUIPMENT_CAPE(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.CAPE),
EQUIPMENT_AMULET(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.AMULET),
EQUIPMENT_WEAPON(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.WEAPON),
EQUIPMENT_BODY(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.BODY),
EQUIPMENT_SHIELD(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.SHIELD),
EQUIPMENT_LEGS(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.LEGS),
EQUIPMENT_GLOVES(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.GLOVES),
EQUIPMENT_BOOTS(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.BOOTS),
EQUIPMENT_RING(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.RING),
EQUIPMENT_AMMO(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.AMMO),
EMOTE_WINDOW(WidgetID.EMOTES_GROUP_ID, WidgetID.Emotes.EMOTE_WINDOW), EMOTE_WINDOW(WidgetID.EMOTES_GROUP_ID, WidgetID.Emotes.EMOTE_WINDOW),
EMOTE_CONTAINER(WidgetID.EMOTES_GROUP_ID, WidgetID.Emotes.EMOTE_CONTAINER), EMOTE_CONTAINER(WidgetID.EMOTES_GROUP_ID, WidgetID.Emotes.EMOTE_CONTAINER),
EMOTE_SCROLLBAR(WidgetID.EMOTES_GROUP_ID, WidgetID.Emotes.EMOTE_SCROLLBAR), EMOTE_SCROLLBAR(WidgetID.EMOTES_GROUP_ID, WidgetID.Emotes.EMOTE_SCROLLBAR),
@@ -35,26 +35,26 @@ import net.runelite.api.Client;
import net.runelite.api.GameState; import net.runelite.api.GameState;
import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ChatMessage;
import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.EventBus;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ChatInput; import net.runelite.client.events.ChatInput;
import net.runelite.client.events.ChatboxInput; import net.runelite.client.events.ChatboxInput;
import net.runelite.client.events.PrivateMessageInput; import net.runelite.client.events.PrivateMessageInput;
@Singleton @Singleton
public class ChatCommandManager implements ChatboxInputListener public class ChatCommandManager
{ {
private final Map<String, ChatCommand> commands = new ConcurrentHashMap<>(); private final Map<String, ChatCommand> commands = new ConcurrentHashMap<>();
private final Client client; private final Client client;
private final ScheduledExecutorService scheduledExecutorService; private final ScheduledExecutorService scheduledExecutorService;
@Inject @Inject
private ChatCommandManager(EventBus eventBus, CommandManager commandManager, Client client, ScheduledExecutorService scheduledExecutorService) private ChatCommandManager(EventBus eventBus, Client client, ScheduledExecutorService scheduledExecutorService)
{ {
this.client = client; this.client = client;
this.scheduledExecutorService = scheduledExecutorService; this.scheduledExecutorService = scheduledExecutorService;
// eventBus.register(this);
commandManager.register(this);
eventBus.subscribe(ChatboxInput.class, this, this::onChatboxInput);
eventBus.subscribe(PrivateMessageInput.class, this, this::onPrivateMessageInput);
eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); eventBus.subscribe(ChatMessage.class, this, this::onChatMessage);
} }
@@ -106,11 +106,6 @@ public class ChatCommandManager implements ChatboxInputListener
String message = chatMessage.getMessage(); String message = chatMessage.getMessage();
String command = extractCommand(message); String command = extractCommand(message);
if (command == null)
{
return;
}
ChatCommand chatCommand = commands.get(command.toLowerCase()); ChatCommand chatCommand = commands.get(command.toLowerCase());
if (chatCommand == null) if (chatCommand == null)
{ {
@@ -127,8 +122,8 @@ public class ChatCommandManager implements ChatboxInputListener
} }
} }
@Override @Subscribe // just for show
public boolean onChatboxInput(ChatboxInput chatboxInput) private void onChatboxInput(ChatboxInput chatboxInput)
{ {
String message = chatboxInput.getValue(); String message = chatboxInput.getValue();
if (message.startsWith("/")) if (message.startsWith("/"))
@@ -136,51 +131,30 @@ public class ChatCommandManager implements ChatboxInputListener
message = message.substring(1); // clan chat input message = message.substring(1); // clan chat input
} }
String command = extractCommand(message); onInput(chatboxInput, message);
if (command == null)
{
return false;
}
ChatCommand chatCommand = commands.get(command.toLowerCase());
if (chatCommand == null)
{
return false;
}
BiPredicate<ChatInput, String> input = chatCommand.getInput();
if (input == null)
{
return false;
}
return input.test(chatboxInput, message);
} }
@Override @Subscribe // just for show
public boolean onPrivateMessageInput(PrivateMessageInput privateMessageInput) private void onPrivateMessageInput(PrivateMessageInput input)
{ {
final String message = privateMessageInput.getMessage(); onInput(input, input.getMessage());
}
private void onInput(ChatInput chatInput, String message)
{
String command = extractCommand(message); String command = extractCommand(message);
if (command == null)
{
return false;
}
ChatCommand chatCommand = commands.get(command.toLowerCase()); ChatCommand chatCommand = commands.get(command.toLowerCase());
if (chatCommand == null) if (chatCommand == null)
{ {
return false; return;
} }
BiPredicate<ChatInput, String> input = chatCommand.getInput(); BiPredicate<ChatInput, String> input = chatCommand.getInput();
if (input == null) if (input != null && input.test(chatInput, message))
{ {
return false; chatInput.setStop();
} }
return input.test(privateMessageInput, message);
} }
private static String extractCommand(String message) private static String extractCommand(String message)
@@ -153,7 +153,7 @@ public class ChatMessageManager
messageNode.setName(ColorUtil.wrapWithColorTag(messageNode.getName(), usernameColor)); messageNode.setName(ColorUtil.wrapWithColorTag(messageNode.getName(), usernameColor));
} }
String sender = chatMessage.getSender(); String sender = messageNode.getSender();
if (senderColor != null && !Strings.isNullOrEmpty(sender)) if (senderColor != null && !Strings.isNullOrEmpty(sender))
{ {
messageNode.setSender(ColorUtil.wrapWithColorTag(sender, senderColor)); messageNode.setSender(ColorUtil.wrapWithColorTag(sender, senderColor));
@@ -26,8 +26,6 @@
package net.runelite.client.chat; package net.runelite.client.chat;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -54,8 +52,6 @@ public class CommandManager
private final ClientThread clientThread; private final ClientThread clientThread;
private boolean sending; private boolean sending;
private final List<ChatboxInputListener> chatboxInputListenerList = new CopyOnWriteArrayList<>();
@Inject @Inject
private CommandManager( private CommandManager(
final Client client, final Client client,
@@ -70,16 +66,6 @@ public class CommandManager
eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent); eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent);
} }
public void register(ChatboxInputListener chatboxInputListener)
{
chatboxInputListenerList.add(chatboxInputListener);
}
public void unregister(ChatboxInputListener chatboxInputListener)
{
chatboxInputListenerList.remove(chatboxInputListener);
}
private void onScriptCallbackEvent(ScriptCallbackEvent event) private void onScriptCallbackEvent(ScriptCallbackEvent event)
{ {
if (sending) if (sending)
@@ -148,13 +134,10 @@ public class CommandManager
clientThread.invoke(() -> sendChatboxInput(chatType, typedText)); clientThread.invoke(() -> sendChatboxInput(chatType, typedText));
} }
}; };
boolean stop = false;
for (ChatboxInputListener chatboxInputListener : chatboxInputListenerList)
{
stop |= chatboxInputListener.onChatboxInput(chatboxInput);
}
if (stop) eventBus.post(ChatboxInput.class, chatboxInput);
if (chatboxInput.isStop())
{ {
// input was blocked. // input was blocked.
stringStack[stringStackCount - 1] = ""; // prevent script from sending stringStack[stringStackCount - 1] = ""; // prevent script from sending
@@ -188,13 +171,9 @@ public class CommandManager
} }
}; };
boolean stop = false; eventBus.post(PrivateMessageInput.class, privateMessageInput);
for (ChatboxInputListener chatboxInputListener : chatboxInputListenerList)
{
stop |= chatboxInputListener.onPrivateMessageInput(privateMessageInput);
}
if (stop) if (privateMessageInput.isStop())
{ {
intStack[intStackCount - 1] = 1; intStack[intStackCount - 1] = 1;
client.setStringStackSize(stringStackCount - 2); // remove both target and message client.setStringStackSize(stringStackCount - 2); // remove both target and message
@@ -64,7 +64,7 @@ public interface OpenOSRSConfig extends Config
@ConfigItem( @ConfigItem(
position = 3, position = 3,
keyName = "shareLogs", keyName = "shareLogs",
name = "Anonymous error data", name = "Share anonymous error data",
description = "Share anonymous error data with the OpenOSRS developers", description = "Share anonymous error data with the OpenOSRS developers",
titleSection = "logTitle" titleSection = "logTitle"
) )
@@ -108,101 +108,26 @@ public interface OpenOSRSConfig extends Config
return SortStyle.CATEGORY; return SortStyle.CATEGORY;
} }
@ConfigTitleSection( @ConfigItem(
keyName = "hidePluginsTitle",
name = "Hide By Type",
description = "",
position = 4, position = 4,
titleSection = "pluginsTitle" keyName = "enableCategories",
name = "Categorize plugins",
description = "Show sections in the plugin list for each plugin type",
titleSection = "pluginSortingTitle",
hidden = true,
unhide = "pluginSortMode",
unhideValue = "Category"
) )
default Title hidePluginsTitle() default boolean enableCategories()
{ {
return new Title(); return true;
}
@ConfigItem(
position = 5,
keyName = "hidePlugins",
name = "Hide All Plugins",
description = "Hides all OpenOSRS plugins if checked",
titleSection = "hidePluginsTitle",
hide = "hidePvmPlugins || hidePvpPlugins || hideSkillingPlugins || hideUtilityPlugins || hideExternalPlugins"
)
default boolean hidePlugins()
{
return false;
}
@ConfigItem(
position = 6,
keyName = "hideExternalPlugins",
name = "Hide External Plugins",
description = "Hides all OpenOSRS external plugins if checked",
titleSection = "hidePluginsTitle",
hide = "hidePlugins"
)
default boolean hideExternalPlugins()
{
return false;
}
@ConfigItem(
position = 7,
keyName = "hidePvmPlugins",
name = "Hide PvM Plugins",
description = "Hides all OpenOSRS PvM plugins if checked",
titleSection = "hidePluginsTitle",
hide = "hidePlugins"
)
default boolean hidePvmPlugins()
{
return false;
}
@ConfigItem(
position = 8,
keyName = "hideSkillingPlugins",
name = "Hide Skilling Plugins",
description = "Hides all OpenOSRS skilling plugins if checked",
titleSection = "hidePluginsTitle",
hide = "hidePlugins"
)
default boolean hideSkillingPlugins()
{
return false;
}
@ConfigItem(
position = 9,
keyName = "hidePvpPlugins",
name = "Hide PvP Plugins",
description = "Hides all OpenOSRS Pvp plugins if checked",
titleSection = "hidePluginsTitle",
hide = "hidePlugins"
)
default boolean hidePvpPlugins()
{
return false;
}
@ConfigItem(
position = 10,
keyName = "hideUtilityPlugins",
name = "Hide Utility Plugins",
description = "Hides all OpenOSRS utility plugins if checked",
titleSection = "hidePluginsTitle",
hide = "hidePlugins"
)
default boolean hideUtilityPlugins()
{
return false;
} }
@ConfigTitleSection( @ConfigTitleSection(
keyName = "pluginsColorTitle", keyName = "pluginsColorTitle",
name = "Colors", name = "Colors",
description = "", description = "",
position = 11, position = 5,
titleSection = "pluginsTitle" titleSection = "pluginsTitle"
) )
default Title pluginsColorTitle() default Title pluginsColorTitle()
@@ -210,26 +135,27 @@ public interface OpenOSRSConfig extends Config
return new Title(); return new Title();
} }
@Alpha
@ConfigItem( @ConfigItem(
position = 12, position = 6,
keyName = "externalColor", keyName = "enabledColors",
name = "External color", name = "Enable plugin colors",
description = "Configure the color of external plugins", description = "Configure whether or not the plugins list should be colorcoded",
titleSection = "pluginsColorTitle" titleSection = "pluginsColorTitle"
) )
default Color externalColor() default boolean enabledColors()
{ {
return new Color(177, 156, 217, 255); return true;
} }
@Alpha @Alpha
@ConfigItem( @ConfigItem(
position = 13, position = 7,
keyName = "pvmColor", keyName = "pvmColor",
name = "PVM color", name = "PvM color",
description = "Configure the color of PVM related plugins", description = "Configure the color of PvM related plugins",
titleSection = "pluginsColorTitle" titleSection = "pluginsColorTitle",
hidden = true,
unhide = "enabledColors"
) )
default Color pvmColor() default Color pvmColor()
{ {
@@ -238,24 +164,13 @@ public interface OpenOSRSConfig extends Config
@Alpha @Alpha
@ConfigItem( @ConfigItem(
position = 14, position = 8,
keyName = "pvpColor",
name = "PVP color",
description = "Configure the color of PVP related plugins",
titleSection = "pluginsColorTitle"
)
default Color pvpColor()
{
return new Color(255, 105, 97, 255);
}
@Alpha
@ConfigItem(
position = 15,
keyName = "skillingColor", keyName = "skillingColor",
name = "Skilling color", name = "Skilling color",
description = "Configure the color of Skilling related plugins", description = "Configure the color of skilling related plugins",
titleSection = "pluginsColorTitle" titleSection = "pluginsColorTitle",
hidden = true,
unhide = "enabledColors"
) )
default Color skillingColor() default Color skillingColor()
{ {
@@ -264,22 +179,99 @@ public interface OpenOSRSConfig extends Config
@Alpha @Alpha
@ConfigItem( @ConfigItem(
position = 16, position = 9,
keyName = "pvpColor",
name = "PvP color",
description = "Configure the color of PvP related plugins",
titleSection = "pluginsColorTitle",
hidden = true,
unhide = "enabledColors"
)
default Color pvpColor()
{
return new Color(255, 105, 97, 255);
}
@Alpha
@ConfigItem(
position = 10,
keyName = "utilityColor", keyName = "utilityColor",
name = "Utility color", name = "Utility color",
description = "Configure the color of Utility related plugins", description = "Configure the color of utility related plugins",
titleSection = "pluginsColorTitle" titleSection = "pluginsColorTitle",
hidden = true,
unhide = "enabledColors"
) )
default Color utilityColor() default Color utilityColor()
{ {
return new Color(144, 212, 237, 255); return new Color(144, 212, 237, 255);
} }
@Alpha
@ConfigItem(
position = 11,
keyName = "minigameColor",
name = "Minigame color",
description = "Configure the color of minigame related plugins",
titleSection = "pluginsColorTitle",
hidden = true,
unhide = "enabledColors"
)
default Color minigameColor()
{
return new Color(235, 130, 66, 255);
}
@Alpha
@ConfigItem(
position = 12,
keyName = "miscellaneousColor",
name = "Miscellaneous color",
description = "Configure the color of miscellaneous related plugins",
titleSection = "pluginsColorTitle",
hidden = true,
unhide = "enabledColors"
)
default Color miscellaneousColor()
{
return new Color(243, 85, 136, 255);
}
@Alpha
@ConfigItem(
position = 13,
keyName = "gamemodeColor",
name = "Gamemode color",
description = "Configure the color of gamemode plugins",
titleSection = "pluginsColorTitle",
hidden = true,
unhide = "enabledColors"
)
default Color gamemodeColor()
{
return new Color(244, 239, 211, 255);
}
@Alpha
@ConfigItem(
position = 14,
keyName = "externalColor",
name = "External color",
description = "Configure the color of external plugins",
titleSection = "pluginsColorTitle",
hidden = true,
unhide = "enabledColors"
)
default Color externalColor()
{
return new Color(177, 156, 217, 255);
}
@ConfigTitleSection( @ConfigTitleSection(
keyName = "externalPluginsTitle", keyName = "externalPluginsTitle",
name = "External", name = "External",
description = "", description = "",
position = 17, position = 15,
titleSection = "pluginsTitle" titleSection = "pluginsTitle"
) )
default Title externalPluginsTitle() default Title externalPluginsTitle()
@@ -291,7 +283,7 @@ public interface OpenOSRSConfig extends Config
keyName = "enablePlugins", keyName = "enablePlugins",
name = "Enable loading of external plugins", name = "Enable loading of external plugins",
description = "Enable loading of external plugins", description = "Enable loading of external plugins",
position = 18, position = 16,
titleSection = "externalPluginsTitle" titleSection = "externalPluginsTitle"
) )
default boolean enablePlugins() default boolean enablePlugins()
@@ -303,7 +295,7 @@ public interface OpenOSRSConfig extends Config
keyName = "opacityTitle", keyName = "opacityTitle",
name = "Opacity", name = "Opacity",
description = "", description = "",
position = 19 position = 17
) )
default Title opacityTitle() default Title opacityTitle()
{ {
@@ -314,7 +306,7 @@ public interface OpenOSRSConfig extends Config
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 = 20, position = 18,
titleSection = "opacityTitle" titleSection = "opacityTitle"
) )
default boolean enableOpacity() default boolean enableOpacity()
@@ -330,7 +322,7 @@ public interface OpenOSRSConfig 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 = 21, position = 19,
titleSection = "opacityTitle" titleSection = "opacityTitle"
) )
default int opacityPercentage() default int opacityPercentage()
@@ -342,7 +334,7 @@ public interface OpenOSRSConfig extends Config
keyName = "miscTitle", keyName = "miscTitle",
name = "Miscellaneous", name = "Miscellaneous",
description = "", description = "",
position = 22 position = 20
) )
default Title miscTitle() default Title miscTitle()
{ {
@@ -353,7 +345,7 @@ public interface OpenOSRSConfig 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 = 23, position = 21,
titleSection = "miscTitle" titleSection = "miscTitle"
) )
default boolean keyboardPin() default boolean keyboardPin()
@@ -365,7 +357,7 @@ public interface OpenOSRSConfig extends Config
keyName = "detachHotkey", keyName = "detachHotkey",
name = "Detach Cam", name = "Detach Cam",
description = "Detach Camera hotkey, press this and it will activate detatched camera.", description = "Detach Camera hotkey, press this and it will activate detatched camera.",
position = 24, position = 22,
titleSection = "miscTitle" titleSection = "miscTitle"
) )
default Keybind detachHotkey() default Keybind detachHotkey()
@@ -29,9 +29,11 @@ import net.runelite.api.Constants;
import net.runelite.client.Notifier; import net.runelite.client.Notifier;
import net.runelite.client.ui.ContainableFrame; import net.runelite.client.ui.ContainableFrame;
@ConfigGroup("runelite") @ConfigGroup(RuneLiteConfig.GROUP_NAME)
public interface RuneLiteConfig extends Config public interface RuneLiteConfig extends Config
{ {
String GROUP_NAME = "runelite";
@ConfigTitleSection( @ConfigTitleSection(
keyName = "uiTitle", keyName = "uiTitle",
name = "User interface", name = "User interface",
@@ -24,7 +24,18 @@
*/ */
package net.runelite.client.events; package net.runelite.client.events;
public abstract class ChatInput import lombok.Getter;
import net.runelite.api.events.Event;
public abstract class ChatInput implements Event
{ {
@Getter
private boolean stop = false;
public void setStop()
{
this.stop = true;
}
public abstract void resume(); public abstract void resume();
} }
@@ -95,7 +95,7 @@ public class ExternalPluginLoader
List<Plugin> loadedPlugins; List<Plugin> loadedPlugins;
try try
{ {
loadedPlugins = pluginManager.scanAndInstantiate(loader, null); loadedPlugins = pluginManager.scanAndInstantiate(loader, null, true);
} }
catch (IOException ex) catch (IOException ex)
{ {
@@ -59,5 +59,5 @@ public @interface PluginDescriptor
boolean loadWhenOutdated() default false; boolean loadWhenOutdated() default false;
PluginType type() default PluginType.GENERAL_USE; PluginType type() default PluginType.UNCATEGORIZED;
} }
@@ -213,7 +213,7 @@ public class PluginManager
public void loadCorePlugins() throws IOException public void loadCorePlugins() throws IOException
{ {
plugins.addAll(scanAndInstantiate(getClass().getClassLoader(), PLUGIN_PACKAGE)); plugins.addAll(scanAndInstantiate(getClass().getClassLoader(), PLUGIN_PACKAGE, false));
} }
public void startCorePlugins() public void startCorePlugins()
@@ -246,7 +246,7 @@ public class PluginManager
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<Plugin> scanAndInstantiate(ClassLoader classLoader, String packageName) throws IOException List<Plugin> scanAndInstantiate(ClassLoader classLoader, String packageName, boolean external) throws IOException
{ {
RuneLiteSplashScreen.stage(.59, "Loading plugins"); RuneLiteSplashScreen.stage(.59, "Loading plugins");
MutableGraph<Class<? extends Plugin>> graph = GraphBuilder MutableGraph<Class<? extends Plugin>> graph = GraphBuilder
@@ -279,6 +279,12 @@ public class PluginManager
continue; continue;
} }
if (external && pluginDescriptor.type() != PluginType.EXTERNAL)
{
log.error("Class {} is using the external plugin loader but doesn't have PluginType.EXTERNAL", clazz);
continue;
}
if (!pluginDescriptor.loadWhenOutdated() && isOutdated) if (!pluginDescriptor.loadWhenOutdated() && isOutdated)
{ {
continue; continue;
@@ -1,12 +1,29 @@
package net.runelite.client.plugins; package net.runelite.client.plugins;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter(AccessLevel.PUBLIC)
@AllArgsConstructor
public enum PluginType public enum PluginType
{ {
PVM, PVM("PvM"),
PVP, PVP("PvP"),
SKILLING, SKILLING("Skilling"),
UTILITY, UTILITY("Utilities"),
GENERAL_USE, MISCELLANEOUS("Miscellaneous"),
EXTERNAL, EXTERNAL("External"),
IMPORTANT IMPORTANT("System"),
MINIGAME("Minigame"),
GAMEMODE("Gamemode"),
UNCATEGORIZED("Uncategorized");
private String name;
@Override
public String toString()
{
return getName();
}
} }
@@ -38,7 +38,8 @@ import net.runelite.client.plugins.PluginDescriptor;
name = "Account", name = "Account",
description = "Sync RuneLite config settings with your Google account", description = "Sync RuneLite config settings with your Google account",
tags = {"external", "google", "integration"}, tags = {"external", "google", "integration"},
loadWhenOutdated = true loadWhenOutdated = true,
hidden = true
) )
@Slf4j @Slf4j
@Singleton @Singleton
@@ -48,6 +48,7 @@ import net.runelite.client.callback.ClientThread;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
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.PluginType;
import net.runelite.client.plugins.achievementdiary.diaries.ArdougneDiaryRequirement; import net.runelite.client.plugins.achievementdiary.diaries.ArdougneDiaryRequirement;
import net.runelite.client.plugins.achievementdiary.diaries.DesertDiaryRequirement; import net.runelite.client.plugins.achievementdiary.diaries.DesertDiaryRequirement;
import net.runelite.client.plugins.achievementdiary.diaries.FaladorDiaryRequirement; import net.runelite.client.plugins.achievementdiary.diaries.FaladorDiaryRequirement;
@@ -65,7 +66,8 @@ import net.runelite.client.plugins.achievementdiary.diaries.WildernessDiaryRequi
@PluginDescriptor( @PluginDescriptor(
name = "Diary Requirements", name = "Diary Requirements",
description = "Display level requirements in Achievement Diary interface", description = "Display level requirements in Achievement Diary interface",
tags = {"achievements", "tasks"} tags = {"achievements", "tasks"},
type = PluginType.UTILITY
) )
@Singleton @Singleton
public class DiaryRequirementsPlugin extends Plugin public class DiaryRequirementsPlugin extends Plugin
@@ -51,7 +51,7 @@ public interface AgilityConfig extends Config
description = "This will remove the distance cap on rendering overlays for agility.", description = "This will remove the distance cap on rendering overlays for agility.",
warning = "<html><center>Enabling this setting on a low end machine may severely affect your fps." + warning = "<html><center>Enabling this setting on a low end machine may severely affect your fps." +
"<br>Click yes to enable this setting, knowing it might affect performance.</center></html>", "<br>Click yes to enable this setting, knowing it might affect performance.</center></html>",
position = 1, position = 0,
titleSection = "mainConfig" titleSection = "mainConfig"
) )
default boolean removeDistanceCap() default boolean removeDistanceCap()
@@ -59,6 +59,17 @@ public interface AgilityConfig extends Config
return false; return false;
} }
@ConfigItem(
keyName = "showCourseClickboxes",
name = "Show course Clickboxes",
description = "Show agility course obstacle clickboxes",
position = 1
)
default boolean showCourseClickboxes()
{
return true;
}
@ConfigItem( @ConfigItem(
keyName = "showLapCount", keyName = "showLapCount",
name = "Show Lap Count", name = "Show Lap Count",
@@ -71,7 +71,8 @@ class AgilityOverlay extends Overlay
plugin.getObstacles().forEach((object, obstacle) -> plugin.getObstacles().forEach((object, obstacle) ->
{ {
if (Obstacles.SHORTCUT_OBSTACLE_IDS.containsKey(object.getId()) && !plugin.isHighlightShortcuts() || if (Obstacles.SHORTCUT_OBSTACLE_IDS.containsKey(object.getId()) && !plugin.isHighlightShortcuts() ||
Obstacles.TRAP_OBSTACLE_IDS.contains(object.getId()) && !plugin.isShowTrapOverlay()) Obstacles.TRAP_OBSTACLE_IDS.contains(object.getId()) && !plugin.isShowTrapOverlay() ||
Obstacles.COURSE_OBSTACLE_IDS.contains(object.getId()) && !plugin.isShowCourseClickboxes())
{ {
return; return;
} }
@@ -77,6 +77,7 @@ import net.runelite.client.game.AgilityShortcut;
import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemManager;
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.PluginType;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
import net.runelite.client.util.ColorUtil; import net.runelite.client.util.ColorUtil;
@@ -84,7 +85,8 @@ import net.runelite.client.util.ColorUtil;
@PluginDescriptor( @PluginDescriptor(
name = "Agility", name = "Agility",
description = "Show helpful information about agility courses and obstacles", description = "Show helpful information about agility courses and obstacles",
tags = {"grace", "marks", "overlay", "shortcuts", "skilling", "traps"} tags = {"grace", "marks", "overlay", "shortcuts", "skilling", "traps"},
type = PluginType.SKILLING
) )
@Slf4j @Slf4j
@Singleton @Singleton
@@ -139,6 +141,8 @@ public class AgilityPlugin extends Plugin
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
private boolean removeDistanceCap; private boolean removeDistanceCap;
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
private boolean showCourseClickboxes;
@Getter(AccessLevel.PACKAGE)
private boolean showLapCount; private boolean showLapCount;
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
private int lapTimeout; private int lapTimeout;
@@ -258,6 +262,7 @@ public class AgilityPlugin extends Plugin
private void updateConfig() private void updateConfig()
{ {
this.removeDistanceCap = config.removeDistanceCap(); this.removeDistanceCap = config.removeDistanceCap();
this.showCourseClickboxes = config.showCourseClickboxes();
this.showLapCount = config.showLapCount(); this.showLapCount = config.showLapCount();
this.lapTimeout = config.lapTimeout(); this.lapTimeout = config.lapTimeout();
this.lapsToLevel = config.lapsToLevel(); this.lapsToLevel = config.lapsToLevel();
@@ -39,12 +39,14 @@ import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemManager;
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.PluginType;
import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
@PluginDescriptor( @PluginDescriptor(
name = "Ammo", name = "Ammo",
description = "Shows the current ammo the player has equipped", description = "Shows the current ammo the player has equipped",
tags = {"bolts", "darts", "chinchompa", "equipment"} tags = {"bolts", "darts", "chinchompa", "equipment"},
type = PluginType.UTILITY
) )
@Singleton @Singleton
public class AmmoPlugin extends Plugin public class AmmoPlugin extends Plugin
@@ -33,12 +33,14 @@ import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged; import net.runelite.client.events.ConfigChanged;
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.PluginType;
@PluginDescriptor( @PluginDescriptor(
name = "Animation Smoothing", name = "Animation Smoothing",
description = "Show smoother player, NPC, and object animations", description = "Show smoother player, NPC, and object animations",
tags = {"npcs", "objects", "players"}, tags = {"npcs", "objects", "players"},
enabledByDefault = false enabledByDefault = false,
type = PluginType.MISCELLANEOUS
) )
@Singleton @Singleton
public class AnimationSmoothingPlugin extends Plugin public class AnimationSmoothingPlugin extends Plugin
@@ -54,6 +54,7 @@ import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged; import net.runelite.client.events.ConfigChanged;
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.PluginType;
import static net.runelite.client.plugins.attackstyles.AttackStyle.CASTING; import static net.runelite.client.plugins.attackstyles.AttackStyle.CASTING;
import static net.runelite.client.plugins.attackstyles.AttackStyle.DEFENSIVE_CASTING; import static net.runelite.client.plugins.attackstyles.AttackStyle.DEFENSIVE_CASTING;
import static net.runelite.client.plugins.attackstyles.AttackStyle.OTHER; import static net.runelite.client.plugins.attackstyles.AttackStyle.OTHER;
@@ -62,7 +63,8 @@ import net.runelite.client.ui.overlay.OverlayManager;
@PluginDescriptor( @PluginDescriptor(
name = "Attack Styles", name = "Attack Styles",
description = "Show your current attack style as an overlay", description = "Show your current attack style as an overlay",
tags = {"combat", "defence", "magic", "overlay", "ranged", "strength", "warn", "pure"} tags = {"combat", "defence", "magic", "overlay", "ranged", "strength", "warn", "pure"},
type = PluginType.UTILITY
) )
@Singleton @Singleton
public class AttackStylesPlugin extends Plugin public class AttackStylesPlugin extends Plugin
@@ -71,13 +71,15 @@ import net.runelite.client.events.ConfigChanged;
import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemManager;
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.PluginType;
import net.runelite.client.plugins.banktags.tabs.BankSearch; import net.runelite.client.plugins.banktags.tabs.BankSearch;
import net.runelite.client.util.QuantityFormatter; import net.runelite.client.util.QuantityFormatter;
@PluginDescriptor( @PluginDescriptor(
name = "Bank", name = "Bank",
description = "Modifications to the banking interface", description = "Modifications to the banking interface",
tags = {"grand", "exchange", "high", "alchemy", "prices", "deposit"} tags = {"grand", "exchange", "high", "alchemy", "prices", "deposit"},
type = PluginType.UTILITY
) )
@Singleton @Singleton
public class BankPlugin extends Plugin public class BankPlugin extends Plugin
@@ -79,6 +79,7 @@ import net.runelite.client.input.MouseWheelListener;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDependency; import net.runelite.client.plugins.PluginDependency;
import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.PluginType;
import net.runelite.client.plugins.banktags.tabs.BankSearch; import net.runelite.client.plugins.banktags.tabs.BankSearch;
import net.runelite.client.plugins.banktags.tabs.TabInterface; import net.runelite.client.plugins.banktags.tabs.TabInterface;
import static net.runelite.client.plugins.banktags.tabs.TabInterface.FILTERED_CHARS; import static net.runelite.client.plugins.banktags.tabs.TabInterface.FILTERED_CHARS;
@@ -89,7 +90,8 @@ import net.runelite.client.util.QuantityFormatter;
@PluginDescriptor( @PluginDescriptor(
name = "Bank Tags", name = "Bank Tags",
description = "Enable tagging of bank items and searching of bank tags", description = "Enable tagging of bank items and searching of bank tags",
tags = {"searching", "tagging"} tags = {"searching", "tagging"},
type = PluginType.UTILITY
) )
@PluginDependency(ClueScrollPlugin.class) @PluginDependency(ClueScrollPlugin.class)
@Singleton @Singleton
@@ -880,19 +880,21 @@ public class TabInterface
--maxTabs; --maxTabs;
} }
if (currentTabIndex + direction >= tabManager.size() || currentTabIndex + direction < 0) int proposedIndex = currentTabIndex + direction;
int numTabs = tabManager.size() + 1;
if (proposedIndex >= numTabs || proposedIndex < 0)
{ {
currentTabIndex = 0; currentTabIndex = 0;
} }
else if (numTabs - proposedIndex >= maxTabs)
if ((tabManager.size() - (currentTabIndex + direction) >= maxTabs) && (currentTabIndex + direction > -1))
{ {
currentTabIndex += direction; currentTabIndex = proposedIndex;
} }
else if (maxTabs < tabManager.size() && tabManager.size() - (currentTabIndex + direction) < maxTabs) else if (maxTabs < numTabs && numTabs - proposedIndex < maxTabs)
{ {
// Edge case when only 1 tab displays instead of up to maxTabs when one is deleted at the end of the list // Edge case when only 1 tab displays instead of up to maxTabs when one is deleted at the end of the list
currentTabIndex += direction; currentTabIndex = proposedIndex;
scrollTab(-1); scrollTab(-1);
} }
@@ -973,7 +975,7 @@ public class TabInterface
{ {
int y = bounds.y + MARGIN + BUTTON_HEIGHT; int y = bounds.y + MARGIN + BUTTON_HEIGHT;
if (maxTabs >= tabManager.size()) if (maxTabs > tabManager.size())
{ {
currentTabIndex = 0; currentTabIndex = 0;
} }
@@ -999,6 +1001,8 @@ public class TabInterface
y += TAB_HEIGHT + MARGIN; y += TAB_HEIGHT + MARGIN;
} }
updateWidget(newTab, y);
boolean hidden = !(tabManager.size() > 0); boolean hidden = !(tabManager.size() > 0);
upButton.setHidden(hidden); upButton.setHidden(hidden);
@@ -68,7 +68,7 @@ import org.jetbrains.annotations.NotNull;
description = "Displays warning in chat when you join a" + description = "Displays warning in chat when you join a" +
"clan chat/new member join your clan chat and he is in a WDR/RuneWatch/Manual List", "clan chat/new member join your clan chat and he is in a WDR/RuneWatch/Manual List",
tags = {"PVM", "WDR", "RuneWatch"}, tags = {"PVM", "WDR", "RuneWatch"},
type = PluginType.UTILITY, type = PluginType.MISCELLANEOUS,
enabledByDefault = false enabledByDefault = false
) )
@Singleton @Singleton
@@ -106,7 +106,7 @@ import org.apache.commons.lang3.StringUtils;
name = "Barbarian Assault", name = "Barbarian Assault",
description = "Custom barbarian assault plugin, use along with BA Tools", description = "Custom barbarian assault plugin, use along with BA Tools",
tags = {"minigame", "overlay", "timer"}, tags = {"minigame", "overlay", "timer"},
type = PluginType.PVM // don't remove this, added this because our barbarian assault plugin is big time modified type = PluginType.MINIGAME // don't remove this, added this because our barbarian assault plugin is big time modified
) )
@Singleton @Singleton
public class BarbarianAssaultPlugin extends Plugin implements KeyListener public class BarbarianAssaultPlugin extends Plugin implements KeyListener
@@ -59,6 +59,7 @@ import net.runelite.client.events.ConfigChanged;
import net.runelite.client.game.SpriteManager; import net.runelite.client.game.SpriteManager;
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.PluginType;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
import net.runelite.client.ui.overlay.infobox.InfoBoxPriority; import net.runelite.client.ui.overlay.infobox.InfoBoxPriority;
@@ -67,7 +68,8 @@ import net.runelite.client.ui.overlay.infobox.LoopTimer;
@PluginDescriptor( @PluginDescriptor(
name = "Barrows Brothers", name = "Barrows Brothers",
description = "Show helpful information for the Barrows minigame", description = "Show helpful information for the Barrows minigame",
tags = {"combat", "minigame", "minimap", "bosses", "pve", "pvm"} tags = {"combat", "minigame", "minimap", "bosses", "pve", "pvm"},
type = PluginType.MINIGAME
) )
@Singleton @Singleton
public class BarrowsPlugin extends Plugin public class BarrowsPlugin extends Plugin
@@ -51,13 +51,15 @@ import net.runelite.client.events.ConfigChanged;
import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemManager;
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.PluginType;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
@PluginDescriptor( @PluginDescriptor(
name = "Blast Furnace", name = "Blast Furnace",
description = "Show helpful information for the Blast Furnace minigame", description = "Show helpful information for the Blast Furnace minigame",
tags = {"minigame", "overlay", "skilling", "smithing"} tags = {"minigame", "overlay", "skilling", "smithing"},
type = PluginType.MINIGAME
) )
@Singleton @Singleton
public class BlastFurnacePlugin extends Plugin public class BlastFurnacePlugin extends Plugin
@@ -45,12 +45,14 @@ import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
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.PluginType;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
@PluginDescriptor( @PluginDescriptor(
name = "Blast Mine", name = "Blast Mine",
description = "Show helpful information for the Blast Mine minigame", description = "Show helpful information for the Blast Mine minigame",
tags = {"explode", "explosive", "mining", "minigame", "skilling"} tags = {"explode", "explosive", "mining", "minigame", "skilling"},
type = PluginType.MINIGAME
) )
@Singleton @Singleton
public class BlastMinePlugin extends Plugin public class BlastMinePlugin extends Plugin
@@ -49,6 +49,7 @@ import net.runelite.client.events.ConfigChanged;
import net.runelite.client.game.SkillIconManager; import net.runelite.client.game.SkillIconManager;
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.PluginType;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
import net.runelite.client.util.ImageUtil; import net.runelite.client.util.ImageUtil;
@@ -56,7 +57,8 @@ import net.runelite.client.util.ImageUtil;
@PluginDescriptor( @PluginDescriptor(
name = "Boosts Information", name = "Boosts Information",
description = "Show combat and/or skill boost information", description = "Show combat and/or skill boost information",
tags = {"combat", "notifications", "skilling", "overlay"} tags = {"combat", "notifications", "skilling", "overlay"},
type = PluginType.UTILITY
) )
@Singleton @Singleton
public class BoostsPlugin extends Plugin public class BoostsPlugin extends Plugin
@@ -34,12 +34,14 @@ import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemManager;
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.PluginType;
import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
@PluginDescriptor( @PluginDescriptor(
name = "Boss Timers", name = "Boss Timers",
description = "Show boss spawn timer overlays", description = "Show boss spawn timer overlays",
tags = {"combat", "pve", "overlay", "spawn"} tags = {"combat", "pve", "overlay", "spawn"},
type = PluginType.PVM
) )
@Singleton @Singleton
@Slf4j @Slf4j
@@ -0,0 +1,139 @@
package net.runelite.client.plugins.bronzeman;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
import net.runelite.client.config.ConfigSection;
@ConfigGroup("bronzemanmode")
public interface BronzeManConfig extends Config
{
@ConfigSection(
name = "Unlocked Notifications",
description = "",
position = 0,
keyName = "unlockNotifications"
)
default boolean unlockNotifications()
{
return false;
}
@ConfigSection(
name = "Game Mode Options",
description = "",
position = 1,
keyName = "gameModeOptions"
)
default boolean gameModeOptions()
{
return false;
}
@ConfigSection(
name = "Chat Commands",
description = "",
position = 2,
keyName = "chatCommands"
)
default boolean chatCommands()
{
return false;
}
@ConfigItem(
keyName = "notifyImgUnlock",
name = "image unlocked notification",
description = "Configure whether to send the notification image when you unlock a new item.",
position = 0,
section = "unlockNotifications"
)
default boolean notifyImgUnlock()
{
return true;
}
@ConfigItem(
keyName = "notifyChatUnlock",
name = "Chat unlocked notification",
description = "Configure whether to send the chat notification when you unlock a new item.",
position = 1,
section = "unlockNotifications"
)
default boolean notifyChatUnlock()
{
return true;
}
@ConfigItem(
keyName = "resetCommand",
name = "Enable resetunlocks command",
description = "Enables the !resetunlocks command used for wiping your unlocked items.",
position = 0,
section = "chatCommands"
)
default boolean resetCommand()
{
return false;
}
@ConfigItem(
keyName = "countCommand",
name = "Enable countunlocks command",
description = "Enables the !countunlocks command used for counting your unlocked items.",
position = 1,
section = "chatCommands"
)
default boolean countCommand()
{
return true;
}
@ConfigItem(
keyName = "backupCommand",
name = "Enable backupunlocks command",
description = "Enables the !backupunlocks command used for backing up your unlocked items.",
position = 2,
section = "chatCommands"
)
default boolean backupCommand()
{
return true;
}
@ConfigItem(
keyName = "restoreCommand",
name = "Enable restoreunlocks command",
description = "Enables the !restoreunlocks command used for restoring your unlocked items file.",
position = 3,
section = "chatCommands"
)
default boolean restoreCommand()
{
return true;
}
@ConfigItem(
keyName = "deleteCommand",
name = "Enable deleteunlocks command",
description = "Enables the !deleteunlocks command used for deleting your unlocked items file.",
position = 4,
section = "chatCommands"
)
default boolean deleteCommand()
{
return false;
}
@ConfigItem(
keyName = "hideTradeOption",
name = "Hide trade with option",
description = "Hides the trade with option from the player menu",
position = 0,
section = "gameModeOptions"
)
default boolean hideTradeOption()
{
return true;
}
}
@@ -73,7 +73,7 @@ public class BronzeManOverlay extends Overlay
{ {
currentUnlock.setLocationY(drawY + 1); currentUnlock.setLocationY(drawY + 1);
} }
if (currentUnlock.displayed()) if (currentUnlock.displayed(itemUnlockList.size()))
{ {
itemUnlockList.remove(currentUnlock); itemUnlockList.remove(currentUnlock);
currentUnlock = null; currentUnlock = null;
@@ -1,38 +1,53 @@
package net.runelite.client.plugins.bronzeman; package net.runelite.client.plugins.bronzeman;
import com.google.inject.Provides;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileReader; import java.io.FileReader;
import java.io.InputStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.net.URL;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.imageio.ImageIO;
import javax.inject.Inject; import javax.inject.Inject;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.ChatMessageType;
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.Item;
import net.runelite.api.ItemID; import net.runelite.api.ItemID;
import net.runelite.api.MenuEntry;
import net.runelite.api.Player;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.ClientTick;
import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.GameTick;
import net.runelite.api.events.ItemContainerChanged; import net.runelite.api.events.ItemContainerChanged;
import net.runelite.api.events.MenuOpened;
import net.runelite.api.events.WidgetLoaded; import net.runelite.api.events.WidgetLoaded;
import net.runelite.api.util.Text;
import static net.runelite.api.util.Text.sanitize;
import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetID;
import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.RuneLite; import net.runelite.client.RuneLite;
import net.runelite.client.chat.ChatColorType;
import net.runelite.client.chat.ChatMessageBuilder;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.chat.QueuedMessage;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged;
import net.runelite.client.game.ItemManager;
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.PluginType; import net.runelite.client.plugins.PluginType;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.util.ImageUtil;
/** /**
* @author Seth Davis * @author Seth Davis
@@ -43,38 +58,69 @@ import net.runelite.client.ui.overlay.OverlayManager;
name = "Bronze Man Mode", name = "Bronze Man Mode",
description = "Restrict yourself as an Iron Meme with GE use for items you have unlocked.", description = "Restrict yourself as an Iron Meme with GE use for items you have unlocked.",
tags = {"Bronze", "pve", "restrict", "game", "challenge", "bronzeman", "ironman"}, tags = {"Bronze", "pve", "restrict", "game", "challenge", "bronzeman", "ironman"},
type = PluginType.UTILITY, type = PluginType.GAMEMODE,
enabledByDefault = false enabledByDefault = false
) )
@Slf4j @Slf4j
public class BronzemanPlugin extends Plugin public class BronzemanPlugin extends Plugin
{ {
private static final String BACKUP_CHAT_COMMAND = "!backupunlocks";
private static final String COUNT_CHAT_COMMAND = "!countunlocks";
private static final String DELETE_CHAT_COMMAND = "!deleteunlocks";
private static final String RESET_CHAT_COMMAND = "!resetunlocks";
private static final String RESTORE_CHAT_COMMAND = "!restoreunlocks";
private final BufferedImage UNLOCK_IMAGE = ImageUtil.getResourceStreamFromClass(getClass(), "item_unlocked.png");
@Inject
ItemManager itemManager;
@Inject @Inject
private Client client; private Client client;
@Inject @Inject
private OverlayManager overlayManager; private OverlayManager overlayManager;
@Inject
private BronzeManConfig config;
@Inject
private ChatMessageManager chatMessageManager;
@Inject @Inject
private BronzeManOverlay bronzemanOverlay; private BronzeManOverlay bronzemanOverlay;
private List<Integer> unlockedItems; private List<Integer> unlockedItems;
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
private BufferedImage unlockImage = null; private BufferedImage unlockImage = null;
private boolean notifyImgUnlock;
private boolean notifyChatUnlock;
private boolean resetCommand;
private boolean countCommand;
private boolean backupCommand;
private boolean deleteCommand;
private boolean restoreCommand;
private boolean hideTradeOption;
/** /**
* Loads GrandExchange widgets for further manipulation of the interface * Loads GrandExchange widgets for further manipulation of the interface
**/ **/
private Widget grandExchangeWindow; private Widget grandExchangeWindow;
private Widget grandExchangeChatBox; private Widget grandExchangeChatBox;
@Provides
BronzeManConfig getConfig(ConfigManager configManager)
{
return configManager.getConfig(BronzeManConfig.class);
}
@Override @Override
protected void startUp() protected void startUp()
{ {
loadUnlockImage(); /**
* Downloads the item-unlock png file to display unlocks
**/
unlockImage = UNLOCK_IMAGE;
unlockedItems = new ArrayList<>(); unlockedItems = new ArrayList<>();
overlayManager.add(bronzemanOverlay); overlayManager.add(bronzemanOverlay);
updateConfig();
loadPlayerUnlocks();
} }
@Override @Override
@@ -84,6 +130,21 @@ public class BronzemanPlugin extends Plugin
overlayManager.remove(bronzemanOverlay); overlayManager.remove(bronzemanOverlay);
} }
@Subscribe
private void onConfigChanged(ConfigChanged event)
{
if (!event.getKey().equals("notifyImgUnlock"))
{
overlayManager.remove(bronzemanOverlay);
}
if (!event.getGroup().equals("bronzemanmode"))
{
return;
}
updateConfig();
}
/** /**
* Loads players unlocks on login * Loads players unlocks on login
**/ **/
@@ -142,7 +203,7 @@ public class BronzemanPlugin extends Plugin
* Handles greying out items in the GrandExchange * Handles greying out items in the GrandExchange
**/ **/
@Subscribe @Subscribe
public void onGameTick(GameTick e) public void onClientTick(ClientTick e)
{ {
if (grandExchangeWindow == null || grandExchangeChatBox == null || grandExchangeWindow.isHidden()) if (grandExchangeWindow == null || grandExchangeChatBox == null || grandExchangeWindow.isHidden())
{ {
@@ -182,8 +243,18 @@ public class BronzemanPlugin extends Plugin
private void queueItemUnlock(int itemId) private void queueItemUnlock(int itemId)
{ {
unlockedItems.add(itemId); unlockedItems.add(itemId);
bronzemanOverlay.addItemUnlock(itemId);
savePlayerUnlocks();// Save after every item to fail-safe logging out savePlayerUnlocks();// Save after every item to fail-safe logging out
if (this.notifyChatUnlock)
{
sendMessage("You have successfully unlocked item: " + itemManager.getItemDefinition(itemId).getName());
}
if (!this.notifyImgUnlock)
{
return;
}
bronzemanOverlay.addItemUnlock(itemId);
} }
/** /**
@@ -193,6 +264,7 @@ public class BronzemanPlugin extends Plugin
{ {
queueItemUnlock(ItemID.COINS_995); queueItemUnlock(ItemID.COINS_995);
queueItemUnlock(ItemID.OLD_SCHOOL_BOND); queueItemUnlock(ItemID.OLD_SCHOOL_BOND);
queueItemUnlock(ItemID.PLATINUM_TOKEN);
} }
/** /**
@@ -218,7 +290,7 @@ public class BronzemanPlugin extends Plugin
} }
/** /**
* Loads a players unlcoks everytime they login * Loads a players unlocks everytime they login
**/ **/
private void loadPlayerUnlocks() private void loadPlayerUnlocks()
{ {
@@ -253,25 +325,180 @@ public class BronzemanPlugin extends Plugin
} }
} }
/**
* Downloads the item-unlock png file to display unlocks @Subscribe
**/ public void onChatMessage(ChatMessage chatMessage)
private void loadUnlockImage()
{ {
final String playerName;
if (chatMessage.equals(ChatMessageType.PRIVATECHATOUT))
{
playerName = client.getLocalPlayer().getName();
}
else
{
playerName = sanitize(chatMessage.getName());
}
if (this.countCommand && chatMessage.getMessage().toLowerCase().equals(COUNT_CHAT_COMMAND))
{
sendMessage("You have successfully unlocked " + unlockedItems.size() + " items.");
}
if (this.resetCommand && chatMessage.getMessage().toLowerCase().equals(RESET_CHAT_COMMAND))
{
resetUnlocks();
}
if (this.backupCommand && chatMessage.getMessage().toLowerCase().equals(BACKUP_CHAT_COMMAND))
{
backupUnlocks();
}
if (this.deleteCommand && chatMessage.getMessage().toLowerCase().equals(DELETE_CHAT_COMMAND))
{
deleteUnlocks();
}
if (this.restoreCommand && chatMessage.getMessage().toLowerCase().equals(RESTORE_CHAT_COMMAND))
{
restoreUnlocks();
}
}
private void backupUnlocks()
{
File playerFolder = new File(RuneLite.PROFILES_DIR, client.getUsername());
if (!playerFolder.exists())
{
return;
}
File playerFile = new File(playerFolder, "bronzeman-unlocks.txt");
if (!playerFile.exists())
{
return;
}
Path originalPath = playerFile.toPath();
try try
{ {
File imageFile = new File(RuneLite.RUNELITE_DIR, "item-unlocked.png"); Files.copy(originalPath, Paths.get(playerFile.getPath().replace(".txt", ".backup")),
if (!imageFile.exists()) StandardCopyOption.REPLACE_EXISTING);
{
InputStream in = new URL("https://i.imgur.com/KWVNlsq.png").openStream();
Files.copy(in, Paths.get(imageFile.getPath()));
}
unlockImage = ImageIO.read(imageFile);
} }
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(); e.printStackTrace();
return;
} }
sendMessage("Successfully backed up current unlock file!");
}
private void restoreUnlocks()
{
File playerFolder = new File(RuneLite.PROFILES_DIR, client.getUsername());
if (!playerFolder.exists())
{
return;
}
File playerFile = new File(playerFolder, "bronzeman-unlocks.backup");
if (!playerFile.exists())
{
return;
}
Path originalPath = playerFile.toPath();
try
{
Files.copy(originalPath, Paths.get(playerFile.getPath().replace(".backup", ".txt")),
StandardCopyOption.REPLACE_EXISTING);
}
catch (Exception e)
{
e.printStackTrace();
return;
}
sendMessage("Successfully restored current unlock file!");
}
private void resetUnlocks()
{
try
{
File playerFolder = new File(RuneLite.PROFILES_DIR, client.getUsername());
File playerFile = new File(playerFolder, "bronzeman-unlocks.txt");
playerFile.delete();
unlockedItems.clear();
savePlayerUnlocks();
unlockDefaultItems();
}
catch (Exception e)
{
e.printStackTrace();
return;
}
sendMessage("Current Unlock file succesfully reset!");
}
private void deleteUnlocks()
{
backupUnlocks();
try
{
File playerFolder = new File(RuneLite.PROFILES_DIR, client.getUsername());
File playerFile = new File(playerFolder, "bronzeman-unlocks.txt");
playerFile.delete();
}
catch (Exception e)
{
e.printStackTrace();
return;
}
sendMessage("Current Unlock file succesfully deleted!");
}
@Subscribe
private void onMenuOpened(MenuOpened event)
{
Player localPlayer = client.getLocalPlayer();
if (localPlayer == null)
{
return;
}
List<MenuEntry> menu_entries = new ArrayList<>();
for (MenuEntry entry : event.getMenuEntries())
{
String option = Text.removeTags(entry.getOption()).toLowerCase();
if (option.contains("trade with") && this.hideTradeOption)
{
continue;
}
menu_entries.add(entry);
}
event.setMenuEntries(menu_entries.toArray(new MenuEntry[0]));
event.setModified();
}
private void sendMessage(String text)
{
final ChatMessageBuilder message = new ChatMessageBuilder()
.append(ChatColorType.HIGHLIGHT)
.append(text);
chatMessageManager.queue(QueuedMessage.builder()
.type(ChatMessageType.CONSOLE)
.runeLiteFormattedMessage(message.build())
.build());
}
private void updateConfig()
{
this.notifyImgUnlock = config.notifyImgUnlock();
this.resetCommand = config.resetCommand();
this.countCommand = config.countCommand();
this.backupCommand = config.backupCommand();
this.notifyChatUnlock = config.notifyChatUnlock();
this.deleteCommand = config.deleteCommand();
this.restoreCommand = config.restoreCommand();
this.hideTradeOption = config.hideTradeOption();
} }
} }
@@ -40,8 +40,12 @@ public class ItemUnlock
/** /**
* Returns whether or not an items has been displayed as unlocked yet * Returns whether or not an items has been displayed as unlocked yet
**/ **/
public boolean displayed() public boolean displayed(int queue)
{ {
if (queue >= 2)
{
return System.currentTimeMillis() > initTime + (750);
}
return System.currentTimeMillis() > initTime + (5000); return System.currentTimeMillis() > initTime + (5000);
} }
@@ -147,4 +147,15 @@ public interface CameraConfig extends Config
{ {
return false; return false;
} }
@ConfigItem(
keyName = "compassLook",
name = "Compass options",
description = "Adds Look South, East, and West options to the compass",
position = 10
)
default boolean compassLook()
{
return true;
}
} }
@@ -30,13 +30,16 @@ import com.google.inject.Inject;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.util.Arrays;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.MenuEntry; import net.runelite.api.MenuEntry;
import net.runelite.api.MenuOpcode;
import net.runelite.api.ScriptID; import net.runelite.api.ScriptID;
import net.runelite.api.VarPlayer; import net.runelite.api.VarPlayer;
import net.runelite.api.events.ClientTick; import net.runelite.api.events.ClientTick;
import net.runelite.api.events.FocusChanged; import net.runelite.api.events.FocusChanged;
import net.runelite.api.events.MenuEntryAdded;
import net.runelite.api.events.ScriptCallbackEvent; import net.runelite.api.events.ScriptCallbackEvent;
import net.runelite.client.callback.ClientThread; import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
@@ -48,13 +51,15 @@ import net.runelite.client.input.MouseListener;
import net.runelite.client.input.MouseManager; import net.runelite.client.input.MouseManager;
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.PluginType;
import net.runelite.client.util.MiscUtils; import net.runelite.client.util.MiscUtils;
@PluginDescriptor( @PluginDescriptor(
name = "Camera Zoom", name = "Camera Zoom",
description = "Expands zoom limit, provides vertical camera, and remaps mouse input keys", description = "Expands zoom limit, provides vertical camera, and remaps mouse input keys",
tags = {"zoom", "limit", "vertical", "click", "mouse"}, tags = {"zoom", "limit", "vertical", "click", "mouse"},
enabledByDefault = false enabledByDefault = false,
type = PluginType.MISCELLANEOUS
) )
public class CameraPlugin extends Plugin implements KeyListener, MouseListener public class CameraPlugin extends Plugin implements KeyListener, MouseListener
{ {
@@ -65,6 +70,10 @@ public class CameraPlugin extends Plugin implements KeyListener, MouseListener
*/ */
private static final int INNER_ZOOM_LIMIT = 1004; private static final int INNER_ZOOM_LIMIT = 1004;
private static final int DEFAULT_ZOOM_INCREMENT = 25; private static final int DEFAULT_ZOOM_INCREMENT = 25;
private static final String LOOK_NORTH = "Look North";
private static final String LOOK_SOUTH = "Look South";
private static final String LOOK_EAST = "Look East";
private static final String LOOK_WEST = "Look West";
private boolean controlDown; private boolean controlDown;
// flags used to store the mousedown states // flags used to store the mousedown states
@@ -96,6 +105,60 @@ public class CameraPlugin extends Plugin implements KeyListener, MouseListener
return configManager.getConfig(CameraConfig.class); return configManager.getConfig(CameraConfig.class);
} }
@Override
protected void startUp()
{
rightClick = false;
middleClick = false;
menuHasEntries = false;
client.setCameraPitchRelaxerEnabled(cameraConfig.relaxCameraPitch());
keyManager.registerKeyListener(this);
mouseManager.registerMouseListener(this);
}
@Override
protected void shutDown()
{
client.setCameraPitchRelaxerEnabled(false);
keyManager.unregisterKeyListener(this);
mouseManager.unregisterMouseListener(this);
controlDown = false;
}
@Subscribe
public void onMenuEntryAdded(MenuEntryAdded menuEntryAdded)
{
if (menuEntryAdded.getOpcode() == MenuOpcode.WIDGET_DEFAULT.getId() && menuEntryAdded.getOption().equals(LOOK_NORTH) && cameraConfig.compassLook())
{
MenuEntry[] menuEntries = client.getMenuEntries();
int len = menuEntries.length;
MenuEntry north = menuEntries[len - 1];
menuEntries = Arrays.copyOf(menuEntries, len + 3);
// The handling for these entries is done in ToplevelCompassOp.rs2asm
menuEntries[--len] = createCameraLookEntry(menuEntryAdded, 4, LOOK_WEST);
menuEntries[++len] = createCameraLookEntry(menuEntryAdded, 3, LOOK_EAST);
menuEntries[++len] = createCameraLookEntry(menuEntryAdded, 2, LOOK_SOUTH);
menuEntries[++len] = north;
client.setMenuEntries(menuEntries);
}
}
private MenuEntry createCameraLookEntry(MenuEntryAdded lookNorth, int identifier, String option)
{
MenuEntry m = new MenuEntry();
m.setOption(option);
m.setTarget(lookNorth.getTarget());
m.setIdentifier(identifier);
m.setOpcode(MenuOpcode.WIDGET_DEFAULT.getId());
m.setParam0(lookNorth.getParam0());
m.setParam1(lookNorth.getParam1());
return m;
}
@Subscribe @Subscribe
private void onScriptCallbackEvent(ScriptCallbackEvent event) private void onScriptCallbackEvent(ScriptCallbackEvent event)
{ {
@@ -169,27 +232,6 @@ public class CameraPlugin extends Plugin implements KeyListener, MouseListener
} }
} }
@Override
protected void startUp()
{
rightClick = false;
middleClick = false;
menuHasEntries = false;
client.setCameraPitchRelaxerEnabled(cameraConfig.relaxCameraPitch());
keyManager.registerKeyListener(this);
mouseManager.registerMouseListener(this);
}
@Override
protected void shutDown()
{
client.setCameraPitchRelaxerEnabled(false);
keyManager.unregisterKeyListener(this);
mouseManager.unregisterMouseListener(this);
controlDown = false;
}
@Subscribe @Subscribe
private void onConfigChanged(ConfigChanged ev) private void onConfigChanged(ConfigChanged ev)
{ {
@@ -51,6 +51,7 @@ import net.runelite.client.events.ConfigChanged;
import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemManager;
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.PluginType;
import net.runelite.client.task.Schedule; import net.runelite.client.task.Schedule;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
@@ -59,7 +60,8 @@ import net.runelite.client.util.ItemUtil;
@PluginDescriptor( @PluginDescriptor(
name = "Cannon", name = "Cannon",
description = "Show information about cannon placement and/or amount of cannonballs", description = "Show information about cannon placement and/or amount of cannonballs",
tags = {"combat", "notifications", "ranged", "overlay"} tags = {"combat", "notifications", "ranged", "overlay"},
type = PluginType.UTILITY
) )
public class CannonPlugin extends Plugin public class CannonPlugin extends Plugin
{ {
@@ -41,12 +41,14 @@ import net.runelite.api.events.NpcSpawned;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
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.PluginType;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
@PluginDescriptor( @PluginDescriptor(
name = "Cerberus", name = "Cerberus",
description = "Show what to pray against the summoned souls", description = "Show what to pray against the summoned souls",
tags = {"bosses", "combat", "ghosts", "prayer", "pve", "overlay", "souls"} tags = {"bosses", "combat", "ghosts", "prayer", "pve", "overlay", "souls"},
type = PluginType.PVM
) )
@Singleton @Singleton
public class CerberusPlugin extends Plugin public class CerberusPlugin extends Plugin
@@ -42,9 +42,11 @@ import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged; import net.runelite.client.events.ConfigChanged;
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.PluginType;
@PluginDescriptor( @PluginDescriptor(
name = "Chatbox performance" name = "Chatbox performance",
type = PluginType.MISCELLANEOUS
) )
@Singleton @Singleton
public class ChatboxPerformancePlugin extends Plugin public class ChatboxPerformancePlugin extends Plugin
@@ -68,6 +68,7 @@ import net.runelite.client.game.ItemManager;
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.PluginType;
import net.runelite.client.util.QuantityFormatter; import net.runelite.client.util.QuantityFormatter;
import net.runelite.http.api.chat.ChatClient; import net.runelite.http.api.chat.ChatClient;
import net.runelite.http.api.chat.Duels; import net.runelite.http.api.chat.Duels;
@@ -84,7 +85,8 @@ import org.apache.commons.text.WordUtils;
@PluginDescriptor( @PluginDescriptor(
name = "Chat Commands", name = "Chat Commands",
description = "Enable chat commands", description = "Enable chat commands",
tags = {"grand", "exchange", "level", "prices"} tags = {"grand", "exchange", "level", "prices"},
type = PluginType.UTILITY
) )
@Singleton @Singleton
@Slf4j @Slf4j
@@ -29,7 +29,9 @@ 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.ScriptID; import net.runelite.api.ScriptID;
import net.runelite.api.VarClientInt;
import net.runelite.api.VarClientStr; import net.runelite.api.VarClientStr;
import net.runelite.api.vars.InputType;
import net.runelite.client.callback.ClientThread; import net.runelite.client.callback.ClientThread;
import net.runelite.client.input.KeyListener; import net.runelite.client.input.KeyListener;
@@ -56,7 +58,11 @@ class ChatKeyboardListener implements KeyListener
{ {
if (chatCommandsConfig.clearSingleWord().matches(e)) if (chatCommandsConfig.clearSingleWord().matches(e))
{ {
String input = client.getVar(VarClientStr.CHATBOX_TYPED_TEXT); int inputTye = client.getVar(VarClientInt.INPUT_TYPE);
String input = inputTye == InputType.NONE.getType()
? client.getVar(VarClientStr.CHATBOX_TYPED_TEXT)
: client.getVar(VarClientStr.INPUT_TEXT);
if (input != null) if (input != null)
{ {
// remove trailing space // remove trailing space
@@ -77,20 +83,27 @@ class ChatKeyboardListener implements KeyListener
replacement = ""; replacement = "";
} }
clientThread.invoke(() -> clientThread.invoke(() -> applyText(inputTye, replacement));
{
client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, replacement);
client.runScript(ScriptID.CHAT_PROMPT_INIT);
});
} }
} }
else if (chatCommandsConfig.clearChatBox().matches(e)) else if (chatCommandsConfig.clearChatBox().matches(e))
{ {
clientThread.invoke(() -> int inputTye = client.getVar(VarClientInt.INPUT_TYPE);
{ clientThread.invoke(() -> applyText(inputTye, ""));
client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, ""); }
client.runScript(ScriptID.CHAT_PROMPT_INIT); }
});
private void applyText(int inputType, String replacement)
{
if (inputType == InputType.NONE.getType())
{
client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, replacement);
client.runScript(ScriptID.CHAT_PROMPT_INIT);
}
else if (inputType == InputType.PRIVATE_MESSAGE.getType())
{
client.setVar(VarClientStr.INPUT_TEXT, replacement);
client.runScript(ScriptID.CHAT_TEXT_INPUT_REBUILD, "");
} }
} }
@@ -50,12 +50,14 @@ import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged; import net.runelite.client.events.ConfigChanged;
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.PluginType;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@PluginDescriptor( @PluginDescriptor(
name = "Chat Filter", name = "Chat Filter",
description = "Censor user configurable words or patterns from chat", description = "Censor user configurable words or patterns from chat",
enabledByDefault = false enabledByDefault = false,
type = PluginType.MISCELLANEOUS
) )
@Singleton @Singleton
public class ChatFilterPlugin extends Plugin public class ChatFilterPlugin extends Plugin
@@ -52,12 +52,14 @@ import net.runelite.client.input.KeyListener;
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.PluginType;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@PluginDescriptor( @PluginDescriptor(
name = "Chat History", name = "Chat History",
description = "Retain your chat history when logging in/out or world hopping", description = "Retain your chat history when logging in/out or world hopping",
tags = {"chat", "history", "retain", "cycle", "pm"} tags = {"chat", "history", "retain", "cycle", "pm"},
type = PluginType.MISCELLANEOUS
) )
@Singleton @Singleton
public class ChatHistoryPlugin extends Plugin implements KeyListener public class ChatHistoryPlugin extends Plugin implements KeyListener
@@ -51,12 +51,14 @@ import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged; import net.runelite.client.events.ConfigChanged;
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.PluginType;
@PluginDescriptor( @PluginDescriptor(
name = "Chat Notifications", name = "Chat Notifications",
description = "Highlight and notify you of chat messages", description = "Highlight and notify you of chat messages",
tags = {"duel", "messages", "notifications", "trade", "username"}, tags = {"duel", "messages", "notifications", "trade", "username"},
enabledByDefault = false enabledByDefault = false,
type = PluginType.MISCELLANEOUS
) )
@Singleton @Singleton
public class ChatNotificationsPlugin extends Plugin public class ChatNotificationsPlugin extends Plugin
@@ -39,7 +39,7 @@ import net.runelite.client.plugins.PluginType;
name = "Chat Translator", name = "Chat Translator",
description = "Translates messages from one Language to another.", description = "Translates messages from one Language to another.",
tags = {"translate", "language", "english", "spanish", "dutch", "french", "welsh", "german"}, tags = {"translate", "language", "english", "spanish", "dutch", "french", "welsh", "german"},
type = PluginType.UTILITY type = PluginType.MISCELLANEOUS
) )
@Singleton @Singleton
@Slf4j @Slf4j
@@ -78,6 +78,7 @@ import net.runelite.client.game.SpriteManager;
import net.runelite.client.game.chatbox.ChatboxPanelManager; import net.runelite.client.game.chatbox.ChatboxPanelManager;
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.PluginType;
import static net.runelite.client.ui.JagexColors.CHAT_CLAN_NAME_OPAQUE_BACKGROUND; import static net.runelite.client.ui.JagexColors.CHAT_CLAN_NAME_OPAQUE_BACKGROUND;
import static net.runelite.client.ui.JagexColors.CHAT_CLAN_NAME_TRANSPARENT_BACKGROUND; import static net.runelite.client.ui.JagexColors.CHAT_CLAN_NAME_TRANSPARENT_BACKGROUND;
import static net.runelite.client.ui.JagexColors.CHAT_CLAN_TEXT_OPAQUE_BACKGROUND; import static net.runelite.client.ui.JagexColors.CHAT_CLAN_TEXT_OPAQUE_BACKGROUND;
@@ -87,7 +88,8 @@ import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
@PluginDescriptor( @PluginDescriptor(
name = "Clan Chat", name = "Clan Chat",
description = "Add rank icons to users talking in clan chat", description = "Add rank icons to users talking in clan chat",
tags = {"icons", "rank", "recent"} tags = {"icons", "rank", "recent"},
type = PluginType.UTILITY
) )
@Singleton @Singleton
public class ClanChatPlugin extends Plugin public class ClanChatPlugin extends Plugin
@@ -78,6 +78,7 @@ import net.runelite.client.events.ConfigChanged;
import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemManager;
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.PluginType;
import net.runelite.client.plugins.cluescrolls.clues.AnagramClue; import net.runelite.client.plugins.cluescrolls.clues.AnagramClue;
import net.runelite.client.plugins.cluescrolls.clues.BeginnerMapClue; import net.runelite.client.plugins.cluescrolls.clues.BeginnerMapClue;
import net.runelite.client.plugins.cluescrolls.clues.CipherClue; import net.runelite.client.plugins.cluescrolls.clues.CipherClue;
@@ -107,7 +108,8 @@ import net.runelite.client.util.ItemUtil;
@PluginDescriptor( @PluginDescriptor(
name = "Clue Scroll", name = "Clue Scroll",
description = "Show answers to clue scroll riddles, anagrams, ciphers, and cryptic clues", description = "Show answers to clue scroll riddles, anagrams, ciphers, and cryptic clues",
tags = {"arrow", "hints", "world", "map", "coordinates", "emotes"} tags = {"arrow", "hints", "world", "map", "coordinates", "emotes"},
type = PluginType.UTILITY
) )
@Slf4j @Slf4j
@Singleton @Singleton
@@ -89,7 +89,7 @@ public class CoordinateClue extends ClueScroll implements TextClueScroll, Locati
.put(new WorldPoint(2209, 3161, 0), "North-east of Tyras Camp (BJS).") .put(new WorldPoint(2209, 3161, 0), "North-east of Tyras Camp (BJS).")
.put(new WorldPoint(2181, 3206, 0), "South of Elf Camp.") .put(new WorldPoint(2181, 3206, 0), "South of Elf Camp.")
.put(new WorldPoint(3081, 3209, 0), "Small Island (CLP).") .put(new WorldPoint(3081, 3209, 0), "Small Island (CLP).")
.put(new WorldPoint(3374, 3250, 0), "Duel Arena combat area.") .put(new WorldPoint(3399, 3246, 0), "Behind the Duel Arena.")
.put(new WorldPoint(2699, 3251, 0), "Little island (AIR).") .put(new WorldPoint(2699, 3251, 0), "Little island (AIR).")
.put(new WorldPoint(3546, 3251, 0), "North-east of Burgh de Rott.") .put(new WorldPoint(3546, 3251, 0), "North-east of Burgh de Rott.")
.put(new WorldPoint(3544, 3256, 0), "North-east of Burgh de Rott.") .put(new WorldPoint(3544, 3256, 0), "North-east of Burgh de Rott.")
@@ -173,7 +173,7 @@ public class EmoteClue extends ClueScroll implements TextClueScroll, LocationClu
new EmoteClue("Yawn in Draynor Marketplace. Equip studded leather chaps, an iron kiteshield and a steel longsword.", "Draynor", DRAYNOR_VILLAGE_MARKET, new WorldPoint(3083, 3253, 0), YAWN, item(STUDDED_CHAPS), item(IRON_KITESHIELD), item(STEEL_LONGSWORD)), new EmoteClue("Yawn in Draynor Marketplace. Equip studded leather chaps, an iron kiteshield and a steel longsword.", "Draynor", DRAYNOR_VILLAGE_MARKET, new WorldPoint(3083, 3253, 0), YAWN, item(STUDDED_CHAPS), item(IRON_KITESHIELD), item(STEEL_LONGSWORD)),
new EmoteClue("Yawn in the Castle Wars lobby. Shrug before you talk to me. Equip a ruby amulet, a mithril scimitar and a Wilderness cape.", "Castle Wars", CASTLE_WARS_BANK, new WorldPoint(2440, 3092, 0), YAWN, SHRUG, item(RUBY_AMULET), item(MITHRIL_SCIMITAR), range("Any team cape", TEAM1_CAPE, TEAM50_CAPE)), new EmoteClue("Yawn in the Castle Wars lobby. Shrug before you talk to me. Equip a ruby amulet, a mithril scimitar and a Wilderness cape.", "Castle Wars", CASTLE_WARS_BANK, new WorldPoint(2440, 3092, 0), YAWN, SHRUG, item(RUBY_AMULET), item(MITHRIL_SCIMITAR), range("Any team cape", TEAM1_CAPE, TEAM50_CAPE)),
new EmoteClue("Yawn in the rogues' general store. Beware of double agents! Equip an adamant square shield, blue dragon vambraces and a rune pickaxe.", "Rogues general store", NOTERAZZOS_SHOP_IN_THE_WILDERNESS, new WorldPoint(3026, 3701, 0), YAWN, item(ADAMANT_SQ_SHIELD), item(BLUE_DHIDE_VAMB), item(RUNE_PICKAXE)), new EmoteClue("Yawn in the rogues' general store. Beware of double agents! Equip an adamant square shield, blue dragon vambraces and a rune pickaxe.", "Rogues general store", NOTERAZZOS_SHOP_IN_THE_WILDERNESS, new WorldPoint(3026, 3701, 0), YAWN, item(ADAMANT_SQ_SHIELD), item(BLUE_DHIDE_VAMB), item(RUNE_PICKAXE)),
new EmoteClue("Yawn at the top of Trollheim. Equip a lava battlestaff, black dragonhide vambraces and a mind shield.", "Trollheim Mountain", ON_TOP_OF_TROLLHEIM_MOUNTAIN, new WorldPoint(2887, 3676, 0), YAWN, item(LAVA_BATTLESTAFF), item(BLACK_DHIDE_VAMB), item(MIND_SHIELD)), new EmoteClue("Yawn at the top of Trollheim. Equip a lava battlestaff, black dragonhide vambraces and a mind shield.", "Trollheim Mountain", ON_TOP_OF_TROLLHEIM_MOUNTAIN, new WorldPoint(2887, 3676, 0), YAWN, any("Lava battlestaff", item(LAVA_BATTLESTAFF), item(LAVA_BATTLESTAFF_21198)), item(BLACK_DHIDE_VAMB), item(MIND_SHIELD)),
new EmoteClue("Yawn in the centre of Arceuus library. Nod your head before you talk to me. Equip blue dragonhide vambraces, adamant boots and an adamant dagger.", "Arceuus library", ENTRANCE_OF_THE_ARCEUUS_LIBRARY, new WorldPoint(1632, 3807, 0), YAWN, YES, item(BLUE_DHIDE_VAMB), item(ADAMANT_BOOTS), item(ADAMANT_DAGGER)), new EmoteClue("Yawn in the centre of Arceuus library. Nod your head before you talk to me. Equip blue dragonhide vambraces, adamant boots and an adamant dagger.", "Arceuus library", ENTRANCE_OF_THE_ARCEUUS_LIBRARY, new WorldPoint(1632, 3807, 0), YAWN, YES, item(BLUE_DHIDE_VAMB), item(ADAMANT_BOOTS), item(ADAMANT_DAGGER)),
new EmoteClue("Swing a bullroarer at the top of the watchtower. Beware of double agents! Equip a dragon plateskirt, climbing boots and a dragon chainbody.", "Yanille watchtower", TOP_FLOOR_OF_THE_YANILLE_WATCHTOWER, new WorldPoint(2932, 4712, 0), BULL_ROARER, item(DRAGON_PLATESKIRT), item(CLIMBING_BOOTS), item(DRAGON_CHAINBODY_3140), item(ItemID.BULL_ROARER)), new EmoteClue("Swing a bullroarer at the top of the watchtower. Beware of double agents! Equip a dragon plateskirt, climbing boots and a dragon chainbody.", "Yanille watchtower", TOP_FLOOR_OF_THE_YANILLE_WATCHTOWER, new WorldPoint(2932, 4712, 0), BULL_ROARER, item(DRAGON_PLATESKIRT), item(CLIMBING_BOOTS), item(DRAGON_CHAINBODY_3140), item(ItemID.BULL_ROARER)),
new EmoteClue("Blow a raspberry at Gypsy Aris in her tent. Equip a gold ring and a gold necklace.", "Varrock", GYPSY_TENT_ENTRANCE, new WorldPoint(3203, 3424, 0), RASPBERRY, item(GOLD_RING), item(GOLD_NECKLACE)), new EmoteClue("Blow a raspberry at Gypsy Aris in her tent. Equip a gold ring and a gold necklace.", "Varrock", GYPSY_TENT_ENTRANCE, new WorldPoint(3203, 3424, 0), RASPBERRY, item(GOLD_RING), item(GOLD_NECKLACE)),
@@ -48,12 +48,14 @@ import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged; import net.runelite.client.events.ConfigChanged;
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.PluginType;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
@PluginDescriptor( @PluginDescriptor(
name = "Combat Level", name = "Combat Level",
description = "Show a more accurate combat level in Combat Options panel and other combat level functions", description = "Show a more accurate combat level in Combat Options panel and other combat level functions",
tags = {"wilderness", "attack", "range"} tags = {"wilderness", "attack", "range"},
type = PluginType.UTILITY
) )
@Singleton @Singleton
public class CombatLevelPlugin extends Plugin public class CombatLevelPlugin extends Plugin
File diff suppressed because it is too large Load Diff
@@ -25,28 +25,21 @@
package net.runelite.client.plugins.config; package net.runelite.client.plugins.config;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.lang.reflect.Method;
import java.util.concurrent.ScheduledExecutorService;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Provider;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import net.runelite.api.MenuOpcode; import net.runelite.api.MenuOpcode;
import net.runelite.client.RuneLite;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.ChatColorConfig; import net.runelite.client.config.ChatColorConfig;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.config.OpenOSRSConfig; import net.runelite.client.config.OpenOSRSConfig;
import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.config.RuneLiteConfig;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.events.OverlayMenuClicked;
import net.runelite.client.events.PluginChanged;
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.PluginManager; import net.runelite.client.plugins.PluginType;
import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.ClientToolbar;
import net.runelite.client.ui.ClientUI;
import net.runelite.client.ui.NavigationButton; import net.runelite.client.ui.NavigationButton;
import net.runelite.client.ui.components.colorpicker.ColorPickerManager;
import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayMenuEntry; import net.runelite.client.ui.overlay.OverlayMenuEntry;
import net.runelite.client.util.ImageUtil; import net.runelite.client.util.ImageUtil;
@@ -56,42 +49,48 @@ import net.runelite.client.util.ImageUtil;
loadWhenOutdated = true, loadWhenOutdated = true,
hidden = true // prevent users from disabling hidden = true // prevent users from disabling
) )
@Singleton
public class ConfigPlugin extends Plugin public class ConfigPlugin extends Plugin
{ {
@Inject @Inject
private ClientToolbar clientToolbar; private ClientToolbar clientToolbar;
@Inject
private Provider<PluginListPanel> pluginListPanelProvider;
@Inject @Inject
private ConfigManager configManager; private ConfigManager configManager;
@Inject
private PluginManager pluginManager;
@Inject
private ScheduledExecutorService executorService;
@Inject @Inject
private RuneLiteConfig runeLiteConfig; private RuneLiteConfig runeLiteConfig;
@Inject @Inject
private OpenOSRSConfig OpenOSRSConfig; private OpenOSRSConfig openOSRSConfig;
@Inject @Inject
private ChatColorConfig chatColorConfig; private ChatColorConfig chatColorConfig;
@Inject private PluginListPanel pluginListPanel;
private ColorPickerManager colorPickerManager;
private ConfigPanel configPanel;
private NavigationButton navButton; private NavigationButton navButton;
@Override @Override
protected void startUp() protected void startUp() throws Exception
{ {
pluginListPanel = pluginListPanelProvider.get();
configPanel = new ConfigPanel(pluginManager, configManager, executorService, runeLiteConfig, OpenOSRSConfig, chatColorConfig, colorPickerManager); pluginListPanel.addFakePlugin(
new PluginConfigurationDescriptor(
"OpenOSRS", "OpenOSRS client settings", PluginType.IMPORTANT, new String[]{"client"},
null, openOSRSConfig, configManager.getConfigDescriptor(openOSRSConfig)
),
new PluginConfigurationDescriptor(
"RuneLite", "RuneLite client settings", PluginType.IMPORTANT, new String[]{"client"},
null, runeLiteConfig, configManager.getConfigDescriptor(runeLiteConfig)
),
new PluginConfigurationDescriptor(
"Chat Color", "Recolor chat text", PluginType.MISCELLANEOUS, new String[]{"colour", "messages"},
null, chatColorConfig, configManager.getConfigDescriptor(chatColorConfig)
));
pluginListPanel.rebuildPluginList();
final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "config_icon.png"); final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "config_icon.png");
@@ -99,42 +98,20 @@ public class ConfigPlugin extends Plugin
.tooltip("Configuration") .tooltip("Configuration")
.icon(icon) .icon(icon)
.priority(0) .priority(0)
.panel(configPanel) .panel(pluginListPanel.getMuxer())
.build(); .build();
clientToolbar.addNavigation(navButton); clientToolbar.addNavigation(navButton);
} }
@Override @Override
public void shutDown() protected void shutDown() throws Exception
{ {
clientToolbar.removeNavigation(navButton); clientToolbar.removeNavigation(navButton);
RuneLite.getInjector().getInstance(ClientThread.class).invokeLater(() ->
{
try
{
ConfigPanel.pluginList.clear();
pluginManager.setPluginEnabled(this, true);
pluginManager.startPlugin(this);
Method expand = ClientUI.class.getDeclaredMethod("expand", NavigationButton.class);
expand.setAccessible(true);
expand.invoke(RuneLite.getInjector().getInstance(ClientUI.class), navButton);
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
});
} }
@Subscribe @Subscribe
private void onPluginChanged(PluginChanged event) public void onOverlayMenuClicked(OverlayMenuClicked overlayMenuClicked)
{
SwingUtilities.invokeLater(configPanel::refreshPluginList);
}
@Subscribe
private void onOverlayMenuClicked(OverlayMenuClicked overlayMenuClicked)
{ {
OverlayMenuEntry overlayMenuEntry = overlayMenuClicked.getEntry(); OverlayMenuEntry overlayMenuEntry = overlayMenuClicked.getEntry();
if (overlayMenuEntry.getMenuOpcode() == MenuOpcode.RUNELITE_OVERLAY_CONFIG) if (overlayMenuEntry.getMenuOpcode() == MenuOpcode.RUNELITE_OVERLAY_CONFIG)
@@ -154,7 +131,7 @@ public class ConfigPlugin extends Plugin
{ {
navButton.getOnSelect().run(); navButton.getOnSelect().run();
} }
configPanel.openConfigurationPanel(descriptor.name()); pluginListPanel.openConfigurationPanel(descriptor.name());
}); });
} }
} }
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2017, 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.config;
import java.awt.Dimension;
import javax.swing.JPanel;
import net.runelite.client.ui.PluginPanel;
class FixedWidthPanel extends JPanel
{
@Override
public Dimension getPreferredSize()
{
return new Dimension(PluginPanel.PANEL_WIDTH, super.getPreferredSize().height);
}
}
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2019 Abex
* 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.config;
import javax.annotation.Nullable;
import lombok.Value;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigDescriptor;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginType;
@Value
public class PluginConfigurationDescriptor
{
private final String name;
private final String description;
private final PluginType pluginType;
private final String[] tags;
// Can be null if its not an actual plugin (RuneLite / ChatColors)
@Nullable
private final Plugin plugin;
// Can be null if it has no more configuration than the on/off toggle
@Nullable
private final Config config;
@Nullable
private final ConfigDescriptor configDescriptor;
boolean hasConfigurables()
{
return configDescriptor != null && !configDescriptor.getItems().stream().allMatch(item -> item.getItem().hidden());
}
}
@@ -28,232 +28,159 @@ import java.awt.BorderLayout;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.GridLayout; import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import javax.annotation.Nullable;
import javax.inject.Singleton;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
import lombok.AccessLevel; import javax.swing.JToggleButton;
import lombok.Getter; import lombok.Getter;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigDescriptor;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.PluginType; import net.runelite.client.plugins.PluginType;
import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.PluginPanel; import net.runelite.client.ui.PluginPanel;
import net.runelite.client.ui.components.IconButton;
import net.runelite.client.util.ImageUtil; import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.SwingUtil;
import org.apache.commons.text.similarity.JaroWinklerDistance; import org.apache.commons.text.similarity.JaroWinklerDistance;
@Singleton
public class PluginListItem extends JPanel public class PluginListItem extends JPanel
{ {
private static final JaroWinklerDistance DISTANCE = new JaroWinklerDistance(); private static final JaroWinklerDistance DISTANCE = new JaroWinklerDistance();
public JLabel nameLabel;
private static final ImageIcon CONFIG_ICON; private static final ImageIcon CONFIG_ICON;
private static final ImageIcon CONFIG_ICON_HOVER; private static final ImageIcon CONFIG_ICON_HOVER;
private static final ImageIcon ON_SWITCHER;
public static final ImageIcon OFF_SWITCHER;
private static final ImageIcon ON_STAR; private static final ImageIcon ON_STAR;
private static final ImageIcon OFF_STAR; private static final ImageIcon OFF_STAR;
private final ConfigPanel configPanel; private final PluginListPanel pluginListPanel;
@Getter(AccessLevel.PACKAGE) @Getter
@Nullable private final PluginConfigurationDescriptor pluginConfig;
private final Plugin plugin;
@Nullable
@Getter(AccessLevel.PACKAGE)
private final Config config;
@Nullable
@Getter(AccessLevel.PACKAGE)
public final ConfigDescriptor configDescriptor;
@Getter(AccessLevel.PUBLIC)
private final String name;
@Getter(AccessLevel.PUBLIC)
private final String description;
@Getter(AccessLevel.PUBLIC)
private final PluginType pluginType;
private final List<String> keywords = new ArrayList<>(); private final List<String> keywords = new ArrayList<>();
private final IconButton pinButton = new IconButton(OFF_STAR); public JLabel nameLabel;
private final IconButton configButton = new IconButton(CONFIG_ICON, CONFIG_ICON_HOVER); private final JToggleButton pinButton;
private final IconButton toggleButton = new IconButton(OFF_SWITCHER); private final JToggleButton onOffToggle;
@Getter(AccessLevel.PACKAGE)
private boolean isPluginEnabled = false;
@Getter(AccessLevel.PACKAGE)
private boolean isPinned = false;
@Getter(AccessLevel.PACKAGE)
private boolean isHidden = false;
private Color color = null; private Color color = null;
static static
{ {
BufferedImage configIcon = ImageUtil.getResourceStreamFromClass(ConfigPanel.class, "config_edit_icon.png"); BufferedImage configIcon = ImageUtil.getResourceStreamFromClass(ConfigPanel.class, "config_edit_icon.png");
BufferedImage onSwitcher = ImageUtil.getResourceStreamFromClass(ConfigPanel.class, "switcher_on.png");
BufferedImage onStar = ImageUtil.getResourceStreamFromClass(ConfigPanel.class, "star_on.png"); BufferedImage onStar = ImageUtil.getResourceStreamFromClass(ConfigPanel.class, "star_on.png");
CONFIG_ICON = new ImageIcon(configIcon); CONFIG_ICON = new ImageIcon(configIcon);
ON_SWITCHER = new ImageIcon(ImageUtil.recolorImage(onSwitcher, ColorScheme.BRAND_BLUE));
ON_STAR = new ImageIcon(ImageUtil.recolorImage(onStar, ColorScheme.BRAND_BLUE)); ON_STAR = new ImageIcon(ImageUtil.recolorImage(onStar, ColorScheme.BRAND_BLUE));
CONFIG_ICON_HOVER = new ImageIcon(ImageUtil.grayscaleOffset(configIcon, -100)); CONFIG_ICON_HOVER = new ImageIcon(ImageUtil.luminanceOffset(configIcon, -100));
BufferedImage offSwitcherImage = ImageUtil.flipImage(
ImageUtil.grayscaleOffset( BufferedImage offStar = ImageUtil.luminanceScale(
ImageUtil.grayscaleImage(onSwitcher),
0.61f
),
true,
false
);
OFF_SWITCHER = new ImageIcon(offSwitcherImage);
BufferedImage offStar = ImageUtil.grayscaleOffset(
ImageUtil.grayscaleImage(onStar), ImageUtil.grayscaleImage(onStar),
0.77f 0.77f
); );
OFF_STAR = new ImageIcon(offStar); OFF_STAR = new ImageIcon(offStar);
} }
/** PluginListItem(PluginListPanel pluginListPanel, PluginConfigurationDescriptor pluginConfig)
* Creates a new {@code PluginListItem} for a plugin.
* <p>
* Note that {@code config} and {@code configDescriptor} can be {@code null}
* if there is no configuration associated with the plugin.
*/
PluginListItem(ConfigPanel configPanel, ConfigManager configManager, Plugin plugin, PluginDescriptor descriptor,
@Nullable Config config, @Nullable ConfigDescriptor configDescriptor)
{ {
this(configPanel, configManager, plugin, config, configDescriptor, this.pluginListPanel = pluginListPanel;
descriptor.name(), descriptor.description(), descriptor.type(), descriptor.tags()); this.pluginConfig = pluginConfig;
}
/** Collections.addAll(keywords, pluginConfig.getName().toLowerCase().split(" "));
* Creates a new {@code PluginListItem} for a core configuration. Collections.addAll(keywords, pluginConfig.getDescription().toLowerCase().split(" "));
*/ Collections.addAll(keywords, pluginConfig.getTags());
PluginListItem(ConfigPanel configPanel, ConfigManager configManager, Config config, ConfigDescriptor configDescriptor,
String name, String description, PluginType pluginType, String... tags)
{
this(configPanel, configManager, null, config, configDescriptor, name, description, pluginType, tags);
}
private PluginListItem(ConfigPanel configPanel, ConfigManager configManager, @Nullable Plugin plugin, @Nullable Config config,
@Nullable ConfigDescriptor configDescriptor, String name, String description, PluginType pluginType, String... tags)
{
this.configPanel = configPanel;
this.plugin = plugin;
this.config = config;
this.configDescriptor = configDescriptor;
this.name = name;
this.description = description;
this.pluginType = pluginType;
Collections.addAll(keywords, name.toLowerCase().split(" "));
Collections.addAll(keywords, description.toLowerCase().split(" "));
Collections.addAll(keywords, tags);
setLayout(new BorderLayout(3, 0)); setLayout(new BorderLayout(3, 0));
setPreferredSize(new Dimension(PluginPanel.PANEL_WIDTH, 20)); setPreferredSize(new Dimension(PluginPanel.PANEL_WIDTH, 20));
nameLabel = new JLabel(name); nameLabel = new JLabel(pluginConfig.getName());
nameLabel.setForeground(Color.WHITE);
if (!description.isEmpty()) if (!pluginConfig.getDescription().isEmpty())
{ {
nameLabel.setToolTipText("<html>" + name + ":<br>" + description + "</html>"); nameLabel.setToolTipText("<html>" + pluginConfig.getName() + ":<br>" + pluginConfig.getDescription() + "</html>");
} }
add(nameLabel, BorderLayout.CENTER); pinButton = new JToggleButton(OFF_STAR);
pinButton.setSelectedIcon(ON_STAR);
SwingUtil.removeButtonDecorations(pinButton);
SwingUtil.addModalTooltip(pinButton, "Unpin plugin", "Pin plugin");
pinButton.setPreferredSize(new Dimension(21, 0)); pinButton.setPreferredSize(new Dimension(21, 0));
add(pinButton, BorderLayout.LINE_START); add(pinButton, BorderLayout.LINE_START);
pinButton.addActionListener(e -> pinButton.addActionListener(e ->
{ {
setPinned(!isPinned); pluginListPanel.savePinnedPlugins();
configPanel.savePinnedPlugins(); pluginListPanel.refresh();
configPanel.openConfigList();
}); });
final JPanel buttonPanel = new JPanel(); final JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(1, 2)); buttonPanel.setLayout(new GridLayout(1, 2));
add(buttonPanel, BorderLayout.LINE_END); add(buttonPanel, BorderLayout.LINE_END);
configButton.setPreferredSize(new Dimension(25, 0)); if (pluginConfig.hasConfigurables())
configButton.setVisible(false);
buttonPanel.add(configButton);
// add a listener to configButton only if there are config items to show
if (configDescriptor != null && config != null && !configDescriptor.getItems().stream().allMatch(item -> item.getItem().hidden()))
{ {
JButton configButton = new JButton(CONFIG_ICON);
configButton.setRolloverIcon(CONFIG_ICON_HOVER);
SwingUtil.removeButtonDecorations(configButton);
configButton.setPreferredSize(new Dimension(25, 0));
configButton.setVisible(false);
buttonPanel.add(configButton);
configButton.addActionListener(e -> configButton.addActionListener(e ->
{ {
configButton.setIcon(CONFIG_ICON); configButton.setIcon(CONFIG_ICON);
configPanel.openGroupConfigPanel(PluginListItem.this, config, configDescriptor); openGroupConfigPanel();
}); });
configButton.setVisible(true); configButton.setVisible(true);
configButton.setToolTipText("Edit plugin configuration"); configButton.setToolTipText("Edit plugin configuration");
} }
toggleButton.setPreferredSize(new Dimension(25, 0)); addLabelMouseOver(nameLabel);
attachToggleButtonListener(toggleButton); add(nameLabel, BorderLayout.CENTER);
buttonPanel.add(toggleButton); onOffToggle = new PluginToggleButton();
} buttonPanel.add(onOffToggle);
if (pluginConfig.getPlugin() != null)
void attachToggleButtonListener(IconButton button)
{
// no need for a listener if there is no plugin to enable / disable
if (plugin == null)
{ {
button.setVisible(false); onOffToggle.addItemListener(i ->
return; {
if (onOffToggle.isSelected())
{
pluginListPanel.startPlugin(pluginConfig.getPlugin());
}
else
{
pluginListPanel.stopPlugin(pluginConfig.getPlugin());
}
});
} }
else
button.addActionListener(e ->
{ {
if (isPluginEnabled) onOffToggle.setVisible(false);
{ }
configPanel.stopPlugin(plugin, PluginListItem.this);
}
else
{
configPanel.startPlugin(plugin, PluginListItem.this);
}
setPluginEnabled(!isPluginEnabled);
updateToggleButton(button);
});
} }
void setPluginEnabled(boolean enabled) boolean isPinned()
{ {
isPluginEnabled = enabled; return pinButton.isSelected();
updateToggleButton(toggleButton);
} }
void setPinned(boolean pinned) void setPinned(boolean pinned)
{ {
isPinned = pinned; pinButton.setSelected(pinned);
pinButton.setIcon(pinned ? ON_STAR : OFF_STAR);
pinButton.setToolTipText(pinned ? "Unpin plugin" : "Pin plugin");
} }
Color getColor() public PluginType getPluginType()
{
return pluginConfig.getPluginType();
}
public Color getColor()
{ {
return this.color == null ? Color.WHITE : this.color; return this.color == null ? Color.WHITE : this.color;
} }
@@ -269,15 +196,9 @@ public class PluginListItem extends JPanel
this.nameLabel.setForeground(color); this.nameLabel.setForeground(color);
} }
public void setHidden(boolean hidden) void setPluginEnabled(boolean enabled)
{ {
isHidden = hidden; onOffToggle.setSelected(enabled);
}
void updateToggleButton(IconButton button)
{
button.setIcon(isPluginEnabled ? ON_SWITCHER : OFF_SWITCHER);
button.setToolTipText(isPluginEnabled ? "Disable plugin" : "Enable plugin");
} }
/** /**
@@ -297,4 +218,37 @@ public class PluginListItem extends JPanel
} }
return true; return true;
} }
private void openGroupConfigPanel()
{
pluginListPanel.openConfigurationPanel(pluginConfig);
}
/**
* Adds a mouseover effect to change the text of the passed label to {@link ColorScheme#BRAND_BLUE} color
*
* @param label The label to attach the mouseover and click effects to
*/
static void addLabelMouseOver(final JLabel label)
{
final Color labelForeground = label.getForeground();
label.addMouseListener(new MouseAdapter()
{
private Color lastForeground;
@Override
public void mouseEntered(MouseEvent mouseEvent)
{
lastForeground = label.getForeground();
label.setForeground(ColorScheme.BRAND_BLUE);
}
@Override
public void mouseExited(MouseEvent mouseEvent)
{
label.setForeground(lastForeground);
}
});
}
} }
@@ -0,0 +1,653 @@
/*
* Copyright (c) 2017, 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.config;
import com.google.common.collect.ImmutableList;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ScheduledExecutorService;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToggleButton;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.util.Text;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigDescriptor;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.config.OpenOSRSConfig;
import net.runelite.client.config.RuneLiteConfig;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged;
import net.runelite.client.events.PluginChanged;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.PluginInstantiationException;
import net.runelite.client.plugins.PluginManager;
import net.runelite.client.plugins.PluginType;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.DynamicGridLayout;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.MultiplexingPluginPanel;
import net.runelite.client.ui.PluginPanel;
import net.runelite.client.ui.components.IconTextField;
import net.runelite.client.ui.components.MinimumSizedPanel;
import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.SwingUtil;
@Slf4j
@Singleton
public class PluginListPanel extends PluginPanel
{
private static final int OFFSET = 6;
private static final ImageIcon SECTION_EXPAND_ICON;
private static final ImageIcon SECTION_EXPAND_ICON_HOVER;
private static final ImageIcon SECTION_RETRACT_ICON;
private static final ImageIcon SECTION_RETRACT_ICON_HOVER;
private static final String RUNELITE_GROUP_NAME = RuneLiteConfig.class.getAnnotation(ConfigGroup.class).value();
private static final String PINNED_PLUGINS_CONFIG_KEY = "pinnedPlugins";
private static final List<String> colorOptions = Arrays.asList("enabledColors", "pvmColor", "pvpColor", "skillingColor", "utilityColor", "minigameColor", "miscellaneousColor", "gamemodeColor");
private static final ImmutableList<PluginType> definedOrder = ImmutableList.of(PluginType.IMPORTANT, PluginType.PVM, PluginType.SKILLING, PluginType.PVP, PluginType.UTILITY, PluginType.MINIGAME, PluginType.MISCELLANEOUS, PluginType.GAMEMODE, PluginType.EXTERNAL, PluginType.UNCATEGORIZED);
private static final Comparator<PluginListItem> categoryComparator = Comparator.comparing(plugin -> definedOrder.indexOf(plugin.getPluginType()));
private final ConfigManager configManager;
private final PluginManager pluginManager;
private final ScheduledExecutorService executorService;
private final Provider<ConfigPanel> configPanelProvider;
private final OpenOSRSConfig openOSRSConfig;
private final List<PluginConfigurationDescriptor> fakePlugins = new ArrayList<>();
@Getter
private final MultiplexingPluginPanel muxer;
private final IconTextField searchBar;
private final JScrollPane scrollPane;
private final FixedWidthPanel mainPanel;
private final Set<JPanel> sectionsCopy = new HashSet<>();
public static List<PluginListItem> pluginList;
static
{
final BufferedImage backIcon = ImageUtil.getResourceStreamFromClass(ConfigPanel.class, "config_back_icon.png");
final BufferedImage orangeBackIcon = ImageUtil.fillImage(backIcon, ColorScheme.BRAND_BLUE);
final BufferedImage sectionRetractIcon = ImageUtil.rotateImage(orangeBackIcon, Math.PI * 1.5);
SECTION_RETRACT_ICON = new ImageIcon(sectionRetractIcon);
SECTION_RETRACT_ICON_HOVER = new ImageIcon(ImageUtil.alphaOffset(sectionRetractIcon, -100));
final BufferedImage sectionExpandIcon = ImageUtil.rotateImage(orangeBackIcon, Math.PI);
SECTION_EXPAND_ICON = new ImageIcon(sectionExpandIcon);
SECTION_EXPAND_ICON_HOVER = new ImageIcon(ImageUtil.alphaOffset(sectionExpandIcon, -100));
}
@Inject
public PluginListPanel(
ConfigManager configManager,
PluginManager pluginManager,
ScheduledExecutorService executorService,
Provider<ConfigPanel> configPanelProvider,
OpenOSRSConfig openOSRSConfig,
EventBus eventBus)
{
super(false);
this.configManager = configManager;
this.pluginManager = pluginManager;
this.executorService = executorService;
this.configPanelProvider = configPanelProvider;
this.openOSRSConfig = openOSRSConfig;
eventBus.subscribe(ConfigChanged.class, this, ev -> {
if (!ev.getGroup().equals("openosrs"))
{
return;
}
if (ev.getKey().equals("enableCategories") || ev.getKey().equals("pluginSortMode"))
{
rebuildPluginList();
}
if (ev.getKey().equals("pluginSortMode"))
{
sortPluginList(null);
}
if (colorOptions.stream().anyMatch(option -> option.equals(ev.getKey())))
{
pluginList.forEach(listItem ->
{
if (listItem.getPluginType() == PluginType.IMPORTANT)
{
return;
}
listItem.setColor(getColorByCategory(listItem.getPluginType()));
});
}
});
muxer = new MultiplexingPluginPanel(this);
searchBar = new IconTextField();
searchBar.setIcon(IconTextField.Icon.SEARCH);
searchBar.setPreferredSize(new Dimension(PluginPanel.PANEL_WIDTH - 20, 30));
searchBar.setBackground(ColorScheme.DARKER_GRAY_COLOR);
searchBar.setHoverBackgroundColor(ColorScheme.DARK_GRAY_HOVER_COLOR);
searchBar.getDocument().addDocumentListener(new DocumentListener()
{
@Override
public void insertUpdate(DocumentEvent e)
{
onSearchBarChanged();
}
@Override
public void removeUpdate(DocumentEvent e)
{
onSearchBarChanged();
}
@Override
public void changedUpdate(DocumentEvent e)
{
onSearchBarChanged();
}
});
setLayout(new BorderLayout());
setBackground(ColorScheme.DARK_GRAY_COLOR);
JPanel topPanel = new JPanel();
topPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
topPanel.setLayout(new BorderLayout(0, BORDER_OFFSET));
topPanel.add(searchBar, BorderLayout.CENTER);
add(topPanel, BorderLayout.NORTH);
mainPanel = new FixedWidthPanel();
mainPanel.setBorder(new EmptyBorder(8, 10, 10, 10));
mainPanel.setLayout(new DynamicGridLayout(0, 1, 0, 5));
mainPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
JPanel northPanel = new FixedWidthPanel();
northPanel.setLayout(new BorderLayout());
northPanel.add(mainPanel, BorderLayout.NORTH);
scrollPane = new JScrollPane(northPanel);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
add(scrollPane, BorderLayout.CENTER);
}
void rebuildPluginList()
{
final List<String> pinnedPlugins = getPinnedPluginNames();
// populate pluginList with all non-hidden plugins
pluginList = Stream.concat(
fakePlugins.stream(),
pluginManager.getPlugins().stream()
.filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).hidden())
.map(plugin ->
{
PluginDescriptor descriptor = plugin.getClass().getAnnotation(PluginDescriptor.class);
Config config = pluginManager.getPluginConfigProxy(plugin);
ConfigDescriptor configDescriptor = config == null ? null : configManager.getConfigDescriptor(config);
return new PluginConfigurationDescriptor(
descriptor.name(),
descriptor.description(),
descriptor.type(),
descriptor.tags(),
plugin,
config,
configDescriptor);
})
).map(desc ->
{
PluginListItem listItem = new PluginListItem(this, desc);
listItem.setPinned(pinnedPlugins.contains(desc.getName()));
listItem.setColor(getColorByCategory(listItem.getPluginType()));
return listItem;
}).collect(Collectors.toList());
sortPluginList(null);
mainPanel.removeAll();
refresh();
}
void addFakePlugin(PluginConfigurationDescriptor... descriptor)
{
Collections.addAll(fakePlugins, descriptor);
}
void refresh()
{
// update enabled / disabled status of all items
pluginList.forEach(listItem ->
{
final Plugin plugin = listItem.getPluginConfig().getPlugin();
if (plugin != null)
{
listItem.setPluginEnabled(pluginManager.isPluginEnabled(plugin));
}
});
int scrollBarPosition = scrollPane.getVerticalScrollBar().getValue();
onSearchBarChanged();
searchBar.requestFocusInWindow();
validate();
scrollPane.getVerticalScrollBar().setValue(scrollBarPosition);
}
private void onSearchBarChanged()
{
final String text = searchBar.getText();
pluginList.forEach(mainPanel::remove);
sectionsCopy.forEach(mainPanel::remove);
sectionsCopy.clear();
showMatchingPlugins(true, text);
showMatchingPlugins(false, text);
revalidate();
}
private void generatePluginList(List<PluginListItem> pluginListItems)
{
final Map<String, JPanel> sections = new HashMap<>();
for (PluginListItem pluginListItem : pluginListItems)
{
if (pluginListItem.isPinned())
{
if (!sections.containsKey("Pinned"))
{
sections.put("Pinned", addSection("Pinned"));
}
sections.get("Pinned").add(pluginListItem);
continue;
}
String sectionName = pluginListItem.getPluginConfig().getPluginType().getName();
if (!sections.containsKey(sectionName))
{
sections.put(sectionName, addSection(sectionName));
}
sections.get(sectionName).add(pluginListItem);
}
sections.forEach((key, value) ->
{
Container parent = value.getParent();
JToggleButton collapseButton = (JToggleButton) ((JPanel) parent.getComponent(0)).getComponent(0);
if (searchBar.getText().equals(""))
{
resetSection(key, collapseButton, value);
}
else
{
forceExpandSection(collapseButton, value);
}
});
}
private void showMatchingPlugins(boolean pinned, String text)
{
final List<PluginListItem> plugins = new ArrayList<>();
if (text.isEmpty())
{
if (openOSRSConfig.pluginSortMode() == net.runelite.client.config.OpenOSRSConfig.SortStyle.ALPHABETICALLY || !openOSRSConfig.enableCategories())
{
pluginList.stream().filter(item -> pinned == item.isPinned()).forEach(mainPanel::add);
}
else
{
pluginList.stream().filter(item -> pinned == item.isPinned()).forEach(plugins::add);
}
}
else
{
final String[] searchTerms = text.toLowerCase().split(" ");
pluginList.forEach(listItem ->
{
if (pinned == listItem.isPinned() && listItem.matchesSearchTerms(searchTerms))
{
if (openOSRSConfig.pluginSortMode() == net.runelite.client.config.OpenOSRSConfig.SortStyle.ALPHABETICALLY || !openOSRSConfig.enableCategories())
{
mainPanel.add(listItem);
}
else
{
plugins.add(listItem);
}
}
});
}
if (openOSRSConfig.pluginSortMode() == net.runelite.client.config.OpenOSRSConfig.SortStyle.CATEGORY && openOSRSConfig.enableCategories())
{
generatePluginList(plugins);
}
}
void openConfigurationPanel(String configGroup)
{
for (PluginListItem pluginListItem : pluginList)
{
if (pluginListItem.getPluginConfig().getName().equals(configGroup))
{
openConfigurationPanel(pluginListItem.getPluginConfig());
break;
}
}
}
void openConfigurationPanel(PluginConfigurationDescriptor plugin)
{
ConfigPanel panel = configPanelProvider.get();
panel.init(plugin);
muxer.pushState(panel);
}
void startPlugin(Plugin plugin)
{
executorService.submit(() ->
{
pluginManager.setPluginEnabled(plugin, true);
try
{
pluginManager.startPlugin(plugin);
}
catch (PluginInstantiationException ex)
{
log.warn("Error when starting plugin {}", plugin.getClass().getSimpleName(), ex);
}
});
}
void stopPlugin(Plugin plugin)
{
executorService.submit(() ->
{
pluginManager.setPluginEnabled(plugin, false);
try
{
pluginManager.stopPlugin(plugin);
}
catch (PluginInstantiationException ex)
{
log.warn("Error when stopping plugin {}", plugin.getClass().getSimpleName(), ex);
}
});
}
private List<String> getPinnedPluginNames()
{
final String config = configManager.getConfiguration(RUNELITE_GROUP_NAME, PINNED_PLUGINS_CONFIG_KEY);
if (config == null)
{
return Collections.emptyList();
}
return Text.fromCSV(config);
}
void savePinnedPlugins()
{
final String value = pluginList.stream()
.filter(PluginListItem::isPinned)
.map(p -> p.getPluginConfig().getName())
.collect(Collectors.joining(","));
configManager.setConfiguration(RUNELITE_GROUP_NAME, PINNED_PLUGINS_CONFIG_KEY, value);
}
@Subscribe
public void onPluginChanged(PluginChanged event)
{
SwingUtilities.invokeLater(this::refresh);
}
@Override
public Dimension getPreferredSize()
{
return new Dimension(PANEL_WIDTH + SCROLLBAR_WIDTH, super.getPreferredSize().height);
}
@Override
public void onActivate()
{
super.onActivate();
if (searchBar.getParent() != null)
{
searchBar.requestFocusInWindow();
}
}
private JPanel addSection(String name)
{
final MinimumSizedPanel section = new MinimumSizedPanel();
section.setLayout(new BoxLayout(section, BoxLayout.Y_AXIS));
section.setMinimumSize(new Dimension(PANEL_WIDTH, 0));
JPanel item = new JPanel();
item.setLayout(new BorderLayout());
item.setMinimumSize(new Dimension(PANEL_WIDTH, 0));
JLabel headerLabel = new JLabel(name);
headerLabel.setFont(FontManager.getRunescapeFont());
headerLabel.setForeground(ColorScheme.BRAND_BLUE);
headerLabel.setPreferredSize(new Dimension(PANEL_WIDTH, (int) headerLabel.getPreferredSize().getHeight()));
final boolean state = Boolean.parseBoolean(configManager.getConfiguration("pluginlist", name));
final JToggleButton collapse = new JToggleButton(SECTION_EXPAND_ICON, state);
SwingUtil.removeButtonDecorations(collapse);
collapse.setRolloverIcon(SECTION_EXPAND_ICON_HOVER);
collapse.setSelectedIcon(SECTION_RETRACT_ICON);
collapse.setRolloverSelectedIcon(SECTION_RETRACT_ICON_HOVER);
collapse.setToolTipText(state ? "Retract" : "Expand");
collapse.setPreferredSize(new Dimension(20, 20));
collapse.setFont(collapse.getFont().deriveFont(16.0f));
collapse.setBorder(null);
collapse.setMargin(new Insets(0, 0, 0, 0));
headerLabel.setBorder(new EmptyBorder(0, 10, 0, 0));
item.add(collapse, BorderLayout.WEST);
item.add(headerLabel, BorderLayout.CENTER);
final JPanel sectionContents = new JPanel();
sectionContents.setLayout(new DynamicGridLayout(0, 1, 0, 5));
sectionContents.setMinimumSize(new Dimension(PANEL_WIDTH, 0));
sectionContents.setBorder(new EmptyBorder(OFFSET, 5, 0, 0));
section.add(item, BorderLayout.NORTH);
section.add(sectionContents, BorderLayout.SOUTH);
sectionContents.setVisible(state);
// Add listeners to each part of the header so that it's easier to toggle them
final MouseAdapter adapter = new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
toggleSection(name, collapse, sectionContents);
}
};
collapse.addActionListener(e -> toggleSection(name, collapse, sectionContents));
headerLabel.addMouseListener(adapter);
// Allow for sub-sections
mainPanel.add(section);
sectionsCopy.add(section);
return sectionContents;
}
private void toggleSection(String key, JToggleButton button, JPanel contents)
{
if (!button.isEnabled())
{
return;
}
boolean newState = !contents.isVisible();
button.setSelected(newState);
button.setToolTipText(newState ? "Retract" : "Expand");
contents.setVisible(newState);
configManager.setConfiguration("pluginlist", key, newState);
SwingUtilities.invokeLater(() ->
{
contents.revalidate();
contents.repaint();
});
}
private void forceExpandSection(JToggleButton button, JPanel contents)
{
button.setSelected(true);
button.setToolTipText(null);
button.setEnabled(false);
contents.setVisible(true);
SwingUtilities.invokeLater(() ->
{
contents.revalidate();
contents.repaint();
});
}
private void resetSection(String key, JToggleButton button, JPanel contents)
{
boolean newState = Boolean.parseBoolean(configManager.getConfiguration("pluginlist", key));
button.setSelected(newState);
button.setToolTipText(newState ? "Retract" : "Expand");
contents.setVisible(newState);
SwingUtilities.invokeLater(() ->
{
contents.revalidate();
contents.repaint();
});
}
private Color getColorByCategory(PluginType pluginType)
{
if (!openOSRSConfig.enabledColors())
{
return Color.LIGHT_GRAY;
}
switch (pluginType)
{
case EXTERNAL:
return openOSRSConfig.externalColor();
case PVM:
return openOSRSConfig.pvmColor();
case PVP:
return openOSRSConfig.pvpColor();
case SKILLING:
return openOSRSConfig.skillingColor();
case UTILITY:
return openOSRSConfig.utilityColor();
case MISCELLANEOUS:
return openOSRSConfig.miscellaneousColor();
case MINIGAME:
return openOSRSConfig.minigameColor();
case GAMEMODE:
return openOSRSConfig.gamemodeColor();
case IMPORTANT:
return Color.WHITE;
}
return Color.LIGHT_GRAY;
}
public void sortPluginList(Comparator<PluginListItem> comparator)
{
if (comparator != null)
{
pluginList.sort(comparator.thenComparing(ev -> ev.getPluginConfig().getName()));
return;
}
if (openOSRSConfig.pluginSortMode() == net.runelite.client.config.OpenOSRSConfig.SortStyle.CATEGORY)
{
pluginList.sort(categoryComparator.thenComparing(ev -> ev.getPluginConfig().getName()));
}
else
{
pluginList.sort(Comparator.comparing(ev -> ev.getPluginConfig().getName()));
}
}
}
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2019 Abex
* 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.config;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JToggleButton;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.SwingUtil;
class PluginToggleButton extends JToggleButton
{
private static final ImageIcon ON_SWITCHER;
private static final ImageIcon OFF_SWITCHER;
static
{
BufferedImage onSwitcher = ImageUtil.getResourceStreamFromClass(ConfigPanel.class, "switcher_on.png");
ON_SWITCHER = new ImageIcon(ImageUtil.recolorImage(onSwitcher, ColorScheme.BRAND_BLUE));
OFF_SWITCHER = new ImageIcon(ImageUtil.flipImage(
ImageUtil.luminanceScale(
ImageUtil.grayscaleImage(onSwitcher),
0.61f
),
true,
false
));
}
public PluginToggleButton()
{
super(OFF_SWITCHER);
setSelectedIcon(ON_SWITCHER);
SwingUtil.removeButtonDecorations(this);
setPreferredSize(new Dimension(25, 0));
SwingUtil.addModalTooltip(this, "Disable plugin", "Enable plugin");
}
}
@@ -51,6 +51,7 @@ import net.runelite.client.game.ItemManager;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDependency; import net.runelite.client.plugins.PluginDependency;
import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.PluginType;
import net.runelite.client.plugins.xptracker.XpTrackerPlugin; import net.runelite.client.plugins.xptracker.XpTrackerPlugin;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.ui.overlay.OverlayMenuEntry; import net.runelite.client.ui.overlay.OverlayMenuEntry;
@@ -59,7 +60,8 @@ import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
@PluginDescriptor( @PluginDescriptor(
name = "Cooking", name = "Cooking",
description = "Show cooking statistics", description = "Show cooking statistics",
tags = {"overlay", "skilling", "cook"} tags = {"overlay", "skilling", "cook"},
type = PluginType.SKILLING
) )
@Singleton @Singleton
@PluginDependency(XpTrackerPlugin.class) @PluginDependency(XpTrackerPlugin.class)
@@ -55,12 +55,14 @@ import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged; import net.runelite.client.events.ConfigChanged;
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.PluginType;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
@PluginDescriptor( @PluginDescriptor(
name = "Corporeal Beast", name = "Corporeal Beast",
description = "Show damage statistics and highlight dark energy cores", description = "Show damage statistics and highlight dark energy cores",
tags = {"bosses", "combat", "pve", "overlay"} tags = {"bosses", "combat", "pve", "overlay"},
type = PluginType.PVM
) )
@Slf4j @Slf4j
public class CorpPlugin extends Plugin public class CorpPlugin extends Plugin
@@ -37,6 +37,7 @@ import net.runelite.api.events.GameTick;
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;
import net.runelite.client.plugins.PluginType;
import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.RuneLiteAPI;
import okhttp3.Call; import okhttp3.Call;
import okhttp3.Callback; import okhttp3.Callback;
@@ -50,7 +51,8 @@ import org.jetbrains.annotations.NotNull;
name = "Crystal Math Labs", name = "Crystal Math Labs",
description = "Automatically updates your stats on Crystal Math Labs when you log out", description = "Automatically updates your stats on Crystal Math Labs when you log out",
tags = {"cml", "external", "integration"}, tags = {"cml", "external", "integration"},
enabledByDefault = false enabledByDefault = false,
type = PluginType.MISCELLANEOUS
) )
@Slf4j @Slf4j
@Singleton @Singleton
@@ -31,7 +31,7 @@ import net.runelite.client.util.ImageUtil;
name = "Custom Client Resizing", name = "Custom Client Resizing",
description = "Resize the window to saved profiles", description = "Resize the window to saved profiles",
tags = {"resize", "window", "position", "layout", "manage"}, tags = {"resize", "window", "position", "layout", "manage"},
type = PluginType.UTILITY, type = PluginType.MISCELLANEOUS,
enabledByDefault = false enabledByDefault = false
) )
public class CustomClientResizingPlugin extends Plugin public class CustomClientResizingPlugin extends Plugin
@@ -40,13 +40,15 @@ import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged; import net.runelite.client.events.ConfigChanged;
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.PluginType;
import net.runelite.client.ui.ClientUI; import net.runelite.client.ui.ClientUI;
@Slf4j @Slf4j
@PluginDescriptor( @PluginDescriptor(
name = "Custom Cursor", name = "Custom Cursor",
description = "Replaces your mouse cursor image", description = "Replaces your mouse cursor image",
enabledByDefault = false enabledByDefault = false,
type = PluginType.MISCELLANEOUS
) )
@Singleton @Singleton
public class CustomCursorPlugin extends Plugin public class CustomCursorPlugin extends Plugin
@@ -47,10 +47,12 @@ import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged; import net.runelite.client.events.ConfigChanged;
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.PluginType;
@PluginDescriptor( @PluginDescriptor(
name = "Daily Task Indicator", name = "Daily Task Indicator",
description = "Show chat notifications for daily tasks upon login" description = "Show chat notifications for daily tasks upon login",
type = PluginType.UTILITY
) )
@Singleton @Singleton
public class DailyTasksPlugin extends Plugin public class DailyTasksPlugin extends Plugin
@@ -61,6 +61,7 @@ import net.runelite.client.events.ConfigChanged;
import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemManager;
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.PluginType;
import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
import net.runelite.client.ui.overlay.infobox.Timer; import net.runelite.client.ui.overlay.infobox.Timer;
import net.runelite.client.ui.overlay.worldmap.WorldMapPointManager; import net.runelite.client.ui.overlay.worldmap.WorldMapPointManager;
@@ -69,7 +70,8 @@ import net.runelite.client.util.ImageUtil;
@PluginDescriptor( @PluginDescriptor(
name = "Death Indicator", name = "Death Indicator",
description = "Show where you last died, and on what world", description = "Show where you last died, and on what world",
tags = {"arrow", "hints", "world", "map", "overlay"} tags = {"arrow", "hints", "world", "map", "overlay"},
type = PluginType.UTILITY
) )
@Singleton @Singleton
@Slf4j @Slf4j
@@ -37,6 +37,7 @@ import net.runelite.client.events.SessionOpen;
import net.runelite.client.game.WorldService; import net.runelite.client.game.WorldService;
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.PluginType;
import net.runelite.client.util.WorldUtil; import net.runelite.client.util.WorldUtil;
import net.runelite.http.api.worlds.World; import net.runelite.http.api.worlds.World;
import net.runelite.http.api.worlds.WorldResult; import net.runelite.http.api.worlds.WorldResult;
@@ -44,7 +45,8 @@ import net.runelite.http.api.worlds.WorldResult;
@PluginDescriptor( @PluginDescriptor(
name = "Default World", name = "Default World",
description = "Enable a default world to be selected when launching the client", description = "Enable a default world to be selected when launching the client",
tags = {"home"} tags = {"home"},
type = PluginType.UTILITY
) )
@Slf4j @Slf4j
@Singleton @Singleton
@@ -61,12 +61,14 @@ import net.runelite.client.callback.ClientThread;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
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.PluginType;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
@PluginDescriptor( @PluginDescriptor(
name = "Demonic Gorillas", name = "Demonic Gorillas",
description = "Count demonic gorilla attacks and display their next possible attack styles", description = "Count demonic gorilla attacks and display their next possible attack styles",
tags = {"combat", "overlay", "pve", "pvm"} tags = {"combat", "overlay", "pve", "pvm"},
type = PluginType.PVM
) )
@Singleton @Singleton
public class DemonicGorillaPlugin extends Plugin public class DemonicGorillaPlugin extends Plugin
@@ -54,6 +54,7 @@ import net.runelite.client.eventbus.EventBus;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
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.PluginType;
import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.ClientToolbar;
import net.runelite.client.ui.JagexColors; import net.runelite.client.ui.JagexColors;
import net.runelite.client.ui.NavigationButton; import net.runelite.client.ui.NavigationButton;
@@ -66,7 +67,8 @@ import org.slf4j.LoggerFactory;
@PluginDescriptor( @PluginDescriptor(
name = "Developer Tools", name = "Developer Tools",
tags = {"panel"}, tags = {"panel"},
developerPlugin = true developerPlugin = true,
type = PluginType.MISCELLANEOUS
) )
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
public class DevToolsPlugin extends Plugin public class DevToolsPlugin extends Plugin
@@ -60,6 +60,7 @@ import net.runelite.client.events.ConfigChanged;
import net.runelite.client.events.PartyChanged; import net.runelite.client.events.PartyChanged;
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.PluginType;
import net.runelite.client.task.Schedule; import net.runelite.client.task.Schedule;
import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.ClientToolbar;
import net.runelite.client.ui.NavigationButton; import net.runelite.client.ui.NavigationButton;
@@ -81,7 +82,8 @@ import org.jetbrains.annotations.NotNull;
@PluginDescriptor( @PluginDescriptor(
name = "Discord", name = "Discord",
description = "Show your status and activity in the Discord user panel", description = "Show your status and activity in the Discord user panel",
tags = {"action", "activity", "external", "integration", "status"} tags = {"action", "activity", "external", "integration", "status"},
type = PluginType.MISCELLANEOUS
) )
@Slf4j @Slf4j
@Singleton @Singleton
@@ -53,7 +53,7 @@ import net.runelite.client.ui.overlay.OverlayManager;
name = "Drop Party", name = "Drop Party",
description = "Marks where a user ran, for drop partys", description = "Marks where a user ran, for drop partys",
tags = {"Drop", "Party", "marker", "player"}, tags = {"Drop", "Party", "marker", "player"},
type = PluginType.UTILITY, type = PluginType.MISCELLANEOUS,
enabledByDefault = false enabledByDefault = false
) )
@Singleton @Singleton
@@ -45,12 +45,14 @@ import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
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.PluginType;
import net.runelite.client.util.ImageUtil; import net.runelite.client.util.ImageUtil;
@PluginDescriptor( @PluginDescriptor(
name = "Emojis", name = "Emojis",
description = "Replaces common emoticons such as :) with their corresponding emoji in the chat", description = "Replaces common emoticons such as :) with their corresponding emoji in the chat",
enabledByDefault = false enabledByDefault = false,
type = PluginType.MISCELLANEOUS
) )
@Slf4j @Slf4j
@Singleton @Singleton
@@ -43,12 +43,14 @@ import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged; import net.runelite.client.events.ConfigChanged;
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.PluginType;
@PluginDescriptor( @PluginDescriptor(
name = "Entity Hider", name = "Entity Hider",
description = "Hide players, NPCs, and/or projectiles", description = "Hide players, NPCs, and/or projectiles",
tags = {"npcs", "players", "projectiles"}, tags = {"npcs", "players", "projectiles"},
enabledByDefault = false enabledByDefault = false,
type = PluginType.UTILITY
) )
@Singleton @Singleton
public class EntityHiderPlugin extends Plugin public class EntityHiderPlugin extends Plugin
@@ -37,6 +37,7 @@ import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.ChatMessageType; import net.runelite.api.ChatMessageType;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.Constants;
import net.runelite.api.ItemDefinition; import net.runelite.api.ItemDefinition;
import net.runelite.api.ItemID; import net.runelite.api.ItemID;
import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ChatMessage;
@@ -58,6 +59,7 @@ import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemManager;
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.PluginType;
import net.runelite.client.util.QuantityFormatter; import net.runelite.client.util.QuantityFormatter;
import net.runelite.http.api.examine.ExamineClient; import net.runelite.http.api.examine.ExamineClient;
import net.runelite.http.api.osbuddy.OSBGrandExchangeClient; import net.runelite.http.api.osbuddy.OSBGrandExchangeClient;
@@ -70,7 +72,8 @@ import net.runelite.http.api.osbuddy.OSBGrandExchangeClient;
@PluginDescriptor( @PluginDescriptor(
name = "Examine", name = "Examine",
description = "Send examine information to the API", description = "Send examine information to the API",
tags = {"npcs", "items", "inventory", "objects"} tags = {"npcs", "items", "inventory", "objects"},
type = PluginType.UTILITY
) )
@Slf4j @Slf4j
@Singleton @Singleton
@@ -335,8 +338,8 @@ public class ExaminePlugin extends Plugin
// quantity is at least 1 // quantity is at least 1
quantity = Math.max(1, quantity); quantity = Math.max(1, quantity);
int itemCompositionPrice = itemComposition.getPrice(); int itemCompositionPrice = itemComposition.getPrice();
final int gePrice = itemManager.getItemPrice(id); final long gePrice = itemManager.getItemPrice(id);
final int alchPrice = itemCompositionPrice <= 0 ? 0 : itemManager.getAlchValue(itemComposition); final long alchPrice = itemCompositionPrice <= 0 ? 0 : Math.round(itemCompositionPrice * Constants.HIGH_ALCHEMY_MULTIPLIER);
if (gePrice > 0 || alchPrice > 0) if (gePrice > 0 || alchPrice > 0)
{ {
@@ -58,13 +58,16 @@ import net.runelite.client.game.NPCManager;
import net.runelite.client.game.XpDropEvent; import net.runelite.client.game.XpDropEvent;
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.PluginType;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.util.ColorUtil; import net.runelite.client.util.ColorUtil;
@PluginDescriptor( @PluginDescriptor(
name = "XP Drop", name = "XP Drop",
description = "Enable customization of the way XP drops are displayed", description = "Enable customization of the way XP drops are displayed",
tags = {"experience", "levels", "tick"}) tags = {"experience", "levels", "tick"},
type = PluginType.UTILITY
)
@Singleton @Singleton
public class XpDropPlugin extends Plugin public class XpDropPlugin extends Plugin
{ {
@@ -61,12 +61,14 @@ import net.runelite.client.game.chatbox.ChatboxPanelManager;
import net.runelite.client.game.chatbox.ChatboxTextInput; import net.runelite.client.game.chatbox.ChatboxTextInput;
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.PluginType;
@Slf4j @Slf4j
@PluginDescriptor( @PluginDescriptor(
name = "Fairy Rings", name = "Fairy Rings",
description = "Show the location of the fairy ring teleport", description = "Show the location of the fairy ring teleport",
tags = {"teleportation"} tags = {"teleportation"},
type = PluginType.UTILITY
) )
@Singleton @Singleton
public class FairyRingPlugin extends Plugin public class FairyRingPlugin extends Plugin
@@ -40,6 +40,7 @@ import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged; import net.runelite.client.events.ConfigChanged;
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.PluginType;
import net.runelite.client.task.Schedule; import net.runelite.client.task.Schedule;
import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.ClientToolbar;
import net.runelite.client.ui.NavigationButton; import net.runelite.client.ui.NavigationButton;
@@ -51,7 +52,8 @@ import net.runelite.http.api.feed.FeedResult;
name = "News Feed", name = "News Feed",
description = "Show the latest RuneLite blog posts, OSRS news, and JMod Twitter posts", description = "Show the latest RuneLite blog posts, OSRS news, and JMod Twitter posts",
tags = {"external", "integration", "panel", "twitter"}, tags = {"external", "integration", "panel", "twitter"},
loadWhenOutdated = true loadWhenOutdated = true,
type = PluginType.MISCELLANEOUS
) )
@Slf4j @Slf4j
@Singleton @Singleton
@@ -71,6 +71,7 @@ import net.runelite.client.events.OverlayMenuClicked;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDependency; import net.runelite.client.plugins.PluginDependency;
import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.PluginType;
import net.runelite.client.plugins.xptracker.XpTrackerPlugin; import net.runelite.client.plugins.xptracker.XpTrackerPlugin;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.ui.overlay.OverlayMenuEntry; import net.runelite.client.ui.overlay.OverlayMenuEntry;
@@ -79,7 +80,8 @@ import net.runelite.client.util.ItemUtil;
@PluginDescriptor( @PluginDescriptor(
name = "Fishing", name = "Fishing",
description = "Show fishing stats and mark fishing spots", description = "Show fishing stats and mark fishing spots",
tags = {"overlay", "skilling"} tags = {"overlay", "skilling"},
type = PluginType.SKILLING
) )
@PluginDependency(XpTrackerPlugin.class) @PluginDependency(XpTrackerPlugin.class)
@Singleton @Singleton
@@ -33,6 +33,7 @@ import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged; import net.runelite.client.events.ConfigChanged;
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.PluginType;
import net.runelite.client.ui.DrawManager; import net.runelite.client.ui.DrawManager;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
@@ -50,7 +51,8 @@ import net.runelite.client.ui.overlay.OverlayManager;
name = "Performance", name = "Performance",
description = "Show current FPS or set an FPS limit", description = "Show current FPS or set an FPS limit",
tags = {"frames", "framerate", "limit", "overlay"}, tags = {"frames", "framerate", "limit", "overlay"},
enabledByDefault = false enabledByDefault = false,
type = PluginType.MISCELLANEOUS
) )
@Singleton @Singleton
public class FpsPlugin extends Plugin public class FpsPlugin extends Plugin
@@ -35,10 +35,12 @@ import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
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.PluginType;
@PluginDescriptor( @PluginDescriptor(
name = "Friend List", name = "Friend List",
description = "Add extra information to the friend and ignore lists" description = "Add extra information to the friend and ignore lists",
type = PluginType.MISCELLANEOUS
) )
@Singleton @Singleton
public class FriendListPlugin extends Plugin public class FriendListPlugin extends Plugin
@@ -50,13 +50,15 @@ import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.game.chatbox.ChatboxPanelManager; import net.runelite.client.game.chatbox.ChatboxPanelManager;
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.PluginType;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.util.ColorUtil; import net.runelite.client.util.ColorUtil;
@Slf4j @Slf4j
@PluginDescriptor( @PluginDescriptor(
name = "Friend Notes", name = "Friend Notes",
description = "Store notes about your friends" description = "Store notes about your friends",
type = PluginType.MISCELLANEOUS
) )
@Singleton @Singleton
public class FriendNotesPlugin extends Plugin public class FriendNotesPlugin extends Plugin

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