From 51e951e4dc9229e963d00d048e766160fd77ccbb Mon Sep 17 00:00:00 2001 From: dekvall Date: Wed, 13 Nov 2019 23:07:12 +0100 Subject: [PATCH 01/22] attack styles: add test for swap between bludgeon and bow When swapping between bludgeon and bow, onWidgetHiddenChanged is called before the weapon varbit is set. Since that varbit determines which widgets should be hidden we would like to make sure the widget is set to hidden even after a varbit change. --- .../attackstyles/AttackStylesPluginTest.java | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/attackstyles/AttackStylesPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/attackstyles/AttackStylesPluginTest.java index 6a6a55a1c0..3b900c283d 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/attackstyles/AttackStylesPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/attackstyles/AttackStylesPluginTest.java @@ -33,6 +33,7 @@ import net.runelite.api.Client; import net.runelite.api.Skill; import net.runelite.api.VarPlayer; import net.runelite.api.Varbits; +import net.runelite.api.events.WidgetHiddenChanged; import net.runelite.client.events.ConfigChanged; import net.runelite.api.events.VarbitChanged; import net.runelite.api.widgets.Widget; @@ -43,8 +44,11 @@ import static org.junit.Assert.assertTrue; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.Mock; +import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.mockito.junit.MockitoJUnitRunner; @@ -169,6 +173,60 @@ public class AttackStylesPluginTest WidgetInfo.COMBAT_STYLE_THREE)); } + /* + * Verify that the defensive style is hidden when switching from bludgeon to bow + */ + @Test + public void testHiddenLongrange() + { + final ArgumentCaptor captor = ArgumentCaptor.forClass(Boolean.class); + final ConfigChanged warnForAttackEvent = new ConfigChanged(); + warnForAttackEvent.setGroup("attackIndicator"); + warnForAttackEvent.setKey("warnForDefensive"); + warnForAttackEvent.setNewValue("true"); + attackPlugin.onConfigChanged(warnForAttackEvent); + + // verify there is a warned skill + Set warnedSkills = attackPlugin.getWarnedSkills(); + assertTrue(warnedSkills.contains(Skill.DEFENCE)); + + // Set up mock widget for strength and longrange + final Widget widget = mock(Widget.class); + when(client.getWidget(WidgetInfo.COMBAT_STYLE_FOUR)).thenReturn(widget); + + // Set up hidden changed event + final WidgetHiddenChanged widgetHiddenChanged = new WidgetHiddenChanged(); + widgetHiddenChanged.setWidget(widget); + when(widget.getId()).thenReturn(WidgetInfo.COMBAT_STYLE_FOUR.getPackedId()); + + // Enable hiding widgets + final ConfigChanged hideWidgetEvent = new ConfigChanged(); + hideWidgetEvent.setGroup("attackIndicator"); + hideWidgetEvent.setKey("removeWarnedStyles"); + hideWidgetEvent.setNewValue("true"); + attackPlugin.onConfigChanged(hideWidgetEvent); + when(attackConfig.removeWarnedStyles()).thenReturn(true); + + // equip bludgeon on player + when(client.getVar(Varbits.EQUIPPED_WEAPON_TYPE)).thenReturn(WeaponType.TYPE_26.ordinal()); + attackPlugin.onVarbitChanged(new VarbitChanged()); + attackPlugin.onWidgetHiddenChanged(widgetHiddenChanged); + + // verify that the agressive style style widget is showing + verify(widget, atLeastOnce()).setHidden(captor.capture()); + assertFalse(captor.getValue()); + + // equip bow on player + // the equipped weaopn varbit will change after the hiddenChanged event has been dispatched + attackPlugin.onWidgetHiddenChanged(widgetHiddenChanged); + when(client.getVar(Varbits.EQUIPPED_WEAPON_TYPE)).thenReturn(WeaponType.TYPE_3.ordinal()); + attackPlugin.onVarbitChanged(new VarbitChanged()); + + // verify that the longrange attack style widget is now hidden + verify(widget, atLeastOnce()).setHidden(captor.capture()); + assertTrue(captor.getValue()); + } + private boolean isAtkHidden() { if (attackPlugin.getHiddenWidgets().size() == 0) From 11e175324080b2c54de6531b096a2f79a30625ba Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 14 Nov 2019 10:19:27 -0500 Subject: [PATCH 02/22] raid plugin: fix layout command room order --- .../runelite/client/plugins/raids/Raid.java | 21 ++++++++++++++++--- .../client/plugins/raids/RaidsPlugin.java | 7 ++++--- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/Raid.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/Raid.java index 87181b4085..574dcebb2a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/Raid.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/Raid.java @@ -136,10 +136,13 @@ public class Raid return builder.toString(); } - public String toRoomString() + /** + * Get the raid rooms in the order they are in the raid + * @return + */ + List getOrderedRooms() { - final StringBuilder sb = new StringBuilder(); - + List orderedRooms = new ArrayList<>(); for (Room r : getLayout().getRooms()) { final int position = r.getPosition(); @@ -150,6 +153,18 @@ public class Raid continue; } + orderedRooms.add(room); + } + + return orderedRooms; + } + + String toRoomString() + { + final StringBuilder sb = new StringBuilder(); + + for (RaidRoom room : getOrderedRooms()) + { switch (room.getType()) { case PUZZLE: diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java index f25ba51534..f96f9c0a9d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java @@ -32,6 +32,7 @@ import java.text.DecimalFormat; import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.concurrent.ScheduledExecutorService; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -53,7 +54,6 @@ import net.runelite.api.Tile; import net.runelite.api.VarPlayer; import net.runelite.api.Varbits; import net.runelite.api.events.ChatMessage; -import net.runelite.client.events.ConfigChanged; import net.runelite.api.events.VarbitChanged; import net.runelite.client.callback.ClientThread; import net.runelite.client.chat.ChatColorType; @@ -64,6 +64,7 @@ import net.runelite.client.chat.QueuedMessage; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ChatInput; +import net.runelite.client.events.ConfigChanged; import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.game.SpriteManager; import net.runelite.client.plugins.Plugin; @@ -665,9 +666,9 @@ public class RaidsPlugin extends Plugin } final String playerName = client.getLocalPlayer().getName(); - RaidRoom[] rooms = raid.getRooms(); + List orderedRooms = raid.getOrderedRooms(); - LayoutRoom[] layoutRooms = Arrays.stream(rooms) + LayoutRoom[] layoutRooms = orderedRooms.stream() .map(room -> LayoutRoom.valueOf(room.name())) .toArray(LayoutRoom[]::new); From a60d0f1a217c84fad98d61f270231103d4a62ff5 Mon Sep 17 00:00:00 2001 From: Max Weber Date: Mon, 11 Nov 2019 05:03:03 -0700 Subject: [PATCH 03/22] runelite-client: Use archive-patcher for the client-patch archive-patcher is faster and produces a smaller patch than the previous bsdiff solution. this also introduces vanilla and patched client caching, which significantly boosts startup time. --- runelite-client/pom.xml | 10 +- .../java/net/runelite/client/RuneLite.java | 1 + .../net/runelite/client/RuneLiteModule.java | 2 +- .../net/runelite/client/rs/ClientLoader.java | 552 +++++++++++------- .../client/rs/CountingInputStream.java | 81 +++ .../runelite/client/rs/TeeInputStream.java | 95 +++ 6 files changed, 505 insertions(+), 236 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/rs/CountingInputStream.java create mode 100644 runelite-client/src/main/java/net/runelite/client/rs/TeeInputStream.java diff --git a/runelite-client/pom.xml b/runelite-client/pom.xml index 557e5b84d4..8858fe86e1 100644 --- a/runelite-client/pom.xml +++ b/runelite-client/pom.xml @@ -158,15 +158,9 @@ runtime - io.sigpipe - jbsdiff + net.runelite + archive-patcher 1.0 - - - org.tukaani - xz - - diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index 61e155b3e6..f70ba2dd63 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -79,6 +79,7 @@ import org.slf4j.LoggerFactory; public class RuneLite { public static final File RUNELITE_DIR = new File(System.getProperty("user.home"), ".runelite"); + public static final File CACHE_DIR = new File(RUNELITE_DIR, "cache"); public static final File PROFILES_DIR = new File(RUNELITE_DIR, "profiles"); public static final File SCREENSHOT_DIR = new File(RUNELITE_DIR, "screenshots"); public static final File LOGS_DIR = new File(RUNELITE_DIR, "logs"); diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLiteModule.java b/runelite-client/src/main/java/net/runelite/client/RuneLiteModule.java index 5d9bbf1531..56076b3368 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLiteModule.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLiteModule.java @@ -74,7 +74,7 @@ public class RuneLiteModule extends AbstractModule bindConstant().annotatedWith(Names.named("developerMode")).to(developerMode); bind(ScheduledExecutorService.class).toInstance(new ExecutorServiceExceptionLogger(Executors.newSingleThreadScheduledExecutor())); bind(OkHttpClient.class).toInstance(RuneLiteAPI.CLIENT.newBuilder() - .cache(new Cache(new File(RuneLite.RUNELITE_DIR, "cache" + File.separator + "okhttp"), MAX_OKHTTP_CACHE_SIZE)) + .cache(new Cache(new File(RuneLite.CACHE_DIR, "okhttp"), MAX_OKHTTP_CACHE_SIZE)) .build()); bind(MenuManager.class); bind(ChatMessageManager.class); diff --git a/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java b/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java index dbd2c0c95e..6a9015d370 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java @@ -1,7 +1,7 @@ /* * Copyright (c) 2016-2017, Adam * Copyright (c) 2018, Tomas Slusny - * Copyright (c) 2018 Abex + * Copyright (c) 2019 Abex * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,32 +26,37 @@ */ package net.runelite.client.rs; +import com.google.archivepatcher.applier.FileByFileV1DeltaApplier; import com.google.common.base.Strings; import com.google.common.hash.Hashing; -import com.google.common.io.ByteStreams; -import com.google.common.reflect.TypeToken; -import com.google.gson.Gson; -import io.sigpipe.jbsdiff.InvalidHeaderException; -import io.sigpipe.jbsdiff.Patch; +import com.google.common.hash.HashingOutputStream; +import com.google.common.io.Files; import java.applet.Applet; import java.io.ByteArrayOutputStream; -import java.io.FilterInputStream; +import java.io.DataInputStream; +import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.channels.Channels; +import java.nio.channels.FileChannel; +import java.nio.channels.FileLock; +import java.nio.file.StandardOpenOption; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.util.Arrays; import java.util.Collection; -import java.util.HashMap; -import java.util.Map; import java.util.function.Supplier; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; import javax.swing.SwingUtilities; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; +import net.runelite.client.RuneLite; import static net.runelite.client.rs.ClientUpdateCheckMode.AUTO; import static net.runelite.client.rs.ClientUpdateCheckMode.NONE; import static net.runelite.client.rs.ClientUpdateCheckMode.VANILLA; @@ -61,16 +66,22 @@ import net.runelite.http.api.RuneLiteAPI; import okhttp3.HttpUrl; import okhttp3.Request; import okhttp3.Response; -import org.apache.commons.compress.compressors.CompressorException; @Slf4j +@SuppressWarnings("deprecation") public class ClientLoader implements Supplier { private static final int NUM_ATTEMPTS = 6; + private static File LOCK_FILE = new File(RuneLite.CACHE_DIR, "cache.lock"); + private static File VANILLA_CACHE = new File(RuneLite.CACHE_DIR, "vanilla.cache"); + private static File PATCHED_CACHE = new File(RuneLite.CACHE_DIR, "patched.cache"); private ClientUpdateCheckMode updateCheckMode; private Object client = null; + private HostSupplier hostSupplier = new HostSupplier(); + private RSConfig config; + public ClientLoader(ClientUpdateCheckMode updateCheckMode) { this.updateCheckMode = updateCheckMode; @@ -101,234 +112,38 @@ public class ClientLoader implements Supplier try { SplashScreen.stage(0, null, "Fetching applet viewer config"); + downloadConfig(); - HostSupplier hostSupplier = new HostSupplier(); + SplashScreen.stage(.05, null, "Waiting for other clients to start"); - String host = null; - RSConfig config; - for (int attempt = 0; ; attempt++) + LOCK_FILE.getParentFile().mkdirs(); + try (FileChannel lockfile = FileChannel.open(LOCK_FILE.toPath(), + StandardOpenOption.CREATE, StandardOpenOption.READ, StandardOpenOption.WRITE); + FileLock flock = lockfile.lock()) { - try + SplashScreen.stage(.05, null, "Downloading Old School RuneScape"); + updateVanilla(); + + if (updateCheckMode == AUTO) { - config = ClientConfigLoader.fetch(host); - - if (Strings.isNullOrEmpty(config.getCodeBase()) || Strings.isNullOrEmpty(config.getInitialJar()) || Strings.isNullOrEmpty(config.getInitialClass())) - { - throw new IOException("Invalid or missing jav_config"); - } - - break; - } - catch (IOException e) - { - log.info("Failed to get jav_config from host \"{}\" ({})", host, e.getMessage()); - - if (attempt >= NUM_ATTEMPTS) - { - throw e; - } - - host = hostSupplier.get(); + SplashScreen.stage(.35, null, "Patching"); + applyPatch(); } } - Map zipFile = new HashMap<>(); - { - Certificate[] jagexCertificateChain = getJagexCertificateChain(); - String codebase = config.getCodeBase(); - String initialJar = config.getInitialJar(); - HttpUrl url = HttpUrl.parse(codebase + initialJar); - - for (int attempt = 0; ; attempt++) - { - zipFile.clear(); - - Request request = new Request.Builder() - .url(url) - .build(); - - try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) - { - int length = (int) response.body().contentLength(); - if (length < 0) - { - length = 3 * 1024 * 1024; - } - final int flength = length; - InputStream istream = new FilterInputStream(response.body().byteStream()) - { - private int read = 0; - - @Override - public int read(byte[] b, int off, int len) throws IOException - { - int thisRead = super.read(b, off, len); - this.read += thisRead; - SplashScreen.stage(.05, .35, null, "Downloading Old School RuneScape", this.read, flength, true); - return thisRead; - } - }; - JarInputStream jis = new JarInputStream(istream); - - byte[] tmp = new byte[4096]; - ByteArrayOutputStream buffer = new ByteArrayOutputStream(756 * 1024); - for (; ; ) - { - JarEntry metadata = jis.getNextJarEntry(); - if (metadata == null) - { - break; - } - - buffer.reset(); - for (; ; ) - { - int n = jis.read(tmp); - if (n <= -1) - { - break; - } - buffer.write(tmp, 0, n); - } - - if (!Arrays.equals(metadata.getCertificates(), jagexCertificateChain)) - { - if (metadata.getName().startsWith("META-INF/")) - { - // META-INF/JAGEXLTD.SF and META-INF/JAGEXLTD.RSA are not signed, but we don't need - // anything in META-INF anyway. - continue; - } - else - { - throw new VerificationException("Unable to verify jar entry: " + metadata.getName()); - } - } - - zipFile.put(metadata.getName(), buffer.toByteArray()); - } - break; - } - catch (IOException e) - { - log.info("Failed to download gamepack from \"{}\" ({})", url, e.getMessage()); - - if (attempt >= NUM_ATTEMPTS) - { - throw e; - } - - url = url.newBuilder().host(hostSupplier.get()).build(); - } - } - } - - if (updateCheckMode == AUTO) - { - SplashScreen.stage(.35, null, "Patching"); - Map hashes; - try (InputStream is = ClientLoader.class.getResourceAsStream("/patch/hashes.json")) - { - if (is == null) - { - SwingUtilities.invokeLater(() -> - new FatalErrorDialog("The client-patch is missing from the classpath. If you are building " + - "the client you need to re-run maven") - .addBuildingGuide() - .open()); - throw new NullPointerException(); - } - hashes = new Gson().fromJson(new InputStreamReader(is), new TypeToken>() - { - }.getType()); - } - - for (Map.Entry file : hashes.entrySet()) - { - byte[] bytes = zipFile.get(file.getKey()); - - String ourHash = null; - if (bytes != null) - { - ourHash = Hashing.sha512().hashBytes(bytes).toString(); - } - - if (!file.getValue().equals(ourHash)) - { - log.debug("{} had a hash mismatch; falling back to vanilla. {} != {}", file.getKey(), file.getValue(), ourHash); - log.info("Client is outdated!"); - updateCheckMode = VANILLA; - break; - } - } - } - - if (updateCheckMode == AUTO) - { - ByteArrayOutputStream patchOs = new ByteArrayOutputStream(756 * 1024); - int patchCount = 0; - - for (Map.Entry file : zipFile.entrySet()) - { - byte[] bytes; - try (InputStream is = ClientLoader.class.getResourceAsStream("/patch/" + file.getKey() + ".bs")) - { - if (is == null) - { - continue; - } - - bytes = ByteStreams.toByteArray(is); - } - - patchOs.reset(); - Patch.patch(file.getValue(), bytes, patchOs); - file.setValue(patchOs.toByteArray()); - - ++patchCount; - SplashScreen.stage(.38, .45, null, "Patching", patchCount, zipFile.size(), false); - } - - log.debug("Patched {} classes", patchCount); - } + File jarFile = updateCheckMode == AUTO ? PATCHED_CACHE : VANILLA_CACHE; + URL jar = jarFile.toURI().toURL(); SplashScreen.stage(.465, "Starting", "Starting Old School RuneScape"); - String initialClass = config.getInitialClass(); - - ClassLoader rsClassLoader = new ClassLoader(ClientLoader.class.getClassLoader()) - { - @Override - protected Class findClass(String name) throws ClassNotFoundException - { - String path = name.replace('.', '/').concat(".class"); - byte[] data = zipFile.get(path); - if (data == null) - { - throw new ClassNotFoundException(name); - } - - return defineClass(name, data, 0, data.length); - } - }; - - Class clientClass = rsClassLoader.loadClass(initialClass); - - Applet rs = (Applet) clientClass.newInstance(); - rs.setStub(new RSAppletStub(config)); - - if (rs instanceof Client) - { - log.info("client-patch {}", ((Client) rs).getBuildID()); - } + Applet rs = loadClient(jar); SplashScreen.stage(.5, null, "Starting core classes"); return rs; } catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException - | CompressorException | InvalidHeaderException | CertificateException | VerificationException - | SecurityException e) + | VerificationException | SecurityException e) { log.error("Error loading RS!", e); @@ -337,10 +152,293 @@ public class ClientLoader implements Supplier } } - private static Certificate[] getJagexCertificateChain() throws CertificateException + private void downloadConfig() throws IOException { - CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); - Collection certificates = certificateFactory.generateCertificates(ClientLoader.class.getResourceAsStream("jagex.crt")); - return certificates.toArray(new Certificate[certificates.size()]); + String host = null; + for (int attempt = 0; ; attempt++) + { + try + { + config = ClientConfigLoader.fetch(host); + + if (Strings.isNullOrEmpty(config.getCodeBase()) || Strings.isNullOrEmpty(config.getInitialJar()) || Strings.isNullOrEmpty(config.getInitialClass())) + { + throw new IOException("Invalid or missing jav_config"); + } + + break; + } + catch (IOException e) + { + log.info("Failed to get jav_config from host \"{}\" ({})", host, e.getMessage()); + + if (attempt >= NUM_ATTEMPTS) + { + throw e; + } + + host = hostSupplier.get(); + } + } + } + + private void updateVanilla() throws IOException, VerificationException + { + Certificate[] jagexCertificateChain = getJagexCertificateChain(); + + // Get the mtime of the first thing in the vanilla cache + // we check this against what the server gives us to let us skip downloading and patching the whole thing + + try (FileChannel vanilla = FileChannel.open(VANILLA_CACHE.toPath(), + StandardOpenOption.CREATE, StandardOpenOption.READ, StandardOpenOption.WRITE)) + { + long vanillaCacheMTime = -1; + boolean vanillaCacheIsInvalid = false; + try + { + JarInputStream vanillaCacheTest = new JarInputStream(Channels.newInputStream(vanilla)); + vanillaCacheTest.skip(Long.MAX_VALUE); + JarEntry je = vanillaCacheTest.getNextJarEntry(); + if (je != null) + { + verifyJarEntry(je, jagexCertificateChain); + vanillaCacheMTime = je.getLastModifiedTime().toMillis(); + } + else + { + vanillaCacheIsInvalid = true; + } + } + catch (Exception e) + { + log.info("Failed to read the vanilla cache: {}", e.toString()); + vanillaCacheIsInvalid = true; + } + vanilla.position(0); + + // Start downloading the vanilla client + + String codebase = config.getCodeBase(); + String initialJar = config.getInitialJar(); + HttpUrl url = HttpUrl.parse(codebase + initialJar); + + for (int attempt = 0; ; attempt++) + { + Request request = new Request.Builder() + .url(url) + .build(); + + try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) + { + // Its important to not close the response manually - this should be the only close or + // try-with-resources on this stream or it's children + + int length = (int) response.body().contentLength(); + if (length < 0) + { + length = 3 * 1024 * 1024; + } + else + { + if (!vanillaCacheIsInvalid && vanilla.size() != length) + { + // The zip trailer filetab can be missing and the ZipInputStream will not notice + log.info("Vanilla cache is the wrong size"); + vanillaCacheIsInvalid = true; + } + } + final int flength = length; + TeeInputStream copyStream = new TeeInputStream(new CountingInputStream(response.body().byteStream(), + read -> SplashScreen.stage(.05, .35, null, "Downloading Old School RuneScape", read, flength, true))); + + // Save the bytes from the mtime test so we can write it to disk + // if the test fails, or the cache doesn't verify + ByteArrayOutputStream preRead = new ByteArrayOutputStream(); + copyStream.setOut(preRead); + + JarInputStream networkJIS = new JarInputStream(copyStream); + + // Get the mtime from the first entry so check it against the cache + { + JarEntry je = networkJIS.getNextJarEntry(); + networkJIS.skip(Long.MAX_VALUE); + verifyJarEntry(je, jagexCertificateChain); + long vanillaClientMTime = je.getLastModifiedTime().toMillis(); + if (!vanillaCacheIsInvalid && vanillaClientMTime != vanillaCacheMTime) + { + log.info("Vanilla cache is out of date: {} != {}", vanillaClientMTime, vanillaCacheMTime); + vanillaCacheIsInvalid = true; + } + } + + // the mtime matches so the cache is probably up to date, but just make sure its fully + // intact before closing the server connection + if (!vanillaCacheIsInvalid) + { + try + { + // as with the request stream, its important to not early close vanilla too + JarInputStream vanillaCacheTest = new JarInputStream(Channels.newInputStream(vanilla)); + verifyWholeJar(vanillaCacheTest, jagexCertificateChain); + } + catch (Exception e) + { + log.warn("Failed to verify the vanilla cache", e); + vanillaCacheIsInvalid = true; + } + } + + if (vanillaCacheIsInvalid) + { + // the cache is not up to date, commit our peek to the file and write the rest of it, while verifying + vanilla.position(0); + OutputStream out = Channels.newOutputStream(vanilla); + out.write(preRead.toByteArray()); + copyStream.setOut(out); + verifyWholeJar(networkJIS, jagexCertificateChain); + copyStream.skip(Long.MAX_VALUE); // write the trailer to the file too + out.flush(); + vanilla.truncate(vanilla.position()); + } + else + { + log.info("Using cached vanilla client"); + } + return; + } + catch (IOException e) + { + log.warn("Failed to download gamepack from \"{}\"", url, e); + + if (attempt >= NUM_ATTEMPTS) + { + throw e; + } + + url = url.newBuilder().host(hostSupplier.get()).build(); + } + } + } + } + + private void applyPatch() throws IOException + { + byte[] vanillaHash = new byte[64]; + byte[] appliedPatchHash = new byte[64]; + + try (InputStream is = ClientLoader.class.getResourceAsStream("/client.serial")) + { + if (is == null) + { + SwingUtilities.invokeLater(() -> + new FatalErrorDialog("The client-patch is missing from the classpath. If you are building " + + "the client you need to re-run maven") + .addBuildingGuide() + .open()); + throw new NullPointerException(); + } + + DataInputStream dis = new DataInputStream(is); + dis.readFully(vanillaHash); + dis.readFully(appliedPatchHash); + } + + byte[] vanillaCacheHash = Files.asByteSource(VANILLA_CACHE).hash(Hashing.sha512()).asBytes(); + if (!Arrays.equals(vanillaHash, vanillaCacheHash)) + { + log.info("Client is outdated!"); + updateCheckMode = VANILLA; + return; + } + + if (PATCHED_CACHE.exists()) + { + byte[] diskBytes = Files.asByteSource(PATCHED_CACHE).hash(Hashing.sha512()).asBytes(); + if (!Arrays.equals(diskBytes, appliedPatchHash)) + { + log.warn("Cached patch hash mismatches, regenerating patch"); + } + else + { + log.info("Using cached patched client"); + return; + } + } + + try (HashingOutputStream hos = new HashingOutputStream(Hashing.sha512(), new FileOutputStream(PATCHED_CACHE)); + InputStream patch = ClientLoader.class.getResourceAsStream("/client.patch")) + { + new FileByFileV1DeltaApplier().applyDelta(VANILLA_CACHE, patch, hos); + + if (!Arrays.equals(hos.hash().asBytes(), appliedPatchHash)) + { + log.error("Patched client hash mismatch"); + updateCheckMode = VANILLA; + return; + } + } + catch (IOException e) + { + log.error("Unable to apply patch despite hash matching", e); + updateCheckMode = VANILLA; + return; + } + } + + private Applet loadClient(URL url) throws ClassNotFoundException, IllegalAccessException, InstantiationException + { + URLClassLoader rsClassLoader = new URLClassLoader(new URL[]{url}); + + String initialClass = config.getInitialClass(); + Class clientClass = rsClassLoader.loadClass(initialClass); + + Applet rs = (Applet) clientClass.newInstance(); + rs.setStub(new RSAppletStub(config)); + + if (rs instanceof Client) + { + log.info("client-patch {}", ((Client) rs).getBuildID()); + } + + return rs; + } + + private static Certificate[] getJagexCertificateChain() + { + try + { + CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); + Collection certificates = certificateFactory.generateCertificates(ClientLoader.class.getResourceAsStream("jagex.crt")); + return certificates.toArray(new Certificate[0]); + } + catch (CertificateException e) + { + throw new RuntimeException("Unable to parse pinned certificates", e); + } + } + + private void verifyJarEntry(JarEntry je, Certificate[] certs) throws VerificationException + { + switch (je.getName()) + { + case "META-INF/JAGEXLTD.SF": + case "META-INF/JAGEXLTD.RSA": + // You can't sign the signing files + return; + default: + if (!Arrays.equals(je.getCertificates(), certs)) + { + throw new VerificationException("Unable to verify jar entry: " + je.getName()); + } + } + } + + private void verifyWholeJar(JarInputStream jis, Certificate[] certs) throws IOException, VerificationException + { + for (JarEntry je; (je = jis.getNextJarEntry()) != null; ) + { + jis.skip(Long.MAX_VALUE); + verifyJarEntry(je, certs); + } } } diff --git a/runelite-client/src/main/java/net/runelite/client/rs/CountingInputStream.java b/runelite-client/src/main/java/net/runelite/client/rs/CountingInputStream.java new file mode 100644 index 0000000000..5f44362b1a --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/rs/CountingInputStream.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2019 Abex + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.rs; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.function.IntConsumer; + +class CountingInputStream extends FilterInputStream +{ + private final IntConsumer changed; + + CountingInputStream(InputStream in, IntConsumer changed) + { + super(in); + this.changed = changed; + } + + private int read = 0; + + @Override + public int read(byte[] b, int off, int len) throws IOException + { + int thisRead = super.read(b, off, len); + if (thisRead > 0) + { + this.read += thisRead; + } + changed.accept(this.read); + return thisRead; + } + + @Override + public int read() throws IOException + { + int val = super.read(); + if (val != -1) + { + this.read++; + } + return val; + } + + @Override + public long skip(long n) throws IOException + { + long thisRead = in.skip(n); + this.read += thisRead; + changed.accept(this.read); + return thisRead; + } + + @Override + public boolean markSupported() + { + return false; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/rs/TeeInputStream.java b/runelite-client/src/main/java/net/runelite/client/rs/TeeInputStream.java new file mode 100644 index 0000000000..6b9b08910d --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/rs/TeeInputStream.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2019 Abex + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.rs; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import lombok.Getter; +import lombok.Setter; + +class TeeInputStream extends FilterInputStream +{ + @Getter + @Setter + private OutputStream out; + + TeeInputStream(InputStream in) + { + super(in); + } + + @Override + public int read(byte[] b, int off, int len) throws IOException + { + int thisRead = super.read(b, off, len); + + if (thisRead > 0) + { + out.write(b, off, thisRead); + } + + return thisRead; + } + + @Override + public int read() throws IOException + { + int val = super.read(); + if (val != -1) + { + out.write(val); + } + return val; + } + + @Override + public long skip(long n) throws IOException + { + byte[] buf = new byte[(int) Math.min(n, 0x4000)]; + long total = 0; + for (; n > 0; ) + { + int read = (int) Math.min(n, buf.length); + + read = read(buf, 0, read); + if (read == -1) + { + break; + } + + total += read; + n -= read; + } + return total; + } + + @Override + public boolean markSupported() + { + return false; + } +} From f837197823bc4f806ae4b49670918ac89c946dd0 Mon Sep 17 00:00:00 2001 From: winterdaze <35933468+winterdaze@users.noreply.github.com> Date: Fri, 15 Nov 2019 04:33:23 -0500 Subject: [PATCH 04/22] Shorten NMZ overlay text to prevent overlapping (#10241) --- .../client/plugins/nightmarezone/NightmareZoneOverlay.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java index 231d7f82c2..feacb57e4a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java @@ -111,7 +111,7 @@ class NightmareZoneOverlay extends Overlay .right(QuantityFormatter.formatNumber(currentPoints)) .build()); panelComponent.getChildren().add(LineComponent.builder() - .left("Points/Hour: ") + .left("Points/Hr: ") .right(QuantityFormatter.formatNumber(plugin.getPointsPerHour())) .build()); panelComponent.getChildren().add(LineComponent.builder() From 71d2e74732c7a5ffc29d7a0db3de118328640707 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 15 Nov 2019 09:13:11 -0500 Subject: [PATCH 05/22] Remove SEASONAL_DEADMAN world type Co-authored-by: Hydrox6 --- .../http/api/hiscore/HiscoreEndpoint.java | 1 - .../net/runelite/http/api/worlds/WorldType.java | 1 - .../http/service/worlds/ServiceWorldType.java | 3 +-- .../src/main/java/net/runelite/api/WorldType.java | 9 ++------- .../client/plugins/hiscore/HiscorePanel.java | 4 ---- .../plugins/opponentinfo/OpponentInfoPlugin.java | 4 ---- .../plugins/screenshot/ScreenshotPlugin.java | 3 +-- .../client/plugins/timers/TimersPlugin.java | 1 - .../client/plugins/worldhopper/WorldTableRow.java | 3 +-- .../client/plugins/xptracker/XpWorldType.java | 3 --- .../client/plugins/hiscore/seasonal_deadman.png | Bin 311 -> 0 bytes 11 files changed, 5 insertions(+), 27 deletions(-) delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/seasonal_deadman.png diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreEndpoint.java b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreEndpoint.java index a88f2e208e..4b0b39b0f4 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreEndpoint.java +++ b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreEndpoint.java @@ -35,7 +35,6 @@ public enum HiscoreEndpoint HARDCORE_IRONMAN("Hardcore Ironman", "https://services.runescape.com/m=hiscore_oldschool_hardcore_ironman/index_lite.ws"), ULTIMATE_IRONMAN("Ultimate Ironman", "https://services.runescape.com/m=hiscore_oldschool_ultimate/index_lite.ws"), DEADMAN("Deadman", "https://services.runescape.com/m=hiscore_oldschool_deadman/index_lite.ws"), - SEASONAL_DEADMAN("Seasonal Deadman", "https://services.runescape.com/m=hiscore_oldschool_seasonal/index_lite.ws"), DEADMAN_TOURNAMENT("Deadman Tournament", "https://services.runescape.com/m=hiscore_oldschool_tournament/index_lite.ws"); private final String name; diff --git a/http-api/src/main/java/net/runelite/http/api/worlds/WorldType.java b/http-api/src/main/java/net/runelite/http/api/worlds/WorldType.java index c94a7c70e6..5c9af6cc10 100644 --- a/http-api/src/main/java/net/runelite/http/api/worlds/WorldType.java +++ b/http-api/src/main/java/net/runelite/http/api/worlds/WorldType.java @@ -34,6 +34,5 @@ public enum WorldType LAST_MAN_STANDING, TOURNAMENT, DEADMAN, - SEASONAL_DEADMAN, DEADMAN_TOURNAMENT } diff --git a/http-service/src/main/java/net/runelite/http/service/worlds/ServiceWorldType.java b/http-service/src/main/java/net/runelite/http/service/worlds/ServiceWorldType.java index c6aa598321..9cfa5a5a41 100644 --- a/http-service/src/main/java/net/runelite/http/service/worlds/ServiceWorldType.java +++ b/http-service/src/main/java/net/runelite/http/service/worlds/ServiceWorldType.java @@ -36,8 +36,7 @@ enum ServiceWorldType LAST_MAN_STANDING(WorldType.LAST_MAN_STANDING, 1 << 14), TOURNAMENT(WorldType.TOURNAMENT, 1 << 25), DEADMAN_TOURNAMENT(WorldType.DEADMAN_TOURNAMENT, 1 << 26), - DEADMAN(WorldType.DEADMAN, 1 << 29), - SEASONAL_DEADMAN(WorldType.SEASONAL_DEADMAN, 1 << 30); + DEADMAN(WorldType.DEADMAN, 1 << 29); private final WorldType apiType; private final int mask; diff --git a/runelite-api/src/main/java/net/runelite/api/WorldType.java b/runelite-api/src/main/java/net/runelite/api/WorldType.java index 0ecfd1ed94..91c16734ca 100644 --- a/runelite-api/src/main/java/net/runelite/api/WorldType.java +++ b/runelite-api/src/main/java/net/runelite/api/WorldType.java @@ -67,11 +67,7 @@ public enum WorldType /** * Deadman world type. */ - DEADMAN(1 << 29), - /** - * Seasonal deadman world type. - */ - SEASONAL_DEADMAN(1 << 30); + DEADMAN(1 << 29); private final int mask; @@ -83,8 +79,7 @@ public enum WorldType private static final EnumSet PVP_WORLD_TYPES = EnumSet.of( DEADMAN, DEADMAN_TOURNAMENT, - PVP, - SEASONAL_DEADMAN + PVP ); /** diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java index d61f8866db..fe93fb04f6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java @@ -651,10 +651,6 @@ public class HiscorePanel extends PluginPanel { return HiscoreEndpoint.DEADMAN_TOURNAMENT; } - else if (wTypes.contains(WorldType.SEASONAL_DEADMAN)) - { - return HiscoreEndpoint.SEASONAL_DEADMAN; - } else if (wTypes.contains(WorldType.DEADMAN)) { return HiscoreEndpoint.DEADMAN; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java index e038e81ab2..c387581790 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java @@ -117,10 +117,6 @@ public class OpponentInfoPlugin extends Plugin { hiscoreEndpoint = HiscoreEndpoint.DEADMAN_TOURNAMENT; } - else if (worldType.contains(WorldType.SEASONAL_DEADMAN)) - { - hiscoreEndpoint = HiscoreEndpoint.SEASONAL_DEADMAN; - } else if (worldType.contains(WorldType.DEADMAN)) { hiscoreEndpoint = HiscoreEndpoint.DEADMAN; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java index 1c4123e795..e58a088118 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java @@ -616,9 +616,8 @@ public class ScreenshotPlugin extends Plugin { final EnumSet worldTypes = client.getWorldType(); final boolean dmm = worldTypes.contains(WorldType.DEADMAN); - final boolean sdmm = worldTypes.contains(WorldType.SEASONAL_DEADMAN); final boolean dmmt = worldTypes.contains(WorldType.DEADMAN_TOURNAMENT); - final boolean isDmmWorld = dmm || sdmm || dmmt; + final boolean isDmmWorld = dmm || dmmt; String playerDir = client.getLocalPlayer().getName(); if (isDmmWorld) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java index 0a2772f253..67d2e6bccf 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java @@ -542,7 +542,6 @@ public class TimersPlugin extends Plugin else if (HALF_TELEBLOCK_PATTERN.matcher(event.getMessage()).find()) { if (client.getWorldType().contains(WorldType.DEADMAN) - && !client.getWorldType().contains(WorldType.SEASONAL_DEADMAN) && !client.getWorldType().contains(WorldType.DEADMAN_TOURNAMENT)) { createGameTimer(DMM_FULLTB); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableRow.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableRow.java index 2cf20ddd4f..077dd7f72b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableRow.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableRow.java @@ -245,8 +245,7 @@ class WorldTableRow extends JPanel } else if (world.getTypes().contains(WorldType.PVP) || world.getTypes().contains(WorldType.HIGH_RISK) - || world.getTypes().contains(WorldType.DEADMAN) - || world.getTypes().contains(WorldType.SEASONAL_DEADMAN)) + || world.getTypes().contains(WorldType.DEADMAN)) { activityField.setForeground(DANGEROUS_WORLD); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpWorldType.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpWorldType.java index a907381347..5126a978e4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpWorldType.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpWorldType.java @@ -31,7 +31,6 @@ enum XpWorldType NORMAL, TOURNEY, DMM, - SDMM, DMMT; static XpWorldType of(WorldType type) @@ -42,8 +41,6 @@ enum XpWorldType return TOURNEY; case DEADMAN: return DMM; - case SEASONAL_DEADMAN: - return SDMM; case DEADMAN_TOURNAMENT: return DMMT; default: diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/seasonal_deadman.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/seasonal_deadman.png deleted file mode 100644 index d3632e62db3c98559117313d114b7a10d4b4319c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 311 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@Rf|&H|6fVg?3oVGw3ym^DWNDEQLT z#WBR9cWtmWU$X&^X{flE-+@_6g+tjbgxnu_lr(iN)mBe{RN9w%uguBp!JG9~H>Vvx_keqjVYjyHnxqxM zwmWw8m`)8-cRK2(cynR=<$GlUc0IDs7=wz}x^0+SRIV_Shc!L)Ua)44!SOt4x7IS$Z|N3`_;TP9(9;Z_u6{1- HoD!M Date: Fri, 15 Nov 2019 09:19:25 -0500 Subject: [PATCH 06/22] Remove DEADMAN_TOURNAMENT world type Co-authored-by: Hydrox6 --- .../http/api/hiscore/HiscoreEndpoint.java | 3 +-- .../net/runelite/http/api/worlds/WorldType.java | 3 +-- .../http/service/worlds/ServiceWorldType.java | 1 - .../main/java/net/runelite/api/WorldType.java | 5 ----- .../client/plugins/hiscore/HiscorePanel.java | 6 +----- .../plugins/opponentinfo/OpponentInfoPlugin.java | 6 +----- .../plugins/screenshot/ScreenshotPlugin.java | 5 +---- .../client/plugins/timers/TimersPlugin.java | 3 +-- .../client/plugins/xptracker/XpWorldType.java | 5 +---- .../plugins/hiscore/deadman_tournament.png | Bin 3020 -> 0 bytes 10 files changed, 7 insertions(+), 30 deletions(-) delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/deadman_tournament.png diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreEndpoint.java b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreEndpoint.java index 4b0b39b0f4..433357c3e5 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreEndpoint.java +++ b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreEndpoint.java @@ -34,8 +34,7 @@ public enum HiscoreEndpoint IRONMAN("Ironman", "https://services.runescape.com/m=hiscore_oldschool_ironman/index_lite.ws"), HARDCORE_IRONMAN("Hardcore Ironman", "https://services.runescape.com/m=hiscore_oldschool_hardcore_ironman/index_lite.ws"), ULTIMATE_IRONMAN("Ultimate Ironman", "https://services.runescape.com/m=hiscore_oldschool_ultimate/index_lite.ws"), - DEADMAN("Deadman", "https://services.runescape.com/m=hiscore_oldschool_deadman/index_lite.ws"), - DEADMAN_TOURNAMENT("Deadman Tournament", "https://services.runescape.com/m=hiscore_oldschool_tournament/index_lite.ws"); + DEADMAN("Deadman", "https://services.runescape.com/m=hiscore_oldschool_deadman/index_lite.ws"); private final String name; private final HttpUrl hiscoreURL; diff --git a/http-api/src/main/java/net/runelite/http/api/worlds/WorldType.java b/http-api/src/main/java/net/runelite/http/api/worlds/WorldType.java index 5c9af6cc10..0e4f9ace6e 100644 --- a/http-api/src/main/java/net/runelite/http/api/worlds/WorldType.java +++ b/http-api/src/main/java/net/runelite/http/api/worlds/WorldType.java @@ -33,6 +33,5 @@ public enum WorldType HIGH_RISK, LAST_MAN_STANDING, TOURNAMENT, - DEADMAN, - DEADMAN_TOURNAMENT + DEADMAN; } diff --git a/http-service/src/main/java/net/runelite/http/service/worlds/ServiceWorldType.java b/http-service/src/main/java/net/runelite/http/service/worlds/ServiceWorldType.java index 9cfa5a5a41..402436c8fa 100644 --- a/http-service/src/main/java/net/runelite/http/service/worlds/ServiceWorldType.java +++ b/http-service/src/main/java/net/runelite/http/service/worlds/ServiceWorldType.java @@ -35,7 +35,6 @@ enum ServiceWorldType HIGH_RISK(WorldType.HIGH_RISK, 1 << 10), LAST_MAN_STANDING(WorldType.LAST_MAN_STANDING, 1 << 14), TOURNAMENT(WorldType.TOURNAMENT, 1 << 25), - DEADMAN_TOURNAMENT(WorldType.DEADMAN_TOURNAMENT, 1 << 26), DEADMAN(WorldType.DEADMAN, 1 << 29); private final WorldType apiType; diff --git a/runelite-api/src/main/java/net/runelite/api/WorldType.java b/runelite-api/src/main/java/net/runelite/api/WorldType.java index 91c16734ca..70e22d7f89 100644 --- a/runelite-api/src/main/java/net/runelite/api/WorldType.java +++ b/runelite-api/src/main/java/net/runelite/api/WorldType.java @@ -60,10 +60,6 @@ public enum WorldType * Tournament world type. */ TOURNAMENT(1 << 25), - /** - * Deadman Tournament world type. - */ - DEADMAN_TOURNAMENT(1 << 26), /** * Deadman world type. */ @@ -78,7 +74,6 @@ public enum WorldType private static final EnumSet PVP_WORLD_TYPES = EnumSet.of( DEADMAN, - DEADMAN_TOURNAMENT, PVP ); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java index fe93fb04f6..82abca4d68 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java @@ -647,11 +647,7 @@ public class HiscorePanel extends PluginPanel { EnumSet wTypes = client.getWorldType(); - if (wTypes.contains(WorldType.DEADMAN_TOURNAMENT)) - { - return HiscoreEndpoint.DEADMAN_TOURNAMENT; - } - else if (wTypes.contains(WorldType.DEADMAN)) + if (wTypes.contains(WorldType.DEADMAN)) { return HiscoreEndpoint.DEADMAN; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java index c387581790..43b573e857 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java @@ -113,11 +113,7 @@ public class OpponentInfoPlugin extends Plugin } final EnumSet worldType = client.getWorldType(); - if (worldType.contains(WorldType.DEADMAN_TOURNAMENT)) - { - hiscoreEndpoint = HiscoreEndpoint.DEADMAN_TOURNAMENT; - } - else if (worldType.contains(WorldType.DEADMAN)) + if (worldType.contains(WorldType.DEADMAN)) { hiscoreEndpoint = HiscoreEndpoint.DEADMAN; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java index e58a088118..fe73b5f4cc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java @@ -615,12 +615,9 @@ public class ScreenshotPlugin extends Plugin if (client.getLocalPlayer() != null && client.getLocalPlayer().getName() != null) { final EnumSet worldTypes = client.getWorldType(); - final boolean dmm = worldTypes.contains(WorldType.DEADMAN); - final boolean dmmt = worldTypes.contains(WorldType.DEADMAN_TOURNAMENT); - final boolean isDmmWorld = dmm || dmmt; String playerDir = client.getLocalPlayer().getName(); - if (isDmmWorld) + if (worldTypes.contains(WorldType.DEADMAN)) { playerDir += "-Deadman"; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java index 67d2e6bccf..3b6f84823e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java @@ -541,8 +541,7 @@ public class TimersPlugin extends Plugin } else if (HALF_TELEBLOCK_PATTERN.matcher(event.getMessage()).find()) { - if (client.getWorldType().contains(WorldType.DEADMAN) - && !client.getWorldType().contains(WorldType.DEADMAN_TOURNAMENT)) + if (client.getWorldType().contains(WorldType.DEADMAN)) { createGameTimer(DMM_FULLTB); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpWorldType.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpWorldType.java index 5126a978e4..dc31a3272e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpWorldType.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpWorldType.java @@ -30,8 +30,7 @@ enum XpWorldType { NORMAL, TOURNEY, - DMM, - DMMT; + DMM; static XpWorldType of(WorldType type) { @@ -41,8 +40,6 @@ enum XpWorldType return TOURNEY; case DEADMAN: return DMM; - case DEADMAN_TOURNAMENT: - return DMMT; default: return NORMAL; } diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/deadman_tournament.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/deadman_tournament.png deleted file mode 100644 index e74b1d940b387aa63d4bffeb3e8fd257950db778..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3020 zcmV;-3p4bIP)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0002@Nkl9LTKw3z01X`BobB9wiH~%~%M`o9lDd zZ`p0k)+ArBjO#gWP&GbhBsVu(RBNkNv%i!i_v=@I8mup-XCOO9V&c~veehe9`LD+Z zgCvd@qX43QO^=cVI^Tfjoz`UcB$E&&N4C)a=x_$Jt6vLW|CRQScn<(Xdyd4pn%g`8 O0000 Date: Fri, 15 Nov 2019 09:37:21 -0500 Subject: [PATCH 07/22] http api: update hiscore for leagues Co-authored-by: Hydrox6 --- .../net/runelite/http/api/hiscore/HiscoreResult.java | 3 +++ .../runelite/http/api/hiscore/HiscoreResultBuilder.java | 9 ++++----- .../java/net/runelite/http/api/hiscore/HiscoreSkill.java | 5 +++-- .../http/service/hiscore/HiscoreServiceTest.java | 6 ++++-- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResult.java b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResult.java index 9af6f6e4b9..57f29c2910 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResult.java +++ b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResult.java @@ -54,6 +54,7 @@ public class HiscoreResult private Skill runecraft; private Skill hunter; private Skill construction; + private Skill leaguePoints; private Skill bountyHunterHunter; private Skill bountyHunterRogue; private Skill clueScrollAll; @@ -115,6 +116,8 @@ public class HiscoreResult return getHunter(); case CONSTRUCTION: return getConstruction(); + case LEAGUE_POINTS: + return getLeaguePoints(); case OVERALL: return getOverall(); case BOUNTY_HUNTER_HUNTER: diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResultBuilder.java b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResultBuilder.java index a6117160a4..10394b4919 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResultBuilder.java +++ b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResultBuilder.java @@ -26,8 +26,6 @@ package net.runelite.http.api.hiscore; import java.util.ArrayList; import java.util.List; -import net.runelite.http.api.hiscore.HiscoreResult; -import net.runelite.http.api.hiscore.Skill; public class HiscoreResultBuilder { @@ -77,9 +75,9 @@ public class HiscoreResultBuilder hiscoreResult.setRunecraft(skills.get(21)); hiscoreResult.setHunter(skills.get(22)); hiscoreResult.setConstruction(skills.get(23)); - hiscoreResult.setBountyHunterHunter(skills.get(24)); - hiscoreResult.setBountyHunterRogue(skills.get(25)); - hiscoreResult.setLastManStanding(skills.get(26)); + hiscoreResult.setLeaguePoints(skills.get(24)); + hiscoreResult.setBountyHunterHunter(skills.get(25)); + hiscoreResult.setBountyHunterRogue(skills.get(26)); hiscoreResult.setClueScrollAll(skills.get(27)); hiscoreResult.setClueScrollBeginner(skills.get(28)); hiscoreResult.setClueScrollEasy(skills.get(29)); @@ -87,6 +85,7 @@ public class HiscoreResultBuilder hiscoreResult.setClueScrollHard(skills.get(31)); hiscoreResult.setClueScrollElite(skills.get(32)); hiscoreResult.setClueScrollMaster(skills.get(33)); + hiscoreResult.setLastManStanding(skills.get(34)); return hiscoreResult; } } diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkill.java b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkill.java index db043dfcfb..f0864a9424 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkill.java +++ b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkill.java @@ -50,16 +50,17 @@ public enum HiscoreSkill RUNECRAFT("Runecraft"), HUNTER("Hunter"), CONSTRUCTION("Construction"), + LEAGUE_POINTS("League Points"), BOUNTY_HUNTER_HUNTER("Bounty Hunter - Hunter"), BOUNTY_HUNTER_ROGUE("Bounty Hunter - Rogue"), - LAST_MAN_STANDING("Last Man Standing"), CLUE_SCROLL_ALL("Clue Scrolls (all)"), CLUE_SCROLL_BEGINNER("Clue Scrolls (beginner)"), CLUE_SCROLL_EASY("Clue Scrolls (easy)"), CLUE_SCROLL_MEDIUM("Clue Scrolls (medium)"), CLUE_SCROLL_HARD("Clue Scrolls (hard)"), CLUE_SCROLL_ELITE("Clue Scrolls (elite)"), - CLUE_SCROLL_MASTER("Clue Scrolls (master)"); + CLUE_SCROLL_MASTER("Clue Scrolls (master)"), + LAST_MAN_STANDING("Last Man Standing"); private final String name; diff --git a/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreServiceTest.java b/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreServiceTest.java index 9cda0a54ed..52aa2e3d06 100644 --- a/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreServiceTest.java +++ b/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreServiceTest.java @@ -60,16 +60,17 @@ public class HiscoreServiceTest + "638177,1,0\n" + "516239,9,1000\n" + "492790,1,0\n" + + "2,2460\n" // leagues + "-1,-1\n" + "73,1738\n" - + "-1,-1\n" + "531,1432\n" + "324,212\n" + "8008,131\n" + "1337,911\n" + "42,14113\n" + "1,777\n" - + "254,92\n"; + + "254,92\n" + + "-1,-1\n"; // lms private final MockWebServer server = new MockWebServer(); @@ -105,6 +106,7 @@ public class HiscoreServiceTest Assert.assertEquals(777, result.getClueScrollElite().getLevel()); Assert.assertEquals(254, result.getClueScrollMaster().getRank()); Assert.assertEquals(-1, result.getLastManStanding().getLevel()); + Assert.assertEquals(2460, result.getLeaguePoints().getLevel()); } } From 7463d2de1a1f4bf7f3ba962d11f04a53eb97ac13 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 15 Nov 2019 09:40:38 -0500 Subject: [PATCH 08/22] api: add league world type Co-authored-by: Hydrox6 --- .../java/net/runelite/http/api/hiscore/HiscoreEndpoint.java | 3 ++- .../main/java/net/runelite/http/api/worlds/WorldType.java | 3 ++- .../net/runelite/http/service/worlds/ServiceWorldType.java | 3 ++- runelite-api/src/main/java/net/runelite/api/WorldType.java | 6 +++++- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreEndpoint.java b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreEndpoint.java index 433357c3e5..8e5a97dfb3 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreEndpoint.java +++ b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreEndpoint.java @@ -34,7 +34,8 @@ public enum HiscoreEndpoint IRONMAN("Ironman", "https://services.runescape.com/m=hiscore_oldschool_ironman/index_lite.ws"), HARDCORE_IRONMAN("Hardcore Ironman", "https://services.runescape.com/m=hiscore_oldschool_hardcore_ironman/index_lite.ws"), ULTIMATE_IRONMAN("Ultimate Ironman", "https://services.runescape.com/m=hiscore_oldschool_ultimate/index_lite.ws"), - DEADMAN("Deadman", "https://services.runescape.com/m=hiscore_oldschool_deadman/index_lite.ws"); + DEADMAN("Deadman", "https://services.runescape.com/m=hiscore_oldschool_deadman/index_lite.ws"), + LEAGUE("Twisted League", "https://services.runescape.com/m=hiscore_oldschool_seasonal/index_lite.ws"); private final String name; private final HttpUrl hiscoreURL; diff --git a/http-api/src/main/java/net/runelite/http/api/worlds/WorldType.java b/http-api/src/main/java/net/runelite/http/api/worlds/WorldType.java index 0e4f9ace6e..af543b7383 100644 --- a/http-api/src/main/java/net/runelite/http/api/worlds/WorldType.java +++ b/http-api/src/main/java/net/runelite/http/api/worlds/WorldType.java @@ -33,5 +33,6 @@ public enum WorldType HIGH_RISK, LAST_MAN_STANDING, TOURNAMENT, - DEADMAN; + DEADMAN, + LEAGUE; } diff --git a/http-service/src/main/java/net/runelite/http/service/worlds/ServiceWorldType.java b/http-service/src/main/java/net/runelite/http/service/worlds/ServiceWorldType.java index 402436c8fa..896f152752 100644 --- a/http-service/src/main/java/net/runelite/http/service/worlds/ServiceWorldType.java +++ b/http-service/src/main/java/net/runelite/http/service/worlds/ServiceWorldType.java @@ -35,7 +35,8 @@ enum ServiceWorldType HIGH_RISK(WorldType.HIGH_RISK, 1 << 10), LAST_MAN_STANDING(WorldType.LAST_MAN_STANDING, 1 << 14), TOURNAMENT(WorldType.TOURNAMENT, 1 << 25), - DEADMAN(WorldType.DEADMAN, 1 << 29); + DEADMAN(WorldType.DEADMAN, 1 << 29), + LEAGUE(WorldType.LEAGUE, 1 << 30); private final WorldType apiType; private final int mask; diff --git a/runelite-api/src/main/java/net/runelite/api/WorldType.java b/runelite-api/src/main/java/net/runelite/api/WorldType.java index 70e22d7f89..618d272796 100644 --- a/runelite-api/src/main/java/net/runelite/api/WorldType.java +++ b/runelite-api/src/main/java/net/runelite/api/WorldType.java @@ -63,7 +63,11 @@ public enum WorldType /** * Deadman world type. */ - DEADMAN(1 << 29); + DEADMAN(1 << 29), + /** + * League world type + */ + LEAGUE(1 << 30); private final int mask; From 2e024cc6883202426f1a58a015ec62e2b192a0a6 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 15 Nov 2019 09:45:46 -0500 Subject: [PATCH 09/22] hiscore plugin: add leagues Co-authored-by: Hydrox6 --- .../client/plugins/hiscore/HiscorePanel.java | 24 ++++++++++++++---- .../client/plugins/hiscore/league.png | Bin 0 -> 227 bytes .../skill_icons_small/league points.png | Bin 0 -> 304 bytes 3 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/league.png create mode 100644 runelite-client/src/main/resources/skill_icons_small/league points.png diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java index 82abca4d68..2a11a59d2c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java @@ -81,6 +81,7 @@ import static net.runelite.http.api.hiscore.HiscoreSkill.HERBLORE; import static net.runelite.http.api.hiscore.HiscoreSkill.HITPOINTS; import static net.runelite.http.api.hiscore.HiscoreSkill.HUNTER; import static net.runelite.http.api.hiscore.HiscoreSkill.LAST_MAN_STANDING; +import static net.runelite.http.api.hiscore.HiscoreSkill.LEAGUE_POINTS; import static net.runelite.http.api.hiscore.HiscoreSkill.MAGIC; import static net.runelite.http.api.hiscore.HiscoreSkill.MINING; import static net.runelite.http.api.hiscore.HiscoreSkill.OVERALL; @@ -276,6 +277,7 @@ public class HiscorePanel extends PluginPanel minigamePanel.setBackground(ColorScheme.DARKER_GRAY_COLOR); minigamePanel.add(makeSkillPanel(CLUE_SCROLL_ALL)); + minigamePanel.add(makeSkillPanel(LEAGUE_POINTS)); minigamePanel.add(makeSkillPanel(LAST_MAN_STANDING)); minigamePanel.add(makeSkillPanel(BOUNTY_HUNTER_ROGUE)); minigamePanel.add(makeSkillPanel(BOUNTY_HUNTER_HUNTER)); @@ -470,15 +472,17 @@ public class HiscorePanel extends PluginPanel case 0: return null; case 1: - return HiscoreSkill.OVERALL; + return OVERALL; case 2: - return HiscoreSkill.CLUE_SCROLL_ALL; + return CLUE_SCROLL_ALL; case 3: - return HiscoreSkill.LAST_MAN_STANDING; + return LEAGUE_POINTS; case 4: - return HiscoreSkill.BOUNTY_HUNTER_ROGUE; + return LAST_MAN_STANDING; case 5: - return HiscoreSkill.BOUNTY_HUNTER_HUNTER; + return BOUNTY_HUNTER_ROGUE; + case 6: + return BOUNTY_HUNTER_HUNTER; } return null; @@ -562,6 +566,12 @@ public class HiscorePanel extends PluginPanel content += "

Rank: " + rank + "

"; break; } + case LEAGUE_POINTS: + { + String rank = (result.getLeaguePoints().getRank() == -1) ? "Unranked" : QuantityFormatter.formatNumber(result.getLeaguePoints().getRank()); + content += "

Rank: " + rank + "

"; + break; + } case OVERALL: { Skill requestedSkill = result.getSkill(skill); @@ -651,6 +661,10 @@ public class HiscorePanel extends PluginPanel { return HiscoreEndpoint.DEADMAN; } + else if (wTypes.contains(WorldType.LEAGUE)) + { + return HiscoreEndpoint.LEAGUE; + } } return HiscoreEndpoint.NORMAL; } diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/league.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/league.png new file mode 100644 index 0000000000000000000000000000000000000000..b9473db51212d5e3647a34153295c19831436c22 GIT binary patch literal 227 zcmV<90382`P)s420+j9|94NojZl7H*0~2ps#$(B1k*LFk^zda dKR~3_dL8R`0;|g?e7pbv002ovPDHLkV1hamT-5*o literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/skill_icons_small/league points.png b/runelite-client/src/main/resources/skill_icons_small/league points.png new file mode 100644 index 0000000000000000000000000000000000000000..1b976d526cd13870751ec63abefd0d6d0cbe22ed GIT binary patch literal 304 zcmV-00nh%4P)8UT(#UEEoo?(VUqrdDyOXl_ Date: Fri, 15 Nov 2019 09:47:11 -0500 Subject: [PATCH 10/22] world hopper: assign leagues world color Co-authored-by: Hydrox6 --- .../runelite/client/plugins/worldhopper/WorldTableRow.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableRow.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableRow.java index 077dd7f72b..31449ff61b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableRow.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableRow.java @@ -62,6 +62,7 @@ class WorldTableRow extends JPanel private static final Color TOURNAMENT_WORLD = new Color(79, 145, 255); private static final Color MEMBERS_WORLD = new Color(210, 193, 53); private static final Color FREE_WORLD = new Color(200, 200, 200); + private static final Color LEAGUE_WORLD = new Color(157, 237, 1); static { @@ -249,6 +250,10 @@ class WorldTableRow extends JPanel { activityField.setForeground(DANGEROUS_WORLD); } + else if (world.getTypes().contains(WorldType.LEAGUE)) + { + activityField.setForeground(LEAGUE_WORLD); + } else if (world.getTypes().contains(WorldType.TOURNAMENT)) { activityField.setForeground(TOURNAMENT_WORLD); From ef15e79885f347cb5471c1a5b2e6bb2bf42c7842 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 15 Nov 2019 09:48:26 -0500 Subject: [PATCH 11/22] screenshot plugin: add League folder Co-authored-by: Hydrox6 --- .../runelite/client/plugins/screenshot/ScreenshotPlugin.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java index fe73b5f4cc..5510a09635 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java @@ -621,6 +621,10 @@ public class ScreenshotPlugin extends Plugin { playerDir += "-Deadman"; } + else if (worldTypes.contains(WorldType.LEAGUE)) + { + playerDir += "-League"; + } playerFolder = new File(SCREENSHOT_DIR, playerDir); } else From db17dd213cae4d40226b58f771413559060eb26a Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 15 Nov 2019 09:50:48 -0500 Subject: [PATCH 12/22] opponent info: add league hiscore endpoint Co-authored-by: Hydrox6 --- .../client/plugins/opponentinfo/OpponentInfoPlugin.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java index 43b573e857..f411fc2dae 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java @@ -117,6 +117,10 @@ public class OpponentInfoPlugin extends Plugin { hiscoreEndpoint = HiscoreEndpoint.DEADMAN; } + else if (worldType.contains(WorldType.LEAGUE)) + { + hiscoreEndpoint = HiscoreEndpoint.LEAGUE; + } else { hiscoreEndpoint = HiscoreEndpoint.NORMAL; From 39e40b655ca00ce057592589fbc2efb9d917636c Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 15 Nov 2019 09:50:55 -0500 Subject: [PATCH 13/22] xptracker: add league world type Co-authored-by: Hydrox6 --- .../net/runelite/client/plugins/xptracker/XpWorldType.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpWorldType.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpWorldType.java index dc31a3272e..b998a2f8b0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpWorldType.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpWorldType.java @@ -30,7 +30,8 @@ enum XpWorldType { NORMAL, TOURNEY, - DMM; + DMM, + LEAGUE; static XpWorldType of(WorldType type) { @@ -40,6 +41,8 @@ enum XpWorldType return TOURNEY; case DEADMAN: return DMM; + case LEAGUE: + return LEAGUE; default: return NORMAL; } From d76a2670de9d51711163ff6a3deb699b36092ff4 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 15 Nov 2019 10:02:05 -0500 Subject: [PATCH 14/22] chat commands: add support for league hiscores --- .../chatcommands/ChatCommandsPlugin.java | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java index 85b19e266c..e771a649a8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java @@ -27,6 +27,7 @@ package net.runelite.client.plugins.chatcommands; import com.google.inject.Provides; import java.io.IOException; +import java.util.EnumSet; import java.util.List; import java.util.concurrent.ScheduledExecutorService; import java.util.regex.Matcher; @@ -41,8 +42,10 @@ import net.runelite.api.Experience; import net.runelite.api.IconID; import net.runelite.api.ItemComposition; import net.runelite.api.MessageNode; +import net.runelite.api.Player; import net.runelite.api.VarPlayer; import net.runelite.api.Varbits; +import net.runelite.api.WorldType; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.GameTick; import net.runelite.api.events.VarbitChanged; @@ -1126,31 +1129,28 @@ public class ChatCommandsPlugin extends Plugin */ private HiscoreLookup getCorrectLookupFor(final ChatMessage chatMessage) { - final String player; - final HiscoreEndpoint ironmanStatus; + Player localPlayer = client.getLocalPlayer(); + final String player = sanitize(chatMessage.getName()); - if (chatMessage.getType().equals(ChatMessageType.PRIVATECHATOUT)) + // If we are sending the message then just use the local hiscore endpoint for the world + if (chatMessage.getType().equals(ChatMessageType.PRIVATECHATOUT) + || player.equals(localPlayer.getName())) { - player = client.getLocalPlayer().getName(); - ironmanStatus = hiscoreEndpoint; + return new HiscoreLookup(localPlayer.getName(), hiscoreEndpoint); } - else - { - player = sanitize(chatMessage.getName()); - if (player.equals(client.getLocalPlayer().getName())) + // Public chat on a leagues world is always league hiscores, regardless of icon + if (chatMessage.getType() == ChatMessageType.PUBLICCHAT || chatMessage.getType() == ChatMessageType.MODCHAT) + { + if (client.getWorldType().contains(WorldType.LEAGUE)) { - // Get ironman status from for the local player - ironmanStatus = hiscoreEndpoint; - } - else - { - // Get ironman status from their icon in chat - ironmanStatus = getHiscoreEndpointByName(chatMessage.getName()); + return new HiscoreLookup(player, HiscoreEndpoint.LEAGUE); } } - return new HiscoreLookup(player, ironmanStatus); + // Get ironman status from their icon in chat + HiscoreEndpoint endpoint = getHiscoreEndpointByName(chatMessage.getName()); + return new HiscoreLookup(player, endpoint); } /** @@ -1189,6 +1189,12 @@ public class ChatCommandsPlugin extends Plugin */ private HiscoreEndpoint getLocalHiscoreEndpointType() { + EnumSet worldType = client.getWorldType(); + if (worldType.contains(WorldType.LEAGUE)) + { + return HiscoreEndpoint.LEAGUE; + } + return toEndPoint(client.getAccountType()); } From 99fd6278e63516d0089a3a8e904737cc075fdab5 Mon Sep 17 00:00:00 2001 From: emiljensen2 <55587410+emiljensen2@users.noreply.github.com> Date: Sat, 16 Nov 2019 04:16:45 +0100 Subject: [PATCH 15/22] notifier: require client to be focused to cancel notifications --- .../src/main/java/net/runelite/client/Notifier.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/Notifier.java b/runelite-client/src/main/java/net/runelite/client/Notifier.java index 20bcf83c97..4f9653ed86 100644 --- a/runelite-client/src/main/java/net/runelite/client/Notifier.java +++ b/runelite-client/src/main/java/net/runelite/client/Notifier.java @@ -195,9 +195,9 @@ public class Notifier case SOLID_UNTIL_CANCELLED: case FLASH_UNTIL_CANCELLED: // Any interaction with the client since the notification started will cancel it after the minimum duration - if (client.getMouseIdleTicks() < MINIMUM_FLASH_DURATION_TICKS + if ((client.getMouseIdleTicks() < MINIMUM_FLASH_DURATION_TICKS || client.getKeyboardIdleTicks() < MINIMUM_FLASH_DURATION_TICKS - || client.getMouseLastPressedMillis() > mouseLastPressedMillis) + || client.getMouseLastPressedMillis() > mouseLastPressedMillis) && clientUI.isFocused()) { flashStart = null; } From 7052977448db092646a73e6e8f004534f29937fc Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 16 Nov 2019 12:46:42 -0500 Subject: [PATCH 16/22] rotation solver: fix to use modulus instead of remainder operator --- .../net/runelite/client/plugins/raids/RotationSolver.java | 5 +++-- .../runelite/client/plugins/raids/RotationSolverTest.java | 8 ++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RotationSolver.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RotationSolver.java index b9179cea1b..5bbc354785 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RotationSolver.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RotationSolver.java @@ -24,6 +24,7 @@ */ package net.runelite.client.plugins.raids; +import static java.lang.Math.floorMod; import java.util.Arrays; import java.util.List; import static net.runelite.client.plugins.raids.RaidRoom.GUARDIANS; @@ -97,7 +98,7 @@ class RotationSolver continue; } - if (rooms[j] != rotation.get((i + j - start) % rotation.size())) + if (rooms[j] != rotation.get(floorMod(i + j - start, rotation.size()))) { break COMPARE; } @@ -128,7 +129,7 @@ class RotationSolver if (rooms[i].getType() != RoomType.COMBAT || rooms[i] == UNKNOWN_COMBAT) { - rooms[i] = match.get((index + i) % match.size()); + rooms[i] = match.get(floorMod(index + i, match.size())); } } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/raids/RotationSolverTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/raids/RotationSolverTest.java index 38039ca832..7bacba91ce 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/raids/RotationSolverTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/raids/RotationSolverTest.java @@ -77,4 +77,12 @@ public class RotationSolverTest RotationSolver.solve(rooms); assertArrayEquals(new RaidRoom[]{GUARDIANS, VESPULA, SHAMANS, VASA}, rooms); } + + @Test + public void testSolve6() + { + RaidRoom[] rooms = new RaidRoom[]{UNKNOWN_COMBAT, UNKNOWN_COMBAT, TEKTON, MUTTADILES}; + RotationSolver.solve(rooms); + assertArrayEquals(new RaidRoom[]{VANGUARDS, MYSTICS, TEKTON, MUTTADILES}, rooms); + } } \ No newline at end of file From 1fd7ea1f9294dba45f960ce0399853bc5c1731f3 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 16 Nov 2019 14:56:49 -0500 Subject: [PATCH 17/22] clue plugin: add support for league hotcold clues --- .../cluescrolls/clues/HotColdClue.java | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java index 2499379be4..94d07a4983 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java @@ -68,6 +68,10 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat "Jorral", "Speak to Jorral to receive a strange device.", new WorldPoint(2436, 3347, 0)); + private static final HotColdClue MASTER_CLUE_LEAGUE = new HotColdClue("Buried beneath the ground, who knows where it's found. Lucky for you, A man called Watson may have a clue.", + "Watson", + "Speak to Watson to receive a strange device.", + new WorldPoint(1645, 3572, 0)); private final String text; private final String npc; @@ -89,6 +93,11 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat MASTER_CLUE.reset(); return MASTER_CLUE; } + else if (MASTER_CLUE_LEAGUE.text.equalsIgnoreCase(text)) + { + MASTER_CLUE_LEAGUE.reset(); + return MASTER_CLUE_LEAGUE; + } return null; } @@ -272,11 +281,11 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat final Set temperatureSet; - if (this.equals(BEGINNER_CLUE)) + if (this == BEGINNER_CLUE) { temperatureSet = HotColdTemperature.BEGINNER_HOT_COLD_TEMPERATURES; } - else if (this.equals(MASTER_CLUE)) + else if (this == MASTER_CLUE || this == MASTER_CLUE_LEAGUE) { temperatureSet = HotColdTemperature.MASTER_HOT_COLD_TEMPERATURES; } @@ -300,8 +309,9 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat return false; } - if ((this.equals(BEGINNER_CLUE) && temperature == HotColdTemperature.BEGINNER_VISIBLY_SHAKING) - || (this.equals(MASTER_CLUE) && temperature == HotColdTemperature.MASTER_VISIBLY_SHAKING)) + boolean master = this == MASTER_CLUE || this == MASTER_CLUE_LEAGUE; + if ((this == BEGINNER_CLUE && temperature == HotColdTemperature.BEGINNER_VISIBLY_SHAKING) + || (master && temperature == HotColdTemperature.MASTER_VISIBLY_SHAKING)) { markFinalSpot(localWorld); } @@ -327,11 +337,11 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat { final boolean isBeginner; - if (this.equals(BEGINNER_CLUE)) + if (this == BEGINNER_CLUE) { isBeginner = true; } - else if (this.equals(MASTER_CLUE)) + else if (this == MASTER_CLUE || this == MASTER_CLUE_LEAGUE) { isBeginner = false; } From a71b7284555d9e82f18f85b2385572135ece764c Mon Sep 17 00:00:00 2001 From: Seth Date: Sat, 16 Nov 2019 19:18:41 -0600 Subject: [PATCH 18/22] death indicator: add Kourend respawn region --- .../client/plugins/deathindicator/DeathIndicatorPlugin.java | 1 + 1 file changed, 1 insertion(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/deathindicator/DeathIndicatorPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/deathindicator/DeathIndicatorPlugin.java index 3667439385..4a425a1334 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/deathindicator/DeathIndicatorPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/deathindicator/DeathIndicatorPlugin.java @@ -60,6 +60,7 @@ import net.runelite.client.util.ImageUtil; public class DeathIndicatorPlugin extends Plugin { private static final Set RESPAWN_REGIONS = ImmutableSet.of( + 6457, // Kourend 12850, // Lumbridge 11828, // Falador 12342, // Edgeville From a8bebe907cd5af407876d5f522679a0840d40295 Mon Sep 17 00:00:00 2001 From: Seth Date: Sat, 16 Nov 2019 19:39:25 -0600 Subject: [PATCH 19/22] regen meter: add support for endless endurance relic Fixes #10267 --- .../src/main/java/net/runelite/api/Varbits.java | 11 ++++++++++- .../client/plugins/regenmeter/RegenMeterPlugin.java | 8 ++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/runelite-api/src/main/java/net/runelite/api/Varbits.java b/runelite-api/src/main/java/net/runelite/api/Varbits.java index f156a4a80e..a7687b9af3 100644 --- a/runelite-api/src/main/java/net/runelite/api/Varbits.java +++ b/runelite-api/src/main/java/net/runelite/api/Varbits.java @@ -507,7 +507,16 @@ public enum Varbits EXPLORER_RING_ALCHS(4554), EXPLORER_RING_RUNENERGY(4553), - WINTERTODT_TIMER(7980); + WINTERTODT_TIMER(7980), + + /** + * Twisted league + */ + TWISTED_LEAGUE_RELIC_1(10049), + TWISTED_LEAGUE_RELIC_2(10050), + TWISTED_LEAGUE_RELIC_3(10051), + TWISTED_LEAGUE_RELIC_4(10052), + TWISTED_LEAGUE_RELIC_5(10053); /** * The raw varbit ID. diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/regenmeter/RegenMeterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/regenmeter/RegenMeterPlugin.java index 004441b6e3..0eb6e9b231 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/regenmeter/RegenMeterPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/regenmeter/RegenMeterPlugin.java @@ -36,6 +36,7 @@ import net.runelite.api.GameState; import net.runelite.api.Prayer; import net.runelite.api.Skill; import net.runelite.api.VarPlayer; +import net.runelite.api.Varbits; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.VarbitChanged; @@ -56,6 +57,8 @@ public class RegenMeterPlugin extends Plugin private static final int SPEC_REGEN_TICKS = 50; private static final int NORMAL_HP_REGEN_TICKS = 100; + private static final int TWISTED_LEAGUE_ENDLESS_ENDURANCE_RELIC = 2; + @Inject private Client client; @@ -141,6 +144,11 @@ public class RegenMeterPlugin extends Plugin ticksPerHPRegen /= 2; } + if (client.getVar(Varbits.TWISTED_LEAGUE_RELIC_1) == TWISTED_LEAGUE_ENDLESS_ENDURANCE_RELIC) + { + ticksPerHPRegen /= 4; + } + ticksSinceHPRegen = (ticksSinceHPRegen + 1) % ticksPerHPRegen; hitpointsPercentage = ticksSinceHPRegen / (double) ticksPerHPRegen; From bfe5873b39a0f37c9d2fac2623e96366d37b868a Mon Sep 17 00:00:00 2001 From: Runelite auto updater Date: Sun, 17 Nov 2019 02:09:08 +0000 Subject: [PATCH 20/22] Release 1.5.41 --- cache-client/pom.xml | 2 +- cache-updater/pom.xml | 2 +- cache/pom.xml | 2 +- http-api/pom.xml | 2 +- http-service/pom.xml | 2 +- pom.xml | 4 ++-- protocol-api/pom.xml | 2 +- protocol/pom.xml | 2 +- runelite-api/pom.xml | 2 +- runelite-client/pom.xml | 2 +- runelite-script-assembler-plugin/pom.xml | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/cache-client/pom.xml b/cache-client/pom.xml index 14b78dedc0..e2b7a819da 100644 --- a/cache-client/pom.xml +++ b/cache-client/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.5.41-SNAPSHOT + 1.5.41 cache-client diff --git a/cache-updater/pom.xml b/cache-updater/pom.xml index 8b1cfbfbce..b478fade95 100644 --- a/cache-updater/pom.xml +++ b/cache-updater/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.5.41-SNAPSHOT + 1.5.41 Cache Updater diff --git a/cache/pom.xml b/cache/pom.xml index 2d6b2902ba..149a8473e3 100644 --- a/cache/pom.xml +++ b/cache/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.5.41-SNAPSHOT + 1.5.41 cache diff --git a/http-api/pom.xml b/http-api/pom.xml index d6f31c6e57..acfa3838ab 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.5.41-SNAPSHOT + 1.5.41 Web API diff --git a/http-service/pom.xml b/http-service/pom.xml index 6a1acf76f9..3d3eef78b3 100644 --- a/http-service/pom.xml +++ b/http-service/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.5.41-SNAPSHOT + 1.5.41 Web Service diff --git a/pom.xml b/pom.xml index 40db9c24b6..9a1962e6e0 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.5.41-SNAPSHOT + 1.5.41 pom RuneLite @@ -59,7 +59,7 @@ https://github.com/runelite/runelite scm:git:git://github.com/runelite/runelite scm:git:git@github.com:runelite/runelite - HEAD + runelite-parent-1.5.41 diff --git a/protocol-api/pom.xml b/protocol-api/pom.xml index 18a385b30b..78349f72cf 100644 --- a/protocol-api/pom.xml +++ b/protocol-api/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.5.41-SNAPSHOT + 1.5.41 protocol-api diff --git a/protocol/pom.xml b/protocol/pom.xml index 1de9223e25..4d01255026 100644 --- a/protocol/pom.xml +++ b/protocol/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.5.41-SNAPSHOT + 1.5.41 protocol diff --git a/runelite-api/pom.xml b/runelite-api/pom.xml index f773eb6747..658a41c29c 100644 --- a/runelite-api/pom.xml +++ b/runelite-api/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.5.41-SNAPSHOT + 1.5.41 runelite-api diff --git a/runelite-client/pom.xml b/runelite-client/pom.xml index 8858fe86e1..bc8727a1d2 100644 --- a/runelite-client/pom.xml +++ b/runelite-client/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.5.41-SNAPSHOT + 1.5.41 client diff --git a/runelite-script-assembler-plugin/pom.xml b/runelite-script-assembler-plugin/pom.xml index 632c879b8a..56aa675868 100644 --- a/runelite-script-assembler-plugin/pom.xml +++ b/runelite-script-assembler-plugin/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.5.41-SNAPSHOT + 1.5.41 script-assembler-plugin From 581d27b608e3055af6c66217eaaeb52ee1a69a66 Mon Sep 17 00:00:00 2001 From: Runelite auto updater Date: Sun, 17 Nov 2019 02:09:15 +0000 Subject: [PATCH 21/22] Bump for 1.5.42-SNAPSHOT --- cache-client/pom.xml | 2 +- cache-updater/pom.xml | 2 +- cache/pom.xml | 2 +- http-api/pom.xml | 2 +- http-service/pom.xml | 2 +- pom.xml | 4 ++-- protocol-api/pom.xml | 2 +- protocol/pom.xml | 2 +- runelite-api/pom.xml | 2 +- runelite-client/pom.xml | 2 +- runelite-script-assembler-plugin/pom.xml | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/cache-client/pom.xml b/cache-client/pom.xml index e2b7a819da..cb5f3a015b 100644 --- a/cache-client/pom.xml +++ b/cache-client/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.5.41 + 1.5.42-SNAPSHOT cache-client diff --git a/cache-updater/pom.xml b/cache-updater/pom.xml index b478fade95..d8847b485a 100644 --- a/cache-updater/pom.xml +++ b/cache-updater/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.5.41 + 1.5.42-SNAPSHOT Cache Updater diff --git a/cache/pom.xml b/cache/pom.xml index 149a8473e3..58c8e79116 100644 --- a/cache/pom.xml +++ b/cache/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.5.41 + 1.5.42-SNAPSHOT cache diff --git a/http-api/pom.xml b/http-api/pom.xml index acfa3838ab..b7f4e98234 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.5.41 + 1.5.42-SNAPSHOT Web API diff --git a/http-service/pom.xml b/http-service/pom.xml index 3d3eef78b3..98f258123e 100644 --- a/http-service/pom.xml +++ b/http-service/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.5.41 + 1.5.42-SNAPSHOT Web Service diff --git a/pom.xml b/pom.xml index 9a1962e6e0..3e6a1f9d82 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.5.41 + 1.5.42-SNAPSHOT pom RuneLite @@ -59,7 +59,7 @@ https://github.com/runelite/runelite scm:git:git://github.com/runelite/runelite scm:git:git@github.com:runelite/runelite - runelite-parent-1.5.41 + HEAD diff --git a/protocol-api/pom.xml b/protocol-api/pom.xml index 78349f72cf..42c621b83c 100644 --- a/protocol-api/pom.xml +++ b/protocol-api/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.5.41 + 1.5.42-SNAPSHOT protocol-api diff --git a/protocol/pom.xml b/protocol/pom.xml index 4d01255026..2491a3c6cc 100644 --- a/protocol/pom.xml +++ b/protocol/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.5.41 + 1.5.42-SNAPSHOT protocol diff --git a/runelite-api/pom.xml b/runelite-api/pom.xml index 658a41c29c..6019461c26 100644 --- a/runelite-api/pom.xml +++ b/runelite-api/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.5.41 + 1.5.42-SNAPSHOT runelite-api diff --git a/runelite-client/pom.xml b/runelite-client/pom.xml index bc8727a1d2..a07335788e 100644 --- a/runelite-client/pom.xml +++ b/runelite-client/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.5.41 + 1.5.42-SNAPSHOT client diff --git a/runelite-script-assembler-plugin/pom.xml b/runelite-script-assembler-plugin/pom.xml index 56aa675868..8e2b4fb336 100644 --- a/runelite-script-assembler-plugin/pom.xml +++ b/runelite-script-assembler-plugin/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.5.41 + 1.5.42-SNAPSHOT script-assembler-plugin From f98ce492608aa8d5b4f80d67d5179b8c99beb8fe Mon Sep 17 00:00:00 2001 From: Max Weber Date: Sat, 16 Nov 2019 19:31:54 -0700 Subject: [PATCH 22/22] ClientLoader: Don't force the bootstrap classloader --- .../src/main/java/net/runelite/client/rs/ClientLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java b/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java index 6a9015d370..6a5067561c 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java @@ -387,7 +387,7 @@ public class ClientLoader implements Supplier private Applet loadClient(URL url) throws ClassNotFoundException, IllegalAccessException, InstantiationException { - URLClassLoader rsClassLoader = new URLClassLoader(new URL[]{url}); + URLClassLoader rsClassLoader = new URLClassLoader(new URL[]{url}, ClientLoader.class.getClassLoader()); String initialClass = config.getInitialClass(); Class clientClass = rsClassLoader.loadClass(initialClass);