diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index d40fcd14f5..4395a67dac 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -37,7 +37,7 @@ jobs: - name: Assembling run: ./gradlew assemble --console=plain - name: Building - run: ./gradlew build --stacktrace -x test -x checkstyleMain --console=plain + run: ./gradlew build --stacktrace -x test -x checkstyleMain -x checkstyleTest --console=plain test: runs-on: ubuntu-latest diff --git a/http-api/src/main/java/net/runelite/http/api/worlds/WorldClient.java b/http-api/src/main/java/net/runelite/http/api/worlds/WorldClient.java index 61169ab601..65e7f5a541 100644 --- a/http-api/src/main/java/net/runelite/http/api/worlds/WorldClient.java +++ b/http-api/src/main/java/net/runelite/http/api/worlds/WorldClient.java @@ -26,7 +26,7 @@ package net.runelite.http.api.worlds; import com.google.gson.JsonParseException; -import io.reactivex.Observable; +import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import javax.inject.Inject; @@ -50,7 +50,7 @@ public class WorldClient this.client = client; } - public Observable lookupWorlds() + public WorldResult lookupWorlds() throws IOException { HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() .addPathSegment("worlds.js") @@ -58,27 +58,24 @@ public class WorldClient logger.debug("Built URI: {}", url); - return Observable.defer(() -> + Request request = new Request.Builder() + .url(url) + .build(); + + try (Response response = client.newCall(request).execute()) { - Request request = new Request.Builder() - .url(url) - .build(); - - try (Response response = client.newCall(request).execute()) + if (!response.isSuccessful()) { - if (!response.isSuccessful()) - { - logger.debug("Error looking up worlds: {}", response); - return Observable.just(null); - } + logger.debug("Error looking up worlds: {}", response); + throw new IOException("unsuccessful response looking up worlds"); + } - InputStream in = response.body().byteStream(); - return Observable.just(RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), WorldResult.class)); - } - catch (JsonParseException ex) - { - return Observable.error(ex); - } - }); + InputStream in = response.body().byteStream(); + return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), WorldResult.class); + } + catch (JsonParseException ex) + { + throw new IOException(ex); + } } -} +} \ No newline at end of file diff --git a/http-service/src/main/java/net/runelite/http/service/chat/ChatController.java b/http-service/src/main/java/net/runelite/http/service/chat/ChatController.java index 15381845b5..ccba9db430 100644 --- a/http-service/src/main/java/net/runelite/http/service/chat/ChatController.java +++ b/http-service/src/main/java/net/runelite/http/service/chat/ChatController.java @@ -47,6 +47,7 @@ public class ChatController { private static final Pattern STRING_VALIDATION = Pattern.compile("[^a-zA-Z0-9' -]"); private static final int STRING_MAX_LENGTH = 50; + private static final int MAX_LAYOUT_ROOMS = 16; private final Cache killCountCache = CacheBuilder.newBuilder() .expireAfterWrite(2, TimeUnit.MINUTES) @@ -214,6 +215,11 @@ public class ChatController @PostMapping("/layout") public void submitLayout(@RequestParam String name, @RequestBody LayoutRoom[] rooms) { + if (rooms.length > MAX_LAYOUT_ROOMS) + { + return; + } + chatService.setLayout(name, rooms); } diff --git a/runelite-api/src/main/java/net/runelite/api/ChatMessageType.java b/runelite-api/src/main/java/net/runelite/api/ChatMessageType.java index b4659dfa18..abed95406c 100644 --- a/runelite-api/src/main/java/net/runelite/api/ChatMessageType.java +++ b/runelite-api/src/main/java/net/runelite/api/ChatMessageType.java @@ -148,6 +148,10 @@ public enum ChatMessageType * A message that times out after 10 seconds. */ TENSECTIMEOUT(107), + /** + * The "Welcome to RuneScape" message + */ + WELCOME(108), /** * An unknown message type. */ diff --git a/runelite-api/src/main/java/net/runelite/api/ItemID.java b/runelite-api/src/main/java/net/runelite/api/ItemID.java index c6fb000229..175b45365d 100644 --- a/runelite-api/src/main/java/net/runelite/api/ItemID.java +++ b/runelite-api/src/main/java/net/runelite/api/ItemID.java @@ -11357,5 +11357,14 @@ public final class ItemID public static final int TWISTED_BOOTS_T1 = 24411; public static final int TWISTED_LEAGUE_BANNER = 24413; public static final int RUNE_POUCH_L = 24416; + public static final int INQUISITORS_MACE = 24417; + public static final int SIRENS_TOME = 24418; + public static final int INQUISITORS_GREAT_HELM = 24419; + public static final int INQUISITORS_HAUBERK = 24420; + public static final int INQUISITORS_PLATESKIRT = 24421; + public static final int NIGHTMARE_STAFF = 24422; + public static final int HARMONISED_NIGHTMARE_STAFF = 24423; + public static final int VOLATILE_NIGHTMARE_STAFF = 24424; + public static final int ELDRITCH_NIGHTMARE_STAFF = 24425; /* This file is automatically generated. Do not edit. */ } diff --git a/runelite-api/src/main/java/net/runelite/api/NullItemID.java b/runelite-api/src/main/java/net/runelite/api/NullItemID.java index 91f4b15a8d..47ecf9083f 100644 --- a/runelite-api/src/main/java/net/runelite/api/NullItemID.java +++ b/runelite-api/src/main/java/net/runelite/api/NullItemID.java @@ -12850,5 +12850,6 @@ public final class NullItemID public static final int NULL_24410 = 24410; public static final int NULL_24412 = 24412; public static final int NULL_24414 = 24414; + public static final int NULL_24415 = 24415; /* This file is automatically generated. Do not edit. */ } diff --git a/runelite-api/src/main/java/net/runelite/api/NullObjectID.java b/runelite-api/src/main/java/net/runelite/api/NullObjectID.java index 86b6e4a5bd..623326fd6a 100644 --- a/runelite-api/src/main/java/net/runelite/api/NullObjectID.java +++ b/runelite-api/src/main/java/net/runelite/api/NullObjectID.java @@ -18070,5 +18070,6 @@ public final class NullObjectID public static final int NULL_37480 = 37480; public static final int NULL_37481 = 37481; public static final int NULL_37490 = 37490; + public static final int NULL_37491 = 37491; /* This file is automatically generated. Do not edit. */ } diff --git a/runelite-api/src/main/java/net/runelite/api/coords/WorldPoint.java b/runelite-api/src/main/java/net/runelite/api/coords/WorldPoint.java index c4a64301a0..bd9a33c0f6 100644 --- a/runelite-api/src/main/java/net/runelite/api/coords/WorldPoint.java +++ b/runelite-api/src/main/java/net/runelite/api/coords/WorldPoint.java @@ -33,6 +33,7 @@ import javax.annotation.Nullable; import lombok.Value; import net.runelite.api.Client; import static net.runelite.api.Constants.CHUNK_SIZE; +import static net.runelite.api.Constants.REGION_SIZE; import net.runelite.api.Perspective; /** @@ -416,6 +417,6 @@ public class WorldPoint private static int getRegionOffset(final int position) { - return position & 0x3f; + return position & (REGION_SIZE - 1); } } diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java index 14445d6c4b..ecec5d6f61 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java @@ -986,6 +986,7 @@ public class WidgetID static class StandardSpellBook { static final int LUMBRIDGE_HOME_TELEPORT = 5; + static final int KOUREND_HOME_TELEPORT = 4; } static class AncientSpellBook diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java index c3e7dfd1c7..60a238b53a 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java @@ -512,6 +512,7 @@ public enum WidgetInfo PVP_FOG_OVERLAY(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.FOG_OVERLAY), PVP_CONTAINER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.PVP_WIDGET_CONTAINER), + PVP_SKULL_CONTAINER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SKULL_CONTAINER), PVP_SKULL(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SKULL), PVP_ATTACK_RANGE(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.ATTACK_RANGE), @@ -676,6 +677,7 @@ public enum WidgetInfo /* END OF LUNAR SPELL BOOK WIDGETS*/ SPELL_TOOLTIP(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TOOLTIP), /* ARCEUUS SPELL BOOK WIDGETS*/ + SPELL_KOUREND_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.KOUREND_HOME_TELEPORT), SPELL_ARCEUUS_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ARCEUUS_HOME_TELEPORT), SPELL_BATTLEFRONT_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BATTLEFRONT_TELEPORT), /* END OF ARCEUUS SPELL BOOK WIDGETS*/ diff --git a/runelite-client/src/main/java/net/runelite/client/callback/ClientThread.java b/runelite-client/src/main/java/net/runelite/client/callback/ClientThread.java index 8935c8118e..7e9bb4106d 100644 --- a/runelite-client/src/main/java/net/runelite/client/callback/ClientThread.java +++ b/runelite-client/src/main/java/net/runelite/client/callback/ClientThread.java @@ -29,6 +29,7 @@ import java.util.Iterator; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Executor; import java.util.function.BooleanSupplier; +import javax.annotation.Nullable; import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; @@ -41,6 +42,7 @@ public class ClientThread implements Executor private final ConcurrentLinkedQueue invokes = new ConcurrentLinkedQueue<>(); @Inject + @Nullable private Client client; public void invoke(Runnable r) diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigInvocationHandler.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigInvocationHandler.java index 6e35195177..26844922cd 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigInvocationHandler.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigInvocationHandler.java @@ -26,12 +26,11 @@ package net.runelite.client.config; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; -import java.lang.invoke.MethodHandles; -import java.lang.reflect.Constructor; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.Objects; import lombok.extern.slf4j.Slf4j; +import net.runelite.client.util.ReflectUtil; @Slf4j class ConfigInvocationHandler implements InvocationHandler @@ -169,12 +168,8 @@ class ConfigInvocationHandler implements InvocationHandler static Object callDefaultMethod(Object proxy, Method method, Object[] args) throws Throwable { - // Call the default method implementation - https://rmannibucau.wordpress.com/2014/03/27/java-8-default-interface-methods-and-jdk-dynamic-proxies/ - Constructor constructor = MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, int.class); - constructor.setAccessible(true); - Class declaringClass = method.getDeclaringClass(); - return constructor.newInstance(declaringClass, MethodHandles.Lookup.PUBLIC | MethodHandles.Lookup.PRIVATE) + return ReflectUtil.privateLookupIn(declaringClass) .unreflectSpecial(method, declaringClass) .bindTo(proxy) .invokeWithArguments(args); diff --git a/runelite-client/src/main/java/net/runelite/client/events/WorldsFetch.java b/runelite-client/src/main/java/net/runelite/client/events/WorldsFetch.java new file mode 100644 index 0000000000..47f6cc99f7 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/events/WorldsFetch.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019, Adam + * 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.events; + +import lombok.Value; +import net.runelite.api.events.Event; +import net.runelite.http.api.worlds.WorldResult; + +/** + * Fired when the @{link net.runelite.client.game.WorldService} refreshes the world list + */ +@Value +public class WorldsFetch implements Event +{ + private final WorldResult worldResult; +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/game/WorldService.java b/runelite-client/src/main/java/net/runelite/client/game/WorldService.java new file mode 100644 index 0000000000..51858692cb --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/game/WorldService.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2019, Adam + * 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 java.io.IOException; +import java.util.Comparator; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import javax.annotation.Nullable; +import javax.inject.Inject; +import javax.inject.Singleton; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.GameState; +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; + +@Singleton +@Slf4j +public class WorldService +{ + private static final int WORLD_FETCH_TIMER = 10; // minutes + + private final Client client; + private final ScheduledExecutorService scheduledExecutorService; + private final WorldClient worldClient; + private final EventBus eventBus; + private final CompletableFuture firstRunFuture = new CompletableFuture<>(); + + private WorldResult worlds; + + @Inject + private WorldService(Client client, ScheduledExecutorService scheduledExecutorService, WorldClient worldClient, + EventBus eventBus) + { + this.client = client; + this.scheduledExecutorService = scheduledExecutorService; + this.worldClient = worldClient; + this.eventBus = eventBus; + + scheduledExecutorService.scheduleWithFixedDelay(RunnableExceptionLogger.wrap(this::tick), 0, WORLD_FETCH_TIMER, TimeUnit.MINUTES); + } + + private void tick() + { + try + { + if (worlds == null || client.getGameState() == GameState.LOGGED_IN) + { + fetch(); + } + } + finally + { + firstRunFuture.complete(worlds); + } + } + + private void fetch() + { + log.debug("Fetching worlds"); + + try + { + WorldResult worldResult = worldClient.lookupWorlds(); + worldResult.getWorlds().sort(Comparator.comparingInt(World::getId)); + worlds = worldResult; + eventBus.post(WorldsFetch.class, new WorldsFetch(worldResult)); + } + catch (IOException ex) + { + log.warn("Error looking up worlds", ex); + } + } + + public void refresh() + { + scheduledExecutorService.execute(this::fetch); + } + + @Nullable + public WorldResult getWorlds() + { + if (!firstRunFuture.isDone()) + { + try + { + return firstRunFuture.get(10, TimeUnit.SECONDS); + } + catch (InterruptedException | ExecutionException | TimeoutException e) + { + log.warn("Failed to retrieve worlds on first run", e); + } + } + + return worlds; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java index 09f3eba7c8..7a68d24622 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java @@ -52,6 +52,7 @@ import net.runelite.client.input.KeyListener; import net.runelite.client.input.KeyManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; +import org.apache.commons.lang3.StringUtils; @PluginDescriptor( name = "Chat History", @@ -61,7 +62,7 @@ import net.runelite.client.plugins.PluginDescriptor; @Singleton public class ChatHistoryPlugin extends Plugin implements KeyListener { - private static final String WELCOME_MESSAGE = "Welcome to Old School RuneScape."; + private static final String WELCOME_MESSAGE = "Welcome to Old School RuneScape"; private static final String CLEAR_HISTORY = "Clear history"; private static final String CLEAR_PRIVATE = "Private:"; private static final int CYCLE_HOTKEY = KeyEvent.VK_TAB; @@ -137,7 +138,8 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener { // Start sending old messages right after the welcome message, as that is most reliable source // of information that chat history was reset - if (chatMessage.getMessage().equals(WELCOME_MESSAGE)) + ChatMessageType chatMessageType = chatMessage.getType(); + if (chatMessageType == ChatMessageType.WELCOME && StringUtils.startsWithIgnoreCase(chatMessage.getMessage(), WELCOME_MESSAGE)) { if (!this.retainChatHistory) { @@ -154,7 +156,7 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener return; } - switch (chatMessage.getType()) + switch (chatMessageType) { case PRIVATECHATOUT: case PRIVATECHAT: @@ -174,7 +176,7 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener case FRIENDSCHAT: case CONSOLE: final QueuedMessage queuedMessage = QueuedMessage.builder() - .type(chatMessage.getType()) + .type(chatMessageType) .name(chatMessage.getName()) .sender(chatMessage.getSender()) .value(tweakSpaces(chatMessage.getMessage())) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java index dca9ea01f4..006f05601f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java @@ -25,22 +25,21 @@ package net.runelite.client.plugins.defaultworld; import com.google.inject.Provides; -import io.reactivex.schedulers.Schedulers; import javax.inject.Inject; import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.events.GameStateChanged; -import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.SessionOpen; +import net.runelite.client.game.WorldService; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.util.WorldUtil; import net.runelite.http.api.worlds.World; -import net.runelite.http.api.worlds.WorldClient; +import net.runelite.http.api.worlds.WorldResult; @PluginDescriptor( name = "Default World", @@ -58,10 +57,7 @@ public class DefaultWorldPlugin extends Plugin private DefaultWorldConfig config; @Inject - private ClientThread clientThread; - - @Inject - private WorldClient worldClient; + private WorldService worldService; private int worldCache; private boolean worldChangeRequired; @@ -122,39 +118,33 @@ public class DefaultWorldPlugin extends Plugin return; } - worldClient.lookupWorlds() - .subscribeOn(Schedulers.io()) - .observeOn(Schedulers.from(clientThread)) - .subscribe( - (worldResult) -> - { - if (worldResult == null) - { - return; - } + final WorldResult worldResult = worldService.getWorlds(); - final World world = worldResult.findWorld(correctedWorld); + if (worldResult == null) + { + log.warn("Failed to lookup worlds."); + return; + } - if (world != null) - { - final net.runelite.api.World rsWorld = client.createWorld(); - rsWorld.setActivity(world.getActivity()); - rsWorld.setAddress(world.getAddress()); - rsWorld.setId(world.getId()); - rsWorld.setPlayerCount(world.getPlayers()); - rsWorld.setLocation(world.getLocation()); - rsWorld.setTypes(WorldUtil.toWorldTypes(world.getTypes())); + final World world = worldResult.findWorld(correctedWorld); - client.changeWorld(rsWorld); - log.debug("Applied new world {}", correctedWorld); - } - else - { - log.warn("World {} not found.", correctedWorld); - } - }, - (e) -> log.warn("Error looking up world {}. Error: {}", correctedWorld, e) - ); + if (world != null) + { + final net.runelite.api.World rsWorld = client.createWorld(); + rsWorld.setActivity(world.getActivity()); + rsWorld.setAddress(world.getAddress()); + rsWorld.setId(world.getId()); + rsWorld.setPlayerCount(world.getPlayers()); + rsWorld.setLocation(world.getLocation()); + rsWorld.setTypes(WorldUtil.toWorldTypes(world.getTypes())); + + client.changeWorld(rsWorld); + log.debug("Applied new world {}", correctedWorld); + } + else + { + log.warn("World {} not found.", correctedWorld); + } } private void applyWorld() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java b/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java index 8d6006856e..16e27b1519 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java @@ -84,7 +84,9 @@ enum Emoji ALIEN("(@.@)"), EGGPLANT("8=D"), WAVE("(^_^)/"), - HEART_EYES("(*.*)"); + HEART_EYES("(*.*)"), + FACEPALM("M-)"), + ; private static final Map emojiMap; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsConfig.java index 16922d9874..6f418e18ec 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsConfig.java @@ -33,14 +33,15 @@ import net.runelite.client.config.Range; public interface FpsConfig extends Config { @ConfigItem( - keyName = "limitMode", - name = "Limit Mode", - description = "Stay at or under the target frames per second even when in this mode", + keyName = "limitFps", + name = "Limit Global FPS", + description = "Global FPS limit in effect regardless of
" + + "whether window is in focus or not", position = 1 ) - default FpsLimitMode limitMode() + default boolean limitFps() { - return FpsLimitMode.NEVER; + return false; } @Range( @@ -49,8 +50,8 @@ public interface FpsConfig extends Config ) @ConfigItem( keyName = "maxFps", - name = "FPS target", - description = "Desired max frames per second", + name = "Global FPS target", + description = "Desired max global frames per second", position = 2 ) default int maxFps() @@ -58,11 +59,33 @@ public interface FpsConfig extends Config return 50; } + @ConfigItem( + keyName = "limitFpsUnfocused", + name = "Limit FPS unfocused", + description = "FPS limit while window is out of focus", + position = 3 + ) + default boolean limitFpsUnfocused() + { + return false; + } + + @ConfigItem( + keyName = "maxFpsUnfocused", + name = "Unfocused FPS target", + description = "Desired max frames per second for unfocused", + position = 4 + ) + default int maxFpsUnfocused() + { + return 50; + } + @ConfigItem( keyName = "drawFps", name = "Draw FPS indicator", description = "Show a number in the corner for the current FPS", - position = 3 + position = 5 ) default boolean drawFps() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsDrawListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsDrawListener.java index b729a4ad9f..8871780b1e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsDrawListener.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsDrawListener.java @@ -69,7 +69,13 @@ public class FpsDrawListener implements Runnable void reloadConfig() { lastMillis = System.currentTimeMillis(); - targetDelay = 1000 / Math.max(1, config.maxFps()); + + int fps = config.limitFpsUnfocused() && !isFocused + ? config.maxFpsUnfocused() + : config.maxFps(); + + targetDelay = 1000 / Math.max(1, fps); + sleepDelay = targetDelay; for (int i = 0; i < SAMPLE_SIZE; i++) @@ -81,18 +87,18 @@ public class FpsDrawListener implements Runnable void onFocusChanged(FocusChanged event) { this.isFocused = event.isFocused(); + reloadConfig(); // load new delay } private boolean isEnforced() { - return FpsLimitMode.ALWAYS == plugin.getLimitMode() - || (FpsLimitMode.UNFOCUSED == plugin.getLimitMode() && !isFocused); + return config.limitFps() + || (config.limitFpsUnfocused() && !isFocused); } @Override public void run() { - if (!isEnforced()) { return; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsOverlay.java index 0103337792..e7e3f669a0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsOverlay.java @@ -57,16 +57,16 @@ public class FpsOverlay extends Overlay // Local dependencies private final Client client; - private final FpsPlugin plugin; + private final FpsConfig config; // Often changing values private boolean isFocused = true; @Inject - private FpsOverlay(final FpsPlugin plugin, final Client client) + private FpsOverlay(final FpsConfig config, final Client client) { this.client = client; - this.plugin = plugin; + this.config = config; setLayer(OverlayLayer.ABOVE_WIDGETS); setPriority(OverlayPriority.HIGH); setPosition(OverlayPosition.DYNAMIC); @@ -79,8 +79,8 @@ public class FpsOverlay extends Overlay private boolean isEnforced() { - return FpsLimitMode.ALWAYS == plugin.getLimitMode() - || (FpsLimitMode.UNFOCUSED == plugin.getLimitMode() && !isFocused); + return config.limitFps() + || (config.limitFpsUnfocused() && !isFocused); } private Color getFpsValueColor() @@ -91,7 +91,7 @@ public class FpsOverlay extends Overlay @Override public Dimension render(Graphics2D graphics) { - if (!plugin.isDrawFps()) + if (!config.drawFps()) { return null; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsPlugin.java index dd641e8e96..24767d2b7d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsPlugin.java @@ -27,8 +27,6 @@ package net.runelite.client.plugins.fps; import com.google.inject.Inject; import com.google.inject.Provides; import com.google.inject.Singleton; -import lombok.AccessLevel; -import lombok.Getter; import net.runelite.api.events.FocusChanged; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; @@ -71,15 +69,6 @@ public class FpsPlugin extends Plugin @Inject private DrawManager drawManager; - @Inject - private FpsConfig fpsConfig; - - @Getter(AccessLevel.PACKAGE) - private FpsLimitMode limitMode; - - @Getter(AccessLevel.PACKAGE) - private boolean drawFps; - @Provides FpsConfig provideConfig(ConfigManager configManager) { @@ -92,9 +81,6 @@ public class FpsPlugin extends Plugin if (event.getGroup().equals(CONFIG_GROUP_KEY)) { drawListener.reloadConfig(); - - limitMode = fpsConfig.limitMode(); - drawFps = fpsConfig.drawFps(); } } @@ -108,9 +94,6 @@ public class FpsPlugin extends Plugin @Override protected void startUp() { - - limitMode = fpsConfig.limitMode(); - drawFps = fpsConfig.drawFps(); overlayManager.add(overlay); drawManager.registerEveryFrameListener(drawListener); drawListener.reloadConfig(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridOverlay.java index 8a921e07c9..d63be48c39 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridOverlay.java @@ -84,7 +84,6 @@ class InventoryGridOverlay extends Overlay final Point mousePoint = new Point(mouse.getX(), mouse.getY()); final int if1DraggedItemIndex = client.getIf1DraggedItemIndex(); final WidgetItem draggedItem = inventoryWidget.getWidgetItem(if1DraggedItemIndex); - final int itemId = draggedItem.getId(); final Rectangle initialBounds = draggedItem.getCanvasBounds(); if (initialMousePoint == null) @@ -92,7 +91,7 @@ class InventoryGridOverlay extends Overlay initialMousePoint = mousePoint; } - if (itemId == -1 || !hoverActive && initialMousePoint.distance(mousePoint) < DISTANCE_TO_ACTIVATE_HOVER) + if (draggedItem.getId() == -1 || !hoverActive && initialMousePoint.distance(mousePoint) < DISTANCE_TO_ACTIVATE_HOVER) { return null; } @@ -101,16 +100,15 @@ class InventoryGridOverlay extends Overlay for (int i = 0; i < INVENTORY_SIZE; ++i) { - WidgetItem widgetItem = inventoryWidget.getWidgetItem(i); - final int targetItemId = widgetItem.getId(); + WidgetItem targetWidgetItem = inventoryWidget.getWidgetItem(i); - final Rectangle bounds = widgetItem.getCanvasBounds(); + final Rectangle bounds = targetWidgetItem.getCanvasBounds(); boolean inBounds = bounds.contains(mousePoint); if (plugin.isShowItem() && inBounds) { - drawItem(graphics, bounds, itemId); - drawItem(graphics, initialBounds, targetItemId); + drawItem(graphics, bounds, draggedItem); + drawItem(graphics, initialBounds, targetWidgetItem); } if (plugin.isShowHighlight() && inBounds) @@ -128,14 +126,14 @@ class InventoryGridOverlay extends Overlay return null; } - private void drawItem(Graphics2D graphics, Rectangle bounds, int itemId) + private void drawItem(Graphics2D graphics, Rectangle bounds, WidgetItem item) { - if (itemId == -1) + if (item.getId() == -1) { return; } - final BufferedImage draggedItemImage = itemManager.getImage(itemId); + final BufferedImage draggedItemImage = itemManager.getImage(item.getId(), item.getQuantity(), false); final int x = (int) bounds.getX(); final int y = (int) bounds.getY(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingPlugin.java index b440ff879c..1a851a7aa8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingPlugin.java @@ -34,7 +34,6 @@ import lombok.Getter; import lombok.Setter; import net.runelite.api.Client; import net.runelite.api.GameState; -import net.runelite.api.IconID; import net.runelite.api.VarClientInt; import net.runelite.api.VarClientStr; import net.runelite.api.Varbits; @@ -212,7 +211,7 @@ public class KeyRemappingPlugin extends Plugin Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT); if (chatboxInput != null && chatboxInput.getText().endsWith(PRESS_ENTER_TO_CHAT)) { - chatboxInput.setText(getWaitingText()); + setChatboxWidgetInput(chatboxInput, PRESS_ENTER_TO_CHAT); } } ); @@ -227,7 +226,7 @@ public class KeyRemappingPlugin extends Plugin Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT); if (chatboxInput != null && chatboxFocused() && !typing) { - chatboxInput.setText(getWaitingText()); + setChatboxWidgetInput(chatboxInput, PRESS_ENTER_TO_CHAT); } break; case SCRIPT_EVENT_BLOCK_CHAT_INPUT: @@ -246,7 +245,7 @@ public class KeyRemappingPlugin extends Plugin Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT); if (chatboxInput != null) { - chatboxInput.setText(getWaitingText()); + setChatboxWidgetInput(chatboxInput, PRESS_ENTER_TO_CHAT); } } @@ -257,39 +256,24 @@ public class KeyRemappingPlugin extends Plugin { final boolean isChatboxTransparent = client.isResized() && client.getVar(Varbits.TRANSPARENT_CHATBOX) == 1; final Color textColor = isChatboxTransparent ? JagexColors.CHAT_TYPED_TEXT_TRANSPARENT_BACKGROUND : JagexColors.CHAT_TYPED_TEXT_OPAQUE_BACKGROUND; - chatboxInput.setText(getPlayerNameWithIcon() + ": " + ColorUtil.wrapWithColorTag(client.getVar(VarClientStr.CHATBOX_TYPED_TEXT) + "*", textColor)); + setChatboxWidgetInput(chatboxInput, ColorUtil.wrapWithColorTag(client.getVar(VarClientStr.CHATBOX_TYPED_TEXT) + "*", textColor)); } } - private String getPlayerNameWithIcon() - { - IconID icon; - switch (client.getAccountType()) - { - case IRONMAN: - icon = IconID.IRONMAN; - break; - case ULTIMATE_IRONMAN: - icon = IconID.ULTIMATE_IRONMAN; - break; - case HARDCORE_IRONMAN: - icon = IconID.HARDCORE_IRONMAN; - break; - default: - return client.getLocalPlayer().getName(); - } - return icon + client.getLocalPlayer().getName(); - } - - private String getWaitingText() + private void setChatboxWidgetInput(Widget widget, String input) { if (this.hideDisplayName) { - return PRESS_ENTER_TO_CHAT; + widget.setText(input); + return; } - else + + String text = widget.getText(); + int idx = text.indexOf(':'); + if (idx != -1) { - return getPlayerNameWithIcon() + ": " + PRESS_ENTER_TO_CHAT; + String newText = text.substring(0, idx) + ": " + input; + widget.setText(newText); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/leaguechaticons/LeagueChatIconsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/leaguechaticons/LeagueChatIconsPlugin.java new file mode 100644 index 0000000000..09619f86ad --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/leaguechaticons/LeagueChatIconsPlugin.java @@ -0,0 +1,349 @@ +/* + * Copyright (c) 2019, hsamoht + * Copyright (c) 2019, Adam + * 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.leaguechaticons; + +import java.awt.image.BufferedImage; +import java.util.Arrays; +import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.ChatPlayer; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.api.IconID; +import net.runelite.api.IndexedSprite; +import net.runelite.api.MessageNode; +import net.runelite.api.Player; +import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.ScriptCallbackEvent; +import net.runelite.api.util.Text; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.callback.ClientThread; +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.game.WorldService; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.util.ImageUtil; +import net.runelite.http.api.worlds.World; +import net.runelite.http.api.worlds.WorldResult; +import net.runelite.http.api.worlds.WorldType; + +@PluginDescriptor( + name = "Chat League Icons", + description = "Changes the chat icon for players on league worlds", + enabledByDefault = false +) +@Slf4j +public class LeagueChatIconsPlugin extends Plugin +{ + private static final String SCRIPT_EVENT_SET_CHATBOX_INPUT = "setChatboxInput"; + private static final String IRONMAN_PREFIX = ""; + + @Inject + private Client client; + + @Inject + private ChatMessageManager chatMessageManager; + + @Inject + private WorldService worldService; + + @Inject + private ClientThread clientThread; + + private int leagueIconOffset = -1; // offset for league icon + private boolean onLeagueWorld; + + @Override + protected void startUp() + { + onLeagueWorld = false; + + clientThread.invoke(() -> + { + if (client.getGameState() == GameState.LOGGED_IN) + { + loadLeagueIcon(); + onLeagueWorld = isLeagueWorld(client.getWorld()); + if (onLeagueWorld) + { + setChatboxName(getNameChatbox()); + } + } + }); + } + + @Override + protected void shutDown() + { + clientThread.invoke(() -> + { + if (client.getGameState() == GameState.LOGGED_IN && onLeagueWorld) + { + setChatboxName(getNameDefault()); + } + }); + } + + @Subscribe + private void onGameStateChanged(GameStateChanged gameStateChanged) + { + if (gameStateChanged.getGameState() == GameState.LOGGED_IN) + { + loadLeagueIcon(); + onLeagueWorld = isLeagueWorld(client.getWorld()); + } + } + + @Subscribe + private void onScriptCallbackEvent(ScriptCallbackEvent scriptCallbackEvent) + { + if (scriptCallbackEvent.getEventName().equals(SCRIPT_EVENT_SET_CHATBOX_INPUT) && onLeagueWorld) + { + setChatboxName(getNameChatbox()); + } + } + + @Subscribe + private void onChatMessage(ChatMessage chatMessage) + { + if (client.getGameState() != GameState.LOADING && client.getGameState() != GameState.LOGGED_IN) + { + return; + } + + switch (chatMessage.getType()) + { + case PRIVATECHAT: + case MODPRIVATECHAT: + // Note this is unable to change icon on PMs if they are not a friend or in clan chat + case FRIENDSCHAT: + String name = Text.removeTags(chatMessage.getName()); + if (isChatPlayerOnLeague(name)) + { + addLeagueIconToMessage(chatMessage); + } + break; + case PUBLICCHAT: + case MODCHAT: + if (onLeagueWorld) + { + addLeagueIconToMessage(chatMessage); + } + break; + } + } + + /** + * Adds the League Icon in front of player names chatting from a league world. + * + * @param chatMessage chat message to edit sender name on + */ + private void addLeagueIconToMessage(ChatMessage chatMessage) + { + String name = chatMessage.getName(); + if (!name.startsWith(IRONMAN_PREFIX)) + { + // don't replace non-ironman icons, like mods + return; + } + + name = Text.removeTags(name); + + final MessageNode messageNode = chatMessage.getMessageNode(); + messageNode.setName(getNameWithIcon(leagueIconOffset, name)); + + chatMessageManager.update(messageNode); + client.refreshChat(); + } + + /** + * Update the player name in the chatbox input + */ + private void setChatboxName(String name) + { + Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT); + if (chatboxInput != null) + { + String text = chatboxInput.getText(); + int idx = text.indexOf(':'); + if (idx != -1) + { + String newText = name + text.substring(idx); + chatboxInput.setText(newText); + } + } + } + + /** + * Gets the league name, including possible icon, of the local player. + * + * @return String of icon + name + */ + private String getNameChatbox() + { + Player player = client.getLocalPlayer(); + if (player != null) + { + return getNameWithIcon(leagueIconOffset, player.getName()); + } + return null; + } + + /** + * Gets the default name, including possible icon, of the local player. + * + * @return String of icon + name + */ + private String getNameDefault() + { + Player player = client.getLocalPlayer(); + if (player == null) + { + return null; + } + + int iconIndex; + switch (client.getAccountType()) + { + case IRONMAN: + iconIndex = IconID.IRONMAN.getIndex(); + break; + case HARDCORE_IRONMAN: + iconIndex = IconID.HARDCORE_IRONMAN.getIndex(); + break; + case ULTIMATE_IRONMAN: + iconIndex = IconID.ULTIMATE_IRONMAN.getIndex(); + break; + default: + return player.getName(); + } + + return getNameWithIcon(iconIndex, player.getName()); + } + + /** + * Get a name formatted with icon + * + * @param iconIndex index of the icon + * @param name name of the player + * @return String of icon + name + */ + private static String getNameWithIcon(int iconIndex, String name) + { + String icon = ""; + return icon + name; + } + + /** + * Checks if a player name is a friend or clan member on a league world. + * + * @param name name of player to check. + * @return boolean true/false. + */ + private boolean isChatPlayerOnLeague(String name) + { + ChatPlayer player = getChatPlayerFromName(name); + + if (player == null) + { + return false; + } + + int world = player.getWorld(); + return isLeagueWorld(world); + } + + /** + * Checks if the world is a League world. + * + * @param worldNumber number of the world to check. + * @return boolean true/false if it is a league world or not. + */ + private boolean isLeagueWorld(int worldNumber) + { + WorldResult worlds = worldService.getWorlds(); + if (worlds == null) + { + return false; + } + + World world = worlds.findWorld(worldNumber); + return world != null && world.getTypes().contains(WorldType.LEAGUE); + } + + /** + * Loads the league icon into the client. + */ + private void loadLeagueIcon() + { + final IndexedSprite[] modIcons = client.getModIcons(); + + if (leagueIconOffset != -1 || modIcons == null) + { + return; + } + + BufferedImage image = ImageUtil.getResourceStreamFromClass(getClass(), "league_icon.png"); + IndexedSprite indexedSprite = ImageUtil.getImageIndexedSprite(image, client); + + leagueIconOffset = modIcons.length; + + final IndexedSprite[] newModIcons = Arrays.copyOf(modIcons, modIcons.length + 1); + newModIcons[newModIcons.length - 1] = indexedSprite; + + client.setModIcons(newModIcons); + } + + /** + * Gets a ChatPlayer object from a clean name by searching clan and friends list. + * + * @param name name of player to find. + * @return ChatPlayer if found, else null. + */ + private ChatPlayer getChatPlayerFromName(String name) + { + if (client.isClanMember(name)) + { + return Arrays.stream(client.getClanMembers()) + .filter(clanMember -> Text.removeTags(clanMember.getUsername()).equals(name)) + .findFirst() + .orElse(null); + } + + if (client.isFriended(name, true)) + { + return Arrays.stream(client.getFriends()) + .filter(friend -> Text.removeTags(friend.getName()).equals(name)) + .findFirst() + .orElse(null); + } + + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerConfig.java index 5577ed3ea2..ac1290381a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerConfig.java @@ -105,7 +105,7 @@ public interface LootTrackerConfig extends Config @ConfigItem( keyName = "syncPanel", name = "Synchronize panel contents", - description = "Synchronize you local loot tracker with your online (requires being logged in). This means" + + description = "Synchronize your local loot tracker with your online (requires being logged in). This means" + " that panel is filled with portion of your remote data on startup and deleting data in panel deletes them" + " also on server." ) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/music/MusicPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/music/MusicPlugin.java index d2d9792e5a..7ee6ca418f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/music/MusicPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/music/MusicPlugin.java @@ -25,10 +25,12 @@ */ package net.runelite.client.plugins.music; +import com.google.common.collect.ImmutableSet; import com.google.inject.Provides; import java.util.Arrays; import java.util.Collection; import java.util.Comparator; +import java.util.Set; import java.util.function.BiConsumer; import java.util.function.ToIntFunction; import java.util.stream.Collectors; @@ -76,6 +78,10 @@ import net.runelite.client.plugins.PluginDescriptor; ) public class MusicPlugin extends Plugin { + private static final Set SOURCELESS_PLAYER_SOUNDS = ImmutableSet.of( + SoundEffectID.TELEPORT_VWOOP + ); + @Inject private Client client; @@ -559,13 +565,14 @@ public class MusicPlugin extends Plugin private void onAreaSoundEffectPlayed(AreaSoundEffectPlayed areaSoundEffectPlayed) { Actor source = areaSoundEffectPlayed.getSource(); + int soundId = areaSoundEffectPlayed.getSoundId(); if (source == client.getLocalPlayer() && musicConfig.muteOwnAreaSounds()) { areaSoundEffectPlayed.consume(); } else if (source != client.getLocalPlayer() - && source instanceof Player + && (source instanceof Player || (source == null && SOURCELESS_PLAYER_SOUNDS.contains(soundId))) && musicConfig.muteOtherAreaSounds()) { areaSoundEffectPlayed.consume(); @@ -576,9 +583,10 @@ public class MusicPlugin extends Plugin areaSoundEffectPlayed.consume(); } else if (source == null + && !SOURCELESS_PLAYER_SOUNDS.contains(soundId) && musicConfig.muteEnvironmentAreaSounds()) { areaSoundEffectPlayed.consume(); } } -} \ No newline at end of file +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java index 8e6959bbca..b5f5483888 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java @@ -45,7 +45,6 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; -import static net.runelite.api.Constants.REGION_SIZE; import net.runelite.api.DecorativeObject; import net.runelite.api.GameObject; import net.runelite.api.GameState; @@ -350,8 +349,8 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener for (ObjectPoint objectPoint : objectPoints) { - if ((worldPoint.getX() & (REGION_SIZE - 1)) == objectPoint.getRegionX() - && (worldPoint.getY() & (REGION_SIZE - 1)) == objectPoint.getRegionY()) + if (worldPoint.getRegionX() == objectPoint.getRegionX() + && worldPoint.getRegionY() == objectPoint.getRegionY()) { // Transform object to get the name which matches against what we've stored if (objectPoint.getName().equals(getObjectDefinition(object.getId()).getName())) @@ -446,18 +445,27 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener } final int regionId = worldPoint.getRegionID(); final ObjectPoint point = new ObjectPoint( + object.getId(), name, regionId, - worldPoint.getX() & (REGION_SIZE - 1), - worldPoint.getY() & (REGION_SIZE - 1), + worldPoint.getRegionX(), + worldPoint.getRegionY(), client.getPlane()); Set objectPoints = points.computeIfAbsent(regionId, k -> new HashSet<>()); - if (objectPoints.contains(point)) + if (objects.remove(object)) { - objectPoints.remove(point); - objects.remove(object); + // Use object id instead of name to match the object point with this object due to the object name being + // able to change because of multilocs. + if (!objectPoints.removeIf(op -> (op.getId() == -1 || op.getId() == object.getId()) + && op.getRegionX() == worldPoint.getRegionX() + && op.getRegionY() == worldPoint.getRegionY() + && op.getZ() == worldPoint.getPlane())) + { + log.warn("unable to find object point for unmarked object {}", object.getId()); + } + log.debug("Unmarking object: {}", point); } else diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectPoint.java b/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectPoint.java index 576f0e7c72..ca8786faa3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectPoint.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectPoint.java @@ -25,11 +25,16 @@ package net.runelite.client.plugins.objectindicators; -import lombok.Value; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; -@Value +@Data +@NoArgsConstructor +@AllArgsConstructor class ObjectPoint { + private int id = -1; private String name; private int regionId; private int regionX; 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 72d584adf3..60003ba543 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 @@ -33,7 +33,7 @@ import lombok.Getter; import net.runelite.client.plugins.raids.solver.Layout; import net.runelite.client.plugins.raids.solver.Room; -public class Raid +class Raid { @Getter(AccessLevel.PACKAGE) private final RaidRoom[] rooms = new RaidRoom[16]; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TeleportWidget.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TeleportWidget.java index 3cb6a7ef3e..1c7beb0c8b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TeleportWidget.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TeleportWidget.java @@ -38,7 +38,8 @@ enum TeleportWidget WidgetInfo.SPELL_LUMBRIDGE_HOME_TELEPORT.getId(), WidgetInfo.SPELL_EDGEVILLE_HOME_TELEPORT.getId(), WidgetInfo.SPELL_LUNAR_HOME_TELEPORT.getId(), - WidgetInfo.SPELL_ARCEUUS_HOME_TELEPORT.getId() + WidgetInfo.SPELL_ARCEUUS_HOME_TELEPORT.getId(), + WidgetInfo.SPELL_KOUREND_HOME_TELEPORT.getId() ); private static final Collection MINIGAME_TELEPORT_IDS = ImmutableList.of( WidgetInfo.MINIGAME_TELEPORT_BUTTON.getId() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java index dfb670ac5a..b20ee110f8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java @@ -25,23 +25,27 @@ package net.runelite.client.plugins.woodcutting; import com.google.common.collect.ImmutableMap; +import java.time.Duration; import java.util.Map; -import lombok.AccessLevel; +import javax.annotation.Nullable; import lombok.Getter; -import static net.runelite.api.ObjectID.REDWOOD; -import static net.runelite.api.ObjectID.REDWOOD_29670; +import static net.runelite.api.NullObjectID.NULL_10823; +import static net.runelite.api.NullObjectID.NULL_10835; +import net.runelite.api.ObjectID; +import static net.runelite.api.ObjectID.*; -@Getter(AccessLevel.PACKAGE) +@Getter enum Tree { - REDWOOD_TREE_SPAWN(REDWOOD, REDWOOD_29670); - - private final int[] treeIds; - - Tree(final int... treeIds) - { - this.treeIds = treeIds; - } + REGULAR_TREE(null, TREE, TREE_1277, TREE_1278, TREE_1279, TREE_1280), + OAK_TREE(Duration.ofMillis(8500), ObjectID.OAK_TREE, OAK_TREE_4540, OAK_10820), + WILLOW_TREE(Duration.ofMillis(8500), WILLOW, WILLOW_10833, WILLOW_10831), + MAPLE_TREE(Duration.ofSeconds(35), ObjectID.MAPLE_TREE, MAPLE_TREE_10832, MAPLE_TREE_36681), + TEAK_TREE(Duration.ofMillis(8500), TEAK, TEAK_36686), + MAHOGANY_TREE(Duration.ofMillis(8500), MAHOGANY, MAHOGANY_36688), + YEW_TREE(Duration.ofMinutes(1), YEW, NULL_10823, YEW_36683), + MAGIC_TREE(Duration.ofMinutes(2), MAGIC_TREE_10834, NULL_10835), + REDWOOD(Duration.ofMinutes(2), ObjectID.REDWOOD, REDWOOD_29670); private static final Map TREES; @@ -60,6 +64,16 @@ enum Tree TREES = builder.build(); } + @Nullable + private final Duration respawnTime; + private final int[] treeIds; + + Tree(@org.jetbrains.annotations.Nullable Duration respawnTime, int... treeIds) + { + this.respawnTime = respawnTime; + this.treeIds = treeIds; + } + static Tree findTree(int objectId) { return TREES.get(objectId); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/TreeRespawn.java b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/TreeRespawn.java new file mode 100644 index 0000000000..a3022ca8f3 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/TreeRespawn.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019, Adam + * Copyright (c) 2019, David + * 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.woodcutting; + +import java.time.Instant; +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.runelite.api.coords.LocalPoint; + +@AllArgsConstructor +@Getter +class TreeRespawn +{ + private final Tree tree; + private final LocalPoint location; + private final Instant startTime; + private final int respawnTime; + + boolean isExpired() + { + return Instant.now().isAfter(startTime.plusMillis(respawnTime)); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingConfig.java index 4c58fe4369..74c1f50830 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingConfig.java @@ -85,4 +85,15 @@ public interface WoodcuttingConfig extends Config { return false; } + + @ConfigItem( + position = 6, + keyName = "showRespawnTimers", + name = "Show respawn timers", + description = "Configures whether to display the respawn timer overlay" + ) + default boolean showRespawnTimers() + { + return true; + } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingOverlay.java index b5c14fec6f..d01629003f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingOverlay.java @@ -43,7 +43,6 @@ import net.runelite.client.ui.overlay.components.TitleComponent; import net.runelite.client.ui.overlay.components.table.TableAlignment; import net.runelite.client.ui.overlay.components.table.TableComponent; - @Singleton class WoodcuttingOverlay extends Overlay { @@ -51,17 +50,18 @@ class WoodcuttingOverlay extends Overlay private final Client client; private final WoodcuttingPlugin plugin; + private final WoodcuttingConfig config; private final XpTrackerService xpTrackerService; private final PanelComponent panelComponent = new PanelComponent(); - @Inject - private WoodcuttingOverlay(final Client client, final WoodcuttingPlugin plugin, final XpTrackerService xpTrackerService) + private WoodcuttingOverlay(Client client, WoodcuttingPlugin plugin, WoodcuttingConfig config, XpTrackerService xpTrackerService) { super(plugin); setPosition(OverlayPosition.TOP_LEFT); this.client = client; this.plugin = plugin; + this.config = config; this.xpTrackerService = xpTrackerService; getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Woodcutting overlay")); getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY, WOODCUTTING_RESET, "Woodcutting overlay")); @@ -70,7 +70,7 @@ class WoodcuttingOverlay extends Overlay @Override public Dimension render(Graphics2D graphics) { - if (!plugin.isShowWoodcuttingStats()) + if (!config.showWoodcuttingStats()) { return null; } @@ -107,7 +107,7 @@ class WoodcuttingOverlay extends Overlay { tableComponent.addRow("Logs cut:", Integer.toString(actions)); - if (plugin.isShowGPEarned()) + if (config.showGPEarned()) { tableComponent.addRow("GP earned:", Integer.toString((plugin.getGpEarned()))); } @@ -123,5 +123,4 @@ class WoodcuttingOverlay extends Overlay return panelComponent.render(graphics); } - } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingPlugin.java index 3492d21c79..1ae325f534 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingPlugin.java @@ -27,17 +27,18 @@ package net.runelite.client.plugins.woodcutting; import com.google.inject.Provides; import java.time.Duration; import java.time.Instant; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import java.util.Set; import java.util.regex.Pattern; import javax.inject.Inject; -import javax.inject.Singleton; import lombok.AccessLevel; import lombok.Getter; +import lombok.extern.slf4j.Slf4j; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.GameObject; -import net.runelite.api.GameState; import net.runelite.api.ItemID; import net.runelite.api.MenuOpcode; import net.runelite.api.Player; @@ -51,7 +52,6 @@ import net.runelite.api.events.GameTick; import net.runelite.client.Notifier; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.events.ConfigChanged; import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; @@ -64,14 +64,21 @@ import net.runelite.client.ui.overlay.OverlayMenuEntry; @PluginDescriptor( name = "Woodcutting", description = "Show woodcutting statistics and/or bird nest notifications", - tags = {"birds", "nest", "notifications", "overlay", "skilling", "wc"} + tags = {"birds", "nest", "notifications", "overlay", "skilling", "wc"}, + enabledByDefault = false ) -@Singleton @PluginDependency(XpTrackerPlugin.class) +@Slf4j public class WoodcuttingPlugin extends Plugin { private static final Pattern WOOD_CUT_PATTERN = Pattern.compile("You get (?:some|an)[\\w ]+(?:logs?|mushrooms)\\."); + @Getter + private final Set treeObjects = new HashSet<>(); + + @Getter(AccessLevel.PACKAGE) + private final List respawns = new ArrayList<>(); + @Inject private Notifier notifier; @@ -93,24 +100,13 @@ public class WoodcuttingPlugin extends Plugin @Inject private ItemManager itemManager; - @Getter(AccessLevel.PACKAGE) + @Getter private WoodcuttingSession session; - @Getter(AccessLevel.PACKAGE) + @Getter private Axe axe; - @Getter(AccessLevel.PACKAGE) - private final Set treeObjects = new HashSet<>(); - - private int statTimeout; - boolean showNestNotification; - @Getter(AccessLevel.PACKAGE) - private boolean showWoodcuttingStats; - @Getter(AccessLevel.PACKAGE) - private boolean showRedwoodTrees; - @Getter(AccessLevel.PACKAGE) - private boolean showGPEarned; - + private boolean recentlyLoggedIn; private int treeTypeID; @Getter(AccessLevel.PACKAGE) private int gpEarned; @@ -122,19 +118,18 @@ public class WoodcuttingPlugin extends Plugin } @Override - protected void startUp() + protected void startUp() throws Exception { - updateConfig(); - overlayManager.add(overlay); overlayManager.add(treesOverlay); } @Override - protected void shutDown() + protected void shutDown() throws Exception { overlayManager.remove(overlay); overlayManager.remove(treesOverlay); + respawns.clear(); treeObjects.clear(); session = null; axe = null; @@ -155,12 +150,16 @@ public class WoodcuttingPlugin extends Plugin @Subscribe private void onGameTick(GameTick gameTick) { + recentlyLoggedIn = false; + + respawns.removeIf(TreeRespawn::isExpired); + if (session == null || session.getLastLogCut() == null) { return; } - Duration statTimeout = Duration.ofMinutes(this.statTimeout); + Duration statTimeout = Duration.ofMinutes(config.statTimeout()); Duration sinceCut = Duration.between(session.getLastLogCut(), Instant.now()); if (sinceCut.compareTo(statTimeout) >= 0) @@ -189,13 +188,90 @@ public class WoodcuttingPlugin extends Plugin gpEarned += itemManager.getItemPrice(treeTypeID); } - if (event.getMessage().contains("A bird's nest falls out of the tree") && this.showNestNotification) + if (event.getMessage().contains("A bird's nest falls out of the tree") && config.showNestNotification()) { notifier.notify("A bird nest has spawned!"); } } } + @Subscribe + private void onGameObjectSpawned(final GameObjectSpawned event) + { + GameObject gameObject = event.getGameObject(); + Tree tree = Tree.findTree(gameObject.getId()); + + if (tree == Tree.REDWOOD) + { + treeObjects.add(gameObject); + } + } + + @Subscribe + private void onGameObjectDespawned(final GameObjectDespawned event) + { + final GameObject object = event.getGameObject(); + + Tree tree = Tree.findTree(object.getId()); + if (tree != null) + { + if (tree.getRespawnTime() != null && !recentlyLoggedIn) + { + log.debug("Adding respawn timer for {} tree at {}", tree, object.getLocalLocation()); + TreeRespawn treeRespawn = new TreeRespawn(tree, object.getLocalLocation(), Instant.now(), (int) tree.getRespawnTime().toMillis()); + respawns.add(treeRespawn); + } + + if (tree == Tree.REDWOOD) + { + treeObjects.remove(event.getGameObject()); + } + } + } + + @Subscribe + private void onGameObjectChanged(final GameObjectChanged event) + { + treeObjects.remove(event.getGameObject()); + } + + @Subscribe + private void onGameStateChanged(final GameStateChanged event) + { + switch (event.getGameState()) + { + case LOADING: + case HOPPING: + respawns.clear(); + treeObjects.clear(); + break; + case LOGGED_IN: + // After login trees that are depleted will be changed, + // wait for the next game tick before watching for + // trees to despawn + recentlyLoggedIn = true; + break; + } + } + + @Subscribe + private void onAnimationChanged(final AnimationChanged event) + { + Player local = client.getLocalPlayer(); + + if (event.getActor() != local) + { + return; + } + + int animId = local.getAnimation(); + Axe axe = Axe.findAxeByAnimId(animId); + if (axe != null) + { + this.axe = axe; + } + } + private void typeOfLogCut(String message) { if (message.contains("mushrooms.")) @@ -239,75 +315,4 @@ public class WoodcuttingPlugin extends Plugin treeTypeID = ItemID.LOGS; } } - - @Subscribe - private void onGameObjectSpawned(final GameObjectSpawned event) - { - GameObject gameObject = event.getGameObject(); - Tree tree = Tree.findTree(gameObject.getId()); - - if (tree != null) - { - treeObjects.add(gameObject); - } - } - - @Subscribe - private void onGameObjectDespawned(final GameObjectDespawned event) - { - treeObjects.remove(event.getGameObject()); - } - - @Subscribe - private void onGameObjectChanged(final GameObjectChanged event) - { - treeObjects.remove(event.getGameObject()); - } - - @Subscribe - private void onGameStateChanged(final GameStateChanged event) - { - if (event.getGameState() != GameState.LOGGED_IN) - { - treeObjects.clear(); - } - } - - @Subscribe - private void onAnimationChanged(final AnimationChanged event) - { - Player local = client.getLocalPlayer(); - - if (event.getActor() != local) - { - return; - } - - int animId = local.getAnimation(); - Axe axe = Axe.findAxeByAnimId(animId); - if (axe != null) - { - this.axe = axe; - } - } - - @Subscribe - private void onConfigChanged(ConfigChanged event) - { - if (!event.getGroup().equals("woodcutting")) - { - return; - } - - updateConfig(); - } - - private void updateConfig() - { - this.statTimeout = config.statTimeout(); - this.showNestNotification = config.showNestNotification(); - this.showWoodcuttingStats = config.showWoodcuttingStats(); - this.showRedwoodTrees = config.showRedwoodTrees(); - this.showGPEarned = config.showGPEarned(); - } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingTreesOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingTreesOverlay.java index cf25150169..990e1bc6eb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingTreesOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingTreesOverlay.java @@ -1,6 +1,7 @@ /* * Copyright (c) 2018, Tomas Slusny * Copyright (c) 2018, Adam + * Copyright (c) 2019, David * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,29 +26,36 @@ */ package net.runelite.client.plugins.woodcutting; +import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; +import java.time.Instant; +import java.util.List; import javax.inject.Inject; -import javax.inject.Singleton; import net.runelite.api.Client; import net.runelite.api.GameObject; +import net.runelite.api.Perspective; +import net.runelite.api.Point; +import net.runelite.api.coords.LocalPoint; import net.runelite.client.game.ItemManager; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayUtil; +import net.runelite.client.ui.overlay.components.ProgressPieComponent; -@Singleton class WoodcuttingTreesOverlay extends Overlay { private final Client client; + private final WoodcuttingConfig config; private final ItemManager itemManager; private final WoodcuttingPlugin plugin; @Inject - private WoodcuttingTreesOverlay(final Client client, final ItemManager itemManager, final WoodcuttingPlugin plugin) + private WoodcuttingTreesOverlay(final Client client, final WoodcuttingConfig config, final ItemManager itemManager, final WoodcuttingPlugin plugin) { this.client = client; + this.config = config; this.itemManager = itemManager; this.plugin = plugin; setLayer(OverlayLayer.ABOVE_SCENE); @@ -57,15 +65,22 @@ class WoodcuttingTreesOverlay extends Overlay @Override public Dimension render(Graphics2D graphics) { - if (plugin.getSession() == null || !plugin.isShowRedwoodTrees()) + renderAxes(graphics); + renderTimers(graphics); + return null; + } + + private void renderAxes(Graphics2D graphics) + { + if (plugin.getSession() == null || !config.showRedwoodTrees()) { - return null; + return; } Axe axe = plugin.getAxe(); if (axe == null) { - return null; + return; } for (GameObject treeObject : plugin.getTreeObjects()) @@ -75,7 +90,34 @@ class WoodcuttingTreesOverlay extends Overlay OverlayUtil.renderImageLocation(client, graphics, treeObject.getLocalLocation(), itemManager.getImage(axe.getItemId()), 120); } } - - return null; } -} + + private void renderTimers(Graphics2D graphics) + { + List respawns = plugin.getRespawns(); + if (respawns.isEmpty() || !config.showRespawnTimers()) + { + return; + } + + Instant now = Instant.now(); + for (TreeRespawn treeRespawn : respawns) + { + LocalPoint loc = treeRespawn.getLocation(); + + float percent = (now.toEpochMilli() - treeRespawn.getStartTime().toEpochMilli()) / (float) treeRespawn.getRespawnTime(); + Point point = Perspective.localToCanvas(client, loc, client.getPlane()); + if (point == null || percent > 1.0f) + { + continue; + } + + ProgressPieComponent ppc = new ProgressPieComponent(); + ppc.setBorderColor(Color.ORANGE); + ppc.setFill(Color.YELLOW); + ppc.setPosition(point); + ppc.setProgress(percent); + ppc.render(graphics); + } + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java index 6360162fff..da300820ac 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java @@ -30,11 +30,9 @@ import com.google.common.base.Stopwatch; import com.google.common.collect.ImmutableList; import com.google.common.collect.ObjectArrays; import com.google.inject.Provides; -import io.reactivex.schedulers.Schedulers; import java.awt.image.BufferedImage; import java.time.Duration; import java.time.Instant; -import java.util.Comparator; import java.util.EnumSet; import java.util.HashMap; import java.util.List; @@ -75,6 +73,8 @@ import net.runelite.client.config.ConfigManager; import net.runelite.client.config.Keybind; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ConfigChanged; +import net.runelite.client.events.WorldsFetch; +import net.runelite.client.game.WorldService; import net.runelite.client.input.KeyManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -87,7 +87,6 @@ import net.runelite.client.util.ImageUtil; import net.runelite.client.util.WorldUtil; import net.runelite.client.util.ping.Ping; import net.runelite.http.api.worlds.World; -import net.runelite.http.api.worlds.WorldClient; import net.runelite.http.api.worlds.WorldResult; import net.runelite.http.api.worlds.WorldType; import org.apache.commons.lang3.ArrayUtils; @@ -126,9 +125,6 @@ public class WorldHopperPlugin extends Plugin @Inject private ChatMessageManager chatMessageManager; - @Inject - private ScheduledExecutorService executorService; - @Inject private WorldHopperConfig config; @@ -139,7 +135,7 @@ public class WorldHopperPlugin extends Plugin private WorldHopperPingOverlay worldHopperOverlay; @Inject - private WorldClient worldClient; + private WorldService worldService; private ScheduledExecutorService hopperExecutorService; @@ -154,11 +150,9 @@ public class WorldHopperPlugin extends Plugin private int favoriteWorld1, favoriteWorld2; - private ScheduledFuture worldResultFuture, pingFuture, currPingFuture; - private WorldResult worldResult; + private ScheduledFuture pingFuture, currPingFuture; private int currentWorld; private Instant lastFetch; - private boolean firstRun; private Keybind previousKey; private Keybind nextKey; @@ -203,7 +197,6 @@ public class WorldHopperPlugin extends Plugin { updateConfig(); - firstRun = true; currentPing = -1; keyManager.registerKeyListener(previousKeyListener); @@ -231,12 +224,15 @@ public class WorldHopperPlugin extends Plugin // The plugin has its own executor for pings, as it blocks for a long time hopperExecutorService = new ExecutorServiceExceptionLogger(Executors.newSingleThreadScheduledExecutor()); - // On first run this schedules an initial ping on hopperExecutorService - worldResultFuture = executorService.scheduleAtFixedRate(this::tick, 0, WORLD_FETCH_TIMER, TimeUnit.MINUTES); + // Run the first-run ping + hopperExecutorService.execute(this::pingInitialWorlds); // Give some initial delay - this won't run until after pingInitialWorlds finishes from tick() anyway pingFuture = hopperExecutorService.scheduleWithFixedDelay(this::pingNextWorld, 15, 3, TimeUnit.SECONDS); currPingFuture = hopperExecutorService.scheduleWithFixedDelay(this::pingCurrentWorld, 15, 1, TimeUnit.SECONDS); + + // populate initial world list + updateList(); } @Override @@ -253,11 +249,6 @@ public class WorldHopperPlugin extends Plugin keyManager.unregisterKeyListener(previousKeyListener); keyManager.unregisterKeyListener(nextKeyListener); - worldResultFuture.cancel(true); - worldResultFuture = null; - worldResult = null; - lastFetch = null; - clientToolbar.removeNavigation(navButton); hopperExecutorService.shutdown(); @@ -393,6 +384,7 @@ public class WorldHopperPlugin extends Plugin // Don't add entry if user is offline ChatPlayer player = getChatPlayerFromName(event.getTarget()); + WorldResult worldResult = worldService.getWorlds(); if (player == null || player.getWorld() == 0 || player.getWorld() == client.getWorld() || worldResult == null) @@ -484,26 +476,6 @@ public class WorldHopperPlugin extends Plugin this.lastFetch = Instant.now(); // This counts as a fetch as it updates populations } - private void tick() - { - Instant now = Instant.now(); - if (lastFetch != null && now.toEpochMilli() - lastFetch.toEpochMilli() < TICK_THROTTLE) - { - log.debug("Throttling world refresh tick"); - return; - } - - fetchWorlds(); - - // Ping worlds once at startup - if (firstRun) - { - firstRun = false; - // On first run we ping all of the worlds at once to initialize the ping values - hopperExecutorService.execute(this::pingInitialWorlds); - } - } - void refresh() { Instant now = Instant.now(); @@ -513,29 +485,14 @@ public class WorldHopperPlugin extends Plugin return; } - fetchWorlds(); + lastFetch = now; + worldService.refresh(); } - private void fetchWorlds() + @Subscribe + public void onWorldsFetch(WorldsFetch worldsFetch) { - log.debug("Fetching worlds"); - - worldClient.lookupWorlds() - .subscribeOn(Schedulers.io()) - .take(1) - .subscribe( - (worldResult) -> - { - if (worldResult != null) - { - worldResult.getWorlds().sort(Comparator.comparingInt(World::getId)); - this.worldResult = worldResult; - this.lastFetch = Instant.now(); - updateList(); - } - }, - (ex) -> log.warn("Error looking up worlds", ex) - ); + updateList(); } /** @@ -543,11 +500,16 @@ public class WorldHopperPlugin extends Plugin */ private void updateList() { - SwingUtilities.invokeLater(() -> panel.populate(worldResult.getWorlds())); + WorldResult worldResult = worldService.getWorlds(); + if (worldResult != null) + { + SwingUtilities.invokeLater(() -> panel.populate(worldResult.getWorlds())); + } } private void hop(boolean previous) { + WorldResult worldResult = worldService.getWorlds(); if (worldResult == null || client.getGameState() != GameState.LOGGED_IN) { return; @@ -658,6 +620,7 @@ public class WorldHopperPlugin extends Plugin private void hop(int worldId) { + WorldResult worldResult = worldService.getWorlds(); // Don't try to hop if the world doesn't exist World world = worldResult.findWorld(worldId); if (world == null) @@ -801,6 +764,7 @@ public class WorldHopperPlugin extends Plugin */ private void pingInitialWorlds() { + WorldResult worldResult = worldService.getWorlds(); if (worldResult == null || !this.showSidebar || !this.ping) { return; @@ -838,6 +802,7 @@ public class WorldHopperPlugin extends Plugin */ private void pingNextWorld() { + WorldResult worldResult = worldService.getWorlds(); if (worldResult == null || !this.showSidebar || !this.ping) { return; @@ -874,6 +839,7 @@ public class WorldHopperPlugin extends Plugin */ private void pingCurrentWorld() { + WorldResult worldResult = worldService.getWorlds(); // There is no reason to ping the current world if not logged in, as the overlay doesn't draw if (worldResult == null || !this.displayPing || client.getGameState() != GameState.LOGGED_IN) { diff --git a/runelite-client/src/main/java/net/runelite/client/rs/ClientConfigLoader.java b/runelite-client/src/main/java/net/runelite/client/rs/ClientConfigLoader.java index d0bd1ebf29..c43a981f3e 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/ClientConfigLoader.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/ClientConfigLoader.java @@ -70,7 +70,8 @@ class ClientConfigLoader supplier = new HostSupplier(); } - url = supplier.get(); + String host = supplier.get(); + url = url.newBuilder().host(host).build(); continue; } diff --git a/runelite-client/src/main/java/net/runelite/client/rs/HostSupplier.java b/runelite-client/src/main/java/net/runelite/client/rs/HostSupplier.java index 2aec1d8505..522173ae74 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/HostSupplier.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/HostSupplier.java @@ -1,6 +1,5 @@ /* * Copyright (c) 2019 Abex - * Copyright (c) 2019, Lucas * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,8 +24,10 @@ */ package net.runelite.client.rs; +import java.io.IOException; import java.util.ArrayDeque; import java.util.Collections; +import java.util.EnumSet; import java.util.List; import java.util.Queue; import java.util.Random; @@ -36,41 +37,46 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.http.api.RuneLiteAPI; 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 net.runelite.http.api.worlds.WorldType; @Slf4j -class HostSupplier implements Supplier +class HostSupplier implements Supplier { - private final Random random = new Random(); - private final Queue hosts = new ArrayDeque<>(); + private final Random random = new Random(System.nanoTime()); + private Queue hosts = new ArrayDeque<>(); @Override - public HttpUrl get() + public String get() { if (!hosts.isEmpty()) { return hosts.poll(); } - List newHosts = new WorldClient(RuneLiteAPI.CLIENT) - .lookupWorlds() - .map(WorldResult::getWorlds) - .blockingSingle() - .stream() - .map(World::getAddress) - .map(HttpUrl::parse) - .collect(Collectors.toList()); + try + { + List newHosts = new WorldClient(RuneLiteAPI.CLIENT) + .lookupWorlds() + .getWorlds() + .stream() + .filter(w -> w.getTypes().isEmpty() || EnumSet.of(WorldType.MEMBERS).equals(w.getTypes())) + .map(World::getAddress) + .collect(Collectors.toList()); - Collections.shuffle(newHosts, random); + Collections.shuffle(newHosts, random); - hosts.addAll(newHosts.subList(0, 16)); + hosts.addAll(newHosts.subList(0, 16)); + } + catch (IOException e) + { + log.warn("Unable to retrieve world list", e); + } while (hosts.size() < 2) { - hosts.add(HttpUrl.parse("oldschool" + (random.nextInt(50) + 1) + ".runescape.COM")); + hosts.add("oldschool" + (random.nextInt(50) + 1) + ".runescape.COM"); } return hosts.poll(); } -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java index c06507e29c..2244ce5b62 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java @@ -1024,9 +1024,9 @@ public class ClientUI setOpacityMethod.invoke(peerField.get(frame), opacity); } - catch (NoSuchFieldException | NoSuchMethodException | ClassNotFoundException | IllegalAccessException | InvocationTargetException e) + catch (NoSuchFieldException | NoSuchMethodException | ClassNotFoundException | IllegalAccessException | InvocationTargetException | NullPointerException e) { - e.printStackTrace(); + // e.printStackTrace(); } }); } diff --git a/runelite-client/src/main/java/net/runelite/client/util/ReflectUtil.java b/runelite-client/src/main/java/net/runelite/client/util/ReflectUtil.java new file mode 100644 index 0000000000..76530b6ab6 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/util/ReflectUtil.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2018, Tomas Slusny + * Copyright (c) 2018, 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.util; + +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class ReflectUtil +{ + private ReflectUtil() + { + } + + public static MethodHandles.Lookup privateLookupIn(Class clazz) + { + try + { + // Java 9+ has privateLookupIn method on MethodHandles, but since we are shipping and using Java 8 + // we need to access it via reflection. This is preferred way because it's Java 9+ public api and is + // likely to not change + final Method privateLookupIn = MethodHandles.class.getMethod("privateLookupIn", Class.class, MethodHandles.Lookup.class); + return (MethodHandles.Lookup) privateLookupIn.invoke(null, clazz, MethodHandles.lookup()); + } + catch (InvocationTargetException | IllegalAccessException e) + { + throw new RuntimeException(e); + } + catch (NoSuchMethodException e) + { + try + { + // In Java 8 we first do standard lookupIn class + final MethodHandles.Lookup lookupIn = MethodHandles.lookup().in(clazz); + + // and then we mark it as trusted for private lookup via reflection on private field + final Field modes = MethodHandles.Lookup.class.getDeclaredField("allowedModes"); + modes.setAccessible(true); + modes.setInt(lookupIn, -1); // -1 == TRUSTED + return lookupIn; + } + catch (ReflectiveOperationException ex) + { + throw new RuntimeException(ex); + } + } + } +} diff --git a/runelite-client/src/main/resources/item_variations.json b/runelite-client/src/main/resources/item_variations.json index 5936aefebb..7d50c546b4 100644 --- a/runelite-client/src/main/resources/item_variations.json +++ b/runelite-client/src/main/resources/item_variations.json @@ -8025,7 +8025,8 @@ ], "rune pouch": [ 12791, - 23650 + 23650, + 24416 ], "nest box": [ 12792, diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/facepalm.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/facepalm.png new file mode 100644 index 0000000000..00c3ddb525 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/facepalm.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/leaguechaticons/league_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/leaguechaticons/league_icon.png new file mode 100644 index 0000000000..41e4487120 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/leaguechaticons/league_icon.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_crafting.json b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_crafting.json index c9c2920899..3df88b7ab5 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_crafting.json +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_crafting.json @@ -48,6 +48,12 @@ "name": "Gold Ring", "xp": 15 }, + { + "level": 5, + "icon": 21512, + "name": "Bird House", + "xp": 15 + }, { "level": 6, "icon": 1654, @@ -120,6 +126,12 @@ "name": "Leather Body", "xp": 25 }, + { + "level": 15, + "icon": 21515, + "name": "Oak Bird House", + "xp": 20 + }, { "level": 16, "icon": 1613, @@ -216,6 +228,12 @@ "name": "Jade Necklace", "xp": 54 }, + { + "level": 25, + "icon": 21518, + "name": "Willow Bird House", + "xp": 25 + }, { "level": 26, "icon": 6209, @@ -318,6 +336,12 @@ "name": "Broodoo shield", "xp": 100 }, + { + "level": 35, + "icon": 21521, + "name": "Teak Bird House", + "xp": 30 + }, { "level": 36, "icon": 5376, @@ -384,6 +408,12 @@ "name": "Snakeskin boots", "xp": 30 }, + { + "level": 45, + "icon": 22192, + "name": "Maple Bird House", + "xp": 35 + }, { "level": 46, "icon": 567, @@ -414,6 +444,12 @@ "name": "Ruby Amulet (U)", "xp": 85 }, + { + "level": 50, + "icon": 22195, + "name": "Mahogany Bird House", + "xp": 40 + }, { "level": 51, "icon": 6324, @@ -480,6 +516,12 @@ "name": "Green D'hide Chaps", "xp": 124 }, + { + "level": 60, + "icon": 22198, + "name": "Yew Bird House", + "xp": 45 + }, { "level": 62, "icon": 1393, @@ -570,6 +612,12 @@ "name": "Red D'hide Chaps", "xp": 156 }, + { + "level": 75, + "icon": 22201, + "name": "Magic Bird House", + "xp": 50 + }, { "level": 76, "icon": 22281, @@ -666,6 +714,12 @@ "name": "Onyx Amulet (U)", "xp": 165 }, + { + "level": 90, + "icon": 22204, + "name": "Redwood Bird House", + "xp": 55 + }, { "level": 92, "icon": 19535, @@ -685,4 +739,4 @@ "xp": 200 } ] -} +} \ No newline at end of file diff --git a/runelite-client/src/main/scripts/FakeXpDrop.hash b/runelite-client/src/main/scripts/FakeXpDrop.hash index cf5e37e931..9eba813f20 100644 --- a/runelite-client/src/main/scripts/FakeXpDrop.hash +++ b/runelite-client/src/main/scripts/FakeXpDrop.hash @@ -1 +1 @@ -32FBC48F8C6D8E62E02BCF09F444BA036F76133B6596396F0AB9E474687D9F3F \ No newline at end of file +C85469C2529D794C523505679F14AA20E988513E8FBAF249E41F4760382B4BBB \ No newline at end of file diff --git a/runelite-client/src/main/scripts/FakeXpDrop.rs2asm b/runelite-client/src/main/scripts/FakeXpDrop.rs2asm index 93ac905034..0f5b817d85 100644 --- a/runelite-client/src/main/scripts/FakeXpDrop.rs2asm +++ b/runelite-client/src/main/scripts/FakeXpDrop.rs2asm @@ -6,9 +6,9 @@ iload 0 ; stat iload 1 ; xp sconst "fakeXpDrop" - runelite_callback - pop_int - pop_int + runelite_callback + pop_int + pop_int iconst 105 iconst 83 iconst 681 @@ -25,7 +25,7 @@ LABEL9: iload 1 movecoord set_varc_int 207 - jump LABEL216 + jump LABEL227 LABEL16: iconst 105 iconst 83 @@ -43,7 +43,7 @@ LABEL25: iload 1 movecoord set_varc_int 208 - jump LABEL216 + jump LABEL227 LABEL32: iconst 105 iconst 83 @@ -61,7 +61,7 @@ LABEL41: iload 1 movecoord set_varc_int 209 - jump LABEL216 + jump LABEL227 LABEL48: iconst 105 iconst 83 @@ -79,7 +79,7 @@ LABEL57: iload 1 movecoord set_varc_int 210 - jump LABEL216 + jump LABEL227 LABEL64: iconst 105 iconst 83 @@ -97,7 +97,7 @@ LABEL73: iload 1 movecoord set_varc_int 211 - jump LABEL216 + jump LABEL227 LABEL80: iconst 105 iconst 83 @@ -115,7 +115,7 @@ LABEL89: iload 1 movecoord set_varc_int 212 - jump LABEL216 + jump LABEL227 LABEL96: iconst 105 iconst 83 @@ -133,13 +133,27 @@ LABEL105: iload 1 movecoord set_varc_int 213 - jump LABEL216 + jump LABEL227 LABEL112: + iload 0 + iconst 3 + if_icmpeq LABEL116 + jump LABEL123 +LABEL116: + iload 1 + iconst 20000001 + if_icmpeq LABEL120 + jump LABEL123 +LABEL120: + iconst 269500481 + set_varc_int 207 + jump LABEL227 +LABEL123: get_varc_int 207 iconst -1 - if_icmpeq LABEL116 - jump LABEL127 -LABEL116: + if_icmpeq LABEL127 + jump LABEL138 +LABEL127: iconst 0 iconst 83 iconst 105 @@ -150,13 +164,13 @@ LABEL116: iload 1 movecoord set_varc_int 207 - jump LABEL216 -LABEL127: + jump LABEL227 +LABEL138: get_varc_int 208 iconst -1 - if_icmpeq LABEL131 - jump LABEL142 -LABEL131: + if_icmpeq LABEL142 + jump LABEL153 +LABEL142: iconst 0 iconst 83 iconst 105 @@ -167,13 +181,13 @@ LABEL131: iload 1 movecoord set_varc_int 208 - jump LABEL216 -LABEL142: + jump LABEL227 +LABEL153: get_varc_int 209 iconst -1 - if_icmpeq LABEL146 - jump LABEL157 -LABEL146: + if_icmpeq LABEL157 + jump LABEL168 +LABEL157: iconst 0 iconst 83 iconst 105 @@ -184,13 +198,13 @@ LABEL146: iload 1 movecoord set_varc_int 209 - jump LABEL216 -LABEL157: + jump LABEL227 +LABEL168: get_varc_int 210 iconst -1 - if_icmpeq LABEL161 - jump LABEL172 -LABEL161: + if_icmpeq LABEL172 + jump LABEL183 +LABEL172: iconst 0 iconst 83 iconst 105 @@ -201,13 +215,13 @@ LABEL161: iload 1 movecoord set_varc_int 210 - jump LABEL216 -LABEL172: + jump LABEL227 +LABEL183: get_varc_int 211 iconst -1 - if_icmpeq LABEL176 - jump LABEL187 -LABEL176: + if_icmpeq LABEL187 + jump LABEL198 +LABEL187: iconst 0 iconst 83 iconst 105 @@ -218,13 +232,13 @@ LABEL176: iload 1 movecoord set_varc_int 211 - jump LABEL216 -LABEL187: + jump LABEL227 +LABEL198: get_varc_int 212 iconst -1 - if_icmpeq LABEL191 - jump LABEL202 -LABEL191: + if_icmpeq LABEL202 + jump LABEL213 +LABEL202: iconst 0 iconst 83 iconst 105 @@ -235,13 +249,13 @@ LABEL191: iload 1 movecoord set_varc_int 212 - jump LABEL216 -LABEL202: + jump LABEL227 +LABEL213: get_varc_int 213 iconst -1 - if_icmpeq LABEL206 - jump LABEL216 -LABEL206: + if_icmpeq LABEL217 + jump LABEL227 +LABEL217: iconst 0 iconst 83 iconst 105 @@ -252,5 +266,5 @@ LABEL206: iload 1 movecoord set_varc_int 213 -LABEL216: +LABEL227: return diff --git a/runelite-client/src/main/scripts/XpDropChanged.hash b/runelite-client/src/main/scripts/XpDropChanged.hash index 052dc1acf7..a1f5ae3d57 100644 --- a/runelite-client/src/main/scripts/XpDropChanged.hash +++ b/runelite-client/src/main/scripts/XpDropChanged.hash @@ -1 +1 @@ -AAA12D64549A1E4573B242AD9D53D8B1A436B947CF55BACBA660812411750E20 \ No newline at end of file +A4641387DC1A542BDEB6F3728D23944F968EF2FD3EA2868B5B6AAF6961D0C6E0 \ No newline at end of file diff --git a/runelite-client/src/main/scripts/XpDropChanged.rs2asm b/runelite-client/src/main/scripts/XpDropChanged.rs2asm index 5c08be1651..401c12d4de 100644 --- a/runelite-client/src/main/scripts/XpDropChanged.rs2asm +++ b/runelite-client/src/main/scripts/XpDropChanged.rs2asm @@ -30,42 +30,54 @@ LABEL9: iload 0 iconst 1 if_icmpeq LABEL25 - jump LABEL71 + jump LABEL81 LABEL25: get_varc_int 207 iconst -1 if_icmpne LABEL29 - jump LABEL70 + jump LABEL80 LABEL29: + get_varc_int 207 + iconst 269500481 + if_icmpeq LABEL33 + jump LABEL39 +LABEL33: + iload 1 + iload 3 + iload 8 + iload 9 + invoke 997 + jump LABEL65 +LABEL39: iload 35 iconst 105 iconst 83 iconst 681 get_varc_int 207 - coordx - enum - set_array_int + coordx + enum + set_array_int iload 35 get_varc_int 207 - coordy + coordy set_array_int 1 iload 35 - get_array_int + get_array_int iconst -1 - if_icmpne LABEL46 - jump LABEL55 -LABEL46: + if_icmpne LABEL56 + jump LABEL65 +LABEL56: iload 35 get_array_int 1 iconst 0 - if_icmpgt LABEL51 - jump LABEL55 -LABEL51: + if_icmpgt LABEL61 + jump LABEL65 +LABEL61: iload 35 iconst 1 - add + add istore 35 -LABEL55: +LABEL65: get_varc_int 208 get_varc_int 209 get_varc_int 210 @@ -81,150 +93,150 @@ LABEL55: set_varc_int 208 set_varc_int 207 jump LABEL25 -LABEL70: - jump LABEL508 -LABEL71: +LABEL80: + jump LABEL518 +LABEL81: sconst "newXpDrop" runelite_callback iconst 10 - stat_xp + stat_xp iload 25 - sub + sub istore 36 iload 36 iconst 0 - if_icmpgt LABEL80 - jump LABEL90 -LABEL80: + if_icmpgt LABEL90 + jump LABEL100 +LABEL90: iload 35 iconst 10 - set_array_int + set_array_int iload 35 iload 36 set_array_int 1 iload 35 iconst 1 - add + add istore 35 -LABEL90: +LABEL100: iconst 0 - stat_xp + stat_xp iload 11 - sub + sub istore 36 iload 36 iconst 0 - if_icmpgt LABEL99 - jump LABEL109 -LABEL99: - iload 35 - iconst 0 - set_array_int - iload 35 - iload 36 - set_array_int 1 - iload 35 - iconst 1 - add - istore 35 + if_icmpgt LABEL109 + jump LABEL119 LABEL109: + iload 35 + iconst 0 + set_array_int + iload 35 + iload 36 + set_array_int 1 + iload 35 + iconst 1 + add + istore 35 +LABEL119: iconst 2 - stat_xp + stat_xp iload 12 - sub + sub istore 36 iload 36 iconst 0 - if_icmpgt LABEL118 - jump LABEL128 -LABEL118: + if_icmpgt LABEL128 + jump LABEL138 +LABEL128: iload 35 iconst 2 - set_array_int + set_array_int iload 35 iload 36 set_array_int 1 iload 35 iconst 1 - add + add istore 35 -LABEL128: +LABEL138: iconst 4 - stat_xp + stat_xp iload 13 - sub + sub istore 36 iload 36 iconst 0 - if_icmpgt LABEL137 - jump LABEL147 -LABEL137: + if_icmpgt LABEL147 + jump LABEL157 +LABEL147: iload 35 iconst 4 - set_array_int + set_array_int iload 35 iload 36 set_array_int 1 iload 35 iconst 1 - add + add istore 35 -LABEL147: +LABEL157: iconst 6 - stat_xp + stat_xp iload 14 - sub + sub istore 36 iload 36 iconst 0 - if_icmpgt LABEL156 - jump LABEL166 -LABEL156: + if_icmpgt LABEL166 + jump LABEL176 +LABEL166: iload 35 iconst 6 - set_array_int + set_array_int iload 35 iload 36 set_array_int 1 iload 35 iconst 1 - add + add istore 35 -LABEL166: +LABEL176: iconst 1 - stat_xp + stat_xp iload 15 - sub + sub istore 36 iload 36 iconst 0 - if_icmpgt LABEL175 - jump LABEL185 -LABEL175: + if_icmpgt LABEL185 + jump LABEL195 +LABEL185: iload 35 iconst 1 - set_array_int + set_array_int iload 35 iload 36 set_array_int 1 iload 35 iconst 1 - add + add istore 35 -LABEL185: +LABEL195: iconst 3 - stat_xp + stat_xp iload 16 - sub + sub istore 36 iload 36 iconst 0 if_icmpgt HP_XP_GAINED - jump LABEL204 + jump LABEL214 HP_XP_GAINED: iload 35 iconst 3 - set_array_int + set_array_int iload 35 iload 36 sconst "hpXpGained" @@ -232,345 +244,345 @@ HP_XP_GAINED: set_array_int 1 iload 35 iconst 1 - add + add istore 35 -LABEL204: +LABEL214: iconst 5 - stat_xp + stat_xp iload 17 - sub + sub istore 36 iload 36 iconst 0 - if_icmpgt LABEL213 - jump LABEL223 -LABEL213: + if_icmpgt LABEL223 + jump LABEL233 +LABEL223: iload 35 iconst 5 - set_array_int + set_array_int iload 35 iload 36 set_array_int 1 iload 35 iconst 1 - add + add istore 35 -LABEL223: +LABEL233: iconst 16 - stat_xp + stat_xp iload 18 - sub + sub istore 36 iload 36 iconst 0 - if_icmpgt LABEL232 - jump LABEL242 -LABEL232: + if_icmpgt LABEL242 + jump LABEL252 +LABEL242: iload 35 iconst 16 - set_array_int + set_array_int iload 35 iload 36 set_array_int 1 iload 35 iconst 1 - add + add istore 35 -LABEL242: +LABEL252: iconst 15 - stat_xp + stat_xp iload 19 - sub + sub istore 36 iload 36 iconst 0 - if_icmpgt LABEL251 - jump LABEL261 -LABEL251: + if_icmpgt LABEL261 + jump LABEL271 +LABEL261: iload 35 iconst 15 - set_array_int + set_array_int iload 35 iload 36 set_array_int 1 iload 35 iconst 1 - add + add istore 35 -LABEL261: +LABEL271: iconst 17 - stat_xp + stat_xp iload 20 - sub + sub istore 36 iload 36 iconst 0 - if_icmpgt LABEL270 - jump LABEL280 -LABEL270: + if_icmpgt LABEL280 + jump LABEL290 +LABEL280: iload 35 iconst 17 - set_array_int + set_array_int iload 35 iload 36 set_array_int 1 iload 35 iconst 1 - add + add istore 35 -LABEL280: +LABEL290: iconst 12 - stat_xp + stat_xp iload 21 - sub + sub istore 36 iload 36 iconst 0 - if_icmpgt LABEL289 - jump LABEL299 -LABEL289: + if_icmpgt LABEL299 + jump LABEL309 +LABEL299: iload 35 iconst 12 - set_array_int + set_array_int iload 35 iload 36 set_array_int 1 iload 35 iconst 1 - add + add istore 35 -LABEL299: +LABEL309: iconst 20 - stat_xp + stat_xp iload 22 - sub + sub istore 36 iload 36 iconst 0 - if_icmpgt LABEL308 - jump LABEL318 -LABEL308: + if_icmpgt LABEL318 + jump LABEL328 +LABEL318: iload 35 iconst 20 - set_array_int + set_array_int iload 35 iload 36 set_array_int 1 iload 35 iconst 1 - add + add istore 35 -LABEL318: +LABEL328: iconst 14 - stat_xp + stat_xp iload 23 - sub + sub istore 36 iload 36 iconst 0 - if_icmpgt LABEL327 - jump LABEL337 -LABEL327: + if_icmpgt LABEL337 + jump LABEL347 +LABEL337: iload 35 iconst 14 - set_array_int + set_array_int iload 35 iload 36 set_array_int 1 iload 35 iconst 1 - add + add istore 35 -LABEL337: +LABEL347: iconst 13 - stat_xp + stat_xp iload 24 - sub + sub istore 36 iload 36 iconst 0 - if_icmpgt LABEL346 - jump LABEL356 -LABEL346: + if_icmpgt LABEL356 + jump LABEL366 +LABEL356: iload 35 iconst 13 - set_array_int + set_array_int iload 35 iload 36 set_array_int 1 iload 35 iconst 1 - add + add istore 35 -LABEL356: +LABEL366: iconst 7 - stat_xp + stat_xp iload 26 - sub + sub istore 36 iload 36 iconst 0 - if_icmpgt LABEL365 - jump LABEL375 -LABEL365: + if_icmpgt LABEL375 + jump LABEL385 +LABEL375: iload 35 iconst 7 - set_array_int + set_array_int iload 35 iload 36 set_array_int 1 iload 35 iconst 1 - add + add istore 35 -LABEL375: +LABEL385: iconst 11 - stat_xp + stat_xp iload 27 - sub + sub istore 36 iload 36 iconst 0 - if_icmpgt LABEL384 - jump LABEL394 -LABEL384: + if_icmpgt LABEL394 + jump LABEL404 +LABEL394: iload 35 iconst 11 - set_array_int + set_array_int iload 35 iload 36 set_array_int 1 iload 35 iconst 1 - add + add istore 35 -LABEL394: +LABEL404: iconst 8 - stat_xp + stat_xp iload 28 - sub + sub istore 36 iload 36 iconst 0 - if_icmpgt LABEL403 - jump LABEL413 -LABEL403: + if_icmpgt LABEL413 + jump LABEL423 +LABEL413: iload 35 iconst 8 - set_array_int + set_array_int iload 35 iload 36 set_array_int 1 iload 35 iconst 1 - add + add istore 35 -LABEL413: +LABEL423: iconst 9 - stat_xp + stat_xp iload 29 - sub + sub istore 36 iload 36 iconst 0 - if_icmpgt LABEL422 - jump LABEL432 -LABEL422: + if_icmpgt LABEL432 + jump LABEL442 +LABEL432: iload 35 iconst 9 - set_array_int + set_array_int iload 35 iload 36 set_array_int 1 iload 35 iconst 1 - add + add istore 35 -LABEL432: +LABEL442: iconst 18 - stat_xp + stat_xp iload 30 - sub + sub istore 36 iload 36 iconst 0 - if_icmpgt LABEL441 - jump LABEL451 -LABEL441: + if_icmpgt LABEL451 + jump LABEL461 +LABEL451: iload 35 iconst 18 - set_array_int + set_array_int iload 35 iload 36 set_array_int 1 iload 35 iconst 1 - add + add istore 35 -LABEL451: +LABEL461: iconst 19 - stat_xp + stat_xp iload 31 - sub + sub istore 36 iload 36 iconst 0 - if_icmpgt LABEL460 - jump LABEL470 -LABEL460: + if_icmpgt LABEL470 + jump LABEL480 +LABEL470: iload 35 iconst 19 - set_array_int + set_array_int iload 35 iload 36 set_array_int 1 iload 35 iconst 1 - add + add istore 35 -LABEL470: +LABEL480: iconst 22 - stat_xp + stat_xp iload 32 - sub + sub istore 36 iload 36 iconst 0 - if_icmpgt LABEL479 - jump LABEL489 -LABEL479: + if_icmpgt LABEL489 + jump LABEL499 +LABEL489: iload 35 iconst 22 - set_array_int + set_array_int iload 35 iload 36 set_array_int 1 iload 35 iconst 1 - add + add istore 35 -LABEL489: +LABEL499: iconst 21 - stat_xp + stat_xp iload 33 - sub + sub istore 36 iload 36 iconst 0 - if_icmpgt LABEL498 - jump LABEL508 -LABEL498: + if_icmpgt LABEL508 + jump LABEL518 +LABEL508: iload 35 iconst 21 - set_array_int + set_array_int iload 35 iload 36 set_array_int 1 iload 35 iconst 1 - add + add istore 35 -LABEL508: +LABEL518: iconst 0 istore 37 iconst 0 @@ -597,221 +609,221 @@ LABEL508: sstore 0 iload 35 iconst 0 - if_icmpgt LABEL536 - jump LABEL779 -LABEL536: + if_icmpgt LABEL546 + jump LABEL789 +LABEL546: iload 16 iconst 0 - if_icmpgt LABEL540 - jump LABEL779 -LABEL540: - clientclock + if_icmpgt LABEL550 + jump LABEL789 +LABEL550: + clientclock get_varc_int 76 - sub + sub iconst 10 - if_icmpgt LABEL546 - jump LABEL779 -LABEL546: + if_icmpgt LABEL556 + jump LABEL789 +LABEL556: get_varbit 4693 iconst 1 - if_icmpeq LABEL550 - jump LABEL561 -LABEL550: + if_icmpeq LABEL560 + jump LABEL571 +LABEL560: invoke 1972 iconst 0 - if_icmpeq LABEL554 - jump LABEL561 -LABEL554: + if_icmpeq LABEL564 + jump LABEL571 +LABEL564: iconst 495 iconst 495 iconst 25 istore 41 istore 40 istore 39 - jump LABEL575 -LABEL561: + jump LABEL585 +LABEL571: get_varbit 4693 iconst 2 - if_icmpeq LABEL565 - jump LABEL575 -LABEL565: + if_icmpeq LABEL575 + jump LABEL585 +LABEL575: invoke 1972 iconst 0 - if_icmpeq LABEL569 - jump LABEL575 -LABEL569: + if_icmpeq LABEL579 + jump LABEL585 +LABEL579: iconst 496 iconst 496 iconst 25 istore 41 istore 40 istore 39 -LABEL575: +LABEL585: iload 8 - if_getheight + if_getheight istore 42 iload 42 iconst 100 - if_icmplt LABEL582 - jump LABEL584 -LABEL582: + if_icmplt LABEL592 + jump LABEL594 +LABEL592: iconst 100 istore 42 -LABEL584: +LABEL594: iload 41 iconst 105 iconst 105 iconst 1171 get_varbit 4722 - enum - multiply + enum + multiply iload 42 - div + div iconst 1 - add + add istore 43 -LABEL596: +LABEL606: iload 37 iload 35 - if_icmplt LABEL600 - jump LABEL774 -LABEL600: + if_icmplt LABEL610 + jump LABEL784 +LABEL610: iload 38 iconst 0 - if_icmpeq LABEL604 - jump LABEL613 -LABEL604: + if_icmpeq LABEL614 + jump LABEL623 +LABEL614: iload 0 iconst 0 - if_icmpeq LABEL608 - jump LABEL613 -LABEL608: + if_icmpeq LABEL618 + jump LABEL623 +LABEL618: iload 37 - get_array_int + get_array_int set_varc_int 72 iconst 1 istore 38 -LABEL613: - get_varc_int 71 - iconst 0 - if_icmpgt LABEL617 - jump LABEL628 -LABEL617: - get_varc_int 71 - clientclock - iload 43 - sub - if_icmpgt LABEL623 - jump LABEL628 LABEL623: get_varc_int 71 + iconst 0 + if_icmpgt LABEL627 + jump LABEL638 +LABEL627: + get_varc_int 71 + clientclock iload 43 - add + sub + if_icmpgt LABEL633 + jump LABEL638 +LABEL633: + get_varc_int 71 + iload 43 + add istore 44 - jump LABEL630 -LABEL628: - clientclock + jump LABEL640 +LABEL638: + clientclock istore 44 -LABEL630: +LABEL640: iload 44 - clientclock + clientclock iload 43 iload 10 - multiply - add - if_icmplt LABEL638 - jump LABEL771 -LABEL638: + multiply + add + if_icmplt LABEL648 + jump LABEL781 +LABEL648: iconst 105 iconst 73 iconst 1163 get_varc_int 70 - enum + enum istore 47 iconst 0 iload 47 - if_sethide + if_sethide iload 37 get_array_int 1 istore 46 iload 47 iconst 5 iconst 1 - cc_create + cc_create iconst 83 iconst 100 iconst 255 iload 37 - get_array_int - enum - cc_setgraphic + get_array_int + enum + cc_setgraphic iconst 0 iconst 0 iconst 0 iconst 5 - cc_setposition + cc_setposition iconst 1 - cc_sethide + cc_sethide iconst 1 istore 45 iload 37 iconst 1 - add + add istore 37 -LABEL674: +LABEL684: get_varbit 4696 iconst 1 - if_icmpeq LABEL678 - jump LABEL722 -LABEL678: + if_icmpeq LABEL688 + jump LABEL732 +LABEL688: iload 37 iload 35 - if_icmplt LABEL682 - jump LABEL722 -LABEL682: + if_icmplt LABEL692 + jump LABEL732 +LABEL692: iload 45 iconst 5 - if_icmplt LABEL686 - jump LABEL722 -LABEL686: + if_icmplt LABEL696 + jump LABEL732 +LABEL696: iload 46 iconst 1000000 - if_icmplt LABEL690 - jump LABEL722 -LABEL690: + if_icmplt LABEL700 + jump LABEL732 +LABEL700: iload 46 iload 37 get_array_int 1 - add + add istore 46 iload 45 iconst 1 - add + add istore 45 iload 47 iconst 5 iload 45 - cc_create + cc_create iconst 83 iconst 100 iconst 255 iload 37 - get_array_int - enum - cc_setgraphic + get_array_int + enum + cc_setgraphic iconst 0 iconst 0 iconst 0 iconst 5 - cc_setposition + cc_setposition iconst 1 - cc_sethide + cc_sethide iload 37 iconst 1 - add + add istore 37 - jump LABEL674 -LABEL722: + jump LABEL684 +LABEL732: iload 46 sconst "," invoke 46 @@ -820,70 +832,70 @@ LABEL722: sstore 0 iload 0 iconst 1 - if_icmpeq LABEL730 - jump LABEL735 -LABEL730: + if_icmpeq LABEL740 + jump LABEL745 +LABEL740: sconst "" sconst " " sload 0 join_string 3 sstore 0 -LABEL735: +LABEL745: iload 47 iconst 0 - cc_find + cc_find iconst 1 - if_icmpeq LABEL741 - jump LABEL756 -LABEL741: + if_icmpeq LABEL751 + jump LABEL766 +LABEL751: sload 0 - cc_settext + cc_settext iconst 0 iconst 0 iconst 0 iconst 5 - cc_setposition + cc_setposition iconst 1 - cc_sethide + cc_sethide iload 47 iload 41 iload 39 iload 40 sload 0 invoke 996 -LABEL756: +LABEL766: iconst 1005 iload 47 iload 44 sconst "Ii" iload 47 - if_setontimer + if_setontimer iload 44 set_varc_int 71 get_varc_int 70 iconst 1 - add + add iload 10 - mod + mod set_varc_int 70 - jump LABEL773 -LABEL771: + jump LABEL783 +LABEL781: iload 35 istore 37 -LABEL773: - jump LABEL596 -LABEL774: +LABEL783: + jump LABEL606 +LABEL784: iload 1 iload 3 iload 8 iload 9 invoke 997 -LABEL779: +LABEL789: iload 0 iconst 0 - if_icmpeq LABEL783 - jump LABEL802 -LABEL783: + if_icmpeq LABEL793 + jump LABEL812 +LABEL793: iload 3 iload 4 iload 5 @@ -903,5 +915,5 @@ LABEL783: iload 9 iload 10 invoke 1003 -LABEL802: +LABEL812: return diff --git a/runelite-client/src/test/java/net/runelite/client/config/ConfigManagerTest.java b/runelite-client/src/test/java/net/runelite/client/config/ConfigManagerTest.java index 14d291acf8..2be777d4d4 100644 --- a/runelite-client/src/test/java/net/runelite/client/config/ConfigManagerTest.java +++ b/runelite-client/src/test/java/net/runelite/client/config/ConfigManagerTest.java @@ -31,6 +31,7 @@ import java.time.Instant; import java.util.UUID; import java.util.concurrent.ScheduledExecutorService; import javax.inject.Inject; +import net.runelite.api.Client; import net.runelite.client.account.AccountSession; import net.runelite.client.eventbus.EventBus; import org.junit.Assert; @@ -43,6 +44,10 @@ import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class ConfigManagerTest { + @Mock + @Bind + Client client; + @Mock @Bind EventBus eventBus; diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/woodcutting/WoodcuttingPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/woodcutting/WoodcuttingPluginTest.java index 8a9578a855..ad4b7fda79 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/woodcutting/WoodcuttingPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/woodcutting/WoodcuttingPluginTest.java @@ -44,6 +44,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) @@ -133,11 +134,11 @@ public class WoodcuttingPluginTest { ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.GAMEMESSAGE, "", BIRDS_NEST_MESSAGE, "", 0); - woodcuttingPlugin.showNestNotification = true; + when(woodcuttingConfig.showNestNotification()).thenReturn(true); woodcuttingPlugin.onChatMessage(chatMessage); verify(notifier).notify("A bird nest has spawned!"); - woodcuttingPlugin.showNestNotification = false; + when(woodcuttingConfig.showNestNotification()).thenReturn(false); woodcuttingPlugin.onChatMessage(chatMessage); verifyNoMoreInteractions(notifier); } diff --git a/runescape-client/src/main/java/DevicePcmPlayer.java b/runescape-client/src/main/java/DevicePcmPlayer.java index db0c48a131..c209b0bcfc 100644 --- a/runescape-client/src/main/java/DevicePcmPlayer.java +++ b/runescape-client/src/main/java/DevicePcmPlayer.java @@ -38,7 +38,7 @@ public class DevicePcmPlayer extends PcmPlayer { ) @Export("init") protected void init() { - this.format = new AudioFormat((float)Messages.field1274, 16, PcmPlayer.PcmPlayer_stereo ? 2 : 1, true, false); + this.format = new AudioFormat((float)Messages.PcmPlayer_sampleRate, 16, PcmPlayer.PcmPlayer_stereo ? 2 : 1, true, false); this.byteSamples = new byte[256 << (PcmPlayer.PcmPlayer_stereo ? 2 : 1)]; } diff --git a/runescape-client/src/main/java/GrandExchangeOfferAgeComparator.java b/runescape-client/src/main/java/GrandExchangeOfferAgeComparator.java index 7d9d1d4eaf..14dfbbbc02 100644 --- a/runescape-client/src/main/java/GrandExchangeOfferAgeComparator.java +++ b/runescape-client/src/main/java/GrandExchangeOfferAgeComparator.java @@ -136,7 +136,7 @@ final class GrandExchangeOfferAgeComparator implements Comparator { ) public static final void method170(int var0, boolean var1, int var2) { if (var0 >= 8000 && var0 <= 48000) { - Messages.field1274 = var0; + Messages.PcmPlayer_sampleRate = var0; PcmPlayer.PcmPlayer_stereo = var1; RouteStrategy.field2114 = var2; } else { diff --git a/runescape-client/src/main/java/GrandExchangeOfferOwnWorldComparator.java b/runescape-client/src/main/java/GrandExchangeOfferOwnWorldComparator.java index b686930696..e9da4da017 100644 --- a/runescape-client/src/main/java/GrandExchangeOfferOwnWorldComparator.java +++ b/runescape-client/src/main/java/GrandExchangeOfferOwnWorldComparator.java @@ -174,7 +174,7 @@ public class GrandExchangeOfferOwnWorldComparator implements Comparator { class60.pcmPlayer1 = HealthBarUpdate.method1776(GameShell.taskHandler, 1, 2048); ClientPacket.pcmStreamMixer = new PcmStreamMixer(); class60.pcmPlayer1.setStream(ClientPacket.pcmStreamMixer); - LoginScreenAnimation.decimator = new Decimator(22050, Messages.field1274); + LoginScreenAnimation.decimator = new Decimator(22050, Messages.PcmPlayer_sampleRate); Login.Login_loadingText = "Prepared sound engine"; Login.Login_loadingPercent = 35; Client.titleLoadingStage = 50; diff --git a/runescape-client/src/main/java/HealthBarUpdate.java b/runescape-client/src/main/java/HealthBarUpdate.java index f6f5d840be..acd94e8aab 100644 --- a/runescape-client/src/main/java/HealthBarUpdate.java +++ b/runescape-client/src/main/java/HealthBarUpdate.java @@ -78,7 +78,7 @@ public class HealthBarUpdate extends Node { garbageValue = "148025221" ) public static final PcmPlayer method1776(TaskHandler var0, int var1, int var2) { - if (Messages.field1274 == 0) { + if (Messages.PcmPlayer_sampleRate == 0) { throw new IllegalStateException(); } else if (var1 >= 0 && var1 < 2) { if (var2 < 256) { diff --git a/runescape-client/src/main/java/JagexCache.java b/runescape-client/src/main/java/JagexCache.java index f42bba4e6b..9ca764084f 100644 --- a/runescape-client/src/main/java/JagexCache.java +++ b/runescape-client/src/main/java/JagexCache.java @@ -138,12 +138,12 @@ public class JagexCache { int var6 = (var3 - 32 - var5) * var2 / (var4 - var3); Rasterizer2D.Rasterizer2D_fillRectangle(var0, var6 + var1 + 16, 16, var5, Client.field706); - Rasterizer2D.rasterizerDrawVerticalLine(var0, var6 + var1 + 16, var5, Client.field708); - Rasterizer2D.rasterizerDrawVerticalLine(var0 + 1, var6 + var1 + 16, var5, Client.field708); + Rasterizer2D.Rasterizer2D_drawVerticalLine(var0, var6 + var1 + 16, var5, Client.field708); + Rasterizer2D.Rasterizer2D_drawVerticalLine(var0 + 1, var6 + var1 + 16, var5, Client.field708); Rasterizer2D.Rasterizer2D_drawHorizontalLine(var0, var6 + var1 + 16, 16, Client.field708); Rasterizer2D.Rasterizer2D_drawHorizontalLine(var0, var6 + var1 + 17, 16, Client.field708); - Rasterizer2D.rasterizerDrawVerticalLine(var0 + 15, var6 + var1 + 16, var5, Client.field707); - Rasterizer2D.rasterizerDrawVerticalLine(var0 + 14, var6 + var1 + 17, var5 - 1, Client.field707); + Rasterizer2D.Rasterizer2D_drawVerticalLine(var0 + 15, var6 + var1 + 16, var5, Client.field707); + Rasterizer2D.Rasterizer2D_drawVerticalLine(var0 + 14, var6 + var1 + 17, var5 - 1, Client.field707); Rasterizer2D.Rasterizer2D_drawHorizontalLine(var0, var6 + var5 + var1 + 15, 16, Client.field707); Rasterizer2D.Rasterizer2D_drawHorizontalLine(var0 + 1, var6 + var5 + var1 + 14, 15, Client.field707); } diff --git a/runescape-client/src/main/java/Messages.java b/runescape-client/src/main/java/Messages.java index 9f82e0812a..7ce65fc1f4 100644 --- a/runescape-client/src/main/java/Messages.java +++ b/runescape-client/src/main/java/Messages.java @@ -35,7 +35,8 @@ public class Messages { @ObfuscatedGetter( intValue = -1088425627 ) - public static int field1274; + @Export("PcmPlayer_sampleRate") + public static int PcmPlayer_sampleRate; @ObfuscatedName("c") @ObfuscatedSignature( signature = "Lat;" diff --git a/runescape-client/src/main/java/MidiPcmStream.java b/runescape-client/src/main/java/MidiPcmStream.java index f9aaa61d3b..6aca87810b 100644 --- a/runescape-client/src/main/java/MidiPcmStream.java +++ b/runescape-client/src/main/java/MidiPcmStream.java @@ -245,7 +245,7 @@ public class MidiPcmStream extends PcmStream { @Export("fill") protected synchronized void fill(int[] var1, int var2, int var3) { if (this.midiFile.isReady()) { - int var4 = this.midiFile.division * this.field2419 * -727379968 / Messages.field1274; + int var4 = this.midiFile.division * this.field2419 * -727379968 / Messages.PcmPlayer_sampleRate; do { long var5 = this.field2431 + (long)var4 * (long)var3; @@ -294,7 +294,7 @@ public class MidiPcmStream extends PcmStream { @Export("skip") protected synchronized void skip(int var1) { if (this.midiFile.isReady()) { - int var2 = this.midiFile.division * this.field2419 * -727379968 / Messages.field1274; + int var2 = this.midiFile.division * this.field2419 * -727379968 / Messages.PcmPlayer_sampleRate; do { long var3 = this.field2431 + (long)var2 * (long)var1; @@ -519,7 +519,7 @@ public class MidiPcmStream extends PcmStream { for (MusicPatchNode var2 = (MusicPatchNode)this.patchStream.queue.last(); var2 != null; var2 = (MusicPatchNode)this.patchStream.queue.previous()) { if (var1 < 0 || var2.field2449 == var1) { if (var2.stream != null) { - var2.stream.method2582(Messages.field1274 / 100); + var2.stream.method2582(Messages.PcmPlayer_sampleRate / 100); if (var2.stream.method2686()) { this.patchStream.mixer.addSubStream(var2.stream); } @@ -858,7 +858,7 @@ public class MidiPcmStream extends PcmStream { var2 += (int)(var6 * (double)var4); } - var4 = (int)((double)(var1.rawSound.sampleRate * 256) * Math.pow(2.0D, (double)var2 * 3.255208333333333E-4D) / (double)Messages.field1274 + 0.5D); + var4 = (int)((double)(var1.rawSound.sampleRate * 256) * Math.pow(2.0D, (double)var2 * 3.255208333333333E-4D) / (double)Messages.PcmPlayer_sampleRate + 0.5D); return var4 < 1 ? 1 : var4; } @@ -990,7 +990,7 @@ public class MidiPcmStream extends PcmStream { garbageValue = "178317578" ) boolean method3802(MusicPatchNode var1, int[] var2, int var3, int var4) { - var1.field2464 = Messages.field1274 / 100; + var1.field2464 = Messages.PcmPlayer_sampleRate / 100; if (var1.field2459 < 0 || var1.stream != null && !var1.stream.method2585()) { int var5 = var1.field2455; if (var5 > 0) { diff --git a/runescape-client/src/main/java/MusicPatchPcmStream.java b/runescape-client/src/main/java/MusicPatchPcmStream.java index 1519ddf8a5..912620735c 100644 --- a/runescape-client/src/main/java/MusicPatchPcmStream.java +++ b/runescape-client/src/main/java/MusicPatchPcmStream.java @@ -41,7 +41,7 @@ public class MusicPatchPcmStream extends PcmStream { ) void method3962(MusicPatchNode var1, int[] var2, int var3, int var4, int var5) { if ((this.superStream.field2428[var1.field2449] & 4) != 0 && var1.field2459 < 0) { - int var6 = this.superStream.field2433[var1.field2449] / Messages.field1274; + int var6 = this.superStream.field2433[var1.field2449] / Messages.PcmPlayer_sampleRate; while (true) { int var7 = (var6 + 1048575 - var1.field2463) / var6; @@ -54,7 +54,7 @@ public class MusicPatchPcmStream extends PcmStream { var3 += var7; var4 -= var7; var1.field2463 += var7 * var6 - 1048576; - int var8 = Messages.field1274 / 100; + int var8 = Messages.PcmPlayer_sampleRate / 100; int var9 = 262144 / var6; if (var9 < var8) { var8 = var9; @@ -91,7 +91,7 @@ public class MusicPatchPcmStream extends PcmStream { ) void method3959(MusicPatchNode var1, int var2) { if ((this.superStream.field2428[var1.field2449] & 4) != 0 && var1.field2459 < 0) { - int var3 = this.superStream.field2433[var1.field2449] / Messages.field1274; + int var3 = this.superStream.field2433[var1.field2449] / Messages.PcmPlayer_sampleRate; int var4 = (var3 + 1048575 - var1.field2463) / var3; var1.field2463 = var3 * var2 + var1.field2463 & 1048575; if (var4 <= var2) { diff --git a/runescape-client/src/main/java/PcmPlayer.java b/runescape-client/src/main/java/PcmPlayer.java index a931174de8..064f71c6ce 100644 --- a/runescape-client/src/main/java/PcmPlayer.java +++ b/runescape-client/src/main/java/PcmPlayer.java @@ -263,7 +263,7 @@ public class PcmPlayer { while (var1 > 5000L + this.timeMs) { this.skip(256); - this.timeMs += (long)(256000 / Messages.field1274); + this.timeMs += (long)(256000 / Messages.PcmPlayer_sampleRate); } } catch (Exception var6) { this.timeMs = var1; @@ -359,7 +359,7 @@ public class PcmPlayer { class300.clearIntArray(var1, 0, var3); this.field1409 -= var2; if (this.stream != null && this.field1409 <= 0) { - this.field1409 += Messages.field1274 >> 4; + this.field1409 += Messages.PcmPlayer_sampleRate >> 4; class1.PcmStream_disable(this.stream); this.method2452(this.stream, this.stream.vmethod2741()); int var4 = 0; diff --git a/runescape-client/src/main/java/Rasterizer2D.java b/runescape-client/src/main/java/Rasterizer2D.java index a2683774f9..66431760a4 100644 --- a/runescape-client/src/main/java/Rasterizer2D.java +++ b/runescape-client/src/main/java/Rasterizer2D.java @@ -609,8 +609,8 @@ public class Rasterizer2D extends DualNode { public static void Rasterizer2D_drawRectangle(int var0, int var1, int var2, int var3, int var4) { Rasterizer2D_drawHorizontalLine(var0, var1, var2, var4); Rasterizer2D_drawHorizontalLine(var0, var3 + var1 - 1, var2, var4); - rasterizerDrawVerticalLine(var0, var1, var3, var4); - rasterizerDrawVerticalLine(var0 + var2 - 1, var1, var3, var4); + Rasterizer2D_drawVerticalLine(var0, var1, var3, var4); + Rasterizer2D_drawVerticalLine(var0 + var2 - 1, var1, var3, var4); } @ObfuscatedName("df") @@ -679,7 +679,7 @@ public class Rasterizer2D extends DualNode { @ObfuscatedName("eg") @Export("Rasterizer2D_drawVerticalLine") - public static void rasterizerDrawVerticalLine(int var0, int var1, int var2, int var3) { + public static void Rasterizer2D_drawVerticalLine(int var0, int var1, int var2, int var3) { if (var0 >= Rasterizer2D_xClipStart && var0 < Rasterizer2D_xClipEnd) { if (var1 < Rasterizer2D_yClipStart) { var2 -= Rasterizer2D_yClipStart - var1; @@ -744,9 +744,9 @@ public class Rasterizer2D extends DualNode { } else if (var2 == 0) { if (var3 >= 0) { - rasterizerDrawVerticalLine(var0, var1, var3 + 1, var4); + Rasterizer2D_drawVerticalLine(var0, var1, var3 + 1, var4); } else { - rasterizerDrawVerticalLine(var0, var3 + var1, -var3 + 1, var4); + Rasterizer2D_drawVerticalLine(var0, var3 + var1, -var3 + 1, var4); } } else { diff --git a/runescape-client/src/main/java/RawPcmStream.java b/runescape-client/src/main/java/RawPcmStream.java index 76ab892cec..39166f684f 100644 --- a/runescape-client/src/main/java/RawPcmStream.java +++ b/runescape-client/src/main/java/RawPcmStream.java @@ -846,7 +846,7 @@ public class RawPcmStream extends PcmStream { ) @Export("createRawPcmStream") public static RawPcmStream createRawPcmStream(RawSound var0, int var1, int var2) { - return var0.samples != null && var0.samples.length != 0 ? new RawPcmStream(var0, (int)((long)var0.sampleRate * 256L * (long)var1 / (long)(Messages.field1274 * 100)), var2 << 6) : null; + return var0.samples != null && var0.samples.length != 0 ? new RawPcmStream(var0, (int)((long)var0.sampleRate * 256L * (long)var1 / (long)(Messages.PcmPlayer_sampleRate * 100)), var2 << 6) : null; } @ObfuscatedName("g") diff --git a/runescape-client/src/main/java/WorldMapRegion.java b/runescape-client/src/main/java/WorldMapRegion.java index 8bd9605b0c..9f89e1cc0a 100644 --- a/runescape-client/src/main/java/WorldMapRegion.java +++ b/runescape-client/src/main/java/WorldMapRegion.java @@ -897,7 +897,7 @@ public class WorldMapRegion { void method469(int var1, int var2, int var3, int var4) { var3 %= 4; if (var3 == 0) { - Rasterizer2D.rasterizerDrawVerticalLine(this.pixelsPerTile * var1, this.pixelsPerTile * (63 - var2), this.pixelsPerTile, var4); + Rasterizer2D.Rasterizer2D_drawVerticalLine(this.pixelsPerTile * var1, this.pixelsPerTile * (63 - var2), this.pixelsPerTile, var4); } if (var3 == 1) { @@ -905,7 +905,7 @@ public class WorldMapRegion { } if (var3 == 2) { - Rasterizer2D.rasterizerDrawVerticalLine(this.pixelsPerTile * var1 + this.pixelsPerTile - 1, this.pixelsPerTile * (63 - var2), this.pixelsPerTile, var4); + Rasterizer2D.Rasterizer2D_drawVerticalLine(this.pixelsPerTile * var1 + this.pixelsPerTile - 1, this.pixelsPerTile * (63 - var2), this.pixelsPerTile, var4); } if (var3 == 3) {