diff --git a/cache/src/main/java/net/runelite/cache/HeightMapDumper.java b/cache/src/main/java/net/runelite/cache/HeightMapDumper.java index 5db30815ff..1e855754e1 100644 --- a/cache/src/main/java/net/runelite/cache/HeightMapDumper.java +++ b/cache/src/main/java/net/runelite/cache/HeightMapDumper.java @@ -30,6 +30,7 @@ import java.io.IOException; import net.runelite.cache.fs.Store; import net.runelite.cache.region.Region; import net.runelite.cache.region.RegionLoader; +import net.runelite.cache.util.KeyProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,9 +49,9 @@ public class HeightMapDumper this.store = store; } - public void load() throws IOException + public void load(KeyProvider keyProvider) throws IOException { - regionLoader = new RegionLoader(store); + regionLoader = new RegionLoader(store, keyProvider); regionLoader.loadRegions(); regionLoader.calculateBounds(); } diff --git a/cache/src/main/java/net/runelite/cache/MapImageDumper.java b/cache/src/main/java/net/runelite/cache/MapImageDumper.java index 833b4c1fc1..230953cab3 100644 --- a/cache/src/main/java/net/runelite/cache/MapImageDumper.java +++ b/cache/src/main/java/net/runelite/cache/MapImageDumper.java @@ -53,6 +53,7 @@ import net.runelite.cache.region.Location; import net.runelite.cache.region.Region; import net.runelite.cache.region.RegionLoader; import net.runelite.cache.util.Djb2; +import net.runelite.cache.util.KeyProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -79,7 +80,7 @@ public class MapImageDumper private final Map overlays = new HashMap<>(); private final Map scaledMapIcons = new HashMap<>(); - private RegionLoader regionLoader; + private final RegionLoader regionLoader; private final AreaManager areas; private final SpriteManager sprites; private RSTextureProvider rsTextureProvider; @@ -93,12 +94,18 @@ public class MapImageDumper @Setter private boolean outlineRegions; - public MapImageDumper(Store store) + public MapImageDumper(Store store, KeyProvider keyProvider) + { + this(store, new RegionLoader(store, keyProvider)); + } + + public MapImageDumper(Store store, RegionLoader regionLoader) { this.store = store; + this.regionLoader = regionLoader; this.areas = new AreaManager(store); this.sprites = new SpriteManager(store); - objectManager = new ObjectManager(store); + this.objectManager = new ObjectManager(store); } public void load() throws IOException @@ -111,7 +118,7 @@ public class MapImageDumper textureManager.load(); rsTextureProvider = new RSTextureProvider(textureManager, sprites); - loadRegions(store); + loadRegions(); areas.load(); sprites.load(); loadSprites(); @@ -891,9 +898,8 @@ public class MapImageDumper } } - private void loadRegions(Store store) throws IOException + private void loadRegions() throws IOException { - regionLoader = new RegionLoader(store); regionLoader.loadRegions(); regionLoader.calculateBounds(); diff --git a/cache/src/main/java/net/runelite/cache/region/RegionLoader.java b/cache/src/main/java/net/runelite/cache/region/RegionLoader.java index 21f4868a9a..6e0687e826 100644 --- a/cache/src/main/java/net/runelite/cache/region/RegionLoader.java +++ b/cache/src/main/java/net/runelite/cache/region/RegionLoader.java @@ -28,6 +28,7 @@ import java.io.IOException; import java.util.Collection; import java.util.HashMap; import java.util.Map; +import lombok.extern.slf4j.Slf4j; import net.runelite.cache.IndexType; import net.runelite.cache.definitions.LocationsDefinition; import net.runelite.cache.definitions.MapDefinition; @@ -37,39 +38,44 @@ import net.runelite.cache.fs.Archive; import net.runelite.cache.fs.Index; import net.runelite.cache.fs.Storage; import net.runelite.cache.fs.Store; -import net.runelite.cache.util.XteaKeyManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import net.runelite.cache.util.KeyProvider; +@Slf4j public class RegionLoader { - private static final Logger logger = LoggerFactory.getLogger(RegionLoader.class); - private static final int MAX_REGION = 32768; private final Store store; private final Index index; - private final XteaKeyManager keyManager; + private final KeyProvider keyProvider; private final Map regions = new HashMap<>(); private Region lowestX = null, lowestY = null; private Region highestX = null, highestY = null; - public RegionLoader(Store store) + public RegionLoader(Store store, KeyProvider keyProvider) { this.store = store; index = store.getIndex(IndexType.MAPS); - keyManager = new XteaKeyManager(); + this.keyProvider = keyProvider; } public void loadRegions() throws IOException { + if (!this.regions.isEmpty()) + { + return; + } + for (int i = 0; i < MAX_REGION; ++i) { - Region region = this.loadRegionFromArchive(i); - if (region != null) + try { - regions.put(i, region); + this.loadRegionFromArchive(i); + } + catch (IOException ex) + { + log.debug("Can't decrypt region " + i, ex); } } } @@ -97,24 +103,31 @@ public class RegionLoader Region region = new Region(i); region.loadTerrain(mapDef); - int[] keys = keyManager.getKeys(i); + int[] keys = keyProvider.getKey(i); if (keys != null) { - try - { - data = land.decompress(storage.loadArchive(land), keys); - LocationsDefinition locDef = new LocationsLoader().load(x, y, data); - region.loadLocations(locDef); - } - catch (IOException ex) - { - logger.debug("Can't decrypt region " + i, ex); - } + data = land.decompress(storage.loadArchive(land), keys); + LocationsDefinition locDef = new LocationsLoader().load(x, y, data); + region.loadLocations(locDef); } + regions.put(i, region); + return region; } + public Region loadRegion(int id, MapDefinition map, LocationsDefinition locs) + { + Region r = new Region(id); + r.loadTerrain(map); + if (locs != null) + { + r.loadLocations(locs); + } + regions.put(id, r); + return r; + } + public void calculateBounds() { for (Region region : regions.values()) @@ -153,6 +166,11 @@ public class RegionLoader return regions.get((x << 8) | y); } + public Region findRegionForRegionCoordinates(int x, int y) + { + return regions.get((x << 8) | y); + } + public Region getLowestX() { return lowestX; diff --git a/cache/src/main/java/net/runelite/cache/util/KeyProvider.java b/cache/src/main/java/net/runelite/cache/util/KeyProvider.java new file mode 100644 index 0000000000..498f51d5a7 --- /dev/null +++ b/cache/src/main/java/net/runelite/cache/util/KeyProvider.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 Abex + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.cache.util; + +public interface KeyProvider +{ + int[] getKey(int region); +} diff --git a/cache/src/main/java/net/runelite/cache/util/XteaKeyManager.java b/cache/src/main/java/net/runelite/cache/util/XteaKeyManager.java index c1c7607e9b..669bb6a02d 100644 --- a/cache/src/main/java/net/runelite/cache/util/XteaKeyManager.java +++ b/cache/src/main/java/net/runelite/cache/util/XteaKeyManager.java @@ -35,7 +35,7 @@ import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class XteaKeyManager +public class XteaKeyManager implements KeyProvider { private static final Logger logger = LoggerFactory.getLogger(XteaKeyManager.class); @@ -56,7 +56,8 @@ public class XteaKeyManager logger.info("Loaded {} keys", keys.size()); } - public int[] getKeys(int region) + @Override + public int[] getKey(int region) { return keys.get(region); } diff --git a/cache/src/test/java/net/runelite/cache/HeightMapDumperTest.java b/cache/src/test/java/net/runelite/cache/HeightMapDumperTest.java index 92327f50d7..4b41b047aa 100644 --- a/cache/src/test/java/net/runelite/cache/HeightMapDumperTest.java +++ b/cache/src/test/java/net/runelite/cache/HeightMapDumperTest.java @@ -52,7 +52,7 @@ public class HeightMapDumperTest store.load(); HeightMapDumper dumper = new HeightMapDumper(store); - dumper.load(); + dumper.load(null); BufferedImage image = dumper.drawHeightMap(0); diff --git a/cache/src/test/java/net/runelite/cache/MapDumperTest.java b/cache/src/test/java/net/runelite/cache/MapDumperTest.java index b73c250e43..b822673988 100644 --- a/cache/src/test/java/net/runelite/cache/MapDumperTest.java +++ b/cache/src/test/java/net/runelite/cache/MapDumperTest.java @@ -75,7 +75,7 @@ public class MapDumperTest for (int i = 0; i < MAX_REGIONS; i++) { - int[] keys = keyManager.getKeys(i); + int[] keys = keyManager.getKey(i); int x = i >> 8; int y = i & 0xFF; @@ -140,7 +140,7 @@ public class MapDumperTest MapDefinition mapDef = new MapLoader().load(x, y, data); LocationsDefinition locDef = null; - int[] keys = keyManager.getKeys(i); + int[] keys = keyManager.getKey(i); if (keys != null) { try diff --git a/cache/src/test/java/net/runelite/cache/MapImageDumperTest.java b/cache/src/test/java/net/runelite/cache/MapImageDumperTest.java index 7491e54b58..89b930673f 100644 --- a/cache/src/test/java/net/runelite/cache/MapImageDumperTest.java +++ b/cache/src/test/java/net/runelite/cache/MapImageDumperTest.java @@ -31,6 +31,7 @@ import javax.imageio.ImageIO; import net.runelite.cache.fs.Store; import net.runelite.cache.region.Region; import net.runelite.cache.region.RegionLoader; +import net.runelite.cache.util.XteaKeyManager; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; @@ -56,7 +57,10 @@ public class MapImageDumperTest { store.load(); - MapImageDumper dumper = new MapImageDumper(store); + XteaKeyManager keyManager = new XteaKeyManager(); + keyManager.loadKeys(null); + + MapImageDumper dumper = new MapImageDumper(store, keyManager); dumper.load(); for (int i = 0; i < Region.Z; ++i) @@ -82,10 +86,13 @@ public class MapImageDumperTest { store.load(); - RegionLoader regionLoader = new RegionLoader(store); + XteaKeyManager keyManager = new XteaKeyManager(); + keyManager.loadKeys(null); + + RegionLoader regionLoader = new RegionLoader(store, keyManager); regionLoader.loadRegions(); - MapImageDumper dumper = new MapImageDumper(store); + MapImageDumper dumper = new MapImageDumper(store, regionLoader); dumper.load(); int z = 0;