From 786e2bb7295b1924313d4bbecd90cf62155513ea Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Fri, 19 Jul 2019 04:16:48 +0200 Subject: [PATCH 01/21] http-api: Run http calls on the IO thread --- .../client/plugins/chatcommands/ChatCommandsPlugin.java | 2 +- .../java/net/runelite/client/plugins/examine/ExaminePlugin.java | 2 +- .../client/plugins/grandexchange/GrandExchangePlugin.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java index 4c411000a4..489a9e21db 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java @@ -827,7 +827,7 @@ public class ChatCommandsPlugin extends Plugin { ItemPrice item = retrieveFromList(results, search); CLIENT.lookupItem(item.getId()) - .subscribeOn(Schedulers.single()) + .subscribeOn(Schedulers.io()) .subscribe( (osbresult) -> clientThread.invoke(() -> diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java index 3cdf71dff4..63a2429419 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java @@ -370,7 +370,7 @@ public class ExaminePlugin extends Plugin { int finalQuantity = quantity; CLIENT.lookupItem(id) - .subscribeOn(Schedulers.single()) + .subscribeOn(Schedulers.io()) .subscribe( (osbresult) -> clientThread.invoke(() -> diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java index 9fc24c8bab..eb0605d440 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java @@ -551,7 +551,7 @@ public class GrandExchangePlugin extends Plugin } CLIENT.lookupItem(itemId) - .subscribeOn(Schedulers.single()) + .subscribeOn(Schedulers.io()) .subscribe( (osbresult) -> clientThread.invoke(() -> From baa338e5333ac31b279db5fe15e3c61d01161b14 Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Fri, 19 Jul 2019 04:17:11 +0200 Subject: [PATCH 02/21] client: ClientThread implements executor --- .../net/runelite/client/callback/ClientThread.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) 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 805b7a5620..8935c8118e 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 @@ -27,14 +27,16 @@ package net.runelite.client.callback; import com.google.inject.Inject; import java.util.Iterator; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.Executor; import java.util.function.BooleanSupplier; import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; +import org.jetbrains.annotations.NotNull; @Singleton @Slf4j -public class ClientThread +public class ClientThread implements Executor { private final ConcurrentLinkedQueue invokes = new ConcurrentLinkedQueue<>(); @@ -112,4 +114,14 @@ public class ClientThread } } } + + @Override + public void execute(@NotNull Runnable r) + { + invoke(() -> + { + r.run(); + return true; + }); + } } From d2e99e23eb22ab506f196be24292aa84ce15f9be Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Fri, 19 Jul 2019 04:18:28 +0200 Subject: [PATCH 03/21] http-api: Use observeOn to run code on the ClientThread --- .../chatcommands/ChatCommandsPlugin.java | 66 +++++++++---------- .../client/plugins/examine/ExaminePlugin.java | 46 ++++++------- .../grandexchange/GrandExchangePlugin.java | 10 +-- 3 files changed, 61 insertions(+), 61 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java index 489a9e21db..4d363e21ac 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java @@ -828,44 +828,44 @@ public class ChatCommandsPlugin extends Plugin ItemPrice item = retrieveFromList(results, search); CLIENT.lookupItem(item.getId()) .subscribeOn(Schedulers.io()) + .observeOn(Schedulers.from(clientThread)) .subscribe( (osbresult) -> - clientThread.invoke(() -> + { + int itemId = item.getId(); + int itemPrice = itemManager.getItemPrice(itemId); + + final ChatMessageBuilder builder = new ChatMessageBuilder(); + builder.append(ChatColorType.NORMAL); + builder.append(ChatColorType.HIGHLIGHT); + builder.append(item.getName()); + builder.append(ChatColorType.NORMAL); + builder.append(": GE "); + builder.append(ChatColorType.HIGHLIGHT); + builder.append(StackFormatter.formatNumber(itemPrice)); + builder.append(ChatColorType.NORMAL); + builder.append(": OSB "); + builder.append(ChatColorType.HIGHLIGHT); + builder.append(StackFormatter.formatNumber(osbresult.getOverall_average())); + + ItemDefinition itemComposition = itemManager.getItemDefinition(itemId); + if (itemComposition != null) { - int itemId = item.getId(); - int itemPrice = itemManager.getItemPrice(itemId); + int alchPrice = itemManager.getAlchValue(itemId); + builder + .append(ChatColorType.NORMAL) + .append(" HA value ") + .append(ChatColorType.HIGHLIGHT) + .append(StackFormatter.formatNumber(alchPrice)); + } - final ChatMessageBuilder builder = new ChatMessageBuilder(); - builder.append(ChatColorType.NORMAL); - builder.append(ChatColorType.HIGHLIGHT); - builder.append(item.getName()); - builder.append(ChatColorType.NORMAL); - builder.append(": GE "); - builder.append(ChatColorType.HIGHLIGHT); - builder.append(StackFormatter.formatNumber(itemPrice)); - builder.append(ChatColorType.NORMAL); - builder.append(": OSB "); - builder.append(ChatColorType.HIGHLIGHT); - builder.append(StackFormatter.formatNumber(osbresult.getOverall_average())); + String response = builder.build(); - ItemDefinition itemComposition = itemManager.getItemDefinition(itemId); - if (itemComposition != null) - { - int alchPrice = itemManager.getAlchValue(itemId); - builder - .append(ChatColorType.NORMAL) - .append(" HA value ") - .append(ChatColorType.HIGHLIGHT) - .append(StackFormatter.formatNumber(alchPrice)); - } - - String response = builder.build(); - - log.debug("Setting response {}", response); - messageNode.setRuneLiteFormatMessage(response); - chatMessageManager.update(messageNode); - client.refreshChat(); - }) + log.debug("Setting response {}", response); + messageNode.setRuneLiteFormatMessage(response); + chatMessageManager.update(messageNode); + client.refreshChat(); + } ); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java index 63a2429419..32ad61add6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java @@ -371,36 +371,36 @@ public class ExaminePlugin extends Plugin int finalQuantity = quantity; CLIENT.lookupItem(id) .subscribeOn(Schedulers.io()) + .observeOn(Schedulers.from(clientThread)) .subscribe( (osbresult) -> - clientThread.invoke(() -> + { + message + .append(ChatColorType.NORMAL) + .append(" GE ") + .append(ChatColorType.HIGHLIGHT) + .append(StackFormatter.formatNumber(gePrice * finalQuantity)); + + if (osbresult != null) { message .append(ChatColorType.NORMAL) - .append(" GE ") + .append(" OSB ") .append(ChatColorType.HIGHLIGHT) - .append(StackFormatter.formatNumber(gePrice * finalQuantity)); + .append(StackFormatter.formatNumber(osbresult.getOverall_average() * finalQuantity)); + } - if (osbresult != null) - { - message - .append(ChatColorType.NORMAL) - .append(" OSB ") - .append(ChatColorType.HIGHLIGHT) - .append(StackFormatter.formatNumber(osbresult.getOverall_average() * finalQuantity)); - } - - if (finalQuantity > 1) - { - message - .append(ChatColorType.NORMAL) - .append(" (") - .append(ChatColorType.HIGHLIGHT) - .append(StackFormatter.formatNumber(gePrice)) - .append(ChatColorType.NORMAL) - .append("ea)"); - } - }), + if (finalQuantity > 1) + { + message + .append(ChatColorType.NORMAL) + .append(" (") + .append(ChatColorType.HIGHLIGHT) + .append(StackFormatter.formatNumber(gePrice)) + .append(ChatColorType.NORMAL) + .append("ea)"); + } + }, (e) -> log.error(e.toString()) ); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java index eb0605d440..b8ffc3c9b1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java @@ -552,13 +552,13 @@ public class GrandExchangePlugin extends Plugin CLIENT.lookupItem(itemId) .subscribeOn(Schedulers.io()) + .observeOn(Schedulers.from(clientThread)) .subscribe( (osbresult) -> - clientThread.invoke(() -> - { - final String text = geText.getText() + OSB_GE_TEXT + StackFormatter.formatNumber(osbresult.getOverall_average()); - geText.setText(text); - }), + { + final String text = geText.getText() + OSB_GE_TEXT + StackFormatter.formatNumber(osbresult.getOverall_average()); + geText.setText(text); + }, (e) -> log.debug("Error getting price of item {}", itemId, e) ); }); From fe2a27e8d1c87be17ee9c3924df46fa55587bd6c Mon Sep 17 00:00:00 2001 From: Ganom Date: Thu, 18 Jul 2019 22:31:32 -0400 Subject: [PATCH 04/21] Add option to turn off item output to webhook. --- .../runelite/client/plugins/playerscouter/PlayerScouter.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/playerscouter/PlayerScouter.java b/runelite-client/src/main/java/net/runelite/client/plugins/playerscouter/PlayerScouter.java index 84af2e2e4f..05e4483e2f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/playerscouter/PlayerScouter.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/playerscouter/PlayerScouter.java @@ -105,6 +105,7 @@ public class PlayerScouter extends Plugin private int minimumRisk; private int minimumValue; private int timeout; + private boolean outputItems; private static Map getLocationMap() { @@ -165,6 +166,7 @@ public class PlayerScouter extends Plugin { return; } + updateConfig(); } @@ -293,7 +295,7 @@ public class PlayerScouter extends Plugin if (player.getRisk() > this.minimumRisk) { - Utils.scoutPlayer(player, url, DISCORD_CLIENT, itemManager, client, this.minimumValue); + Utils.scoutPlayer(player, url, DISCORD_CLIENT, itemManager, client, this.minimumValue, this.outputItems); } }); } @@ -322,6 +324,7 @@ public class PlayerScouter extends Plugin this.overlayEnabled = config.overlayEnabled(); this.timeout = config.timeout(); this.onlyWildy = config.onlyWildy(); + this.outputItems = config.outputItems(); } private boolean checkWildy() From 1bc3d1c26c3ce270141006db19c3a71c9be64ec6 Mon Sep 17 00:00:00 2001 From: Ganom Date: Thu, 18 Jul 2019 22:32:54 -0400 Subject: [PATCH 05/21] Add config option --- .../playerscouter/PlayerScouterConfig.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/playerscouter/PlayerScouterConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/playerscouter/PlayerScouterConfig.java index 7c7b9faffb..258341e610 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/playerscouter/PlayerScouterConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/playerscouter/PlayerScouterConfig.java @@ -56,18 +56,29 @@ public interface PlayerScouterConfig extends Config keyName = "onlyWildy", name = "Only Scout in Wildy", description = "This will only scout players in the wilderness.", - position = 1 + position = 2 ) default boolean onlyWildy() { return true; } + @ConfigItem( + keyName = "outputItems", + name = "Output Items", + description = "This will output all of their risked gear to the webhook.", + position = 3 + ) + default boolean outputItems() + { + return false; + } + @ConfigItem( keyName = "minimumRisk", name = "Minimum Risk", description = "Minimum risk for the player to be scouted.", - position = 2 + position = 4 ) default int minimumRisk() { @@ -78,7 +89,7 @@ public interface PlayerScouterConfig extends Config keyName = "minimumValue", name = "Minimum Value", description = "Minimum value for the item to be posted on discord.", - position = 3 + position = 5 ) default int minimumValue() { @@ -89,7 +100,7 @@ public interface PlayerScouterConfig extends Config keyName = "timeout", name = "Timeout", description = "Minimum amount of ticks before the player can be scouted again. (1 tick = 600ms)", - position = 4 + position = 6 ) default int timeout() { From 3e12c67cbcaf754ba23bf5985b44ed1260e8be21 Mon Sep 17 00:00:00 2001 From: Ganom Date: Thu, 18 Jul 2019 22:33:21 -0400 Subject: [PATCH 06/21] Update utils to reflect output change --- .../client/plugins/playerscouter/Utils.java | 75 ++++++++++--------- 1 file changed, 39 insertions(+), 36 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/playerscouter/Utils.java b/runelite-client/src/main/java/net/runelite/client/plugins/playerscouter/Utils.java index d63f98bf64..f3dd181ad7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/playerscouter/Utils.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/playerscouter/Utils.java @@ -498,7 +498,7 @@ class Utils return "No Target Detected"; } - static void scoutPlayer(PlayerContainer player, HttpUrl url, DiscordClient discordClient, ItemManager itemManager, Client client, int minimumValue) + static void scoutPlayer(PlayerContainer player, HttpUrl url, DiscordClient discordClient, ItemManager itemManager, Client client, int minimumValue, boolean outputItems) { if (player.isScouted()) { @@ -571,43 +571,46 @@ class Utils .inline(true) .build()); - fieldList.add(FieldEmbed.builder() - .name("Risked Items Sorted by Value") - .value("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━") - .build()); - - final int[] items = {0}; - - player.getRiskedGear().forEach((gear, value) -> - { - if (value <= 0 || value <= minimumValue) - { - items[0]++; - return; - } - - ItemStats item = itemManager.getItemStats(gear, false); - - if (item == null) - { - log.error("Item is Null: {}", gear); - return; - } - - fieldList.add(FieldEmbed.builder() - .name(item.getName()) - .value("Value: " + StackFormatter.quantityToRSDecimalStack(value)) - .inline(true) - .build()); - }); - - if (items[0] > 0) + if (outputItems) { fieldList.add(FieldEmbed.builder() - .name("Items below value: " + minimumValue) - .value(Integer.toString(items[0])) - .inline(true) + .name("Risked Items Sorted by Value") + .value("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━") .build()); + + final int[] items = {0}; + + player.getRiskedGear().forEach((gear, value) -> + { + if (value <= 0 || value <= minimumValue) + { + items[0]++; + return; + } + + ItemStats item = itemManager.getItemStats(gear, false); + + if (item == null) + { + log.error("Item is Null: {}", gear); + return; + } + + fieldList.add(FieldEmbed.builder() + .name(item.getName()) + .value("Value: " + StackFormatter.quantityToRSDecimalStack(value)) + .inline(true) + .build()); + }); + + if (items[0] > 0) + { + fieldList.add(FieldEmbed.builder() + .name("Items below value: " + minimumValue) + .value(Integer.toString(items[0])) + .inline(true) + .build()); + } } message(player.getPlayer().getName(), " ", ICONBASEURL + Objects.requireNonNull(getEntry(player.getGear())).getKey() + ".png", image, fieldList, url, discordClient, color); @@ -695,4 +698,4 @@ class Utils } return s; } -} \ No newline at end of file +} From 241fbd136ca2c8cfa0e84387da315895e9bf22aa Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Fri, 19 Jul 2019 04:51:40 +0200 Subject: [PATCH 07/21] http-api: Use observables for ItemClient --- .../runelite/http/api/item/ItemClient.java | 139 ++++++++++-------- .../net/runelite/client/game/ItemManager.java | 61 ++++---- 2 files changed, 107 insertions(+), 93 deletions(-) diff --git a/http-api/src/main/java/net/runelite/http/api/item/ItemClient.java b/http-api/src/main/java/net/runelite/http/api/item/ItemClient.java index 17784dd67b..2566a9c603 100644 --- a/http-api/src/main/java/net/runelite/http/api/item/ItemClient.java +++ b/http-api/src/main/java/net/runelite/http/api/item/ItemClient.java @@ -26,6 +26,7 @@ package net.runelite.http.api.item; import com.google.gson.JsonParseException; import com.google.gson.reflect.TypeToken; +import io.reactivex.Observable; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.InputStream; @@ -112,7 +113,7 @@ public class ItemClient } } - public BufferedImage getIcon(int itemId) throws IOException + public Observable getIcon(int itemId) { HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() .addPathSegment("item") @@ -126,23 +127,26 @@ public class ItemClient .url(url) .build(); - try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) + return Observable.defer(() -> { - if (!response.isSuccessful()) + try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) { - logger.debug("Error grabbing icon {}: {}", itemId, response); - return null; - } + if (!response.isSuccessful()) + { + logger.debug("Error grabbing icon {}: {}", itemId, response); + return null; + } - InputStream in = response.body().byteStream(); - synchronized (ImageIO.class) - { - return ImageIO.read(in); + InputStream in = response.body().byteStream(); + synchronized (ImageIO.class) + { + return Observable.just(ImageIO.read(in)); + } } - } + }); } - public SearchResult search(String itemName) throws IOException + public Observable search(String itemName) { HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() .addPathSegment("item") @@ -152,28 +156,31 @@ public class ItemClient logger.debug("Built URI: {}", url); - Request request = new Request.Builder() - .url(url) - .build(); - - try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) + return Observable.defer(() -> { - if (!response.isSuccessful()) + Request request = new Request.Builder() + .url(url) + .build(); + + try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) { - logger.debug("Error looking up item {}: {}", itemName, response); - return null; - } + if (!response.isSuccessful()) + { + logger.debug("Error looking up item {}: {}", itemName, response); + return null; + } - InputStream in = response.body().byteStream(); - return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), SearchResult.class); - } - catch (JsonParseException ex) - { - throw new IOException(ex); - } + InputStream in = response.body().byteStream(); + return Observable.just(RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), SearchResult.class)); + } + catch (JsonParseException ex) + { + return Observable.error(ex); + } + }); } - public ItemPrice[] getPrices() throws IOException + public Observable getPrices() { HttpUrl.Builder urlBuilder = RuneLiteAPI.getApiBase().newBuilder() .addPathSegment("item") @@ -183,28 +190,32 @@ public class ItemClient logger.debug("Built URI: {}", url); - Request request = new Request.Builder() - .url(url) - .build(); - try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) + return Observable.defer(() -> { - if (!response.isSuccessful()) + Request request = new Request.Builder() + .url(url) + .build(); + + try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) { - logger.warn("Error looking up prices: {}", response); - return null; - } + if (!response.isSuccessful()) + { + logger.warn("Error looking up prices: {}", response); + return null; + } - InputStream in = response.body().byteStream(); - return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), ItemPrice[].class); - } - catch (JsonParseException ex) - { - throw new IOException(ex); - } + InputStream in = response.body().byteStream(); + return Observable.just(RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), ItemPrice[].class)); + } + catch (JsonParseException ex) + { + return Observable.error(ex); + } + }); } - public Map getStats() throws IOException + public Observable> getStats() { HttpUrl.Builder urlBuilder = RuneLiteAPI.getStaticBase().newBuilder() .addPathSegment("item") @@ -215,27 +226,31 @@ public class ItemClient logger.debug("Built URI: {}", url); - Request request = new Request.Builder() - .url(url) - .build(); - try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) + return Observable.defer(() -> { - if (!response.isSuccessful()) + Request request = new Request.Builder() + .url(url) + .build(); + + try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) { - logger.warn("Error looking up item stats: {}", response); - return null; + if (!response.isSuccessful()) + { + logger.warn("Error looking up item stats: {}", response); + return null; + } + + InputStream in = response.body().byteStream(); + final Type typeToken = new TypeToken>() + { + }.getType(); + return Observable.just(RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), typeToken)); } - - InputStream in = response.body().byteStream(); - final Type typeToken = new TypeToken>() + catch (JsonParseException ex) { - }.getType(); - return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), typeToken); - } - catch (JsonParseException ex) - { - throw new IOException(ex); - } + return Observable.error(ex); + } + }); } } diff --git a/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java b/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java index 34a95e613a..fc6a5f6d90 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java +++ b/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java @@ -30,9 +30,9 @@ import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableMap; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; +import io.reactivex.schedulers.Schedulers; import java.awt.Color; import java.awt.image.BufferedImage; -import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.Type; @@ -209,43 +209,42 @@ public class ItemManager private void loadPrices() { - try - { - ItemPrice[] prices = itemClient.getPrices(); - if (prices != null) - { - ImmutableMap.Builder map = ImmutableMap.builderWithExpectedSize(prices.length); - for (ItemPrice price : prices) + itemClient.getPrices() + .subscribeOn(Schedulers.io()) + .subscribe( + (prices) -> { - map.put(price.getId(), price); - } - itemPrices = map.build(); - } + if (prices != null) + { + ImmutableMap.Builder map = ImmutableMap.builderWithExpectedSize(prices.length); + for (ItemPrice price : prices) + { + map.put(price.getId(), price); + } + itemPrices = map.build(); + } - log.debug("Loaded {} prices", itemPrices.size()); - } - catch (IOException e) - { - log.warn("error loading prices!", e); - } + log.debug("Loaded {} prices", itemPrices.size()); + }, + (e) -> log.warn("error loading prices!", e) + ); } private void loadStats() { - try - { - final Map stats = itemClient.getStats(); - if (stats != null) - { - itemStats = ImmutableMap.copyOf(stats); - } + itemClient.getStats() + .subscribeOn(Schedulers.io()) + .subscribe( + (stats) -> { + if (stats != null) + { + itemStats = ImmutableMap.copyOf(stats); + } - log.debug("Loaded {} stats", itemStats.size()); - } - catch (IOException e) - { - log.warn("error loading stats!", e); - } + log.debug("Loaded {} stats", itemStats.size()); + }, + (e) -> log.warn("error loading stats!", e) + ); } private void onGameStateChanged(final GameStateChanged event) From 60d734549ff153170c7ea718276dd83f783f55fd Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Fri, 19 Jul 2019 04:56:54 +0200 Subject: [PATCH 08/21] http-api: Return null obervables when failing --- .../runelite/http/api/item/ItemClient.java | 9 +++-- .../api/osbuddy/OSBGrandExchangeClient.java | 2 +- .../runelite/http/api/worlds/WorldClient.java | 38 ++++++++++--------- 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/http-api/src/main/java/net/runelite/http/api/item/ItemClient.java b/http-api/src/main/java/net/runelite/http/api/item/ItemClient.java index 2566a9c603..9305a7c695 100644 --- a/http-api/src/main/java/net/runelite/http/api/item/ItemClient.java +++ b/http-api/src/main/java/net/runelite/http/api/item/ItemClient.java @@ -34,6 +34,7 @@ import java.io.InputStreamReader; import java.lang.reflect.Type; import java.util.Arrays; import java.util.Map; +import java.util.Observer; import javax.imageio.ImageIO; import net.runelite.http.api.RuneLiteAPI; import okhttp3.HttpUrl; @@ -134,7 +135,7 @@ public class ItemClient if (!response.isSuccessful()) { logger.debug("Error grabbing icon {}: {}", itemId, response); - return null; + return Observable.just(null); } InputStream in = response.body().byteStream(); @@ -167,7 +168,7 @@ public class ItemClient if (!response.isSuccessful()) { logger.debug("Error looking up item {}: {}", itemName, response); - return null; + return Observable.just(null); } InputStream in = response.body().byteStream(); @@ -202,7 +203,7 @@ public class ItemClient if (!response.isSuccessful()) { logger.warn("Error looking up prices: {}", response); - return null; + return Observable.just(null); } InputStream in = response.body().byteStream(); @@ -238,7 +239,7 @@ public class ItemClient if (!response.isSuccessful()) { logger.warn("Error looking up item stats: {}", response); - return null; + return Observable.just(null); } InputStream in = response.body().byteStream(); diff --git a/http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeClient.java b/http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeClient.java index 3c187552fc..1739125f8c 100644 --- a/http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeClient.java +++ b/http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeClient.java @@ -58,7 +58,7 @@ public class OSBGrandExchangeClient { if (!response.isSuccessful()) { - throw new IOException("Error looking up item id: " + response); + return Observable.error(new IOException("Error looking up item id: " + response)); } final InputStream in = response.body().byteStream(); 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 668e088404..fbdbca9ad8 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,6 +26,7 @@ package net.runelite.http.api.worlds; import com.google.gson.JsonParseException; +import io.reactivex.Observable; import net.runelite.http.api.RuneLiteAPI; import okhttp3.HttpUrl; import okhttp3.Request; @@ -41,7 +42,7 @@ public class WorldClient { private static final Logger logger = LoggerFactory.getLogger(WorldClient.class); - public WorldResult lookupWorlds() throws IOException + public Observable lookupWorlds() { HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() .addPathSegment("worlds.js") @@ -49,24 +50,27 @@ public class WorldClient logger.debug("Built URI: {}", url); - Request request = new Request.Builder() - .url(url) - .build(); - - try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) + return Observable.defer(() -> { - if (!response.isSuccessful()) + Request request = new Request.Builder() + .url(url) + .build(); + + try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) { - logger.debug("Error looking up worlds: {}", response); - return null; - } + if (!response.isSuccessful()) + { + logger.debug("Error looking up worlds: {}", response); + return null; + } - InputStream in = response.body().byteStream(); - return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), WorldResult.class); - } - catch (JsonParseException ex) - { - throw new IOException(ex); - } + InputStream in = response.body().byteStream(); + return Observable.just(RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), WorldResult.class)); + } + catch (JsonParseException ex) + { + throw new IOException(ex); + } + }); } } From 1cddf12a2ce079e5b5968c014d8f1f092d6ebf84 Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Fri, 19 Jul 2019 05:00:39 +0200 Subject: [PATCH 09/21] http-api: Use observables for world api --- .../runelite/http/api/worlds/WorldClient.java | 4 +- .../defaultworld/DefaultWorldPlugin.java | 65 ++++++++++--------- .../worldhopper/WorldHopperPlugin.java | 32 ++++----- 3 files changed, 53 insertions(+), 48 deletions(-) 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 fbdbca9ad8..f213abcfa3 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 @@ -61,7 +61,7 @@ public class WorldClient if (!response.isSuccessful()) { logger.debug("Error looking up worlds: {}", response); - return null; + return Observable.just(null); } InputStream in = response.body().byteStream(); @@ -69,7 +69,7 @@ public class WorldClient } catch (JsonParseException ex) { - throw new IOException(ex); + return Observable.error(ex); } }); } 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 0999eda3c1..d8aed33f04 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,6 +25,7 @@ package net.runelite.client.plugins.defaultworld; import com.google.inject.Provides; +import io.reactivex.schedulers.Schedulers; import java.io.IOException; import javax.inject.Inject; import javax.inject.Singleton; @@ -32,6 +33,7 @@ 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.EventBus; import net.runelite.client.events.SessionOpen; @@ -60,6 +62,9 @@ public class DefaultWorldPlugin extends Plugin @Inject private EventBus eventBus; + @Inject + private ClientThread clientThread; + private final WorldClient worldClient = new WorldClient(); private int worldCache; private boolean worldChangeRequired; @@ -122,39 +127,39 @@ public class DefaultWorldPlugin extends Plugin return; } - try - { - final WorldResult worldResult = worldClient.lookupWorlds(); + worldClient.lookupWorlds() + .subscribeOn(Schedulers.io()) + .observeOn(Schedulers.from(clientThread)) + .subscribe( + (worldResult) -> + { + if (worldResult == null) + { + return; + } - if (worldResult == null) - { - return; - } + final World world = worldResult.findWorld(correctedWorld); - final World world = worldResult.findWorld(correctedWorld); + 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())); - 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); - } - } - catch (IOException e) - { - log.warn("Error looking up world {}. Error: {}", correctedWorld, e); - } + 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) + ); } private void applyWorld() 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 7613e456ce..89838a6cff 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 @@ -29,6 +29,7 @@ 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.io.IOException; import java.time.Duration; @@ -502,22 +503,21 @@ public class WorldHopperPlugin extends Plugin { log.debug("Fetching worlds"); - try - { - WorldResult worldResult = new WorldClient().lookupWorlds(); - - if (worldResult != null) - { - worldResult.getWorlds().sort(Comparator.comparingInt(World::getId)); - this.worldResult = worldResult; - this.lastFetch = Instant.now(); - updateList(); - } - } - catch (IOException ex) - { - log.warn("Error looking up worlds", ex); - } + new WorldClient().lookupWorlds() + .subscribeOn(Schedulers.io()) + .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) + ); } /** From 10fdb3da4cc99d5a3a610f3c48cce252c7112b56 Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Fri, 19 Jul 2019 05:04:15 +0200 Subject: [PATCH 10/21] http-api: checkstyle --- .../main/java/net/runelite/http/api/item/ItemClient.java | 1 - .../main/java/net/runelite/http/api/worlds/WorldClient.java | 6 ++---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/http-api/src/main/java/net/runelite/http/api/item/ItemClient.java b/http-api/src/main/java/net/runelite/http/api/item/ItemClient.java index 9305a7c695..0e34a05742 100644 --- a/http-api/src/main/java/net/runelite/http/api/item/ItemClient.java +++ b/http-api/src/main/java/net/runelite/http/api/item/ItemClient.java @@ -34,7 +34,6 @@ import java.io.InputStreamReader; import java.lang.reflect.Type; import java.util.Arrays; import java.util.Map; -import java.util.Observer; import javax.imageio.ImageIO; import net.runelite.http.api.RuneLiteAPI; import okhttp3.HttpUrl; 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 f213abcfa3..13559bdd3b 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 @@ -27,6 +27,8 @@ package net.runelite.http.api.worlds; import com.google.gson.JsonParseException; import io.reactivex.Observable; +import java.io.InputStream; +import java.io.InputStreamReader; import net.runelite.http.api.RuneLiteAPI; import okhttp3.HttpUrl; import okhttp3.Request; @@ -34,10 +36,6 @@ import okhttp3.Response; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; - public class WorldClient { private static final Logger logger = LoggerFactory.getLogger(WorldClient.class); From 049bc6e74f28beb79391ce5674c9ed0c7a8828fe Mon Sep 17 00:00:00 2001 From: Ganom Date: Thu, 18 Jul 2019 23:06:21 -0400 Subject: [PATCH 11/21] Revert "aoewarnings: rework AoE Warnings to use projectile spawned, rather than projectile moved. (#1032)" This reverts commit 948444b77113f090879d0199d5267f0ec0b84774. --- .../aoewarnings/AoeWarningOverlay.java | 34 +++-- .../plugins/aoewarnings/AoeWarningPlugin.java | 103 +++++++------- .../plugins/aoewarnings/BombOverlay.java | 131 +++++++++++------- .../plugins/aoewarnings/CrystalBomb.java | 11 +- .../aoewarnings/ProjectileContainer.java | 30 ---- 5 files changed, 151 insertions(+), 158 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/ProjectileContainer.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningOverlay.java index 135a55a71d..1dfeb1c1a0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningOverlay.java @@ -34,12 +34,14 @@ import java.awt.Polygon; import java.awt.Rectangle; import java.time.Duration; import java.time.Instant; -import java.util.Set; +import java.util.Iterator; +import java.util.Map; import javax.inject.Inject; import javax.inject.Singleton; import net.runelite.api.Client; import net.runelite.api.Perspective; import net.runelite.api.Point; +import net.runelite.api.Projectile; import net.runelite.api.coords.WorldPoint; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayLayer; @@ -90,35 +92,32 @@ public class AoeWarningOverlay extends Overlay } Instant now = Instant.now(); - Set projectiles = plugin.getProjectiles(); - projectiles.forEach(proj -> + Map projectiles = plugin.getProjectiles(); + for (Iterator it = projectiles.values().iterator(); it.hasNext(); ) { - if (proj.getTargetPoint() == null) - { - return; - } - + AoeProjectile aoeProjectile = it.next(); Color color; - - if (now.isAfter(proj.getStartTime().plus(Duration.ofMillis(proj.getLifetime())))) + if (now.isAfter(aoeProjectile.getStartTime().plus(Duration.ofMillis(aoeProjectile.getProjectileLifetime())))) { - return; + it.remove(); + continue; } - final Polygon tilePoly = Perspective.getCanvasTileAreaPoly(client, proj.getTargetPoint(), proj.getAoeProjectileInfo().getAoeSize()); + Polygon tilePoly = Perspective.getCanvasTileAreaPoly(client, aoeProjectile.getTargetPoint(), aoeProjectile.getAoeProjectileInfo().getAoeSize()); if (tilePoly == null) { - return; + continue; } - final double progress = (System.currentTimeMillis() - proj.getStartTime().toEpochMilli()) / (double) proj.getLifetime(); + // how far through the projectiles lifetime between 0-1. + double progress = (System.currentTimeMillis() - aoeProjectile.getStartTime().toEpochMilli()) / (double) aoeProjectile.getProjectileLifetime(); - final int tickProgress = proj.getFinalTick() - client.getTickCount(); + int tickProgress = aoeProjectile.getFinalTick() - client.getTickCount(); int fillAlpha, outlineAlpha; if (plugin.isConfigFadeEnabled()) { - fillAlpha = (int) ((1 - progress) * FILL_START_ALPHA); + fillAlpha = (int) ((1 - progress) * FILL_START_ALPHA);//alpha drop off over lifetime outlineAlpha = (int) ((1 - progress) * OUTLINE_START_ALPHA); } else @@ -166,8 +165,7 @@ public class AoeWarningOverlay extends Overlay graphics.setColor(new Color(setAlphaComponent(plugin.getOverlayColor().getRGB(), fillAlpha), true)); graphics.fillPolygon(tilePoly); - }); - projectiles.removeIf(proj -> now.isAfter(proj.getStartTime().plus(Duration.ofMillis(proj.getLifetime())))); + } return null; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningPlugin.java index 55f5c6838a..8c7a98d914 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningPlugin.java @@ -32,10 +32,9 @@ import java.awt.Color; import java.time.Instant; import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Set; import javax.inject.Inject; import javax.inject.Singleton; import lombok.AccessLevel; @@ -45,6 +44,7 @@ import net.runelite.api.Client; import net.runelite.api.GameObject; import net.runelite.api.GameState; import net.runelite.api.GraphicID; +import net.runelite.api.GraphicsObject; import net.runelite.api.NullObjectID; import net.runelite.api.ObjectID; import net.runelite.api.Projectile; @@ -57,7 +57,6 @@ import net.runelite.api.events.GameObjectSpawned; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.ProjectileMoved; -import net.runelite.api.events.ProjectileSpawned; import net.runelite.client.Notifier; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.EventBus; @@ -80,7 +79,7 @@ public class AoeWarningPlugin extends Plugin @Getter(AccessLevel.PACKAGE) private final Map bombs = new HashMap<>(); @Getter(AccessLevel.PACKAGE) - private final Set projectiles = new HashSet<>(); + private final Map projectiles = new HashMap<>(); @Inject public AoeWarningConfig config; @Inject @@ -103,6 +102,13 @@ public class AoeWarningPlugin extends Plugin private List CrystalSpike = new ArrayList<>(); @Getter(AccessLevel.PACKAGE) private List WintertodtSnowFall = new ArrayList<>(); + + @Provides + AoeWarningConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(AoeWarningConfig.class); + } + // Config values private boolean aoeNotifyAll; @Getter(AccessLevel.PACKAGE) @@ -162,17 +168,12 @@ public class AoeWarningPlugin extends Plugin private boolean configDemonicGorillaEnabled; private boolean configDemonicGorillaNotifyEnabled; - @Provides - AoeWarningConfig getConfig(ConfigManager configManager) - { - return configManager.getConfig(AoeWarningConfig.class); - } - @Override protected void startUp() throws Exception { updateConfig(); addSubscriptions(); + overlayManager.add(coreOverlay); overlayManager.add(bombOverlay); reset(); @@ -196,7 +197,6 @@ public class AoeWarningPlugin extends Plugin eventbus.subscribe(GameObjectDespawned.class, this, this::onGameObjectDespawned); eventbus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); eventbus.subscribe(GameTick.class, this, this::onGameTick); - eventbus.subscribe(ProjectileSpawned.class, this, this::onProjectileSpawned); } private void onConfigChanged(ConfigChanged event) @@ -209,52 +209,33 @@ public class AoeWarningPlugin extends Plugin updateConfig(); } - private void onProjectileSpawned(ProjectileSpawned event) + private void onProjectileMoved(ProjectileMoved event) { - final Projectile projectile = event.getProjectile(); + Projectile projectile = event.getProjectile(); - if (AoeProjectileInfo.getById(projectile.getId()) == null) - { - return; - } - - final int id = projectile.getId(); - final int lifetime = this.delay + (projectile.getRemainingCycles() * 20); + int projectileId = projectile.getId(); + int projectileLifetime = this.delay + (projectile.getRemainingCycles() * 20); int ticksRemaining = projectile.getRemainingCycles() / 30; - if (!isTickTimersEnabledForProjectileID(id)) + if (!isTickTimersEnabledForProjectileID(projectileId)) { ticksRemaining = 0; } - final int tickCycle = client.getTickCount() + ticksRemaining; - if (isConfigEnabledForProjectileId(id, false)) + int tickCycle = client.getTickCount() + ticksRemaining; + AoeProjectileInfo aoeProjectileInfo = AoeProjectileInfo.getById(projectileId); + if (aoeProjectileInfo != null + && isConfigEnabledForProjectileId(projectileId, false)) { - projectiles.add(new ProjectileContainer(projectile, Instant.now(), lifetime, tickCycle)); + LocalPoint targetPoint = event.getPosition(); + AoeProjectile aoeProjectile = new AoeProjectile(Instant.now(), targetPoint, aoeProjectileInfo, projectileLifetime, tickCycle); + projectiles.put(projectile, aoeProjectile); - if (this.aoeNotifyAll || isConfigEnabledForProjectileId(id, true)) + if (this.aoeNotifyAll || isConfigEnabledForProjectileId(projectileId, true)) { notifier.notify("AoE attack detected!"); } } } - private void onProjectileMoved(ProjectileMoved event) - { - if (projectiles.isEmpty()) - { - return; - } - - final Projectile projectile = event.getProjectile(); - - projectiles.forEach(proj -> - { - if (proj.getProjectile() == projectile) - { - proj.setTargetPoint(event.getPosition()); - } - }); - } - private void onGameObjectSpawned(GameObjectSpawned event) { final GameObject gameObject = event.getGameObject(); @@ -277,6 +258,7 @@ public class AoeWarningPlugin extends Plugin CrystalSpike.add(wp); break; case NullObjectID.NULL_26690: + //Wintertodt Snowfall if (this.configWintertodtEnabled) { WintertodtSnowFall.add(wp); @@ -306,7 +288,11 @@ public class AoeWarningPlugin extends Plugin CrystalSpike.remove(wp); break; case NullObjectID.NULL_26690: - WintertodtSnowFall.remove(wp); + //Wintertodt Snowfall + if (this.configWintertodtEnabled) + { + WintertodtSnowFall.remove(wp); + } break; } } @@ -321,11 +307,10 @@ public class AoeWarningPlugin extends Plugin private void onGameTick(GameTick event) { - LightningTrail.clear(); - if (this.configLightningTrail) { - client.getGraphicsObjects().forEach(o -> + LightningTrail.clear(); + for (GraphicsObject o : client.getGraphicsObjects()) { if (o.getId() == GraphicID.OLM_LIGHTNING) { @@ -336,29 +321,34 @@ public class AoeWarningPlugin extends Plugin notifier.notify("Lightning!"); } } - }); + } } - bombs.forEach((k, v) -> + for (Map.Entry entry : bombs.entrySet()) { - v.bombClockUpdate(); - }); + CrystalBomb bomb = entry.getValue(); + bomb.bombClockUpdate(); + //bombClockUpdate smooths the shown timer; not using this results in 1.2 --> .6 vs. 1.2 --> 1.1, etc. + } } private void purgeBombs(Map bombs) { + Iterator> it = bombs.entrySet().iterator(); Tile[][][] tiles = client.getScene().getTiles(); - bombs.forEach((k, v) -> + while (it.hasNext()) { - LocalPoint local = LocalPoint.fromWorld(client, k); + Map.Entry entry = it.next(); + WorldPoint world = entry.getKey(); + LocalPoint local = LocalPoint.fromWorld(client, world); if (local == null) { return; } - Tile tile = tiles[k.getPlane()][local.getSceneX()][local.getSceneY()]; + Tile tile = tiles[world.getPlane()][local.getSceneX()][local.getSceneY()]; GameObject[] objects = tile.getGameObjects(); boolean containsObjects = false; @@ -372,9 +362,10 @@ public class AoeWarningPlugin extends Plugin if (!containsObjects) { - bombs.remove(k, v); + it.remove(); } - }); + + } } private boolean isTickTimersEnabledForProjectileID(int projectileId) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/BombOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/BombOverlay.java index 9d56056d93..d51b52aee3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/BombOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/BombOverlay.java @@ -33,11 +33,13 @@ import java.text.DecimalFormat; import java.text.NumberFormat; import java.time.Instant; import java.util.Locale; +import java.util.Map; import javax.inject.Inject; import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.Perspective; +import net.runelite.api.Player; import net.runelite.api.Point; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; @@ -53,13 +55,24 @@ public class BombOverlay extends Overlay { private static final String SAFE = "#00cc00"; + //safe private static final String CAUTION = "#ffff00"; + //1 tile in range (minor damage) private static final String WARNING = "#ff9933"; + //2 tiles in range (moderate damage) private static final String DANGER = "#ff6600"; + //3 tiles in range/adjacent to bomb (major damage) private static final String LETHAL = "#cc0000"; + //On the bomb, using it as a makeshift space launch vehicle. (massive damage) + private static final int BOMB_AOE = 7; private static final int BOMB_DETONATE_TIME = 8; + //This is in ticks. It should be 10, but it varies from 8 to 11. private static final double ESTIMATED_TICK_LENGTH = .6; + //Thank you Woox & co. for this assumption. .6 seconds/tick. + + + //Utilized from the npc highlight code for formatting text being displayed on the client canvas. private static final NumberFormat TIME_LEFT_FORMATTER = DecimalFormat.getInstance(Locale.US); @@ -86,72 +99,84 @@ public class BombOverlay extends Overlay { if (plugin.isConfigbombDisplay()) { - drawDangerZone(graphics); + drawBombs(graphics); } return null; } - private void drawDangerZone(Graphics2D graphics) + private void drawBombs(Graphics2D graphics) + //I can condense drawDangerZone into this. Ambivalent though. { - final WorldPoint loc = client.getLocalPlayer().getWorldLocation(); - plugin.getBombs().forEach((k, v) -> + for (Map.Entry entry : plugin.getBombs().entrySet()) { - LocalPoint localLoc = LocalPoint.fromWorld(client, v.getWorldLocation()); + CrystalBomb bomb = entry.getValue(); + drawDangerZone(graphics, bomb); + } + } - if (localLoc == null) - { - return; - } + private void drawDangerZone(Graphics2D graphics, CrystalBomb bomb) + { + final Player localPlayer = client.getLocalPlayer(); + LocalPoint localLoc = LocalPoint.fromWorld(client, bomb.getWorldLocation()); + if (localLoc == null) + { + return; + } + double distance_x = Math.abs(bomb.getWorldLocation().getX() - localPlayer.getWorldLocation().getX()); + double distance_y = Math.abs(bomb.getWorldLocation().getY() - localPlayer.getWorldLocation().getY()); + Color color_code = Color.decode(SAFE); + //defaults to this unless conditionals met below. - final double distance_x = Math.abs(v.getWorldLocation().getX() - loc.getX()); - final double distance_y = Math.abs(v.getWorldLocation().getY() - loc.getY()); + if (distance_x < 1 && distance_y < 1) + { + color_code = Color.decode(LETHAL); + } + else if (distance_x < 2 && distance_y < 2) + { + color_code = Color.decode(DANGER); + } + else if (distance_x < 3 && distance_y < 3) + { + color_code = Color.decode(WARNING); + } + else if (distance_x < 4 && distance_y < 4) + { + color_code = Color.decode(CAUTION); + } + LocalPoint CenterPoint = new LocalPoint(localLoc.getX(), localLoc.getY()); + Polygon poly = Perspective.getCanvasTileAreaPoly(client, CenterPoint, BOMB_AOE); - Color color_code = Color.decode(SAFE); + if (poly != null) + { + //manually generating the polygon so as to assign a custom alpha value. Request adtl' arg for alpha maybe? + graphics.setColor(color_code); + graphics.setStroke(new BasicStroke(1)); + graphics.drawPolygon(poly); + graphics.setColor(new Color(0, 0, 0, 10)); + graphics.fillPolygon(poly); + } - if (distance_x < 1 && distance_y < 1) - { - color_code = Color.decode(LETHAL); - } - else if (distance_x < 2 && distance_y < 2) - { - color_code = Color.decode(DANGER); - } - else if (distance_x < 3 && distance_y < 3) - { - color_code = Color.decode(WARNING); - } - else if (distance_x < 4 && distance_y < 4) - { - color_code = Color.decode(CAUTION); - } - final LocalPoint CenterPoint = new LocalPoint(localLoc.getX(), localLoc.getY()); - final Polygon poly = Perspective.getCanvasTileAreaPoly(client, CenterPoint, BOMB_AOE); + Instant now = Instant.now(); + double timeLeft = ((BOMB_DETONATE_TIME - (client.getTickCount() - + bomb.getTickStarted())) * ESTIMATED_TICK_LENGTH) - + (now.toEpochMilli() - bomb.getLastClockUpdate().toEpochMilli()) / 1000.0; + //divided by 1000.00 because of milliseconds :) - if (poly != null) - { - graphics.setColor(color_code); - graphics.setStroke(new BasicStroke(1)); - graphics.drawPolygon(poly); - graphics.setColor(new Color(0, 0, 0, 10)); - graphics.fillPolygon(poly); - } + timeLeft = Math.max(0.0, timeLeft); + String bombTimerString = TIME_LEFT_FORMATTER.format(timeLeft); + int textWidth = graphics.getFontMetrics().stringWidth(bombTimerString); + int textHeight = graphics.getFontMetrics().getAscent(); + Point canvasPoint = Perspective.localToCanvas(client, localLoc.getX(), + localLoc.getY(), bomb.getWorldLocation().getPlane()); - final Instant now = Instant.now(); - double timeLeft = ((BOMB_DETONATE_TIME - (client.getTickCount() - v.getTickStarted())) * ESTIMATED_TICK_LENGTH) - - (now.toEpochMilli() - v.getLastClockUpdate().toEpochMilli()) / 1000.0; + if (canvasPoint != null) + { + Point canvasCenterPoint = new Point( + canvasPoint.getX() - textWidth / 2, + canvasPoint.getY() + textHeight / 2); + OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, bombTimerString, color_code); + } - timeLeft = Math.max(0.0, timeLeft); - final String bombTimerString = TIME_LEFT_FORMATTER.format(timeLeft); - final int textWidth = graphics.getFontMetrics().stringWidth(bombTimerString); - final int textHeight = graphics.getFontMetrics().getAscent(); - final Point canvasPoint = Perspective.localToCanvas(client, localLoc.getX(), localLoc.getY(), v.getWorldLocation().getPlane()); - - if (canvasPoint != null) - { - Point canvasCenterPoint = new Point(canvasPoint.getX() - textWidth / 2, canvasPoint.getY() + textHeight / 2); - OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, bombTimerString, color_code); - } - }); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/CrystalBomb.java b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/CrystalBomb.java index eb54538881..0a63fa4b97 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/CrystalBomb.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/CrystalBomb.java @@ -32,13 +32,22 @@ import net.runelite.api.GameObject; import net.runelite.api.coords.WorldPoint; @Slf4j -@Getter(AccessLevel.PACKAGE) class CrystalBomb { + @Getter(AccessLevel.PACKAGE) private Instant plantedOn; + + @Getter(AccessLevel.PACKAGE) private Instant lastClockUpdate; + + @Getter(AccessLevel.PACKAGE) private int objectId; + + @Getter(AccessLevel.PACKAGE) private int tickStarted; + // + + @Getter(AccessLevel.PACKAGE) private WorldPoint worldLocation; CrystalBomb(GameObject gameObject, int startTick) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/ProjectileContainer.java b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/ProjectileContainer.java deleted file mode 100644 index cb226d6262..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/ProjectileContainer.java +++ /dev/null @@ -1,30 +0,0 @@ -package net.runelite.client.plugins.aoewarnings; - -import java.time.Instant; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.Setter; -import net.runelite.api.Projectile; -import net.runelite.api.coords.LocalPoint; - -@Getter(AccessLevel.PACKAGE) -class ProjectileContainer -{ - private Projectile projectile; - private Instant startTime; - private AoeProjectileInfo aoeProjectileInfo; - private int lifetime; - private int finalTick; - @Setter(AccessLevel.PACKAGE) - private LocalPoint targetPoint; - - ProjectileContainer(Projectile projectile, Instant startTime, int lifetime, int finalTick) - { - this.projectile = projectile; - this.startTime = startTime; - this.targetPoint = null; - this.aoeProjectileInfo = AoeProjectileInfo.getById(projectile.getId()); - this.lifetime = lifetime; - this.finalTick = finalTick; - } -} From 7a863c207cfbedeb1c06879872581eb3a39df163 Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Fri, 19 Jul 2019 05:13:23 +0200 Subject: [PATCH 12/21] client: checkstyle --- .../src/main/java/net/runelite/client/game/ItemManager.java | 6 ++++-- .../client/plugins/defaultworld/DefaultWorldPlugin.java | 2 -- .../client/plugins/worldhopper/WorldHopperPlugin.java | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java b/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java index fc6a5f6d90..9a60cf848f 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java +++ b/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java @@ -142,6 +142,7 @@ public class ItemManager private final LoadingCache itemOutlines; private Map itemPrices = Collections.emptyMap(); private Map itemStats = Collections.emptyMap(); + @Inject public ItemManager( Client client, @@ -235,7 +236,8 @@ public class ItemManager itemClient.getStats() .subscribeOn(Schedulers.io()) .subscribe( - (stats) -> { + (stats) -> + { if (stats != null) { itemStats = ImmutableMap.copyOf(stats); @@ -284,7 +286,7 @@ public class ItemManager /** * Look up an item's price * - * @param itemID item id + * @param itemID item id * @param ignoreUntradeableMap should the price returned ignore the {@link UntradeableItemMapping} * @return item price */ 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 d8aed33f04..39614234bd 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 @@ -26,7 +26,6 @@ package net.runelite.client.plugins.defaultworld; import com.google.inject.Provides; import io.reactivex.schedulers.Schedulers; -import java.io.IOException; import javax.inject.Inject; import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; @@ -42,7 +41,6 @@ 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", 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 89838a6cff..1b99c8549c 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 @@ -31,7 +31,6 @@ import com.google.common.collect.ObjectArrays; import com.google.inject.Provides; import io.reactivex.schedulers.Schedulers; import java.awt.image.BufferedImage; -import java.io.IOException; import java.time.Duration; import java.time.Instant; import java.util.Comparator; From 36d1fd41485ee8cae7b836f9490756d283c018e3 Mon Sep 17 00:00:00 2001 From: Zeruth Date: Fri, 19 Jul 2019 00:46:04 -0400 Subject: [PATCH 13/21] live update --- live/bootstrap.json | 62 ++++++++++++------- .../java/net/runelite/client/RuneLite.java | 2 +- .../client/util/bootstrap/Bootstrap.java | 18 ++++-- .../client/util/bootstrap/Client.java | 2 +- 4 files changed, 56 insertions(+), 28 deletions(-) diff --git a/live/bootstrap.json b/live/bootstrap.json index 9256d3672d..e372264b28 100644 --- a/live/bootstrap.json +++ b/live/bootstrap.json @@ -1,12 +1,12 @@ { - "buildCommit": "b82c8903c64695d44b255d45b449440e4eaa17ef", + "buildCommit": "6fe334c02648d3f8b38625e3175e3f547d54aa37", "client": { "artifactId": "client", "classifier": "", "extension": "jar", "groupId": "net.runelite", "properties": "", - "version": "1.5.29" + "version": "1.5.30" }, "clientJvm9Arguments": [ "-XX:+DisableAttachMechanism", @@ -56,10 +56,10 @@ "size": "3168921" }, { - "hash": "08774848b10e8f76f96f364150a956d13c798e7c266d88cd0a0534e1f2f26c30", - "name": "client-1.5.29-SNAPSHOT.jar", - "path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/client-1.5.29-SNAPSHOT.jar", - "size": "6185577" + "hash": "d982191ebbd930b573e6d2242cdfefefdf1c610f1f046e204866749eefde1c5f", + "name": "client-1.5.30-SNAPSHOT.jar", + "path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/client-1.5.30-SNAPSHOT.jar", + "size": "6280727" }, { "hash": "18c4a0095d5c1da6b817592e767bb23d29dd2f560ad74df75ff3961dbde25b79", @@ -248,22 +248,22 @@ "size": "2327547" }, { - "hash": "b98cb800d9013cb3d84ba89a8ea8d54b88d66a2010f282cbf0265953b3f37491", - "name": "runelite-api-1.5.29-SNAPSHOT.jar", - "path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/runelite-api-1.5.29-SNAPSHOT.jar", - "size": "1031527" + "hash": "c0a81abdd6a7486851ef7f0df2ce70d7e362fb033eb5c4267a4a476e35a1824a", + "name": "runelite-api-1.5.30-SNAPSHOT.jar", + "path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/runelite-api-1.5.30-SNAPSHOT.jar", + "size": "1033784" }, { - "hash": "bfbd1bdea706a23799f9630adad9825acc358b8185a1cb8356853032f99d1a22", - "name": "runescape-api-1.5.29-SNAPSHOT.jar", - "path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/runescape-api-1.5.29-SNAPSHOT.jar", - "size": "58397" + "hash": "e8e743c2eb9e59f2990a5bdc48f061b7138890f065c0d603ecb8cdf0b0b158f7", + "name": "runescape-api-1.5.30-SNAPSHOT.jar", + "path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/runescape-api-1.5.30-SNAPSHOT.jar", + "size": "58398" }, { - "hash": "7ad65d4043416ddb09769c0b554fd43a9aa906d6934de03639310c6c552ecc6e", - "name": "http-api-1.5.29-SNAPSHOT.jar", - "path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/http-api-1.5.29-SNAPSHOT.jar", - "size": "138036" + "hash": "fea59d29ac883248bcc77a5f05b0cefebc226583d291f52d377e39db06fe7d19", + "name": "http-api-1.5.30-SNAPSHOT.jar", + "path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/http-api-1.5.30-SNAPSHOT.jar", + "size": "139678" }, { "hash": "f55abda036da75e1af45bd43b9dfa79b2a3d90905be9cb38687c6621597a8165", @@ -290,10 +290,28 @@ "size": "617294" }, { - "hash": "01521c7b56e2f76aa7adef5082c2f8ee8cf9e93b02d3b2f4101a30f750db9db4", - "name": "injected-client-1.5.29-SNAPSHOT.jar", - "path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/injected-client-1.5.29-SNAPSHOT.jar", - "size": "2252769" + "hash": "9f5333cb045ebd90b1ee457f1ceafc1a085265232926a24fb582ff1960bef703", + "name": "injected-client-1.5.30-SNAPSHOT.jar", + "path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/injected-client-1.5.30-SNAPSHOT.jar", + "size": "2253443" + }, + { + "hash": "21b5cac673a156cd8d6cf9efe15ff267b6353eeb129678aa4b39542683ba0dc2", + "name": "rxjava-2.2.10.jar", + "path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/artifacts/rxjava-2.2.10.jar", + "size": "2348810" + }, + { + "hash": "830a08b9d5c20ab8e2033c16fc6ee067e6ffcd0c730f303d648aadfa81210d62", + "name": "rxrelay-2.1.0.jar", + "path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/artifacts/rxrelay-2.1.0.jar", + "size": "27750" + }, + { + "hash": "830a08b9d5c20ab8e2033c16fc6ee067e6ffcd0c730f303d648aadfa81210d62", + "name": "reactive-streams-1.0.2.jar", + "path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/artifacts/reactive-streams-1.0.2.jar", + "size": "27750" } ] } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index 2993fdf108..c77abcdb59 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -72,7 +72,7 @@ import org.slf4j.LoggerFactory; @Slf4j public class RuneLite { - public static final String RUNELIT_VERSION = "2.0.3"; + public static final String RUNELIT_VERSION = "2.0.4"; public static final File RUNELITE_DIR = new File(System.getProperty("user.home"), ".runelite"); public static final File PROFILES_DIR = new File(RUNELITE_DIR, "profiles"); public static final File PLUGIN_DIR = new File(RUNELITE_DIR, "plugins"); diff --git a/runelite-client/src/main/java/net/runelite/client/util/bootstrap/Bootstrap.java b/runelite-client/src/main/java/net/runelite/client/util/bootstrap/Bootstrap.java index 88d3db7c96..5994063b8d 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/bootstrap/Bootstrap.java +++ b/runelite-client/src/main/java/net/runelite/client/util/bootstrap/Bootstrap.java @@ -15,7 +15,7 @@ import org.codehaus.plexus.util.FileUtils; public class Bootstrap { - String buildCommit = "b82c8903c64695d44b255d45b449440e4eaa17ef"; + String buildCommit = "6fe334c02648d3f8b38625e3175e3f547d54aa37"; Client client = new Client(); String[] clientJvm9Arguments = new String[]{ "-XX:+DisableAttachMechanism", @@ -106,7 +106,7 @@ public class Bootstrap { try { - artifacts = new Artifact[43]; + artifacts = new Artifact[46]; //Static artifacts artifacts[0] = new Artifact(); @@ -301,9 +301,19 @@ public class Bootstrap artifacts[41].size = "617294"; artifacts[43] = new Artifact(); artifacts[43].hash = "21b5cac673a156cd8d6cf9efe15ff267b6353eeb129678aa4b39542683ba0dc2"; - artifacts[43].name = "rxjava-2.2.10"; - artifacts[43].path = "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/" + artifacts[43].name; + artifacts[43].name = "rxjava-2.2.10.jar"; + artifacts[43].path = "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/artifacts/" + artifacts[43].name; artifacts[43].size = "2348810"; + artifacts[44] = new Artifact(); + artifacts[44].hash = "830a08b9d5c20ab8e2033c16fc6ee067e6ffcd0c730f303d648aadfa81210d62"; + artifacts[44].name = "rxrelay-2.1.0.jar"; + artifacts[44].path = "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/artifacts/" + artifacts[44].name; + artifacts[44].size = "27750"; + artifacts[45] = new Artifact(); + artifacts[45].hash = "cc09ab0b140e0d0496c2165d4b32ce24f4d6446c0a26c5dc77b06bdf99ee8fae"; + artifacts[45].name = "reactive-streams-1.0.2.jar"; + artifacts[45].path = "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/artifacts/" + artifacts[45].name; + artifacts[45].size = "27750"; //Dynamic artifacts artifacts[3] = new Artifact(); diff --git a/runelite-client/src/main/java/net/runelite/client/util/bootstrap/Client.java b/runelite-client/src/main/java/net/runelite/client/util/bootstrap/Client.java index 3f1374f71b..a8c1e18678 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/bootstrap/Client.java +++ b/runelite-client/src/main/java/net/runelite/client/util/bootstrap/Client.java @@ -8,5 +8,5 @@ public class Client String extension = "jar"; String groupId = "net.runelite"; String properties = ""; - String version = "1.5.29"; + String version = "1.5.30"; } From f4181265c0bf6a7db15f0994e39b09011be4d5a7 Mon Sep 17 00:00:00 2001 From: ThatGamerBlue Date: Fri, 19 Jul 2019 07:25:27 +0100 Subject: [PATCH 14/21] rs-client: refactor sprite loading methods --- runescape-client/src/main/java/Friend.java | 4 ++-- runescape-client/src/main/java/GameObject.java | 2 +- .../src/main/java/HealthBarDefinition.java | 4 ++-- runescape-client/src/main/java/HitSplatDefinition.java | 10 +++++----- runescape-client/src/main/java/PacketBuffer.java | 5 +++-- runescape-client/src/main/java/TilePaint.java | 2 +- runescape-client/src/main/java/Timer.java | 4 ++-- runescape-client/src/main/java/Widget.java | 4 ++-- runescape-client/src/main/java/WorldMapElement.java | 2 +- runescape-client/src/main/java/class215.java | 2 +- runescape-client/src/main/java/class287.java | 2 +- runescape-client/src/main/java/class289.java | 2 +- runescape-client/src/main/java/class65.java | 6 +++--- 13 files changed, 25 insertions(+), 24 deletions(-) diff --git a/runescape-client/src/main/java/Friend.java b/runescape-client/src/main/java/Friend.java index 81cbfa3ed8..feb55b9984 100644 --- a/runescape-client/src/main/java/Friend.java +++ b/runescape-client/src/main/java/Friend.java @@ -61,8 +61,8 @@ public class Friend extends Buddy { signature = "(Lhp;IIB)Z", garbageValue = "-3" ) - @Export("SpriteBuffer_loadSprite") - public static boolean SpriteBuffer_loadSprite(AbstractArchive var0, int var1, int var2) { + @Export("doesSpriteExist") + public static boolean doesSpriteExist(AbstractArchive var0, int var1, int var2) { byte[] var3 = var0.takeFile(var1, var2); if (var3 == null) { return false; diff --git a/runescape-client/src/main/java/GameObject.java b/runescape-client/src/main/java/GameObject.java index 5ec3ae7f8a..4af5cf4946 100644 --- a/runescape-client/src/main/java/GameObject.java +++ b/runescape-client/src/main/java/GameObject.java @@ -103,6 +103,6 @@ public final class GameObject { ) @Export("loadFont") public static Font loadFont(AbstractArchive var0, AbstractArchive var1, int var2, int var3) { - return !Friend.SpriteBuffer_loadSprite(var0, var2, var3) ? null : WallDecoration.getWorldMapSprite(var1.takeFile(var2, var3)); + return !Friend.doesSpriteExist(var0, var2, var3) ? null : WallDecoration.getWorldMapSprite(var1.takeFile(var2, var3)); } } diff --git a/runescape-client/src/main/java/HealthBarDefinition.java b/runescape-client/src/main/java/HealthBarDefinition.java index 1a2c02cdd1..a4c3723563 100644 --- a/runescape-client/src/main/java/HealthBarDefinition.java +++ b/runescape-client/src/main/java/HealthBarDefinition.java @@ -172,7 +172,7 @@ public class HealthBarDefinition extends DualNode { if (var1 != null) { return var1; } else { - var1 = class65.SpriteBuffer_tryCreateSprite(HealthBarDefinition_spritesArchive, this.frontSpriteID, 0); + var1 = class65.loadSprite(HealthBarDefinition_spritesArchive, this.frontSpriteID, 0); if (var1 != null) { HealthBarDefinition_cachedSprites.put(var1, (long)this.frontSpriteID); } @@ -196,7 +196,7 @@ public class HealthBarDefinition extends DualNode { if (var1 != null) { return var1; } else { - var1 = class65.SpriteBuffer_tryCreateSprite(HealthBarDefinition_spritesArchive, this.backSpriteID, 0); + var1 = class65.loadSprite(HealthBarDefinition_spritesArchive, this.backSpriteID, 0); if (var1 != null) { HealthBarDefinition_cachedSprites.put(var1, (long)this.backSpriteID); } diff --git a/runescape-client/src/main/java/HitSplatDefinition.java b/runescape-client/src/main/java/HitSplatDefinition.java index 486167e105..06745eeb1c 100644 --- a/runescape-client/src/main/java/HitSplatDefinition.java +++ b/runescape-client/src/main/java/HitSplatDefinition.java @@ -290,7 +290,7 @@ public class HitSplatDefinition extends DualNode { if (var1 != null) { return var1; } else { - var1 = class65.SpriteBuffer_tryCreateSprite(HitSplatDefinition_spritesArchive, this.field3334, 0); + var1 = class65.loadSprite(HitSplatDefinition_spritesArchive, this.field3334, 0); if (var1 != null) { HitSplatDefinition_cachedSprites.put(var1, (long)this.field3334); } @@ -313,7 +313,7 @@ public class HitSplatDefinition extends DualNode { if (var1 != null) { return var1; } else { - var1 = class65.SpriteBuffer_tryCreateSprite(HitSplatDefinition_spritesArchive, this.field3336, 0); + var1 = class65.loadSprite(HitSplatDefinition_spritesArchive, this.field3336, 0); if (var1 != null) { HitSplatDefinition_cachedSprites.put(var1, (long)this.field3336); } @@ -336,7 +336,7 @@ public class HitSplatDefinition extends DualNode { if (var1 != null) { return var1; } else { - var1 = class65.SpriteBuffer_tryCreateSprite(HitSplatDefinition_spritesArchive, this.field3337, 0); + var1 = class65.loadSprite(HitSplatDefinition_spritesArchive, this.field3337, 0); if (var1 != null) { HitSplatDefinition_cachedSprites.put(var1, (long)this.field3337); } @@ -359,7 +359,7 @@ public class HitSplatDefinition extends DualNode { if (var1 != null) { return var1; } else { - var1 = class65.SpriteBuffer_tryCreateSprite(HitSplatDefinition_spritesArchive, this.field3338, 0); + var1 = class65.loadSprite(HitSplatDefinition_spritesArchive, this.field3338, 0); if (var1 != null) { HitSplatDefinition_cachedSprites.put(var1, (long)this.field3338); } @@ -387,7 +387,7 @@ public class HitSplatDefinition extends DualNode { AbstractArchive var4 = HitSplatDefinition_fontsArchive; int var5 = this.fontId; Font var2; - if (!Friend.SpriteBuffer_loadSprite(var3, var5, 0)) { + if (!Friend.doesSpriteExist(var3, var5, 0)) { var2 = null; } else { var2 = WallDecoration.getWorldMapSprite(var4.takeFile(var5, 0)); diff --git a/runescape-client/src/main/java/PacketBuffer.java b/runescape-client/src/main/java/PacketBuffer.java index da87ae854d..77a0c37783 100644 --- a/runescape-client/src/main/java/PacketBuffer.java +++ b/runescape-client/src/main/java/PacketBuffer.java @@ -169,8 +169,9 @@ public class PacketBuffer extends Buffer { signature = "(Lhp;III)Llx;", garbageValue = "-1232611828" ) - static IndexedSprite method5474(AbstractArchive var0, int var1, int var2) { - if (!Friend.SpriteBuffer_loadSprite(var0, var1, var2)) { + @Export("loadIndexedSprite") + static IndexedSprite loadIndexedSprite(AbstractArchive var0, int var1, int var2) { + if (!Friend.doesSpriteExist(var0, var1, var2)) { return null; } else { IndexedSprite var4 = new IndexedSprite(); diff --git a/runescape-client/src/main/java/TilePaint.java b/runescape-client/src/main/java/TilePaint.java index 3a78f78d8f..f883e9d16a 100644 --- a/runescape-client/src/main/java/TilePaint.java +++ b/runescape-client/src/main/java/TilePaint.java @@ -64,7 +64,7 @@ public final class TilePaint { garbageValue = "1591290793" ) public static Sprite[] method3062(AbstractArchive var0, int var1, int var2) { - if (!Friend.SpriteBuffer_loadSprite(var0, var1, var2)) { + if (!Friend.doesSpriteExist(var0, var1, var2)) { return null; } else { Sprite[] var4 = new Sprite[class326.SpriteBuffer_spriteCount]; diff --git a/runescape-client/src/main/java/Timer.java b/runescape-client/src/main/java/Timer.java index 73f0f5e74d..ad1070f05d 100644 --- a/runescape-client/src/main/java/Timer.java +++ b/runescape-client/src/main/java/Timer.java @@ -491,13 +491,13 @@ public class Timer { } else if (Client.titleLoadingStage == 80) { var0 = 0; if (Message.compass == null) { - Message.compass = class65.SpriteBuffer_tryCreateSprite(Client.archive8, UserComparator6.spriteIds.compass, 0); + Message.compass = class65.loadSprite(Client.archive8, UserComparator6.spriteIds.compass, 0); } else { ++var0; } if (UserComparator4.redHintArrowSprite == null) { - UserComparator4.redHintArrowSprite = class65.SpriteBuffer_tryCreateSprite(Client.archive8, UserComparator6.spriteIds.field3823, 0); + UserComparator4.redHintArrowSprite = class65.loadSprite(Client.archive8, UserComparator6.spriteIds.field3823, 0); } else { ++var0; } diff --git a/runescape-client/src/main/java/Widget.java b/runescape-client/src/main/java/Widget.java index 43f82fc040..f926090468 100644 --- a/runescape-client/src/main/java/Widget.java +++ b/runescape-client/src/main/java/Widget.java @@ -1271,7 +1271,7 @@ public class Widget extends Node { if (var5 != null) { return var5; } else { - var5 = class65.SpriteBuffer_tryCreateSprite(class216.Widget_spritesArchive, var2, 0); + var5 = class65.loadSprite(class216.Widget_spritesArchive, var2, 0); if (var5 == null) { field2562 = true; return null; @@ -1351,7 +1351,7 @@ public class Widget extends Node { if (var3 != null) { return var3; } else { - var3 = class65.SpriteBuffer_tryCreateSprite(class216.Widget_spritesArchive, var2, 0); + var3 = class65.loadSprite(class216.Widget_spritesArchive, var2, 0); if (var3 != null) { Widget_cachedSprites.put(var3, (long)var2); } else { diff --git a/runescape-client/src/main/java/WorldMapElement.java b/runescape-client/src/main/java/WorldMapElement.java index c7e1267222..1cc5978b06 100644 --- a/runescape-client/src/main/java/WorldMapElement.java +++ b/runescape-client/src/main/java/WorldMapElement.java @@ -283,7 +283,7 @@ public class WorldMapElement extends DualNode { if (var2 != null) { return var2; } else { - var2 = class65.SpriteBuffer_tryCreateSprite(WorldMapElement_archive, var1, 0); + var2 = class65.loadSprite(WorldMapElement_archive, var1, 0); if (var2 != null) { WorldMapElement_cachedSprites.put(var2, (long)var1); } diff --git a/runescape-client/src/main/java/class215.java b/runescape-client/src/main/java/class215.java index a316f84c1d..9270440606 100644 --- a/runescape-client/src/main/java/class215.java +++ b/runescape-client/src/main/java/class215.java @@ -71,7 +71,7 @@ public class class215 { public static IndexedSprite loadIndexedSpriteByName(AbstractArchive var0, String var1, String var2) { int var3 = var0.getGroupId(var1); int var4 = var0.getFileId(var3, var2); - return PacketBuffer.method5474(var0, var3, var4); + return PacketBuffer.loadIndexedSprite(var0, var3, var4); } @ObfuscatedName("eg") diff --git a/runescape-client/src/main/java/class287.java b/runescape-client/src/main/java/class287.java index c664792bcb..caf7f7f4bc 100644 --- a/runescape-client/src/main/java/class287.java +++ b/runescape-client/src/main/java/class287.java @@ -12,7 +12,7 @@ public class class287 { int var4 = var0.getGroupId(var2); int var5 = var0.getFileId(var4, var3); Font var6; - if (!Friend.SpriteBuffer_loadSprite(var0, var4, var5)) { + if (!Friend.doesSpriteExist(var0, var4, var5)) { var6 = null; } else { var6 = WallDecoration.getWorldMapSprite(var1.takeFile(var4, var5)); diff --git a/runescape-client/src/main/java/class289.java b/runescape-client/src/main/java/class289.java index 347dcc1dfb..f97846313b 100644 --- a/runescape-client/src/main/java/class289.java +++ b/runescape-client/src/main/java/class289.java @@ -26,7 +26,7 @@ public final class class289 { garbageValue = "1777014825" ) public static IndexedSprite[] method5281(AbstractArchive var0, int var1, int var2) { - if (!Friend.SpriteBuffer_loadSprite(var0, var1, var2)) { + if (!Friend.doesSpriteExist(var0, var1, var2)) { return null; } else { IndexedSprite[] var4 = new IndexedSprite[class326.SpriteBuffer_spriteCount]; diff --git a/runescape-client/src/main/java/class65.java b/runescape-client/src/main/java/class65.java index 3a103e802a..db52abf11f 100644 --- a/runescape-client/src/main/java/class65.java +++ b/runescape-client/src/main/java/class65.java @@ -69,9 +69,9 @@ public class class65 extends RouteStrategy { signature = "(Lhp;III)Lly;", garbageValue = "300652258" ) - @Export("SpriteBuffer_tryCreateSprite") - public static Sprite SpriteBuffer_tryCreateSprite(AbstractArchive var0, int var1, int var2) { - if (!Friend.SpriteBuffer_loadSprite(var0, var1, var2)) { + @Export("loadSprite") + public static Sprite loadSprite(AbstractArchive var0, int var1, int var2) { + if (!Friend.doesSpriteExist(var0, var1, var2)) { return null; } else { Sprite var4 = new Sprite(); From 7df795101b4f1a20a313c6233e35a5617748faa5 Mon Sep 17 00:00:00 2001 From: ThatGamerBlue Date: Fri, 19 Jul 2019 07:25:54 +0100 Subject: [PATCH 15/21] mixins: replace loadSprite mixin --- .../java/net/runelite/mixins/SpriteMixin.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/SpriteMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/SpriteMixin.java index 83e1cde163..78bf89adac 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/SpriteMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/SpriteMixin.java @@ -3,9 +3,14 @@ package net.runelite.mixins; import net.runelite.api.Sprite; import java.util.HashMap; import java.util.Map; + +import net.runelite.api.mixins.Copy; import net.runelite.api.mixins.Inject; import net.runelite.api.mixins.Mixin; +import net.runelite.api.mixins.Replace; +import net.runelite.rs.api.RSAbstractArchive; import net.runelite.rs.api.RSClient; +import net.runelite.rs.api.RSSprite; @Mixin(RSClient.class) public abstract class SpriteMixin implements RSClient @@ -29,4 +34,23 @@ public abstract class SpriteMixin implements RSClient { return widgetSpriteOverrides; } + + @Copy("loadSprite") + public static RSSprite rs$loadSprite(RSAbstractArchive var0, int var1, int var2) + { + throw new RuntimeException(); + } + + @Replace("loadSprite") + public static RSSprite rl$loadSprite(RSAbstractArchive var0, int var1, int var2) + { + Sprite sprite = spriteOverrides.get(var1); + + if (sprite != null) + { + return (RSSprite) sprite; + } + + return rs$loadSprite(var0, var1, var2); + } } \ No newline at end of file From 24b7aff85ae199b34d04a306c36833a2e28ad2db Mon Sep 17 00:00:00 2001 From: Justin Date: Fri, 19 Jul 2019 17:28:36 +1000 Subject: [PATCH 16/21] grandexchangeplugin: fixed duplicate price string (#1041) fixes #1039 --- .../plugins/grandexchange/GrandExchangePlugin.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java index b8ffc3c9b1..c9604a9382 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java @@ -544,12 +544,6 @@ public class GrandExchangePlugin extends Plugin executorService.submit(() -> { - if (geText.getText().contains(OSB_GE_TEXT)) - { - // If there are multiple tasks queued and one of them have already added the price - return; - } - CLIENT.lookupItem(itemId) .subscribeOn(Schedulers.io()) .observeOn(Schedulers.from(clientThread)) @@ -557,6 +551,11 @@ public class GrandExchangePlugin extends Plugin (osbresult) -> { final String text = geText.getText() + OSB_GE_TEXT + StackFormatter.formatNumber(osbresult.getOverall_average()); + if (geText.getText().contains(OSB_GE_TEXT)) + { + // If there are multiple tasks queued and one of them have already added the price + return; + } geText.setText(text); }, (e) -> log.debug("Error getting price of item {}", itemId, e) From d08d80c468ec45a512f96c737a78d93f2d0ca4fe Mon Sep 17 00:00:00 2001 From: James <38226001+f0rmatme@users.noreply.github.com> Date: Fri, 19 Jul 2019 01:28:05 -0700 Subject: [PATCH 17/21] ChatCommands: Add Clipboard Support (#1040) * Add Chat Input Clipboard Support Add CTRL+V and CTRL+C support to the in-game chatbox. Fixes an issue with errors being thrown when shortcuts were used when not currently logged in. Extracts clipboard logic (a couple places already had a sort of "copy" functionality) to a simple clipboard util. * Checkstyle fix --- .../chatcommands/ChatCommandsConfig.java | 11 ++++ .../chatcommands/ChatKeyboardListener.java | 42 ++++++++++++- .../plugins/screenshot/ScreenshotPlugin.java | 12 ++-- .../net/runelite/client/util/Clipboard.java | 62 +++++++++++++++++++ .../net/runelite/client/util/LinkBrowser.java | 5 +- 5 files changed, 118 insertions(+), 14 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/util/Clipboard.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsConfig.java index 835ccec71e..a7e4963bcc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsConfig.java @@ -129,4 +129,15 @@ public interface ChatCommandsConfig extends Config { return true; } + + @ConfigItem( + position = 5, + keyName = "clipboardShortcuts", + name = "Clipboard shortcuts", + description = "Enable clipboard shortcuts (ctrl+c and ctrl+v)" + ) + default boolean clipboardShortcuts() + { + return true; + } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatKeyboardListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatKeyboardListener.java index d32dab3fc1..cd2678e520 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatKeyboardListener.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatKeyboardListener.java @@ -29,9 +29,11 @@ import javax.inject.Inject; import javax.inject.Singleton; import net.runelite.api.Client; import net.runelite.api.ScriptID; +import net.runelite.api.GameState; import net.runelite.api.VarClientStr; import net.runelite.client.callback.ClientThread; import net.runelite.client.input.KeyListener; +import net.runelite.client.util.Clipboard; @Singleton class ChatKeyboardListener implements KeyListener @@ -54,15 +56,45 @@ class ChatKeyboardListener implements KeyListener @Override public void keyPressed(KeyEvent e) { - if (!e.isControlDown() || !chatCommandsConfig.clearShortcuts()) + if (!e.isControlDown() || client.getGameState() != GameState.LOGGED_IN) { return; } + String input = client.getVar(VarClientStr.CHATBOX_TYPED_TEXT); + switch (e.getKeyCode()) { + case KeyEvent.VK_C: + if (!chatCommandsConfig.clipboardShortcuts()) + { + break; + } + + Clipboard.store(input); + + break; + case KeyEvent.VK_V: + if (!chatCommandsConfig.clipboardShortcuts()) + { + break; + } + + final String clipboard = Clipboard.retrieve(); + if (clipboard != null && !clipboard.isEmpty()) + { + final String replacement = input + clipboard; + + clientThread.invoke(() -> client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, replacement)); + } + + break; case KeyEvent.VK_W: - String input = client.getVar(VarClientStr.CHATBOX_TYPED_TEXT); + if (!chatCommandsConfig.clearShortcuts()) + { + break; + } + if (input != null) { // remove trailing space @@ -96,6 +128,12 @@ class ChatKeyboardListener implements KeyListener client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, ""); client.runScript(ScriptID.CHAT_PROMPT_INIT); }); + if (!chatCommandsConfig.clearShortcuts()) + { + break; + } + + clientThread.invoke(() -> client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, "")); break; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java index 73991b48fa..421341e75f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java @@ -32,10 +32,7 @@ import com.google.inject.Provides; import java.awt.Desktop; import java.awt.Graphics; import java.awt.Image; -import java.awt.Toolkit; import java.awt.TrayIcon; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.StringSelection; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; @@ -103,6 +100,7 @@ import net.runelite.client.ui.ClientUI; import net.runelite.client.ui.DrawManager; import net.runelite.client.ui.NavigationButton; import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.util.Clipboard; import net.runelite.client.util.HotkeyListener; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.Text; @@ -247,7 +245,7 @@ public class ScreenshotPlugin extends Plugin { updateConfig(); addSubscriptions(); - + overlayManager.add(screenshotOverlay); SCREENSHOT_DIR.mkdirs(); keyManager.registerKeyListener(hotkeyListener); @@ -855,9 +853,7 @@ public class ScreenshotPlugin extends Plugin { String link = imageUploadResponse.getData().getLink(); - StringSelection selection = new StringSelection(link); - Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); - clipboard.setContents(selection, selection); + Clipboard.store(link); if (notifyWhenTaken) { @@ -915,7 +911,7 @@ public class ScreenshotPlugin extends Plugin updateConfig(); } - + private void updateConfig() { this.includeFrame = config.includeFrame(); diff --git a/runelite-client/src/main/java/net/runelite/client/util/Clipboard.java b/runelite-client/src/main/java/net/runelite/client/util/Clipboard.java new file mode 100644 index 0000000000..58932ba5ed --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/util/Clipboard.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2018, Connor + * 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.awt.Toolkit; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.IOException; + +public class Clipboard +{ + public static String retrieve() + { + Transferable contents = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null); + + if (contents == null || ! contents.isDataFlavorSupported(DataFlavor.stringFlavor)) + { + return null; + } + + try + { + return (String) contents.getTransferData(DataFlavor.stringFlavor); + } + catch (UnsupportedFlavorException | IOException ex) + { + return null; + } + } + + public static void store(String contents) + { + final StringSelection selection = new StringSelection(contents); + + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, null); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/util/LinkBrowser.java b/runelite-client/src/main/java/net/runelite/client/util/LinkBrowser.java index 793ccaf8a0..094ae56102 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/LinkBrowser.java +++ b/runelite-client/src/main/java/net/runelite/client/util/LinkBrowser.java @@ -26,8 +26,6 @@ package net.runelite.client.util; import com.google.common.base.Strings; import java.awt.Desktop; -import java.awt.Toolkit; -import java.awt.datatransfer.StringSelection; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; @@ -144,8 +142,7 @@ public class LinkBrowser if (result == JOptionPane.OK_OPTION) { - final StringSelection stringSelection = new StringSelection(data); - Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null); + Clipboard.store(data); } }); } From 3675061f21d6e2ad25bb24980db133256616f1a4 Mon Sep 17 00:00:00 2001 From: James <38226001+f0rmatme@users.noreply.github.com> Date: Fri, 19 Jul 2019 02:13:45 -0700 Subject: [PATCH 18/21] grandexchange: Shows the quantity you can buy on the GE WIP (#1042) * Add measures to ensure positions of strings when togg:ling configItem change method of gathering price per item change math.round to math.floor, errors when certain numbers are rounded fix * implement geBuilt script event, clear values when item isn't visible * Update * Update pos number * Update --- .../main/java/net/runelite/api/Varbits.java | 5 ++ .../grandexchange/GrandExchangeConfig.java | 11 +++ .../grandexchange/GrandExchangePlugin.java | 90 +++++++++++++++---- 3 files changed, 87 insertions(+), 19 deletions(-) diff --git a/runelite-api/src/main/java/net/runelite/api/Varbits.java b/runelite-api/src/main/java/net/runelite/api/Varbits.java index 28486dc43f..48c138e013 100644 --- a/runelite-api/src/main/java/net/runelite/api/Varbits.java +++ b/runelite-api/src/main/java/net/runelite/api/Varbits.java @@ -49,6 +49,11 @@ public enum Varbits */ CHAT_SCROLLBAR_ON_LEFT(6374), + /** + * Grand Exchange + */ + GRAND_EXCHANGE_PRICE_PER_ITEM(4398), + /** * Runepouch */ diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeConfig.java index b1eb1e212c..b2ca3c22de 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeConfig.java @@ -96,4 +96,15 @@ public interface GrandExchangeConfig extends Config { return false; } + + @ConfigItem( + position = 7, + keyName = "enableAfford", + name = "Enable Afford quantity on GE", + description = "Shows the quantity you can buy on the GE" + ) + default boolean enableAfford() + { + return true; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java index c9604a9382..afd9b1de9a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java @@ -48,14 +48,18 @@ import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.GrandExchangeOffer; import net.runelite.api.GrandExchangeOfferState; +import net.runelite.api.InventoryID; +import net.runelite.api.Item; +import net.runelite.api.ItemContainer; import net.runelite.api.ItemDefinition; +import static net.runelite.api.ItemID.COINS_995; import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; +import net.runelite.api.Varbits; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.FocusChanged; import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.GameTick; import net.runelite.api.events.GrandExchangeOfferChanged; import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.ScriptCallbackEvent; @@ -99,7 +103,8 @@ public class GrandExchangePlugin extends Plugin private static final OSBGrandExchangeClient CLIENT = new OSBGrandExchangeClient(); private static final String OSB_GE_TEXT = "
OSBuddy Actively traded price: "; - private static final String BUY_LIMIT_GE_TEXT = "
Buy limit: "; + private static final String BUY_LIMIT_GE_TEXT = "Buy limit: "; + private static final String AFFORD_GE_TEXT = "
Afford: "; private static final Gson GSON = new Gson(); private static final TypeToken> BUY_LIMIT_TOKEN = new TypeToken>() { @@ -162,6 +167,13 @@ public class GrandExchangePlugin extends Plugin private GrandExchangeClient grandExchangeClient; + private int coins = 0; + private int lastAmount = -1; + private int lastItem = -1; + + private int osbItem = -1; + private String osbText = ""; + private SavedOffer getOffer(int slot) { String offer = configManager.getConfiguration("geoffer." + client.getUsername().toLowerCase(), Integer.toString(slot)); @@ -186,6 +198,7 @@ public class GrandExchangePlugin extends Plugin private boolean enableNotifications; private boolean enableOsbPrices; private boolean enableGELimits; + private boolean enableAfford; @Provides GrandExchangeConfig provideConfig(ConfigManager configManager) @@ -244,7 +257,6 @@ public class GrandExchangePlugin extends Plugin private void addSubscriptions() { eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); - eventBus.subscribe(GameTick.class, this, this::onGameTick); eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); eventBus.subscribe(SessionOpen.class, this, this::onSessionOpen); eventBus.subscribe(SessionClose.class, this, this::onSessionClose); @@ -254,7 +266,6 @@ public class GrandExchangePlugin extends Plugin eventBus.subscribe(FocusChanged.class, this, this::onFocusChanged); eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent); - eventBus.subscribe(GameTick.class, this, this::onGameTick); } private void onSessionOpen(SessionOpen sessionOpen) @@ -276,6 +287,7 @@ public class GrandExchangePlugin extends Plugin this.enableNotifications = config.enableNotifications(); this.enableOsbPrices = config.enableOsbPrices(); this.enableGELimits = config.enableGELimits(); + this.enableAfford = config.enableAfford(); } private void onSessionClose(SessionClose sessionClose) @@ -465,6 +477,11 @@ public class GrandExchangePlugin extends Plugin private void onScriptCallbackEvent(ScriptCallbackEvent event) { + if (event.getEventName().equals("geBuilt")) + { + rebuildGeText(); + } + if (!event.getEventName().equals("setGETitle") || !config.showTotal()) { return; @@ -505,7 +522,7 @@ public class GrandExchangePlugin extends Plugin stringStack[stringStackSize - 1] += titleBuilder.toString(); } - private void onGameTick(GameTick event) + public void rebuildGeText() { if (grandExchangeText == null || grandExchangeItem == null || grandExchangeItem.isHidden()) { @@ -513,34 +530,74 @@ public class GrandExchangePlugin extends Plugin } final Widget geText = grandExchangeText; - final String geTextString = geText.getText(); final int itemId = grandExchangeItem.getItemId(); if (itemId == OFFER_DEFAULT_ITEM_ID || itemId == -1) { + lastAmount = osbItem = lastItem = -1; // This item is invalid/nothing has been searched for return; } - if (this.enableGELimits && itemGELimits != null && !geTextString.contains(BUY_LIMIT_GE_TEXT)) + final int currentItemPrice = client.getVar(Varbits.GRAND_EXCHANGE_PRICE_PER_ITEM); + + if (lastItem == itemId && lastAmount == currentItemPrice ) + { + return; + } + + lastItem = itemId; + lastAmount = currentItemPrice; + + String[] texts = geText.getText().split("
"); + String text = texts[0]; + + if (this.enableAfford) + { + final ItemContainer itemContainer = client.getItemContainer(InventoryID.INVENTORY); + final Item[] items = itemContainer.getItems(); + for (Item item : items) + { + if (item.getId() == COINS_995) + { + coins = item.getQuantity(); + break; + } + } + + text += AFFORD_GE_TEXT + StackFormatter.formatNumber(coins / currentItemPrice) + " "; + } + + if (this.enableGELimits && itemGELimits != null) { final Integer itemLimit = itemGELimits.get(itemId); // If we have item buy limit, append it if (itemLimit != null) { - final String text = geText.getText() + BUY_LIMIT_GE_TEXT + StackFormatter.formatNumber(itemLimit); - geText.setText(text); + text += (!this.enableAfford ? "
" : "") + BUY_LIMIT_GE_TEXT + StackFormatter.formatNumber(itemLimit); } } - if (!this.enableOsbPrices || geTextString.contains(OSB_GE_TEXT)) + if (!this.enableOsbPrices) + { - // OSB prices are disabled or price was already looked up, so no need to set it again + geText.setText(text); return; } + geText.setText(text + osbText); + log.debug("Looking up OSB item price {}", itemId); + if (osbItem == lastItem) + { + // OSB Item was already looked up + return; + } + + osbItem = lastItem; + + final String str = text; executorService.submit(() -> { @@ -550,13 +607,8 @@ public class GrandExchangePlugin extends Plugin .subscribe( (osbresult) -> { - final String text = geText.getText() + OSB_GE_TEXT + StackFormatter.formatNumber(osbresult.getOverall_average()); - if (geText.getText().contains(OSB_GE_TEXT)) - { - // If there are multiple tasks queued and one of them have already added the price - return; - } - geText.setText(text); + osbText = OSB_GE_TEXT + StackFormatter.formatNumber(osbresult.getOverall_average()); + geText.setText(str + osbText); }, (e) -> log.debug("Error getting price of item {}", itemId, e) ); @@ -570,4 +622,4 @@ public class GrandExchangePlugin extends Plugin log.debug("Loaded {} limits", itemGELimits.size()); return itemGELimits; } -} +} \ No newline at end of file From a0711cb3df93ed2760db3bf5f7df8fc2f80ac14a Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Fri, 19 Jul 2019 12:22:50 +0200 Subject: [PATCH 19/21] idlenotifier: Fix plugin (#1043) --- .../runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java | 1 + 1 file changed, 1 insertion(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java index 57f2bbab2f..09bc5ab850 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java @@ -896,6 +896,7 @@ public class IdleNotifierPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); } @Override From 3fd290b2a88215f1af07ac9d9fefdda6869c55bc Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Fri, 19 Jul 2019 12:50:43 +0200 Subject: [PATCH 20/21] client: Initialize managers to make them subscribe to events (#1044) --- .../java/net/runelite/client/RuneLite.java | 51 ++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index c77abcdb59..250b90f877 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -48,9 +48,15 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.client.account.SessionManager; import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.chat.CommandManager; import net.runelite.client.config.ConfigManager; import net.runelite.client.discord.DiscordService; +import net.runelite.client.game.ClanManager; +import net.runelite.client.game.ItemManager; +import net.runelite.client.game.LootManager; +import net.runelite.client.game.chatbox.ChatboxPanelManager; import net.runelite.client.graphics.ModelOutlineRenderer; +import net.runelite.client.menus.MenuManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginInstantiationException; import net.runelite.client.plugins.PluginManager; @@ -58,14 +64,18 @@ import net.runelite.client.rs.ClientLoader; import net.runelite.client.rs.ClientUpdateCheckMode; import net.runelite.client.task.Scheduler; import net.runelite.client.ui.ClientUI; +import net.runelite.client.ui.DrawManager; import net.runelite.client.ui.RuneLiteSplashScreen; import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.ui.overlay.OverlayRenderer; import net.runelite.client.ui.overlay.WidgetOverlay; import net.runelite.client.ui.overlay.arrow.ArrowMinimapOverlay; import net.runelite.client.ui.overlay.arrow.ArrowWorldOverlay; +import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.ui.overlay.infobox.InfoBoxOverlay; import net.runelite.client.ui.overlay.tooltip.TooltipOverlay; import net.runelite.client.ui.overlay.worldmap.WorldMapOverlay; +import net.runelite.client.ws.PartyService; import org.slf4j.LoggerFactory; @Singleton @@ -89,6 +99,9 @@ public class RuneLite @Inject private ConfigManager configManager; + @Inject + private DrawManager drawManager; + @Inject private SessionManager sessionManager; @@ -101,12 +114,33 @@ public class RuneLite @Inject private ClientUI clientUI; + @Inject + private InfoBoxManager infoBoxManager; + @Inject private OverlayManager overlayManager; + @Inject + private PartyService partyService; + + @Inject + private Provider itemManager; + + @Inject + private Provider overlayRenderer; + + @Inject + private Provider clanManager; + @Inject private Provider chatMessageManager; + @Inject + private Provider menuManager; + + @Inject + private Provider commandManager; + @Inject private Provider infoBoxOverlay; @@ -122,6 +156,12 @@ public class RuneLite @Inject private Provider arrowMinimapOverlay; + @Inject + private Provider lootManager; + + @Inject + private Provider chatboxPanelManager; + @Inject @Nullable private Client client; @@ -166,7 +206,7 @@ public class RuneLite if (options.has("proxy")) { String[] proxy = options.valueOf(proxyInfo).split(":"); - + if (proxy.length >= 2) { System.setProperty("socksProxyHost", proxy[0]); @@ -312,6 +352,15 @@ public class RuneLite // Initialize chat colors chatMessageManager.get().loadColors(); + overlayRenderer.get(); + clanManager.get(); + itemManager.get(); + menuManager.get(); + chatMessageManager.get(); + commandManager.get(); + lootManager.get(); + chatboxPanelManager.get(); + // Add core overlays WidgetOverlay.createOverlays(client).forEach(overlayManager::add); overlayManager.add(infoBoxOverlay.get()); From 5fe8f3d01ed029eacccdc246e61b9c7c95f2aa40 Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Fri, 19 Jul 2019 15:15:16 +0200 Subject: [PATCH 21/21] examine: Fix prices (#1046) --- .../client/plugins/examine/ExaminePlugin.java | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java index 32ad61add6..8fb6cecad4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java @@ -400,12 +400,33 @@ public class ExaminePlugin extends Plugin .append(ChatColorType.NORMAL) .append("ea)"); } + + message + .append(ChatColorType.NORMAL) + .append(" HA value ") + .append(ChatColorType.HIGHLIGHT) + .append(StackFormatter.formatNumber(alchPrice * finalQuantity)); + + if (finalQuantity > 1) + { + message + .append(ChatColorType.NORMAL) + .append(" (") + .append(ChatColorType.HIGHLIGHT) + .append(StackFormatter.formatNumber(alchPrice)) + .append(ChatColorType.NORMAL) + .append("ea)"); + } + + chatMessageManager.queue(QueuedMessage.builder() + .type(ChatMessageType.ITEM_EXAMINE) + .runeLiteFormattedMessage(message.build()) + .build()); }, (e) -> log.error(e.toString()) ); } - - if (alchPrice > 0) + else { message .append(ChatColorType.NORMAL) @@ -423,12 +444,12 @@ public class ExaminePlugin extends Plugin .append(ChatColorType.NORMAL) .append("ea)"); } - } - chatMessageManager.queue(QueuedMessage.builder() - .type(ChatMessageType.ITEM_EXAMINE) - .runeLiteFormattedMessage(message.build()) - .build()); + chatMessageManager.queue(QueuedMessage.builder() + .type(ChatMessageType.ITEM_EXAMINE) + .runeLiteFormattedMessage(message.build()) + .build()); + } } }