Skip to content

Commit

Permalink
Revert "cache: remove old world map index"
Browse files Browse the repository at this point in the history
This reverts commit 5aa9ca4.
  • Loading branch information
Adam- committed May 18, 2024
1 parent db21cbc commit e817ad7
Show file tree
Hide file tree
Showing 4 changed files with 313 additions and 0 deletions.
1 change: 1 addition & 0 deletions cache/src/main/java/net/runelite/cache/IndexType.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public enum IndexType
FONTS(13),
MUSIC_SAMPLES(14),
MUSIC_PATCHES(15),
WORLDMAP_OLD(16), // looks unused
WORLDMAP_GEOGRAPHY(18),
WORLDMAP(19),
WORLDMAP_GROUND(20),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2017, Adam <[email protected]>
* 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.definitions;

import java.util.List;
import lombok.Data;
import net.runelite.cache.region.Position;

@Data
public class WorldMapDefinition
{
public String name;
public int field450;
public int defaultZoom;
public int fileId;
public int field453;
public int field454;
public int field456;
public boolean isSurface;
public List regionList;
public String safeName;
public Position position;
public int field463;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
/*
* Copyright (c) 2017, Adam <[email protected]>
* 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.definitions.loaders;

import java.util.LinkedList;
import net.runelite.cache.definitions.WorldMapDefinition;
import net.runelite.cache.definitions.WorldMapType0;
import net.runelite.cache.definitions.WorldMapType1;
import net.runelite.cache.definitions.WorldMapType2;
import net.runelite.cache.definitions.WorldMapType3;
import net.runelite.cache.definitions.WorldMapTypeBase;
import net.runelite.cache.io.InputStream;
import net.runelite.cache.region.Position;

public class WorldMapLoader
{
public WorldMapDefinition load(byte[] b, int fileId)
{
WorldMapDefinition def = new WorldMapDefinition();
InputStream in = new InputStream(b);

def.fileId = fileId;
def.safeName = in.readString();
def.name = in.readString();

int packedPos = in.readInt();
if (packedPos == -1)
{
def.position = new Position(-1, -1, -1);
}
else
{
int y = packedPos >> 28 & 3;
int x = packedPos >> 14 & 16383;
int z = packedPos & 16383;
def.position = new Position(x, y, z);
}

def.field450 = in.readInt();
in.readUnsignedByte();
def.isSurface = in.readUnsignedByte() == 1;
def.defaultZoom = in.readUnsignedByte();
int var3 = in.readUnsignedByte();
def.regionList = new LinkedList();

for (int var4 = 0; var4 < var3; ++var4)
{
def.regionList.add(this.loadType(in));
}

return def;
}

private WorldMapTypeBase loadType(InputStream var1)
{
int var2 = var1.readUnsignedByte();
// field397 = new class27(1, (byte)0);
// field390 = new class27(2, (byte)1);
// field399 = new class27(3, (byte)2);
// field393 = new class27(0, (byte)3);
WorldMapTypeBase base;
switch (var2)
{
case 0:
// type 1
base = load1(var1);
break;
case 1:
// type 2
base = load2(var1);
break;
case 2:
// type 3
base = load3(var1);
break;
case 3:
// type 0
base = load0(var1);
break;
default:
throw new IllegalStateException();
}
return base;
}

private WorldMapTypeBase load0(InputStream in)
{
WorldMapType0 wm = new WorldMapType0();

wm.plane = in.readUnsignedByte();
wm.numberOfPlanes = in.readUnsignedByte();
wm.xLow = in.readUnsignedShort();
wm.chunk_xLow = in.readUnsignedByte();
wm.yLow = in.readUnsignedShort();
wm.chunk_yLow = in.readUnsignedByte();
wm.xHigh = in.readUnsignedShort();
wm.chunk_xHigh = in.readUnsignedByte();
wm.yHigh = in.readUnsignedShort();
wm.chunk_yHigh = in.readUnsignedByte();

return wm;
}

private WorldMapTypeBase load1(InputStream in)
{
WorldMapType1 wm = new WorldMapType1();

wm.plane = in.readUnsignedByte();
wm.numberOfPlanes = in.readUnsignedByte();
wm.xLowerLeft = in.readUnsignedShort();
wm.yLowerLeft = in.readUnsignedShort();
wm.xLowerRight = in.readUnsignedShort();
wm.yUpperLeft = in.readUnsignedShort();
wm.xUpperLeft = in.readUnsignedShort();
wm.yLowerRight = in.readUnsignedShort();
wm.xUpperRight = in.readUnsignedShort();
wm.yUpperRight = in.readUnsignedShort();

return wm;
}

private WorldMapTypeBase load2(InputStream in)
{
WorldMapType2 wm = new WorldMapType2();

wm.plane = in.readUnsignedByte();
wm.numberOfPlanes = in.readUnsignedByte();
wm.xLow = in.readUnsignedShort();
wm.yLow = in.readUnsignedShort();
wm.xHigh = in.readUnsignedShort();
wm.yHigh = in.readUnsignedShort();

return wm;
}

private WorldMapTypeBase load3(InputStream in)
{
WorldMapType3 wm = new WorldMapType3();

wm.oldPlane = in.readUnsignedByte();
wm.numberOfPlanes = in.readUnsignedByte();
wm.oldX = in.readUnsignedShort();
wm.chunk_oldXLow = in.readUnsignedByte();
wm.chunk_oldXHigh = in.readUnsignedByte();
wm.oldY = in.readUnsignedShort();
wm.chunk_oldYLow = in.readUnsignedByte();
wm.chunk_oldYHigh = in.readUnsignedByte();
wm.newX = in.readUnsignedShort();
wm.chunk_newXLow = in.readUnsignedByte();
wm.chunk_newXHigh = in.readUnsignedByte();
wm.newY = in.readUnsignedShort();
wm.chunk_newYLow = in.readUnsignedByte();
wm.chunk_newYHigh = in.readUnsignedByte();

return wm;
}
}
87 changes: 87 additions & 0 deletions cache/src/test/java/net/runelite/cache/WorldMapDumperTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright (c) 2017, Adam <[email protected]>
* 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;

import com.google.common.io.Files;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import net.runelite.cache.definitions.WorldMapDefinition;
import net.runelite.cache.definitions.loaders.WorldMapLoader;
import net.runelite.cache.fs.Archive;
import net.runelite.cache.fs.ArchiveFiles;
import net.runelite.cache.fs.FSFile;
import net.runelite.cache.fs.Index;
import net.runelite.cache.fs.Storage;
import net.runelite.cache.fs.Store;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class WorldMapDumperTest
{
private static final Logger logger = LoggerFactory.getLogger(WorldMapDumperTest.class);

@Rule
public TemporaryFolder folder = StoreLocation.getTemporaryFolder();

private final Gson gson = new GsonBuilder().setPrettyPrinting().create();

@Test
public void extract() throws IOException
{
File base = StoreLocation.LOCATION,
outDir = folder.newFolder();

int count = 0;

try (Store store = new Store(base))
{
store.load();

Storage storage = store.getStorage();
Index index = store.getIndex(IndexType.WORLDMAP_OLD);
Archive archive = index.getArchive(0); // there is also archive 1/2, but their data format is not this

byte[] archiveData = storage.loadArchive(archive);
ArchiveFiles files = archive.getFiles(archiveData);

for (FSFile file : files.getFiles())
{
WorldMapLoader loader = new WorldMapLoader();
WorldMapDefinition def = loader.load(file.getContents(), file.getFileId());

Files.asCharSink(new File(outDir, file.getFileId() + ".json"), Charset.defaultCharset()).write(gson.toJson(def));
++count;
}
}

logger.info("Dumped {} world map data to {}", count, outDir);
}
}

0 comments on commit e817ad7

Please sign in to comment.