Merge pull request #3105 from SRLJustin/upstream-03012022

upstream: merge
This commit is contained in:
Justin
2022-01-04 16:54:53 +11:00
committed by GitHub
81 changed files with 1023 additions and 380 deletions

View File

@@ -25,9 +25,9 @@
object ProjectVersions { object ProjectVersions {
const val launcherVersion = "2.2.0" const val launcherVersion = "2.2.0"
const val rlVersion = "1.8.7.1" const val rlVersion = "1.8.8"
const val openosrsVersion = "4.17.1" const val openosrsVersion = "4.17.2"
const val rsversion = 202 const val rsversion = 202
const val cacheversion = 165 const val cacheversion = 165

View File

@@ -60,7 +60,6 @@ public class RegionLoader
this.store = store; this.store = store;
index = store.getIndex(IndexType.MAPS); index = store.getIndex(IndexType.MAPS);
keyManager = new XteaKeyManager(); keyManager = new XteaKeyManager();
keyManager.loadKeys();
} }
public void loadRegions() throws IOException public void loadRegions() throws IOException

View File

@@ -26,8 +26,6 @@ package net.runelite.cache.util;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import net.runelite.http.api.RuneLiteAPI;
import net.runelite.http.api.xtea.XteaClient;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -39,8 +37,6 @@ public class XteaKeyManager
public void loadKeys() public void loadKeys()
{ {
XteaClient xteaClient = new XteaClient(RuneLiteAPI.CLIENT);
keys = null; keys = null;
logger.info("Loaded {} keys", keys.size()); logger.info("Loaded {} keys", keys.size());

View File

@@ -25,8 +25,8 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--> -->
<!DOCTYPE module PUBLIC <!DOCTYPE module PUBLIC
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN" "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd"> "https://checkstyle.org/dtds/configuration_1_3.dtd">
<module name="Checker"> <module name="Checker">
<module name="TreeWalker"> <module name="TreeWalker">
<module name="SuppressionCommentFilter"/> <module name="SuppressionCommentFilter"/>

View File

@@ -34,6 +34,7 @@ dependencies {
implementation(group = "com.google.code.gson", name = "gson", version = "2.8.5") implementation(group = "com.google.code.gson", name = "gson", version = "2.8.5")
implementation(group = "com.google.guava", name = "guava", version = "30.1.1-jre") implementation(group = "com.google.guava", name = "guava", version = "30.1.1-jre")
implementation(group = "com.google.inject", name = "guice", version = "5.0.1")
implementation(group = "com.squareup.okhttp3", name = "okhttp", version = "4.9.1") implementation(group = "com.squareup.okhttp3", name = "okhttp", version = "4.9.1")
implementation(group = "org.apache.commons", name = "commons-csv", version = "1.9.0") implementation(group = "org.apache.commons", name = "commons-csv", version = "1.9.0")
implementation(group = "org.slf4j", name = "slf4j-api", version = "1.7.32") implementation(group = "org.slf4j", name = "slf4j-api", version = "1.7.32")

View File

@@ -51,17 +51,12 @@ public class RuneLiteAPI
public static final String RUNELITE_AUTH = "RUNELITE-AUTH"; public static final String RUNELITE_AUTH = "RUNELITE-AUTH";
public static final String RUNELITE_MACHINEID = "RUNELITE-MACHINEID"; public static final String RUNELITE_MACHINEID = "RUNELITE-MACHINEID";
public static final OkHttpClient CLIENT; public static OkHttpClient CLIENT;
public static final Gson GSON; public static final Gson GSON;
public static final MediaType JSON = MediaType.parse("application/json"); public static final MediaType JSON = MediaType.parse("application/json");
public static String userAgent; public static String userAgent;
private static final String BASE = "https://api.runelite.net"; private static final String BASE = "https://api.runelite.net";
private static final String WSBASE = "https://api.runelite.net/ws";
private static final String STATICBASE = "https://static.runelite.net";
private static final String OPENOSRS_SESSION = "https://session.openosrs.dev";
private static final String OPENOSRS_XTEA = "https://xtea.openosrs.dev";
private static final Properties properties = new Properties(); private static final Properties properties = new Properties();
private static String version; private static String version;
@@ -123,11 +118,6 @@ public class RuneLiteAPI
GSON = gsonBuilder.create(); GSON = gsonBuilder.create();
} }
public static HttpUrl getSessionBase()
{
return HttpUrl.parse(OPENOSRS_SESSION);
}
public static HttpUrl getApiBase() public static HttpUrl getApiBase()
{ {
final String prop = System.getProperty("runelite.http-service.url"); final String prop = System.getProperty("runelite.http-service.url");
@@ -140,43 +130,9 @@ public class RuneLiteAPI
return HttpUrl.parse(BASE + "/runelite-" + getVersion()); return HttpUrl.parse(BASE + "/runelite-" + getVersion());
} }
public static HttpUrl getStaticBase()
{
final String prop = System.getProperty("runelite.static.url");
if (prop != null && !prop.isEmpty())
{
return HttpUrl.parse(prop);
}
return HttpUrl.parse(STATICBASE);
}
public static HttpUrl getWsEndpoint()
{
final String prop = System.getProperty("runelite.ws.url");
if (prop != null && !prop.isEmpty())
{
return HttpUrl.parse(prop);
}
return HttpUrl.parse(WSBASE);
}
public static HttpUrl getXteaBase()
{
return HttpUrl.parse(OPENOSRS_XTEA);
}
public static String getVersion() public static String getVersion()
{ {
return version; return version;
} }
public static void setVersion(String version)
{
RuneLiteAPI.version = version;
}
} }

View File

@@ -187,9 +187,9 @@ public final class RuntimeTypeAdapterFactory<T> implements TypeAdapterFactory {
} }
final Map<String, TypeAdapter<?>> labelToDelegate final Map<String, TypeAdapter<?>> labelToDelegate
= new LinkedHashMap<String, TypeAdapter<?>>(); = new LinkedHashMap<String, TypeAdapter<?>>();
final Map<Class<?>, TypeAdapter<?>> subtypeToDelegate final Map<Class<?>, TypeAdapter<?>> subtypeToDelegate
= new LinkedHashMap<Class<?>, TypeAdapter<?>>(); = new LinkedHashMap<Class<?>, TypeAdapter<?>>();
for (Map.Entry<String, Class<?>> entry : labelToSubtype.entrySet()) { for (Map.Entry<String, Class<?>> entry : labelToSubtype.entrySet()) {
TypeAdapter<?> delegate = gson.getDelegateAdapter(this, TypeToken.get(entry.getValue())); TypeAdapter<?> delegate = gson.getDelegateAdapter(this, TypeToken.get(entry.getValue()));
labelToDelegate.put(entry.getKey(), delegate); labelToDelegate.put(entry.getKey(), delegate);
@@ -202,14 +202,14 @@ public final class RuntimeTypeAdapterFactory<T> implements TypeAdapterFactory {
JsonElement labelJsonElement = jsonElement.getAsJsonObject().remove(typeFieldName); JsonElement labelJsonElement = jsonElement.getAsJsonObject().remove(typeFieldName);
if (labelJsonElement == null) { if (labelJsonElement == null) {
throw new JsonParseException("cannot deserialize " + baseType throw new JsonParseException("cannot deserialize " + baseType
+ " because it does not define a field named " + typeFieldName); + " because it does not define a field named " + typeFieldName);
} }
String label = labelJsonElement.getAsString(); String label = labelJsonElement.getAsString();
@SuppressWarnings("unchecked") // registration requires that subtype extends T @SuppressWarnings("unchecked") // registration requires that subtype extends T
TypeAdapter<R> delegate = (TypeAdapter<R>) labelToDelegate.get(label); TypeAdapter<R> delegate = (TypeAdapter<R>) labelToDelegate.get(label);
if (delegate == null) { if (delegate == null) {
throw new JsonParseException("cannot deserialize " + baseType + " subtype named " throw new JsonParseException("cannot deserialize " + baseType + " subtype named "
+ label + "; did you forget to register a subtype?"); + label + "; did you forget to register a subtype?");
} }
return delegate.fromJsonTree(jsonElement); return delegate.fromJsonTree(jsonElement);
} }
@@ -221,12 +221,12 @@ public final class RuntimeTypeAdapterFactory<T> implements TypeAdapterFactory {
TypeAdapter<R> delegate = (TypeAdapter<R>) subtypeToDelegate.get(srcType); TypeAdapter<R> delegate = (TypeAdapter<R>) subtypeToDelegate.get(srcType);
if (delegate == null) { if (delegate == null) {
throw new JsonParseException("cannot serialize " + srcType.getName() throw new JsonParseException("cannot serialize " + srcType.getName()
+ "; did you forget to register a subtype?"); + "; did you forget to register a subtype?");
} }
JsonObject jsonObject = delegate.toJsonTree(value).getAsJsonObject(); JsonObject jsonObject = delegate.toJsonTree(value).getAsJsonObject();
if (jsonObject.has(typeFieldName)) { if (jsonObject.has(typeFieldName)) {
throw new JsonParseException("cannot serialize " + srcType.getName() throw new JsonParseException("cannot serialize " + srcType.getName()
+ " because it already defines a field named " + typeFieldName); + " because it already defines a field named " + typeFieldName);
} }
JsonObject clone = new JsonObject(); JsonObject clone = new JsonObject();
clone.add(typeFieldName, new JsonPrimitive(label)); clone.add(typeFieldName, new JsonPrimitive(label));

View File

@@ -31,7 +31,8 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.List; import java.util.List;
import lombok.AllArgsConstructor; import javax.inject.Inject;
import javax.inject.Named;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.RuneLiteAPI;
import static net.runelite.http.api.RuneLiteAPI.JSON; import static net.runelite.http.api.RuneLiteAPI.JSON;
@@ -44,25 +45,30 @@ import okhttp3.RequestBody;
import okhttp3.Response; import okhttp3.Response;
@Slf4j @Slf4j
@AllArgsConstructor
public class XteaClient public class XteaClient
{ {
private final OkHttpClient client; private final OkHttpClient client;
private final HttpUrl apiBase;
@Inject
public XteaClient(OkHttpClient client, @Named("runelite.api.base") HttpUrl apiBase)
{
this.client = client;
this.apiBase = apiBase;
}
public void submit(XteaRequest xteaRequest) public void submit(XteaRequest xteaRequest)
{ {
String json = RuneLiteAPI.GSON.toJson(xteaRequest); HttpUrl url = apiBase.newBuilder()
.addPathSegment("xtea")
HttpUrl url = RuneLiteAPI.getXteaBase().newBuilder() .build();
.addPathSegment("xtea")
.build();
log.debug("Built URI: {}", url); log.debug("Built URI: {}", url);
Request request = new Request.Builder() Request request = new Request.Builder()
.post(RequestBody.create(JSON, json)) .post(RequestBody.create(JSON, RuneLiteAPI.GSON.toJson(xteaRequest)))
.url(url) .url(url)
.build(); .build();
client.newCall(request).enqueue(new Callback() client.newCall(request).enqueue(new Callback()
{ {
@@ -75,7 +81,7 @@ public class XteaClient
@Override @Override
public void onResponse(Call call, Response response) public void onResponse(Call call, Response response)
{ {
try try // NOPMD: UseTryWithResources
{ {
if (!response.isSuccessful()) if (!response.isSuccessful())
{ {
@@ -92,13 +98,13 @@ public class XteaClient
public List<XteaKey> get() throws IOException public List<XteaKey> get() throws IOException
{ {
HttpUrl url = RuneLiteAPI.getXteaBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("xtea") .addPathSegment("xtea")
.build(); .build();
Request request = new Request.Builder() Request request = new Request.Builder()
.url(url) .url(url)
.build(); .build();
try (Response response = client.newCall(request).execute()) try (Response response = client.newCall(request).execute())
{ {
@@ -115,14 +121,14 @@ public class XteaClient
public XteaKey get(int region) throws IOException public XteaKey get(int region) throws IOException
{ {
HttpUrl url = RuneLiteAPI.getXteaBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("xtea") .addPathSegment("xtea")
.addPathSegment(Integer.toString(region)) .addPathSegment(Integer.toString(region))
.build(); .build();
Request request = new Request.Builder() Request request = new Request.Builder()
.url(url) .url(url)
.build(); .build();
try (Response response = client.newCall(request).execute()) try (Response response = client.newCall(request).execute())
{ {

View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) 2021 Abex
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.http.api.gson;
import java.awt.Color;
import net.runelite.http.api.RuneLiteAPI;
import org.junit.Assert;
import org.junit.Test;
public class ColorTypeAdapterTest
{
@Test
public void test()
{
test("null", null, true);
test("{\"value\":-13347208,\"falpha\":0.0}", new Color(0x12345678, false), false);
test("{\"value\":305419896,\"falpha\":0.0}", new Color(0x12345678, true), false);
test("{\"value\":-1.4221317E7,\"falpha\":0.0}", new Color(0xFF26FFFB, true), false);
test("\"#FF345678\"", new Color(0x12345678, false), true);
test("\"#12345678\"", new Color(0x12345678, true), true);
test("\"#FF26FFFB\"", new Color(0xFF26FFFB, true), true);
}
private void test(String json, Color object, boolean exactEncoding)
{
Color parsed = RuneLiteAPI.GSON.fromJson(json, Color.class);
Assert.assertEquals(object, parsed);
String serialized = RuneLiteAPI.GSON.toJson(object);
if (exactEncoding)
{
Assert.assertEquals(json, serialized);
}
Color roundTripped = RuneLiteAPI.GSON.fromJson(serialized, Color.class);
Assert.assertEquals(object, roundTripped);
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright (c) 2021 Abex
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.http.api.gson;
import java.time.Instant;
import net.runelite.http.api.RuneLiteAPI;
import org.junit.Assert;
import org.junit.Test;
public class InstantTypeAdapterTest
{
@Test
public void test()
{
test("null", null, true);
test("{\"seconds\":1609538310,\"nanos\":291000000}", Instant.ofEpochSecond(1609538310, 291_000_000), false);
test("1609538310291", Instant.ofEpochSecond(1609538310, 291_000_000), true);
}
private void test(String json, Instant object, boolean exactEncoding)
{
Instant parsed = RuneLiteAPI.GSON.fromJson(json, Instant.class);
Assert.assertEquals(object, parsed);
String serialized = RuneLiteAPI.GSON.toJson(object);
if (exactEncoding)
{
Assert.assertEquals(json, serialized);
}
Instant roundTripped = RuneLiteAPI.GSON.fromJson(serialized, Instant.class);
Assert.assertEquals(object, roundTripped);
}
}

View File

@@ -1114,7 +1114,9 @@ public interface Client extends GameEngine
* Loads a model from the cache * Loads a model from the cache
* *
* @param id the ID of the model * @param id the ID of the model
* @return the model or null if it is loading or nonexistent
*/ */
@Nullable
Model loadModel(int id); Model loadModel(int id);
/** /**
@@ -1123,7 +1125,9 @@ public interface Client extends GameEngine
* @param id the ID of the model * @param id the ID of the model
* @param colorToFind array of hsl color values to find in the model to replace * @param colorToFind array of hsl color values to find in the model to replace
* @param colorToReplace array of hsl color values to replace in the model * @param colorToReplace array of hsl color values to replace in the model
* @return the model or null if it is loading or nonexistent
*/ */
@Nullable
Model loadModel(int id, short[] colorToFind, short[] colorToReplace); Model loadModel(int id, short[] colorToFind, short[] colorToReplace);
/** /**

View File

@@ -54,4 +54,14 @@ public interface DecorativeObject extends TileObject
* account for walls of varying widths. * account for walls of varying widths.
*/ */
int getYOffset(); int getYOffset();
/**
* A bitfield containing various flags:
* <pre>{@code
* object type id = bits & 0x20
* orientation (0-3) = bits >>> 6 & 3
* supports items = bits >>> 8 & 1
* }</pre>
*/
int getConfig();
} }

View File

@@ -93,4 +93,14 @@ public interface GameObject extends TileObject
* @see net.runelite.api.coords.Angle * @see net.runelite.api.coords.Angle
*/ */
int getModelOrientation(); int getModelOrientation();
/**
* A bitfield containing various flags:
* <pre>{@code
* object type id = bits & 0x20
* orientation (0-3) = bits >>> 6 & 3
* supports items = bits >>> 8 & 1
* }</pre>
*/
int getConfig();
} }

View File

@@ -42,4 +42,14 @@ public interface GroundObject extends TileObject
* @see net.runelite.api.model.Jarvis * @see net.runelite.api.model.Jarvis
*/ */
Shape getConvexHull(); Shape getConvexHull();
/**
* A bitfield containing various flags:
* <pre>{@code
* object type id = bits & 0x20
* orientation (0-3) = bits >>> 6 & 3
* supports items = bits >>> 8 & 1
* }</pre>
*/
int getConfig();
} }

View File

@@ -53,6 +53,12 @@ public interface ScriptEvent
*/ */
ScriptEvent setSource(Widget widget); ScriptEvent setSource(Widget widget);
/**
* Arguments passed to the script. Index 0 is the script being run and is not an argument.
* @return
*/
Object[] getArguments();
/** /**
* Gets the menu index of the event * Gets the menu index of the event
* *
@@ -73,6 +79,11 @@ public interface ScriptEvent
*/ */
int getMouseX(); int getMouseX();
/**
* Parent relative y coordinate for mouse related events
*/
int getMouseY();
/** /**
* Jagex typed keycode * Jagex typed keycode
* *

View File

@@ -27,37 +27,46 @@ package net.runelite.api;
import java.awt.Shape; import java.awt.Shape;
/** /**
* Represents the wall of a tile, which is an un-passable boundary. * Represents one or two walls on a tile
*/ */
public interface WallObject extends TileObject public interface WallObject extends TileObject
{ {
/** /**
* Gets the first orientation of the wall. * A bitfield with the orientation of the first wall
* * 1 = West
* @return the first orientation, 0-2048 where 0 is north * 2 = North
* 4 = East
* 8 = South
* 16 = North-west
* 32 = North-east
* 64 = South-east
* 128 = South-west
*/ */
int getOrientationA(); int getOrientationA();
/** /**
* Gets the second orientation value of the wall. * A bitfield with the orientation of the second wall
* * 1 = West
* @return the second orientation, 0-2048 where 0 is north * 2 = North
* 4 = East
* 8 = South
* 16 = North-west
* 32 = North-east
* 64 = South-east
* 128 = South-west
*/ */
int getOrientationB(); int getOrientationB();
/** /**
* Gets the boundary configuration of the wall. * A bitfield containing various flags:
* * <pre>{@code
* @return the boundary configuration * object type id = bits & 0x20
* orientation (0-3) = bits >>> 6 & 3
* supports items = bits >>> 8 & 1
* }</pre>
*/ */
int getConfig(); int getConfig();
Renderable getRenderable1();
Renderable getRenderable2();
Model getModelA();
Model getModelB();
/** /**
* Gets the convex hull of the objects model. * Gets the convex hull of the objects model.
* *
@@ -66,4 +75,10 @@ public interface WallObject extends TileObject
*/ */
Shape getConvexHull(); Shape getConvexHull();
Shape getConvexHull2(); Shape getConvexHull2();
Renderable getRenderable1();
Renderable getRenderable2();
Model getModelA();
Model getModelB();
} }

View File

@@ -199,7 +199,7 @@ public class WorldPoint
// get the template chunk for the chunk // get the template chunk for the chunk
int[][][] instanceTemplateChunks = client.getInstanceTemplateChunks(); int[][][] instanceTemplateChunks = client.getInstanceTemplateChunks();
int templateChunk = instanceTemplateChunks[client.getPlane()][chunkX][chunkY]; int templateChunk = instanceTemplateChunks[plane][chunkX][chunkY];
int rotation = templateChunk >> 1 & 0x3; int rotation = templateChunk >> 1 & 0x3;
int templateChunkY = (templateChunk >> 3 & 0x7FF) * CHUNK_SIZE; int templateChunkY = (templateChunk >> 3 & 0x7FF) * CHUNK_SIZE;

View File

@@ -551,8 +551,8 @@ public enum WidgetInfo
TRAILBLAZER_AREA_TELEPORT(WidgetID.TRAILBLAZER_AREAS_GROUP_ID, WidgetID.TrailblazerAreas.TELEPORT), TRAILBLAZER_AREA_TELEPORT(WidgetID.TRAILBLAZER_AREAS_GROUP_ID, WidgetID.TrailblazerAreas.TELEPORT),
MULTICOMBAT_FIXED(WidgetID.FIXED_VIEWPORT_GROUP_ID, WidgetID.FixedViewport.MULTICOMBAT_INDICATOR), MULTICOMBAT_FIXED(WidgetID.FIXED_VIEWPORT_GROUP_ID, WidgetID.FixedViewport.MULTICOMBAT_INDICATOR),
MULTICOMBAT_RESIZEABLE_MODERN(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewport.MULTICOMBAT_INDICATOR), MULTICOMBAT_RESIZABLE_MODERN(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewport.MULTICOMBAT_INDICATOR),
MULTICOMBAT_RESIZEABLE_CLASSIC(WidgetID.RESIZABLE_VIEWPORT_OLD_SCHOOL_BOX_GROUP_ID, WidgetID.ResizableViewport.MULTICOMBAT_INDICATOR), MULTICOMBAT_RESIZABLE_CLASSIC(WidgetID.RESIZABLE_VIEWPORT_OLD_SCHOOL_BOX_GROUP_ID, WidgetID.ResizableViewport.MULTICOMBAT_INDICATOR),
TEMPOROSS_STATUS_INDICATOR(WidgetID.TEMPOROSS_GROUP_ID, WidgetID.TemporossStatus.STATUS_INDICATOR), TEMPOROSS_STATUS_INDICATOR(WidgetID.TEMPOROSS_GROUP_ID, WidgetID.TemporossStatus.STATUS_INDICATOR),

View File

@@ -38,7 +38,6 @@ import net.runelite.api.GameState;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ClientShutdown; import net.runelite.client.events.ClientShutdown;
import net.runelite.client.util.RunnableExceptionLogger; import net.runelite.client.util.RunnableExceptionLogger;
import okhttp3.OkHttpClient;
@Singleton @Singleton
@Slf4j @Slf4j
@@ -54,11 +53,11 @@ public class ClientSessionManager
@Inject @Inject
ClientSessionManager(ScheduledExecutorService executorService, ClientSessionManager(ScheduledExecutorService executorService,
@Nullable Client client, @Nullable Client client,
OkHttpClient okHttpClient) SessionClient sessionClient)
{ {
this.executorService = executorService; this.executorService = executorService;
this.client = client; this.client = client;
this.sessionClient = new SessionClient(okHttpClient); this.sessionClient = sessionClient;
} }
public void start() public void start()

View File

@@ -49,6 +49,7 @@ import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.Locale; import java.util.Locale;
import java.util.concurrent.TimeUnit;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Stream; import java.util.stream.Stream;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -91,6 +92,7 @@ import net.runelite.http.api.worlds.World;
import net.runelite.http.api.worlds.WorldResult; import net.runelite.http.api.worlds.WorldResult;
import okhttp3.Cache; import okhttp3.Cache;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -109,6 +111,7 @@ public class RuneLite
public static final File DEFAULT_CONFIG_FILE = new File(RUNELITE_DIR, "settings.properties"); public static final File DEFAULT_CONFIG_FILE = new File(RUNELITE_DIR, "settings.properties");
private static final int MAX_OKHTTP_CACHE_SIZE = 20 * 1024 * 1024; // 20mb private static final int MAX_OKHTTP_CACHE_SIZE = 20 * 1024 * 1024; // 20mb
public static String USER_AGENT = "RuneLite/" + RuneLiteProperties.getVersion() + "-" + RuneLiteProperties.getCommit() + (RuneLiteProperties.isDirty() ? "+" : "");
@Getter @Getter
private static Injector injector; private static Injector injector;
@@ -273,16 +276,8 @@ public class RuneLite
OpenOSRS.preload(); OpenOSRS.preload();
OkHttpClient.Builder okHttpClientBuilder = RuneLiteAPI.CLIENT.newBuilder(); final OkHttpClient okHttpClient = buildHttpClient(options.has("insecure-skip-tls-verification"));
setupCache(okHttpClientBuilder, new File(CACHE_DIR, "okhttp")); RuneLiteAPI.CLIENT = okHttpClient;
final boolean insecureSkipTlsVerification = options.has("insecure-skip-tls-verification");
if (insecureSkipTlsVerification || RuneLiteProperties.isInsecureSkipTlsVerification())
{
setupInsecureTrustManager(okHttpClientBuilder);
}
final OkHttpClient okHttpClient = okHttpClientBuilder.build();
SplashScreen.init(); SplashScreen.init();
OpenOSRSSplashScreen.init(); OpenOSRSSplashScreen.init();
@@ -532,9 +527,20 @@ public class RuneLite
} }
@VisibleForTesting @VisibleForTesting
static void setupCache(OkHttpClient.Builder builder, File cacheDir) static OkHttpClient buildHttpClient(boolean insecureSkipTlsVerification)
{ {
builder.cache(new Cache(cacheDir, MAX_OKHTTP_CACHE_SIZE)) OkHttpClient.Builder builder = new OkHttpClient.Builder()
.pingInterval(30, TimeUnit.SECONDS)
.addNetworkInterceptor(chain ->
{
Request userAgentRequest = chain.request()
.newBuilder()
.header("User-Agent", USER_AGENT)
.build();
return chain.proceed(userAgentRequest);
})
// Setup cache
.cache(new Cache(new File(CACHE_DIR, "okhttp"), MAX_OKHTTP_CACHE_SIZE))
.addNetworkInterceptor(chain -> .addNetworkInterceptor(chain ->
{ {
// This has to be a network interceptor so it gets hit before the cache tries to store stuff // This has to be a network interceptor so it gets hit before the cache tries to store stuff
@@ -548,6 +554,13 @@ public class RuneLite
} }
return res; return res;
}); });
if (insecureSkipTlsVerification || RuneLiteProperties.isInsecureSkipTlsVerification())
{
setupInsecureTrustManager(builder);
}
return builder.build();
} }
private static void setupInsecureTrustManager(OkHttpClient.Builder okHttpClientBuilder) private static void setupInsecureTrustManager(OkHttpClient.Builder okHttpClientBuilder)

View File

@@ -25,6 +25,7 @@
package net.runelite.client; package net.runelite.client;
import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.google.common.base.Strings;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Provides; import com.google.inject.Provides;
@@ -41,6 +42,7 @@ import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Supplier; import java.util.function.Supplier;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import net.runelite.api.Client; import net.runelite.api.Client;
@@ -59,7 +61,7 @@ import net.runelite.client.task.Scheduler;
import net.runelite.client.util.DeferredEventBus; import net.runelite.client.util.DeferredEventBus;
import net.runelite.client.util.ExecutorServiceExceptionLogger; import net.runelite.client.util.ExecutorServiceExceptionLogger;
import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.RuneLiteAPI;
import net.runelite.http.api.chat.ChatClient; import okhttp3.HttpUrl;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
@AllArgsConstructor @AllArgsConstructor
@@ -135,10 +137,35 @@ public class RuneLiteModule extends AbstractModule
} }
@Provides @Provides
@Singleton @Named("runelite.api.base")
ChatClient provideChatClient(OkHttpClient okHttpClient) HttpUrl provideApiBase(@Named("runelite.api.base") String s)
{ {
return new ChatClient(okHttpClient); final String prop = System.getProperty("runelite.http-service.url");
return HttpUrl.get(Strings.isNullOrEmpty(prop) ? s : prop);
}
@Provides
@Named("runelite.session")
HttpUrl provideSession(@Named("runelite.session") String s)
{
final String prop = System.getProperty("runelite.session.url");
return HttpUrl.get(Strings.isNullOrEmpty(prop) ? s : prop);
}
@Provides
@Named("runelite.static.base")
HttpUrl provideStaticBase(@Named("runelite.static.base") String s)
{
final String prop = System.getProperty("runelite.static.url");
return HttpUrl.get(Strings.isNullOrEmpty(prop) ? s : prop);
}
@Provides
@Named("runelite.ws")
HttpUrl provideWs(@Named("runelite.ws") String s)
{
final String prop = System.getProperty("runelite.ws.url");
return HttpUrl.get(Strings.isNullOrEmpty(prop) ? s : prop);
} }
@Provides @Provides

View File

@@ -36,6 +36,8 @@ public class RuneLiteProperties
{ {
private static final String RUNELITE_TITLE = "runelite.title"; private static final String RUNELITE_TITLE = "runelite.title";
private static final String RUNELITE_VERSION = "runelite.version"; private static final String RUNELITE_VERSION = "runelite.version";
private static final String RUNELITE_COMMIT = "runelite.commit";
private static final String RUNELITE_DIRTY = "runelite.dirty";
private static final String DISCORD_INVITE = "runelite.discord.invite"; private static final String DISCORD_INVITE = "runelite.discord.invite";
private static final String LAUNCHER_VERSION_PROPERTY = "runelite.launcher.version"; private static final String LAUNCHER_VERSION_PROPERTY = "runelite.launcher.version";
private static final String INSECURE_SKIP_TLS_VERIFICATION_PROPERTY = "runelite.insecure-skip-tls-verification"; private static final String INSECURE_SKIP_TLS_VERIFICATION_PROPERTY = "runelite.insecure-skip-tls-verification";
@@ -46,6 +48,7 @@ public class RuneLiteProperties
private static final String JAV_CONFIG_BACKUP = "runelite.jav_config_backup"; private static final String JAV_CONFIG_BACKUP = "runelite.jav_config_backup";
private static final String PLUGINHUB_BASE = "runelite.pluginhub.url"; private static final String PLUGINHUB_BASE = "runelite.pluginhub.url";
private static final String PLUGINHUB_VERSION = "runelite.pluginhub.version"; private static final String PLUGINHUB_VERSION = "runelite.pluginhub.version";
private static final String API_BASE = "runelite.api.base";
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
private static final Properties properties = new Properties(); private static final Properties properties = new Properties();
@@ -78,6 +81,16 @@ public class RuneLiteProperties
return properties.getProperty(RUNELITE_VERSION); return properties.getProperty(RUNELITE_VERSION);
} }
public static String getCommit()
{
return properties.getProperty(RUNELITE_COMMIT);
}
public static boolean isDirty()
{
return Boolean.parseBoolean(properties.getProperty(RUNELITE_DIRTY));
}
public static String getDiscordInvite() public static String getDiscordInvite()
{ {
return properties.getProperty(DISCORD_INVITE); return properties.getProperty(DISCORD_INVITE);
@@ -124,4 +137,9 @@ public class RuneLiteProperties
String version = System.getProperty(PLUGINHUB_VERSION, properties.getProperty(PLUGINHUB_VERSION)); String version = System.getProperty(PLUGINHUB_VERSION, properties.getProperty(PLUGINHUB_VERSION));
return HttpUrl.parse(properties.get(PLUGINHUB_BASE) + "/" + version); return HttpUrl.parse(properties.get(PLUGINHUB_BASE) + "/" + version);
} }
public static String getApiBase()
{
return properties.getProperty(API_BASE);
}
} }

View File

@@ -30,7 +30,8 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.UUID; import java.util.UUID;
import lombok.AllArgsConstructor; import javax.inject.Inject;
import javax.inject.Named;
import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.RuneLiteAPI;
import okhttp3.HttpUrl; import okhttp3.HttpUrl;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
@@ -39,14 +40,21 @@ import okhttp3.RequestBody;
import okhttp3.Response; import okhttp3.Response;
import okhttp3.ResponseBody; import okhttp3.ResponseBody;
@AllArgsConstructor
class SessionClient class SessionClient
{ {
private final OkHttpClient okHttpClient; private final OkHttpClient client;
private final HttpUrl sessionUrl;
@Inject
private SessionClient(OkHttpClient client, @Named("runelite.session") HttpUrl sessionUrl)
{
this.client = client;
this.sessionUrl = sessionUrl;
}
UUID open() throws IOException UUID open() throws IOException
{ {
HttpUrl url = RuneLiteAPI.getSessionBase().newBuilder() HttpUrl url = sessionUrl.newBuilder()
.build(); .build();
Request request = new Request.Builder() Request request = new Request.Builder()
@@ -54,10 +62,10 @@ class SessionClient
.url(url) .url(url)
.build(); .build();
try (Response response = okHttpClient.newCall(request).execute()) try (Response response = client.newCall(request).execute())
{ {
ResponseBody body = response.body(); ResponseBody body = response.body();
InputStream in = body.byteStream(); InputStream in = body.byteStream();
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), UUID.class); return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), UUID.class);
} }
@@ -69,7 +77,7 @@ class SessionClient
void ping(UUID uuid, boolean loggedIn) throws IOException void ping(UUID uuid, boolean loggedIn) throws IOException
{ {
HttpUrl url = RuneLiteAPI.getSessionBase().newBuilder() HttpUrl url = sessionUrl.newBuilder()
.addPathSegment("ping") .addPathSegment("ping")
.addQueryParameter("session", uuid.toString()) .addQueryParameter("session", uuid.toString())
.addQueryParameter("logged-in", String.valueOf(loggedIn)) .addQueryParameter("logged-in", String.valueOf(loggedIn))
@@ -80,7 +88,7 @@ class SessionClient
.url(url) .url(url)
.build(); .build();
try (Response response = okHttpClient.newCall(request).execute()) try (Response response = client.newCall(request).execute())
{ {
if (!response.isSuccessful()) if (!response.isSuccessful())
{ {
@@ -91,7 +99,7 @@ class SessionClient
void delete(UUID uuid) throws IOException void delete(UUID uuid) throws IOException
{ {
HttpUrl url = RuneLiteAPI.getSessionBase().newBuilder() HttpUrl url = sessionUrl.newBuilder()
.addQueryParameter("session", uuid.toString()) .addQueryParameter("session", uuid.toString())
.build(); .build();
@@ -100,6 +108,6 @@ class SessionClient
.url(url) .url(url)
.build(); .build();
okHttpClient.newCall(request).execute().close(); client.newCall(request).execute().close();
} }
} }

View File

@@ -22,7 +22,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.http.api.account; package net.runelite.client.account;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import java.io.IOException; import java.io.IOException;
@@ -30,29 +30,36 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.UUID; import java.util.UUID;
import lombok.RequiredArgsConstructor; import javax.inject.Inject;
import javax.inject.Named;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.RuneLiteAPI;
import net.runelite.http.api.account.OAuthResponse;
import okhttp3.HttpUrl; import okhttp3.HttpUrl;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
@Slf4j @Slf4j
@RequiredArgsConstructor
public class AccountClient public class AccountClient
{ {
private final OkHttpClient client; private final OkHttpClient client;
private final HttpUrl apiBase;
@Setter
private UUID uuid; private UUID uuid;
public void setUuid(UUID uuid) @Inject
private AccountClient(OkHttpClient client, @Named("runelite.api.base") HttpUrl apiBase)
{ {
this.uuid = uuid; this.client = client;
this.apiBase = apiBase;
} }
public OAuthResponse login() throws IOException public OAuthResponse login() throws IOException
{ {
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("account") .addPathSegment("account")
.addPathSegment("login") .addPathSegment("login")
.addQueryParameter("uuid", uuid.toString()) .addQueryParameter("uuid", uuid.toString())
@@ -77,7 +84,7 @@ public class AccountClient
public void logout() throws IOException public void logout() throws IOException
{ {
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("account") .addPathSegment("account")
.addPathSegment("logout") .addPathSegment("logout")
.build(); .build();
@@ -97,7 +104,7 @@ public class AccountClient
public boolean sessionCheck() public boolean sessionCheck()
{ {
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("account") .addPathSegment("account")
.addPathSegment("session-check") .addPathSegment("session-check")
.build(); .build();

View File

@@ -47,10 +47,8 @@ import net.runelite.client.events.SessionClose;
import net.runelite.client.events.SessionOpen; import net.runelite.client.events.SessionOpen;
import net.runelite.client.util.LinkBrowser; import net.runelite.client.util.LinkBrowser;
import net.runelite.client.ws.WSClient; import net.runelite.client.ws.WSClient;
import net.runelite.http.api.account.AccountClient;
import net.runelite.http.api.account.OAuthResponse; import net.runelite.http.api.account.OAuthResponse;
import net.runelite.http.api.ws.messages.LoginResponse; import net.runelite.http.api.ws.messages.LoginResponse;
import okhttp3.OkHttpClient;
@Singleton @Singleton
@Slf4j @Slf4j
@@ -72,14 +70,14 @@ public class SessionManager
ConfigManager configManager, ConfigManager configManager,
EventBus eventBus, EventBus eventBus,
WSClient wsClient, WSClient wsClient,
OkHttpClient okHttpClient, AccountClient accountClient,
Gson gson) Gson gson)
{ {
this.configManager = configManager; this.configManager = configManager;
this.eventBus = eventBus; this.eventBus = eventBus;
this.wsClient = wsClient; this.wsClient = wsClient;
this.sessionFile = sessionfile; this.sessionFile = sessionfile;
this.accountClient = new AccountClient(okHttpClient); this.accountClient = accountClient;
this.gson = gson; this.gson = gson;
eventBus.register(this); eventBus.register(this);

View File

@@ -127,6 +127,10 @@ public class ClientThread implements Executor
{ {
ir.remove(); ir.remove();
} }
else
{
log.trace("Deferring task {}", r);
}
} }
} }
} }

View File

@@ -22,7 +22,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.http.api.chat; package net.runelite.client.chat;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
@@ -32,22 +32,33 @@ import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Collection; import java.util.Collection;
import java.util.Set; import java.util.Set;
import lombok.AllArgsConstructor; import javax.inject.Inject;
import javax.inject.Named;
import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.RuneLiteAPI;
import net.runelite.http.api.chat.Duels;
import net.runelite.http.api.chat.LayoutRoom;
import net.runelite.http.api.chat.Task;
import okhttp3.HttpUrl; import okhttp3.HttpUrl;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.RequestBody; import okhttp3.RequestBody;
import okhttp3.Response; import okhttp3.Response;
@AllArgsConstructor
public class ChatClient public class ChatClient
{ {
private final OkHttpClient client; private final OkHttpClient client;
private final HttpUrl apiBase;
@Inject
private ChatClient(OkHttpClient client, @Named("runelite.api.base") HttpUrl apiBase)
{
this.client = client;
this.apiBase = apiBase;
}
public boolean submitKc(String username, String boss, int kc) throws IOException public boolean submitKc(String username, String boss, int kc) throws IOException
{ {
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("chat") .addPathSegment("chat")
.addPathSegment("kc") .addPathSegment("kc")
.addQueryParameter("name", username) .addQueryParameter("name", username)
@@ -68,7 +79,7 @@ public class ChatClient
public int getKc(String username, String boss) throws IOException public int getKc(String username, String boss) throws IOException
{ {
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("chat") .addPathSegment("chat")
.addPathSegment("kc") .addPathSegment("kc")
.addQueryParameter("name", username) .addQueryParameter("name", username)
@@ -91,7 +102,7 @@ public class ChatClient
public boolean submitQp(String username, int qp) throws IOException public boolean submitQp(String username, int qp) throws IOException
{ {
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("chat") .addPathSegment("chat")
.addPathSegment("qp") .addPathSegment("qp")
.addQueryParameter("name", username) .addQueryParameter("name", username)
@@ -111,7 +122,7 @@ public class ChatClient
public int getQp(String username) throws IOException public int getQp(String username) throws IOException
{ {
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("chat") .addPathSegment("chat")
.addPathSegment("qp") .addPathSegment("qp")
.addQueryParameter("name", username) .addQueryParameter("name", username)
@@ -133,7 +144,7 @@ public class ChatClient
public boolean submitTask(String username, String task, int amount, int initialAmount, String location) throws IOException public boolean submitTask(String username, String task, int amount, int initialAmount, String location) throws IOException
{ {
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("chat") .addPathSegment("chat")
.addPathSegment("task") .addPathSegment("task")
.addQueryParameter("name", username) .addQueryParameter("name", username)
@@ -156,7 +167,7 @@ public class ChatClient
public Task getTask(String username) throws IOException public Task getTask(String username) throws IOException
{ {
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("chat") .addPathSegment("chat")
.addPathSegment("task") .addPathSegment("task")
.addQueryParameter("name", username) .addQueryParameter("name", username)
@@ -184,7 +195,7 @@ public class ChatClient
public boolean submitPb(String username, String boss, double pb) throws IOException public boolean submitPb(String username, String boss, double pb) throws IOException
{ {
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("chat") .addPathSegment("chat")
.addPathSegment("pb") .addPathSegment("pb")
.addQueryParameter("name", username) .addQueryParameter("name", username)
@@ -205,7 +216,7 @@ public class ChatClient
public double getPb(String username, String boss) throws IOException public double getPb(String username, String boss) throws IOException
{ {
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("chat") .addPathSegment("chat")
.addPathSegment("pb") .addPathSegment("pb")
.addQueryParameter("name", username) .addQueryParameter("name", username)
@@ -228,7 +239,7 @@ public class ChatClient
public boolean submitGc(String username, int gc) throws IOException public boolean submitGc(String username, int gc) throws IOException
{ {
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("chat") .addPathSegment("chat")
.addPathSegment("gc") .addPathSegment("gc")
.addQueryParameter("name", username) .addQueryParameter("name", username)
@@ -248,7 +259,7 @@ public class ChatClient
public int getGc(String username) throws IOException public int getGc(String username) throws IOException
{ {
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("chat") .addPathSegment("chat")
.addPathSegment("gc") .addPathSegment("gc")
.addQueryParameter("name", username) .addQueryParameter("name", username)
@@ -270,7 +281,7 @@ public class ChatClient
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 = apiBase.newBuilder()
.addPathSegment("chat") .addPathSegment("chat")
.addPathSegment("duels") .addPathSegment("duels")
.addQueryParameter("name", username) .addQueryParameter("name", username)
@@ -293,7 +304,7 @@ public class ChatClient
public Duels getDuels(String username) throws IOException public Duels getDuels(String username) throws IOException
{ {
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("chat") .addPathSegment("chat")
.addPathSegment("duels") .addPathSegment("duels")
.addQueryParameter("name", username) .addQueryParameter("name", username)
@@ -321,7 +332,7 @@ public class ChatClient
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 = apiBase.newBuilder()
.addPathSegment("chat") .addPathSegment("chat")
.addPathSegment("layout") .addPathSegment("layout")
.addQueryParameter("name", username) .addQueryParameter("name", username)
@@ -340,7 +351,7 @@ public class ChatClient
public LayoutRoom[] getLayout(String username) throws IOException public LayoutRoom[] getLayout(String username) throws IOException
{ {
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("chat") .addPathSegment("chat")
.addPathSegment("layout") .addPathSegment("layout")
.addQueryParameter("name", username) .addQueryParameter("name", username)
@@ -368,7 +379,7 @@ public class ChatClient
public boolean submitPetList(String username, Collection<Integer> petList) throws IOException public boolean submitPetList(String username, Collection<Integer> petList) throws IOException
{ {
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("chat") .addPathSegment("chat")
.addPathSegment("pets") .addPathSegment("pets")
.addQueryParameter("name", username) .addQueryParameter("name", username)
@@ -387,7 +398,7 @@ public class ChatClient
public Set<Integer> getPetList(String username) throws IOException public Set<Integer> getPetList(String username) throws IOException
{ {
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("chat") .addPathSegment("chat")
.addPathSegment("pets") .addPathSegment("pets")
.addQueryParameter("name", username) .addQueryParameter("name", username)

View File

@@ -22,7 +22,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.http.api.config; package net.runelite.client.config;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
@@ -32,9 +32,12 @@ import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import lombok.AllArgsConstructor; import javax.inject.Inject;
import javax.inject.Named;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.RuneLiteAPI;
import net.runelite.http.api.config.Configuration;
import okhttp3.Call; import okhttp3.Call;
import okhttp3.Callback; import okhttp3.Callback;
import okhttp3.HttpUrl; import okhttp3.HttpUrl;
@@ -44,7 +47,6 @@ import okhttp3.Request;
import okhttp3.RequestBody; import okhttp3.RequestBody;
import okhttp3.Response; import okhttp3.Response;
@AllArgsConstructor
@Slf4j @Slf4j
public class ConfigClient public class ConfigClient
{ {
@@ -52,11 +54,21 @@ public class ConfigClient
private static final Gson GSON = RuneLiteAPI.GSON; private static final Gson GSON = RuneLiteAPI.GSON;
private final OkHttpClient client; private final OkHttpClient client;
private final UUID uuid; private final HttpUrl apiBase;
@Setter
private UUID uuid;
@Inject
private ConfigClient(OkHttpClient client, @Named("runelite.api.base") HttpUrl apiBase)
{
this.client = client;
this.apiBase = apiBase;
}
public Configuration get() throws IOException public Configuration get() throws IOException
{ {
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("config") .addPathSegment("config")
.build(); .build();
@@ -82,7 +94,7 @@ public class ConfigClient
{ {
CompletableFuture<Void> future = new CompletableFuture<>(); CompletableFuture<Void> future = new CompletableFuture<>();
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("config") .addPathSegment("config")
.addPathSegment(key) .addPathSegment(key)
.build(); .build();
@@ -120,7 +132,7 @@ public class ConfigClient
{ {
CompletableFuture<Void> future = new CompletableFuture<>(); CompletableFuture<Void> future = new CompletableFuture<>();
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("config") .addPathSegment("config")
.build(); .build();
@@ -173,7 +185,7 @@ public class ConfigClient
{ {
CompletableFuture<Void> future = new CompletableFuture<>(); CompletableFuture<Void> future = new CompletableFuture<>();
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("config") .addPathSegment("config")
.addPathSegment(key) .addPathSegment(key)
.build(); .build();

View File

@@ -101,7 +101,6 @@ import net.runelite.client.events.RuneScapeProfileChanged;
import net.runelite.client.plugins.OPRSExternalPluginManager; import net.runelite.client.plugins.OPRSExternalPluginManager;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
import net.runelite.client.util.ColorUtil; import net.runelite.client.util.ColorUtil;
import net.runelite.http.api.config.ConfigClient;
import net.runelite.http.api.config.ConfigEntry; import net.runelite.http.api.config.ConfigEntry;
import net.runelite.http.api.config.Configuration; import net.runelite.http.api.config.Configuration;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;

View File

@@ -44,6 +44,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.client.RuneLiteProperties; import net.runelite.client.RuneLiteProperties;
import net.runelite.client.util.VerificationException; import net.runelite.client.util.VerificationException;
@@ -62,12 +63,17 @@ public class ExternalPluginClient
{ {
private final OkHttpClient okHttpClient; private final OkHttpClient okHttpClient;
private final Gson gson; private final Gson gson;
private final HttpUrl apiBase;
@Inject @Inject
private ExternalPluginClient(OkHttpClient okHttpClient, Gson gson) private ExternalPluginClient(OkHttpClient okHttpClient,
Gson gson,
@Named("runelite.api.base") HttpUrl apiBase
)
{ {
this.okHttpClient = okHttpClient; this.okHttpClient = okHttpClient;
this.gson = gson; this.gson = gson;
this.apiBase = apiBase;
} }
public List<ExternalPluginManifest> downloadManifest() throws IOException, VerificationException public List<ExternalPluginManifest> downloadManifest() throws IOException, VerificationException
@@ -153,7 +159,7 @@ public class ExternalPluginClient
return; return;
} }
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("pluginhub") .addPathSegment("pluginhub")
.build(); .build();
@@ -181,7 +187,7 @@ public class ExternalPluginClient
public Map<String, Integer> getPluginCounts() throws IOException public Map<String, Integer> getPluginCounts() throws IOException
{ {
HttpUrl url = RuneLiteAPI.getApiBase() HttpUrl url = apiBase
.newBuilder() .newBuilder()
.addPathSegments("pluginhub") .addPathSegments("pluginhub")
.build(); .build();

View File

@@ -38,9 +38,7 @@ import net.runelite.api.FriendsChatRank;
import net.runelite.api.GameState; import net.runelite.api.GameState;
import net.runelite.api.IndexedSprite; import net.runelite.api.IndexedSprite;
import net.runelite.api.clan.ClanTitle; import net.runelite.api.clan.ClanTitle;
import net.runelite.api.events.GameStateChanged; import net.runelite.client.callback.ClientThread;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.util.ImageUtil; import net.runelite.client.util.ImageUtil;
@Singleton @Singleton
@@ -55,15 +53,23 @@ public class ChatIconManager
private BufferedImage[] friendsChatRankImages; private BufferedImage[] friendsChatRankImages;
private BufferedImage[] clanRankImages; private BufferedImage[] clanRankImages;
private int friendsChatOffset; private int friendsChatOffset = -1;
private int clanOffset; private int clanOffset = -1;
@Inject @Inject
private ChatIconManager(Client client, SpriteManager spriteManager, EventBus eventBus) private ChatIconManager(Client client, SpriteManager spriteManager, ClientThread clientThread)
{ {
this.client = client; this.client = client;
this.spriteManager = spriteManager; this.spriteManager = spriteManager;
eventBus.register(this); clientThread.invokeLater(() ->
{
if (client.getGameState().getState() >= GameState.LOGIN_SCREEN.getState())
{
loadRankIcons();
return true;
}
return false;
});
} }
@Nullable @Nullable
@@ -87,22 +93,13 @@ public class ChatIconManager
public int getIconNumber(final FriendsChatRank friendsChatRank) public int getIconNumber(final FriendsChatRank friendsChatRank)
{ {
return friendsChatOffset + friendsChatRank.ordinal() - 1; return friendsChatOffset == -1 ? -1 : friendsChatOffset + friendsChatRank.ordinal() - 1;
} }
public int getIconNumber(final ClanTitle clanTitle) public int getIconNumber(final ClanTitle clanTitle)
{ {
int rank = clanTitle.getId(); int rank = clanTitle.getId();
return clanOffset + clanRankToIdx(rank); return clanOffset == -1 ? -1 : clanOffset + clanRankToIdx(rank);
}
@Subscribe
public void onGameStateChanged(GameStateChanged gameStateChanged)
{
if (gameStateChanged.getGameState() == GameState.LOGIN_SCREEN && friendsChatOffset == 0)
{
loadRankIcons();
}
} }
private void loadRankIcons() private void loadRankIcons()

View File

@@ -22,7 +22,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.http.api.item; package net.runelite.client.game;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
@@ -32,25 +32,39 @@ import java.io.InputStreamReader;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Map; import java.util.Map;
import lombok.AllArgsConstructor; import javax.inject.Inject;
import javax.inject.Named;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.RuneLiteAPI;
import net.runelite.http.api.item.ItemPrice;
import net.runelite.http.api.item.ItemStats;
import okhttp3.HttpUrl; import okhttp3.HttpUrl;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
@Slf4j @Slf4j
@AllArgsConstructor
public class ItemClient public class ItemClient
{ {
private final OkHttpClient client; private final OkHttpClient client;
private final HttpUrl apiBase, staticBase;
@Inject
private ItemClient(OkHttpClient client,
@Named("runelite.api.base") HttpUrl apiBase,
@Named("runelite.static.base") HttpUrl staticBase
)
{
this.client = client;
this.apiBase = apiBase;
this.staticBase = staticBase;
}
public ItemPrice[] getPrices() throws IOException public ItemPrice[] getPrices() throws IOException
{ {
HttpUrl.Builder urlBuilder = RuneLiteAPI.getApiBase().newBuilder() HttpUrl.Builder urlBuilder = apiBase.newBuilder()
.addPathSegment("item") .addPathSegment("item")
.addPathSegment("prices.js"); .addPathSegment("prices.js");
HttpUrl url = urlBuilder.build(); HttpUrl url = urlBuilder.build();
@@ -79,7 +93,7 @@ public class ItemClient
public Map<Integer, ItemStats> getStats() throws IOException public Map<Integer, ItemStats> getStats() throws IOException
{ {
HttpUrl.Builder urlBuilder = RuneLiteAPI.getStaticBase().newBuilder() HttpUrl.Builder urlBuilder = staticBase.newBuilder()
.addPathSegment("item") .addPathSegment("item")
// TODO: Change this to stats.min.json later after release is undeployed // TODO: Change this to stats.min.json later after release is undeployed
.addPathSegment("stats.ids.min.json"); .addPathSegment("stats.ids.min.json");

View File

@@ -56,10 +56,8 @@ import net.runelite.api.SpritePixels;
import net.runelite.client.callback.ClientThread; import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.config.RuneLiteConfig;
import net.runelite.client.util.AsyncBufferedImage; import net.runelite.client.util.AsyncBufferedImage;
import net.runelite.http.api.item.ItemClient;
import net.runelite.http.api.item.ItemPrice; import net.runelite.http.api.item.ItemPrice;
import net.runelite.http.api.item.ItemStats; import net.runelite.http.api.item.ItemStats;
import okhttp3.OkHttpClient;
@Singleton @Singleton
@Slf4j @Slf4j
@@ -168,11 +166,11 @@ public class ItemManager
@Inject @Inject
public ItemManager(Client client, ScheduledExecutorService scheduledExecutorService, ClientThread clientThread, public ItemManager(Client client, ScheduledExecutorService scheduledExecutorService, ClientThread clientThread,
OkHttpClient okHttpClient, RuneLiteConfig runeLiteConfig) ItemClient itemClient, RuneLiteConfig runeLiteConfig)
{ {
this.client = client; this.client = client;
this.clientThread = clientThread; this.clientThread = clientThread;
this.itemClient = new ItemClient(okHttpClient); this.itemClient = itemClient;
this.runeLiteConfig = runeLiteConfig; this.runeLiteConfig = runeLiteConfig;
scheduledExecutorService.scheduleWithFixedDelay(this::loadPrices, 0, 30, TimeUnit.MINUTES); scheduledExecutorService.scheduleWithFixedDelay(this::loadPrices, 0, 30, TimeUnit.MINUTES);

View File

@@ -32,21 +32,18 @@ import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.http.api.npc.NpcInfo;
import net.runelite.http.api.npc.NpcInfoClient;
import okhttp3.OkHttpClient;
@Singleton @Singleton
@Slf4j @Slf4j
public class NPCManager public class NPCManager
{ {
private final OkHttpClient okHttpClient; private final NpcInfoClient npcInfoClient;
private Map<Integer, NpcInfo> npcMap = Collections.emptyMap(); private Map<Integer, NpcInfo> npcMap = Collections.emptyMap();
@Inject @Inject
private NPCManager(OkHttpClient okHttpClient, ScheduledExecutorService scheduledExecutorService) private NPCManager(NpcInfoClient npcInfoClient, ScheduledExecutorService scheduledExecutorService)
{ {
this.okHttpClient = okHttpClient; this.npcInfoClient = npcInfoClient;
scheduledExecutorService.execute(this::loadNpcs); scheduledExecutorService.execute(this::loadNpcs);
} }
@@ -67,7 +64,7 @@ public class NPCManager
{ {
try try
{ {
npcMap = new NpcInfoClient(okHttpClient).getNpcs(); npcMap = npcInfoClient.getNpcs();
} }
catch (IOException e) catch (IOException e)
{ {

View File

@@ -22,7 +22,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.http.api.npc; package net.runelite.client.game;
import lombok.Data; import lombok.Data;

View File

@@ -22,7 +22,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.http.api.npc; package net.runelite.client.game;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
@@ -32,7 +32,8 @@ import java.io.InputStreamReader;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Map; import java.util.Map;
import lombok.Value; import javax.inject.Inject;
import javax.inject.Named;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.RuneLiteAPI;
import okhttp3.HttpUrl; import okhttp3.HttpUrl;
@@ -41,14 +42,21 @@ import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
@Slf4j @Slf4j
@Value
public class NpcInfoClient public class NpcInfoClient
{ {
private final OkHttpClient client; private final OkHttpClient client;
private final HttpUrl staticBase;
@Inject
private NpcInfoClient(OkHttpClient client, @Named("runelite.static.base") HttpUrl staticBase)
{
this.client = client;
this.staticBase = staticBase;
}
public Map<Integer, NpcInfo> getNpcs() throws IOException public Map<Integer, NpcInfo> getNpcs() throws IOException
{ {
HttpUrl.Builder urlBuilder = RuneLiteAPI.getStaticBase().newBuilder() HttpUrl.Builder urlBuilder = staticBase.newBuilder()
.addPathSegment("npcs") .addPathSegment("npcs")
.addPathSegment("npcs.min.json"); .addPathSegment("npcs.min.json");

View File

@@ -23,7 +23,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.http.api.worlds; package net.runelite.client.game;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import java.io.IOException; import java.io.IOException;
@@ -33,6 +33,7 @@ import java.nio.charset.StandardCharsets;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.RuneLiteAPI;
import net.runelite.http.api.worlds.WorldResult;
import okhttp3.HttpUrl; import okhttp3.HttpUrl;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;
@@ -43,10 +44,11 @@ import okhttp3.Response;
public class WorldClient public class WorldClient
{ {
private final OkHttpClient client; private final OkHttpClient client;
private final HttpUrl apiBase;
public WorldResult lookupWorlds() throws IOException public WorldResult lookupWorlds() throws IOException
{ {
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("worlds.js") .addPathSegment("worlds.js")
.build(); .build();

View File

@@ -33,6 +33,7 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import javax.annotation.Nullable; import javax.annotation.Nullable;
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.Client; import net.runelite.api.Client;
@@ -41,8 +42,8 @@ import net.runelite.client.eventbus.EventBus;
import net.runelite.client.events.WorldsFetch; import net.runelite.client.events.WorldsFetch;
import net.runelite.client.util.RunnableExceptionLogger; import net.runelite.client.util.RunnableExceptionLogger;
import net.runelite.http.api.worlds.World; import net.runelite.http.api.worlds.World;
import net.runelite.http.api.worlds.WorldClient;
import net.runelite.http.api.worlds.WorldResult; import net.runelite.http.api.worlds.WorldResult;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
@Singleton @Singleton
@@ -61,11 +62,11 @@ public class WorldService
@Inject @Inject
private WorldService(@Nullable Client client, ScheduledExecutorService scheduledExecutorService, OkHttpClient okHttpClient, private WorldService(@Nullable Client client, ScheduledExecutorService scheduledExecutorService, OkHttpClient okHttpClient,
EventBus eventBus) @Named("runelite.api.base") HttpUrl apiBase, EventBus eventBus)
{ {
this.client = client; this.client = client;
this.scheduledExecutorService = scheduledExecutorService; this.scheduledExecutorService = scheduledExecutorService;
this.worldClient = new WorldClient(okHttpClient); this.worldClient = new WorldClient(okHttpClient, apiBase);
this.eventBus = eventBus; this.eventBus = eventBus;
scheduledExecutorService.scheduleWithFixedDelay(RunnableExceptionLogger.wrap(this::tick), 0, WORLD_FETCH_TIMER, TimeUnit.MINUTES); scheduledExecutorService.scheduleWithFixedDelay(RunnableExceptionLogger.wrap(this::tick), 0, WORLD_FETCH_TIMER, TimeUnit.MINUTES);

View File

@@ -632,18 +632,21 @@ public class ChatChannelPlugin extends Plugin
if (rank != null && rank != FriendsChatRank.UNRANKED) if (rank != null && rank != FriendsChatRank.UNRANKED)
{ {
int iconNumber = chatIconManager.getIconNumber(rank); int iconNumber = chatIconManager.getIconNumber(rank);
final String img = "<img=" + iconNumber + ">"; if (iconNumber > -1)
if (message.getType() == ChatMessageType.FRIENDSCHAT)
{ {
message.getMessageNode() final String img = "<img=" + iconNumber + ">";
.setSender(message.getMessageNode().getSender() + " " + img); if (message.getType() == ChatMessageType.FRIENDSCHAT)
{
message.getMessageNode()
.setSender(message.getMessageNode().getSender() + " " + img);
}
else
{
message.getMessageNode()
.setName(img + message.getMessageNode().getName());
}
client.refreshChat();
} }
else
{
message.getMessageNode()
.setName(img + message.getMessageNode().getName());
}
client.refreshChat();
} }
} }

View File

@@ -73,6 +73,7 @@ import static net.runelite.api.widgets.WidgetID.DIARY_QUEST_GROUP_ID;
import static net.runelite.api.widgets.WidgetID.KILL_LOGS_GROUP_ID; import static net.runelite.api.widgets.WidgetID.KILL_LOGS_GROUP_ID;
import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.callback.ClientThread; import net.runelite.client.callback.ClientThread;
import net.runelite.client.chat.ChatClient;
import net.runelite.client.chat.ChatColorType; import net.runelite.client.chat.ChatColorType;
import net.runelite.client.chat.ChatCommandManager; import net.runelite.client.chat.ChatCommandManager;
import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageBuilder;
@@ -93,7 +94,6 @@ import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.util.ImageUtil; import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.QuantityFormatter; import net.runelite.client.util.QuantityFormatter;
import net.runelite.client.util.Text; import net.runelite.client.util.Text;
import net.runelite.http.api.chat.ChatClient;
import net.runelite.http.api.chat.Duels; import net.runelite.http.api.chat.Duels;
import net.runelite.http.api.item.ItemPrice; import net.runelite.http.api.item.ItemPrice;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;

View File

@@ -22,30 +22,39 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.http.api.feed; package net.runelite.client.plugins.feed;
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.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import lombok.RequiredArgsConstructor; import javax.inject.Inject;
import javax.inject.Named;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.RuneLiteAPI;
import net.runelite.http.api.feed.FeedResult;
import okhttp3.HttpUrl; import okhttp3.HttpUrl;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
@Slf4j @Slf4j
@RequiredArgsConstructor
public class FeedClient public class FeedClient
{ {
private final OkHttpClient client; private final OkHttpClient client;
private final HttpUrl apiBase;
@Inject
private FeedClient(OkHttpClient client, @Named("runelite.api.base") HttpUrl apiBase)
{
this.client = client;
this.apiBase = apiBase;
}
public FeedResult lookupFeed() throws IOException public FeedResult lookupFeed() throws IOException
{ {
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("feed.js") .addPathSegment("feed.js")
.build(); .build();

View File

@@ -45,9 +45,7 @@ import net.runelite.client.task.Schedule;
import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.ClientToolbar;
import net.runelite.client.ui.NavigationButton; import net.runelite.client.ui.NavigationButton;
import net.runelite.client.util.ImageUtil; import net.runelite.client.util.ImageUtil;
import net.runelite.http.api.feed.FeedClient;
import net.runelite.http.api.feed.FeedResult; import net.runelite.http.api.feed.FeedResult;
import okhttp3.OkHttpClient;
@PluginDescriptor( @PluginDescriptor(
name = "News Feed", name = "News Feed",
@@ -145,10 +143,4 @@ public class FeedPlugin extends Plugin
{ {
return configManager.getConfig(FeedConfig.class); return configManager.getConfig(FeedConfig.class);
} }
@Provides
FeedClient provideFeedClient(OkHttpClient okHttpClient)
{
return new FeedClient(okHttpClient);
}
} }

View File

@@ -44,9 +44,13 @@ import com.jogamp.opengl.GLFBODrawable;
import com.jogamp.opengl.GLProfile; import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.math.Matrix4; import com.jogamp.opengl.math.Matrix4;
import java.awt.Canvas; import java.awt.Canvas;
import java.awt.Component;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Image; import java.awt.Image;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt; import java.awt.image.DataBufferInt;
@@ -293,6 +297,24 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
private int uniSmoothBanding; private int uniSmoothBanding;
private int uniTextureLightMode; private int uniTextureLightMode;
private int needsReset;
private final ComponentListener resizeListener = new ComponentAdapter()
{
@Override
public void componentResized(ComponentEvent e)
{
// forward to the JAWTWindow component listener on the canvas. The JAWTWindow component
// listener listens for resizes or movement of the component in order to resize and move
// the associated offscreen layer (calayer on macos only)
canvas.dispatchEvent(e);
// resetSize needs to be run awhile after the resize is completed.
// I've tried waiting until all EDT events are completed and even that is too soon.
// Not sure why, so we just wait a few frames.
needsReset = 5;
}
};
@Override @Override
protected void startUp() protected void startUp()
{ {
@@ -447,6 +469,12 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
{ {
invokeOnMainThread(this::uploadScene); invokeOnMainThread(this::uploadScene);
} }
if (OSType.getOSType() == OSType.MacOS)
{
SwingUtilities.invokeAndWait(() -> ((Component) client).addComponentListener(resizeListener));
needsReset = 5; // plugin startup races with ClientUI positioning, so do a reset in a little bit
}
} }
catch (Throwable e) catch (Throwable e)
{ {
@@ -474,6 +502,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
@Override @Override
protected void shutDown() protected void shutDown()
{ {
((Component) client).removeComponentListener(resizeListener);
clientThread.invoke(() -> clientThread.invoke(() ->
{ {
client.setGpu(false); client.setGpu(false);
@@ -1091,16 +1120,22 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
gl.glBindTexture(gl.GL_TEXTURE_2D, interfaceTexture); gl.glBindTexture(gl.GL_TEXTURE_2D, interfaceTexture);
gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, canvasWidth, canvasHeight, 0, gl.GL_BGRA, gl.GL_UNSIGNED_BYTE, null); gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, canvasWidth, canvasHeight, 0, gl.GL_BGRA, gl.GL_UNSIGNED_BYTE, null);
gl.glBindTexture(gl.GL_TEXTURE_2D, 0); gl.glBindTexture(gl.GL_TEXTURE_2D, 0);
}
if (OSType.getOSType() == OSType.MacOS && glDrawable instanceof GLFBODrawable) if (needsReset > 0)
{
assert OSType.getOSType() == OSType.MacOS;
if (needsReset == 1 && glDrawable instanceof GLFBODrawable)
{ {
// GLDrawables created with createGLDrawable() do not have a resize listener // GLDrawables created with createGLDrawable() do not have a resize listener
// I don't know why this works with Windows/Linux, but on OSX // I don't know why this works with Windows/Linux, but on OSX
// it prevents JOGL from resizing its FBOs and underlying GL textures. So, // it prevents JOGL from resizing its FBOs and underlying GL textures. So,
// we manually trigger a resize here. // we manually trigger a resize here.
GLFBODrawable glfboDrawable = (GLFBODrawable) glDrawable; GLFBODrawable glfboDrawable = (GLFBODrawable) glDrawable;
log.debug("Resetting GLFBODrawable size");
glfboDrawable.resetSize(gl); glfboDrawable.resetSize(gl);
} }
needsReset--;
} }
final BufferProvider bufferProvider = client.getBufferProvider(); final BufferProvider bufferProvider = client.getBufferProvider();

View File

@@ -0,0 +1,102 @@
/*
* Copyright (c) 2019, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.grandexchange;
import com.google.gson.Gson;
import java.io.IOException;
import java.util.UUID;
import javax.inject.Inject;
import javax.inject.Named;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.http.api.RuneLiteAPI;
import static net.runelite.http.api.RuneLiteAPI.JSON;
import net.runelite.http.api.ge.GrandExchangeTrade;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
@Slf4j
public class GrandExchangeClient
{
private static final Gson GSON = RuneLiteAPI.GSON;
private final OkHttpClient client;
private final HttpUrl apiBase;
@Setter
private UUID uuid;
@Setter
private String machineId;
@Inject
private GrandExchangeClient(OkHttpClient client, @Named("runelite.api.base") HttpUrl apiBase)
{
this.client = client;
this.apiBase = apiBase;
}
public void submit(GrandExchangeTrade grandExchangeTrade)
{
final HttpUrl url = apiBase.newBuilder()
.addPathSegment("ge")
.build();
Request.Builder builder = new Request.Builder();
if (uuid != null)
{
builder.header(RuneLiteAPI.RUNELITE_AUTH, uuid.toString());
}
if (machineId != null)
{
builder.header(RuneLiteAPI.RUNELITE_MACHINEID, machineId);
}
Request request = builder
.post(RequestBody.create(JSON, GSON.toJson(grandExchangeTrade)))
.url(url)
.build();
client.newCall(request).enqueue(new Callback()
{
@Override
public void onFailure(Call call, IOException e)
{
log.debug("unable to submit trade", e);
}
@Override
public void onResponse(Call call, Response response)
{
log.debug("Submitted trade");
response.close();
}
});
}
}

View File

@@ -100,11 +100,9 @@ import net.runelite.client.util.LinkBrowser;
import net.runelite.client.util.OSType; import net.runelite.client.util.OSType;
import net.runelite.client.util.QuantityFormatter; import net.runelite.client.util.QuantityFormatter;
import net.runelite.client.util.Text; import net.runelite.client.util.Text;
import net.runelite.http.api.ge.GrandExchangeClient;
import net.runelite.http.api.ge.GrandExchangeTrade; import net.runelite.http.api.ge.GrandExchangeTrade;
import net.runelite.http.api.item.ItemStats; import net.runelite.http.api.item.ItemStats;
import net.runelite.http.api.worlds.WorldType; import net.runelite.http.api.worlds.WorldType;
import okhttp3.OkHttpClient;
import org.apache.commons.lang3.time.DurationFormatUtils; import org.apache.commons.lang3.time.DurationFormatUtils;
import org.apache.commons.text.similarity.FuzzyScore; import org.apache.commons.text.similarity.FuzzyScore;
@@ -259,12 +257,6 @@ public class GrandExchangePlugin extends Plugin
return configManager.getConfig(GrandExchangeConfig.class); return configManager.getConfig(GrandExchangeConfig.class);
} }
@Provides
GrandExchangeClient provideGrandExchangeClient(OkHttpClient okHttpClient)
{
return new GrandExchangeClient(okHttpClient);
}
@Override @Override
protected void startUp() protected void startUp()
{ {

View File

@@ -800,7 +800,7 @@ public class GroundItemsPlugin extends Plugin
Lootbeam lootbeam = lootbeams.get(worldPoint); Lootbeam lootbeam = lootbeams.get(worldPoint);
if (lootbeam == null) if (lootbeam == null)
{ {
lootbeam = new Lootbeam(client, worldPoint, color); lootbeam = new Lootbeam(client, clientThread, worldPoint, color);
lootbeams.put(worldPoint, lootbeam); lootbeams.put(worldPoint, lootbeam);
} }
else else

View File

@@ -27,10 +27,12 @@ package net.runelite.client.plugins.grounditems;
import net.runelite.api.AnimationID; import net.runelite.api.AnimationID;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.JagexColor; import net.runelite.api.JagexColor;
import net.runelite.api.Model;
import net.runelite.api.RuneLiteObject; import net.runelite.api.RuneLiteObject;
import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.LocalPoint;
import net.runelite.api.coords.WorldPoint; import net.runelite.api.coords.WorldPoint;
import java.awt.Color; import java.awt.Color;
import net.runelite.client.callback.ClientThread;
class Lootbeam class Lootbeam
{ {
@@ -39,11 +41,13 @@ class Lootbeam
private final RuneLiteObject runeLiteObject; private final RuneLiteObject runeLiteObject;
private final Client client; private final Client client;
private final ClientThread clientThread;
private Color color; private Color color;
public Lootbeam(Client client, WorldPoint worldPoint, Color color) public Lootbeam(Client client, ClientThread clientThread, WorldPoint worldPoint, Color color)
{ {
this.client = client; this.client = client;
this.clientThread = clientThread;
runeLiteObject = client.createRuneLiteObject(); runeLiteObject = client.createRuneLiteObject();
setColor(color); setColor(color);
@@ -64,11 +68,21 @@ class Lootbeam
} }
this.color = color; this.color = color;
runeLiteObject.setModel(client.loadModel( clientThread.invoke(() ->
RAID_LIGHT_MODEL, {
new short[]{RAID_LIGHT_FIND_COLOR}, Model m = client.loadModel(
new short[]{JagexColor.rgbToHSL(color.getRGB(), 1.0d)} RAID_LIGHT_MODEL,
)); new short[]{RAID_LIGHT_FIND_COLOR},
new short[]{JagexColor.rgbToHSL(color.getRGB(), 1.0d)}
);
if (m == null)
{
return false;
}
runeLiteObject.setModel(m);
return true;
});
} }
public void remove() public void remove()

View File

@@ -79,7 +79,7 @@ enum WidgetOffset
FIXED_2010_STATS_HIGHLIGHT(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_STATS_TAB, 41, 1, null, null), FIXED_2010_STATS_HIGHLIGHT(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_STATS_TAB, 41, 1, null, null),
FIXED_2010_STATS_ICON(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_STATS_ICON, 41, null, null, null), FIXED_2010_STATS_ICON(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_STATS_ICON, 41, null, null, null),
FIXED_2010_QUESTS_HIGHLIGHT(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_QUESTS_TAB, 75, 1, 33, null), FIXED_2010_QUESTS_HIGHLIGHT(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_QUESTS_TAB, 75, 1, 33, null),
FIXED_2010_QUESTS_ICON(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_QUESTS_ICON, 75, 0, null, null), FIXED_2010_QUESTS_ICON(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_QUESTS_ICON, 75, null, null, null),
FIXED_2010_INVENTORY_HIGHLIGHT(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_INVENTORY_TAB, 109, 1, null, null), FIXED_2010_INVENTORY_HIGHLIGHT(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_INVENTORY_TAB, 109, 1, null, null),
FIXED_2010_INVENTORY_ICON(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_INVENTORY_ICON, 111, -1, null, null), FIXED_2010_INVENTORY_ICON(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_INVENTORY_ICON, 111, -1, null, null),
FIXED_2010_EQUIPMENT_ICON(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_EQUIPMENT_ICON, 143, 2, null, null), FIXED_2010_EQUIPMENT_ICON(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_EQUIPMENT_ICON, 143, 2, null, null),
@@ -87,7 +87,7 @@ enum WidgetOffset
FIXED_2010_PRAYER_ICON(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_PRAYER_ICON, 178, 1, null, null), FIXED_2010_PRAYER_ICON(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_PRAYER_ICON, 178, 1, null, null),
FIXED_2010_MAGIC_HIGHLIGHT(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_MAGIC_TAB, 211, 1, null, null), FIXED_2010_MAGIC_HIGHLIGHT(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_MAGIC_TAB, 211, 1, null, null),
FIXED_2010_MAGIC_ICON(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_MAGIC_ICON, 212, 1, null, null), FIXED_2010_MAGIC_ICON(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_MAGIC_ICON, 212, 1, null, null),
FIXED_2010_FRIENDS_CHAT_HIGHLIGHT(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_FRIENDS_CHAT_TAB, 0, 1, null, null), FIXED_2010_FRIENDS_CHAT_HIGHLIGHT(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_FRIENDS_CHAT_TAB, null, 1, null, null),
FIXED_2010_FRIENDS_CHAT_ICON(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_FRIENDS_CHAT_ICON, 5, null, null, null), FIXED_2010_FRIENDS_CHAT_ICON(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_FRIENDS_CHAT_ICON, 5, null, null, null),
FIXED_2010_FRIENDS_HIGHLIGHT(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_FRIENDS_TAB, 38, 1, 33, null), FIXED_2010_FRIENDS_HIGHLIGHT(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_FRIENDS_TAB, 38, 1, 33, null),
FIXED_2010_FRIENDS_ICON(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_FRIENDS_ICON, 40, null, null, null), FIXED_2010_FRIENDS_ICON(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_FRIENDS_ICON, 40, null, null, null),
@@ -102,17 +102,25 @@ enum WidgetOffset
FIXED_2010_MUSIC_HIGHLIGHT(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_MUSIC_TAB, 208, 1, null, null), FIXED_2010_MUSIC_HIGHLIGHT(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_MUSIC_TAB, 208, 1, null, null),
FIXED_2010_MUSIC_ICON(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_MUSIC_ICON, 209, 2, null, null), FIXED_2010_MUSIC_ICON(Skin.AROUND_2010, WidgetInfo.FIXED_VIEWPORT_MUSIC_ICON, 209, 2, null, null),
RESIZABLE_2005_QUESTS_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_QUESTS_ICON, 72, 0, null, null), RESIZABLE_2005_QUESTS_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_QUESTS_ICON, 71, -1, null, null),
RESIZABLE_2005_LOGOUT_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_LOGOUT_ICON, null, null, null, null), RESIZABLE_2005_LOGOUT_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_LOGOUT_ICON, null, null, null, null),
RESIZABLE_2005_OPTIONS_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_OPTIONS_ICON, 137, null, null, null), RESIZABLE_2005_OPTIONS_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_OPTIONS_ICON, 137, null, null, null),
RESIZABLE_2005_EMOTE_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_EMOTES_ICON, 173, 1, null, null), RESIZABLE_2005_EMOTE_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_EMOTES_ICON, 171, 2, null, null),
RESIZABLE_2005_INVENTORY_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_INVENTORY_ICON, null, -2, null, null), RESIZABLE_2005_INVENTORY_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_INVENTORY_ICON, 103, 1, null, null),
RESIZABLE_2005_EQUIPMENT_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_EQUIPMENT_ICON, null, 2, null, null), RESIZABLE_2005_EQUIPMENT_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_EQUIPMENT_ICON, 136, 3, null, null),
RESIZABLE_2005_MUSIC_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_MUSIC_ICON, null, 3, null, null), RESIZABLE_2005_MUSIC_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_MUSIC_ICON, null, 3, null, null),
RESIZABLE_2005_PRAYER_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_PRAYER_ICON, 169, -1, null, null),
RESIZABLE_2005_STATS_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_STATS_ICON, 37, null, null, null),
RESIZABLE_2005_FRIENDS_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_FRIENDS_ICON, 38, null, null, null),
RESIZABLE_BOTTOM_2005_INVENTORY_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_ICON, 98, 2, null, null), RESIZABLE_BOTTOM_2005_INVENTORY_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_ICON, 98, 1, null, null),
RESIZABLE_BOTTOM_2005_QUESTS_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_QUESTS_ICON, 67, 0, null, null), RESIZABLE_BOTTOM_2005_QUESTS_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_QUESTS_ICON, 66, -1, null, null),
RESIZABLE_BOTTOM_2005_EQUIPMENT_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_EQUIPMENT_ICON, 132, 2, null, null), RESIZABLE_BOTTOM_2005_EQUIPMENT_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_EQUIPMENT_ICON, 131, 3, null, null),
RESIZABLE_BOTTOM_2005_MUSIC_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_MUSIC_ICON, null, 3, null, null),
RESIZABLE_BOTTOM_2005_EMOTE_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_EMOTES_ICON, 133, 1, null, null),
RESIZABLE_BOTTOM_2005_STATS_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_STATS_ICON, 32, null, null, null),
RESIZABLE_BOTTOM_2005_PRAYER_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_PRAYER_ICON, null, -1, null, null),
RESIZABLE_BOTTOM_2005_COMBAT_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_COMBAT_ICON, 1, -1, null, null),
FIXED_2005_ROOT_INTERFACE_CONTAINER(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_ROOT_INTERFACE_CONTAINER, null, null, 197, null), FIXED_2005_ROOT_INTERFACE_CONTAINER(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_ROOT_INTERFACE_CONTAINER, null, null, 197, null),
FIXED_2005_INTERFACE_CONTAINER(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_INTERFACE_CONTAINER, 7, null, null, null), FIXED_2005_INTERFACE_CONTAINER(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_INTERFACE_CONTAINER, 7, null, null, null),
@@ -128,11 +136,11 @@ enum WidgetOffset
FIXED_2005_EQUIPMENT_HIGHLIGHT(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_EQUIPMENT_TAB, 153, 1, 30, null), FIXED_2005_EQUIPMENT_HIGHLIGHT(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_EQUIPMENT_TAB, 153, 1, 30, null),
FIXED_2005_EQUIPMENT_ICON(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_EQUIPMENT_ICON, 151, 4, null, null), FIXED_2005_EQUIPMENT_ICON(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_EQUIPMENT_ICON, 151, 4, null, null),
FIXED_2005_PRAYER_HIGHLIGHT(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_PRAYER_TAB, 181, null, 30, null), FIXED_2005_PRAYER_HIGHLIGHT(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_PRAYER_TAB, 181, null, 30, null),
FIXED_2005_PRAYER_ICON(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_PRAYER_ICON, 178, null, null, null), FIXED_2005_PRAYER_ICON(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_PRAYER_ICON, 179, null, null, null),
FIXED_2005_MAGIC_HIGHLIGHT(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_MAGIC_TAB, 209, 1, 30, null), FIXED_2005_MAGIC_HIGHLIGHT(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_MAGIC_TAB, 209, 1, 30, null),
FIXED_2005_MAGIC_ICON(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_MAGIC_ICON, 206, 2, null, null), FIXED_2005_MAGIC_ICON(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_MAGIC_ICON, 206, 3, null, null),
FIXED_2005_FRIENDS_CHAT_HIGHLIGHT(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_FRIENDS_CHAT_TAB, 15, null, null, null), FIXED_2005_FRIENDS_CHAT_HIGHLIGHT(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_FRIENDS_CHAT_TAB, 15, null, null, null),
FIXED_2005_FRIENDS_CHAT_ICON(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_FRIENDS_CHAT_ICON, 22, 0, null, null), FIXED_2005_FRIENDS_CHAT_ICON(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_FRIENDS_CHAT_ICON, 22, null, null, null),
FIXED_2005_FRIENDS_HIGHLIGHT(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_FRIENDS_TAB, 51, null, 30, null), FIXED_2005_FRIENDS_HIGHLIGHT(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_FRIENDS_TAB, 51, null, 30, null),
FIXED_2005_FRIENDS_ICON(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_FRIENDS_ICON, 49, -1, null, null), FIXED_2005_FRIENDS_ICON(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_FRIENDS_ICON, 49, -1, null, null),
FIXED_2005_IGNORES_HIGHLIGHT(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_IGNORES_TAB, 79, null, 30, null), FIXED_2005_IGNORES_HIGHLIGHT(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_IGNORES_TAB, 79, null, 30, null),
@@ -144,7 +152,7 @@ enum WidgetOffset
FIXED_2005_EMOTES_HIGHLIGHT(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_EMOTES_TAB, 178, null, 30, null), FIXED_2005_EMOTES_HIGHLIGHT(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_EMOTES_TAB, 178, null, 30, null),
FIXED_2005_EMOTES_ICON(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_EMOTES_ICON, 178, 1, null, null), FIXED_2005_EMOTES_ICON(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_EMOTES_ICON, 178, 1, null, null),
FIXED_2005_MUSIC_HIGHLIGHT(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_MUSIC_TAB, 206, null, 30, null), FIXED_2005_MUSIC_HIGHLIGHT(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_MUSIC_TAB, 206, null, 30, null),
FIXED_2005_MUSIC_ICON(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_MUSIC_ICON, 202, 5, null, null), FIXED_2005_MUSIC_ICON(Skin.AROUND_2005, WidgetInfo.FIXED_VIEWPORT_MUSIC_ICON, 202, 2, null, null),
FIXED_2006_ROOT_INTERFACE_CONTAINER(Skin.AROUND_2006, WidgetInfo.FIXED_VIEWPORT_ROOT_INTERFACE_CONTAINER, null, null, 197, null), FIXED_2006_ROOT_INTERFACE_CONTAINER(Skin.AROUND_2006, WidgetInfo.FIXED_VIEWPORT_ROOT_INTERFACE_CONTAINER, null, null, 197, null),
FIXED_2006_INTERFACE_CONTAINER(Skin.AROUND_2006, WidgetInfo.FIXED_VIEWPORT_INTERFACE_CONTAINER, 7, null, null, null), FIXED_2006_INTERFACE_CONTAINER(Skin.AROUND_2006, WidgetInfo.FIXED_VIEWPORT_INTERFACE_CONTAINER, 7, null, null, null),

View File

@@ -22,7 +22,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.http.api.loottracker; package net.runelite.client.plugins.loottracker;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
@@ -35,12 +35,15 @@ import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import javax.inject.Inject;
import javax.inject.Named;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter; import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.RuneLiteAPI;
import static net.runelite.http.api.RuneLiteAPI.JSON; import static net.runelite.http.api.RuneLiteAPI.JSON;
import net.runelite.http.api.loottracker.LootAggregate;
import net.runelite.http.api.loottracker.LootRecord;
import okhttp3.Call; import okhttp3.Call;
import okhttp3.Callback; import okhttp3.Callback;
import okhttp3.HttpUrl; import okhttp3.HttpUrl;
@@ -50,21 +53,29 @@ import okhttp3.RequestBody;
import okhttp3.Response; import okhttp3.Response;
@Slf4j @Slf4j
@RequiredArgsConstructor
public class LootTrackerClient public class LootTrackerClient
{ {
private static final Gson GSON = RuneLiteAPI.GSON; private static final Gson GSON = RuneLiteAPI.GSON;
private final OkHttpClient client; private final OkHttpClient client;
private final HttpUrl apiBase;
@Getter @Getter
@Setter @Setter
private UUID uuid; private UUID uuid;
@Inject
private LootTrackerClient(OkHttpClient client, @Named("runelite.api.base") HttpUrl apiBase)
{
this.client = client;
this.apiBase = apiBase;
}
public CompletableFuture<Void> submit(Collection<LootRecord> lootRecords) public CompletableFuture<Void> submit(Collection<LootRecord> lootRecords)
{ {
CompletableFuture<Void> future = new CompletableFuture<>(); CompletableFuture<Void> future = new CompletableFuture<>();
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("loottracker") .addPathSegment("loottracker")
.build(); .build();
@@ -107,7 +118,7 @@ public class LootTrackerClient
public Collection<LootAggregate> get() throws IOException public Collection<LootAggregate> get() throws IOException
{ {
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("loottracker") .addPathSegment("loottracker")
.build(); .build();
@@ -137,7 +148,7 @@ public class LootTrackerClient
public void delete(String eventId) public void delete(String eventId)
{ {
HttpUrl.Builder builder = RuneLiteAPI.getApiBase().newBuilder() HttpUrl.Builder builder = apiBase.newBuilder()
.addPathSegment("loottracker"); .addPathSegment("loottracker");
if (eventId != null) if (eventId != null)

View File

@@ -65,7 +65,6 @@ import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.QuantityFormatter; import net.runelite.client.util.QuantityFormatter;
import net.runelite.client.util.SwingUtil; import net.runelite.client.util.SwingUtil;
import net.runelite.http.api.loottracker.LootRecordType; import net.runelite.http.api.loottracker.LootRecordType;
import net.runelite.http.api.loottracker.LootTrackerClient;
class LootTrackerPanel extends PluginPanel class LootTrackerPanel extends PluginPanel
{ {

View File

@@ -114,8 +114,6 @@ import net.runelite.http.api.loottracker.GameItem;
import net.runelite.http.api.loottracker.LootAggregate; import net.runelite.http.api.loottracker.LootAggregate;
import net.runelite.http.api.loottracker.LootRecord; import net.runelite.http.api.loottracker.LootRecord;
import net.runelite.http.api.loottracker.LootRecordType; import net.runelite.http.api.loottracker.LootRecordType;
import net.runelite.http.api.loottracker.LootTrackerClient;
import okhttp3.OkHttpClient;
import org.apache.commons.text.WordUtils; import org.apache.commons.text.WordUtils;
@PluginDescriptor( @PluginDescriptor(
@@ -340,12 +338,6 @@ public class LootTrackerPlugin extends Plugin
return list; return list;
} }
@Provides
LootTrackerClient provideLootTrackerClient(OkHttpClient okHttpClient)
{
return new LootTrackerClient(okHttpClient);
}
@Provides @Provides
LootTrackerConfig provideConfig(ConfigManager configManager) LootTrackerConfig provideConfig(ConfigManager configManager)
{ {

View File

@@ -29,7 +29,6 @@ import javax.inject.Inject;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.GameState; import net.runelite.api.GameState;
import net.runelite.api.events.BeforeRender; import net.runelite.api.events.BeforeRender;
import net.runelite.api.events.GameStateChanged;
import net.runelite.client.callback.ClientThread; import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
@@ -57,10 +56,18 @@ public class LowMemoryPlugin extends Plugin
@Override @Override
protected void startUp() protected void startUp()
{ {
if (client.getGameState() == GameState.LOGGED_IN) clientThread.invoke(() ->
{ {
clientThread.invoke(() -> client.changeMemoryMode(config.lowDetail())); // When the client starts it initializes the texture size based on the memory mode setting.
} // Don't set low memory before the login screen is ready to prevent loading the low detail textures,
// which breaks the gpu plugin due to it requiring the 128x128px textures
if (client.getGameState().getState() >= GameState.LOGIN_SCREEN.getState())
{
client.changeMemoryMode(config.lowDetail());
return true;
}
return false;
});
} }
@Override @Override
@@ -80,19 +87,13 @@ public class LowMemoryPlugin extends Plugin
{ {
if (configChanged.getGroup().equals(LowMemoryConfig.GROUP)) if (configChanged.getGroup().equals(LowMemoryConfig.GROUP))
{ {
clientThread.invoke(() -> client.changeMemoryMode(config.lowDetail())); clientThread.invoke(() ->
} {
} if (client.getGameState().getState() >= GameState.LOGIN_SCREEN.getState())
{
@Subscribe client.changeMemoryMode(config.lowDetail());
public void onGameStateChanged(GameStateChanged event) }
{ });
// When the client starts it initializes the texture size based on the memory mode setting.
// Don't set low memory before the login screen is ready to prevent loading the low detail textures,
// which breaks the gpu plugin due to it requiring the 128x128px textures
if (event.getGameState() == GameState.LOGIN_SCREEN)
{
client.changeMemoryMode(config.lowDetail());
} }
} }

View File

@@ -128,7 +128,6 @@ public class MenuEntrySwapperPlugin extends Plugin
MenuAction.ITEM_THIRD_OPTION, MenuAction.ITEM_THIRD_OPTION,
MenuAction.ITEM_FOURTH_OPTION, MenuAction.ITEM_FOURTH_OPTION,
MenuAction.ITEM_FIFTH_OPTION, MenuAction.ITEM_FIFTH_OPTION,
MenuAction.EXAMINE_ITEM,
MenuAction.ITEM_USE MenuAction.ITEM_USE
); );
@@ -791,7 +790,7 @@ public class MenuEntrySwapperPlugin extends Plugin
ItemComposition itemComposition = event.getItemComposition(); ItemComposition itemComposition = event.getItemComposition();
Integer option = getSwapConfig(true, itemComposition.getId()); Integer option = getSwapConfig(true, itemComposition.getId());
if (option != null) if (option != null && option < itemComposition.getInventoryActions().length)
{ {
itemComposition.setShiftClickActionIndex(option); itemComposition.setShiftClickActionIndex(option);
} }

View File

@@ -67,6 +67,7 @@ import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.GameTick; import net.runelite.api.events.GameTick;
import net.runelite.api.events.VarbitChanged; import net.runelite.api.events.VarbitChanged;
import net.runelite.client.callback.ClientThread; import net.runelite.client.callback.ClientThread;
import net.runelite.client.chat.ChatClient;
import net.runelite.client.chat.ChatColorType; import net.runelite.client.chat.ChatColorType;
import net.runelite.client.chat.ChatCommandManager; import net.runelite.client.chat.ChatCommandManager;
import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageBuilder;
@@ -96,7 +97,6 @@ import static net.runelite.client.util.Text.sanitize;
import net.runelite.client.ws.PartyMember; import net.runelite.client.ws.PartyMember;
import net.runelite.client.ws.PartyService; import net.runelite.client.ws.PartyService;
import net.runelite.client.ws.WSClient; import net.runelite.client.ws.WSClient;
import net.runelite.http.api.chat.ChatClient;
import net.runelite.http.api.chat.LayoutRoom; import net.runelite.http.api.chat.LayoutRoom;
import net.runelite.http.api.ws.messages.party.PartyChatMessage; import net.runelite.http.api.ws.messages.party.PartyChatMessage;

View File

@@ -27,16 +27,32 @@ package net.runelite.client.plugins.roofremoval;
import net.runelite.client.config.Config; import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem; import net.runelite.client.config.ConfigItem;
import net.runelite.client.config.ConfigSection;
@ConfigGroup(RoofRemovalConfig.CONFIG_GROUP) @ConfigGroup(RoofRemovalConfig.CONFIG_GROUP)
public interface RoofRemovalConfig extends Config public interface RoofRemovalConfig extends Config
{ {
String CONFIG_GROUP = "roofremoval"; String CONFIG_GROUP = "roofremoval";
@ConfigSection(
name = "Modes",
description = "In what situations should roofs be removed",
position = 0
)
String modesSection = "modes";
@ConfigSection(
name = "Area Overrides",
description = "Always remove roofs in specific areas",
position = 1
)
String overridesSection = "overrides";
@ConfigItem( @ConfigItem(
keyName = "removePosition", keyName = "removePosition",
name = "Player's position", name = "Player's position",
description = "Remove roofs above the player's position" description = "Remove roofs above the player's position",
section = modesSection
) )
default boolean removePosition() default boolean removePosition()
{ {
@@ -46,7 +62,8 @@ public interface RoofRemovalConfig extends Config
@ConfigItem( @ConfigItem(
keyName = "removeHovered", keyName = "removeHovered",
name = "Hovered tile", name = "Hovered tile",
description = "Remove roofs above the hovered tile" description = "Remove roofs above the hovered tile",
section = modesSection
) )
default boolean removeHovered() default boolean removeHovered()
{ {
@@ -56,7 +73,8 @@ public interface RoofRemovalConfig extends Config
@ConfigItem( @ConfigItem(
keyName = "removeDestination", keyName = "removeDestination",
name = "Destination tile", name = "Destination tile",
description = "Remove roofs above the destination tile" description = "Remove roofs above the destination tile",
section = modesSection
) )
default boolean removeDestination() default boolean removeDestination()
{ {
@@ -66,10 +84,22 @@ public interface RoofRemovalConfig extends Config
@ConfigItem( @ConfigItem(
keyName = "removeBetween", keyName = "removeBetween",
name = "Between camera & player", name = "Between camera & player",
description = "Remove roofs between the camera and the player at low camera angles" description = "Remove roofs between the camera and the player at low camera angles",
section = modesSection
) )
default boolean removeBetween() default boolean removeBetween()
{ {
return true; return true;
} }
@ConfigItem(
keyName = "overridePOH",
name = "Player Owned House",
description = "Always remove roofs while in the Player Owned House",
section = overridesSection
)
default boolean overridePOH()
{
return false;
}
} }

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2021 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.roofremoval;
import lombok.Getter;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
@Getter
enum RoofRemovalConfigOverride
{
POH(RoofRemovalConfig::overridePOH, 7257, 7513, 7514, 7769, 7770, 8025, 8026);
private final Predicate<RoofRemovalConfig> enabled;
private final List<Integer> regions;
RoofRemovalConfigOverride(Predicate<RoofRemovalConfig> enabled, Integer... regions)
{
this.enabled = enabled;
this.regions = Arrays.asList(regions);
}
}

View File

@@ -34,8 +34,10 @@ import java.io.InputStreamReader;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import javax.inject.Inject; import javax.inject.Inject;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client; import net.runelite.api.Client;
@@ -86,6 +88,7 @@ public class RoofRemovalPlugin extends Plugin
private RoofRemovalConfig config; private RoofRemovalConfig config;
private final Map<Integer, long[]> overrides = new HashMap<>(); private final Map<Integer, long[]> overrides = new HashMap<>();
private final Set<Integer> configOverrideRegions = new HashSet<>();
@Provides @Provides
RoofRemovalConfig getConfig(ConfigManager configManager) RoofRemovalConfig getConfig(ConfigManager configManager)
@@ -96,6 +99,7 @@ public class RoofRemovalPlugin extends Plugin
@Override @Override
public void startUp() throws IOException public void startUp() throws IOException
{ {
buildConfigOverrides();
loadRoofOverrides(); loadRoofOverrides();
clientThread.invoke(() -> clientThread.invoke(() ->
{ {
@@ -139,7 +143,21 @@ public class RoofRemovalPlugin extends Plugin
return; return;
} }
client.getScene().setRoofRemovalMode(buildRoofRemovalFlags()); if (e.getKey().startsWith("remove"))
{
client.getScene().setRoofRemovalMode(buildRoofRemovalFlags());
}
else if (e.getKey().startsWith("override"))
{
buildConfigOverrides();
clientThread.invoke(() ->
{
if (client.getGameState() == GameState.LOGGED_IN)
{
client.setGameState(GameState.LOADING);
}
});
}
} }
private int buildRoofRemovalFlags() private int buildRoofRemovalFlags()
@@ -164,6 +182,18 @@ public class RoofRemovalPlugin extends Plugin
return roofRemovalMode; return roofRemovalMode;
} }
private void buildConfigOverrides()
{
configOverrideRegions.clear();
for (RoofRemovalConfigOverride configOverride : RoofRemovalConfigOverride.values())
{
if (configOverride.getEnabled().test(config))
{
configOverrideRegions.addAll(configOverride.getRegions());
}
}
}
private void performRoofRemoval() private void performRoofRemoval()
{ {
assert client.isClientThread(); assert client.isClientThread();
@@ -218,6 +248,11 @@ public class RoofRemovalPlugin extends Plugin
outer: outer:
for (int regionID : client.getMapRegions()) for (int regionID : client.getMapRegions())
{ {
if (configOverrideRegions.contains(regionID))
{
regionsHaveOverrides = true;
break;
}
for (int z = 0; z < Constants.MAX_Z; z++) for (int z = 0; z < Constants.MAX_Z; z++)
{ {
if (overrides.containsKey(regionID << 2 | z)) if (overrides.containsKey(regionID << 2 | z))
@@ -250,19 +285,21 @@ public class RoofRemovalPlugin extends Plugin
// Properly account for instances shifting worldpoints around // Properly account for instances shifting worldpoints around
final WorldPoint wp = WorldPoint.fromLocalInstance(client, tile.getLocalLocation(), tile.getPlane()); final WorldPoint wp = WorldPoint.fromLocalInstance(client, tile.getLocalLocation(), tile.getPlane());
int regionID = wp.getRegionID() << 2 | z; int regionAndPlane = wp.getRegionID() << 2 | wp.getPlane();
if (!overrides.containsKey(regionID)) if (configOverrideRegions.contains(wp.getRegionID()))
{
continue;
}
int rx = wp.getRegionX();
int ry = wp.getRegionY();
long[] region = overrides.get(regionID);
if ((region[ry] & (1L << rx)) != 0)
{ {
settings[z][x][y] |= Constants.TILE_FLAG_UNDER_ROOF; settings[z][x][y] |= Constants.TILE_FLAG_UNDER_ROOF;
} }
else if (overrides.containsKey(regionAndPlane))
{
int rx = wp.getRegionX();
int ry = wp.getRegionY();
long[] region = overrides.get(regionAndPlane);
if ((region[ry] & (1L << rx)) != 0)
{
settings[z][x][y] |= Constants.TILE_FLAG_UNDER_ROOF;
}
}
} }
} }
} }

View File

@@ -74,6 +74,7 @@ import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.Notifier; import net.runelite.client.Notifier;
import net.runelite.client.callback.ClientThread; import net.runelite.client.callback.ClientThread;
import net.runelite.client.chat.ChatClient;
import net.runelite.client.chat.ChatColorType; import net.runelite.client.chat.ChatColorType;
import net.runelite.client.chat.ChatCommandManager; import net.runelite.client.chat.ChatCommandManager;
import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageBuilder;
@@ -91,7 +92,6 @@ import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
import net.runelite.client.util.ColorUtil; import net.runelite.client.util.ColorUtil;
import net.runelite.client.util.Text; import net.runelite.client.util.Text;
import net.runelite.http.api.chat.ChatClient;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
@PluginDescriptor( @PluginDescriptor(

View File

@@ -488,17 +488,14 @@ public class WorldMapPlugin extends Plugin
} }
// Must setup the quest icons on the client thread, after the player has logged in. // Must setup the quest icons on the client thread, after the player has logged in.
clientThread.invokeLater(() -> clientThread.invoke(() ->
{ {
if (client.getGameState() != GameState.LOGGED_IN) if (client.getGameState() == GameState.LOGGED_IN)
{ {
return false; Arrays.stream(QuestStartLocation.values())
.map(this::createQuestStartPoint)
.forEach(worldMapPointManager::add);
} }
Arrays.stream(QuestStartLocation.values())
.map(this::createQuestStartPoint)
.forEach(worldMapPointManager::add);
return true;
}); });
} }

View File

@@ -22,11 +22,12 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.http.api.xp; package net.runelite.client.plugins.xptracker;
import java.io.IOException; import java.io.IOException;
import javax.inject.Inject;
import javax.inject.Named;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.http.api.RuneLiteAPI;
import okhttp3.Call; import okhttp3.Call;
import okhttp3.Callback; import okhttp3.Callback;
import okhttp3.HttpUrl; import okhttp3.HttpUrl;
@@ -38,15 +39,18 @@ import okhttp3.Response;
public class XpClient public class XpClient
{ {
private final OkHttpClient client; private final OkHttpClient client;
private final HttpUrl apiBase;
public XpClient(OkHttpClient client) @Inject
private XpClient(OkHttpClient client, @Named("runelite.api.base") HttpUrl apiBase)
{ {
this.client = client; this.client = client;
this.apiBase = apiBase;
} }
public void update(String username) public void update(String username)
{ {
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = apiBase.newBuilder()
.addPathSegment("xp") .addPathSegment("xp")
.addPathSegment("update") .addPathSegment("update")
.addQueryParameter("username", username) .addQueryParameter("username", username)

View File

@@ -69,8 +69,6 @@ import net.runelite.client.ui.NavigationButton;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.util.ImageUtil; import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.Text; import net.runelite.client.util.Text;
import net.runelite.http.api.xp.XpClient;
import okhttp3.OkHttpClient;
@PluginDescriptor( @PluginDescriptor(
name = "XP Tracker", name = "XP Tracker",
@@ -139,12 +137,6 @@ public class XpTrackerPlugin extends Plugin
return configManager.getConfig(XpTrackerConfig.class); return configManager.getConfig(XpTrackerConfig.class);
} }
@Provides
XpClient provideXpClient(OkHttpClient okHttpClient)
{
return new XpClient(okHttpClient);
}
@Override @Override
public void configure(Binder binder) public void configure(Binder binder)
{ {

View File

@@ -24,7 +24,6 @@
*/ */
package net.runelite.client.plugins.xtea; package net.runelite.client.plugins.xtea;
import com.google.inject.Provides;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import javax.inject.Inject; import javax.inject.Inject;
@@ -38,11 +37,10 @@ import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.http.api.xtea.XteaClient; import net.runelite.http.api.xtea.XteaClient;
import net.runelite.http.api.xtea.XteaKey; import net.runelite.http.api.xtea.XteaKey;
import net.runelite.http.api.xtea.XteaRequest; import net.runelite.http.api.xtea.XteaRequest;
import okhttp3.OkHttpClient;
@PluginDescriptor( @PluginDescriptor(
name = "Xtea", name = "Xtea",
hidden = true hidden = true
) )
@Slf4j @Slf4j
public class XteaPlugin extends Plugin public class XteaPlugin extends Plugin
@@ -55,12 +53,6 @@ public class XteaPlugin extends Plugin
@Inject @Inject
private XteaClient xteaClient; private XteaClient xteaClient;
@Provides
XteaClient provideXteaClient(OkHttpClient okHttpClient)
{
return new XteaClient(okHttpClient);
}
@Subscribe @Subscribe
public void onGameStateChanged(GameStateChanged gameStateChanged) public void onGameStateChanged(GameStateChanged gameStateChanged)
{ {

View File

@@ -78,7 +78,7 @@ import okhttp3.Response;
public class ClientLoader implements Supplier<Applet> public class ClientLoader implements Supplier<Applet>
{ {
private static final String INJECTED_CLIENT_NAME = "/injected-client.oprs"; private static final String INJECTED_CLIENT_NAME = "/injected-client.oprs";
private static final int NUM_ATTEMPTS = 0; private static final int NUM_ATTEMPTS = 6;
private static File LOCK_FILE = new File(RuneLite.CACHE_DIR, "cache.lock"); private static File LOCK_FILE = new File(RuneLite.CACHE_DIR, "cache.lock");
private static File VANILLA_CACHE = new File(RuneLite.CACHE_DIR, "vanilla.cache"); private static File VANILLA_CACHE = new File(RuneLite.CACHE_DIR, "vanilla.cache");
private static File PATCHED_CACHE = new File(RuneLite.CACHE_DIR, "patched.cache"); private static File PATCHED_CACHE = new File(RuneLite.CACHE_DIR, "patched.cache");

View File

@@ -35,9 +35,11 @@ import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.client.RuneLiteProperties;
import net.runelite.http.api.worlds.World; import net.runelite.http.api.worlds.World;
import net.runelite.http.api.worlds.WorldClient; import net.runelite.client.game.WorldClient;
import net.runelite.http.api.worlds.WorldType; import net.runelite.http.api.worlds.WorldType;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
@Slf4j @Slf4j
@@ -46,7 +48,7 @@ class WorldSupplier implements Supplier<World>
{ {
private final OkHttpClient okHttpClient; private final OkHttpClient okHttpClient;
private final Random random = new Random(System.nanoTime()); private final Random random = new Random(System.nanoTime());
private Queue<World> worlds = new ArrayDeque<>(); private final Queue<World> worlds = new ArrayDeque<>();
@Override @Override
public World get() public World get()
@@ -58,7 +60,7 @@ class WorldSupplier implements Supplier<World>
try try
{ {
List<World> newWorlds = new WorldClient(okHttpClient) List<World> newWorlds = new WorldClient(okHttpClient, HttpUrl.get(RuneLiteProperties.getApiBase()))
.lookupWorlds() .lookupWorlds()
.getWorlds() .getWorlds()
.stream() .stream()

View File

@@ -336,6 +336,12 @@ public class ClientUI
frame.setResizable(true); frame.setResizable(true);
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
if (OSType.getOSType() == OSType.MacOS)
{
// Change the default quit strategy to CLOSE_ALL_WINDOWS so that ctrl+q
// triggers the listener below instead of exiting.
MacOSQuitStrategy.setup();
}
frame.addWindowListener(new WindowAdapter() frame.addWindowListener(new WindowAdapter()
{ {
@Override @Override
@@ -550,7 +556,11 @@ public class ClientUI
// When Windows screen scaling is on, the position/bounds will be wrong when they are set. // When Windows screen scaling is on, the position/bounds will be wrong when they are set.
// The bounds saved in shutdown are the full, non-scaled co-ordinates. // The bounds saved in shutdown are the full, non-scaled co-ordinates.
if (scale != 1) // On MacOS the scaling is already applied and the position/bounds are correct on at least
// - 2015 x64 MBP JDK11 Mohave
// - 2020 m1 MBP JDK17 Big Sur
// Adjusting the scaling further results in the client position being incorrect
if (scale != 1 && OSType.getOSType() != OSType.MacOS)
{ {
clientBounds.setRect( clientBounds.setRect(
clientBounds.getX() / scale, clientBounds.getX() / scale,

View File

@@ -0,0 +1,48 @@
/*
* Copyright (c) 2022, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.ui;
import com.apple.eawt.Application;
import com.apple.eawt.QuitStrategy;
class MacOSQuitStrategy
{
public static void setup()
{
try
{
// com.apple.eawt.QuitStrategy was moved to java.desktop in Java 9,
// but our OrangeExtensions API targets 1.6, so this code is only valid
// on 8 below.
Application.getApplication()
.setQuitStrategy(QuitStrategy.CLOSE_ALL_WINDOWS);
}
catch (NoClassDefFoundError ex)
{
// IntelliJ doesn't handle our multi-release Maven setup well, and will run
// this class on 11+. Ignore the error so the client can launch.
}
}
}

View File

@@ -31,7 +31,6 @@ import java.awt.Font;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
@@ -67,7 +66,7 @@ public class SplashScreen extends JFrame implements ActionListener
private volatile String subActionText = ""; private volatile String subActionText = "";
private volatile String progressText = null; private volatile String progressText = null;
private SplashScreen() throws IOException private SplashScreen()
{ {
BufferedImage logo = ImageUtil.loadImageResource(SplashScreen.class, "openosrs_transparent.png"); BufferedImage logo = ImageUtil.loadImageResource(SplashScreen.class, "openosrs_transparent.png");
@@ -205,6 +204,12 @@ public class SplashScreen extends JFrame implements ActionListener
} }
INSTANCE.timer.stop(); INSTANCE.timer.stop();
// The CLOSE_ALL_WINDOWS quit strategy on MacOS dispatches WINDOW_CLOSING events to each frame
// from Window.getWindows. However, getWindows uses weak refs and relies on gc to remove windows
// from its list, causing events to get dispatched to disposed frames. The frames handle the events
// regardless of being disposed and will run the configured close operation. Set the close operation
// to DO_NOTHING_ON_CLOSE prior to disposing to prevent this.
INSTANCE.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
INSTANCE.dispose(); INSTANCE.dispose();
INSTANCE = null; INSTANCE = null;
}); });

View File

@@ -71,8 +71,8 @@ public class WidgetOverlay extends Overlay
new WidgetOverlay(client, WidgetInfo.VOLCANIC_MINE_VENTS_INFOBOX_GROUP, OverlayPosition.BOTTOM_RIGHT), new WidgetOverlay(client, WidgetInfo.VOLCANIC_MINE_VENTS_INFOBOX_GROUP, OverlayPosition.BOTTOM_RIGHT),
new WidgetOverlay(client, WidgetInfo.VOLCANIC_MINE_STABILITY_INFOBOX_GROUP, OverlayPosition.BOTTOM_LEFT), new WidgetOverlay(client, WidgetInfo.VOLCANIC_MINE_STABILITY_INFOBOX_GROUP, OverlayPosition.BOTTOM_LEFT),
new WidgetOverlay(client, WidgetInfo.MULTICOMBAT_FIXED, OverlayPosition.BOTTOM_RIGHT), new WidgetOverlay(client, WidgetInfo.MULTICOMBAT_FIXED, OverlayPosition.BOTTOM_RIGHT),
new WidgetOverlay(client, WidgetInfo.MULTICOMBAT_RESIZEABLE_MODERN, OverlayPosition.CANVAS_TOP_RIGHT), new WidgetOverlay(client, WidgetInfo.MULTICOMBAT_RESIZABLE_MODERN, OverlayPosition.CANVAS_TOP_RIGHT),
new WidgetOverlay(client, WidgetInfo.MULTICOMBAT_RESIZEABLE_CLASSIC, OverlayPosition.CANVAS_TOP_RIGHT), new WidgetOverlay(client, WidgetInfo.MULTICOMBAT_RESIZABLE_CLASSIC, OverlayPosition.CANVAS_TOP_RIGHT),
new WidgetOverlay(client, WidgetInfo.TEMPOROSS_STATUS_INDICATOR, OverlayPosition.TOP_LEFT), new WidgetOverlay(client, WidgetInfo.TEMPOROSS_STATUS_INDICATOR, OverlayPosition.TOP_LEFT),
new WidgetOverlay(client, WidgetInfo.BA_HEAL_TEAMMATES, OverlayPosition.BOTTOM_LEFT), new WidgetOverlay(client, WidgetInfo.BA_HEAL_TEAMMATES, OverlayPosition.BOTTOM_LEFT),
new WidgetOverlay(client, WidgetInfo.BA_TEAM, OverlayPosition.TOP_RIGHT), new WidgetOverlay(client, WidgetInfo.BA_TEAM, OverlayPosition.TOP_RIGHT),

View File

@@ -1131,7 +1131,7 @@ public class ModelOutlineRenderer
{ {
drawModelOutline(model, lp.getX(), lp.getY(), drawModelOutline(model, lp.getX(), lp.getY(),
Perspective.getTileHeight(client, lp, wallObject.getPlane()), Perspective.getTileHeight(client, lp, wallObject.getPlane()),
wallObject.getOrientationA(), outlineWidth, color, feather); 0, outlineWidth, color, feather);
} }
} }
@@ -1143,7 +1143,7 @@ public class ModelOutlineRenderer
{ {
drawModelOutline(model, lp.getX(), lp.getY(), drawModelOutline(model, lp.getX(), lp.getY(),
Perspective.getTileHeight(client, lp, wallObject.getPlane()), Perspective.getTileHeight(client, lp, wallObject.getPlane()),
wallObject.getOrientationB(), outlineWidth, color, feather); 0, outlineWidth, color, feather);
} }
} }
} }

View File

@@ -187,6 +187,18 @@ public class SwingUtil
@Override @Override
public void mouseClicked(MouseEvent e) public void mouseClicked(MouseEvent e)
{ {
if (OSType.getOSType() == OSType.MacOS)
{
// On macOS, frame.setVisible(true) only restores focus when the visibility was previously false.
// The frame's visibility is not set to false when the window loses focus, so we set it manually.
// Additionally, in order to bring the window to the foreground,
// frame.setVisible(true) calls CPlatformWindow::nativePushNSWindowToFront.
// However, this native method is not called with activateIgnoringOtherApps:YES,
// so any other active window will prevent our window from being brought to the front.
// To work around this, we use our macOS-specific requestForeground().
frame.setVisible(false);
OSXUtil.requestForeground();
}
frame.setVisible(true); frame.setVisible(true);
frame.setState(Frame.NORMAL); // Restore frame.setState(Frame.NORMAL); // Restore
} }

View File

@@ -31,15 +31,17 @@ import java.util.HashSet;
import java.util.Objects; import java.util.Objects;
import java.util.UUID; import java.util.UUID;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.client.RuneLite;
import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.EventBus;
import net.runelite.http.api.RuneLiteAPI;
import net.runelite.http.api.ws.WebsocketGsonFactory; import net.runelite.http.api.ws.WebsocketGsonFactory;
import net.runelite.http.api.ws.WebsocketMessage; import net.runelite.http.api.ws.WebsocketMessage;
import net.runelite.http.api.ws.messages.Handshake; import net.runelite.http.api.ws.messages.Handshake;
import net.runelite.http.api.ws.messages.party.PartyMessage; import net.runelite.http.api.ws.messages.party.PartyMessage;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
@@ -52,6 +54,7 @@ public class WSClient extends WebSocketListener implements AutoCloseable
{ {
private final EventBus eventBus; private final EventBus eventBus;
private final OkHttpClient okHttpClient; private final OkHttpClient okHttpClient;
private final HttpUrl runeliteWs;
private final Collection<Class<? extends WebsocketMessage>> messages = new HashSet<>(); private final Collection<Class<? extends WebsocketMessage>> messages = new HashSet<>();
private volatile Gson gson; private volatile Gson gson;
@@ -60,10 +63,11 @@ public class WSClient extends WebSocketListener implements AutoCloseable
private WebSocket webSocket; private WebSocket webSocket;
@Inject @Inject
private WSClient(EventBus eventBus, OkHttpClient okHttpClient) private WSClient(EventBus eventBus, OkHttpClient okHttpClient, @Named("runelite.ws") HttpUrl runeliteWs)
{ {
this.eventBus = eventBus; this.eventBus = eventBus;
this.okHttpClient = okHttpClient; this.okHttpClient = okHttpClient;
this.runeliteWs = runeliteWs;
this.gson = WebsocketGsonFactory.build(WebsocketGsonFactory.factory(messages)); this.gson = WebsocketGsonFactory.build(WebsocketGsonFactory.factory(messages));
} }
@@ -101,8 +105,8 @@ public class WSClient extends WebSocketListener implements AutoCloseable
} }
Request request = new Request.Builder() Request request = new Request.Builder()
.url(RuneLiteAPI.getWsEndpoint()) .url(runeliteWs)
.header("User-Agent", RuneLiteAPI.userAgent) .header("User-Agent", RuneLite.USER_AGENT)
.build(); .build();
webSocket = okHttpClient.newWebSocket(request, this); webSocket = okHttpClient.newWebSocket(request, this);

View File

@@ -3328,5 +3328,35 @@
"z1": 0, "z1": 0,
"z2": 0 "z2": 0
} }
],
"7513": [ // POH styles 1-4
{
"rx1": 24,
"ry1": 0,
"rx2": 31,
"ry2": 7,
"z1": 0,
"z2": 3
}
],
"7769": [ // POH styles 5-8
{
"rx1": 24,
"ry1": 0,
"rx2": 31,
"ry2": 7,
"z1": 0,
"z2": 3
}
],
"8025": [ // POH styles 9-12
{
"rx1": 24,
"ry1": 0,
"rx2": 31,
"ry2": 7,
"z1": 0,
"z2": 3
}
] ]
} }

View File

@@ -2,7 +2,7 @@ runelite.title=OpenOSRS
runelite.version=@project.version@ runelite.version=@project.version@
runescape.version=@rs.version@ runescape.version=@rs.version@
runelite.discord.appid=627741263881568257 runelite.discord.appid=627741263881568257
runelite.discord.invite=https://discord.gg/r287wN6bkc runelite.discord.invite=https://discord.gg/OpenOSRS
runelite.github.link=https://github.com/open-osrs runelite.github.link=https://github.com/open-osrs
runelite.wiki.link=https://github.com/open-osrs/runelite/wiki runelite.wiki.link=https://github.com/open-osrs/runelite/wiki
runelite.patreon.link=https://www.patreon.com/openosrs runelite.patreon.link=https://www.patreon.com/openosrs
@@ -13,4 +13,8 @@ runelite.jav_config=https://oldschool.runescape.com/jav_config.ws
runelite.jav_config_backup=https://static.runelite.net/jav_config.ws runelite.jav_config_backup=https://static.runelite.net/jav_config.ws
runelite.pluginhub.url=https://repo.runelite.net/plugins runelite.pluginhub.url=https://repo.runelite.net/plugins
runelite.pluginhub.version=@project.version@ runelite.pluginhub.version=@project.version@
runelite.imgur.client.id=30d71e5f6860809 runelite.imgur.client.id=30d71e5f6860809
runelite.api.base=https://api.runelite.net/runelite-@project.version@
runelite.session=https://session.openosrs.dev
runelite.static.base=https://static.runelite.net
runelite.ws=https://api.runelite.net/ws

View File

@@ -30,7 +30,6 @@ import java.time.ZoneId;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.Locale; import java.util.Locale;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import net.runelite.http.api.RuneLiteAPI;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
@@ -38,11 +37,12 @@ import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest; import okhttp3.mockwebserver.RecordedRequest;
import org.junit.Assert; import org.junit.Assert;
import static org.junit.Assert.assertTrue;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
public class OkHttpCacheSanityTest public class OkHttpTest
{ {
@Rule @Rule
public TemporaryFolder cacheFolder = new TemporaryFolder(); public TemporaryFolder cacheFolder = new TemporaryFolder();
@@ -71,9 +71,7 @@ public class OkHttpCacheSanityTest
@Test @Test
public void testCacheSanity() throws IOException, InterruptedException public void testCacheSanity() throws IOException, InterruptedException
{ {
OkHttpClient.Builder builder = RuneLiteAPI.CLIENT.newBuilder(); OkHttpClient client = RuneLite.buildHttpClient(false);
RuneLite.setupCache(builder, cacheFolder.getRoot());
OkHttpClient client = builder.build();
Instant lastModified = Instant.now().minusSeconds(20); Instant lastModified = Instant.now().minusSeconds(20);
@@ -122,4 +120,19 @@ public class OkHttpCacheSanityTest
Assert.assertNotNull("cache did not make a conditional request", req); Assert.assertNotNull("cache did not make a conditional request", req);
Assert.assertNotNull(req.getHeader("If-Modified-Since")); Assert.assertNotNull(req.getHeader("If-Modified-Since"));
} }
@Test
public void testUserAgent() throws IOException, InterruptedException
{
server.enqueue(new MockResponse().setBody("OK"));
Request request = new Request.Builder()
.url(server.url("/"))
.build();
RuneLite.buildHttpClient(false)
.newCall(request).execute().close();
// rest of UA depends on if git is found
assertTrue(server.takeRequest().getHeader("User-Agent").startsWith("RuneLite/" + RuneLiteProperties.getVersion()));
}
} }

View File

@@ -25,7 +25,7 @@
package net.runelite.client.hiscore; package net.runelite.client.hiscore;
import java.io.IOException; import java.io.IOException;
import net.runelite.http.api.RuneLiteAPI; import okhttp3.OkHttpClient;
import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.MockWebServer;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@@ -132,7 +132,7 @@ public class HiscoreClientTest
@Test @Test
public void testNormalLookup() throws Exception public void testNormalLookup() throws Exception
{ {
HiscoreClient hiscoreClient = new HiscoreClient(RuneLiteAPI.CLIENT); HiscoreClient hiscoreClient = new HiscoreClient(new OkHttpClient());
HiscoreResult result = hiscoreClient.lookup("zezima", server.url("/")); HiscoreResult result = hiscoreClient.lookup("zezima", server.url("/"));

View File

@@ -49,17 +49,18 @@ import net.runelite.api.widgets.Widget;
import static net.runelite.api.widgets.WidgetID.ADVENTURE_LOG_ID; import static net.runelite.api.widgets.WidgetID.ADVENTURE_LOG_ID;
import static net.runelite.api.widgets.WidgetID.DIARY_QUEST_GROUP_ID; import static net.runelite.api.widgets.WidgetID.DIARY_QUEST_GROUP_ID;
import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.chat.ChatClient;
import net.runelite.client.chat.ChatCommandManager; import net.runelite.client.chat.ChatCommandManager;
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.RuneLiteConfig; import net.runelite.client.config.RuneLiteConfig;
import net.runelite.client.game.ItemManager;
import net.runelite.client.hiscore.HiscoreClient; import net.runelite.client.hiscore.HiscoreClient;
import net.runelite.client.hiscore.HiscoreEndpoint; import net.runelite.client.hiscore.HiscoreEndpoint;
import net.runelite.client.hiscore.HiscoreResult; import net.runelite.client.hiscore.HiscoreResult;
import net.runelite.client.hiscore.Skill; import net.runelite.client.hiscore.Skill;
import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.RuneLiteAPI;
import net.runelite.http.api.chat.ChatClient;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -116,6 +117,10 @@ public class ChatCommandsPluginTest
@Bind @Bind
RuneLiteConfig runeLiteConfig; RuneLiteConfig runeLiteConfig;
@Mock
@Bind
ItemManager itemManager;
@Mock @Mock
@Bind @Bind
ChatCommandsConfig chatCommandsConfig; ChatCommandsConfig chatCommandsConfig;

View File

@@ -51,7 +51,6 @@ import net.runelite.client.input.KeyManager;
import net.runelite.client.input.MouseManager; import net.runelite.client.input.MouseManager;
import static net.runelite.client.plugins.grandexchange.GrandExchangePlugin.findFuzzyIndices; import static net.runelite.client.plugins.grandexchange.GrandExchangePlugin.findFuzzyIndices;
import static net.runelite.http.api.RuneLiteAPI.GSON; import static net.runelite.http.api.RuneLiteAPI.GSON;
import net.runelite.http.api.ge.GrandExchangeClient;
import net.runelite.http.api.ge.GrandExchangeTrade; import net.runelite.http.api.ge.GrandExchangeTrade;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;

View File

@@ -61,7 +61,6 @@ import net.runelite.client.game.SpriteManager;
import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
import net.runelite.http.api.item.ItemPrice; import net.runelite.http.api.item.ItemPrice;
import net.runelite.http.api.loottracker.LootRecordType; import net.runelite.http.api.loottracker.LootRecordType;
import net.runelite.http.api.loottracker.LootTrackerClient;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import org.junit.Before; import org.junit.Before;

View File

@@ -52,6 +52,7 @@ import net.runelite.api.events.StatChanged;
import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.Notifier; import net.runelite.client.Notifier;
import net.runelite.client.chat.ChatClient;
import net.runelite.client.chat.ChatCommandManager; import net.runelite.client.chat.ChatCommandManager;
import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
@@ -59,7 +60,6 @@ import net.runelite.client.game.ItemManager;
import net.runelite.client.game.npcoverlay.NpcOverlayService; import net.runelite.client.game.npcoverlay.NpcOverlayService;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
import net.runelite.http.api.chat.ChatClient;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -142,6 +142,10 @@ public class SlayerPluginTest
@Bind @Bind
SlayerOverlay overlay; SlayerOverlay overlay;
@Mock
@Bind
TargetWeaknessOverlay targetWeaknessOverlay;
@Mock @Mock
@Bind @Bind
InfoBoxManager infoBoxManager; InfoBoxManager infoBoxManager;

View File

@@ -46,6 +46,7 @@ import net.runelite.client.Notifier;
import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemManager;
import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
import net.runelite.client.ws.PartyService; import net.runelite.client.ws.PartyService;
import net.runelite.client.ws.WSClient;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@@ -81,6 +82,10 @@ public class SpecialCounterPluginTest
@Bind @Bind
private Notifier notifier; private Notifier notifier;
@Mock
@Bind
private WSClient wsClient;
@Mock @Mock
@Bind @Bind
private SpecialCounterConfig specialCounterConfig; private SpecialCounterConfig specialCounterConfig;