Merge branch 'master' of https://github.com/runelite/runelite into upstream-03012022
Conflicts: README.md cache-client/pom.xml cache-updater/pom.xml cache/pom.xml cache/src/test/java/net/runelite/cache/SpritePixelsManagerTest.java config/checkstyle/checkstyle.xml config/checkstyle/suppressions.xml deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/BALoad.java deobfuscator/src/main/java/net/runelite/asm/pool/Class.java deobfuscator/src/main/java/net/runelite/deob/DeobProperties.java deobfuscator/src/main/java/net/runelite/deob/deobfuscators/lvt/LVTType.java deobfuscator/src/test/java/net/runelite/asm/annotations/MyAnnotation.java deobfuscator/src/test/java/net/runelite/asm/execution/mapper/StaticStepTest.java deobfuscator/src/test/java/net/runelite/deob/deobfuscators/UnusedParametersTest.java deobfuscator/src/test/java/net/runelite/deob/deobfuscators/transformers/buffer/BufferFinderTest.java deobfuscator/src/test/java/net/runelite/deob/deobfuscators/unusedclass/ClassA.java deobfuscator/src/test/java/net/runelite/deob/deobfuscators/unusedclass/EmptyClass.java http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java http-api/src/main/java/net/runelite/http/api/item/ItemStats.java http-api/src/main/resources/runelite.properties injection-annotations/src/main/java/net/runelite/api/mixins/Mixins.java pom.xml runelite-api/pom.xml runelite-api/src/main/java/net/runelite/api/Frames.java runelite-api/src/main/java/net/runelite/api/events/NpcActionChanged.java runelite-api/src/main/java/net/runelite/api/events/PlayerSkullChanged.java runelite-api/src/main/java/net/runelite/api/events/WidgetPressed.java runelite-api/src/main/java/net/runelite/api/queries/InventoryItemQuery.java runelite-api/src/main/java/net/runelite/api/util/JagexPrintableCharMatcher.java runelite-client/pom.xml runelite-client/src/main/java/com/openosrs/client/events/OPRSPluginChanged.java runelite-client/src/main/java/com/openosrs/client/events/OPRSRepositoryChanged.java runelite-client/src/main/java/com/openosrs/client/game/AttackStyle.java runelite-client/src/main/java/net/runelite/client/ClientSessionManager.java runelite-client/src/main/java/net/runelite/client/RuneLite.java runelite-client/src/main/java/net/runelite/client/RuneLiteModule.java runelite-client/src/main/java/net/runelite/client/SessionClient.java runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java runelite-client/src/main/java/net/runelite/client/game/ItemClient.java runelite-client/src/main/java/net/runelite/client/game/ItemManager.java runelite-client/src/main/java/net/runelite/client/game/WorldService.java runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpData.java runelite-client/src/main/java/net/runelite/client/plugins/xtea/XteaClient.java runelite-client/src/main/java/net/runelite/client/util/PvPUtil.java runelite-client/src/main/resources/net/runelite/client/runelite.properties runelite-client/src/test/java/net/runelite/client/config/ConfigManagerTest.java runelite-client/src/test/java/net/runelite/client/plugins/raids/RaidsPluginTest.java runelite-client/src/test/java/net/runelite/client/plugins/xptracker/XpTrackerPluginTest.java runelite-jshell/pom.xml runelite-mixins/src/main/java/net/runelite/mixins/ProcessClientErrorMixin.java runelite-mixins/src/main/java/net/runelite/mixins/RSTextureMixin.java runelite-script-assembler-plugin/pom.xml runescape-api/src/main/java/net/runelite/rs/api/RSAbstractRasterProvider.java runescape-api/src/main/java/net/runelite/rs/api/RSDecimator.java runescape-api/src/main/java/net/runelite/rs/api/RSFrames.java runescape-api/src/main/java/net/runelite/rs/api/RSProjectile.java runescape-api/src/main/java/net/runelite/rs/api/RSRasterProvider.java runescape-api/src/main/java/net/runelite/rs/api/RSScriptEvent.java runescape-api/src/main/java/net/runelite/rs/api/RSUsername.java runescape-client/src/test/java/ISAACCipherTest.java
This commit is contained in:
@@ -38,7 +38,6 @@ import net.runelite.api.GameState;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.ClientShutdown;
|
||||
import net.runelite.client.util.RunnableExceptionLogger;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
@@ -54,11 +53,11 @@ public class ClientSessionManager
|
||||
@Inject
|
||||
ClientSessionManager(ScheduledExecutorService executorService,
|
||||
@Nullable Client client,
|
||||
OkHttpClient okHttpClient)
|
||||
SessionClient sessionClient)
|
||||
{
|
||||
this.executorService = executorService;
|
||||
this.client = client;
|
||||
this.sessionClient = new SessionClient(okHttpClient);
|
||||
this.sessionClient = sessionClient;
|
||||
}
|
||||
|
||||
public void start()
|
||||
|
||||
@@ -49,6 +49,7 @@ import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
import javax.annotation.Nullable;
|
||||
@@ -91,6 +92,7 @@ import net.runelite.http.api.worlds.World;
|
||||
import net.runelite.http.api.worlds.WorldResult;
|
||||
import okhttp3.Cache;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -109,6 +111,7 @@ public class RuneLite
|
||||
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
|
||||
public static String USER_AGENT = "RuneLite/" + RuneLiteProperties.getVersion() + "-" + RuneLiteProperties.getCommit() + (RuneLiteProperties.isDirty() ? "+" : "");
|
||||
|
||||
@Getter
|
||||
private static Injector injector;
|
||||
@@ -273,16 +276,8 @@ public class RuneLite
|
||||
|
||||
OpenOSRS.preload();
|
||||
|
||||
OkHttpClient.Builder okHttpClientBuilder = RuneLiteAPI.CLIENT.newBuilder();
|
||||
setupCache(okHttpClientBuilder, new File(CACHE_DIR, "okhttp"));
|
||||
|
||||
final boolean insecureSkipTlsVerification = options.has("insecure-skip-tls-verification");
|
||||
if (insecureSkipTlsVerification || RuneLiteProperties.isInsecureSkipTlsVerification())
|
||||
{
|
||||
setupInsecureTrustManager(okHttpClientBuilder);
|
||||
}
|
||||
|
||||
final OkHttpClient okHttpClient = okHttpClientBuilder.build();
|
||||
final OkHttpClient okHttpClient = buildHttpClient(options.has("insecure-skip-tls-verification"));
|
||||
RuneLiteAPI.CLIENT = okHttpClient;
|
||||
|
||||
SplashScreen.init();
|
||||
OpenOSRSSplashScreen.init();
|
||||
@@ -532,9 +527,20 @@ public class RuneLite
|
||||
}
|
||||
|
||||
@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 ->
|
||||
{
|
||||
// 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;
|
||||
});
|
||||
|
||||
if (insecureSkipTlsVerification || RuneLiteProperties.isInsecureSkipTlsVerification())
|
||||
{
|
||||
setupInsecureTrustManager(builder);
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private static void setupInsecureTrustManager(OkHttpClient.Builder okHttpClientBuilder)
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
package net.runelite.client;
|
||||
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
@@ -41,6 +42,7 @@ import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Supplier;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.AllArgsConstructor;
|
||||
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.ExecutorServiceExceptionLogger;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import net.runelite.http.api.chat.ChatClient;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
@AllArgsConstructor
|
||||
@@ -135,10 +137,35 @@ public class RuneLiteModule extends AbstractModule
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
ChatClient provideChatClient(OkHttpClient okHttpClient)
|
||||
@Named("runelite.api.base")
|
||||
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
|
||||
|
||||
@@ -36,6 +36,8 @@ public class RuneLiteProperties
|
||||
{
|
||||
private static final String RUNELITE_TITLE = "runelite.title";
|
||||
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 LAUNCHER_VERSION_PROPERTY = "runelite.launcher.version";
|
||||
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 PLUGINHUB_BASE = "runelite.pluginhub.url";
|
||||
private static final String PLUGINHUB_VERSION = "runelite.pluginhub.version";
|
||||
private static final String API_BASE = "runelite.api.base";
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private static final Properties properties = new Properties();
|
||||
@@ -78,6 +81,16 @@ public class RuneLiteProperties
|
||||
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()
|
||||
{
|
||||
return properties.getProperty(DISCORD_INVITE);
|
||||
@@ -124,4 +137,9 @@ public class RuneLiteProperties
|
||||
String version = System.getProperty(PLUGINHUB_VERSION, properties.getProperty(PLUGINHUB_VERSION));
|
||||
return HttpUrl.parse(properties.get(PLUGINHUB_BASE) + "/" + version);
|
||||
}
|
||||
|
||||
public static String getApiBase()
|
||||
{
|
||||
return properties.getProperty(API_BASE);
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,8 @@ import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.UUID;
|
||||
import lombok.AllArgsConstructor;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
@@ -42,11 +44,19 @@ import okhttp3.ResponseBody;
|
||||
@AllArgsConstructor
|
||||
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
|
||||
{
|
||||
HttpUrl url = RuneLiteAPI.getSessionBase().newBuilder()
|
||||
HttpUrl url = sessionUrl.newBuilder()
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
@@ -54,10 +64,10 @@ class SessionClient
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = okHttpClient.newCall(request).execute())
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
ResponseBody body = response.body();
|
||||
|
||||
|
||||
InputStream in = body.byteStream();
|
||||
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), UUID.class);
|
||||
}
|
||||
@@ -69,7 +79,7 @@ class SessionClient
|
||||
|
||||
void ping(UUID uuid, boolean loggedIn) throws IOException
|
||||
{
|
||||
HttpUrl url = RuneLiteAPI.getSessionBase().newBuilder()
|
||||
HttpUrl url = sessionUrl.newBuilder()
|
||||
.addPathSegment("ping")
|
||||
.addQueryParameter("session", uuid.toString())
|
||||
.addQueryParameter("logged-in", String.valueOf(loggedIn))
|
||||
@@ -80,7 +90,7 @@ class SessionClient
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = okHttpClient.newCall(request).execute())
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
@@ -91,7 +101,7 @@ class SessionClient
|
||||
|
||||
void delete(UUID uuid) throws IOException
|
||||
{
|
||||
HttpUrl url = RuneLiteAPI.getSessionBase().newBuilder()
|
||||
HttpUrl url = sessionUrl.newBuilder()
|
||||
.addQueryParameter("session", uuid.toString())
|
||||
.build();
|
||||
|
||||
@@ -100,6 +110,6 @@ class SessionClient
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
okHttpClient.newCall(request).execute().close();
|
||||
client.newCall(request).execute().close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.account;
|
||||
|
||||
import com.google.gson.JsonParseException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
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 net.runelite.http.api.account.OAuthResponse;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
@Slf4j
|
||||
public class AccountClient
|
||||
{
|
||||
private final OkHttpClient client;
|
||||
private final HttpUrl apiBase;
|
||||
|
||||
@Setter
|
||||
private UUID uuid;
|
||||
|
||||
@Inject
|
||||
private AccountClient(OkHttpClient client, @Named("runelite.api.base") HttpUrl apiBase)
|
||||
{
|
||||
this.client = client;
|
||||
this.apiBase = apiBase;
|
||||
}
|
||||
|
||||
public OAuthResponse login() throws IOException
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("account")
|
||||
.addPathSegment("login")
|
||||
.addQueryParameter("uuid", uuid.toString())
|
||||
.build();
|
||||
|
||||
log.debug("Built URI: {}", url);
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
InputStream in = response.body().byteStream();
|
||||
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), OAuthResponse.class);
|
||||
}
|
||||
catch (JsonParseException ex)
|
||||
{
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void logout() throws IOException
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("account")
|
||||
.addPathSegment("logout")
|
||||
.build();
|
||||
|
||||
log.debug("Built URI: {}", url);
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.header(RuneLiteAPI.RUNELITE_AUTH, uuid.toString())
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
log.debug("Sent logout request");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean sessionCheck()
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("account")
|
||||
.addPathSegment("session-check")
|
||||
.build();
|
||||
|
||||
log.debug("Built URI: {}", url);
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.header(RuneLiteAPI.RUNELITE_AUTH, uuid.toString())
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
return response.isSuccessful();
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
log.debug("Unable to verify session", ex);
|
||||
return true; // assume it is still valid if the server is unreachable
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,10 +47,8 @@ import net.runelite.client.events.SessionClose;
|
||||
import net.runelite.client.events.SessionOpen;
|
||||
import net.runelite.client.util.LinkBrowser;
|
||||
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.ws.messages.LoginResponse;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
@@ -72,14 +70,14 @@ public class SessionManager
|
||||
ConfigManager configManager,
|
||||
EventBus eventBus,
|
||||
WSClient wsClient,
|
||||
OkHttpClient okHttpClient,
|
||||
AccountClient accountClient,
|
||||
Gson gson)
|
||||
{
|
||||
this.configManager = configManager;
|
||||
this.eventBus = eventBus;
|
||||
this.wsClient = wsClient;
|
||||
this.sessionFile = sessionfile;
|
||||
this.accountClient = new AccountClient(okHttpClient);
|
||||
this.accountClient = accountClient;
|
||||
this.gson = gson;
|
||||
|
||||
eventBus.register(this);
|
||||
|
||||
@@ -0,0 +1,429 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.chat;
|
||||
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
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.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
|
||||
public class ChatClient
|
||||
{
|
||||
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
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("chat")
|
||||
.addPathSegment("kc")
|
||||
.addQueryParameter("name", username)
|
||||
.addQueryParameter("boss", boss)
|
||||
.addQueryParameter("kc", Integer.toString(kc))
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.post(RequestBody.create(null, new byte[0]))
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
return response.isSuccessful();
|
||||
}
|
||||
}
|
||||
|
||||
public int getKc(String username, String boss) throws IOException
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("chat")
|
||||
.addPathSegment("kc")
|
||||
.addQueryParameter("name", username)
|
||||
.addQueryParameter("boss", boss)
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
throw new IOException("Unable to look up killcount!");
|
||||
}
|
||||
return Integer.parseInt(response.body().string());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean submitQp(String username, int qp) throws IOException
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("chat")
|
||||
.addPathSegment("qp")
|
||||
.addQueryParameter("name", username)
|
||||
.addQueryParameter("qp", Integer.toString(qp))
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.post(RequestBody.create(null, new byte[0]))
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
return response.isSuccessful();
|
||||
}
|
||||
}
|
||||
|
||||
public int getQp(String username) throws IOException
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("chat")
|
||||
.addPathSegment("qp")
|
||||
.addQueryParameter("name", username)
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
throw new IOException("Unable to look up quest points!");
|
||||
}
|
||||
return Integer.parseInt(response.body().string());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean submitTask(String username, String task, int amount, int initialAmount, String location) throws IOException
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("chat")
|
||||
.addPathSegment("task")
|
||||
.addQueryParameter("name", username)
|
||||
.addQueryParameter("task", task)
|
||||
.addQueryParameter("amount", Integer.toString(amount))
|
||||
.addQueryParameter("initialAmount", Integer.toString(initialAmount))
|
||||
.addQueryParameter("location", location)
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.post(RequestBody.create(null, new byte[0]))
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
return response.isSuccessful();
|
||||
}
|
||||
}
|
||||
|
||||
public Task getTask(String username) throws IOException
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("chat")
|
||||
.addPathSegment("task")
|
||||
.addQueryParameter("name", username)
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
throw new IOException("Unable to look up task!");
|
||||
}
|
||||
|
||||
InputStream in = response.body().byteStream();
|
||||
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), Task.class);
|
||||
}
|
||||
catch (JsonParseException ex)
|
||||
{
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean submitPb(String username, String boss, double pb) throws IOException
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("chat")
|
||||
.addPathSegment("pb")
|
||||
.addQueryParameter("name", username)
|
||||
.addQueryParameter("boss", boss)
|
||||
.addQueryParameter("pb", Double.toString(pb))
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.post(RequestBody.create(null, new byte[0]))
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
return response.isSuccessful();
|
||||
}
|
||||
}
|
||||
|
||||
public double getPb(String username, String boss) throws IOException
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("chat")
|
||||
.addPathSegment("pb")
|
||||
.addQueryParameter("name", username)
|
||||
.addQueryParameter("boss", boss)
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
throw new IOException("Unable to look up personal best!");
|
||||
}
|
||||
return Double.parseDouble(response.body().string());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean submitGc(String username, int gc) throws IOException
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("chat")
|
||||
.addPathSegment("gc")
|
||||
.addQueryParameter("name", username)
|
||||
.addQueryParameter("gc", Integer.toString(gc))
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.post(RequestBody.create(null, new byte[0]))
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
return response.isSuccessful();
|
||||
}
|
||||
}
|
||||
|
||||
public int getGc(String username) throws IOException
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("chat")
|
||||
.addPathSegment("gc")
|
||||
.addQueryParameter("name", username)
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
throw new IOException("Unable to look up gamble count!");
|
||||
}
|
||||
return Integer.parseInt(response.body().string());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean submitDuels(String username, int wins, int losses, int winningStreak, int losingStreak) throws IOException
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("chat")
|
||||
.addPathSegment("duels")
|
||||
.addQueryParameter("name", username)
|
||||
.addQueryParameter("wins", Integer.toString(wins))
|
||||
.addQueryParameter("losses", Integer.toString(losses))
|
||||
.addQueryParameter("winningStreak", Integer.toString(winningStreak))
|
||||
.addQueryParameter("losingStreak", Integer.toString(losingStreak))
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.post(RequestBody.create(null, new byte[0]))
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
return response.isSuccessful();
|
||||
}
|
||||
}
|
||||
|
||||
public Duels getDuels(String username) throws IOException
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("chat")
|
||||
.addPathSegment("duels")
|
||||
.addQueryParameter("name", username)
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
throw new IOException("Unable to look up duels!");
|
||||
}
|
||||
|
||||
InputStream in = response.body().byteStream();
|
||||
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), Duels.class);
|
||||
}
|
||||
catch (JsonParseException ex)
|
||||
{
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean submitLayout(String username, LayoutRoom[] rooms) throws IOException
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("chat")
|
||||
.addPathSegment("layout")
|
||||
.addQueryParameter("name", username)
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.post(RequestBody.create(RuneLiteAPI.JSON, RuneLiteAPI.GSON.toJson(rooms)))
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
return response.isSuccessful();
|
||||
}
|
||||
}
|
||||
|
||||
public LayoutRoom[] getLayout(String username) throws IOException
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("chat")
|
||||
.addPathSegment("layout")
|
||||
.addQueryParameter("name", username)
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
throw new IOException("Unable to look up layout!");
|
||||
}
|
||||
|
||||
InputStream in = response.body().byteStream();
|
||||
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), LayoutRoom[].class);
|
||||
}
|
||||
catch (JsonParseException ex)
|
||||
{
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean submitPetList(String username, Collection<Integer> petList) throws IOException
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("chat")
|
||||
.addPathSegment("pets")
|
||||
.addQueryParameter("name", username)
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.post(RequestBody.create(RuneLiteAPI.JSON, RuneLiteAPI.GSON.toJson(petList)))
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
return response.isSuccessful();
|
||||
}
|
||||
}
|
||||
|
||||
public Set<Integer> getPetList(String username) throws IOException
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("chat")
|
||||
.addPathSegment("pets")
|
||||
.addQueryParameter("name", username)
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
throw new IOException("Unable to look up pet list!");
|
||||
}
|
||||
|
||||
InputStream in = response.body().byteStream();
|
||||
// CHECKSTYLE:OFF
|
||||
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8),
|
||||
new TypeToken<Set<Integer>>(){}.getType());
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
catch (JsonParseException ex)
|
||||
{
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.config;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonParseException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import net.runelite.http.api.config.Configuration;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
|
||||
@Slf4j
|
||||
public class ConfigClient
|
||||
{
|
||||
private static final MediaType TEXT_PLAIN = MediaType.parse("text/plain");
|
||||
private static final Gson GSON = RuneLiteAPI.GSON;
|
||||
|
||||
private final OkHttpClient client;
|
||||
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
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("config")
|
||||
.build();
|
||||
|
||||
log.debug("Built URI: {}", url);
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.header(RuneLiteAPI.RUNELITE_AUTH, uuid.toString())
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
InputStream in = response.body().byteStream();
|
||||
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), Configuration.class);
|
||||
}
|
||||
catch (JsonParseException ex)
|
||||
{
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> set(String key, String value)
|
||||
{
|
||||
CompletableFuture<Void> future = new CompletableFuture<>();
|
||||
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("config")
|
||||
.addPathSegment(key)
|
||||
.build();
|
||||
|
||||
log.debug("Built URI: {}", url);
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.put(RequestBody.create(TEXT_PLAIN, value))
|
||||
.header(RuneLiteAPI.RUNELITE_AUTH, uuid.toString())
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
client.newCall(request).enqueue(new Callback()
|
||||
{
|
||||
@Override
|
||||
public void onFailure(Call call, IOException e)
|
||||
{
|
||||
log.warn("Unable to synchronize configuration item", e);
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Call call, Response response)
|
||||
{
|
||||
response.close();
|
||||
log.debug("Synchronized configuration value '{}' to '{}'", key, value);
|
||||
future.complete(null);
|
||||
}
|
||||
});
|
||||
|
||||
return future;
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> patch(Configuration configuration)
|
||||
{
|
||||
CompletableFuture<Void> future = new CompletableFuture<>();
|
||||
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("config")
|
||||
.build();
|
||||
|
||||
log.debug("Built URI: {}", url);
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.patch(RequestBody.create(RuneLiteAPI.JSON, GSON.toJson(configuration)))
|
||||
.header(RuneLiteAPI.RUNELITE_AUTH, uuid.toString())
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
client.newCall(request).enqueue(new Callback()
|
||||
{
|
||||
@Override
|
||||
public void onFailure(Call call, IOException e)
|
||||
{
|
||||
log.warn("Unable to synchronize configuration item", e);
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Call call, Response response)
|
||||
{
|
||||
if (response.code() != 200)
|
||||
{
|
||||
String body = "bad response";
|
||||
try
|
||||
{
|
||||
body = response.body().string();
|
||||
}
|
||||
catch (IOException ignored)
|
||||
{
|
||||
}
|
||||
|
||||
log.warn("failed to synchronize some of {} configuration values: {}", configuration.getConfig().size(), body);
|
||||
}
|
||||
else
|
||||
{
|
||||
log.debug("Synchronized {} configuration values", configuration.getConfig().size());
|
||||
}
|
||||
response.close();
|
||||
future.complete(null);
|
||||
}
|
||||
});
|
||||
|
||||
return future;
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> unset(String key)
|
||||
{
|
||||
CompletableFuture<Void> future = new CompletableFuture<>();
|
||||
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("config")
|
||||
.addPathSegment(key)
|
||||
.build();
|
||||
|
||||
log.debug("Built URI: {}", url);
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.delete()
|
||||
.header(RuneLiteAPI.RUNELITE_AUTH, uuid.toString())
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
client.newCall(request).enqueue(new Callback()
|
||||
{
|
||||
@Override
|
||||
public void onFailure(Call call, IOException e)
|
||||
{
|
||||
log.warn("Unable to unset configuration item", e);
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Call call, Response response)
|
||||
{
|
||||
response.close();
|
||||
log.debug("Unset configuration value '{}'", key);
|
||||
future.complete(null);
|
||||
}
|
||||
});
|
||||
|
||||
return future;
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.RuneLiteProperties;
|
||||
import net.runelite.client.util.VerificationException;
|
||||
@@ -62,12 +63,17 @@ public class ExternalPluginClient
|
||||
{
|
||||
private final OkHttpClient okHttpClient;
|
||||
private final Gson gson;
|
||||
private final HttpUrl apiBase;
|
||||
|
||||
@Inject
|
||||
private ExternalPluginClient(OkHttpClient okHttpClient, Gson gson)
|
||||
private ExternalPluginClient(OkHttpClient okHttpClient,
|
||||
Gson gson,
|
||||
@Named("runelite.api.base") HttpUrl apiBase
|
||||
)
|
||||
{
|
||||
this.okHttpClient = okHttpClient;
|
||||
this.gson = gson;
|
||||
this.apiBase = apiBase;
|
||||
}
|
||||
|
||||
public List<ExternalPluginManifest> downloadManifest() throws IOException, VerificationException
|
||||
@@ -153,7 +159,7 @@ public class ExternalPluginClient
|
||||
return;
|
||||
}
|
||||
|
||||
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder()
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("pluginhub")
|
||||
.build();
|
||||
|
||||
@@ -181,7 +187,7 @@ public class ExternalPluginClient
|
||||
|
||||
public Map<String, Integer> getPluginCounts() throws IOException
|
||||
{
|
||||
HttpUrl url = RuneLiteAPI.getApiBase()
|
||||
HttpUrl url = apiBase
|
||||
.newBuilder()
|
||||
.addPathSegments("pluginhub")
|
||||
.build();
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.game;
|
||||
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class ItemClient
|
||||
{
|
||||
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
|
||||
{
|
||||
HttpUrl.Builder urlBuilder = apiBase.newBuilder()
|
||||
.addPathSegment("item")
|
||||
.addPathSegment("prices.js");
|
||||
|
||||
HttpUrl url = urlBuilder.build();
|
||||
|
||||
log.debug("Built URI: {}", url);
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
log.warn("Error looking up prices: {}", response);
|
||||
return null;
|
||||
}
|
||||
|
||||
InputStream in = response.body().byteStream();
|
||||
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), ItemPrice[].class);
|
||||
}
|
||||
catch (JsonParseException ex)
|
||||
{
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Integer, ItemStats> getStats() throws IOException
|
||||
{
|
||||
HttpUrl.Builder urlBuilder = staticBase.newBuilder()
|
||||
.addPathSegment("item")
|
||||
// TODO: Change this to stats.min.json later after release is undeployed
|
||||
.addPathSegment("stats.ids.min.json");
|
||||
|
||||
HttpUrl url = urlBuilder.build();
|
||||
|
||||
log.debug("Built URI: {}", url);
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
log.warn("Error looking up item stats: {}", response);
|
||||
return null;
|
||||
}
|
||||
|
||||
InputStream in = response.body().byteStream();
|
||||
final Type typeToken = new TypeToken<Map<Integer, ItemStats>>()
|
||||
{
|
||||
}.getType();
|
||||
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), typeToken);
|
||||
}
|
||||
catch (JsonParseException ex)
|
||||
{
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,10 +56,8 @@ import net.runelite.api.SpritePixels;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.config.RuneLiteConfig;
|
||||
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.ItemStats;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
@@ -168,11 +166,11 @@ public class ItemManager
|
||||
|
||||
@Inject
|
||||
public ItemManager(Client client, ScheduledExecutorService scheduledExecutorService, ClientThread clientThread,
|
||||
OkHttpClient okHttpClient, RuneLiteConfig runeLiteConfig)
|
||||
ItemClient itemClient, RuneLiteConfig runeLiteConfig)
|
||||
{
|
||||
this.client = client;
|
||||
this.clientThread = clientThread;
|
||||
this.itemClient = new ItemClient(okHttpClient);
|
||||
this.itemClient = itemClient;
|
||||
this.runeLiteConfig = runeLiteConfig;
|
||||
|
||||
scheduledExecutorService.scheduleWithFixedDelay(this::loadPrices, 0, 30, TimeUnit.MINUTES);
|
||||
|
||||
@@ -32,21 +32,18 @@ import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.http.api.npc.NpcInfo;
|
||||
import net.runelite.http.api.npc.NpcInfoClient;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class NPCManager
|
||||
{
|
||||
private final OkHttpClient okHttpClient;
|
||||
private final NpcInfoClient npcInfoClient;
|
||||
private Map<Integer, NpcInfo> npcMap = Collections.emptyMap();
|
||||
|
||||
@Inject
|
||||
private NPCManager(OkHttpClient okHttpClient, ScheduledExecutorService scheduledExecutorService)
|
||||
private NPCManager(NpcInfoClient npcInfoClient, ScheduledExecutorService scheduledExecutorService)
|
||||
{
|
||||
this.okHttpClient = okHttpClient;
|
||||
this.npcInfoClient = npcInfoClient;
|
||||
scheduledExecutorService.execute(this::loadNpcs);
|
||||
}
|
||||
|
||||
@@ -67,7 +64,7 @@ public class NPCManager
|
||||
{
|
||||
try
|
||||
{
|
||||
npcMap = new NpcInfoClient(okHttpClient).getNpcs();
|
||||
npcMap = npcInfoClient.getNpcs();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.game;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class NpcInfo
|
||||
{
|
||||
private int hitpoints;
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.game;
|
||||
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
@Slf4j
|
||||
public class NpcInfoClient
|
||||
{
|
||||
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
|
||||
{
|
||||
HttpUrl.Builder urlBuilder = staticBase.newBuilder()
|
||||
.addPathSegment("npcs")
|
||||
.addPathSegment("npcs.min.json");
|
||||
|
||||
HttpUrl url = urlBuilder.build();
|
||||
|
||||
log.debug("Built URI: {}", url);
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
log.warn("Error looking up npcs: {}", response);
|
||||
return null;
|
||||
}
|
||||
|
||||
InputStream in = response.body().byteStream();
|
||||
final Type typeToken = new TypeToken<Map<Integer, NpcInfo>>()
|
||||
{
|
||||
}.getType();
|
||||
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), typeToken);
|
||||
}
|
||||
catch (JsonParseException ex)
|
||||
{
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.game;
|
||||
|
||||
import com.google.gson.JsonParseException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import net.runelite.http.api.worlds.WorldResult;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class WorldClient
|
||||
{
|
||||
private final OkHttpClient client;
|
||||
private final HttpUrl apiBase;
|
||||
|
||||
public WorldResult lookupWorlds() throws IOException
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("worlds.js")
|
||||
.build();
|
||||
|
||||
log.debug("Built URI: {}", url);
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
log.debug("Error looking up worlds: {}", response);
|
||||
throw new IOException("unsuccessful response looking up worlds");
|
||||
}
|
||||
|
||||
InputStream in = response.body().byteStream();
|
||||
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), WorldResult.class);
|
||||
}
|
||||
catch (JsonParseException ex)
|
||||
{
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.util.RunnableExceptionLogger;
|
||||
import net.runelite.http.api.worlds.World;
|
||||
import net.runelite.http.api.worlds.WorldClient;
|
||||
import net.runelite.http.api.worlds.WorldResult;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
@Singleton
|
||||
@@ -61,11 +62,11 @@ public class WorldService
|
||||
|
||||
@Inject
|
||||
private WorldService(@Nullable Client client, ScheduledExecutorService scheduledExecutorService, OkHttpClient okHttpClient,
|
||||
EventBus eventBus)
|
||||
@Named("runelite.api.base") HttpUrl apiBase, EventBus eventBus)
|
||||
{
|
||||
this.client = client;
|
||||
this.scheduledExecutorService = scheduledExecutorService;
|
||||
this.worldClient = new WorldClient(okHttpClient);
|
||||
this.worldClient = new WorldClient(okHttpClient, apiBase);
|
||||
this.eventBus = eventBus;
|
||||
|
||||
scheduledExecutorService.scheduleWithFixedDelay(RunnableExceptionLogger.wrap(this::tick), 0, WORLD_FETCH_TIMER, TimeUnit.MINUTES);
|
||||
|
||||
@@ -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 net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.chat.ChatClient;
|
||||
import net.runelite.client.chat.ChatColorType;
|
||||
import net.runelite.client.chat.ChatCommandManager;
|
||||
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.QuantityFormatter;
|
||||
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.item.ItemPrice;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
|
||||
* 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.feed;
|
||||
|
||||
import com.google.gson.JsonParseException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import net.runelite.http.api.feed.FeedResult;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
@Slf4j
|
||||
public class FeedClient
|
||||
{
|
||||
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
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("feed.js")
|
||||
.build();
|
||||
|
||||
log.debug("Built URI: {}", url);
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
log.debug("Error looking up feed: {}", response);
|
||||
return null;
|
||||
}
|
||||
|
||||
InputStream in = response.body().byteStream();
|
||||
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), FeedResult.class);
|
||||
}
|
||||
catch (JsonParseException ex)
|
||||
{
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,9 +45,7 @@ import net.runelite.client.task.Schedule;
|
||||
import net.runelite.client.ui.ClientToolbar;
|
||||
import net.runelite.client.ui.NavigationButton;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
import net.runelite.http.api.feed.FeedClient;
|
||||
import net.runelite.http.api.feed.FeedResult;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "News Feed",
|
||||
@@ -145,10 +143,4 @@ public class FeedPlugin extends Plugin
|
||||
{
|
||||
return configManager.getConfig(FeedConfig.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
FeedClient provideFeedClient(OkHttpClient okHttpClient)
|
||||
{
|
||||
return new FeedClient(okHttpClient);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,9 +44,13 @@ import com.jogamp.opengl.GLFBODrawable;
|
||||
import com.jogamp.opengl.GLProfile;
|
||||
import com.jogamp.opengl.math.Matrix4;
|
||||
import java.awt.Canvas;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
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.image.BufferedImage;
|
||||
import java.awt.image.DataBufferInt;
|
||||
@@ -293,6 +297,24 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
||||
private int uniSmoothBanding;
|
||||
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
|
||||
protected void startUp()
|
||||
{
|
||||
@@ -447,6 +469,12 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
||||
{
|
||||
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)
|
||||
{
|
||||
@@ -474,6 +502,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
||||
@Override
|
||||
protected void shutDown()
|
||||
{
|
||||
((Component) client).removeComponentListener(resizeListener);
|
||||
clientThread.invoke(() ->
|
||||
{
|
||||
client.setGpu(false);
|
||||
@@ -1091,16 +1120,22 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
||||
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.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
|
||||
// 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,
|
||||
// we manually trigger a resize here.
|
||||
GLFBODrawable glfboDrawable = (GLFBODrawable) glDrawable;
|
||||
log.debug("Resetting GLFBODrawable size");
|
||||
glfboDrawable.resetSize(gl);
|
||||
}
|
||||
needsReset--;
|
||||
}
|
||||
|
||||
final BufferProvider bufferProvider = client.getBufferProvider();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -100,11 +100,9 @@ import net.runelite.client.util.LinkBrowser;
|
||||
import net.runelite.client.util.OSType;
|
||||
import net.runelite.client.util.QuantityFormatter;
|
||||
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.item.ItemStats;
|
||||
import net.runelite.http.api.worlds.WorldType;
|
||||
import okhttp3.OkHttpClient;
|
||||
import org.apache.commons.lang3.time.DurationFormatUtils;
|
||||
import org.apache.commons.text.similarity.FuzzyScore;
|
||||
|
||||
@@ -259,12 +257,6 @@ public class GrandExchangePlugin extends Plugin
|
||||
return configManager.getConfig(GrandExchangeConfig.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
GrandExchangeClient provideGrandExchangeClient(OkHttpClient okHttpClient)
|
||||
{
|
||||
return new GrandExchangeClient(okHttpClient);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp()
|
||||
{
|
||||
|
||||
@@ -800,7 +800,7 @@ public class GroundItemsPlugin extends Plugin
|
||||
Lootbeam lootbeam = lootbeams.get(worldPoint);
|
||||
if (lootbeam == null)
|
||||
{
|
||||
lootbeam = new Lootbeam(client, worldPoint, color);
|
||||
lootbeam = new Lootbeam(client, clientThread, worldPoint, color);
|
||||
lootbeams.put(worldPoint, lootbeam);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -27,10 +27,12 @@ package net.runelite.client.plugins.grounditems;
|
||||
import net.runelite.api.AnimationID;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.JagexColor;
|
||||
import net.runelite.api.Model;
|
||||
import net.runelite.api.RuneLiteObject;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import java.awt.Color;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
|
||||
class Lootbeam
|
||||
{
|
||||
@@ -39,11 +41,13 @@ class Lootbeam
|
||||
|
||||
private final RuneLiteObject runeLiteObject;
|
||||
private final Client client;
|
||||
private final ClientThread clientThread;
|
||||
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.clientThread = clientThread;
|
||||
runeLiteObject = client.createRuneLiteObject();
|
||||
|
||||
setColor(color);
|
||||
@@ -64,11 +68,21 @@ class Lootbeam
|
||||
}
|
||||
|
||||
this.color = color;
|
||||
runeLiteObject.setModel(client.loadModel(
|
||||
RAID_LIGHT_MODEL,
|
||||
new short[]{RAID_LIGHT_FIND_COLOR},
|
||||
new short[]{JagexColor.rgbToHSL(color.getRGB(), 1.0d)}
|
||||
));
|
||||
clientThread.invoke(() ->
|
||||
{
|
||||
Model m = client.loadModel(
|
||||
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()
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.loottracker;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import lombok.Getter;
|
||||
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.loottracker.LootAggregate;
|
||||
import net.runelite.http.api.loottracker.LootRecord;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
|
||||
@Slf4j
|
||||
public class LootTrackerClient
|
||||
{
|
||||
private static final Gson GSON = RuneLiteAPI.GSON;
|
||||
|
||||
private final OkHttpClient client;
|
||||
private final HttpUrl apiBase;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
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)
|
||||
{
|
||||
CompletableFuture<Void> future = new CompletableFuture<>();
|
||||
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("loottracker")
|
||||
.build();
|
||||
|
||||
Request.Builder requestBuilder = new Request.Builder();
|
||||
if (uuid != null)
|
||||
{
|
||||
requestBuilder.header(RuneLiteAPI.RUNELITE_AUTH, uuid.toString());
|
||||
}
|
||||
requestBuilder.post(RequestBody.create(JSON, GSON.toJson(lootRecords)))
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
client.newCall(requestBuilder.build()).enqueue(new Callback()
|
||||
{
|
||||
@Override
|
||||
public void onFailure(Call call, IOException e)
|
||||
{
|
||||
log.warn("unable to submit loot", e);
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Call call, Response response)
|
||||
{
|
||||
if (response.isSuccessful())
|
||||
{
|
||||
log.debug("Submitted loot");
|
||||
}
|
||||
else
|
||||
{
|
||||
log.warn("Error submitting loot: {} - {}", response.code(), response.message());
|
||||
}
|
||||
response.close();
|
||||
future.complete(null);
|
||||
}
|
||||
});
|
||||
|
||||
return future;
|
||||
}
|
||||
|
||||
public Collection<LootAggregate> get() throws IOException
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("loottracker")
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.header(RuneLiteAPI.RUNELITE_AUTH, uuid.toString())
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
log.debug("Error looking up loot: {}", response);
|
||||
return null;
|
||||
}
|
||||
|
||||
InputStream in = response.body().byteStream();
|
||||
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), new TypeToken<List<LootAggregate>>()
|
||||
{
|
||||
}.getType());
|
||||
}
|
||||
catch (JsonParseException ex)
|
||||
{
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void delete(String eventId)
|
||||
{
|
||||
HttpUrl.Builder builder = apiBase.newBuilder()
|
||||
.addPathSegment("loottracker");
|
||||
|
||||
if (eventId != null)
|
||||
{
|
||||
builder.addQueryParameter("eventId", eventId);
|
||||
}
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.header(RuneLiteAPI.RUNELITE_AUTH, uuid.toString())
|
||||
.delete()
|
||||
.url(builder.build())
|
||||
.build();
|
||||
|
||||
client.newCall(request).enqueue(new Callback()
|
||||
{
|
||||
@Override
|
||||
public void onFailure(Call call, IOException e)
|
||||
{
|
||||
log.warn("unable to delete loot", e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Call call, Response response)
|
||||
{
|
||||
log.debug("Deleted loot");
|
||||
response.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -65,7 +65,6 @@ import net.runelite.client.util.ImageUtil;
|
||||
import net.runelite.client.util.QuantityFormatter;
|
||||
import net.runelite.client.util.SwingUtil;
|
||||
import net.runelite.http.api.loottracker.LootRecordType;
|
||||
import net.runelite.http.api.loottracker.LootTrackerClient;
|
||||
|
||||
class LootTrackerPanel extends PluginPanel
|
||||
{
|
||||
|
||||
@@ -114,8 +114,6 @@ import net.runelite.http.api.loottracker.GameItem;
|
||||
import net.runelite.http.api.loottracker.LootAggregate;
|
||||
import net.runelite.http.api.loottracker.LootRecord;
|
||||
import net.runelite.http.api.loottracker.LootRecordType;
|
||||
import net.runelite.http.api.loottracker.LootTrackerClient;
|
||||
import okhttp3.OkHttpClient;
|
||||
import org.apache.commons.text.WordUtils;
|
||||
|
||||
@PluginDescriptor(
|
||||
@@ -340,12 +338,6 @@ public class LootTrackerPlugin extends Plugin
|
||||
return list;
|
||||
}
|
||||
|
||||
@Provides
|
||||
LootTrackerClient provideLootTrackerClient(OkHttpClient okHttpClient)
|
||||
{
|
||||
return new LootTrackerClient(okHttpClient);
|
||||
}
|
||||
|
||||
@Provides
|
||||
LootTrackerConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
|
||||
@@ -67,6 +67,7 @@ import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.VarbitChanged;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.chat.ChatClient;
|
||||
import net.runelite.client.chat.ChatColorType;
|
||||
import net.runelite.client.chat.ChatCommandManager;
|
||||
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.PartyService;
|
||||
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.ws.messages.party.PartyChatMessage;
|
||||
|
||||
|
||||
@@ -27,16 +27,32 @@ package net.runelite.client.plugins.roofremoval;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import net.runelite.client.config.ConfigSection;
|
||||
|
||||
@ConfigGroup(RoofRemovalConfig.CONFIG_GROUP)
|
||||
public interface RoofRemovalConfig extends Config
|
||||
{
|
||||
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(
|
||||
keyName = "removePosition",
|
||||
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()
|
||||
{
|
||||
@@ -46,7 +62,8 @@ public interface RoofRemovalConfig extends Config
|
||||
@ConfigItem(
|
||||
keyName = "removeHovered",
|
||||
name = "Hovered tile",
|
||||
description = "Remove roofs above the hovered tile"
|
||||
description = "Remove roofs above the hovered tile",
|
||||
section = modesSection
|
||||
)
|
||||
default boolean removeHovered()
|
||||
{
|
||||
@@ -56,7 +73,8 @@ public interface RoofRemovalConfig extends Config
|
||||
@ConfigItem(
|
||||
keyName = "removeDestination",
|
||||
name = "Destination tile",
|
||||
description = "Remove roofs above the destination tile"
|
||||
description = "Remove roofs above the destination tile",
|
||||
section = modesSection
|
||||
)
|
||||
default boolean removeDestination()
|
||||
{
|
||||
@@ -66,10 +84,22 @@ public interface RoofRemovalConfig extends Config
|
||||
@ConfigItem(
|
||||
keyName = "removeBetween",
|
||||
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()
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -34,8 +34,10 @@ import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
@@ -86,6 +88,7 @@ public class RoofRemovalPlugin extends Plugin
|
||||
private RoofRemovalConfig config;
|
||||
|
||||
private final Map<Integer, long[]> overrides = new HashMap<>();
|
||||
private final Set<Integer> configOverrideRegions = new HashSet<>();
|
||||
|
||||
@Provides
|
||||
RoofRemovalConfig getConfig(ConfigManager configManager)
|
||||
@@ -96,6 +99,7 @@ public class RoofRemovalPlugin extends Plugin
|
||||
@Override
|
||||
public void startUp() throws IOException
|
||||
{
|
||||
buildConfigOverrides();
|
||||
loadRoofOverrides();
|
||||
clientThread.invoke(() ->
|
||||
{
|
||||
@@ -139,7 +143,21 @@ public class RoofRemovalPlugin extends Plugin
|
||||
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()
|
||||
@@ -164,6 +182,18 @@ public class RoofRemovalPlugin extends Plugin
|
||||
return roofRemovalMode;
|
||||
}
|
||||
|
||||
private void buildConfigOverrides()
|
||||
{
|
||||
configOverrideRegions.clear();
|
||||
for (RoofRemovalConfigOverride configOverride : RoofRemovalConfigOverride.values())
|
||||
{
|
||||
if (configOverride.getEnabled().test(config))
|
||||
{
|
||||
configOverrideRegions.addAll(configOverride.getRegions());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void performRoofRemoval()
|
||||
{
|
||||
assert client.isClientThread();
|
||||
@@ -218,6 +248,11 @@ public class RoofRemovalPlugin extends Plugin
|
||||
outer:
|
||||
for (int regionID : client.getMapRegions())
|
||||
{
|
||||
if (configOverrideRegions.contains(regionID))
|
||||
{
|
||||
regionsHaveOverrides = true;
|
||||
break;
|
||||
}
|
||||
for (int z = 0; z < Constants.MAX_Z; z++)
|
||||
{
|
||||
if (overrides.containsKey(regionID << 2 | z))
|
||||
@@ -250,19 +285,21 @@ public class RoofRemovalPlugin extends Plugin
|
||||
// Properly account for instances shifting worldpoints around
|
||||
final WorldPoint wp = WorldPoint.fromLocalInstance(client, tile.getLocalLocation(), tile.getPlane());
|
||||
|
||||
int regionID = wp.getRegionID() << 2 | z;
|
||||
if (!overrides.containsKey(regionID))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int rx = wp.getRegionX();
|
||||
int ry = wp.getRegionY();
|
||||
long[] region = overrides.get(regionID);
|
||||
if ((region[ry] & (1L << rx)) != 0)
|
||||
int regionAndPlane = wp.getRegionID() << 2 | wp.getPlane();
|
||||
if (configOverrideRegions.contains(wp.getRegionID()))
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.chat.ChatClient;
|
||||
import net.runelite.client.chat.ChatColorType;
|
||||
import net.runelite.client.chat.ChatCommandManager;
|
||||
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.util.ColorUtil;
|
||||
import net.runelite.client.util.Text;
|
||||
import net.runelite.http.api.chat.ChatClient;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
@PluginDescriptor(
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.xptracker;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
@Slf4j
|
||||
public class XpClient
|
||||
{
|
||||
private final OkHttpClient client;
|
||||
private final HttpUrl apiBase;
|
||||
|
||||
@Inject
|
||||
private XpClient(OkHttpClient client, @Named("runelite.api.base") HttpUrl apiBase)
|
||||
{
|
||||
this.client = client;
|
||||
this.apiBase = apiBase;
|
||||
}
|
||||
|
||||
public void update(String username)
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("xp")
|
||||
.addPathSegment("update")
|
||||
.addQueryParameter("username", username)
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
client.newCall(request).enqueue(new Callback()
|
||||
{
|
||||
@Override
|
||||
public void onFailure(Call call, IOException e)
|
||||
{
|
||||
log.warn("Error submitting xp track", e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Call call, Response response)
|
||||
{
|
||||
response.close();
|
||||
log.debug("Submitted xp track for {}", username);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.xp;
|
||||
|
||||
import java.time.Instant;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(exclude = "time")
|
||||
public class XpData
|
||||
{
|
||||
private Instant time;
|
||||
|
||||
private int attack_xp;
|
||||
private int defence_xp;
|
||||
private int strength_xp;
|
||||
private int hitpoints_xp;
|
||||
private int ranged_xp;
|
||||
private int prayer_xp;
|
||||
private int magic_xp;
|
||||
private int cooking_xp;
|
||||
private int woodcutting_xp;
|
||||
private int fletching_xp;
|
||||
private int fishing_xp;
|
||||
private int firemaking_xp;
|
||||
private int crafting_xp;
|
||||
private int smithing_xp;
|
||||
private int mining_xp;
|
||||
private int herblore_xp;
|
||||
private int agility_xp;
|
||||
private int thieving_xp;
|
||||
private int slayer_xp;
|
||||
private int farming_xp;
|
||||
private int runecraft_xp;
|
||||
private int hunter_xp;
|
||||
private int construction_xp;
|
||||
|
||||
private int overall_rank;
|
||||
private int attack_rank;
|
||||
private int defence_rank;
|
||||
private int strength_rank;
|
||||
private int hitpoints_rank;
|
||||
private int ranged_rank;
|
||||
private int prayer_rank;
|
||||
private int magic_rank;
|
||||
private int cooking_rank;
|
||||
private int woodcutting_rank;
|
||||
private int fletching_rank;
|
||||
private int fishing_rank;
|
||||
private int firemaking_rank;
|
||||
private int crafting_rank;
|
||||
private int smithing_rank;
|
||||
private int mining_rank;
|
||||
private int herblore_rank;
|
||||
private int agility_rank;
|
||||
private int thieving_rank;
|
||||
private int slayer_rank;
|
||||
private int farming_rank;
|
||||
private int runecraft_rank;
|
||||
private int hunter_rank;
|
||||
private int construction_rank;
|
||||
}
|
||||
@@ -69,8 +69,6 @@ import net.runelite.client.ui.NavigationButton;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
import net.runelite.client.util.Text;
|
||||
import net.runelite.http.api.xp.XpClient;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "XP Tracker",
|
||||
@@ -139,12 +137,6 @@ public class XpTrackerPlugin extends Plugin
|
||||
return configManager.getConfig(XpTrackerConfig.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
XpClient provideXpClient(OkHttpClient okHttpClient)
|
||||
{
|
||||
return new XpClient(okHttpClient);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(Binder binder)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.xtea;
|
||||
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import static net.runelite.http.api.RuneLiteAPI.JSON;
|
||||
import net.runelite.http.api.xtea.XteaKey;
|
||||
import net.runelite.http.api.xtea.XteaRequest;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class XteaClient
|
||||
{
|
||||
private final OkHttpClient client;
|
||||
private final HttpUrl apiBase;
|
||||
|
||||
@Inject
|
||||
private XteaClient(OkHttpClient client, @Named("runelite.api.base") HttpUrl apiBase)
|
||||
{
|
||||
this.client = client;
|
||||
this.apiBase = apiBase;
|
||||
}
|
||||
|
||||
public void submit(XteaRequest xteaRequest)
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("xtea")
|
||||
.build();
|
||||
|
||||
log.debug("Built URI: {}", url);
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.post(RequestBody.create(JSON, RuneLiteAPI.GSON.toJson(xteaRequest)))
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
client.newCall(request).enqueue(new Callback()
|
||||
{
|
||||
@Override
|
||||
public void onFailure(Call call, IOException e)
|
||||
{
|
||||
log.warn("unable to submit xtea keys", e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Call call, Response response)
|
||||
{
|
||||
try // NOPMD: UseTryWithResources
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
log.debug("unsuccessful xtea response");
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
response.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public List<XteaKey> get() throws IOException
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("xtea")
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
InputStream in = response.body().byteStream();
|
||||
// CHECKSTYLE:OFF
|
||||
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), new TypeToken<List<XteaKey>>() { }.getType());
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
catch (JsonParseException ex)
|
||||
{
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public XteaKey get(int region) throws IOException
|
||||
{
|
||||
HttpUrl url = apiBase.newBuilder()
|
||||
.addPathSegment("xtea")
|
||||
.addPathSegment(Integer.toString(region))
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute())
|
||||
{
|
||||
InputStream in = response.body().byteStream();
|
||||
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), XteaKey.class);
|
||||
}
|
||||
catch (JsonParseException ex)
|
||||
{
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,6 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.xtea;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
@@ -35,10 +34,8 @@ import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.http.api.xtea.XteaClient;
|
||||
import net.runelite.http.api.xtea.XteaKey;
|
||||
import net.runelite.http.api.xtea.XteaRequest;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Xtea",
|
||||
@@ -55,12 +52,6 @@ public class XteaPlugin extends Plugin
|
||||
@Inject
|
||||
private XteaClient xteaClient;
|
||||
|
||||
@Provides
|
||||
XteaClient provideXteaClient(OkHttpClient okHttpClient)
|
||||
{
|
||||
return new XteaClient(okHttpClient);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged gameStateChanged)
|
||||
{
|
||||
|
||||
@@ -35,9 +35,11 @@ import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.RuneLiteProperties;
|
||||
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 okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
@Slf4j
|
||||
@@ -46,7 +48,7 @@ class WorldSupplier implements Supplier<World>
|
||||
{
|
||||
private final OkHttpClient okHttpClient;
|
||||
private final Random random = new Random(System.nanoTime());
|
||||
private Queue<World> worlds = new ArrayDeque<>();
|
||||
private final Queue<World> worlds = new ArrayDeque<>();
|
||||
|
||||
@Override
|
||||
public World get()
|
||||
@@ -58,7 +60,7 @@ class WorldSupplier implements Supplier<World>
|
||||
|
||||
try
|
||||
{
|
||||
List<World> newWorlds = new WorldClient(okHttpClient)
|
||||
List<World> newWorlds = new WorldClient(okHttpClient, HttpUrl.get(RuneLiteProperties.getApiBase()))
|
||||
.lookupWorlds()
|
||||
.getWorlds()
|
||||
.stream()
|
||||
|
||||
@@ -336,6 +336,12 @@ public class ClientUI
|
||||
frame.setResizable(true);
|
||||
|
||||
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()
|
||||
{
|
||||
@Override
|
||||
@@ -550,7 +556,11 @@ public class ClientUI
|
||||
|
||||
// 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.
|
||||
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.getX() / scale,
|
||||
|
||||
@@ -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.
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,6 @@ import java.awt.Font;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.swing.ImageIcon;
|
||||
@@ -67,7 +66,7 @@ public class SplashScreen extends JFrame implements ActionListener
|
||||
private volatile String subActionText = "";
|
||||
private volatile String progressText = null;
|
||||
|
||||
private SplashScreen() throws IOException
|
||||
private SplashScreen()
|
||||
{
|
||||
BufferedImage logo = ImageUtil.loadImageResource(SplashScreen.class, "openosrs_transparent.png");
|
||||
|
||||
@@ -205,6 +204,12 @@ public class SplashScreen extends JFrame implements ActionListener
|
||||
}
|
||||
|
||||
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 = null;
|
||||
});
|
||||
|
||||
@@ -31,15 +31,17 @@ import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.RuneLite;
|
||||
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.WebsocketMessage;
|
||||
import net.runelite.http.api.ws.messages.Handshake;
|
||||
import net.runelite.http.api.ws.messages.party.PartyMessage;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
@@ -52,6 +54,7 @@ public class WSClient extends WebSocketListener implements AutoCloseable
|
||||
{
|
||||
private final EventBus eventBus;
|
||||
private final OkHttpClient okHttpClient;
|
||||
private final HttpUrl runeliteWs;
|
||||
private final Collection<Class<? extends WebsocketMessage>> messages = new HashSet<>();
|
||||
|
||||
private volatile Gson gson;
|
||||
@@ -60,10 +63,11 @@ public class WSClient extends WebSocketListener implements AutoCloseable
|
||||
private WebSocket webSocket;
|
||||
|
||||
@Inject
|
||||
private WSClient(EventBus eventBus, OkHttpClient okHttpClient)
|
||||
private WSClient(EventBus eventBus, OkHttpClient okHttpClient, @Named("runelite.ws") HttpUrl runeliteWs)
|
||||
{
|
||||
this.eventBus = eventBus;
|
||||
this.okHttpClient = okHttpClient;
|
||||
this.runeliteWs = runeliteWs;
|
||||
this.gson = WebsocketGsonFactory.build(WebsocketGsonFactory.factory(messages));
|
||||
}
|
||||
|
||||
@@ -101,8 +105,8 @@ public class WSClient extends WebSocketListener implements AutoCloseable
|
||||
}
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(RuneLiteAPI.getWsEndpoint())
|
||||
.header("User-Agent", RuneLiteAPI.userAgent)
|
||||
.url(runeliteWs)
|
||||
.header("User-Agent", RuneLite.USER_AGENT)
|
||||
.build();
|
||||
|
||||
webSocket = okHttpClient.newWebSocket(request, this);
|
||||
|
||||
Reference in New Issue
Block a user