Merge branch 'master' into externalserror1

This commit is contained in:
Tyler Bochard
2020-03-12 22:33:30 -04:00
committed by GitHub
96 changed files with 2094 additions and 2758 deletions
+13 -2
View File
@@ -16,9 +16,17 @@ jobs:
with: with:
title-regex: '^([\w-/]+): \w+' title-regex: '^([\w-/]+): \w+'
build: validate:
name: Validate gradle wrapper
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: gradle/wrapper-validation-action@v1
build:
name: Build name: Build
needs: [pr-lint, validate]
runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v1
@@ -40,8 +48,9 @@ jobs:
run: ./gradlew build --stacktrace -x test -x checkstyleMain -x checkstyleTest --console=plain run: ./gradlew build --stacktrace -x test -x checkstyleMain -x checkstyleTest --console=plain
test: test:
runs-on: ubuntu-latest
name: Test name: Test
needs: [pr-lint, validate]
runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v1
@@ -64,6 +73,7 @@ jobs:
checkstyleMain: checkstyleMain:
name: Checkstyle main name: Checkstyle main
needs: [pr-lint, validate]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@@ -87,6 +97,7 @@ jobs:
checkstyleTest: checkstyleTest:
name: Checkstyle test name: Checkstyle test
needs: [pr-lint, validate]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
-1
View File
@@ -19,4 +19,3 @@ jobs:
exempt-issue-label: 'awaiting-approval' exempt-issue-label: 'awaiting-approval'
exempt-pr-label: 'awaiting-approval' exempt-pr-label: 'awaiting-approval'
days-before-stale: 60 days-before-stale: 60
days-before-close: 30
+2 -1
View File
@@ -58,7 +58,7 @@ fun isNonStable(version: String): Boolean {
allprojects { allprojects {
group = "com.openosrs" group = "com.openosrs"
version = ProjectVersions.rlVersion version = ProjectVersions.openosrsVersion
apply<MavenPublishPlugin>() apply<MavenPublishPlugin>()
} }
@@ -90,6 +90,7 @@ subprojects {
} }
filter { filter {
includeModule("net.runelite", "fernflower") includeModule("net.runelite", "fernflower")
includeModule("com.openosrs.rxrelay3", "rxrelay")
} }
} }
} }
+3 -3
View File
@@ -44,10 +44,10 @@ open class BootstrapTask @Inject constructor(@Input val type: String) : DefaultT
val version = splat[2] val version = splat[2]
lateinit var path: String lateinit var path: String
if (it.file.name.contains(ProjectVersions.rlVersion)) { if (it.file.name.contains(ProjectVersions.openosrsVersion)) {
path = "https://github.com/open-osrs/hosting/raw/master/${type}/${it.file.name}" path = "https://github.com/open-osrs/hosting/raw/master/${type}/${it.file.name}"
} else if (it.file.name.contains("injection-annotations")) { } else if (it.file.name.contains("injection-annotations") || it.file.name.contains("rxrelay")) {
path = "https://github.com/open-osrs/hosting/raw/master/" + group.replace(".", "/") + "/${name}/$version/${it.file.name}" path = "https://github.com/open-osrs/hosting/raw/master/" + group.replace(".", "/") + "/${name}/$version/${it.file.name}"
} else if (!group.contains("runelite")) { } else if (!group.contains("runelite")) {
path = "https://repo.maven.apache.org/maven2/" + group.replace(".", "/") + "/${name}/$version/${name}-$version" path = "https://repo.maven.apache.org/maven2/" + group.replace(".", "/") + "/${name}/$version/${name}-$version"
if (it.classifier != null && it.classifier != "no_aop") { if (it.classifier != null && it.classifier != "no_aop") {
+21 -23
View File
@@ -25,9 +25,9 @@
object ProjectVersions { object ProjectVersions {
const val launcherVersion = "2.0.4" const val launcherVersion = "2.0.4"
const val rlVersion = "1.6.8" const val rlVersion = "1.6.9"
const val openosrsVersion = "3.0.6" const val openosrsVersion = "3.1.0"
const val rsversion = 188 const val rsversion = 188
const val cacheversion = 165 const val cacheversion = 165
@@ -47,12 +47,12 @@ object Plugins {
object Libraries { object Libraries {
private object Versions { private object Versions {
const val annotations = "18.0.0" const val annotations = "19.0.0"
const val antlr = "4.7.2" const val antlr = "4.8-1"
const val apacheCommonsCompress = "1.19" const val apacheCommonsCompress = "1.20"
const val apacheCommonsCsv = "1.7" const val apacheCommonsCsv = "1.8"
const val apacheCommonsText = "1.8" const val apacheCommonsText = "1.8"
const val asm = "7.2" const val asm = "7.3.1"
const val commonsCli = "1.4" const val commonsCli = "1.4"
const val discord = "1.1" const val discord = "1.1"
const val fernflower = "07082019" const val fernflower = "07082019"
@@ -67,27 +67,26 @@ object Libraries {
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.13.0"
const val junit = "4.13" const val junit = "4.13"
const val jupiter = "5.6.0-M1" const val jupiter = "5.6.0"
const val logback = "1.2.3" const val logback = "1.2.3"
const val lombok = "1.18.10" const val lombok = "1.18.12"
const val mavenPluginAnnotations = "3.6.0" const val mavenPluginAnnotations = "3.6.0"
const val mavenPluginApi = "3.6.3" const val mavenPluginApi = "3.6.3"
const val mockito = "3.2.4" const val mockito = "3.3.1"
const val naturalMouse = "2.0.2" const val netty = "4.1.45.Final"
const val netty = "4.1.44.Final" const val okhttp3 = "4.4.0"
const val okhttp3 = "4.3.0"
const val orangeExtensions = "1.0" const val orangeExtensions = "1.0"
const val petitparser = "2.3.1" const val petitparser = "2.3.1"
const val pf4j = "3.2.0" const val pf4j = "3.2.0"
const val pf4jUpdate = "2.2.0" const val pf4jUpdate = "2.3.0"
const val plexus = "3.3.0"
const val radiance = "2.5.1" const val radiance = "2.5.1"
const val rxjava = "2.2.16" const val rxjava = "3.0.0"
const val rxrelay = "2.1.1" const val rxrelay = "3.0.0-SNAPSHOT"
const val sisu = "0.3.4" const val sisu = "0.3.4"
const val sentry = "1.7.29" const val sentry = "1.7.30"
const val semver = "0.9.0"
const val slf4j = "1.7.30" const val slf4j = "1.7.30"
} }
@@ -135,7 +134,6 @@ object Libraries {
const val mavenPluginApi = "org.apache.maven:maven-plugin-api:${Versions.mavenPluginApi}" const val mavenPluginApi = "org.apache.maven:maven-plugin-api:${Versions.mavenPluginApi}"
const val mockitoCore = "org.mockito:mockito-core:${Versions.mockito}" const val mockitoCore = "org.mockito:mockito-core:${Versions.mockito}"
const val mockitoInline = "org.mockito:mockito-inline:${Versions.mockito}" const val mockitoInline = "org.mockito:mockito-inline:${Versions.mockito}"
const val naturalMouse = "com.github.joonasvali.naturalmouse:naturalmouse:${Versions.naturalMouse}"
const val nettyBuffer = "io.netty:netty-buffer:${Versions.netty}" const val nettyBuffer = "io.netty:netty-buffer:${Versions.netty}"
const val okhttp3 = "com.squareup.okhttp3:okhttp:${Versions.okhttp3}" const val okhttp3 = "com.squareup.okhttp3:okhttp:${Versions.okhttp3}"
const val okhttp3Webserver = "com.squareup.okhttp3:mockwebserver:${Versions.okhttp3}" const val okhttp3Webserver = "com.squareup.okhttp3:mockwebserver:${Versions.okhttp3}"
@@ -143,14 +141,14 @@ object Libraries {
const val petitparser = "com.github.petitparser:java-petitparser:${Versions.petitparser}" const val petitparser = "com.github.petitparser:java-petitparser:${Versions.petitparser}"
const val pf4j = "org.pf4j:pf4j:${Versions.pf4j}" const val pf4j = "org.pf4j:pf4j:${Versions.pf4j}"
const val pf4jUpdate = "org.pf4j:pf4j-update:${Versions.pf4jUpdate}" const val pf4jUpdate = "org.pf4j:pf4j-update:${Versions.pf4jUpdate}"
const val plexus = "org.codehaus.plexus:plexus-utils:${Versions.plexus}" const val rxjava = "io.reactivex.rxjava3:rxjava:${Versions.rxjava}"
const val rxjava = "io.reactivex.rxjava2:rxjava:${Versions.rxjava}" const val rxrelay = "com.openosrs.rxrelay3:rxrelay:${Versions.rxrelay}"
const val rxrelay = "com.jakewharton.rxrelay2:rxrelay:${Versions.rxrelay}"
const val sisu = "org.eclipse.sisu:org.eclipse.sisu.inject:${Versions.sisu}" const val sisu = "org.eclipse.sisu:org.eclipse.sisu.inject:${Versions.sisu}"
const val slf4jApi = "org.slf4j:slf4j-api:${Versions.slf4j}" const val slf4jApi = "org.slf4j:slf4j-api:${Versions.slf4j}"
const val slf4jNop = "org.slf4j:slf4j-nop:${Versions.slf4j}" const val slf4jNop = "org.slf4j:slf4j-nop:${Versions.slf4j}"
const val slf4jSimple = "org.slf4j:slf4j-simple:${Versions.slf4j}" const val slf4jSimple = "org.slf4j:slf4j-simple:${Versions.slf4j}"
const val sentry = "io.sentry:sentry:${Versions.sentry}" const val sentry = "io.sentry:sentry:${Versions.sentry}"
const val semver = "com.github.zafarkhaja:java-semver:${Versions.semver}"
const val substance = "org.pushing-pixels:radiance-substance:${Versions.radiance}" const val substance = "org.pushing-pixels:radiance-substance:${Versions.radiance}"
const val trident = "org.pushing-pixels:radiance-trident:${Versions.radiance}" 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}"
@@ -35,8 +35,8 @@ public class KitDefinition
public short[] retextureToFind; public short[] retextureToFind;
public short[] retextureToReplace; public short[] retextureToReplace;
public int bodyPartId = -1; public int bodyPartId = -1;
public int[] modelIds; public int[] models;
public int[] models = new int[] public int[] chatheadModels = new int[]
{ {
-1, -1, -1, -1, -1 -1, -1, -1, -1, -1
}; };
@@ -53,11 +53,11 @@ public class KitLoader
else if (opcode == 2) else if (opcode == 2)
{ {
int length = is.readUnsignedByte(); int length = is.readUnsignedByte();
def.modelIds = new int[length]; def.models = new int[length];
for (int index = 0; index < length; ++index) for (int index = 0; index < length; ++index)
{ {
def.modelIds[index] = is.readUnsignedShort(); def.models[index] = is.readUnsignedShort();
} }
} }
else if (opcode == 3) else if (opcode == 3)
@@ -90,7 +90,7 @@ public class KitLoader
} }
else if (opcode >= 60 && opcode < 70) else if (opcode >= 60 && opcode < 70)
{ {
def.models[opcode - 60] = is.readShort(); def.chatheadModels[opcode - 60] = is.readUnsignedShort();
} }
} }
+1 -1
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.2.1-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.2.2-all.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
@@ -64,7 +64,6 @@ public class RuneLiteAPI
private static final String WSBASE = "https://api.runelite.net/ws"; private static final String WSBASE = "https://api.runelite.net/ws";
private static final String STATICBASE = "https://static.runelite.net"; private static final String STATICBASE = "https://static.runelite.net";
private static final String OPENOSRS_BASE = /*"https://api.openosrs.com*/ "https://api.runelitepl.us";
private static final String OPENOSRS_SESSION = "http://session.openosrs.dev"; private static final String OPENOSRS_SESSION = "http://session.openosrs.dev";
private static final String OPENOSRS_XTEA = "http://xtea.openosrs.dev"; private static final String OPENOSRS_XTEA = "http://xtea.openosrs.dev";
private static final String OPENOSRS_ANIMATIONS = "http://animations.openosrs.dev"; private static final String OPENOSRS_ANIMATIONS = "http://animations.openosrs.dev";
@@ -151,11 +150,6 @@ public class RuneLiteAPI
return HttpUrl.parse(BASE + "/runelite-" + getVersion()); return HttpUrl.parse(BASE + "/runelite-" + getVersion());
} }
public static HttpUrl getOpenOSRSApiBase()
{
return HttpUrl.parse(OPENOSRS_BASE + "/http-service-" + getRlpVersion());
}
public static HttpUrl getStaticBase() public static HttpUrl getStaticBase()
{ {
final String prop = System.getProperty("runelite.static.url"); final String prop = System.getProperty("runelite.static.url");
@@ -25,7 +25,7 @@
package net.runelite.http.api.account; package net.runelite.http.api.account;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import io.reactivex.Observable; import io.reactivex.rxjava3.core.Observable;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
@@ -27,8 +27,6 @@ package net.runelite.http.api.chat;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.RuneLiteAPI;
import okhttp3.HttpUrl; import okhttp3.HttpUrl;
@@ -40,9 +38,6 @@ public class ChatClient
{ {
private static final RequestBody body = RequestBody.Companion.create(new byte[0], null); private static final RequestBody body = RequestBody.Companion.create(new byte[0], null);
private static final Predicate<String> LAYOUT_VALIDATOR = Pattern
.compile("\\[[A-Z]+]:(\\s*\\w+\\s*(\\([A-Za-z]+\\))?,?)+")
.asPredicate();
public boolean submitKc(String username, String boss, int kc) throws IOException public boolean submitKc(String username, String boss, int kc) throws IOException
{ {
@@ -56,7 +51,7 @@ public class ChatClient
Request request = new Request.Builder() Request request = new Request.Builder()
.post(body) .post(RequestBody.create(null, new byte[0]))
.url(url) .url(url)
.build(); .build();
@@ -99,7 +94,7 @@ public class ChatClient
.build(); .build();
Request request = new Request.Builder() Request request = new Request.Builder()
.post(body) .post(RequestBody.create(null, new byte[0]))
.url(url) .url(url)
.build(); .build();
@@ -144,7 +139,7 @@ public class ChatClient
.build(); .build();
Request request = new Request.Builder() Request request = new Request.Builder()
.post(body) .post(RequestBody.create(null, new byte[0]))
.url(url) .url(url)
.build(); .build();
@@ -193,7 +188,7 @@ public class ChatClient
.build(); .build();
Request request = new Request.Builder() Request request = new Request.Builder()
.post(body) .post(RequestBody.create(null, new byte[0]))
.url(url) .url(url)
.build(); .build();
@@ -236,7 +231,7 @@ public class ChatClient
.build(); .build();
Request request = new Request.Builder() Request request = new Request.Builder()
.post(body) .post(RequestBody.create(null, new byte[0]))
.url(url) .url(url)
.build(); .build();
@@ -268,31 +263,6 @@ public class ChatClient
} }
} }
public boolean submitLayout(String username, String layout) throws IOException
{
if (!testLayout(layout))
{
throw new IOException("Layout " + layout + " is not valid!");
}
HttpUrl url = RuneLiteAPI.getOpenOSRSApiBase().newBuilder()
.addPathSegment("chat")
.addPathSegment("layout")
.addQueryParameter("name", username)
.addQueryParameter("layout", layout)
.build();
Request request = new Request.Builder()
.post(body)
.url(url)
.build();
try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute())
{
return response.isSuccessful();
}
}
public boolean submitDuels(String username, int wins, int losses, int winningStreak, int losingStreak) throws IOException public boolean submitDuels(String username, int wins, int losses, int winningStreak, int losingStreak) throws IOException
{ {
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = RuneLiteAPI.getApiBase().newBuilder()
@@ -306,7 +276,7 @@ public class ChatClient
.build(); .build();
Request request = new Request.Builder() Request request = new Request.Builder()
.post(body) .post(RequestBody.create(null, new byte[0]))
.url(url) .url(url)
.build(); .build();
@@ -316,40 +286,6 @@ public class ChatClient
} }
} }
public boolean testLayout(String layout)
{
return LAYOUT_VALIDATOR.test(layout);
}
public House[] getHosts(int world, String location) throws IOException
{
HttpUrl url = RuneLiteAPI.getOpenOSRSApiBase().newBuilder()
.addPathSegment("chat")
.addPathSegment("hosts")
.addQueryParameter("world", Integer.toString(world))
.addQueryParameter("location", location)
.build();
Request request = new Request.Builder()
.url(url)
.build();
try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute())
{
if (!response.isSuccessful())
{
throw new IOException("Unable to look up hosts!");
}
InputStream in = response.body().byteStream();
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), House[].class);
}
catch (JsonParseException ex)
{
throw new IOException(ex);
}
}
public Duels getDuels(String username) throws IOException public Duels getDuels(String username) throws IOException
{ {
@@ -379,63 +315,6 @@ public class ChatClient
} }
} }
public boolean submitHost(int world, String location, House house) throws IOException
{
HttpUrl url = RuneLiteAPI.getOpenOSRSApiBase().newBuilder()
.addPathSegment("chat")
.addPathSegment("hosts")
.addQueryParameter("world", Integer.toString(world))
.addQueryParameter("location", location)
.addQueryParameter("owner", house.getOwner())
.addQueryParameter("guildedAltar", Boolean.toString(house.isGuildedAltarPresent()))
.addQueryParameter("occultAltar", Boolean.toString(house.isOccultAltarPresent()))
.addQueryParameter("spiritTree", Boolean.toString(house.isSpiritTreePresent()))
.addQueryParameter("fairyRing", Boolean.toString(house.isFairyRingPresent()))
.addQueryParameter("wildernessObelisk", Boolean.toString(house.isWildernessObeliskPresent()))
.addQueryParameter("repairStand", Boolean.toString(house.isRepairStandPresent()))
.addQueryParameter("combatDummy", Boolean.toString(house.isCombatDummyPresent()))
.build();
Request request = new Request.Builder()
.post(body)
.url(url)
.build();
try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute())
{
return response.isSuccessful();
}
}
public boolean removeHost(int world, String location, House house) throws IOException
{
HttpUrl url = RuneLiteAPI.getOpenOSRSApiBase().newBuilder()
.addPathSegment("chat")
.addPathSegment("hosts")
.addQueryParameter("world", Integer.toString(world))
.addQueryParameter("location", location)
.addQueryParameter("owner", house.getOwner())
.addQueryParameter("guildedAltar", Boolean.toString(house.isGuildedAltarPresent()))
.addQueryParameter("occultAltar", Boolean.toString(house.isOccultAltarPresent()))
.addQueryParameter("spiritTree", Boolean.toString(house.isSpiritTreePresent()))
.addQueryParameter("fairyRing", Boolean.toString(house.isFairyRingPresent()))
.addQueryParameter("wildernessObelisk", Boolean.toString(house.isWildernessObeliskPresent()))
.addQueryParameter("repairStand", Boolean.toString(house.isRepairStandPresent()))
.addQueryParameter("combatDummy", Boolean.toString(house.isCombatDummyPresent()))
.addQueryParameter("remove", Boolean.toString(true))
.build();
Request request = new Request.Builder()
.post(body)
.url(url)
.build();
try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute())
{
return response.isSuccessful();
}
}
public boolean submitLayout(String username, LayoutRoom[] rooms) throws IOException public boolean submitLayout(String username, LayoutRoom[] rooms) throws IOException
{ {
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = RuneLiteAPI.getApiBase().newBuilder()
@@ -482,4 +361,4 @@ public class ChatClient
throw new IOException(ex); throw new IOException(ex);
} }
} }
} }
@@ -27,7 +27,7 @@ package net.runelite.http.api.item;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonReader;
import io.reactivex.Observable; import io.reactivex.rxjava3.core.Observable;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@@ -25,7 +25,7 @@
package net.runelite.http.api.osbuddy; package net.runelite.http.api.osbuddy;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import io.reactivex.Observable; import io.reactivex.rxjava3.core.Observable;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
@@ -37,13 +37,21 @@ public class Hitsplat
public enum HitsplatType public enum HitsplatType
{ {
/** /**
* Blocking damage (blue). * Blocking damage by me (blue).
*/ */
BLOCK, BLOCK_ME,
/** /**
* Taking damage (red). * Blocking damage by others (blue).
*/ */
DAMAGE, BLOCK_OTHER,
/**
* Taking damage by me (red).
*/
DAMAGE_ME,
/**
* Taking damage by others (red).
*/
DAMAGE_OTHER,
/** /**
* Damage from poison (green). * Damage from poison (green).
*/ */
@@ -72,8 +80,10 @@ public class Hitsplat
{ {
switch (type) switch (type)
{ {
case 0: return BLOCK; case 12: return BLOCK_ME;
case 1: return DAMAGE; case 13: return BLOCK_OTHER;
case 16: return DAMAGE_ME;
case 17: return DAMAGE_OTHER;
case 2: return POISON; case 2: return POISON;
case 4: return DISEASE; case 4: return DISEASE;
case 5: return VENOM; case 5: return VENOM;
@@ -57,6 +57,10 @@ public enum InventoryID
* Monkey madness puzzle box inventory. * Monkey madness puzzle box inventory.
*/ */
MONKEY_MADNESS_PUZZLE_BOX(221), MONKEY_MADNESS_PUZZLE_BOX(221),
/**
* Drift net fishing reward
*/
DRIFT_NET_FISHING_REWARD(307),
/** /**
* Looting Bag inventory * Looting Bag inventory
*/ */
@@ -1,5 +1,7 @@
package net.runelite.api; package net.runelite.api;
import javax.annotation.Nullable;
/** /**
* Represents the template of a specific item type. * Represents the template of a specific item type.
*/ */
@@ -127,4 +129,29 @@ public interface ItemDefinition
* @param id The itemID of the item with desired model * @param id The itemID of the item with desired model
*/ */
void setModelOverride(int id); void setModelOverride(int id);
/**
* Gets the model ID of the inventory item.
*
* @return the model ID
*/
int getInventoryModel();
/**
* Since the client reuses item models, it stores colors that can be replaced.
* This returns what colors the item model will be replaced with.
*
* @return the colors to replace with
*/
@Nullable
short[] getColorToReplaceWith();
/**
* Since the client reuses item models, it stores textures that can be replaced.
* This returns what textures the item model will be replaced with.
*
* @return the textures to replace with
*/
@Nullable
short[] getTextureToReplaceWith();
} }
@@ -7347,7 +7347,7 @@ public final class ItemID
public static final int ABSORPTION_2 = 11736; public static final int ABSORPTION_2 = 11736;
public static final int ABSORPTION_1 = 11737; public static final int ABSORPTION_1 = 11737;
public static final int HERB_BOX = 11738; public static final int HERB_BOX = 11738;
public static final int OPENED_HERB_BOX = 11739; public static final int OPEN_HERB_BOX = 11739;
public static final int SCROLL_OF_REDIRECTION = 11740; public static final int SCROLL_OF_REDIRECTION = 11740;
public static final int RIMMINGTON_TELEPORT = 11741; public static final int RIMMINGTON_TELEPORT = 11741;
public static final int TAVERLEY_TELEPORT = 11742; public static final int TAVERLEY_TELEPORT = 11742;
@@ -7481,6 +7481,7 @@ public final class ItemID
public static final int BOX_OF_CHOCOLATE_STRAWBERRIES = 11912; public static final int BOX_OF_CHOCOLATE_STRAWBERRIES = 11912;
public static final int BOX_OF_CHOCOLATE_STRAWBERRIES_11914 = 11914; public static final int BOX_OF_CHOCOLATE_STRAWBERRIES_11914 = 11914;
public static final int SLICE_OF_BIRTHDAY_CAKE = 11916; public static final int SLICE_OF_BIRTHDAY_CAKE = 11916;
public static final int SLICE_OF_BIRTHDAY_CAKE_11917 = 11917;
public static final int BIRTHDAY_PRESENT = 11918; public static final int BIRTHDAY_PRESENT = 11918;
public static final int COW_MASK = 11919; public static final int COW_MASK = 11919;
public static final int DRAGON_PICKAXE = 11920; public static final int DRAGON_PICKAXE = 11920;
@@ -11391,8 +11392,8 @@ public final class ItemID
public static final int TWISTED_RELICHUNTER_T3_ARMOUR_SET = 24475; public static final int TWISTED_RELICHUNTER_T3_ARMOUR_SET = 24475;
public static final int OPEN_HERB_SACK = 24478; public static final int OPEN_HERB_SACK = 24478;
public static final int SPICE_RACK = 24479; public static final int SPICE_RACK = 24479;
public static final int OPENED_COAL_BAG = 24480; public static final int OPEN_COAL_BAG = 24480;
public static final int OPENED_GEM_BAG = 24481; public static final int OPEN_GEM_BAG = 24481;
public static final int OPEN_SEED_BOX = 24482; public static final int OPEN_SEED_BOX = 24482;
public static final int PHOENIX_24483 = 24483; public static final int PHOENIX_24483 = 24483;
public static final int PHOENIX_24484 = 24484; public static final int PHOENIX_24484 = 24484;
@@ -11407,11 +11408,9 @@ public final class ItemID
public static final int VOLATILE_ORB = 24514; public static final int VOLATILE_ORB = 24514;
public static final int ELDRITCH_ORB = 24517; public static final int ELDRITCH_ORB = 24517;
public static final int VICTORS_CAPE_1000 = 24520; public static final int VICTORS_CAPE_1000 = 24520;
public static final int CAT_EARS = 24522; public static final int CAT_EARS = 24525;
public static final int LOOSE_CAT_HAIR = 24523;
public static final int GERTRUDES_COMB = 24524;
public static final int CAT_EARS_24525 = 24525;
public static final int HELL_CAT_EARS = 24527; public static final int HELL_CAT_EARS = 24527;
public static final int LAMP_OF_THE_GATHERER = 24528; public static final int LAMP_OF_THE_GATHERER = 24528;
public static final int HARMONY = 24529;
/* This file is automatically generated. Do not edit. */ /* This file is automatically generated. Do not edit. */
} }
@@ -27,7 +27,7 @@ package net.runelite.api;
/** /**
* Represents a message in the chatbox. * Represents a message in the chatbox.
*/ */
public interface MessageNode public interface MessageNode extends Node
{ {
/** /**
* Get the id for this message node * Get the id for this message node
@@ -8429,6 +8429,15 @@ public final class NpcID
public static final int SHURA = 9413; public static final int SHURA = 9413;
public static final int SHURA_9414 = 9414; public static final int SHURA_9414 = 9414;
public static final int ACORN = 9415; public static final int ACORN = 9415;
public static final int PHOSANIS_NIGHTMARE = 9416;
public static final int PHOSANIS_NIGHTMARE_9417 = 9417;
public static final int PHOSANIS_NIGHTMARE_9418 = 9418;
public static final int PHOSANIS_NIGHTMARE_9419 = 9419;
public static final int PHOSANIS_NIGHTMARE_9420 = 9420;
public static final int PHOSANIS_NIGHTMARE_9421 = 9421;
public static final int PHOSANIS_NIGHTMARE_9422 = 9422;
public static final int PHOSANIS_NIGHTMARE_9423 = 9423;
public static final int PHOSANIS_NIGHTMARE_9424 = 9424;
public static final int THE_NIGHTMARE = 9425; public static final int THE_NIGHTMARE = 9425;
public static final int THE_NIGHTMARE_9426 = 9426; public static final int THE_NIGHTMARE_9426 = 9426;
public static final int THE_NIGHTMARE_9427 = 9427; public static final int THE_NIGHTMARE_9427 = 9427;
@@ -8466,12 +8475,12 @@ public final class NpcID
public static final int THE_NIGHTMARE_9463 = 9463; public static final int THE_NIGHTMARE_9463 = 9463;
public static final int THE_NIGHTMARE_9464 = 9464; public static final int THE_NIGHTMARE_9464 = 9464;
public static final int INFERNAL_PYRELORD = 9465; public static final int INFERNAL_PYRELORD = 9465;
public static final int DRAUL_LEPTOC_9467 = 9467; public static final int HUSK_9466 = 9466;
public static final int HORACIO_9468 = 9468; public static final int HUSK_9467 = 9467;
public static final int WISE_OLD_MAN_9469 = 9469; public static final int PARASITE_9468 = 9468;
public static final int HANS_9470 = 9470; public static final int PARASITE_9469 = 9469;
public static final int KING_ROALD_9471 = 9471; public static final int SLEEPWALKER_9470 = 9470;
public static final int ELLAMARIA_9472 = 9472; public static final int SISTER_SENGA = 9471;
public static final int GNOME_CHILD_9473 = 9473; public static final int SISTER_SENGA_9472 = 9472;
/* This file is automatically generated. Do not edit. */ /* This file is automatically generated. Do not edit. */
} }
@@ -4321,7 +4321,6 @@ public final class NullItemID
public static final int NULL_11911 = 11911; public static final int NULL_11911 = 11911;
public static final int NULL_11913 = 11913; public static final int NULL_11913 = 11913;
public static final int NULL_11915 = 11915; public static final int NULL_11915 = 11915;
public static final int NULL_11917 = 11917;
public static final int NULL_11921 = 11921; public static final int NULL_11921 = 11921;
public static final int NULL_11925 = 11925; public static final int NULL_11925 = 11925;
public static final int NULL_11927 = 11927; public static final int NULL_11927 = 11927;
@@ -12906,6 +12905,10 @@ public final class NullItemID
public static final int NULL_24518 = 24518; public static final int NULL_24518 = 24518;
public static final int NULL_24519 = 24519; public static final int NULL_24519 = 24519;
public static final int NULL_24521 = 24521; public static final int NULL_24521 = 24521;
public static final int NULL_24522 = 24522;
public static final int NULL_24523 = 24523;
public static final int NULL_24524 = 24524;
public static final int NULL_24526 = 24526; public static final int NULL_24526 = 24526;
public static final int NULL_24530 = 24530;
/* This file is automatically generated. Do not edit. */ /* This file is automatically generated. Do not edit. */
} }
@@ -13894,7 +13894,8 @@ public final class NullObjectID
public static final int NULL_29702 = 29702; public static final int NULL_29702 = 29702;
public static final int NULL_29703 = 29703; public static final int NULL_29703 = 29703;
public static final int NULL_29704 = 29704; public static final int NULL_29704 = 29704;
public static final int NULL_29706 = 29706; public static final int NULL_29709 = 29709;
public static final int NULL_29710 = 29710;
public static final int NULL_29713 = 29713; public static final int NULL_29713 = 29713;
public static final int NULL_29714 = 29714; public static final int NULL_29714 = 29714;
public static final int NULL_29715 = 29715; public static final int NULL_29715 = 29715;
@@ -18160,7 +18161,6 @@ public final class NullObjectID
public static final int NULL_37722 = 37722; public static final int NULL_37722 = 37722;
public static final int NULL_37723 = 37723; public static final int NULL_37723 = 37723;
public static final int NULL_37724 = 37724; public static final int NULL_37724 = 37724;
public static final int NULL_37725 = 37725;
public static final int NULL_37732 = 37732; public static final int NULL_37732 = 37732;
public static final int NULL_37733 = 37733; public static final int NULL_37733 = 37733;
public static final int NULL_37734 = 37734; public static final int NULL_37734 = 37734;
@@ -18329,34 +18329,5 @@ public final class NullObjectID
public static final int NULL_37934 = 37934; public static final int NULL_37934 = 37934;
public static final int NULL_37935 = 37935; public static final int NULL_37935 = 37935;
public static final int NULL_37950 = 37950; public static final int NULL_37950 = 37950;
public static final int NULL_37952 = 37952;
public static final int NULL_37953 = 37953;
public static final int NULL_37954 = 37954;
public static final int NULL_37962 = 37962;
public static final int NULL_37963 = 37963;
public static final int NULL_37964 = 37964;
public static final int NULL_37965 = 37965;
public static final int NULL_37966 = 37966;
public static final int NULL_37967 = 37967;
public static final int NULL_37971 = 37971;
public static final int NULL_37972 = 37972;
public static final int NULL_37973 = 37973;
public static final int NULL_37975 = 37975;
public static final int NULL_37977 = 37977;
public static final int NULL_37978 = 37978;
public static final int NULL_37979 = 37979;
public static final int NULL_37980 = 37980;
public static final int NULL_37981 = 37981;
public static final int NULL_37982 = 37982;
public static final int NULL_37984 = 37984;
public static final int NULL_37985 = 37985;
public static final int NULL_37986 = 37986;
public static final int NULL_37987 = 37987;
public static final int NULL_37988 = 37988;
public static final int NULL_37989 = 37989;
public static final int NULL_37990 = 37990;
public static final int NULL_37991 = 37991;
public static final int NULL_37992 = 37992;
public static final int NULL_37994 = 37994;
/* This file is automatically generated. Do not edit. */ /* This file is automatically generated. Do not edit. */
} }
@@ -15800,6 +15800,9 @@ public final class ObjectID
public static final int CARVED_REDWOOD_29681 = 29681; public static final int CARVED_REDWOOD_29681 = 29681;
public static final int CARVED_REDWOOD_29682 = 29682; public static final int CARVED_REDWOOD_29682 = 29682;
public static final int CRACK_29705 = 29705; public static final int CRACK_29705 = 29705;
public static final int POOL_OF_NIGHTMARES = 29706;
public static final int POOL_OF_NIGHTMARES_29707 = 29707;
public static final int SCOREBOARD_29708 = 29708;
public static final int NOTICEBOARD_29718 = 29718; public static final int NOTICEBOARD_29718 = 29718;
public static final int BALLISTA_29719 = 29719; public static final int BALLISTA_29719 = 29719;
public static final int STAIRCASE_29720 = 29720; public static final int STAIRCASE_29720 = 29720;
@@ -19580,16 +19583,5 @@ public final class ObjectID
public static final int DOOR_37938 = 37938; public static final int DOOR_37938 = 37938;
public static final int SCOREBOARD_37949 = 37949; public static final int SCOREBOARD_37949 = 37949;
public static final int COFFIN_37951 = 37951; public static final int COFFIN_37951 = 37951;
public static final int LIGHT_37955 = 37955;
public static final int LIGHT_37956 = 37956;
public static final int LIGHT_37957 = 37957;
public static final int LIGHT_37958 = 37958;
public static final int LIGHT_37959 = 37959;
public static final int LIGHT_37960 = 37960;
public static final int BANQUET_TABLE_37968 = 37968;
public static final int PRESENT_TABLE = 37969;
public static final int BIRTHDAY_HAT_TABLE = 37970;
public static final int PARTY_BALLOONS = 37974;
public static final int TABLE_37976 = 37976;
/* This file is automatically generated. Do not edit. */ /* This file is automatically generated. Do not edit. */
} }
@@ -36,6 +36,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static net.runelite.api.Constants.TILE_FLAG_BRIDGE; import static net.runelite.api.Constants.TILE_FLAG_BRIDGE;
import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.LocalPoint;
import net.runelite.api.coords.WorldPoint;
import net.runelite.api.geometry.RectangleUnion; import net.runelite.api.geometry.RectangleUnion;
import net.runelite.api.geometry.Shapes; import net.runelite.api.geometry.Shapes;
import net.runelite.api.geometry.SimplePolygon; import net.runelite.api.geometry.SimplePolygon;
@@ -760,4 +761,119 @@ public class Perspective
return new Point(xOffset, yOffset); return new Point(xOffset, yOffset);
} }
/**
* Calculates a polygon line from 2 LocalPoints
*
* @param client the game client
* @param startLocation start location of the polygon
* @param endLocation end location of the polygon
* @return a {@link Polygon}
*/
private static Polygon linePoly(@Nonnull Client client, @Nonnull LocalPoint startLocation, @Nonnull LocalPoint endLocation)
{
LocalPoint startPoint = new LocalPoint(
startLocation.getX() - (LOCAL_TILE_SIZE / 2),
startLocation.getY() + (LOCAL_TILE_SIZE / 2));
LocalPoint endPoint = new LocalPoint(
endLocation.getX() - (LOCAL_TILE_SIZE / 2),
endLocation.getY() + (LOCAL_TILE_SIZE / 2));
int plane = client.getPlane();
Point p1 = Perspective.localToCanvas(client, startPoint, plane);
Point p2 = Perspective.localToCanvas(client, endPoint, plane);
if (p1 != null && p2 != null)
{
Polygon polygon = new Polygon();
polygon.addPoint(p1.getX(), p1.getY());
polygon.addPoint(p2.getX(), p2.getY());
return polygon;
}
return null;
}
/**
* Calculates a list of polygon lines with 2 Worldpoints
* Start location is the South-West WorldPoint, end location is the North-East WorldPoint
* @param client the game client
* @param startLocation start location of the polygon
* @param endLocation end location of the polygon
* @return a {@link List} of {@link Polygon}
*/
public static List<Polygon> getLinePolyList(@Nonnull Client client, @Nonnull WorldPoint startLocation, @Nonnull WorldPoint endLocation)
{
List<Polygon> pList = new ArrayList<>();
int sizeX = Math.abs(endLocation.getX() - startLocation.getX()) + 1;
int sizeY = Math.abs(endLocation.getY() - startLocation.getY()) + 1;
//HANDLE NORTH
for (int i = 0; i < sizeX; i++)
{
WorldPoint startPoint = new WorldPoint(startLocation.getX() + i, startLocation.getY() + sizeY - 1, startLocation.getPlane());
WorldPoint endPoint = new WorldPoint(startLocation.getX() + (i + 1), startLocation.getY() + sizeY - 1, startLocation.getPlane());
LocalPoint localPointStart = LocalPoint.fromWorld(client, startPoint);
LocalPoint localPointEnd = LocalPoint.fromWorld(client, endPoint);
if (localPointStart != null && localPointEnd != null)
{
Polygon p = linePoly(client, localPointStart, localPointEnd);
if (p != null)
{
pList.add(p);
}
}
}
//HANDLE SOUTH
for (int i = 0; i < sizeX; i++)
{
WorldPoint startPoint = new WorldPoint(startLocation.getX() + i, startLocation.getY() - 1, startLocation.getPlane());
WorldPoint endPoint = new WorldPoint(startLocation.getX() + (i + 1), startLocation.getY() - 1, startLocation.getPlane());
LocalPoint localPointStart = LocalPoint.fromWorld(client, startPoint);
LocalPoint localPointEnd = LocalPoint.fromWorld(client, endPoint);
if (localPointStart != null && localPointEnd != null)
{
Polygon p = linePoly(client, localPointStart, localPointEnd);
if (p != null)
{
pList.add(p);
}
}
}
//HANDLE WEST
for (int j = 0; j < sizeY; j++)
{
WorldPoint startPoint = new WorldPoint(startLocation.getX(), startLocation.getY() + (j - 1), startLocation.getPlane());
WorldPoint endPoint = new WorldPoint(startLocation.getX(), startLocation.getY() + j, startLocation.getPlane());
LocalPoint localPointStart = LocalPoint.fromWorld(client, startPoint);
LocalPoint localPointEnd = LocalPoint.fromWorld(client, endPoint);
if (localPointStart != null && localPointEnd != null)
{
Polygon p = linePoly(client, localPointStart, localPointEnd);
if (p != null)
{
pList.add(p);
}
}
}
//HANDLE EAST
for (int j = 0; j < sizeY; j++)
{
WorldPoint startPoint = new WorldPoint(startLocation.getX() + sizeX, startLocation.getY() + (j - 1), startLocation.getPlane());
WorldPoint endPoint = new WorldPoint(startLocation.getX() + sizeX, startLocation.getY() + j, startLocation.getPlane());
LocalPoint localPointStart = LocalPoint.fromWorld(client, startPoint);
LocalPoint localPointEnd = LocalPoint.fromWorld(client, endPoint);
if (localPointStart != null && localPointEnd != null)
{
Polygon p = linePoly(client, localPointStart, localPointEnd);
if (p != null)
{
pList.add(p);
}
}
}
return pList;
}
} }
@@ -24,46 +24,17 @@
*/ */
package net.runelite.api; package net.runelite.api;
import lombok.Value;
/** /**
* A two-dimensional coordinate on the canvas. * A two-dimensional coordinate on the canvas.
*/ */
@Value
public class Point public class Point
{ {
private final int x; private final int x;
private final int y; private final int y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
@Override
public String toString()
{
return "Point{" + "x=" + x + ", y=" + y + '}';
}
/**
* Gets the x-axis coordinate of the point.
*
* @return the x-axis coordinate
*/
public int getX()
{
return x;
}
/**
* Gets the y-axis coordinate of the point.
*
* @return the y-axis coordinate
*/
public int getY()
{
return y;
}
/** /**
* Gets the distance between this point and another. * Gets the distance between this point and another.
* *
@@ -74,36 +45,4 @@ public class Point
{ {
return (int) Math.hypot(getX() - other.getX(), getY() - other.getY()); return (int) Math.hypot(getX() - other.getX(), getY() - other.getY());
} }
@Override
public int hashCode()
{
int hash = 3;
hash = 23 * hash + this.x;
hash = 23 * hash + this.y;
return hash;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
final Point other = (Point) obj;
if (this.x != other.x)
{
return false;
}
return this.y == other.y;
}
} }
@@ -227,5 +227,48 @@ public final class ScriptID
@ScriptArguments(string = 1) @ScriptArguments(string = 1)
public static final int CLAN_SEND_KICK = 215; public static final int CLAN_SEND_KICK = 215;
/**
* Toggles the bank search
*
* <ul>
* <li>int 1 (must be 1 or script immediately returns)</li>
* </ul>
*
* Also takes 17 widget IDs corresponding to various bank widgets.
* These can be retrieved from the getOnInvTransmit of BANK_ITEM_CONTAINER. Note that this array also
* contains the script ID for the bank layout script in the first index
*/
@ScriptArguments(integer = 18)
public static final int BANKMAIN_SEARCH_TOGGLE = 281;
/**
* Builds the items kept on death widget
*/
@ScriptArguments(integer = 4, string = 2)
public static final int DEATH_KEEP_BUILD = 1601;
/**
* Builds the widget that holds all of the players inside a clan chat
*/
@ScriptArguments(integer = 15)
public static final int CLAN_CHAT_CHANNEL_BUILD = 1658;
/**
* Builds the widget for making an offer in Grand Exchange
*/
@ScriptArguments(integer = 15)
public static final int GE_OFFERS_SETUP_BUILD = 779;
/**
* Builds the quest list inside the quest tab that shows each quest's progress
*/
@ScriptArguments(integer = 3)
public static final int QUESTLIST_PROGRESS_LIST_SHOW = 1354;
/**
* Procedure called when the toplevel interface is resized
*/
@ScriptArguments(integer = 2)
public static final int TOPLEVEL_RESIZE = 909;
} }
@@ -1293,7 +1293,7 @@ public final class SpriteID
public static final int SPELL_REANIMATE_CROPS_DISABLED = 1327; public static final int SPELL_REANIMATE_CROPS_DISABLED = 1327;
/* Unmapped: 1328~1337 */ /* Unmapped: 1328~1337 */
public static final int WORLD_SWITCHER_WORLD_STAR_BLUE = 1338; public static final int WORLD_SWITCHER_WORLD_STAR_BLUE = 1338;
public static final int GAMEBLAST16_PROMO_BANNER = 1339; public static final int HITSPLAT_DARK_GREEN_VENOM = 1339;
public static final int FAIRY_RING_REMOVE_FAVOURITE = 1340; public static final int FAIRY_RING_REMOVE_FAVOURITE = 1340;
public static final int FAIRY_RING_ADD_FAVOURITE = 1341; public static final int FAIRY_RING_ADD_FAVOURITE = 1341;
public static final int BANK_PLACEHOLDERS_LOCK = 1342; public static final int BANK_PLACEHOLDERS_LOCK = 1342;
@@ -1317,7 +1317,7 @@ public final class SpriteID
public static final int HITSPLAT_GREEN_POISON = 1360; public static final int HITSPLAT_GREEN_POISON = 1360;
public static final int HITSPLAT_ORANGE = 1361; public static final int HITSPLAT_ORANGE = 1361;
public static final int HITSPLAT_ORANGE_DISEASE = 1362; public static final int HITSPLAT_ORANGE_DISEASE = 1362;
public static final int HITSPLAT_DARK_GREEN_VENOM = 1363; public static final int HITSPLAT_GREY = 1363;
public static final int BOUNTY_HUNTER_SKIP_TARGET = 1364; public static final int BOUNTY_HUNTER_SKIP_TARGET = 1364;
public static final int BOUNTY_HUNTER_SKIP_TARGET_HOVERED = 1365; public static final int BOUNTY_HUNTER_SKIP_TARGET_HOVERED = 1365;
public static final int HOUSE_VIEWER_ROTATE_CLOCKWISE = 1366; public static final int HOUSE_VIEWER_ROTATE_CLOCKWISE = 1366;
@@ -405,6 +405,15 @@ public enum Varbits
*/ */
KINGDOM_FAVOR(72), KINGDOM_FAVOR(72),
KINGDOM_COFFER(74), KINGDOM_COFFER(74),
KINGDOM_WORKERS_WOOD(81),
KINGDOM_WORKERS_HERBS(82),
KINGDOM_WORKERS_FISHING(83),
KINGDOM_WORKERS_MINING(84),
KINGDOM_WORKERS_FISH_COOKED_BUTTON(135), // 0 - Raw, 1 - Cooked
KINGDOM_WORKERS_HARDWOOD(2131),
KINGDOM_WORKERS_FARM(2132),
KINGDOM_WORKERS_HARDWOOD_BUTTON(2133), // 0 - Mahogany, 1 - Teak, 2 - Both
KINGDOM_WORKERS_HERBS_BUTTON(2134), // 0 - Herbs, 1 - Flax
/** /**
* The Hand in the Sand quest status * The Hand in the Sand quest status
@@ -501,6 +510,7 @@ public enum Varbits
SUPERIOR_ENABLED(5362), SUPERIOR_ENABLED(5362),
FOSSIL_ISLAND_WYVERN_DISABLE(6251), FOSSIL_ISLAND_WYVERN_DISABLE(6251),
BANK_REARRANGE_MODE(3959),
CURRENT_BANK_TAB(4150), CURRENT_BANK_TAB(4150),
WORLDHOPPER_FAVROITE_1(4597), WORLDHOPPER_FAVROITE_1(4597),
@@ -0,0 +1,17 @@
package net.runelite.api.events.player.headicon;
import lombok.Data;
import net.runelite.api.HeadIcon;
import net.runelite.api.Player;
import net.runelite.api.events.Event;
@Data
public class OverheadPrayerChanged implements Event
{
private final Player player;
private final HeadIcon oldHeadIcon;
private final HeadIcon newHeadIcon;
}
@@ -0,0 +1,17 @@
package net.runelite.api.events.player.headicon;
import lombok.Data;
import net.runelite.api.Player;
import net.runelite.api.SkullIcon;
import net.runelite.api.events.Event;
@Data
public class PlayerSkullChanged implements Event
{
private final Player player;
private final SkullIcon oldSkullIcon;
private final SkullIcon newSkullIcon;
}
@@ -33,11 +33,12 @@ import java.util.Collection;
import java.util.List; import java.util.List;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.WordUtils; import org.apache.commons.text.WordUtils;
import org.apache.commons.text.similarity.JaroWinklerDistance;
public class Text public class Text
{ {
private static final StringBuilder SB = new StringBuilder(64); private static final StringBuilder SB = new StringBuilder(64);
public static final JaroWinklerDistance DISTANCE = new JaroWinklerDistance();
public static final Splitter COMMA_SPLITTER = Splitter public static final Splitter COMMA_SPLITTER = Splitter
.on(",") .on(",")
.omitEmptyStrings() .omitEmptyStrings()
@@ -292,4 +293,22 @@ public class Text
return toString; return toString;
} }
/**
* Checks if all the search terms in the given list matches at least one keyword.
*
* @return true if all search terms matches at least one keyword, or false if otherwise.
*/
public static boolean matchesSearchTerms(String[] searchTerms, final Collection<String> keywords)
{
for (String term : searchTerms)
{
if (keywords.stream().noneMatch((t) -> t.contains(term) ||
DISTANCE.apply(t, term) > 0.9))
{
return false;
}
}
return true;
}
} }
@@ -124,6 +124,7 @@ public class WidgetID
public static final int WORLD_SWITCHER_GROUP_ID = 69; public static final int WORLD_SWITCHER_GROUP_ID = 69;
public static final int DIALOG_OPTION_GROUP_ID = 219; public static final int DIALOG_OPTION_GROUP_ID = 219;
public static final int DIALOG_PLAYER_GROUP_ID = 217; public static final int DIALOG_PLAYER_GROUP_ID = 217;
public static final int DRIFT_NET_FISHING_REWARD_GROUP_ID = 607;
public static final int FOSSIL_ISLAND_OXYGENBAR_ID = 609; public static final int FOSSIL_ISLAND_OXYGENBAR_ID = 609;
public static final int MINIGAME_TAB_ID = 76; public static final int MINIGAME_TAB_ID = 76;
public static final int SPELLBOOK_GROUP_ID = 218; public static final int SPELLBOOK_GROUP_ID = 218;
@@ -164,6 +165,9 @@ public class WidgetID
public static final int OPTIONS_GROUP_ID = 261; public static final int OPTIONS_GROUP_ID = 261;
public static final int THEATRE_OF_BLOOD_PARTY_GROUP_ID = 28; public static final int THEATRE_OF_BLOOD_PARTY_GROUP_ID = 28;
public static final int GWD_KC_GROUP_ID = 406; public static final int GWD_KC_GROUP_ID = 406;
public static final int ADVENTURE_LOG_ID = 187;
public static final int COUNTERS_LOG_GROUP_ID = 625;
public static final int GAUNTLET_TIMER_GROUP_ID = 637;
static class WorldMap static class WorldMap
{ {
@@ -726,6 +730,7 @@ public class WidgetID
static final int LIGHT_BOX = 1; static final int LIGHT_BOX = 1;
static final int LIGHT_BOX_WINDOW = 2; static final int LIGHT_BOX_WINDOW = 2;
static final int LIGHT_BULB_CONTAINER = 3; static final int LIGHT_BULB_CONTAINER = 3;
static final int LIGHT_BOX_BUTTON_CONTAINER = 6;
static final int BUTTON_A = 8; static final int BUTTON_A = 8;
static final int BUTTON_B = 9; static final int BUTTON_B = 9;
static final int BUTTON_C = 10; static final int BUTTON_C = 10;
@@ -1190,15 +1195,6 @@ public class WidgetID
static final int INVENTORY = 7; static final int INVENTORY = 7;
} }
static class Lms
{
static final int INFO = 3;
}
static class LmsKDA
{
static final int INFO = 4;
}
static class JewelBox static class JewelBox
{ {
@@ -1212,9 +1208,9 @@ public class WidgetID
static class Options static class Options
{ {
static final int MUSIC_SLIDER = 38; static final int MUSIC_SLIDER = 37;
static final int SOUND_EFFECT_SLIDER = 44; static final int SOUND_EFFECT_SLIDER = 43;
static final int AREA_SOUND_SLIDER = 50; static final int AREA_SOUND_SLIDER = 49;
} }
static class AchievementDiary static class AchievementDiary
@@ -1226,5 +1222,30 @@ public class WidgetID
{ {
static final int CONTAINER = 0; static final int CONTAINER = 0;
} }
static class Lms
{
static final int INFO = 3;
}
static class LmsKDA
{
static final int INFO = 5;
}
static class AdventureLog
{
static final int CONTAINER = 0;
}
static class CountersLog
{
static final int OWNER = 4;
static final int TEXT = 6;
}
static class GauntletTimer
{
static final int CONTAINER = 2;
}
} }
@@ -443,6 +443,7 @@ public enum WidgetInfo
LIGHT_BOX(WidgetID.LIGHT_BOX_GROUP_ID, WidgetID.LightBox.LIGHT_BOX), LIGHT_BOX(WidgetID.LIGHT_BOX_GROUP_ID, WidgetID.LightBox.LIGHT_BOX),
LIGHT_BOX_CONTENTS(WidgetID.LIGHT_BOX_GROUP_ID, WidgetID.LightBox.LIGHT_BULB_CONTAINER), LIGHT_BOX_CONTENTS(WidgetID.LIGHT_BOX_GROUP_ID, WidgetID.LightBox.LIGHT_BULB_CONTAINER),
LIGHT_BOX_BUTTON_CONTAINER(WidgetID.LIGHT_BOX_GROUP_ID, WidgetID.LightBox.LIGHT_BOX_BUTTON_CONTAINER),
LIGHT_BOX_BUTTON_A(WidgetID.LIGHT_BOX_GROUP_ID, WidgetID.LightBox.BUTTON_A), LIGHT_BOX_BUTTON_A(WidgetID.LIGHT_BOX_GROUP_ID, WidgetID.LightBox.BUTTON_A),
LIGHT_BOX_BUTTON_B(WidgetID.LIGHT_BOX_GROUP_ID, WidgetID.LightBox.BUTTON_B), LIGHT_BOX_BUTTON_B(WidgetID.LIGHT_BOX_GROUP_ID, WidgetID.LightBox.BUTTON_B),
LIGHT_BOX_BUTTON_C(WidgetID.LIGHT_BOX_GROUP_ID, WidgetID.LightBox.BUTTON_C), LIGHT_BOX_BUTTON_C(WidgetID.LIGHT_BOX_GROUP_ID, WidgetID.LightBox.BUTTON_C),
@@ -515,6 +516,10 @@ public enum WidgetInfo
KILL_LOG_KILLS(WidgetID.KILL_LOGS_GROUP_ID, WidgetID.KillLog.KILLS), KILL_LOG_KILLS(WidgetID.KILL_LOGS_GROUP_ID, WidgetID.KillLog.KILLS),
KILL_LOG_STREAK(WidgetID.KILL_LOGS_GROUP_ID, WidgetID.KillLog.STREAK), KILL_LOG_STREAK(WidgetID.KILL_LOGS_GROUP_ID, WidgetID.KillLog.STREAK),
ADVENTURE_LOG(WidgetID.ADVENTURE_LOG_ID, WidgetID.AdventureLog.CONTAINER),
COUNTERS_LOG_TEXT(WidgetID.COUNTERS_LOG_GROUP_ID, WidgetID.CountersLog.TEXT),
WORLD_SWITCHER_LIST(WidgetID.WORLD_SWITCHER_GROUP_ID, WidgetID.WorldSwitcher.WORLD_LIST), WORLD_SWITCHER_LIST(WidgetID.WORLD_SWITCHER_GROUP_ID, WidgetID.WorldSwitcher.WORLD_LIST),
FOSSIL_ISLAND_OXYGENBAR(WidgetID.FOSSIL_ISLAND_OXYGENBAR_ID, WidgetID.FossilOxygen.FOSSIL_ISLAND_OXYGEN_BAR), FOSSIL_ISLAND_OXYGENBAR(WidgetID.FOSSIL_ISLAND_OXYGENBAR_ID, WidgetID.FossilOxygen.FOSSIL_ISLAND_OXYGEN_BAR),
@@ -793,7 +798,9 @@ public enum WidgetInfo
SKILLS_CONTAINER(WidgetID.SKILLS_GROUP_ID, WidgetID.Skills.CONTAINER), SKILLS_CONTAINER(WidgetID.SKILLS_GROUP_ID, WidgetID.Skills.CONTAINER),
TRADING_WITH(WidgetID.PLAYER_TRADE_SCREEN_GROUP_ID, WidgetID.TradeScreen.FIRST_TRADING_WITH); TRADING_WITH(WidgetID.PLAYER_TRADE_SCREEN_GROUP_ID, WidgetID.TradeScreen.FIRST_TRADING_WITH),
GAUNTLET_TIMER_CONTAINER(WidgetID.GAUNTLET_TIMER_GROUP_ID, WidgetID.GauntletTimer.CONTAINER);
private final int groupId; private final int groupId;
private final int childId; private final int childId;
+3 -11
View File
@@ -41,6 +41,8 @@ dependencies {
annotationProcessor(Libraries.lombok) annotationProcessor(Libraries.lombok)
annotationProcessor(Libraries.pf4j) annotationProcessor(Libraries.pf4j)
api(project(":runelite-api"))
compileOnly(Libraries.javax) compileOnly(Libraries.javax)
compileOnly(Libraries.lombok) compileOnly(Libraries.lombok)
compileOnly(Libraries.orangeExtensions) compileOnly(Libraries.orangeExtensions)
@@ -66,14 +68,13 @@ dependencies {
implementation(Libraries.jooqCodegen) implementation(Libraries.jooqCodegen)
implementation(Libraries.jooqMeta) implementation(Libraries.jooqMeta)
implementation(Libraries.sentry) implementation(Libraries.sentry)
implementation(Libraries.semver)
implementation(Libraries.slf4jApi) implementation(Libraries.slf4jApi)
implementation(Libraries.pf4j) { implementation(Libraries.pf4j) {
exclude(group = "org.slf4j") exclude(group = "org.slf4j")
} }
implementation(Libraries.pf4jUpdate) implementation(Libraries.pf4jUpdate)
implementation(project(":http-api")) implementation(project(":http-api"))
api(project(":runelite-api"))
implementation(Libraries.naturalMouse)
runtimeOnly(Libraries.trident) runtimeOnly(Libraries.trident)
runtimeOnly(Libraries.jogampGluegenLinuxAmd64) runtimeOnly(Libraries.jogampGluegenLinuxAmd64)
@@ -105,16 +106,8 @@ fun formatDate(date: Date?) = with(date ?: Date()) {
SimpleDateFormat("MM-dd-yyyy").format(this) SimpleDateFormat("MM-dd-yyyy").format(this)
} }
fun launcherVersion(): String {
if (project.hasProperty("releaseBuild")) {
return ProjectVersions.launcherVersion
}
return "-1"
}
fun pluginPath(): String { fun pluginPath(): String {
if (project.hasProperty("pluginPath")) { if (project.hasProperty("pluginPath")) {
print(project.property("pluginPath").toString())
return project.property("pluginPath").toString() return project.property("pluginPath").toString()
} }
return "" return ""
@@ -135,7 +128,6 @@ tasks {
"rs.version" to ProjectVersions.rsversion.toString(), "rs.version" to ProjectVersions.rsversion.toString(),
"open.osrs.version" to ProjectVersions.openosrsVersion, "open.osrs.version" to ProjectVersions.openosrsVersion,
"open.osrs.builddate" to formatDate(Date()), "open.osrs.builddate" to formatDate(Date()),
"launcher.version" to launcherVersion(),
"plugin.path" to pluginPath() "plugin.path" to pluginPath()
) )
@@ -24,7 +24,7 @@
*/ */
package net.runelite.client; package net.runelite.client;
import io.reactivex.schedulers.Schedulers; import io.reactivex.rxjava3.schedulers.Schedulers;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.UUID; import java.util.UUID;
import javax.inject.Inject; import javax.inject.Inject;
@@ -30,8 +30,8 @@ import com.google.common.annotations.VisibleForTesting;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Injector; import com.google.inject.Injector;
import io.reactivex.Completable; import io.reactivex.rxjava3.core.Completable;
import io.reactivex.schedulers.Schedulers; import io.reactivex.rxjava3.schedulers.Schedulers;
import io.sentry.Sentry; import io.sentry.Sentry;
import io.sentry.SentryClient; import io.sentry.SentryClient;
import java.io.File; import java.io.File;
@@ -39,14 +39,18 @@ import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean; import java.lang.management.RuntimeMXBean;
import java.net.Authenticator; import java.net.Authenticator;
import java.net.PasswordAuthentication; import java.net.PasswordAuthentication;
import java.nio.file.Paths;
import java.util.Locale; import java.util.Locale;
import java.util.Optional; import java.util.Optional;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Provider; import javax.inject.Provider;
import javax.inject.Singleton; import javax.inject.Singleton;
import joptsimple.ArgumentAcceptingOptionSpec; import joptsimple.ArgumentAcceptingOptionSpec;
import joptsimple.OptionException;
import joptsimple.OptionParser; import joptsimple.OptionParser;
import joptsimple.OptionSet; import joptsimple.OptionSet;
import joptsimple.ValueConversionException;
import joptsimple.ValueConverter;
import joptsimple.util.EnumConverter; import joptsimple.util.EnumConverter;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -85,6 +89,7 @@ import net.runelite.client.ui.overlay.arrow.ArrowWorldOverlay;
import net.runelite.client.ui.overlay.infobox.InfoBoxOverlay; import net.runelite.client.ui.overlay.infobox.InfoBoxOverlay;
import net.runelite.client.ui.overlay.tooltip.TooltipOverlay; import net.runelite.client.ui.overlay.tooltip.TooltipOverlay;
import net.runelite.client.ui.overlay.worldmap.WorldMapOverlay; import net.runelite.client.ui.overlay.worldmap.WorldMapOverlay;
import net.runelite.client.util.AppLock;
import net.runelite.client.util.WorldUtil; import net.runelite.client.util.WorldUtil;
import net.runelite.client.ws.PartyService; import net.runelite.client.ws.PartyService;
import net.runelite.http.api.worlds.World; import net.runelite.http.api.worlds.World;
@@ -105,6 +110,7 @@ public class RuneLite
public static final File SCREENSHOT_DIR = new File(RUNELITE_DIR, "screenshots"); public static final File SCREENSHOT_DIR = new File(RUNELITE_DIR, "screenshots");
public static final File LOGS_DIR = new File(RUNELITE_DIR, "logs"); public static final File LOGS_DIR = new File(RUNELITE_DIR, "logs");
public static final File PLUGINS_DIR = new File(RUNELITE_DIR, "plugins"); public static final File PLUGINS_DIR = new File(RUNELITE_DIR, "plugins");
public static final File DEFAULT_CONFIG_FILE = new File(RUNELITE_DIR, "runeliteplus.properties");
public static final Locale SYSTEM_LOCALE = Locale.getDefault(); public static final Locale SYSTEM_LOCALE = Locale.getDefault();
public static boolean allowPrivateServer = false; public static boolean allowPrivateServer = false;
@@ -201,6 +207,9 @@ public class RuneLite
@Inject @Inject
private Scheduler scheduler; private Scheduler scheduler;
@Inject
private AppLock appLock;
public static void main(String[] args) throws Exception public static void main(String[] args) throws Exception
{ {
Locale.setDefault(Locale.ENGLISH); Locale.setDefault(Locale.ENGLISH);
@@ -215,6 +224,11 @@ public class RuneLite
final ArgumentAcceptingOptionSpec<Integer> worldInfo = parser final ArgumentAcceptingOptionSpec<Integer> worldInfo = parser
.accepts("world") .accepts("world")
.withRequiredArg().ofType(Integer.class); .withRequiredArg().ofType(Integer.class);
final ArgumentAcceptingOptionSpec<File> configfile = parser.accepts("config", "Use a specified config file")
.withRequiredArg()
.withValuesConvertedBy(new ConfigFileConverter())
.defaultsTo(DEFAULT_CONFIG_FILE);
final ArgumentAcceptingOptionSpec<ClientUpdateCheckMode> updateMode = parser final ArgumentAcceptingOptionSpec<ClientUpdateCheckMode> updateMode = parser
.accepts("rs", "Select client type") .accepts("rs", "Select client type")
.withRequiredArg() .withRequiredArg()
@@ -230,7 +244,18 @@ public class RuneLite
}); });
parser.accepts("help", "Show this text").forHelp(); parser.accepts("help", "Show this text").forHelp();
OptionSet options = parser.parse(args);
OptionSet options = parser.parse("");
try
{
options = parser.parse(args);
}
catch (OptionException e)
{
log.warn("Error parsing launch args: {}", e.getMessage());
log.warn("Proceeding with no arguments.");
}
if (options.has("help")) if (options.has("help"))
{ {
@@ -297,18 +322,6 @@ public class RuneLite
RuneLiteSplashScreen.init(); RuneLiteSplashScreen.init();
} }
final boolean developerMode = options.has("developer-mode");
if (developerMode)
{
boolean assertions = false;
assert assertions = true;
if (!assertions)
{
log.warn("Developers should enable assertions; Add `-ea` to your JVM arguments`");
}
}
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> Thread.setDefaultUncaughtExceptionHandler((thread, throwable) ->
{ {
log.error("Uncaught exception:", throwable); log.error("Uncaught exception:", throwable);
@@ -327,7 +340,7 @@ public class RuneLite
injector = Guice.createInjector(new RuneLiteModule( injector = Guice.createInjector(new RuneLiteModule(
clientLoader, clientLoader,
true)); options.valueOf(configfile)));
injector.getInstance(RuneLite.class).start(); injector.getInstance(RuneLite.class).start();
final long end = System.currentTimeMillis(); final long end = System.currentTimeMillis();
@@ -368,9 +381,11 @@ public class RuneLite
externalPluginManager.startExternalUpdateManager(); externalPluginManager.startExternalUpdateManager();
externalPluginManager.startExternalPluginManager(); externalPluginManager.startExternalPluginManager();
if (appLock.lock(this.getClass().getName()))
RuneLiteSplashScreen.stage(.59, "Updating external plugins"); {
externalPluginManager.update(); RuneLiteSplashScreen.stage(.59, "Updating external plugins");
externalPluginManager.update();
}
// Load the plugins, but does not start them yet. // Load the plugins, but does not start them yet.
// This will initialize configuration // This will initialize configuration
@@ -387,7 +402,7 @@ public class RuneLite
pluginManager.loadDefaultPluginConfiguration(); pluginManager.loadDefaultPluginConfiguration();
// Start client session // Start client session
RuneLiteSplashScreen.stage(.80, "Starting core interface"); RuneLiteSplashScreen.stage(.77, "Starting core interface");
clientSessionManager.start(); clientSessionManager.start();
//Set the world if specified via CLI args - will not work until clientUI.init is called //Set the world if specified via CLI args - will not work until clientUI.init is called
@@ -395,7 +410,7 @@ public class RuneLite
worldArg.ifPresent(this::setWorld); worldArg.ifPresent(this::setWorld);
// Initialize UI // Initialize UI
RuneLiteSplashScreen.stage(.77, "Initialize UI"); RuneLiteSplashScreen.stage(.80, "Initialize UI");
clientUI.init(this); clientUI.init(this);
// Initialize Discord service // Initialize Discord service
@@ -487,8 +502,47 @@ public class RuneLite
public void shutdown() public void shutdown()
{ {
configManager.sendConfig();
clientSessionManager.shutdown(); clientSessionManager.shutdown();
discordService.close(); discordService.close();
appLock.release();
}
private static class ConfigFileConverter implements ValueConverter<File>
{
@Override
public File convert(String fileName)
{
final File file;
if (Paths.get(fileName).isAbsolute()
|| fileName.startsWith("./")
|| fileName.startsWith(".\\"))
{
file = new File(fileName);
}
else
{
file = new File(RuneLite.RUNELITE_DIR, fileName);
}
if (file.exists() && (!file.isFile() || !file.canWrite()))
{
throw new ValueConversionException(String.format("File %s is not accessible", file.getAbsolutePath()));
}
return file;
}
@Override
public Class<? extends File> valueType()
{
return File.class;
}
@Override
public String valuePattern()
{
return null;
}
} }
} }
@@ -41,6 +41,7 @@ import net.runelite.client.callback.Hooks;
import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.config.ChatColorConfig; import net.runelite.client.config.ChatColorConfig;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.config.LauncherConfig;
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.EventBus; import net.runelite.client.eventbus.EventBus;
@@ -61,18 +62,18 @@ public class RuneLiteModule extends AbstractModule
private static final int MAX_OKHTTP_CACHE_SIZE = 20 * 1024 * 1024; // 20mb private static final int MAX_OKHTTP_CACHE_SIZE = 20 * 1024 * 1024; // 20mb
private final Supplier<Applet> clientLoader; private final Supplier<Applet> clientLoader;
private final boolean developerMode; private final File config;
public RuneLiteModule(final Supplier<Applet> clientLoader, boolean developerMode) public RuneLiteModule(final Supplier<Applet> clientLoader, File config)
{ {
this.clientLoader = clientLoader; this.clientLoader = clientLoader;
this.developerMode = developerMode; this.config = config;
} }
@Override @Override
protected void configure() protected void configure()
{ {
bindConstant().annotatedWith(Names.named("developerMode")).to(developerMode); bind(File.class).annotatedWith(Names.named("config")).toInstance(config);
bind(ScheduledExecutorService.class).toInstance(new ExecutorServiceExceptionLogger(Executors.newSingleThreadScheduledExecutor())); bind(ScheduledExecutorService.class).toInstance(new ExecutorServiceExceptionLogger(Executors.newSingleThreadScheduledExecutor()));
bind(OkHttpClient.class).toInstance(RuneLiteAPI.CLIENT.newBuilder() bind(OkHttpClient.class).toInstance(RuneLiteAPI.CLIENT.newBuilder()
.cache(new Cache(new File(RuneLite.CACHE_DIR, "okhttp"), MAX_OKHTTP_CACHE_SIZE)) .cache(new Cache(new File(RuneLite.CACHE_DIR, "okhttp"), MAX_OKHTTP_CACHE_SIZE))
@@ -132,4 +133,11 @@ public class RuneLiteModule extends AbstractModule
{ {
return configManager.getConfig(ChatColorConfig.class); return configManager.getConfig(ChatColorConfig.class);
} }
@Provides
@Singleton
LauncherConfig provideLauncherConfig(ConfigManager configManager)
{
return configManager.getConfig(LauncherConfig.class);
}
} }
@@ -136,8 +136,7 @@ public class RuneLiteProperties
@Nullable @Nullable
public static String getLauncherVersion() public static String getLauncherVersion()
{ {
String launcherVersion = properties.getProperty(LAUNCHER_VERSION_PROPERTY); return System.getProperty(LAUNCHER_VERSION_PROPERTY);
return launcherVersion.equals("-1") ? null : launcherVersion;
} }
@Nullable @Nullable
@@ -24,8 +24,8 @@
*/ */
package net.runelite.client; package net.runelite.client;
import io.reactivex.Completable; import io.reactivex.rxjava3.core.Completable;
import io.reactivex.Observable; import io.reactivex.rxjava3.core.Observable;
import java.io.IOException; import java.io.IOException;
import java.util.UUID; import java.util.UUID;
import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.RuneLiteAPI;
@@ -25,7 +25,7 @@
package net.runelite.client.account; package net.runelite.client.account;
import com.google.gson.Gson; import com.google.gson.Gson;
import io.reactivex.schedulers.Schedulers; import io.reactivex.rxjava3.schedulers.Schedulers;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileWriter; import java.io.FileWriter;
@@ -25,8 +25,8 @@
package net.runelite.client.callback; package net.runelite.client.callback;
import com.google.inject.Inject; import com.google.inject.Inject;
import io.reactivex.plugins.RxJavaPlugins; import io.reactivex.rxjava3.plugins.RxJavaPlugins;
import io.reactivex.schedulers.Schedulers; import io.reactivex.rxjava3.schedulers.Schedulers;
import java.util.Iterator; import java.util.Iterator;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
@@ -59,6 +59,7 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.coords.WorldPoint; import net.runelite.api.coords.WorldPoint;
@@ -75,20 +76,20 @@ import org.apache.commons.lang3.StringUtils;
@Slf4j @Slf4j
public class ConfigManager public class ConfigManager
{ {
private static final String SETTINGS_FILE_NAME = "runeliteplus.properties";
private static final String STANDARD_SETTINGS_FILE_NAME = "settings.properties"; private static final String STANDARD_SETTINGS_FILE_NAME = "settings.properties";
private static final File SETTINGS_FILE = new File(RuneLite.RUNELITE_DIR, SETTINGS_FILE_NAME);
private static final File STANDARD_SETTINGS_FILE = new File(RuneLite.RUNELITE_DIR, STANDARD_SETTINGS_FILE_NAME); private static final File STANDARD_SETTINGS_FILE = new File(RuneLite.RUNELITE_DIR, STANDARD_SETTINGS_FILE_NAME);
private final ConfigInvocationHandler handler = new ConfigInvocationHandler(this); private final ConfigInvocationHandler handler = new ConfigInvocationHandler(this);
private final Properties properties = new Properties(); private final Properties properties = new Properties();
private final Map<String, String> pendingChanges = new HashMap<>(); private final Map<String, String> pendingChanges = new HashMap<>();
private final File settingsFileInput;
@Inject @Inject
EventBus eventBus; EventBus eventBus;
@Inject @Inject
public ConfigManager(ScheduledExecutorService scheduledExecutorService) public ConfigManager(@Named("config") File config, ScheduledExecutorService scheduledExecutorService)
{ {
this.settingsFileInput = config;
scheduledExecutorService.scheduleWithFixedDelay(this::sendConfig, 30, 30, TimeUnit.SECONDS); scheduledExecutorService.scheduleWithFixedDelay(this::sendConfig, 30, 30, TimeUnit.SECONDS);
} }
@@ -414,7 +415,7 @@ public class ConfigManager
handler.invalidate(); handler.invalidate();
properties.clear(); properties.clear();
try (FileInputStream in = new FileInputStream(SETTINGS_FILE)) try (FileInputStream in = new FileInputStream(settingsFileInput))
{ {
properties.load(new InputStreamReader(in, StandardCharsets.UTF_8)); properties.load(new InputStreamReader(in, StandardCharsets.UTF_8));
} }
@@ -460,9 +461,9 @@ public class ConfigManager
private void saveToFile() throws IOException private void saveToFile() throws IOException
{ {
ConfigManager.SETTINGS_FILE.getParentFile().mkdirs(); settingsFileInput.getParentFile().mkdirs();
File tempFile = new File(RuneLite.RUNELITE_DIR, SETTINGS_FILE_NAME + ".tmp"); File tempFile = new File(RuneLite.RUNELITE_DIR, RuneLite.DEFAULT_CONFIG_FILE.getName() + ".tmp");
try (FileOutputStream out = new FileOutputStream(tempFile)) try (FileOutputStream out = new FileOutputStream(tempFile))
{ {
@@ -473,12 +474,12 @@ public class ConfigManager
try try
{ {
Files.move(tempFile.toPath(), ConfigManager.SETTINGS_FILE.toPath(), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE); Files.move(tempFile.toPath(), settingsFileInput.toPath(), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
} }
catch (AtomicMoveNotSupportedException ex) catch (AtomicMoveNotSupportedException ex)
{ {
log.debug("atomic move not supported", ex); log.debug("atomic move not supported", ex);
Files.move(tempFile.toPath(), ConfigManager.SETTINGS_FILE.toPath(), StandardCopyOption.REPLACE_EXISTING); Files.move(tempFile.toPath(), settingsFileInput.toPath(), StandardCopyOption.REPLACE_EXISTING);
} }
} }
@@ -0,0 +1,174 @@
/*
* Copyright (c) 2019 Owain van Brakel <https://github.com/Owain94>
* 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.config;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
@ConfigGroup("openosrs")
public interface LauncherConfig extends Config
{
@Getter(AccessLevel.PRIVATE)
@AllArgsConstructor
enum BootstrapMode
{
STABLE("Stable"),
NIGHTLY("Nightly");
private String name;
@Override
public String toString()
{
return getName();
}
}
@ConfigTitleSection(
keyName = "launcherTitle",
name = "Launcher",
description = "",
position = -1
)
default Title launcherTitle()
{
return new Title();
}
@ConfigTitleSection(
keyName = "updateChannelTitle",
name = "Update channel",
description = "",
position = 1,
titleSection = "launcherTitle"
)
default Title updateChannelTitle()
{
return new Title();
}
@ConfigItem(
position = 2,
keyName = "askMode",
name = "Prompt for update channel",
description = "Ask for nightly or stable every startup",
titleSection = "updateChannelTitle"
)
default boolean askMode()
{
return true;
}
@ConfigItem(
keyName = "bootstrapMode",
name = "Update channel",
description = "Select the update channel",
titleSection = "updateChannelTitle",
position = 3,
hide = "askMode"
)
default BootstrapMode bootstrapMode()
{
return BootstrapMode.STABLE;
}
@ConfigTitleSection(
keyName = "miscLauncherTitle",
name = "Miscellaneous",
description = "",
position = 4,
titleSection = "launcherTitle"
)
default Title miscLauncherTitle()
{
return new Title();
}
@ConfigItem(
position = 5,
keyName = "disableHw",
name = "Disable hardware acceleration",
description = "Enable this if you have graphical issues",
titleSection = "miscLauncherTitle",
warning = "Toggling this setting requires a restart of the client"
)
default boolean disableHw()
{
return false;
}
@ConfigTitleSection(
keyName = "advancedTitle",
name = "Advanced",
description = "",
position = 6,
titleSection = "launcherTitle"
)
default Title advancedTitle()
{
return new Title();
}
@ConfigItem(
position = 7,
keyName = "noJvm",
name = "Use system java (caution!)",
description = "Enable this if you want to make use of the system java version instead of the launcher bundled version",
titleSection = "advancedTitle",
warning = "Toggling this setting requires a restart of the client"
)
default boolean noJvm()
{
return false;
}
@ConfigItem(
position = 8,
keyName = "useProxy",
name = "Use SOCKS5 proxy",
description = "Enable the client to use a proxy",
titleSection = "advancedTitle",
warning = "Toggling this setting requires a restart of the client"
)
default boolean useProxy()
{
return false;
}
@ConfigItem(
keyName = "proxyDetails",
name = "Proxy details",
description = "The format for this field is ip:port or ip:port:user:pass",
titleSection = "advancedTitle",
position = 9,
hidden = true,
unhide = "useProxy"
)
default String proxyDetails()
{
return "";
}
}
@@ -31,7 +31,7 @@ import lombok.Value;
/** /**
* Represents Discord Rich Presence RPC data * Represents Discord Rich Presence RPC data
*/ */
@Builder @Builder(toBuilder = true)
@Value @Value
public class DiscordPresence public class DiscordPresence
{ {
@@ -1,7 +1,7 @@
package net.runelite.client.eventbus; package net.runelite.client.eventbus;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import io.reactivex.functions.Consumer; import io.reactivex.rxjava3.functions.Consumer;
import java.lang.invoke.CallSite; import java.lang.invoke.CallSite;
import java.lang.invoke.LambdaMetafactory; import java.lang.invoke.LambdaMetafactory;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
@@ -1,18 +1,18 @@
package net.runelite.client.eventbus; package net.runelite.client.eventbus;
import com.jakewharton.rxrelay2.PublishRelay; import com.jakewharton.rxrelay3.PublishRelay;
import com.jakewharton.rxrelay2.Relay; import com.jakewharton.rxrelay3.Relay;
import io.reactivex.ObservableTransformer; import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.Scheduler; import io.reactivex.rxjava3.core.ObservableTransformer;
import io.reactivex.annotations.NonNull; import io.reactivex.rxjava3.core.Scheduler;
import io.reactivex.annotations.Nullable; import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.disposables.CompositeDisposable; import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.disposables.Disposable; import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.functions.Consumer;
import io.sentry.Sentry; import io.sentry.Sentry;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -1,7 +1,7 @@
package net.runelite.client.eventbus; package net.runelite.client.eventbus;
import io.reactivex.annotations.NonNull; import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.functions.Consumer; import io.reactivex.rxjava3.functions.Consumer;
import net.runelite.api.events.Event; import net.runelite.api.events.Event;
public interface EventBusInterface public interface EventBusInterface
@@ -1,9 +1,9 @@
package net.runelite.client.eventbus; package net.runelite.client.eventbus;
import io.reactivex.Scheduler; import io.reactivex.rxjava3.core.Scheduler;
import io.reactivex.annotations.Nullable; import io.reactivex.rxjava3.functions.Supplier;
import io.reactivex.schedulers.Schedulers; import io.reactivex.rxjava3.schedulers.Schedulers;
import java.util.function.Supplier; import javax.annotation.Nullable;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@AllArgsConstructor @AllArgsConstructor
@@ -22,6 +22,14 @@ public enum EventScheduler
@Nullable @Nullable
public Scheduler get() public Scheduler get()
{ {
return scheduler.get(); try
{
return scheduler.get();
}
catch (Throwable ignored)
{
}
return null;
} }
} }
@@ -1,6 +1,6 @@
package net.runelite.client.eventbus; package net.runelite.client.eventbus;
import io.reactivex.functions.Consumer; import io.reactivex.rxjava3.functions.Consumer;
import lombok.Value; import lombok.Value;
@Value @Value
@@ -28,8 +28,8 @@ import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache; import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import io.reactivex.Completable; import io.reactivex.rxjava3.core.Completable;
import io.reactivex.schedulers.Schedulers; import io.reactivex.rxjava3.schedulers.Schedulers;
import java.awt.Color; import java.awt.Color;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.util.ArrayList; import java.util.ArrayList;
@@ -27,8 +27,8 @@ package net.runelite.client.game;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonReader;
import io.reactivex.Completable; import io.reactivex.rxjava3.core.Completable;
import io.reactivex.schedulers.Schedulers; import io.reactivex.rxjava3.schedulers.Schedulers;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@@ -28,11 +28,14 @@ package net.runelite.client.game.chatbox;
import com.google.common.primitives.Ints; import com.google.common.primitives.Ints;
import com.google.inject.Inject; import com.google.inject.Inject;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.function.Consumer; import java.util.function.Consumer;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.Getter; import lombok.Getter;
import lombok.Value;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.ItemDefinition; import net.runelite.api.ItemDefinition;
import net.runelite.api.widgets.ItemQuantityMode; import net.runelite.api.widgets.ItemQuantityMode;
@@ -66,6 +69,14 @@ public class ChatboxItemSearch extends ChatboxTextInput
@Getter @Getter
private Consumer<Integer> onItemSelected; private Consumer<Integer> onItemSelected;
@Value
private static class ItemIcon
{
private final int modelId;
private final short[] colorsToReplace;
private final short[] texturesToReplace;
}
@Inject @Inject
private ChatboxItemSearch(ChatboxPanelManager chatboxPanelManager, ClientThread clientThread, private ChatboxItemSearch(ChatboxPanelManager chatboxPanelManager, ClientThread clientThread,
ItemManager itemManager, Client client) ItemManager itemManager, Client client)
@@ -287,15 +298,26 @@ public class ChatboxItemSearch extends ChatboxTextInput
return; return;
} }
Set<ItemIcon> itemIcons = new HashSet<>();
for (int i = 0; i < client.getItemCount() && results.size() < MAX_RESULTS; i++) for (int i = 0; i < client.getItemCount() && results.size() < MAX_RESULTS; i++)
{ {
ItemDefinition itemComposition = itemManager.getItemDefinition(itemManager.canonicalize(i)); ItemDefinition itemComposition = itemManager.getItemDefinition(itemManager.canonicalize(i));
String name = itemComposition.getName().toLowerCase(); String name = itemComposition.getName().toLowerCase();
// The client assigns "null" to item names of items it doesn't know about // The client assigns "null" to item names of items it doesn't know about
if (!name.equals("null") && name.contains(search)) // and the item might already be in the results from canonicalize
if (!name.equals("null") && name.contains(search) && !results.containsKey(itemComposition.getId()))
{ {
// This may already be in the map due to canonicalize mapping the item to something we've already seen // Check if the results already contain the same item image
results.putIfAbsent(itemComposition.getId(), itemComposition); ItemIcon itemIcon = new ItemIcon(itemComposition.getInventoryModel(),
itemComposition.getColorToReplaceWith(), itemComposition.getTextureToReplaceWith());
if (itemIcons.contains(itemIcon))
{
continue;
}
itemIcons.add(itemIcon);
results.put(itemComposition.getId(), itemComposition);
} }
} }
} }
@@ -17,6 +17,7 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@@ -49,7 +50,9 @@ import net.runelite.client.config.OpenOSRSConfig;
import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.EventBus;
import net.runelite.client.events.ExternalPluginChanged; import net.runelite.client.events.ExternalPluginChanged;
import net.runelite.client.events.ExternalRepositoryChanged; import net.runelite.client.events.ExternalRepositoryChanged;
import net.runelite.client.ui.ClientUI;
import net.runelite.client.ui.RuneLiteSplashScreen; import net.runelite.client.ui.RuneLiteSplashScreen;
import net.runelite.client.util.MiscUtils;
import net.runelite.client.util.SwingUtil; import net.runelite.client.util.SwingUtil;
import org.pf4j.DefaultPluginManager; import org.pf4j.DefaultPluginManager;
import org.pf4j.DependencyResolver; import org.pf4j.DependencyResolver;
@@ -77,7 +80,7 @@ class ExternalPluginManager
{ {
public static ArrayList<ClassLoader> pluginClassLoaders = new ArrayList<>(); public static ArrayList<ClassLoader> pluginClassLoaders = new ArrayList<>();
private final PluginManager runelitePluginManager; private final PluginManager runelitePluginManager;
private final org.pf4j.PluginManager externalPluginManager; private org.pf4j.PluginManager externalPluginManager;
@Getter(AccessLevel.PUBLIC) @Getter(AccessLevel.PUBLIC)
private final List<UpdateRepository> repositories = new ArrayList<>(); private final List<UpdateRepository> repositories = new ArrayList<>();
private final OpenOSRSConfig openOSRSConfig; private final OpenOSRSConfig openOSRSConfig;
@@ -85,7 +88,6 @@ class ExternalPluginManager
private final ConfigManager configManager; private final ConfigManager configManager;
private final List<Plugin> plugins = new CopyOnWriteArrayList<>(); private final List<Plugin> plugins = new CopyOnWriteArrayList<>();
private final Map<String, String> pluginsMap = new HashMap<>(); private final Map<String, String> pluginsMap = new HashMap<>();
@Getter(AccessLevel.PUBLIC) @Getter(AccessLevel.PUBLIC)
private UpdateManager updateManager; private UpdateManager updateManager;
@@ -104,9 +106,16 @@ class ExternalPluginManager
//noinspection ResultOfMethodCallIgnored //noinspection ResultOfMethodCallIgnored
EXTERNALPLUGIN_DIR.mkdirs(); EXTERNALPLUGIN_DIR.mkdirs();
initPluginManager();
}
private void initPluginManager()
{
boolean debug = RuneLiteProperties.getLauncherVersion() == null && RuneLiteProperties.getPluginPath() != null; boolean debug = RuneLiteProperties.getLauncherVersion() == null && RuneLiteProperties.getPluginPath() != null;
this.externalPluginManager = new DefaultPluginManager(debug ? Paths.get(RuneLiteProperties.getPluginPath() + File.separator + "release") : EXTERNALPLUGIN_DIR.toPath()) this.externalPluginManager = new DefaultPluginManager(
debug ? Paths.get(RuneLiteProperties.getPluginPath() + File.separator + "release")
: EXTERNALPLUGIN_DIR.toPath())
{ {
@Override @Override
protected PluginDescriptorFinder createPluginDescriptorFinder() protected PluginDescriptorFinder createPluginDescriptorFinder()
@@ -117,7 +126,27 @@ class ExternalPluginManager
@Override @Override
protected PluginRepository createPluginRepository() protected PluginRepository createPluginRepository()
{ {
return new JarPluginRepository(getPluginsRoot()); return new JarPluginRepository(getPluginsRoot())
{
@Override
public List<Path> getPluginPaths()
{
File[] files = pluginsRoot.toFile().listFiles(filter);
if ((files == null) || files.length == 0)
{
return Collections.emptyList();
}
List<Path> paths = new ArrayList<>(files.length);
for (File file : files)
{
paths.add(file.toPath());
}
return paths;
}
};
} }
@Override @Override
@@ -184,22 +213,41 @@ class ExternalPluginManager
this.externalPluginManager.setSystemVersion(SYSTEM_VERSION); this.externalPluginManager.setSystemVersion(SYSTEM_VERSION);
} }
public boolean doesGhRepoExist(String owner, String name)
{
return doesRepoExist("gh:" + owner + "/" + name);
}
/**
* Note that {@link org.pf4j.update.UpdateManager#addRepository} checks if the repo exists, however it throws an exception which is bad
*/
public boolean doesRepoExist(String id)
{
return repositories.stream().anyMatch((repo) -> repo.getId().equals(id));
}
private static URL toRepositoryUrl(String owner, String name) throws MalformedURLException private static URL toRepositoryUrl(String owner, String name) throws MalformedURLException
{ {
return new URL("https://raw.githubusercontent.com/" + owner + "/" + name + "/master/"); return new URL("https://raw.githubusercontent.com/" + owner + "/" + name + "/master/");
} }
public static boolean testRepository(String owner, String name) public static boolean testGHRepository(String owner, String name)
{ {
final List<UpdateRepository> repositories = new ArrayList<>();
try try
{ {
repositories.add(new DefaultUpdateRepository("github", new URL("https://raw.githubusercontent.com/" + owner + "/" + name + "/master/"))); return testRepository(toRepositoryUrl(owner, name));
} }
catch (MalformedURLException e) catch (MalformedURLException e)
{ {
return true; e.printStackTrace();
} }
return false;
}
public static boolean testRepository(URL url)
{
final List<UpdateRepository> repositories = new ArrayList<>();
repositories.add(new DefaultUpdateRepository("repository-testing", url));
DefaultPluginManager testPluginManager = new DefaultPluginManager(EXTERNALPLUGIN_DIR.toPath()); DefaultPluginManager testPluginManager = new DefaultPluginManager(EXTERNALPLUGIN_DIR.toPath());
UpdateManager updateManager = new UpdateManager(testPluginManager, repositories); UpdateManager updateManager = new UpdateManager(testPluginManager, repositories);
@@ -238,9 +286,63 @@ class ExternalPluginManager
} }
public void startExternalUpdateManager() public void startExternalUpdateManager()
{
if (!tryLoadNewFormat())
{
loadOldFormat();
}
this.updateManager = new UpdateManager(this.externalPluginManager, repositories);
saveConfig();
}
public boolean tryLoadNewFormat()
{ {
try try
{ {
for (String keyval : openOSRSConfig.getExternalRepositories().split(";"))
{
String[] split = keyval.split("\\|");
if (split.length != 2)
{
repositories.clear();
return false;
}
String id = split[0];
String url = split[1];
if (!url.endsWith("/"))
{
url = url.concat("/");
}
if (id.contains("https://raw.githubusercontent.com/"))
{
id = "gh:" + id.substring(id.indexOf("https://raw.githubusercontent.com/")).replace("/master", "")
.replace("https://raw.githubusercontent.com/", "");
if (id.endsWith("/"))
{
id = id.substring(0, id.lastIndexOf("/"));
}
}
repositories.add(new DefaultUpdateRepository(id, new URL(url)));
}
}
catch (ArrayIndexOutOfBoundsException | MalformedURLException e)
{
repositories.clear();
return false;
}
return true;
}
public void loadOldFormat()
{
try
{
repositories.clear();
for (String keyval : openOSRSConfig.getExternalRepositories().split(";")) for (String keyval : openOSRSConfig.getExternalRepositories().split(";"))
{ {
String id = keyval.substring(0, keyval.lastIndexOf(":https")); String id = keyval.substring(0, keyval.lastIndexOf(":https"));
@@ -262,14 +364,11 @@ class ExternalPluginManager
this.updateManager = new UpdateManager(this.externalPluginManager, repositories); this.updateManager = new UpdateManager(this.externalPluginManager, repositories);
} }
public void addRepository(String owner, String name) public void addGHRepository(String owner, String name)
{ {
try try
{ {
DefaultUpdateRepository respository = new DefaultUpdateRepository(owner + toRepositoryUrl(owner, name), toRepositoryUrl(owner, name)); addRepository("gh:" + owner + "/" + name, toRepositoryUrl(owner, name));
updateManager.addRepository(respository);
eventBus.post(ExternalRepositoryChanged.class, new ExternalRepositoryChanged(owner + toRepositoryUrl(owner, name), true));
saveConfig();
} }
catch (MalformedURLException e) catch (MalformedURLException e)
{ {
@@ -277,6 +376,14 @@ class ExternalPluginManager
} }
} }
public void addRepository(String key, URL url)
{
DefaultUpdateRepository respository = new DefaultUpdateRepository(key, url);
updateManager.addRepository(respository);
eventBus.post(ExternalRepositoryChanged.class, new ExternalRepositoryChanged(key, true));
saveConfig();
}
public void removeRepository(String owner) public void removeRepository(String owner)
{ {
updateManager.removeRepository(owner); updateManager.removeRepository(owner);
@@ -291,8 +398,8 @@ class ExternalPluginManager
for (UpdateRepository repository : updateManager.getRepositories()) for (UpdateRepository repository : updateManager.getRepositories())
{ {
config.append(repository.getId()); config.append(repository.getId());
config.append(":"); config.append("|");
config.append(repository.getUrl().toString()); config.append(MiscUtils.urlToStringEncoded(repository.getUrl()));
config.append(";"); config.append(";");
} }
config.deleteCharAt(config.lastIndexOf(";")); config.deleteCharAt(config.lastIndexOf(";"));
@@ -333,7 +440,8 @@ class ExternalPluginManager
} }
else if (pluginDescriptor.type() == PluginType.EXTERNAL) else if (pluginDescriptor.type() == PluginType.EXTERNAL)
{ {
log.error("Class {} is using the the new external plugin loader, it should not use PluginType.EXTERNAL", clazz); log.error("Class {} is using the the new external plugin loader, it should not use PluginType.EXTERNAL",
clazz);
continue; continue;
} }
@@ -373,16 +481,21 @@ class ExternalPluginManager
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private Plugin instantiate(List<Plugin> scannedPlugins, Class<Plugin> clazz, boolean init, boolean initConfig) throws PluginInstantiationException private Plugin instantiate(List<Plugin> scannedPlugins, Class<Plugin> clazz, boolean init, boolean initConfig)
throws PluginInstantiationException
{ {
net.runelite.client.plugins.PluginDependency[] pluginDependencies = clazz.getAnnotationsByType(net.runelite.client.plugins.PluginDependency.class); net.runelite.client.plugins.PluginDependency[] pluginDependencies =
clazz.getAnnotationsByType(net.runelite.client.plugins.PluginDependency.class);
List<Plugin> deps = new ArrayList<>(); List<Plugin> deps = new ArrayList<>();
for (net.runelite.client.plugins.PluginDependency pluginDependency : pluginDependencies) for (net.runelite.client.plugins.PluginDependency pluginDependency : pluginDependencies)
{ {
Optional<Plugin> dependency = Stream.concat(runelitePluginManager.getPlugins().stream(), scannedPlugins.stream()).filter(p -> p.getClass() == pluginDependency.value()).findFirst(); Optional<Plugin> dependency =
Stream.concat(runelitePluginManager.getPlugins().stream(), scannedPlugins.stream())
.filter(p -> p.getClass() == pluginDependency.value()).findFirst();
if (!dependency.isPresent()) if (!dependency.isPresent())
{ {
throw new PluginInstantiationException("Unmet dependency for " + clazz.getSimpleName() + ": " + pluginDependency.value().getSimpleName()); throw new PluginInstantiationException(
"Unmet dependency for " + clazz.getSimpleName() + ": " + pluginDependency.value().getSimpleName());
} }
deps.add(dependency.get()); deps.add(dependency.get());
} }
@@ -444,7 +557,9 @@ class ExternalPluginManager
{ {
runelitePluginManager.startPlugin(plugin); runelitePluginManager.startPlugin(plugin);
runelitePluginManager.add(plugin); runelitePluginManager.add(plugin);
eventBus.post(ExternalPluginChanged.class, new ExternalPluginChanged(pluginsMap.get(plugin.getClass().getSimpleName()), plugin, true)); eventBus.post(ExternalPluginChanged.class,
new ExternalPluginChanged(pluginsMap.get(plugin.getClass().getSimpleName()), plugin,
true));
} }
catch (PluginInstantiationException e) catch (PluginInstantiationException e)
{ {
@@ -479,6 +594,21 @@ class ExternalPluginManager
for (PluginWrapper plugin : startedPlugins) for (PluginWrapper plugin : startedPlugins)
{ {
boolean depsLoaded = true;
for (PluginDependency dependency : plugin.getDescriptor().getDependencies())
{
if (startedPlugins.stream().noneMatch(pl -> pl.getPluginId().equals(dependency.getPluginId())))
{
depsLoaded = false;
}
}
if (!depsLoaded)
{
// This should never happen but can crash the client
continue;
}
scannedPlugins.addAll(loadPlugin(plugin.getPluginId())); scannedPlugins.addAll(loadPlugin(plugin.getPluginId()));
} }
@@ -630,7 +760,7 @@ class ExternalPluginManager
try try
{ {
SwingUtil.syncExec(() -> SwingUtil.syncExec(() ->
JOptionPane.showMessageDialog(null, JOptionPane.showMessageDialog(ClientUI.getFrame(),
pluginId + " is outdated and cannot be installed", pluginId + " is outdated and cannot be installed",
"Installation error", "Installation error",
JOptionPane.ERROR_MESSAGE)); JOptionPane.ERROR_MESSAGE));
@@ -678,6 +808,7 @@ class ExternalPluginManager
public void update() public void update()
{ {
boolean error = false;
if (updateManager.hasUpdates()) if (updateManager.hasUpdates())
{ {
List<PluginInfo> updates = updateManager.getUpdates(); List<PluginInfo> updates = updateManager.getUpdates();
@@ -692,14 +823,24 @@ class ExternalPluginManager
if (!updated) if (!updated)
{ {
log.warn("Cannot update plugin '{}'", plugin.id); log.warn("Cannot update plugin '{}'", plugin.id);
error = true;
} }
} }
catch (PluginRuntimeException ex) catch (PluginRuntimeException ex)
{ {
log.warn("Cannot update plugin '{}', the user probably has another client open", plugin.id); log.warn("Cannot update plugin '{}', the user probably has another client open", plugin.id);
error = true;
break;
} }
} }
} }
if (error)
{
initPluginManager();
startExternalUpdateManager();
startExternalPluginManager();
}
} }
public Set<String> getDependencies() public Set<String> getDependencies()
@@ -28,7 +28,7 @@ import com.google.common.collect.ImmutableSet;
import com.google.inject.Binder; import com.google.inject.Binder;
import com.google.inject.Injector; import com.google.inject.Injector;
import com.google.inject.Module; import com.google.inject.Module;
import io.reactivex.functions.Consumer; import io.reactivex.rxjava3.functions.Consumer;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Set; import java.util.Set;
import lombok.AccessLevel; import lombok.AccessLevel;
@@ -53,8 +53,6 @@ public @interface PluginDescriptor
*/ */
boolean hidden() default false; boolean hidden() default false;
boolean developerPlugin() default false;
boolean loadWhenOutdated() default false; boolean loadWhenOutdated() default false;
PluginType type() default PluginType.UNCATEGORIZED; PluginType type() default PluginType.UNCATEGORIZED;
@@ -56,7 +56,6 @@ import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider; import javax.inject.Provider;
import javax.inject.Singleton; import javax.inject.Singleton;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
@@ -87,7 +86,6 @@ public class PluginManager
*/ */
private static final String PLUGIN_PACKAGE = "net.runelite.client.plugins"; private static final String PLUGIN_PACKAGE = "net.runelite.client.plugins";
private final boolean developerMode;
private final EventBus eventBus; private final EventBus eventBus;
private final Scheduler scheduler; private final Scheduler scheduler;
private final ConfigManager configManager; private final ConfigManager configManager;
@@ -108,13 +106,11 @@ public class PluginManager
@Inject @Inject
@VisibleForTesting @VisibleForTesting
PluginManager( PluginManager(
@Named("developerMode") final boolean developerMode,
final EventBus eventBus, final EventBus eventBus,
final Scheduler scheduler, final Scheduler scheduler,
final ConfigManager configManager, final ConfigManager configManager,
final Provider<GameEventManager> sceneTileManager) final Provider<GameEventManager> sceneTileManager)
{ {
this.developerMode = developerMode;
this.eventBus = eventBus; this.eventBus = eventBus;
this.scheduler = scheduler; this.scheduler = scheduler;
this.configManager = configManager; this.configManager = configManager;
@@ -355,11 +351,6 @@ public class PluginManager
continue; continue;
} }
if (pluginDescriptor.developerPlugin() && !developerMode)
{
continue;
}
@SuppressWarnings("unchecked") Class<Plugin> pluginClass = (Class<Plugin>) clazz; @SuppressWarnings("unchecked") Class<Plugin> pluginClass = (Class<Plugin>) clazz;
graph.addNode(pluginClass); graph.addNode(pluginClass);
} }
@@ -462,10 +453,12 @@ public class PluginManager
} }
catch (ThreadDeath e) catch (ThreadDeath e)
{ {
activePlugins.remove(plugin);
throw e; throw e;
} }
catch (Throwable ex) catch (Throwable ex)
{ {
activePlugins.remove(plugin);
throw new PluginInstantiationException(ex); throw new PluginInstantiationException(ex);
} }
@@ -41,7 +41,6 @@ import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;
@@ -672,11 +671,7 @@ class ConfigPanel extends PluginPanel
if (units != null) if (units != null)
{ {
DecimalFormat df = ((JSpinner.NumberEditor) spinner.getEditor()).getFormat(); spinnerTextField.setFormatterFactory(new UnitFormatterFactory(units));
df.setPositiveSuffix(units.value());
df.setNegativeSuffix(units.value());
// Force update the spinner to have it add the units initially
spinnerTextField.setValue(value);
} }
item.add(spinner, BorderLayout.EAST); item.add(spinner, BorderLayout.EAST);
@@ -812,11 +807,7 @@ class ConfigPanel extends PluginPanel
if (units != null) if (units != null)
{ {
DecimalFormat df = ((JSpinner.NumberEditor) widthSpinner.getEditor()).getFormat(); widthSpinnerTextField.setFormatterFactory(new UnitFormatterFactory(units));
df.setPositiveSuffix(units.value());
df.setNegativeSuffix(units.value());
// Force update the spinner to have it add the units initially
widthSpinnerTextField.setValue(width);
} }
SpinnerModel heightModel = new SpinnerNumberModel(height, 0, Integer.MAX_VALUE, 1); SpinnerModel heightModel = new SpinnerNumberModel(height, 0, Integer.MAX_VALUE, 1);
@@ -827,11 +818,7 @@ class ConfigPanel extends PluginPanel
if (units != null) if (units != null)
{ {
DecimalFormat df = ((JSpinner.NumberEditor) heightSpinner.getEditor()).getFormat(); heightSpinnerTextField.setFormatterFactory(new UnitFormatterFactory(units));
df.setPositiveSuffix(units.value());
df.setNegativeSuffix(units.value());
// Force update the spinner to have it add the units initially
heightSpinnerTextField.setValue(height);
} }
ChangeListener listener = e -> ChangeListener listener = e ->
@@ -24,13 +24,16 @@
*/ */
package net.runelite.client.plugins.config; package net.runelite.client.plugins.config;
import com.github.zafarkhaja.semver.Version;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Provider; 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.RuneLiteProperties;
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.LauncherConfig;
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;
@@ -69,6 +72,9 @@ public class ConfigPlugin extends Plugin
@Inject @Inject
private ChatColorConfig chatColorConfig; private ChatColorConfig chatColorConfig;
@Inject
private LauncherConfig launcherConfig;
private PluginListPanel pluginListPanel; private PluginListPanel pluginListPanel;
private NavigationButton navButton; private NavigationButton navButton;
@@ -92,6 +98,18 @@ public class ConfigPlugin extends Plugin
"Chat Color", "Recolor chat text", PluginType.MISCELLANEOUS, new String[]{"colour", "messages"}, "Chat Color", "Recolor chat text", PluginType.MISCELLANEOUS, new String[]{"colour", "messages"},
null, chatColorConfig, configManager.getConfigDescriptor(chatColorConfig) null, chatColorConfig, configManager.getConfigDescriptor(chatColorConfig)
)); ));
// Support for this has been added in launcher version 2.2.0
if (launcherVersion("2.2.0"))
{
pluginListPanel.addFakePlugin(
new PluginConfigurationDescriptor(
"Launcher", "Launcher settings", PluginType.IMPORTANT,
new String[]{"hw", "nightly", "stable", "proxy", "bootstrap"},
null, launcherConfig, configManager.getConfigDescriptor(launcherConfig)
));
}
pluginListPanel.rebuildPluginList(); pluginListPanel.rebuildPluginList();
final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "config_icon.png"); final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "config_icon.png");
@@ -137,4 +155,16 @@ public class ConfigPlugin extends Plugin
}); });
} }
} }
private boolean launcherVersion(String version)
{
String launcherVersion = RuneLiteProperties.getLauncherVersion();
if (launcherVersion == null)
{
return false;
}
return Version.valueOf(launcherVersion).greaterThanOrEqualTo(Version.valueOf(version));
}
} }
@@ -45,12 +45,9 @@ import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.PluginPanel; import net.runelite.client.ui.PluginPanel;
import net.runelite.client.util.ImageUtil; import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.SwingUtil; import net.runelite.client.util.SwingUtil;
import org.apache.commons.text.similarity.JaroWinklerDistance;
public class PluginListItem extends JPanel public class PluginListItem extends JPanel
{ {
private static final JaroWinklerDistance DISTANCE = new JaroWinklerDistance();
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_STAR; private static final ImageIcon ON_STAR;
@@ -61,6 +58,7 @@ public class PluginListItem extends JPanel
@Getter @Getter
private final PluginConfigurationDescriptor pluginConfig; private final PluginConfigurationDescriptor pluginConfig;
@Getter
private final List<String> keywords = new ArrayList<>(); private final List<String> keywords = new ArrayList<>();
public JLabel nameLabel; public JLabel nameLabel;
@@ -201,24 +199,6 @@ public class PluginListItem extends JPanel
onOffToggle.setSelected(enabled); onOffToggle.setSelected(enabled);
} }
/**
* Checks if all the search terms in the given list matches at least one keyword.
*
* @return true if all search terms matches at least one keyword, or false if otherwise.
*/
boolean matchesSearchTerms(String[] searchTerms)
{
for (String term : searchTerms)
{
if (keywords.stream().noneMatch((t) -> t.contains(term) ||
DISTANCE.apply(t, term) > 0.9))
{
return false;
}
}
return true;
}
private void openGroupConfigPanel() private void openGroupConfigPanel()
{ {
pluginListPanel.openConfigurationPanel(pluginConfig); pluginListPanel.openConfigurationPanel(pluginConfig);
@@ -381,7 +381,7 @@ public class PluginListPanel extends PluginPanel
final String[] searchTerms = text.toLowerCase().split(" "); final String[] searchTerms = text.toLowerCase().split(" ");
pluginList.forEach(listItem -> pluginList.forEach(listItem ->
{ {
if (pinned == listItem.isPinned() && listItem.matchesSearchTerms(searchTerms)) if (pinned == listItem.isPinned() && Text.matchesSearchTerms(searchTerms, listItem.getKeywords()))
{ {
if (openOSRSConfig.pluginSortMode() == OpenOSRSConfig.SortStyle.ALPHABETICALLY || !openOSRSConfig.enableCategories()) if (openOSRSConfig.pluginSortMode() == OpenOSRSConfig.SortStyle.ALPHABETICALLY || !openOSRSConfig.enableCategories())
{ {
@@ -0,0 +1,86 @@
/*
* Copyright (c) 2020, Hydrox6 <ikada@protonmail.ch>
* 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.text.ParseException;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JFormattedTextField;
import lombok.RequiredArgsConstructor;
import net.runelite.client.config.Units;
final class UnitFormatter extends JFormattedTextField.AbstractFormatter
{
private final String units;
UnitFormatter(Units units)
{
this.units = units.value();
}
@Override
public Object stringToValue(final String text) throws ParseException
{
final String trimmedText;
// Using the spinner controls causes the value to have the unit on the end, so remove it
if (text.endsWith(units))
{
trimmedText = text.substring(0, text.length() - units.length());
}
else
{
trimmedText = text;
}
try
{
return Integer.valueOf(trimmedText);
}
catch (NumberFormatException e)
{
throw new ParseException(trimmedText + " is not an integer.", 0);
}
}
@Override
public String valueToString(final Object value)
{
return value + units;
}
}
@RequiredArgsConstructor
final class UnitFormatterFactory extends JFormattedTextField.AbstractFormatterFactory
{
private final Units units;
private final Map<JFormattedTextField, JFormattedTextField.AbstractFormatter> formatters = new HashMap<>();
@Override
public JFormattedTextField.AbstractFormatter getFormatter(final JFormattedTextField tf)
{
return formatters.computeIfAbsent(tf, (key) -> new UnitFormatter(units));
}
}
@@ -79,11 +79,14 @@ class InfoPanel extends PluginPanel
} }
private JPanel syncPanel; private JPanel syncPanel;
@Inject @Inject
@Nullable @Nullable
private Client client; private Client client;
@Inject @Inject
private ConfigManager configManager; private ConfigManager configManager;
@Inject @Inject
private InfoPlugin plugin; private InfoPlugin plugin;
@@ -104,8 +107,12 @@ class InfoPanel extends PluginPanel
JLabel version = new JLabel(htmlLabel("RuneLite version: ", RuneLiteProperties.getVersion())); JLabel version = new JLabel(htmlLabel("RuneLite version: ", RuneLiteProperties.getVersion()));
version.setFont(smallFont); version.setFont(smallFont);
JLabel plusVersion = new JLabel(htmlLabel("OpenOSRS version: ", RuneLiteProperties.getPlusVersion())); JLabel openOsrsVersion = new JLabel(htmlLabel("OpenOSRS version: ", RuneLiteProperties.getPlusVersion()));
plusVersion.setFont(smallFont); openOsrsVersion.setFont(smallFont);
String launcher = RuneLiteProperties.getLauncherVersion();
JLabel launcherVersion = new JLabel(htmlLabel("Launcher version: ", launcher));
launcherVersion.setFont(smallFont);
JLabel revision = new JLabel(); JLabel revision = new JLabel();
revision.setFont(smallFont); revision.setFont(smallFont);
@@ -119,7 +126,11 @@ class InfoPanel extends PluginPanel
revision.setText(htmlLabel("Oldschool revision: ", engineVer)); revision.setText(htmlLabel("Oldschool revision: ", engineVer));
versionPanel.add(version); versionPanel.add(version);
versionPanel.add(plusVersion); versionPanel.add(openOsrsVersion);
if (launcher != null)
{
versionPanel.add(launcherVersion);
}
versionPanel.add(revision); versionPanel.add(revision);
JPanel actionsContainer = new JPanel(); JPanel actionsContainer = new JPanel();
@@ -6,6 +6,8 @@ import java.awt.Dimension;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import javax.inject.Inject; import javax.inject.Inject;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
@@ -18,23 +20,28 @@ import javax.swing.JTextField;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;
import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.EventBus;
import net.runelite.client.plugins.ExternalPluginManager; import net.runelite.client.plugins.ExternalPluginManager;
import net.runelite.client.ui.ClientUI;
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.util.ImageUtil; import net.runelite.client.util.ImageUtil;
public class ExternalPluginManagerPanel extends PluginPanel public class ExternalPluginManagerPanel extends PluginPanel
{ {
private static final ImageIcon ADD_ICON; private static final ImageIcon ADD_ICON_RAW;
private static final ImageIcon ADD_HOVER_ICON; private static final ImageIcon ADD_HOVER_ICON_RAW;
private static final ImageIcon ADD_ICON_GH;
private static final ImageIcon ADD_HOVER_ICON_GH;
static static
{ {
final BufferedImage addIcon = final BufferedImage addIconRaw =
ImageUtil.recolorImage( ImageUtil.getResourceStreamFromClass(ExternalPluginManagerPanel.class, "add_raw_icon.png");
ImageUtil.getResourceStreamFromClass(ExternalPluginManagerPanel.class, "add_icon.png"), ColorScheme.BRAND_BLUE final BufferedImage addIconGh = ImageUtil
); .resizeImage(ImageUtil.getResourceStreamFromClass(ExternalPluginManagerPanel.class, "gh_icon.png"), 14, 14);
ADD_ICON = new ImageIcon(addIcon); ADD_ICON_RAW = new ImageIcon(addIconRaw);
ADD_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(addIcon, 0.53f)); ADD_HOVER_ICON_RAW = new ImageIcon(ImageUtil.alphaOffset(addIconRaw, 0.53f));
ADD_ICON_GH = new ImageIcon(addIconGh);
ADD_HOVER_ICON_GH = new ImageIcon(ImageUtil.alphaOffset(addIconGh, 0.53f));
} }
private final ExternalPluginManager externalPluginManager; private final ExternalPluginManager externalPluginManager;
@@ -73,13 +80,17 @@ public class ExternalPluginManagerPanel extends PluginPanel
titlePanel.setBorder(new EmptyBorder(10, 10, 10, 10)); titlePanel.setBorder(new EmptyBorder(10, 10, 10, 10));
JLabel title = new JLabel(); JLabel title = new JLabel();
JLabel addRepo = new JLabel(ADD_ICON); JLabel addGHRepo = new JLabel(ADD_ICON_GH);
JLabel addRawRepo = new JLabel(ADD_ICON_RAW);
JPanel buttonHolder = new JPanel(new BorderLayout());
buttonHolder.setBorder(new EmptyBorder(0, 0, 0, 0));
title.setText("External Plugin Manager"); title.setText("External Plugin Manager");
title.setForeground(Color.WHITE); title.setForeground(Color.WHITE);
addRepo.setToolTipText("Add new repository"); addGHRepo.setToolTipText("Add new GitHub repository");
addRepo.addMouseListener(new MouseAdapter() addGHRepo.addMouseListener(new MouseAdapter()
{ {
@Override @Override
public void mousePressed(MouseEvent mouseEvent) public void mousePressed(MouseEvent mouseEvent)
@@ -91,36 +102,120 @@ public class ExternalPluginManagerPanel extends PluginPanel
"Github Repository name:", name "Github Repository name:", name
}; };
int option = JOptionPane.showConfirmDialog(null, message, "Add repository", JOptionPane.OK_CANCEL_OPTION); int option =
JOptionPane.showConfirmDialog(ClientUI.getFrame(), message, "Add repository", JOptionPane.OK_CANCEL_OPTION);
if (option != JOptionPane.OK_OPTION || owner.getText().equals("") || name.getText().equals("")) if (option != JOptionPane.OK_OPTION || owner.getText().equals("") || name.getText().equals(""))
{ {
return; return;
} }
if (ExternalPluginManager.testRepository(owner.getText(), name.getText())) if (externalPluginManager.doesGhRepoExist(owner.getText(), name.getText()))
{ {
JOptionPane.showMessageDialog(null, "This doesn't appear to be a valid repository.", "Error!", JOptionPane.ERROR_MESSAGE); JOptionPane.showMessageDialog(ClientUI.getFrame(), "This repository already exists.", "Error!",
JOptionPane.ERROR_MESSAGE);
return; return;
} }
externalPluginManager.addRepository(owner.getText(), name.getText()); if (ExternalPluginManager.testGHRepository(owner.getText(), name.getText()))
{
JOptionPane.showMessageDialog(ClientUI.getFrame(), "This doesn't appear to be a valid repository.", "Error!",
JOptionPane.ERROR_MESSAGE);
return;
}
externalPluginManager.addGHRepository(owner.getText(), name.getText());
} }
@Override @Override
public void mouseEntered(MouseEvent mouseEvent) public void mouseEntered(MouseEvent mouseEvent)
{ {
addRepo.setIcon(ADD_HOVER_ICON); addGHRepo.setIcon(ADD_HOVER_ICON_GH);
} }
@Override @Override
public void mouseExited(MouseEvent mouseEvent) public void mouseExited(MouseEvent mouseEvent)
{ {
addRepo.setIcon(ADD_ICON); addGHRepo.setIcon(ADD_ICON_GH);
} }
}); });
addGHRepo.setBorder(new EmptyBorder(0, 3, 0, 0));
addRawRepo.setToolTipText("Add new raw repository");
addRawRepo.addMouseListener(new MouseAdapter()
{
@Override
public void mousePressed(MouseEvent mouseEvent)
{
JTextField id = new JTextField();
JTextField url = new JTextField();
Object[] message = {
"Repository ID:", id,
"Repository URL:", url
};
int option =
JOptionPane.showConfirmDialog(ClientUI.getFrame(), message, "Add repository", JOptionPane.OK_CANCEL_OPTION);
if (option != JOptionPane.OK_OPTION || id.getText().equals("") || url.getText().equals(""))
{
return;
}
if (id.getText().startsWith("gh:") || id.getText().contains("|"))
{
JOptionPane.showMessageDialog(ClientUI.getFrame(),
"Repository id cannot begin with \"gh:\"\nor contain the pipe character '|'.", "Error!",
JOptionPane.ERROR_MESSAGE);
return;
}
if (externalPluginManager.doesRepoExist(id.getText()))
{
JOptionPane.showMessageDialog(ClientUI.getFrame(),
String.format("The repository with id %s already exists.", id.getText()), "Error!",
JOptionPane.ERROR_MESSAGE);
return;
}
URL urlActual;
try
{
urlActual = new URL(url.getText());
}
catch (MalformedURLException e)
{
JOptionPane.showMessageDialog(ClientUI.getFrame(), "This doesn't appear to be a valid repository.", "Error!",
JOptionPane.ERROR_MESSAGE);
return;
}
if (ExternalPluginManager.testRepository(urlActual))
{
JOptionPane.showMessageDialog(ClientUI.getFrame(), "This doesn't appear to be a valid repository.", "Error!",
JOptionPane.ERROR_MESSAGE);
return;
}
externalPluginManager.addRepository(id.getText(), urlActual);
}
@Override
public void mouseEntered(MouseEvent mouseEvent)
{
addRawRepo.setIcon(ADD_HOVER_ICON_RAW);
}
@Override
public void mouseExited(MouseEvent mouseEvent)
{
addRawRepo.setIcon(ADD_ICON_RAW);
}
});
addRawRepo.setBorder(new EmptyBorder(0, 0, 0, 3));
titlePanel.add(title, BorderLayout.WEST); titlePanel.add(title, BorderLayout.WEST);
titlePanel.add(addRepo, BorderLayout.EAST); buttonHolder.add(addRawRepo, BorderLayout.WEST);
buttonHolder.add(addGHRepo, BorderLayout.EAST);
titlePanel.add(buttonHolder, BorderLayout.EAST);
return titlePanel; return titlePanel;
} }
@@ -30,11 +30,13 @@ import javax.swing.SwingConstants;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import static net.runelite.api.util.Text.DISTANCE;
import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.EventBus;
import net.runelite.client.events.ExternalPluginChanged; import net.runelite.client.events.ExternalPluginChanged;
import net.runelite.client.events.ExternalRepositoryChanged; import net.runelite.client.events.ExternalRepositoryChanged;
import net.runelite.client.plugins.ExternalPluginManager; import net.runelite.client.plugins.ExternalPluginManager;
import static net.runelite.client.plugins.openosrs.externals.ExternalPluginManagerPanel.wrapContainer; import static net.runelite.client.plugins.openosrs.externals.ExternalPluginManagerPanel.wrapContainer;
import net.runelite.client.ui.ClientUI;
import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.FontManager; import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.PluginPanel; import net.runelite.client.ui.PluginPanel;
@@ -43,7 +45,6 @@ import net.runelite.client.ui.components.shadowlabel.JShadowedLabel;
import net.runelite.client.util.DeferredDocumentChangedListener; import net.runelite.client.util.DeferredDocumentChangedListener;
import net.runelite.client.util.ImageUtil; import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.SwingUtil; import net.runelite.client.util.SwingUtil;
import org.apache.commons.text.similarity.JaroWinklerDistance;
import org.pf4j.update.PluginInfo; import org.pf4j.update.PluginInfo;
import org.pf4j.update.UpdateManager; import org.pf4j.update.UpdateManager;
import org.pf4j.update.UpdateRepository; import org.pf4j.update.UpdateRepository;
@@ -52,7 +53,6 @@ import org.pf4j.update.VerifyException;
@Slf4j @Slf4j
public class PluginsPanel extends JPanel public class PluginsPanel extends JPanel
{ {
private static final JaroWinklerDistance DISTANCE = new JaroWinklerDistance();
private static final ImageIcon ADD_ICON; private static final ImageIcon ADD_ICON;
private static final ImageIcon ADD_HOVER_ICON; private static final ImageIcon ADD_HOVER_ICON;
private static final ImageIcon DELETE_ICON; private static final ImageIcon DELETE_ICON;
@@ -257,7 +257,7 @@ public class PluginsPanel extends JPanel
if (availablePlugins == null || plugins == null) if (availablePlugins == null || plugins == null)
{ {
JOptionPane.showMessageDialog(null, "The external plugin list could not be loaded.", "Error", JOptionPane.ERROR_MESSAGE); JOptionPane.showMessageDialog(ClientUI.getFrame(), "The external plugin list could not be loaded.", "Error", JOptionPane.ERROR_MESSAGE);
return; return;
} }
@@ -465,7 +465,7 @@ public class PluginsPanel extends JPanel
{ {
if (hideAction) if (hideAction)
{ {
JOptionPane.showMessageDialog(null, "This plugin can't be uninstalled because one or more other plugins have a dependency on it.", "Error!", JOptionPane.ERROR_MESSAGE); JOptionPane.showMessageDialog(ClientUI.getFrame(), "This plugin can't be uninstalled because one or more other plugins have a dependency on it.", "Error!", JOptionPane.ERROR_MESSAGE);
} }
else else
{ {
@@ -573,7 +573,7 @@ public class PluginsPanel extends JPanel
try try
{ {
SwingUtil.syncExec(() -> SwingUtil.syncExec(() ->
JOptionPane.showMessageDialog(null, pluginInfo.name + " could not be installed, the hash could not be verified.", "Error!", JOptionPane.ERROR_MESSAGE)); JOptionPane.showMessageDialog(ClientUI.getFrame(), pluginInfo.name + " could not be installed, the hash could not be verified.", "Error!", JOptionPane.ERROR_MESSAGE));
} }
catch (InvocationTargetException | InterruptedException ignored) catch (InvocationTargetException | InterruptedException ignored)
{ {
@@ -58,8 +58,12 @@ public class RepositoryBox extends JPanel
setLayout(new BorderLayout()); setLayout(new BorderLayout());
setBackground(ColorScheme.DARKER_GRAY_COLOR); setBackground(ColorScheme.DARKER_GRAY_COLOR);
String name = updateRepository.getId().replace(updateRepository.getUrl().toString(), ""); String name = updateRepository.getId();
String urlString = updateRepository.getUrl().toString().replace("https://raw.githubusercontent.com/", "").replace("/master/", ""); String urlString = updateRepository.getUrl().toString();
if (urlString.startsWith("/"))
{
urlString = urlString.substring(1);
}
JPanel titleWrapper = new JPanel(new BorderLayout()); JPanel titleWrapper = new JPanel(new BorderLayout());
titleWrapper.setBackground(ColorScheme.DARKER_GRAY_COLOR); titleWrapper.setBackground(ColorScheme.DARKER_GRAY_COLOR);
@@ -145,11 +149,31 @@ public class RepositoryBox extends JPanel
titleWrapper.add(titleActions, BorderLayout.EAST); titleWrapper.add(titleActions, BorderLayout.EAST);
JMultilineLabel repository = new JMultilineLabel(); JMultilineLabel repository = new JMultilineLabel();
repository.setText(urlString.split("/", 2)[1]); repository.setText(formatURL(urlString));
repository.setFont(smallFont); repository.setFont(smallFont);
repository.setDisabledTextColor(Color.WHITE); repository.setDisabledTextColor(Color.WHITE);
String finalUrlString = urlString;
repository.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
LinkBrowser.browse(formatURL(finalUrlString));
}
});
add(titleWrapper, BorderLayout.NORTH); add(titleWrapper, BorderLayout.NORTH);
add(repository, BorderLayout.CENTER); add(repository, BorderLayout.CENTER);
} }
private String formatURL(String url)
{
if (url.contains("githubusercontent"))
{
url = url.replace("raw.githubusercontent", "github").replace("/master/", "");
}
return url;
}
} }
@@ -29,7 +29,6 @@ import java.applet.Applet;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.awt.Color; import java.awt.Color;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.swing.JFrame;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import net.runelite.api.Client; import net.runelite.api.Client;
@@ -65,13 +64,13 @@ final class ClientPanel extends JPanel
{ {
String message = "Detected a bad codebase. Resetting...\n" String message = "Detected a bad codebase. Resetting...\n"
+ "Please restart client.\n"; + "Please restart client.\n";
JOptionPane.showMessageDialog(new JFrame(), message, "Bad Codebase", JOptionPane.showMessageDialog(ClientUI.getFrame(), message, "Bad Codebase",
JOptionPane.ERROR_MESSAGE); JOptionPane.ERROR_MESSAGE);
StringFileUtils.writeStringToFile(RuneLite.RUNELITE_DIR + "/codebase", "http://127.0.0.1/"); StringFileUtils.writeStringToFile(RuneLite.RUNELITE_DIR + "/codebase", "http://127.0.0.1/");
} }
else else
{ {
JOptionPane.showMessageDialog(new JFrame(), "Error loading Oldschool RuneScape!", "Error", JOptionPane.showMessageDialog(ClientUI.getFrame(), "Error loading Oldschool RuneScape!", "Error",
JOptionPane.ERROR_MESSAGE); JOptionPane.ERROR_MESSAGE);
Sentry.capture(e); Sentry.capture(e);
} }
@@ -667,7 +667,7 @@ public class ClientUI
return; return;
} }
final java.awt.Point hotspot = new java.awt.Point(container.getX(), container.getY()); final java.awt.Point hotspot = new java.awt.Point(0, 0);
final Cursor cursorAwt = Toolkit.getDefaultToolkit().createCustomCursor(image, hotspot, name); final Cursor cursorAwt = Toolkit.getDefaultToolkit().createCustomCursor(image, hotspot, name);
container.setCursor(cursorAwt); container.setCursor(cursorAwt);
} }
@@ -0,0 +1,247 @@
/*
* Copyright (c) 2018, Shingyx <https://github.com/Shingyx>
* 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.ui.components;
import java.awt.Component;
import java.awt.Container;
import java.awt.LayoutManager;
import java.awt.Point;
import java.awt.dnd.DragSource;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.Map;
import javax.swing.BoxLayout;
import javax.swing.JLayeredPane;
/**
* Pane which allows reordering its components via drag and drop.
* <p>
* For child components' popup menus, implement the PopupMenuOwner interface in the child components.
*/
public class DragAndDropReorderPane extends JLayeredPane
{
private Point dragStartPoint;
private Component draggingComponent;
private int dragIndex = -1;
private final Map<Integer, PopupMenuOwner> popupMenuCandidates = new HashMap<>(); // keyed by mouse button
public DragAndDropReorderPane()
{
super();
setLayout(new DragAndDropReorderLayoutManager());
MouseAdapter mouseAdapter = new DragAndDropReorderMouseAdapter();
addMouseListener(mouseAdapter);
addMouseMotionListener(mouseAdapter);
}
@Override
public void setLayout(LayoutManager layoutManager)
{
if (layoutManager != null && !(layoutManager instanceof DragAndDropReorderLayoutManager))
{
throw new IllegalArgumentException("DragAndDropReorderPane only supports DragAndDropReorderLayoutManager");
}
super.setLayout(layoutManager);
}
private void startDragging(Point point)
{
draggingComponent = getDefaultLayerComponentAt(dragStartPoint);
if (draggingComponent == null)
{
dragStartPoint = null;
return;
}
dragIndex = getPosition(draggingComponent);
setLayer(draggingComponent, DRAG_LAYER);
moveDraggingComponent(point);
}
private void drag(Point point)
{
moveDraggingComponent(point);
Component component = getDefaultLayerComponentAt(point);
if (component != null)
{
int index = getPosition(component);
dragIndex = index < dragIndex ? index : index + 1;
revalidate();
}
}
private void finishDragging()
{
if (draggingComponent != null)
{
setLayer(draggingComponent, DEFAULT_LAYER, dragIndex);
revalidate();
}
dragStartPoint = null;
draggingComponent = null;
dragIndex = -1;
}
private void moveDraggingComponent(Point point)
{
// place the center of the dragging component onto the mouse cursor
int y = point.y - draggingComponent.getHeight() / 2;
// clamp the height to stay within the pane
y = Math.max(y, 0);
y = Math.min(y, getHeight() - draggingComponent.getHeight());
draggingComponent.setLocation(new Point(0, y));
}
private Component getDefaultLayerComponentAt(Point point)
{
for (Component component : getComponentsInLayer(DEFAULT_LAYER))
{
if (component.contains(point.x - component.getX(), point.y - component.getY()))
{
return component;
}
}
return null;
}
private class DragAndDropReorderLayoutManager extends BoxLayout
{
private DragAndDropReorderLayoutManager()
{
super(DragAndDropReorderPane.this, BoxLayout.Y_AXIS);
}
@Override
public void layoutContainer(Container target)
{
if (draggingComponent != null)
{
// temporarily move the dragging component to the default layer for correct layout calculation
Point location = draggingComponent.getLocation();
setLayer(draggingComponent, DEFAULT_LAYER, dragIndex);
super.layoutContainer(target);
setLayer(draggingComponent, DRAG_LAYER);
draggingComponent.setLocation(location);
}
else
{
super.layoutContainer(target);
}
}
}
private class DragAndDropReorderMouseAdapter extends MouseAdapter
{
@Override
public void mousePressed(MouseEvent e)
{
Point point = e.getPoint();
int mouseButton = e.getButton();
if (mouseButton == MouseEvent.BUTTON1)
{
// candidate for dragging
if (popupMenuCandidates.isEmpty() && getComponentCount() > 1)
{
dragStartPoint = point;
}
}
else
{
if (dragStartPoint != null)
{
finishDragging();
}
else
{
// candidate for child popup menu
Component component = getDefaultLayerComponentAt(point);
if (component instanceof PopupMenuOwner)
{
PopupMenuOwner popupMenuCandidate = (PopupMenuOwner) component;
if (e.isPopupTrigger())
{
popupMenuCandidate.getPopupMenu().show(DragAndDropReorderPane.this, point.x, point.y);
}
else
{
popupMenuCandidates.put(mouseButton, popupMenuCandidate);
}
}
}
}
}
@Override
public void mouseDragged(MouseEvent e)
{
if (dragStartPoint == null)
{
return;
}
Point point = e.getPoint();
if (contains(point))
{
if (draggingComponent == null)
{
if (point.distance(dragStartPoint) > DragSource.getDragThreshold())
{
startDragging(point);
}
}
else
{
drag(point);
}
}
else
{
finishDragging();
}
}
@Override
public void mouseReleased(MouseEvent e)
{
Point point = e.getPoint();
int mouseButton = e.getButton();
if (mouseButton == MouseEvent.BUTTON1)
{
finishDragging();
}
else
{
PopupMenuOwner popupMenuCandidate = popupMenuCandidates.remove(mouseButton);
if (popupMenuCandidate != null && e.isPopupTrigger())
{
popupMenuCandidate.getPopupMenu().show(DragAndDropReorderPane.this, point.x, point.y);
}
}
}
}
}
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2018, Shingyx <https://github.com/Shingyx>
* 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.ui.components;
import javax.swing.JPopupMenu;
/**
* Represents a UI component which has a popup menu, to be used on child components inside DragAndDropReorderPane.
* This is because using setComponentPopupMenu consumes the MouseEvents required for drag and drop reordering.
*/
public interface PopupMenuOwner
{
JPopupMenu getPopupMenu();
}
@@ -63,6 +63,7 @@ public class WidgetOverlay extends Overlay
.put(WidgetInfo.LMS_INFO, OverlayPosition.TOP_CENTER) .put(WidgetInfo.LMS_INFO, OverlayPosition.TOP_CENTER)
.put(WidgetInfo.LMS_KDA, OverlayPosition.TOP_CENTER) .put(WidgetInfo.LMS_KDA, OverlayPosition.TOP_CENTER)
.put(WidgetInfo.THEATRE_OF_BLOOD_HEALTH_ORBS, OverlayPosition.TOP_LEFT) .put(WidgetInfo.THEATRE_OF_BLOOD_HEALTH_ORBS, OverlayPosition.TOP_LEFT)
.put(WidgetInfo.GAUNTLET_TIMER_CONTAINER, OverlayPosition.TOP_LEFT)
.build(); .build();
public static Collection<WidgetOverlay> createOverlays(final Client client) public static Collection<WidgetOverlay> createOverlays(final Client client)
@@ -44,7 +44,6 @@ import net.runelite.client.ui.overlay.components.TooltipComponent;
public class TooltipOverlay extends Overlay public class TooltipOverlay extends Overlay
{ {
private static final int UNDER_OFFSET = 24; private static final int UNDER_OFFSET = 24;
private static final int ABOVE_OFFSET = -20;
private static final int PADDING = 2; private static final int PADDING = 2;
private final TooltipManager tooltipManager; private final TooltipManager tooltipManager;
private final Client client; private final Client client;
@@ -84,50 +83,28 @@ public class TooltipOverlay extends Overlay
private Dimension renderTooltips(Graphics2D graphics, List<Tooltip> tooltips) private Dimension renderTooltips(Graphics2D graphics, List<Tooltip> tooltips)
{ {
final Rectangle clientCanvasBounds = new Rectangle(client.getRealDimensions()); final int canvasWidth = client.getCanvasWidth();
final int canvasHeight = client.getCanvasHeight();
final net.runelite.api.Point mouseCanvasPosition = client.getMouseCanvasPosition(); final net.runelite.api.Point mouseCanvasPosition = client.getMouseCanvasPosition();
final int offset = runeLiteConfig.tooltipPosition() == TooltipPositionType.UNDER_CURSOR ? UNDER_OFFSET : ABOVE_OFFSET; final Rectangle prevBounds = getBounds();
final Point mousePosition = new Point(mouseCanvasPosition.getX(), mouseCanvasPosition.getY() + offset);
final Rectangle bounds = new Rectangle(getBounds());
bounds.setLocation(mousePosition);
if (!clientCanvasBounds.contains(bounds)) final int tooltipX = Math.min(canvasWidth - prevBounds.width, mouseCanvasPosition.getX());
{ final int tooltipY = runeLiteConfig.tooltipPosition() == TooltipPositionType.ABOVE_CURSOR
final int clientX = (int) clientCanvasBounds.getMaxX(); ? Math.max(0, mouseCanvasPosition.getY() - prevBounds.height)
final int clientY = (int) clientCanvasBounds.getMaxY(); : Math.min(canvasHeight - prevBounds.height, mouseCanvasPosition.getY() + UNDER_OFFSET);
final int boundsX = (int) bounds.getMaxX();
final int boundsY = (int) bounds.getMaxY();
if (boundsY > clientY) final Rectangle newBounds = new Rectangle(tooltipX, tooltipY, 0, 0);
{
graphics.translate(0, -bounds.height - offset);
}
if (boundsX > clientX)
{
graphics.translate(-bounds.width + clientCanvasBounds.width - bounds.x, 0);
}
}
final Rectangle newBounds = new Rectangle(-1, -1, 0, 0);
for (Tooltip tooltip : tooltips) for (Tooltip tooltip : tooltips)
{ {
final TooltipComponent tooltipComponent = new TooltipComponent(); final TooltipComponent tooltipComponent = new TooltipComponent();
tooltipComponent.setModIcons(client.getModIcons()); tooltipComponent.setModIcons(client.getModIcons());
tooltipComponent.setText(tooltip.getText()); tooltipComponent.setText(tooltip.getText());
tooltipComponent.setPosition(new Point(tooltipX, tooltipY + newBounds.height));
if (newBounds.contains(mousePosition))
{
mousePosition.move(mouseCanvasPosition.getX(), mouseCanvasPosition.getY() + offset + newBounds.height);
}
tooltipComponent.setPosition(mousePosition);
final Dimension dimension = tooltipComponent.render(graphics); final Dimension dimension = tooltipComponent.render(graphics);
// Create incremental tooltip newBounds // Create incremental tooltip newBounds
newBounds.x = newBounds.x != -1 ? Math.min(newBounds.x, mousePosition.x) : mousePosition.x;
newBounds.y = newBounds.y != -1 ? Math.min(newBounds.y, mousePosition.y) : mousePosition.y;
newBounds.height += dimension.height + PADDING; newBounds.height += dimension.height + PADDING;
newBounds.width = Math.max(newBounds.width, dimension.width); newBounds.width = Math.max(newBounds.width, dimension.width);
} }
@@ -0,0 +1,64 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2018 by rumatoest at github.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package net.runelite.client.util;
/**
* The Class AppLock.
*
* @author Vladislav Zablotsky
*/
public class AppLock
{
private static CrossLock lockInstance;
/**
* Set lock for application instance.
* Method must be run only one time at application start.
*
* @param lockId Unique lock identifiers
* @return true if succeeded
*/
public synchronized boolean lock(String lockId)
{
if (lockInstance == null)
{
lockInstance = new CrossLock("application_" + lockId);
}
return lockInstance.lock();
}
/**
* Trying to release application lock.
* Thus another application instances will be able to use lock with current ID.
*/
public synchronized void release()
{
if (lockInstance != null)
{
lockInstance.clear();
}
lockInstance = null;
}
}
@@ -0,0 +1,228 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2018 by rumatoest at github.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package net.runelite.client.util;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import static net.runelite.client.RuneLite.RUNELITE_DIR;
/**
* Universal cross application instances locker.
* Allow you to create simple lock like object which can be used for
* different application instances. Basic idea is simple - just a simple file lock.
* <br />
* All you need is to define unique key for each lock type.
*
* @author Vladislav Zablotsky
*/
public class CrossLock
{
private static final HashMap<String, CrossLock> locks = new HashMap<>();
private final String id;
private final File fileToLock;
private FileOutputStream fileStream;
private FileChannel fileStreamChannel;
private FileLock lockOnFile;
/**
* Will create or retrieve lock instance.
* Each lock id is unique among all you instances,
* thus only one instance can acquire lock for this id.
*
* @param lockId Unique lock identifier
* @return Not null
*/
public static CrossLock get(String lockId)
{
if (locks.containsKey(lockId))
{
return locks.get(lockId);
}
else
{
synchronized (CrossLock.class)
{
if (locks.containsKey(lockId))
{
return locks.get(lockId);
}
else
{
CrossLock cl = new CrossLock(lockId);
locks.put(lockId, cl);
return cl;
}
}
}
}
/**
* Will remove lock object for specific id and release lock if any.
*
* @param lockId Unique lock identifier
*/
public static void remove(String lockId)
{
if (locks.containsKey(lockId))
{
CrossLock lock = null;
synchronized (CrossLock.class)
{
if (locks.containsKey(lockId))
{
lock = locks.remove(lockId);
}
}
if (lock != null)
{
lock.release();
}
}
}
CrossLock(String lockId)
{
this.id = lockId;
fileToLock = new File(RUNELITE_DIR, lockId + ".app_lock");
}
/**
* Return lock instance identifier.
*/
public String id()
{
return this.id;
}
/**
* Activate lock.
* Note! This is only cross application (cross instances) lock. It will not work
* as lock inside single application instance.
*
* @return true if lock was acquire or false
*/
public synchronized boolean lock()
{
if (lockOnFile != null && lockOnFile.isValid())
{
return true;
}
else
{
release();
}
String lockContent = "#Java AppLock Object\n#Locked by key: " + id() + "\r\n";
try
{
if (fileToLock.exists())
{
fileToLock.createNewFile();
}
fileStream = new FileOutputStream(fileToLock);
fileStreamChannel = fileStream.getChannel();
lockOnFile = fileStreamChannel.tryLock();
if (lockOnFile != null)
{
fileStream.write(lockContent.getBytes());
}
}
catch (Exception ex)
{
if (!(ex instanceof OverlappingFileLockException))
{
Logger.getLogger(AppLock.class.getName()).log(Level.WARNING,
"Can not get application lock for id=" + id() + "\n" + ex.getMessage(), ex);
}
return false;
}
return lockOnFile != null;
}
/**
* Release lock associated with this object.
*/
public synchronized void release()
{
try
{
if (lockOnFile != null && lockOnFile.isValid())
{
lockOnFile.release();
}
lockOnFile = null;
if (fileStream != null)
{
fileStream.close();
fileStream = null;
}
if (fileStreamChannel != null && fileStreamChannel.isOpen())
{
fileStreamChannel.close();
}
fileStreamChannel = null;
}
catch (IOException ex)
{
Logger.getLogger(AppLock.class.getName()).log(Level.WARNING,
"Can not get application lock for id=" + id() + "\n" + ex.getMessage(), ex);
}
}
/**
* Release lock and remove lock file.
*/
public synchronized void clear()
{
release();
if (fileToLock.exists())
{
fileToLock.delete();
}
}
@Override
protected void finalize() throws Throwable
{
this.clear();
super.finalize();
}
}
@@ -24,7 +24,7 @@
*/ */
package net.runelite.client.util; package net.runelite.client.util;
import io.reactivex.annotations.NonNull; import io.reactivex.rxjava3.annotations.NonNull;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import javax.inject.Inject; import javax.inject.Inject;
@@ -25,6 +25,7 @@
*/ */
package net.runelite.client.util; package net.runelite.client.util;
import com.google.common.base.Strings;
import java.awt.Toolkit; import java.awt.Toolkit;
import java.awt.TrayIcon; import java.awt.TrayIcon;
import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.Clipboard;
@@ -40,6 +41,7 @@ import java.text.SimpleDateFormat;
import java.util.Base64; import java.util.Base64;
import java.util.Date; import java.util.Date;
import java.util.EnumSet; import java.util.EnumSet;
import javax.annotation.Nullable;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
@@ -80,10 +82,11 @@ public class ImageCapture
* *
* @param screenshot BufferedImage to capture. * @param screenshot BufferedImage to capture.
* @param fileName Filename to use, without file extension. * @param fileName Filename to use, without file extension.
* @param subDir Directory within the player screenshots dir to store the captured screenshot to.
* @param notify Send a notification to the system tray when the image is captured. * @param notify Send a notification to the system tray when the image is captured.
* @param imageUploadStyle which method to use to upload the screenshot (Imgur or directly to clipboard). * @param imageUploadStyle which method to use to upload the screenshot (Imgur or directly to clipboard).
*/ */
public void takeScreenshot(BufferedImage screenshot, String fileName, boolean notify, ImageUploadStyle imageUploadStyle) public void takeScreenshot(BufferedImage screenshot, String fileName, @Nullable String subDir, boolean notify, ImageUploadStyle imageUploadStyle)
{ {
if (client.getGameState() == GameState.LOGIN_SCREEN) if (client.getGameState() == GameState.LOGIN_SCREEN)
{ {
@@ -106,6 +109,12 @@ public class ImageCapture
{ {
playerDir += "-League"; playerDir += "-League";
} }
if (!Strings.isNullOrEmpty(subDir))
{
playerDir += File.separator + subDir;
}
playerFolder = new File(SCREENSHOT_DIR, playerDir); playerFolder = new File(SCREENSHOT_DIR, playerDir);
} }
else else
@@ -157,6 +166,20 @@ public class ImageCapture
} }
} }
/**
* Saves a screenshot of the client window to the screenshot folder as a PNG,
* and optionally uploads it to an image-hosting service.
*
* @param screenshot BufferedImage to capture.
* @param fileName Filename to use, without file extension.
* @param notify Send a notification to the system tray when the image is captured.
* @param imageUploadStyle which method to use to upload the screenshot (Imgur or directly to clipboard).
*/
public void takeScreenshot(BufferedImage screenshot, String fileName, boolean notify, ImageUploadStyle imageUploadStyle)
{
takeScreenshot(screenshot, fileName, null, notify, imageUploadStyle);
}
/** /**
* Uploads a screenshot to the Imgur image-hosting service, * Uploads a screenshot to the Imgur image-hosting service,
* and copies the image link to the clipboard. * and copies the image link to the clipboard.
@@ -36,6 +36,7 @@ import javax.inject.Singleton;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.client.ui.ClientUI;
/** /**
* Utility class used for web and file browser navigation * Utility class used for web and file browser navigation
@@ -249,7 +250,7 @@ public class LinkBrowser
{ {
SwingUtilities.invokeLater(() -> SwingUtilities.invokeLater(() ->
{ {
final int result = JOptionPane.showConfirmDialog(null, message, "Message", final int result = JOptionPane.showConfirmDialog(ClientUI.getFrame(), message, "Message",
JOptionPane.OK_CANCEL_OPTION); JOptionPane.OK_CANCEL_OPTION);
if (result == JOptionPane.OK_OPTION) if (result == JOptionPane.OK_OPTION)
@@ -1,12 +1,17 @@
package net.runelite.client.util; package net.runelite.client.util;
import java.awt.Polygon;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.Player; import net.runelite.api.Player;
import net.runelite.api.WorldType; import net.runelite.api.WorldType;
import net.runelite.api.coords.WorldPoint; import net.runelite.api.coords.WorldPoint;
import java.awt.Polygon;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class MiscUtils public class MiscUtils
{ {
@@ -170,4 +175,28 @@ public class MiscUtils
} }
return str; return str;
} }
/**
* Mostly stolen from {@link java.net.URLStreamHandler#toExternalForm(URL)}
*
* @param url URL to encode
* @return URL, with path, query and ref encoded
*/
public static String urlToStringEncoded(URL url)
{
String s;
String path = url.getPath() != null ? Stream.of(url.getPath().split("/"))
.map(s2 -> URLEncoder.encode(s2, StandardCharsets.UTF_8)).collect(Collectors.joining("/")) : "";
return url.getProtocol()
+ ':'
+ (((s = url.getAuthority()) != null && s.length() > 0) ? "//" + s : "")
+ (path)
+ (((s = url.getQuery()) != null) ? '?' + urlEncode(s) : "")
+ (((s = url.getRef()) != null) ? '#' + urlEncode(s) : "");
}
private static String urlEncode(String s)
{
return URLEncoder.encode(s, StandardCharsets.UTF_8);
}
} }
@@ -1401,11 +1401,13 @@
], ],
"coal bag": [ "coal bag": [
764, 764,
12019 12019,
24480
], ],
"gem bag": [ "gem bag": [
766, 766,
12020 12020,
24481
], ],
"phoenix crossbow": [ "phoenix crossbow": [
767, 767,
@@ -7609,6 +7611,10 @@
11736, 11736,
11737 11737
], ],
"herb box": [
11738,
11739
],
"armadyl crossbow": [ "armadyl crossbow": [
11785, 11785,
23611 23611
@@ -7815,6 +7821,10 @@
11912, 11912,
11914 11914
], ],
"slice of birthday cake": [
11916,
11917
],
"dragon pickaxe": [ "dragon pickaxe": [
11920, 11920,
12797, 12797,
@@ -8271,6 +8281,10 @@
13222, 13222,
13224 13224
], ],
"herb sack": [
13226,
24478
],
"eternal boots": [ "eternal boots": [
13235, 13235,
23644 23644
@@ -8539,6 +8553,10 @@
13576, 13576,
20785 20785
], ],
"seed box": [
13639,
24482
],
"farmers boro trousers": [ "farmers boro trousers": [
13640, 13640,
13641 13641
@@ -9692,9 +9710,5 @@
24469, 24469,
24472, 24472,
24475 24475
],
"cat ears": [
24522,
24525
] ]
} }
Binary file not shown.

After

Width:  |  Height:  |  Size: 384 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 580 B

File diff suppressed because one or more lines are too long
@@ -11,6 +11,5 @@ open.osrs.builddate=@open.osrs.builddate@
runelite.wiki.troubleshooting.link=https://github.com/open-osrs/runelite/wiki/Troubleshooting-problems-with-the-client runelite.wiki.troubleshooting.link=https://github.com/open-osrs/runelite/wiki/Troubleshooting-problems-with-the-client
runelite.wiki.building.link=https://github.com/open-osrs/runelite/wiki/Building-with-IntelliJ-IDEA runelite.wiki.building.link=https://github.com/open-osrs/runelite/wiki/Building-with-IntelliJ-IDEA
runelite.dnschange.link=https://1.1.1.1/dns/ runelite.dnschange.link=https://1.1.1.1/dns/
launcher.version=@launcher.version@
plugin.path=@plugin.path@ plugin.path=@plugin.path@
runelite.imgur.client.id=30d71e5f6860809 runelite.imgur.client.id=30d71e5f6860809
@@ -3,7 +3,17 @@
.string_stack_count 0 .string_stack_count 0
.int_var_count 35 .int_var_count 35
.string_var_count 1 .string_var_count 1
sconst "bankLayoutInit" ; callback "beforeBankLayout"
; Fired before the bank starts its layout
; Used by the TabInterface to hide fake bank items for tag tabs
;
; callback "setBankScroll"
; Fired before bank is calculated
; Used by the TabInterface to show fake bank items for tag tabs
;
; callback "isTabMenuActive"
; Used by the TabInterface to skip setting the bank title
sconst "beforeBankLayout"
runelite_callback runelite_callback
get_varbit 5102 get_varbit 5102
iconst 1 iconst 1
@@ -12,12 +22,12 @@
LABEL4: LABEL4:
iconst 0 iconst 0
iload 9 iload 9
if_sethide if_sethide
jump LABEL13 jump LABEL13
LABEL8: LABEL8:
iconst 1 iconst 1
iload 9 iload 9
if_sethide if_sethide
iload 11 iload 11
invoke 41 invoke 41
LABEL13: LABEL13:
@@ -33,10 +43,10 @@ LABEL19:
LABEL21: LABEL21:
iload 16 iload 16
iload 14 iload 14
if_sethide if_sethide
iload 16 iload 16
iload 15 iload 15
if_sethide if_sethide
get_varbit 8352 get_varbit 8352
iconst 1 iconst 1
if_icmpeq LABEL31 if_icmpeq LABEL31
@@ -51,22 +61,22 @@ LABEL34:
LABEL36: LABEL36:
iload 16 iload 16
iload 12 iload 12
if_sethide if_sethide
iload 16 iload 16
iload 13 iload 13
if_sethide if_sethide
iconst 441 iconst 441
iconst 0 iconst 0
iconst 0 iconst 0
iconst 0 iconst 0
iload 14 iload 14
if_setposition if_setposition
iconst 444 iconst 444
iconst 7 iconst 7
iconst 0 iconst 0
iconst 0 iconst 0
iload 15 iload 15
if_setposition if_setposition
get_varbit 8352 get_varbit 8352
iconst 1 iconst 1
if_icmpeq LABEL58 if_icmpeq LABEL58
@@ -78,27 +88,27 @@ LABEL58:
jump LABEL85 jump LABEL85
LABEL62: LABEL62:
iload 12 iload 12
if_getx if_getx
iload 12 iload 12
if_gety if_gety
iconst 0 iconst 0
iconst 0 iconst 0
iload 14 iload 14
if_setposition if_setposition
iload 13 iload 13
if_getx if_getx
iload 13 iload 13
if_gety if_gety
iconst 0 iconst 0
iconst 0 iconst 0
iload 15 iload 15
if_setposition if_setposition
iconst 37 iconst 37
iconst 37 iconst 37
iconst 1 iconst 1
iconst 0 iconst 0
iload 4 iload 4
if_setsize if_setsize
jump LABEL121 jump LABEL121
LABEL85: LABEL85:
get_varbit 8352 get_varbit 8352
@@ -116,7 +126,7 @@ LABEL93:
iconst 1 iconst 1
iconst 0 iconst 0
iload 4 iload 4
if_setsize if_setsize
jump LABEL121 jump LABEL121
LABEL100: LABEL100:
get_varbit 8352 get_varbit 8352
@@ -134,7 +144,7 @@ LABEL108:
iconst 1 iconst 1
iconst 0 iconst 0
iload 4 iload 4
if_setsize if_setsize
jump LABEL121 jump LABEL121
LABEL115: LABEL115:
iconst 0 iconst 0
@@ -142,13 +152,13 @@ LABEL115:
iconst 1 iconst 1
iconst 0 iconst 0
iload 4 iload 4
if_setsize if_setsize
LABEL121: LABEL121:
iconst 1 iconst 1
iload 10 iload 10
if_sethide if_sethide
iload 10 iload 10
cc_deleteall cc_deleteall
iconst 0 iconst 0
istore 17 istore 17
get_varbit 4170 get_varbit 4170
@@ -201,7 +211,7 @@ LABEL165:
LABEL171: LABEL171:
iconst 1 iconst 1
iload 8 iload 8
if_sethide if_sethide
iconst 2 iconst 2
istore 18 istore 18
iconst 460 iconst 460
@@ -209,42 +219,42 @@ LABEL171:
iconst 0 iconst 0
iconst 1 iconst 1
iload 2 iload 2
if_setsize if_setsize
iconst 16 iconst 16
iconst 39 iconst 39
iconst 0 iconst 0
iconst 1 iconst 1
iload 3 iload 3
if_setsize if_setsize
iconst 28 iconst 28
iconst 42 iconst 42
iconst 2 iconst 2
iconst 0 iconst 0
iload 1 iload 1
if_setposition if_setposition
jump LABEL216 jump LABEL216
LABEL195: LABEL195:
iconst 0 iconst 0
iload 8 iload 8
if_sethide if_sethide
iconst 460 iconst 460
iconst 81 iconst 81
iconst 0 iconst 0
iconst 1 iconst 1
iload 2 iload 2
if_setsize if_setsize
iconst 16 iconst 16
iconst 81 iconst 81
iconst 0 iconst 0
iconst 1 iconst 1
iload 3 iload 3
if_setsize if_setsize
iconst 12 iconst 12
iconst 42 iconst 42
iconst 2 iconst 2
iconst 0 iconst 0
iload 1 iload 1
if_setposition if_setposition
LABEL216: LABEL216:
iload 3 iload 3
iload 2 iload 2
@@ -254,8 +264,8 @@ LABEL216:
iconst 816 iconst 816
iconst 9 iconst 9
iconst 3 iconst 3
multiply multiply
add add
istore 20 istore 20
LABEL227: LABEL227:
iload 19 iload 19
@@ -265,17 +275,17 @@ LABEL227:
LABEL231: LABEL231:
iload 2 iload 2
iload 19 iload 19
cc_find cc_find
iconst 1 iconst 1
if_icmpeq LABEL237 if_icmpeq LABEL237
jump LABEL239 jump LABEL239
LABEL237: LABEL237:
iconst 1 iconst 1
cc_sethide cc_sethide
LABEL239: LABEL239:
iload 19 iload 19
iconst 1 iconst 1
add add
istore 19 istore 19
jump LABEL227 jump LABEL227
LABEL244: LABEL244:
@@ -283,22 +293,22 @@ LABEL244:
istore 19 istore 19
iconst 8 iconst 8
iconst 1 iconst 1
sub sub
istore 21 istore 21
iload 2 iload 2
if_getwidth if_getwidth
iconst 51 iconst 51
sub sub
iconst 35 iconst 35
sub sub
istore 22 istore 22
iload 22 iload 22
iconst 8 iconst 8
iconst 36 iconst 36
multiply multiply
sub sub
iload 21 iload 21
div div
istore 23 istore 23
iconst -1 iconst -1
istore 24 istore 24
@@ -331,51 +341,51 @@ LABEL288:
LABEL292: LABEL292:
iload 2 iload 2
iload 19 iload 19
cc_find cc_find
iconst 1 iconst 1
if_icmpeq LABEL298 if_icmpeq LABEL298
jump LABEL300 jump LABEL300
LABEL298: LABEL298:
iconst 1 iconst 1
cc_sethide cc_sethide
LABEL300: LABEL300:
iconst 95 iconst 95
iload 19 iload 19
inv_getobj inv_getobj
iconst -1 iconst -1
if_icmpne LABEL306 if_icmpne LABEL306
jump LABEL312 jump LABEL312
LABEL306: LABEL306:
iload 28 iload 28
iconst 1 iconst 1
add add
iload 19 iload 19
istore 29 istore 29
istore 28 istore 28
LABEL312: LABEL312:
iload 19 iload 19
iconst 1 iconst 1
add add
istore 19 istore 19
jump LABEL288 jump LABEL288
LABEL317: LABEL317:
get_varbit 4171 get_varbit 4171
get_varbit 4172 get_varbit 4172
add add
get_varbit 4173 get_varbit 4173
add add
get_varbit 4174 get_varbit 4174
add add
get_varbit 4175 get_varbit 4175
add add
get_varbit 4176 get_varbit 4176
add add
get_varbit 4177 get_varbit 4177
add add
get_varbit 4178 get_varbit 4178
add add
get_varbit 4179 get_varbit 4179
add add
istore 30 istore 30
iload 30 iload 30
iconst 0 iconst 0
@@ -384,13 +394,22 @@ LABEL317:
LABEL339: LABEL339:
iconst 816 iconst 816
iconst 1 iconst 1
sub sub
istore 29 istore 29
LABEL343: LABEL343:
iconst 0 ; Scroll height variable
iconst 0 ; Compare variable
iconst 0 ;
sconst "setBankScroll" ; Show fake bank items for tag tabs
runelite_callback ; If tag tab menu search isn't active
if_icmpeq CONTINUE_SEARCH ; continue to normal bank search
istore 27 ; Load scroll height into variable
jump GetTabRange ; Skip normal bank layout
CONTINUE_SEARCH:
iload 30 iload 30
iload 29 iload 29
iconst 1 iconst 1
add add
iconst 0 iconst 0
iload 2 iload 2
iload 3 iload 3
@@ -406,7 +425,7 @@ LABEL343:
istore 27 istore 27
iload 26 iload 26
iload 25 iload 25
add add
istore 26 istore 26
iconst 0 iconst 0
istore 19 istore 19
@@ -423,7 +442,7 @@ LABEL370:
iload 19 iload 19
iload 19 iload 19
get_varbit 4171 get_varbit 4171
add add
iconst 1 iconst 1
iload 2 iload 2
iload 3 iload 3
@@ -439,11 +458,11 @@ LABEL370:
istore 27 istore 27
iload 26 iload 26
iload 25 iload 25
add add
istore 26 istore 26
iload 19 iload 19
get_varbit 4171 get_varbit 4171
add add
istore 19 istore 19
LABEL400: LABEL400:
get_varbit 4172 get_varbit 4172
@@ -459,7 +478,7 @@ LABEL404:
iload 19 iload 19
iload 19 iload 19
get_varbit 4172 get_varbit 4172
add add
iconst 2 iconst 2
iload 2 iload 2
iload 3 iload 3
@@ -475,11 +494,11 @@ LABEL404:
istore 27 istore 27
iload 26 iload 26
iload 25 iload 25
add add
istore 26 istore 26
iload 19 iload 19
get_varbit 4172 get_varbit 4172
add add
istore 19 istore 19
LABEL434: LABEL434:
get_varbit 4173 get_varbit 4173
@@ -495,7 +514,7 @@ LABEL438:
iload 19 iload 19
iload 19 iload 19
get_varbit 4173 get_varbit 4173
add add
iconst 3 iconst 3
iload 2 iload 2
iload 3 iload 3
@@ -511,11 +530,11 @@ LABEL438:
istore 27 istore 27
iload 26 iload 26
iload 25 iload 25
add add
istore 26 istore 26
iload 19 iload 19
get_varbit 4173 get_varbit 4173
add add
istore 19 istore 19
LABEL468: LABEL468:
get_varbit 4174 get_varbit 4174
@@ -531,7 +550,7 @@ LABEL472:
iload 19 iload 19
iload 19 iload 19
get_varbit 4174 get_varbit 4174
add add
iconst 4 iconst 4
iload 2 iload 2
iload 3 iload 3
@@ -547,11 +566,11 @@ LABEL472:
istore 27 istore 27
iload 26 iload 26
iload 25 iload 25
add add
istore 26 istore 26
iload 19 iload 19
get_varbit 4174 get_varbit 4174
add add
istore 19 istore 19
LABEL502: LABEL502:
get_varbit 4175 get_varbit 4175
@@ -567,7 +586,7 @@ LABEL506:
iload 19 iload 19
iload 19 iload 19
get_varbit 4175 get_varbit 4175
add add
iconst 5 iconst 5
iload 2 iload 2
iload 3 iload 3
@@ -583,11 +602,11 @@ LABEL506:
istore 27 istore 27
iload 26 iload 26
iload 25 iload 25
add add
istore 26 istore 26
iload 19 iload 19
get_varbit 4175 get_varbit 4175
add add
istore 19 istore 19
LABEL536: LABEL536:
get_varbit 4176 get_varbit 4176
@@ -603,7 +622,7 @@ LABEL540:
iload 19 iload 19
iload 19 iload 19
get_varbit 4176 get_varbit 4176
add add
iconst 6 iconst 6
iload 2 iload 2
iload 3 iload 3
@@ -619,11 +638,11 @@ LABEL540:
istore 27 istore 27
iload 26 iload 26
iload 25 iload 25
add add
istore 26 istore 26
iload 19 iload 19
get_varbit 4176 get_varbit 4176
add add
istore 19 istore 19
LABEL570: LABEL570:
get_varbit 4177 get_varbit 4177
@@ -639,7 +658,7 @@ LABEL574:
iload 19 iload 19
iload 19 iload 19
get_varbit 4177 get_varbit 4177
add add
iconst 7 iconst 7
iload 2 iload 2
iload 3 iload 3
@@ -655,11 +674,11 @@ LABEL574:
istore 27 istore 27
iload 26 iload 26
iload 25 iload 25
add add
istore 26 istore 26
iload 19 iload 19
get_varbit 4177 get_varbit 4177
add add
istore 19 istore 19
LABEL604: LABEL604:
get_varbit 4178 get_varbit 4178
@@ -675,7 +694,7 @@ LABEL608:
iload 19 iload 19
iload 19 iload 19
get_varbit 4178 get_varbit 4178
add add
iconst 8 iconst 8
iload 2 iload 2
iload 3 iload 3
@@ -691,11 +710,11 @@ LABEL608:
istore 27 istore 27
iload 26 iload 26
iload 25 iload 25
add add
istore 26 istore 26
iload 19 iload 19
get_varbit 4178 get_varbit 4178
add add
istore 19 istore 19
LABEL638: LABEL638:
get_varbit 4179 get_varbit 4179
@@ -711,7 +730,7 @@ LABEL642:
iload 19 iload 19
iload 19 iload 19
get_varbit 4179 get_varbit 4179
add add
iconst 9 iconst 9
iload 2 iload 2
iload 3 iload 3
@@ -727,11 +746,11 @@ LABEL642:
istore 27 istore 27
iload 26 iload 26
iload 25 iload 25
add add
istore 26 istore 26
iload 19 iload 19
get_varbit 4179 get_varbit 4179
add add
istore 19 istore 19
LABEL672: LABEL672:
invoke 514 invoke 514
@@ -743,7 +762,7 @@ LABEL676:
lowercase ; instead get the var directly and lowercase it lowercase ; instead get the var directly and lowercase it
sstore 0 sstore 0
sload 0 sload 0
string_length string_length
iconst 0 iconst 0
if_icmpgt LABEL683 if_icmpgt LABEL683
jump LABEL702 jump LABEL702
@@ -754,7 +773,7 @@ LABEL683:
sconst "</col>" sconst "</col>"
join_string 4 join_string 4
iload 5 iload 5
if_settext if_settext
get_varc_int 5 get_varc_int 5
iconst 11 iconst 11
if_icmpeq LABEL694 if_icmpeq LABEL694
@@ -762,7 +781,7 @@ LABEL683:
LABEL694: LABEL694:
sconst "Show items whose names contain the following text: (" sconst "Show items whose names contain the following text: ("
iload 26 iload 26
tostring tostring
sconst " found)" sconst " found)"
join_string 3 join_string 3
iload 26 ; load number of matches iload 26 ; load number of matches
@@ -770,7 +789,7 @@ LABEL694:
runelite_callback ; invoke callback runelite_callback ; invoke callback
pop_int ; pop number of matches pop_int ; pop number of matches
iconst 10616876 iconst 10616876
if_settext if_settext
LABEL701: LABEL701:
jump LABEL716 jump LABEL716
LABEL702: LABEL702:
@@ -780,7 +799,7 @@ LABEL702:
sconst "</col>" sconst "</col>"
join_string 4 join_string 4
iload 5 iload 5
if_settext if_settext
get_varc_int 5 get_varc_int 5
iconst 11 iconst 11
if_icmpeq LABEL713 if_icmpeq LABEL713
@@ -790,7 +809,7 @@ LABEL713:
sconst "setSearchBankInputText" ; load event name sconst "setSearchBankInputText" ; load event name
runelite_callback ; invoke callback runelite_callback ; invoke callback
iconst 10616876 iconst 10616876
if_settext if_settext
LABEL716: LABEL716:
jump LABEL720 jump LABEL720
LABEL717: LABEL717:
@@ -798,7 +817,7 @@ LABEL717:
sconst "setBankTitle" ; sconst "setBankTitle" ;
runelite_callback ; runelite_callback ;
iload 5 iload 5
if_settext if_settext
LABEL720: LABEL720:
iload 0 iload 0
iload 1 iload 1
@@ -821,17 +840,17 @@ LABEL720:
iload 14 iload 14
iload 15 iload 15
invoke 505 invoke 505
return return
LABEL740: LABEL740:
invoke 514 invoke 514
iconst 1 iconst 1
if_icmpeq LABEL744 if_icmpeq LABEL744
jump LABEL747 jump GetTabRange
LABEL744: LABEL744:
iconst 1 iconst 1
iconst 1 iconst 1
invoke 299 invoke 299
LABEL747: GetTabRange:
iconst -1 iconst -1
istore 31 istore 31
iconst -1 iconst -1
@@ -848,18 +867,18 @@ LABEL759:
iload 19 iload 19
iconst 816 iconst 816
if_icmplt LABEL763 if_icmplt LABEL763
jump LABEL843 jump SetTitle
LABEL763: LABEL763:
iload 2 iload 2
iload 19 iload 19
cc_find cc_find
iconst 1 iconst 1
if_icmpeq LABEL769 if_icmpeq LABEL769
jump LABEL838 jump LABEL838
LABEL769: LABEL769:
iconst 95 iconst 95
iload 19 iload 19
inv_getobj inv_getobj
istore 24 istore 24
iload 24 iload 24
iconst -1 iconst -1
@@ -868,7 +887,7 @@ LABEL769:
LABEL777: LABEL777:
iload 28 iload 28
iconst 1 iconst 1
add add
istore 28 istore 28
LABEL781: LABEL781:
iload 19 iload 19
@@ -882,11 +901,11 @@ LABEL785:
jump LABEL836 jump LABEL836
LABEL789: LABEL789:
iconst 0 iconst 0
cc_sethide cc_sethide
iload 24 iload 24
iconst 95 iconst 95
iload 19 iload 19
inv_getnum inv_getnum
iload 2 iload 2
iload 3 iload 3
iload 9 iload 9
@@ -895,22 +914,22 @@ LABEL789:
invoke 278 invoke 278
iload 34 iload 34
iconst 36 iconst 36
multiply multiply
istore 27 istore 27
iconst 51 iconst 51
iload 33 iload 33
iconst 36 iconst 36
iload 23 iload 23
add add
multiply multiply
add add
iload 27 iload 27
iconst 0 iconst 0
iconst 0 iconst 0
cc_setposition cc_setposition
iload 27 iload 27
iconst 32 iconst 32
add add
istore 27 istore 27
iload 33 iload 33
iload 21 iload 21
@@ -919,55 +938,60 @@ LABEL789:
LABEL824: LABEL824:
iload 33 iload 33
iconst 1 iconst 1
add add
istore 33 istore 33
jump LABEL835 jump LABEL835
LABEL829: LABEL829:
iconst 0 iconst 0
iload 34 iload 34
iconst 1 iconst 1
add add
istore 34 istore 34
istore 33 istore 33
LABEL835: LABEL835:
jump LABEL838 jump LABEL838
LABEL836: LABEL836:
iconst 1 iconst 1
cc_sethide cc_sethide
LABEL838: LABEL838:
iload 19 iload 19
iconst 1 iconst 1
add add
istore 19 istore 19
jump LABEL759 jump LABEL759
LABEL843: SetTitle:
iconst 0 ; Compare variable
iconst 0 ;
sconst "isTabMenuActive" ; Check if tag tab menu
runelite_callback ; is active and skip setting
if_icmpne FinishBuilding ; the bank title if it is
get_varbit 4170 get_varbit 4170
iconst 2 iconst 2
if_icmpeq LABEL847 if_icmpeq SetTitleRomanNumeral
jump LABEL857 jump SetTitleNumber
LABEL847: SetTitleRomanNumeral:
sconst "Tab " sconst "Tab "
iconst 105 iconst 105
iconst 115 iconst 115
iconst 207 iconst 207
get_varbit 4150 get_varbit 4150
enum enum
join_string 2 join_string 2
sconst "setBankTitle" ; sconst "setBankTitle" ;
runelite_callback ; runelite_callback ;
iload 5 iload 5
if_settext if_settext
jump LABEL863 jump FinishBuilding
LABEL857: SetTitleNumber:
sconst "Tab " sconst "Tab "
get_varbit 4150 get_varbit 4150
tostring tostring
join_string 2 join_string 2
sconst "setBankTitle" ; sconst "setBankTitle" ;
runelite_callback ; runelite_callback ;
iload 5 iload 5
if_settext if_settext
LABEL863: FinishBuilding:
iload 0 iload 0
iload 1 iload 1
iload 2 iload 2
@@ -987,4 +1011,4 @@ LABEL863:
iload 14 iload 14
iload 15 iload 15
invoke 505 invoke 505
return return
@@ -1 +1 @@
15660E39A740C416BFD71621A448A96FA6B5C5E8AD212179F3D6785AE35CAA38 A9BA4723E7D91AD151C1AB3ABEAF84971BFFD71AA8C23E763ECCC8981A8A1429
@@ -47,7 +47,7 @@ LABEL23:
get_varbit 8119 get_varbit 8119
iconst 1 iconst 1
if_icmpeq LABEL42 if_icmpeq LABEL42
jump LABEL144 jump LABEL146
LABEL42: LABEL42:
iconst 105 iconst 105
iconst 115 iconst 115
@@ -96,11 +96,13 @@ LABEL77:
iload 4 iload 4
iconst 1 iconst 1
if_icmpeq LABEL86 if_icmpeq LABEL86
jump LABEL101 jump LABEL103
LABEL86: LABEL86:
iconst 60
iconst 5 iconst 5
iload 3 iload 3
add add
invoke 1045
iconst 30 iconst 30
iconst 0 iconst 0
iconst 0 iconst 0
@@ -112,8 +114,8 @@ LABEL86:
iconst 2 iconst 2
iconst 10616871 iconst 10616871
if_setposition if_setposition
jump LABEL113 jump LABEL115
LABEL101: LABEL103:
iconst 0 iconst 0
iconst 30 iconst 30
iconst 0 iconst 0
@@ -126,26 +128,26 @@ LABEL101:
iconst 2 iconst 2
iconst 10616871 iconst 10616871
if_setposition if_setposition
LABEL113: LABEL115:
iload 3 iload 3
iconst 10616889 iconst 10616889
if_getwidth if_getwidth
if_icmpgt LABEL118 if_icmpgt LABEL120
jump LABEL124 jump LABEL126
LABEL118: LABEL120:
iconst 2 iconst 2
iconst 2 iconst 2
iconst 0 iconst 0
iconst 10616889 iconst 10616889
if_settextalign if_settextalign
jump LABEL129 jump LABEL131
LABEL124: LABEL126:
iconst 0 iconst 0
iconst 2 iconst 2
iconst 0 iconst 0
iconst 10616889 iconst 10616889
if_settextalign if_settextalign
LABEL129: LABEL131:
iconst 10616889 iconst 10616889
if_clearops if_clearops
iconst -1 iconst -1
@@ -160,8 +162,8 @@ LABEL129:
sconst "" sconst ""
iconst 10616889 iconst 10616889
if_setonop if_setonop
jump LABEL185 jump LABEL187
LABEL144: LABEL146:
iconst 105 iconst 105
iconst 115 iconst 115
iconst 1894 iconst 1894
@@ -203,7 +205,7 @@ LABEL144:
sconst "ii" sconst "ii"
iconst 10616889 iconst 10616889
if_setonop if_setonop
LABEL185: LABEL187:
sload 2 sload 2
iconst 10616889 iconst 10616889
if_settext if_settext
@@ -1 +0,0 @@
C70BDF62710D9FC0EB6707BD94FC0C4335B428DEDD1B52DD51776F811F32C9CF
@@ -1,802 +0,0 @@
.id 1658
.int_stack_count 15
.string_stack_count 0
.int_var_count 25
.string_var_count 1
; Callback "clanChatChannelRebuild" for whenever clan chat is done being built, used inside ClanChatPlugin for ignores
iload 3
iconst 6
iconst 7
iconst 6
sconst "Sort by rank"
iload 0
iload 1
iload 2
iload 3
iload 4
iload 5
iload 6
iload 7
iload 8
iload 9
iload 10
iload 11
iload 12
iload 13
iload 14
invoke 1659
iload 4
iconst 2
iconst 3
iconst 2
sconst "Sort by name"
iload 0
iload 1
iload 2
iload 3
iload 4
iload 5
iload 6
iload 7
iload 8
iload 9
iload 10
iload 11
iload 12
iload 13
iload 14
invoke 1659
iload 5
iconst 8
iconst 9
iconst 9
sconst "Sort by last world change"
iload 0
iload 1
iload 2
iload 3
iload 4
iload 5
iload 6
iload 7
iload 8
iload 9
iload 10
iload 11
iload 12
iload 13
iload 14
invoke 1659
iload 6
iconst 4
iconst 5
iconst 4
sconst "Sort by world"
iload 0
iload 1
iload 2
iload 3
iload 4
iload 5
iload 6
iload 7
iload 8
iload 9
iload 10
iload 11
iload 12
iload 13
iload 14
invoke 1659
iload 7
iconst 0
iconst 1
iconst 0
sconst "Legacy sort"
iload 0
iload 1
iload 2
iload 3
iload 4
iload 5
iload 6
iload 7
iload 8
iload 9
iload 10
iload 11
iload 12
iload 13
iload 14
invoke 1659
3644
get_varc_int 185
switch
1: LABEL109
2: LABEL112
3: LABEL115
4: LABEL184
5: LABEL212
6: LABEL118
7: LABEL148
8: LABEL178
9: LABEL181
jump LABEL239
LABEL109:
iconst 0
3645
jump LABEL239
LABEL112:
iconst 1
3646
jump LABEL239
LABEL115:
iconst 0
3646
jump LABEL239
LABEL118:
iconst 1
3657
get_varc_int 206
switch
3: LABEL125
4: LABEL128
5: LABEL135
8: LABEL142
9: LABEL145
iconst 1
3646
jump LABEL147
LABEL125:
iconst 0
3646
jump LABEL147
LABEL128:
iconst 1
3652
iconst 1
3647
iconst 1
3646
jump LABEL147
LABEL135:
iconst 1
3652
iconst 0
3647
iconst 1
3646
jump LABEL147
LABEL142:
iconst 1
3648
jump LABEL147
LABEL145:
iconst 0
3648
LABEL147:
jump LABEL239
LABEL148:
iconst 0
3657
get_varc_int 206
switch
3: LABEL155
4: LABEL158
5: LABEL165
8: LABEL172
9: LABEL175
iconst 1
3646
jump LABEL177
LABEL155:
iconst 0
3646
jump LABEL177
LABEL158:
iconst 1
3652
iconst 1
3647
iconst 1
3646
jump LABEL177
LABEL165:
iconst 1
3652
iconst 0
3647
iconst 1
3646
jump LABEL177
LABEL172:
iconst 1
3648
jump LABEL177
LABEL175:
iconst 0
3648
LABEL177:
jump LABEL239
LABEL178:
iconst 1
3648
jump LABEL239
LABEL181:
iconst 0
3648
jump LABEL239
LABEL184:
iconst 1
3652
iconst 1
3647
get_varc_int 206
switch
3: LABEL193
6: LABEL196
7: LABEL201
8: LABEL206
9: LABEL209
iconst 1
3646
jump LABEL211
LABEL193:
iconst 0
3646
jump LABEL211
LABEL196:
iconst 1
3657
iconst 1
3646
jump LABEL211
LABEL201:
iconst 0
3657
iconst 1
3646
jump LABEL211
LABEL206:
iconst 1
3648
jump LABEL211
LABEL209:
iconst 0
3648
LABEL211:
jump LABEL239
LABEL212:
iconst 1
3652
iconst 0
3647
get_varc_int 206
switch
3: LABEL221
6: LABEL224
7: LABEL229
8: LABEL234
9: LABEL237
iconst 1
3646
jump LABEL239
LABEL221:
iconst 0
3646
jump LABEL239
LABEL224:
iconst 1
3657
iconst 1
3646
jump LABEL239
LABEL229:
iconst 0
3657
iconst 1
3646
jump LABEL239
LABEL234:
iconst 1
3648
jump LABEL239
LABEL237:
iconst 0
3648
LABEL239:
3655
iload 8
cc_deleteall
clan_getchatcount
istore 15
get_varbit 6363
iconst 1
if_icmpeq LABEL248
jump LABEL296
LABEL248:
iload 15
iconst 0
if_icmpgt LABEL252
jump LABEL253
LABEL252:
clan_leavechat
LABEL253:
iconst 0
istore 15
iconst 0
iload 2
if_sethide
iconst 1
iload 9
if_sethide
iload 11
invoke 2067
pop_int
iconst -1
sconst ""
iload 11
if_setonmouserepeat
iconst -1
sconst ""
iload 11
if_setonmouseleave
iload 13
invoke 2067
pop_int
iconst -1
sconst ""
iload 13
if_setonmouserepeat
iconst -1
sconst ""
iload 13
if_setonmouseleave
sconst "<col=7f7f7f>"
sconst "---"
sconst "</col>"
join_string 3
iload 12
if_settext
iload 12
if_clearops
iconst -1
sconst ""
iload 12
if_setonop
jump LABEL341
LABEL296:
iconst 1
iload 2
if_sethide
iconst 0
iload 9
if_sethide
iload 11
invoke 486
pop_int
iconst 94
iconst -2147483645
sconst "I"
iload 11
if_setonmouserepeat
iconst 92
iconst -2147483645
sconst "I"
iload 11
if_setonmouseleave
iload 13
invoke 486
pop_int
iconst 94
iconst -2147483645
sconst "I"
iload 13
if_setonmouserepeat
iconst 92
iconst -2147483645
sconst "I"
iload 13
if_setonmouseleave
sconst "Clan Setup"
iload 12
if_settext
iconst 1
sconst "Clan Setup"
iload 12
if_setop
iconst 489
iconst -2147483644
iconst 1
sconst "ii"
iload 12
if_setonop
LABEL341:
sconst ""
sstore 0
iconst -1
istore 16
iconst -1
istore 17
clan_getchatrank
istore 18
clan_getchatminkick
istore 19
iload 3
if_getwidth
istore 20
iconst 0
istore 21
iconst 0
istore 22
iconst 15
istore 23
invoke 1972
iconst 1
if_icmpeq LABEL364
jump LABEL369
LABEL364:
iconst 8
iconst 5
iload 23
scale
istore 23
LABEL369:
iconst 0
istore 24
LABEL371:
iload 24
iload 15
if_icmplt LABEL375
jump LABEL572
LABEL375:
iload 24
clan_getchatusername
iload 24
clan_getchatuserworld
iload 24
clan_getchatuserrank
istore 17
istore 16
sstore 0
iload 8
iconst 4
iload 21
cc_create
iload 21
iconst 1
add
istore 21
iload 20
iload 23
iconst 1
iconst 0
cc_setsize
iconst 0
iload 22
iconst 2
iconst 0
cc_setposition
iconst 494
cc_settextfont
iconst 0
iconst 1
iconst 0
cc_settextalign
sload 0
cc_settext
iconst 16777215
cc_setcolour
iconst 0
cc_settextshadow
iload 8
iconst 4
iload 21
cc_create 1
iload 21
iconst 1
add
istore 21
iload 20
iload 23
iconst 1
iconst 0
cc_setsize 1
iconst 0
iload 22
iconst 2
iconst 0
cc_setposition 1
iconst 494
cc_settextfont 1
iconst 2
iconst 1
iconst 0
cc_settextalign 1
sconst "World "
iload 16
tostring
join_string 2
cc_settext 1
iload 16
map_world
if_icmpeq LABEL447
jump LABEL450
LABEL447:
iconst 901389
cc_setcolour 1
jump LABEL452
LABEL450:
iconst 16777060
cc_setcolour 1
LABEL452:
iconst 0
cc_settextshadow 1
iload 8
iconst 5
iload 21
cc_create 1
iload 21
iconst 1
add
istore 21
iconst 9
iconst 9
iconst 0
iconst 0
cc_setsize 1
iconst 1
iload 22
iload 23
iconst 9
sub
iconst 2
div
add
iconst 0
iconst 0
cc_setposition 1
iconst 105
iconst 100
iconst 706
iload 17
enum
cc_setgraphic 1
iload 24
clan_isself
iconst 0
if_icmpeq LABEL489
jump LABEL525
LABEL489:
iload 24
clan_isfriend
iconst 1
if_icmpeq LABEL494
jump LABEL501
LABEL494:
iconst 9
sconst "Remove friend"
cc_setop
iconst 9
sconst "Remove friend"
cc_setop 1
jump LABEL525
LABEL501:
iload 24
clan_isignore
iconst 1
if_icmpeq LABEL506
jump LABEL513
LABEL506:
iconst 10
sconst "Remove ignore"
cc_setop
iconst 10
sconst "Remove ignore"
cc_setop 1
jump LABEL525
LABEL513:
iconst 7
sconst "Add friend"
cc_setop
iconst 7
sconst "Add friend"
cc_setop 1
iconst 8
sconst "Add ignore"
cc_setop
iconst 8
sconst "Add ignore"
cc_setop 1
LABEL525:
invoke 1942
iconst 0
if_icmpeq LABEL529
jump LABEL543
LABEL529:
iload 18
iload 19
if_icmpge LABEL533
jump LABEL543
LABEL533:
iload 18
iload 17
if_icmpgt LABEL537
jump LABEL543
LABEL537:
iconst 6
sconst "Kick user"
cc_setop
iconst 6
sconst "Kick user"
cc_setop 1
LABEL543:
sconst "<col=ff9040>"
sload 0
sconst "</col>"
join_string 3
cc_setopbase
sconst "<col=ff9040>"
sload 0
sconst "</col>"
join_string 3
cc_setopbase 1
iconst 214
sconst "event_opbase"
iconst -2147483644
sconst "si"
cc_setonop
iconst 214
sconst "event_opbase"
iconst -2147483644
sconst "si"
cc_setonop 1
iload 24
iconst 1
add
iload 22
iload 23
add
istore 22
istore 24
jump LABEL371
LABEL572:
iload 15
iconst 1
if_icmpge LABEL576
jump LABEL580
LABEL576:
iload 22
iconst 5
add
istore 22
LABEL580:
iload 10
if_clearops
get_varbit 6363
iconst 1
if_icmpeq LABEL586
jump LABEL605
LABEL586:
sconst ""
iload 0
if_settext
sconst ""
iload 1
if_settext
sconst "<col=7f7f7f>"
sconst "---"
sconst "</col>"
join_string 3
iload 10
if_settext
iload 10
if_clearops
iconst -1
sconst ""
iload 10
if_setonop
jump LABEL672
LABEL605:
iload 15
iconst 0
if_icmpgt LABEL609
jump LABEL653
LABEL609:
sconst "<col=ffff64>"
clan_getchatdisplayname
sconst "</col>"
join_string 3
iload 0
if_settext
sconst "<col=ffffff>"
clan_getchatownername
sconst "</col>"
join_string 3
iload 1
if_settext
sconst "Leave Chat"
iload 10
if_settext
get_varbit 5432
iconst 1
if_icmpeq LABEL631
get_varbit 4289
iconst 0
if_icmpne LABEL631
jump LABEL642
LABEL631:
iconst 6
sconst "Leave Chat"
iload 10
if_setop
iconst 194
iconst -2147483644
iconst 6
sconst "ii"
iload 10
if_setonop
jump LABEL652
LABEL642:
iconst 1
sconst "Leave Chat"
iload 10
if_setop
iconst 194
iconst -2147483644
iconst 1
sconst "ii"
iload 10
if_setonop
LABEL652:
jump LABEL672
LABEL653:
sconst "Not in chat"
iload 0
if_settext
sconst "None"
iload 1
if_settext
sconst "Join Chat"
iload 10
if_settext
iconst 1
sconst "Join Chat"
iload 10
if_setop
iconst 194
iconst -2147483644
iconst 1
sconst "ii"
iload 10
if_setonop
LABEL672:
iload 22
iload 8
if_getheight
if_icmpgt LABEL677
jump LABEL687
LABEL677:
iconst 0
iload 22
iload 8
if_setscrollsize
iload 9
iload 8
iload 8
if_getscrolly
invoke 72
jump LABEL695
LABEL687:
iconst 0
iconst 0
iload 8
if_setscrollsize
iload 9
iload 8
iconst 0
invoke 72
LABEL695:
sconst "clanChatChannelRebuild"
runelite_callback
return
@@ -1 +0,0 @@
15F58F5939D9311F3D76FA2F0F3441B7B0DA1E8EAE23C654948095A7D51E07F0
@@ -1,634 +0,0 @@
.id 1601
.int_stack_count 4
.string_stack_count 2
.int_var_count 14
.string_var_count 3
; callback "itemsKeptOnDeath"
; Used by the ItemsKepthOnDeath plugin to edit the interface
; Put a rune pouch in your inventory and it shouldn't have a white outline
; in the Items kept on death screen
sload 1
iconst 262167
if_settext
iconst 0
istore 4
iconst 0
istore 5
iconst -1
istore 6
iconst 0
istore 7
sconst ""
sstore 2
iconst 0
istore 8
iconst 0
istore 9
iconst 0
istore 10
iconst 0
istore 11
iload 1
define_array 111
iconst 0
istore 12
iconst 0
istore 13
iload 0
iconst 0
if_icmpeq LABEL31
jump LABEL525
LABEL31:
iconst 93
iconst 13190
inv_total
iconst 0
if_icmpgt LABEL42
iconst 93
iconst 13192
inv_total
iconst 0
if_icmpgt LABEL42
jump LABEL44
LABEL42:
iconst 1
istore 9
LABEL44:
iload 10
iload 1
if_icmplt LABEL48
jump LABEL88
LABEL48:
iconst 584
iload 11
inv_getobj
istore 6
iload 6
iconst -1
if_icmpne LABEL56
jump LABEL85
LABEL56:
iconst 584
iload 11
inv_getnum
istore 7
LABEL60:
iload 10
iload 1
if_icmplt LABEL64
jump LABEL80
LABEL64:
iload 7
iconst 0
if_icmpgt LABEL68
jump LABEL80
LABEL68:
iload 10
iload 6
set_array_int
iload 7
iconst 1
sub
istore 7
iload 10
iconst 1
add
istore 10
jump LABEL60
LABEL80:
iload 11
iconst 1
add
istore 11
jump LABEL87
LABEL85:
iload 1
istore 10
LABEL87:
jump LABEL44
LABEL88:
iload 4
iload 1
if_icmplt LABEL92
jump LABEL147
LABEL92:
iconst 262162
iconst 5
iload 4
cc_create
iconst 36
iconst 32
iconst 0
iconst 0
cc_setsize
iconst 5
iload 4
iconst 40
multiply
add
iconst 25
iconst 0
iconst 0
cc_setposition
iload 4
get_array_int
istore 6
iload 6
iconst -1
if_icmpne LABEL117
jump LABEL144
LABEL117:
iload 6
iconst 1
cc_setobject
sconst "<col=ff981f>"
iload 6
oc_name
join_string 2
cc_setopbase
iconst 1
sconst "Item:"
cc_setop
iconst 1603
iconst 1
iconst 1
iload 6
oc_name
sconst "1is"
cc_setonop
iconst 1118481
cc_setgraphicshadow
iconst 1
cc_setoutline
iload 4
iconst 1
add
istore 4
jump LABEL146
LABEL144:
iload 1
istore 4
LABEL146:
jump LABEL88
LABEL147:
iconst 0
istore 4
LABEL149:
iload 4
iconst 468
inv_size
if_icmplt LABEL154
jump LABEL350
LABEL154:
iconst 468
iload 4
inv_getobj
istore 6
iload 6
iconst -1
if_icmpne LABEL162
jump LABEL345
LABEL162:
iconst 262165
iconst 5
iload 5
cc_create
iconst 36
iconst 32
iconst 0
iconst 0
cc_setsize
iconst 5
iload 5
iconst 8
mod
iconst 38
multiply
add
iconst 25
iconst 38
iload 5
iconst 8
div
multiply
add
iconst 0
iconst 0
cc_setposition
iload 6
iconst 468
iload 4
inv_getnum
cc_setobject
sconst "<col=ff981f>"
iload 6
oc_name
join_string 2
cc_setopbase
iconst 1
sconst "Item:"
cc_setop
iconst 1603
iconst 0
iconst 468
iload 4
inv_getnum
iload 6
oc_name
sconst "1is"
cc_setonop
iconst 1118481
cc_setgraphicshadow
iconst 111
iconst 49
iconst 879
iload 6
oc_uncert
enum
iconst 1
if_icmpeq LABEL221
jump LABEL226
LABEL221:
iconst 2
cc_setoutline
iconst 1
istore 8
jump LABEL228
LABEL226:
iconst 1
cc_setoutline
LABEL228:
iload 5
iconst 1
add
istore 5
iload 6
oc_stackable
iconst 1
if_icmpeq LABEL237
jump LABEL345
LABEL237:
iconst 0
istore 10
iconst 0
istore 13
LABEL241:
iload 10
iload 1
if_icmplt LABEL245
jump LABEL259
LABEL245:
iload 10
get_array_int
iload 6
if_icmpeq LABEL250
jump LABEL254
LABEL250:
iload 13
iconst 1
add
istore 13
LABEL254:
iload 10
iconst 1
add
istore 10
jump LABEL241
LABEL259:
iconst 2147483647
iconst 94
iload 6
inv_total
sub
iconst 93
iload 6
inv_total
sub
iload 13
add
istore 12
iconst 0
iload 12
sub
istore 12
iload 12
iconst 0
if_icmpgt LABEL279
jump LABEL345
LABEL279:
iconst 262165
iconst 5
iload 5
cc_create
iconst 36
iconst 32
iconst 0
iconst 0
cc_setsize
iconst 5
iload 5
iconst 8
mod
iconst 38
multiply
add
iconst 25
iconst 38
iload 5
iconst 8
div
multiply
add
iconst 0
iconst 0
cc_setposition
iload 6
iload 12
cc_setobject
sconst "<col=ff981f>"
iload 6
oc_name
join_string 2
cc_setopbase
iconst 1
sconst "Item:"
cc_setop
iconst 1603
iconst 0
iload 12
iload 6
oc_name
sconst "1is"
cc_setonop
iconst 1118481
cc_setgraphicshadow
iconst 111
iconst 49
iconst 879
iload 6
oc_uncert
enum
iconst 1
if_icmpeq LABEL334
jump LABEL339
LABEL334:
iconst 2
cc_setoutline
iconst 1
istore 8
jump LABEL341
LABEL339:
iconst 1
cc_setoutline
LABEL341:
iload 5
iconst 1
add
istore 5
LABEL345:
iload 4
iconst 1
add
istore 4
jump LABEL149
LABEL350:
sconst "The normal amount of items kept is "
sconst "three"
sconst "."
sconst "<br>"
sconst "<br>"
join_string 5
sstore 2
iload 3
iconst 1
if_icmpeq LABEL361
jump LABEL371
LABEL361:
sload 2
sconst "You're an "
sconst "<col=ff3333>"
sconst "Ultimate Iron Man"
sconst "<col=ff981f>"
sconst ", so you will always keep zero items."
join_string 5
append
sstore 2
jump LABEL434
LABEL371:
iload 1
iconst 0
if_icmpeq LABEL375
jump LABEL387
LABEL375:
sload 2
sconst "You're marked with a "
sconst "<col=ff3333>"
sconst "PK skull"
sconst "<col=ff981f>"
sconst ". This reduces the items you keep from "
sconst "three"
sconst " to zero!"
join_string 7
append
sstore 2
jump LABEL434
LABEL387:
iload 1
iconst 1
if_icmpeq LABEL391
jump LABEL410
LABEL391:
sload 2
sconst "You're marked with a "
sconst "<col=ff3333>"
sconst "PK skull"
sconst "<col=ff981f>"
sconst ". This reduces the items you keep from "
sconst "three"
sconst " to zero!"
sconst "<br>"
sconst "<br>"
sconst "However, you also have the "
sconst "<col=ff3333>"
sconst "Protect Items"
sconst "<col=ff981f>"
sconst " prayer active, which saves you one extra item!"
join_string 14
append
sstore 2
jump LABEL434
LABEL410:
iload 1
iconst 3
if_icmpeq LABEL414
jump LABEL419
LABEL414:
sload 2
sconst "You have no factors affecting the items you keep."
append
sstore 2
jump LABEL434
LABEL419:
iload 1
iconst 3
iconst 1
add
if_icmpeq LABEL425
jump LABEL434
LABEL425:
sload 2
sconst "You have the "
sconst "<col=ff3333>"
sconst "Protect Items"
sconst "<col=ff981f>"
sconst " prayer active, which saves you one extra item!"
join_string 5
append
sstore 2
LABEL434:
iload 8
iconst 1
if_icmpeq LABEL441
iload 9
iconst 1
if_icmpeq LABEL441
jump LABEL492
LABEL441:
iload 8
iconst 1
if_icmpeq LABEL445
jump LABEL466
LABEL445:
iload 9
iconst 1
if_icmpeq LABEL449
jump LABEL466
LABEL449:
sload 2
sconst "<br>"
sconst "<br>"
sconst "Items with a "
sconst "<col=ffffff>"
sconst "white outline"
sconst "<col=ff981f>"
sconst " will always be lost."
sconst "<br>"
sconst "<col=00ff00>"
sconst "Bonds"
sconst "</col>"
sconst " are always protected."
join_string 12
append
sstore 2
jump LABEL492
LABEL466:
iload 8
iconst 1
if_icmpeq LABEL470
jump LABEL482
LABEL470:
sload 2
sconst "<br>"
sconst "<br>"
sconst "Items with a "
sconst "<col=ffffff>"
sconst "white outline"
sconst "<col=ff981f>"
sconst " will always be lost."
join_string 7
append
sstore 2
jump LABEL492
LABEL482:
sload 2
sconst "<br>"
sconst "<br>"
sconst "<col=00ff00>"
sconst "Bonds"
sconst "</col>"
sconst " are always protected, so are not shown here."
join_string 6
append
sstore 2
LABEL492:
sload 2
iconst 262173
if_settext
sconst "<col=ffcc33>"
sconst "Max items kept on death :"
sconst "<br>"
sconst "<br>"
sconst "<col=ffcc33>"
sconst "~ "
iload 1
tostring
sconst " ~"
join_string 8
iconst 262174
if_settext
iload 2
iconst 0
if_icmpgt LABEL511
jump LABEL518
LABEL511:
sconst "Items you will keep on death:"
iconst 262161
if_settext
sconst "Items you will lose on death:"
iconst 262164
if_settext
jump LABEL524
LABEL518:
sconst "Items you will keep on death if not skulled:"
iconst 262161
if_settext
sconst "Items you will lose on death if not skulled:"
iconst 262164
if_settext
LABEL524:
jump LABEL565
LABEL525:
iconst 1
iconst 262165
if_sethide
iconst 1
iconst 262162
if_sethide
iconst 0
iconst 262175
if_sethide
sload 0
iconst 262176
if_settext
sconst "The normal amount of items kept is "
sconst "three"
sconst "."
sconst "<br>"
sconst "<br>"
join_string 5
sstore 2
sload 2
sconst "You're in a "
sconst "<col=ff3333>"
sconst "safe area"
sconst "<col=ff981f>"
sconst ". See information to the left for a more detailed description."
join_string 5
append
sstore 2
sload 2
iconst 262173
if_settext
sconst "<col=ffcc33>"
sconst "Max items kept on death :"
sconst "<br>"
sconst "<br>"
sconst "<col=ffcc33>"
sconst "All items!"
join_string 6
iconst 262174
if_settext
LABEL565:
sconst "itemsKeptOnDeath" ; push event name
runelite_callback ; invoke callback
return
@@ -1 +0,0 @@
B370DDEEF61E0F420C1990DDA4FBBEDCEE8324F3750ABAC79B072A27268D887B
@@ -1,394 +0,0 @@
.id 779
.int_stack_count 15
.string_stack_count 0
.int_var_count 16
.string_var_count 1
get_varbit 4397
iconst 1
if_icmpeq LABEL4
jump LABEL65
LABEL4:
iload 0
iload 1
cc_find
iconst 1
if_icmpeq LABEL10
jump LABEL12
LABEL10:
iconst 1
cc_sethide
LABEL12:
iload 0
iload 6
cc_find
iconst 1
if_icmpeq LABEL18
jump LABEL23
LABEL18:
iconst 0
cc_settrans
iconst -1
sconst ""
cc_setontimer
LABEL23:
iload 0
iload 12
cc_find
iconst 1
if_icmpeq LABEL29
jump LABEL31
LABEL29:
iconst 1
cc_sethide
LABEL31:
iload 0
iload 4
cc_find
iconst 1
if_icmpeq LABEL37
jump LABEL39
LABEL37:
sconst "Sell offer"
cc_settext
LABEL39:
iload 0
iload 5
cc_find
iconst 1
if_icmpeq LABEL45
jump LABEL47
LABEL45:
iconst 1119
cc_setgraphic
LABEL47:
iload 0
iload 2
cc_find
iconst 1
if_icmpeq LABEL53
jump LABEL56
LABEL53:
iconst 1
sconst "All"
cc_setop
LABEL56:
iload 0
iload 3
cc_find
iconst 1
if_icmpeq LABEL62
jump LABEL64
LABEL62:
sconst "All"
cc_settext
LABEL64:
jump LABEL130
LABEL65:
iload 0
iload 1
cc_find
iconst 1
if_icmpeq LABEL71
jump LABEL73
LABEL71:
iconst 0
cc_sethide
LABEL73:
iload 0
iload 6
cc_find
iconst 1
if_icmpeq LABEL79
jump LABEL89
LABEL79:
iconst 100
cc_settrans
iconst 811
iconst -2147483645
iconst -2147483643
clientclock
iconst 100
iconst 250
sconst "Iiiii"
cc_setontimer
LABEL89:
iload 0
iload 12
cc_find
iconst 1
if_icmpeq LABEL95
jump LABEL97
LABEL95:
iconst 0
cc_sethide
LABEL97:
iload 0
iload 4
cc_find
iconst 1
if_icmpeq LABEL103
jump LABEL105
LABEL103:
sconst "Buy offer"
cc_settext
LABEL105:
iload 0
iload 5
cc_find
iconst 1
if_icmpeq LABEL111
jump LABEL113
LABEL111:
iconst 1118
cc_setgraphic
LABEL113:
iload 0
iload 2
cc_find
iconst 1
if_icmpeq LABEL119
jump LABEL122
LABEL119:
iconst 1
sconst "+1K"
cc_setop
LABEL122:
iload 0
iload 3
cc_find
iconst 1
if_icmpeq LABEL128
jump LABEL130
LABEL128:
sconst "+1K"
cc_settext
LABEL130:
sconst ","
sstore 0
iconst 0
istore 15
get_varp 1151
iconst -1
if_icmpne LABEL138
jump LABEL274
LABEL138:
iload 0
iload 7
cc_find
iconst 1
if_icmpeq LABEL144
jump LABEL147
LABEL144:
get_varp 1151
get_varbit 4396
cc_setobject_nonum
LABEL147:
iload 0
iload 8
cc_find
iconst 1
if_icmpeq LABEL153
jump LABEL156
LABEL153:
get_varp 1151
oc_name
cc_settext
LABEL156:
iload 0
iload 9
cc_find
iconst 1
if_icmpeq LABEL162
jump LABEL166
LABEL162:
get_varbit 4396
sload 0
invoke 46
cc_settext
LABEL166:
iload 0
iload 10
cc_find
iconst 1
if_icmpeq LABEL172
jump LABEL185
LABEL172:
get_varbit 4398
iconst 1
if_icmpeq LABEL176
jump LABEL179
LABEL176:
sconst "1 coin"
cc_settext
jump LABEL185
LABEL179:
get_varbit 4398
sload 0
invoke 46
sconst " coins"
join_string 2
cc_settext
LABEL185:
get_varbit 4396
iconst 0
if_icmpgt LABEL189
jump LABEL211
LABEL189:
iconst 2147483647
get_varbit 4396
div
get_varbit 4398
if_icmplt LABEL195
jump LABEL211
LABEL195:
iload 0
iload 11
cc_find
iconst 1
if_icmpeq LABEL201
jump LABEL206
LABEL201:
sconst "<col=ff0000>"
sconst "Too much money!"
sconst "</col>"
join_string 3
cc_settext
LABEL206:
iload 0
iload 14
iload 13
invoke 780
jump LABEL273
LABEL211:
get_varbit 4396
get_varbit 4398
multiply
istore 15
iload 0
iload 11
cc_find
iconst 1
if_icmpeq LABEL221
jump LABEL234
LABEL221:
iload 15
iconst 1
if_icmpeq LABEL225
jump LABEL228
LABEL225:
sconst "1 coin"
cc_settext
jump LABEL234
LABEL228:
iload 15
sload 0
invoke 46
sconst " coins"
join_string 2
cc_settext
LABEL234:
iload 15
iconst 0
if_icmpgt LABEL238
jump LABEL269
LABEL238:
iload 13
invoke 208
pop_int
iconst 772
iconst -2147483645
sconst "I"
iload 13
if_setonmouserepeat
iconst 97
iconst -2147483645
sconst "I"
iload 13
if_setonmouseleave
iconst 489
iconst -2147483644
iconst 2
sconst "ii"
iload 13
if_setonop
iload 0
iload 14
cc_find
iconst 1
if_icmpeq LABEL263
jump LABEL268
LABEL263:
sconst "<col=ffffff>"
sconst "Confirm"
sconst "</col>"
join_string 3
cc_settext
LABEL268:
jump LABEL273
LABEL269:
iload 0
iload 14
iload 13
invoke 780
LABEL273:
jump LABEL319
LABEL274:
iload 0
iload 7
cc_find
iconst 1
if_icmpeq LABEL280
jump LABEL283
LABEL280:
iconst 6512
iconst 1
cc_setobject_nonum
LABEL283:
iload 0
iload 8
cc_find
iconst 1
if_icmpeq LABEL289
jump LABEL291
LABEL289:
sconst "Choose an item..."
cc_settext
LABEL291:
iload 0
iload 9
cc_find
iconst 1
if_icmpeq LABEL297
jump LABEL299
LABEL297:
sconst ""
cc_settext
LABEL299:
iload 0
iload 10
cc_find
iconst 1
if_icmpeq LABEL305
jump LABEL307
LABEL305:
sconst ""
cc_settext
LABEL307:
iload 0
iload 11
cc_find
iconst 1
if_icmpeq LABEL313
jump LABEL315
LABEL313:
sconst ""
cc_settext
LABEL315:
iload 0
iload 14
iload 13
invoke 780
LABEL319:
sconst "geBuilt" ;
runelite_callback ;
return
@@ -1 +0,0 @@
FC7F8B54745582D6DD530D5458E129B67D6B3CFF61BACD4BBE7BC8C40E26F3C6
@@ -1,228 +0,0 @@
.id 1354
.int_stack_count 3
.string_stack_count 0
.int_var_count 7
.string_var_count 0
iconst 0
istore 3
iconst 0
istore 4
iconst 0
istore 5
invoke 1340
istore 6
LABEL8:
iload 5
iload 6
if_icmplt LABEL12
jump LABEL64
LABEL12:
iload 0
iload 5
cc_find
iconst 1
if_icmpeq LABEL18
jump LABEL59
LABEL18:
iload 5
invoke 1357
istore 3
iload 5
invoke 3236
iconst 1
if_icmpeq LABEL26
jump LABEL29
LABEL26:
iconst 10461087
istore 4
jump LABEL45
LABEL29:
iload 3
iconst 2
if_icmpeq LABEL33
jump LABEL36
LABEL33:
iconst 901389
istore 4
jump LABEL45
LABEL36:
iload 3
iconst 0
if_icmpeq LABEL40
jump LABEL43
LABEL40:
iconst 16776960
istore 4
jump LABEL45
LABEL43:
iconst 16711680
istore 4
LABEL45:
iload 4
cc_setcolour
iconst 85
iconst -2147483645
iconst -2147483643
iconst 16777215
sconst "Iii"
cc_setonmouseover
iconst 85
iconst -2147483645
iconst -2147483643
iload 4
sconst "Iii"
cc_setonmouseleave
LABEL59:
iload 5
iconst 1
add
istore 5
jump LABEL8
LABEL64:
iconst 0
invoke 2245
istore 6
istore 5
LABEL68:
iload 5
iload 6
if_icmplt LABEL72
jump LABEL124
LABEL72:
iload 1
iload 5
cc_find
iconst 1
if_icmpeq LABEL78
jump LABEL119
LABEL78:
iload 5
invoke 1358
istore 3
iload 5
invoke 3237
iconst 1
if_icmpeq LABEL86
jump LABEL89
LABEL86:
iconst 10461087
istore 4
jump LABEL105
LABEL89:
iload 3
iconst 2
if_icmpeq LABEL93
jump LABEL96
LABEL93:
iconst 901389
istore 4
jump LABEL105
LABEL96:
iload 3
iconst 0
if_icmpeq LABEL100
jump LABEL103
LABEL100:
iconst 16776960
istore 4
jump LABEL105
LABEL103:
iconst 16711680
istore 4
LABEL105:
iload 4
cc_setcolour
iconst 85
iconst -2147483645
iconst -2147483643
iconst 16777215
sconst "Iii"
cc_setonmouseover
iconst 85
iconst -2147483645
iconst -2147483643
iload 4
sconst "Iii"
cc_setonmouseleave
LABEL119:
iload 5
iconst 1
add
istore 5
jump LABEL68
LABEL124:
iconst 0
invoke 2265
istore 6
istore 5
LABEL128:
iload 5
iload 6
if_icmplt LABEL132
jump LABEL184
LABEL132:
iload 2
iload 5
cc_find
iconst 1
if_icmpeq LABEL138
jump LABEL179
LABEL138:
iload 5
invoke 1359
istore 3
iload 5
invoke 3238
iconst 1
if_icmpeq LABEL146
jump LABEL149
LABEL146:
iconst 10461087
istore 4
jump LABEL165
LABEL149:
iload 3
iconst 2
if_icmpeq LABEL153
jump LABEL156
LABEL153:
iconst 901389
istore 4
jump LABEL165
LABEL156:
iload 3
iconst 0
if_icmpeq LABEL160
jump LABEL163
LABEL160:
iconst 16776960
istore 4
jump LABEL165
LABEL163:
iconst 16711680
istore 4
LABEL165:
iload 4
cc_setcolour
iconst 85
iconst -2147483645
iconst -2147483643
iconst 16777215
sconst "Iii"
cc_setonmouseover
iconst 85
iconst -2147483645
iconst -2147483643
iload 4
sconst "Iii"
cc_setonmouseleave
LABEL179:
iload 5
iconst 1
add
istore 5
jump LABEL128
LABEL184:
sconst "questProgressUpdated"
runelite_callback
return
@@ -27,11 +27,14 @@ package net.runelite.client.config;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.testing.fieldbinder.Bind; import com.google.inject.testing.fieldbinder.Bind;
import com.google.inject.testing.fieldbinder.BoundFieldModule; import com.google.inject.testing.fieldbinder.BoundFieldModule;
import java.io.File;
import java.time.Instant; import java.time.Instant;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.client.RuneLite;
import net.runelite.client.account.AccountSession; import net.runelite.client.account.AccountSession;
import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.EventBus;
import org.junit.Assert; import org.junit.Assert;
@@ -64,6 +67,10 @@ public class ConfigManagerTest
@Bind @Bind
private OpenOSRSConfig openOSRSConfig; private OpenOSRSConfig openOSRSConfig;
@Bind
@Named("config")
private File config = RuneLite.DEFAULT_CONFIG_FILE;
@Inject @Inject
ConfigManager manager; ConfigManager manager;
@@ -87,7 +87,7 @@ public class PluginManagerTest
public void before() throws IOException public void before() throws IOException
{ {
Injector injector = Guice.createInjector(Modules Injector injector = Guice.createInjector(Modules
.override(new RuneLiteModule(() -> null, true)) .override(new RuneLiteModule(() -> null, RuneLite.DEFAULT_CONFIG_FILE))
.with(BoundFieldModule.of(this))); .with(BoundFieldModule.of(this)));
RuneLite.setInjector(injector); RuneLite.setInjector(injector);
@@ -116,7 +116,7 @@ public class PluginManagerTest
@Test @Test
public void testLoadPlugins() throws Exception public void testLoadPlugins() throws Exception
{ {
PluginManager pluginManager = new PluginManager(false, null, null, null, null); PluginManager pluginManager = new PluginManager(null, null, null, null);
pluginManager.setOutdated(true); pluginManager.setOutdated(true);
pluginManager.loadCorePlugins(); pluginManager.loadCorePlugins();
Collection<Plugin> plugins = pluginManager.getPlugins(); Collection<Plugin> plugins = pluginManager.getPlugins();
@@ -127,14 +127,13 @@ public class PluginManagerTest
.count(); .count();
assertEquals(expected, plugins.size()); assertEquals(expected, plugins.size());
pluginManager = new PluginManager(false, null, null, null, null); pluginManager = new PluginManager(null, null, null, null);
pluginManager.loadCorePlugins(); pluginManager.loadCorePlugins();
plugins = pluginManager.getPlugins(); plugins = pluginManager.getPlugins();
expected = pluginClasses.stream() expected = pluginClasses.stream()
.map(cl -> (PluginDescriptor) cl.getAnnotation(PluginDescriptor.class)) .map(cl -> (PluginDescriptor) cl.getAnnotation(PluginDescriptor.class))
.filter(Objects::nonNull) .filter(Objects::nonNull)
.filter(pd -> !pd.developerPlugin())
.count(); .count();
assertEquals(expected, plugins.size()); assertEquals(expected, plugins.size());
} }
@@ -144,9 +143,9 @@ public class PluginManagerTest
{ {
List<Module> modules = new ArrayList<>(); List<Module> modules = new ArrayList<>();
modules.add(new GraphvizModule()); modules.add(new GraphvizModule());
modules.add(new RuneLiteModule(() -> null, true)); modules.add(new RuneLiteModule(() -> null, RuneLite.DEFAULT_CONFIG_FILE));
PluginManager pluginManager = new PluginManager(true, null, null, null, null); PluginManager pluginManager = new PluginManager(null, null, null, null);
pluginManager.loadCorePlugins(); pluginManager.loadCorePlugins();
modules.addAll(pluginManager.getPlugins()); modules.addAll(pluginManager.getPlugins());
@@ -198,7 +197,7 @@ public class PluginManagerTest
public void testEventbusAnnotations() throws PluginInstantiationException public void testEventbusAnnotations() throws PluginInstantiationException
{ {
EventBus eventbus = new EventBus(); EventBus eventbus = new EventBus();
PluginManager pluginManager = new PluginManager(true, eventbus, null, null, null) PluginManager pluginManager = new PluginManager(eventbus, null, null, null)
{ {
@Override @Override
public boolean isPluginEnabled(Plugin plugin) public boolean isPluginEnabled(Plugin plugin)
@@ -46,7 +46,10 @@ import static net.runelite.api.SkullIcon.SKULL;
import static net.runelite.api.SkullIcon.SKULL_FIGHT_PIT; import static net.runelite.api.SkullIcon.SKULL_FIGHT_PIT;
import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.LocalPoint;
import net.runelite.api.events.PlayerAppearanceChanged; import net.runelite.api.events.PlayerAppearanceChanged;
import net.runelite.api.events.player.headicon.OverheadPrayerChanged;
import net.runelite.api.events.player.headicon.PlayerSkullChanged;
import net.runelite.api.mixins.Copy; import net.runelite.api.mixins.Copy;
import net.runelite.api.mixins.FieldHook;
import net.runelite.api.mixins.Inject; import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.MethodHook; import net.runelite.api.mixins.MethodHook;
import net.runelite.api.mixins.Mixin; import net.runelite.api.mixins.Mixin;
@@ -67,6 +70,12 @@ public abstract class RSPlayerMixin implements RSPlayer
@Inject @Inject
private boolean friended; private boolean friended;
@Inject
private int oldHeadIcon = -1;
@Inject
private int oldSkullIcon = -1;
@Inject @Inject
@Override @Override
public String getName() public String getName()
@@ -88,11 +97,53 @@ public abstract class RSPlayerMixin implements RSPlayer
return name.replace('\u00A0', ' '); return name.replace('\u00A0', ' ');
} }
@Inject
@FieldHook("headIconPrayer")
public void prayerChanged(int idx)
{
if (!(getRsOverheadIcon() == -1 && oldHeadIcon == -1))
{
final HeadIcon headIcon = getHeadIcon(getRsOverheadIcon());
if (getRsOverheadIcon() != oldHeadIcon)
{
client.getCallbacks().post(OverheadPrayerChanged.class,
new OverheadPrayerChanged(this, getHeadIcon(oldHeadIcon), headIcon));
}
}
oldHeadIcon = getRsOverheadIcon();
}
@Inject @Inject
@Override @Override
public HeadIcon getOverheadIcon() public HeadIcon getOverheadIcon()
{ {
switch (getRsOverheadIcon()) return getHeadIcon(getRsOverheadIcon());
}
@Inject
@FieldHook("headIconPk")
public void skullChanged(int idx)
{
final SkullIcon skullIcon = skullFromInt(getRsSkullIcon());
if (getRsSkullIcon() != oldSkullIcon)
{
client.getCallbacks().post(PlayerSkullChanged.class,
new PlayerSkullChanged(this, skullFromInt(getRsSkullIcon()), skullIcon));
}
oldSkullIcon = getRsSkullIcon();
}
@Inject
@Override
public SkullIcon getSkullIcon()
{
return skullFromInt(getRsSkullIcon());
}
@Inject
private HeadIcon getHeadIcon(int overheadIcon)
{
switch (overheadIcon)
{ {
case 0: case 0:
return MELEE; return MELEE;
@@ -112,10 +163,9 @@ public abstract class RSPlayerMixin implements RSPlayer
} }
@Inject @Inject
@Override private SkullIcon skullFromInt(int skull)
public SkullIcon getSkullIcon()
{ {
switch (getRsSkullIcon()) switch (skull)
{ {
case 0: case 0:
return SKULL; return SKULL;
@@ -71,4 +71,13 @@ public interface RSItemDefinition extends ItemDefinition
@Import("getModel") @Import("getModel")
RSModel getModel(int quantity); RSModel getModel(int quantity);
@Import("unnotedId")
int getInventoryModel();
@Import("recolorTo")
short[] getColorToReplaceWith();
@Import("retextureTo")
short[] getTextureToReplaceWith();
} }