diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index 90ae2e24ed..4f6b3c07d9 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -30,7 +30,7 @@ import net.runelite.api.widgets.Widget; public class Client { - private net.runelite.rs.api.Client client; + private final net.runelite.rs.api.Client client; public Client(net.runelite.rs.api.Client client) { @@ -203,4 +203,19 @@ public class Client { return client.getWidgetPositionsY(); } + + public int getRevision() + { + return client.getRevision(); + } + + public int[] getMapRegions() + { + return client.getMapRegions(); + } + + public int[][] getXteaKeys() + { + return client.getXteaKeys(); + } } 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 9023c178a1..e571200986 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -28,6 +28,8 @@ package net.runelite.client; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.SubscriberExceptionContext; import java.io.File; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; import joptsimple.OptionParser; import joptsimple.OptionSet; import net.runelite.api.Client; @@ -53,6 +55,7 @@ public class RuneLite private PluginManager pluginManager; private OverlayRenderer renderer; private EventBus eventBus = new EventBus(this::eventExceptionHandler); + private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); public static void main(String[] args) throws Exception { @@ -118,4 +121,9 @@ public class RuneLite { return options; } + + public ScheduledExecutorService getExecutor() + { + return executor; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/events/MapRegionChanged.java b/runelite-client/src/main/java/net/runelite/client/events/MapRegionChanged.java new file mode 100644 index 0000000000..fd83910afc --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/events/MapRegionChanged.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2017, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.events; + +public class MapRegionChanged +{ + /** index into the region map that is changing + */ + private int index; + + public int getIndex() + { + return index; + } + + public void setIndex(int index) + { + this.index = index; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java index dbe5a98a52..23d3df3e89 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java @@ -36,6 +36,7 @@ import net.runelite.client.plugins.fpsinfo.FPS; import net.runelite.client.plugins.gronditems.GroundItems; import net.runelite.client.plugins.hiscore.Hiscore; import net.runelite.client.plugins.opponentinfo.OpponentInfo; +import net.runelite.client.plugins.xtea.Xtea; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -58,6 +59,7 @@ public class PluginManager load(new FPS()); load(new Hiscore()); load(new BossTimers()); + load(new Xtea()); if (RuneLite.getOptions().has("developer-mode")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xtea/Xtea.java b/runelite-client/src/main/java/net/runelite/client/plugins/xtea/Xtea.java new file mode 100644 index 0000000000..cf8f6f3368 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xtea/Xtea.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2017, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.xtea; + +import com.google.common.eventbus.Subscribe; +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.ScheduledExecutorService; +import java.util.logging.Level; +import net.runelite.api.Client; +import net.runelite.client.RuneLite; +import net.runelite.client.events.MapRegionChanged; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.http.api.xtea.XteaClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Xtea extends Plugin +{ + private static final Logger logger = LoggerFactory.getLogger(Xtea.class); + + private final RuneLite runeLite = RuneLite.getRunelite(); + private final Client client = RuneLite.getClient(); + private final XteaClient xteaClient = new XteaClient(); + + private final Set sentRegions = new HashSet<>(); + + @Override + public Overlay getOverlay() + { + return null; + } + + @Subscribe + public void onMapRegionChanged(MapRegionChanged event) + { + int idx = event.getIndex(); + + if (idx == -1) + { + return; // this is the new array being assigned to the field + } + + int revision = client.getRevision(); + int[] regions = client.getMapRegions(); + int[][] xteaKeys = client.getXteaKeys(); + + int region = regions[idx]; + int[] keys = xteaKeys[idx]; + + logger.debug("Region {} keys {}, {}, {}, {}", region, keys[0], keys[1], keys[2], keys[3]); + + // No need to ever send more than once + if (sentRegions.contains(region)) + { + return; + } + + sentRegions.add(region); + + ScheduledExecutorService executor = runeLite.getExecutor(); + executor.execute(() -> + { + try + { + xteaClient.submut(revision, region, keys); + } + catch (URISyntaxException | IOException ex) + { + logger.debug("unable to submit xtea keys", ex); + } + }); + } +} diff --git a/runelite-client/src/main/java/net/runelite/inject/callbacks/Hooks.java b/runelite-client/src/main/java/net/runelite/inject/callbacks/Hooks.java index 1491ed09a4..217682fc3b 100644 --- a/runelite-client/src/main/java/net/runelite/inject/callbacks/Hooks.java +++ b/runelite-client/src/main/java/net/runelite/inject/callbacks/Hooks.java @@ -26,6 +26,7 @@ package net.runelite.inject.callbacks; import net.runelite.client.RuneLite; import net.runelite.client.events.ExperienceChanged; +import net.runelite.client.events.MapRegionChanged; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,6 +53,13 @@ public class Hooks runelite.getEventBus().post(experienceChanged); break; } + case "mapRegionsChanged": + { + MapRegionChanged regionChanged = new MapRegionChanged(); + regionChanged.setIndex(idx); + runelite.getEventBus().post(regionChanged); + break; + } default: logger.warn("Unknown event {} triggered on {}", name, object); return; diff --git a/runescape-api/src/main/java/net/runelite/rs/api/Client.java b/runescape-api/src/main/java/net/runelite/rs/api/Client.java index 1219c8837b..600dc8e74d 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/Client.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/Client.java @@ -213,4 +213,13 @@ public interface Client extends GameEngine @Import("canvas") Canvas getCanvas(); + + @Import("revision") + int getRevision(); + + @Import("mapRegions") + int[] getMapRegions(); + + @Import("xteaKeys") + int[][] getXteaKeys(); }