Add height map dumper
This commit is contained in:
153
cache/src/main/java/net/runelite/cache/HeightMapDumper.java
vendored
Normal file
153
cache/src/main/java/net/runelite/cache/HeightMapDumper.java
vendored
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016, Adam <Adam@sigterm.info>
|
||||||
|
* 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.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by Adam <Adam@sigterm.info>
|
||||||
|
* 4. Neither the name of the Adam <Adam@sigterm.info> nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY Adam <Adam@sigterm.info> ''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 Adam <Adam@sigterm.info> 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;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import net.runelite.cache.fs.Store;
|
||||||
|
import net.runelite.cache.region.Region;
|
||||||
|
import net.runelite.cache.region.RegionLoader;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class HeightMapDumper
|
||||||
|
{
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(HeightMapDumper.class);
|
||||||
|
|
||||||
|
private static final int MAP_SCALE = 1;
|
||||||
|
|
||||||
|
private final Store store;
|
||||||
|
private RegionLoader regionLoader;
|
||||||
|
|
||||||
|
public HeightMapDumper(Store store)
|
||||||
|
{
|
||||||
|
this.store = store;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load() throws IOException
|
||||||
|
{
|
||||||
|
regionLoader = new RegionLoader();
|
||||||
|
regionLoader.loadRegions(store);
|
||||||
|
regionLoader.calculateBounds();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufferedImage drawHeightMap(int z)
|
||||||
|
{
|
||||||
|
int minX = regionLoader.getLowestX().getBaseX();
|
||||||
|
int minY = regionLoader.getLowestY().getBaseY();
|
||||||
|
|
||||||
|
int maxX = regionLoader.getHighestX().getBaseX() + Region.X;
|
||||||
|
int maxY = regionLoader.getHighestY().getBaseY() + Region.Y;
|
||||||
|
|
||||||
|
int dimX = maxX - minX;
|
||||||
|
int dimY = maxY - minY;
|
||||||
|
|
||||||
|
dimX *= MAP_SCALE;
|
||||||
|
dimY *= MAP_SCALE;
|
||||||
|
|
||||||
|
logger.info("Map image dimensions: {}px x {}px, {}px per map square ({} MB)", dimX, dimY, MAP_SCALE, (dimX * dimY / 1024 / 1024));
|
||||||
|
|
||||||
|
BufferedImage image = new BufferedImage(dimX, dimY, BufferedImage.TYPE_INT_RGB);
|
||||||
|
draw(image, z);
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void draw(BufferedImage image, int z)
|
||||||
|
{
|
||||||
|
int max = Integer.MIN_VALUE;
|
||||||
|
int min = Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
for (Region region : regionLoader.getRegions())
|
||||||
|
{
|
||||||
|
int baseX = region.getBaseX();
|
||||||
|
int baseY = region.getBaseY();
|
||||||
|
|
||||||
|
// to pixel X
|
||||||
|
int drawBaseX = baseX - regionLoader.getLowestX().getBaseX();
|
||||||
|
|
||||||
|
// to pixel Y. top most y is 0, but the top most
|
||||||
|
// region has the greatest y, so invert
|
||||||
|
int drawBaseY = regionLoader.getHighestY().getBaseY() - baseY;
|
||||||
|
|
||||||
|
for (int x = 0; x < Region.X; ++x)
|
||||||
|
{
|
||||||
|
int drawX = drawBaseX + x;
|
||||||
|
|
||||||
|
for (int y = 0; y < Region.Y; ++y)
|
||||||
|
{
|
||||||
|
int drawY = drawBaseY + (Region.Y - 1 - y);
|
||||||
|
|
||||||
|
int height = region.getTileHeight(z, x, y);
|
||||||
|
if (height > max)
|
||||||
|
{
|
||||||
|
max = height;
|
||||||
|
}
|
||||||
|
if (height < min)
|
||||||
|
{
|
||||||
|
min = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rgb = toColor(height);
|
||||||
|
|
||||||
|
drawMapSquare(image, drawX, drawY, rgb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("max " + max);
|
||||||
|
System.out.println("min " + min);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int toColor(int height)
|
||||||
|
{
|
||||||
|
// height seems to be between -2040 and 0, inclusive
|
||||||
|
height = -height;
|
||||||
|
// Convert to between 0 and 1
|
||||||
|
float color = (float) height / 2040f;
|
||||||
|
|
||||||
|
assert color >= 0.0f && color <= 1.0f;
|
||||||
|
|
||||||
|
return new Color(color, color, color).getRGB();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawMapSquare(BufferedImage image, int x, int y, int rgb)
|
||||||
|
{
|
||||||
|
x *= MAP_SCALE;
|
||||||
|
y *= MAP_SCALE;
|
||||||
|
|
||||||
|
for (int i = 0; i < MAP_SCALE; ++i)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < MAP_SCALE; ++j)
|
||||||
|
{
|
||||||
|
image.setRGB(x + i, y + j, rgb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -57,8 +57,8 @@ import net.runelite.cache.fs.Store;
|
|||||||
import net.runelite.cache.io.InputStream;
|
import net.runelite.cache.io.InputStream;
|
||||||
import net.runelite.cache.region.Location;
|
import net.runelite.cache.region.Location;
|
||||||
import net.runelite.cache.region.Region;
|
import net.runelite.cache.region.Region;
|
||||||
|
import net.runelite.cache.region.RegionLoader;
|
||||||
import net.runelite.cache.util.Djb2;
|
import net.runelite.cache.util.Djb2;
|
||||||
import net.runelite.cache.util.XteaKeyManager;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -66,7 +66,6 @@ public class MapImageDumper
|
|||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(MapImageDumper.class);
|
private static final Logger logger = LoggerFactory.getLogger(MapImageDumper.class);
|
||||||
|
|
||||||
private static final int MAX_REGION = 32768;
|
|
||||||
private static final int MAP_SCALE = 2; // this squared is the number of pixels per map square
|
private static final int MAP_SCALE = 2; // this squared is the number of pixels per map square
|
||||||
private static final int MAPICON_MAX_WIDTH = 5; // scale minimap icons down to this size so they fit..
|
private static final int MAPICON_MAX_WIDTH = 5; // scale minimap icons down to this size so they fit..
|
||||||
private static final int MAPICON_MAX_HEIGHT = 6;
|
private static final int MAPICON_MAX_HEIGHT = 6;
|
||||||
@@ -82,9 +81,7 @@ public class MapImageDumper
|
|||||||
private final Map<Integer, ObjectDefinition> objects = new HashMap<>();
|
private final Map<Integer, ObjectDefinition> objects = new HashMap<>();
|
||||||
private final Map<Integer, Image> mapFunctions = new HashMap<>(); // quest, water, etc
|
private final Map<Integer, Image> mapFunctions = new HashMap<>(); // quest, water, etc
|
||||||
|
|
||||||
private final List<Region> regions = new ArrayList<>();
|
private RegionLoader regionLoader;
|
||||||
private Region lowestX = null, lowestY = null;
|
|
||||||
private Region highestX = null, highestY = null;
|
|
||||||
|
|
||||||
private boolean labelRegions;
|
private boolean labelRegions;
|
||||||
private boolean outlineRegions;
|
private boolean outlineRegions;
|
||||||
@@ -107,11 +104,11 @@ public class MapImageDumper
|
|||||||
|
|
||||||
public BufferedImage drawMap(int z) throws IOException
|
public BufferedImage drawMap(int z) throws IOException
|
||||||
{
|
{
|
||||||
int minX = lowestX.getBaseX();
|
int minX = regionLoader.getLowestX().getBaseX();
|
||||||
int minY = lowestY.getBaseY();
|
int minY = regionLoader.getLowestY().getBaseY();
|
||||||
|
|
||||||
int maxX = highestX.getBaseX() + Region.X;
|
int maxX = regionLoader.getHighestX().getBaseX() + Region.X;
|
||||||
int maxY = highestY.getBaseY() + Region.Y;
|
int maxY = regionLoader.getHighestY().getBaseY() + Region.Y;
|
||||||
|
|
||||||
int dimX = maxX - minX;
|
int dimX = maxX - minX;
|
||||||
int dimY = maxY - minY;
|
int dimY = maxY - minY;
|
||||||
@@ -127,17 +124,17 @@ public class MapImageDumper
|
|||||||
drawOverlay(image, z);
|
drawOverlay(image, z);
|
||||||
|
|
||||||
// objects
|
// objects
|
||||||
for (Region region : regions)
|
for (Region region : regionLoader.getRegions())
|
||||||
{
|
{
|
||||||
int baseX = region.getBaseX();
|
int baseX = region.getBaseX();
|
||||||
int baseY = region.getBaseY();
|
int baseY = region.getBaseY();
|
||||||
|
|
||||||
// to pixel X
|
// to pixel X
|
||||||
int drawBaseX = baseX - lowestX.getBaseX();
|
int drawBaseX = baseX - regionLoader.getLowestX().getBaseX();
|
||||||
|
|
||||||
// to pixel Y. top most y is 0, but the top most
|
// to pixel Y. top most y is 0, but the top most
|
||||||
// region has the greaters y, so invert
|
// region has the greatest y, so invert
|
||||||
int drawBaseY = highestY.getBaseY() - baseY;
|
int drawBaseY = regionLoader.getHighestY().getBaseY() - baseY;
|
||||||
|
|
||||||
Graphics2D graphics = image.createGraphics();
|
Graphics2D graphics = image.createGraphics();
|
||||||
|
|
||||||
@@ -147,17 +144,17 @@ public class MapImageDumper
|
|||||||
}
|
}
|
||||||
|
|
||||||
// map icons
|
// map icons
|
||||||
for (Region region : regions)
|
for (Region region : regionLoader.getRegions())
|
||||||
{
|
{
|
||||||
int baseX = region.getBaseX();
|
int baseX = region.getBaseX();
|
||||||
int baseY = region.getBaseY();
|
int baseY = region.getBaseY();
|
||||||
|
|
||||||
// to pixel X
|
// to pixel X
|
||||||
int drawBaseX = baseX - lowestX.getBaseX();
|
int drawBaseX = baseX - regionLoader.getLowestX().getBaseX();
|
||||||
|
|
||||||
// to pixel Y. top most y is 0, but the top most
|
// to pixel Y. top most y is 0, but the top most
|
||||||
// region has the greaters y, so invert
|
// region has the greatest y, so invert
|
||||||
int drawBaseY = highestY.getBaseY() - baseY;
|
int drawBaseY = regionLoader.getHighestY().getBaseY() - baseY;
|
||||||
|
|
||||||
Graphics2D graphics = image.createGraphics();
|
Graphics2D graphics = image.createGraphics();
|
||||||
|
|
||||||
@@ -184,17 +181,17 @@ public class MapImageDumper
|
|||||||
private void drawUnderlay(BufferedImage image, int z)
|
private void drawUnderlay(BufferedImage image, int z)
|
||||||
{
|
{
|
||||||
// pass 1
|
// pass 1
|
||||||
for (Region region : regions)
|
for (Region region : regionLoader.getRegions())
|
||||||
{
|
{
|
||||||
int baseX = region.getBaseX();
|
int baseX = region.getBaseX();
|
||||||
int baseY = region.getBaseY();
|
int baseY = region.getBaseY();
|
||||||
|
|
||||||
// to pixel X
|
// to pixel X
|
||||||
int drawBaseX = baseX - lowestX.getBaseX();
|
int drawBaseX = baseX - regionLoader.getLowestX().getBaseX();
|
||||||
|
|
||||||
// to pixel Y. top most y is 0, but the top most
|
// to pixel Y. top most y is 0, but the top most
|
||||||
// region has the greaters y, so invert
|
// region has the greatest y, so invert
|
||||||
int drawBaseY = highestY.getBaseY() - baseY;
|
int drawBaseY = regionLoader.getHighestY().getBaseY() - baseY;
|
||||||
|
|
||||||
for (int x = 0; x < Region.X; ++x)
|
for (int x = 0; x < Region.X; ++x)
|
||||||
{
|
{
|
||||||
@@ -231,17 +228,17 @@ public class MapImageDumper
|
|||||||
|
|
||||||
private void drawOverlay(BufferedImage image, int z)
|
private void drawOverlay(BufferedImage image, int z)
|
||||||
{
|
{
|
||||||
for (Region region : regions)
|
for (Region region : regionLoader.getRegions())
|
||||||
{
|
{
|
||||||
int baseX = region.getBaseX();
|
int baseX = region.getBaseX();
|
||||||
int baseY = region.getBaseY();
|
int baseY = region.getBaseY();
|
||||||
|
|
||||||
// to pixel X
|
// to pixel X
|
||||||
int drawBaseX = baseX - lowestX.getBaseX();
|
int drawBaseX = baseX - regionLoader.getLowestX().getBaseX();
|
||||||
|
|
||||||
// to pixel Y. top most y is 0, but the top most
|
// to pixel Y. top most y is 0, but the top most
|
||||||
// region has the greaters y, so invert
|
// region has the greatest y, so invert
|
||||||
int drawBaseY = highestY.getBaseY() - baseY;
|
int drawBaseY = regionLoader.getHighestY().getBaseY() - baseY;
|
||||||
|
|
||||||
for (int x = 0; x < Region.X; ++x)
|
for (int x = 0; x < Region.X; ++x)
|
||||||
{
|
{
|
||||||
@@ -354,83 +351,14 @@ public class MapImageDumper
|
|||||||
|
|
||||||
private void loadRegions(Store store) throws IOException
|
private void loadRegions(Store store) throws IOException
|
||||||
{
|
{
|
||||||
Index index = store.getIndex(IndexType.MAPS);
|
regionLoader = new RegionLoader();
|
||||||
XteaKeyManager keyManager = index.getXteaManager();
|
regionLoader.loadRegions(store);
|
||||||
|
regionLoader.calculateBounds();
|
||||||
|
|
||||||
for (int i = 0; i < MAX_REGION; ++i)
|
logger.info("North most region: {}", regionLoader.getLowestY().getBaseY());
|
||||||
{
|
logger.info("South most region: {}", regionLoader.getHighestY().getBaseY());
|
||||||
int x = i >> 8;
|
logger.info("West most region: {}", regionLoader.getLowestX().getBaseX());
|
||||||
int y = i & 0xFF;
|
logger.info("East most region: {}", regionLoader.getHighestX().getBaseX());
|
||||||
|
|
||||||
Archive map = index.findArchiveByName("m" + x + "_" + y);
|
|
||||||
Archive land = index.findArchiveByName("l" + x + "_" + y);
|
|
||||||
|
|
||||||
assert (map == null) == (land == null);
|
|
||||||
|
|
||||||
if (map == null || land == null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert map.getFiles().size() == 1;
|
|
||||||
assert land.getFiles().size() == 1;
|
|
||||||
|
|
||||||
map.decompressAndLoad(null);
|
|
||||||
|
|
||||||
byte[] data = map.getFiles().get(0).getContents();
|
|
||||||
|
|
||||||
Region region = new Region(i);
|
|
||||||
region.loadTerrain(data);
|
|
||||||
|
|
||||||
int[] keys = keyManager.getKeys(i);
|
|
||||||
if (keys != null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
land.decompressAndLoad(keys);
|
|
||||||
|
|
||||||
data = land.getFiles().get(0).getContents();
|
|
||||||
region.loadLocations(data);
|
|
||||||
}
|
|
||||||
catch (IOException ex)
|
|
||||||
{
|
|
||||||
logger.debug("Can't decrypt region " + i, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
regions.add(region);
|
|
||||||
|
|
||||||
if (lowestX == null || region.getBaseX() < lowestX.getBaseX())
|
|
||||||
{
|
|
||||||
lowestX = region;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (highestX == null || region.getBaseX() > highestX.getBaseX())
|
|
||||||
{
|
|
||||||
highestX = region;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lowestY == null || region.getBaseY() < lowestY.getBaseY())
|
|
||||||
{
|
|
||||||
lowestY = region;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (highestY == null || region.getBaseY() > highestY.getBaseY())
|
|
||||||
{
|
|
||||||
highestY = region;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assert lowestX != null;
|
|
||||||
assert lowestY != null;
|
|
||||||
|
|
||||||
assert highestX != null;
|
|
||||||
assert highestY != null;
|
|
||||||
|
|
||||||
logger.info("North most region: {}", lowestY.getBaseY());
|
|
||||||
logger.info("South most region: {}", highestY.getBaseY());
|
|
||||||
logger.info("West most region: {}", lowestX.getBaseX());
|
|
||||||
logger.info("East most region: {}", highestX.getBaseX());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadUnderlays(Store store)
|
private void loadUnderlays(Store store)
|
||||||
|
|||||||
153
cache/src/main/java/net/runelite/cache/region/RegionLoader.java
vendored
Normal file
153
cache/src/main/java/net/runelite/cache/region/RegionLoader.java
vendored
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016, Adam <Adam@sigterm.info>
|
||||||
|
* 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.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by Adam <Adam@sigterm.info>
|
||||||
|
* 4. Neither the name of the Adam <Adam@sigterm.info> nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY Adam <Adam@sigterm.info> ''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 Adam <Adam@sigterm.info> 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.region;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import net.runelite.cache.IndexType;
|
||||||
|
import net.runelite.cache.fs.Archive;
|
||||||
|
import net.runelite.cache.fs.Index;
|
||||||
|
import net.runelite.cache.fs.Store;
|
||||||
|
import net.runelite.cache.util.XteaKeyManager;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class RegionLoader
|
||||||
|
{
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(RegionLoader.class);
|
||||||
|
|
||||||
|
private static final int MAX_REGION = 32768;
|
||||||
|
|
||||||
|
private final List<Region> regions = new ArrayList<>();
|
||||||
|
private Region lowestX = null, lowestY = null;
|
||||||
|
private Region highestX = null, highestY = null;
|
||||||
|
|
||||||
|
public void loadRegions(Store store) throws IOException
|
||||||
|
{
|
||||||
|
Index index = store.getIndex(IndexType.MAPS);
|
||||||
|
XteaKeyManager keyManager = index.getXteaManager();
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_REGION; ++i)
|
||||||
|
{
|
||||||
|
int x = i >> 8;
|
||||||
|
int y = i & 0xFF;
|
||||||
|
|
||||||
|
Archive map = index.findArchiveByName("m" + x + "_" + y);
|
||||||
|
Archive land = index.findArchiveByName("l" + x + "_" + y);
|
||||||
|
|
||||||
|
assert (map == null) == (land == null);
|
||||||
|
|
||||||
|
if (map == null || land == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert map.getFiles().size() == 1;
|
||||||
|
assert land.getFiles().size() == 1;
|
||||||
|
|
||||||
|
map.decompressAndLoad(null);
|
||||||
|
|
||||||
|
byte[] data = map.getFiles().get(0).getContents();
|
||||||
|
|
||||||
|
Region region = new Region(i);
|
||||||
|
region.loadTerrain(data);
|
||||||
|
|
||||||
|
int[] keys = keyManager.getKeys(i);
|
||||||
|
if (keys != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
land.decompressAndLoad(keys);
|
||||||
|
|
||||||
|
data = land.getFiles().get(0).getContents();
|
||||||
|
region.loadLocations(data);
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
logger.debug("Can't decrypt region " + i, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
regions.add(region);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void calculateBounds()
|
||||||
|
{
|
||||||
|
for (Region region : regions)
|
||||||
|
{
|
||||||
|
if (lowestX == null || region.getBaseX() < lowestX.getBaseX())
|
||||||
|
{
|
||||||
|
lowestX = region;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (highestX == null || region.getBaseX() > highestX.getBaseX())
|
||||||
|
{
|
||||||
|
highestX = region;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lowestY == null || region.getBaseY() < lowestY.getBaseY())
|
||||||
|
{
|
||||||
|
lowestY = region;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (highestY == null || region.getBaseY() > highestY.getBaseY())
|
||||||
|
{
|
||||||
|
highestY = region;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Region> getRegions()
|
||||||
|
{
|
||||||
|
return regions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Region getLowestX()
|
||||||
|
{
|
||||||
|
return lowestX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Region getLowestY()
|
||||||
|
{
|
||||||
|
return lowestY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Region getHighestX()
|
||||||
|
{
|
||||||
|
return highestX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Region getHighestY()
|
||||||
|
{
|
||||||
|
return highestY;
|
||||||
|
}
|
||||||
|
}
|
||||||
70
cache/src/test/java/net/runelite/cache/HeightMapDumperTest.java
vendored
Normal file
70
cache/src/test/java/net/runelite/cache/HeightMapDumperTest.java
vendored
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016, Adam <Adam@sigterm.info>
|
||||||
|
* 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.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by Adam <Adam@sigterm.info>
|
||||||
|
* 4. Neither the name of the Adam <Adam@sigterm.info> nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY Adam <Adam@sigterm.info> ''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 Adam <Adam@sigterm.info> 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;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import net.runelite.cache.fs.Store;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.rules.TemporaryFolder;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class HeightMapDumperTest
|
||||||
|
{
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(HeightMapDumperTest.class);
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public TemporaryFolder folder = StoreLocation.getTemporaryFolder();
|
||||||
|
|
||||||
|
//@Test
|
||||||
|
public void extract() throws IOException
|
||||||
|
{
|
||||||
|
File base = StoreLocation.LOCATION,
|
||||||
|
outDir = folder.newFolder();
|
||||||
|
|
||||||
|
try (Store store = new Store(base))
|
||||||
|
{
|
||||||
|
store.load();
|
||||||
|
|
||||||
|
HeightMapDumper dumper = new HeightMapDumper(store);
|
||||||
|
dumper.load();
|
||||||
|
|
||||||
|
BufferedImage image = dumper.drawHeightMap(0);
|
||||||
|
|
||||||
|
File imageFile = new File(outDir, "heightmap-0.png");
|
||||||
|
|
||||||
|
ImageIO.write(image, "png", imageFile);
|
||||||
|
logger.info("Wrote image {}", imageFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user