cache: split loading archive files from archive loading

Also no longer store archive contents in memory and instead read it from
storage on demand.
This commit is contained in:
Adam
2017-12-17 18:36:05 -05:00
parent 801a907f15
commit 033cf3bb01
53 changed files with 853 additions and 708 deletions

View File

@@ -22,7 +22,6 @@
* (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;
@@ -34,8 +33,10 @@ import java.nio.charset.Charset;
import net.runelite.cache.definitions.EnumDefinition;
import net.runelite.cache.definitions.loaders.EnumLoader;
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;
@@ -62,12 +63,16 @@ public class EnumDumperTest
{
store.load();
Storage storage = store.getStorage();
Index index = store.getIndex(IndexType.CONFIGS);
Archive archive = index.getArchive(ConfigType.ENUM.getId());
byte[] archiveData = storage.loadArchive(archive);
ArchiveFiles files = archive.getFiles(archiveData);
EnumLoader loader = new EnumLoader();
for (FSFile file : archive.getFiles())
for (FSFile file : files.getFiles())
{
byte[] b = file.getContents();

View File

@@ -37,11 +37,10 @@ import net.runelite.cache.definitions.FramemapDefinition;
import net.runelite.cache.definitions.loaders.FrameLoader;
import net.runelite.cache.definitions.loaders.FramemapLoader;
import net.runelite.cache.fs.Archive;
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;
@@ -67,6 +66,7 @@ public class FrameDumper
{
store.load();
Storage storage = store.getStorage();
Index frameIndex = store.getIndex(IndexType.FRAMES);
Index framemapIndex = store.getIndex(IndexType.FRAMEMAPS);
@@ -74,24 +74,22 @@ public class FrameDumper
{
List<FrameDefinition> frames = new ArrayList<>();
for (FSFile file : archive.getFiles())
{
byte[] contents = file.getContents();
byte[] archiveData = storage.loadArchive(archive);
byte[] contents = archive.decompress(archiveData);
int framemapArchiveId = (contents[0] & 0xff) << 8 | contents[1] & 0xff;
int framemapArchiveId = (contents[0] & 0xff) << 8 | contents[1] & 0xff;
Archive framemapArchive = framemapIndex.getArchives().get(framemapArchiveId);
assert framemapArchive.getFiles().size() == 1;
FSFile framemapFile = framemapArchive.getFiles().get(0);
Archive framemapArchive = framemapIndex.getArchives().get(framemapArchiveId);
archiveData = storage.loadArchive(framemapArchive);
byte[] framemapContents = framemapArchive.decompress(archiveData);
FramemapLoader fmloader = new FramemapLoader();
FramemapDefinition framemap = fmloader.load(framemapFile.getFileId(), framemapFile.getContents());
FramemapLoader fmloader = new FramemapLoader();
FramemapDefinition framemap = fmloader.load(0, framemapContents);
FrameLoader frameLoader = new FrameLoader();
FrameDefinition frame = frameLoader.load(framemap, contents);
FrameLoader frameLoader = new FrameLoader();
FrameDefinition frame = frameLoader.load(framemap, contents);
frames.add(frame);
}
frames.add(frame);
Files.write(gson.toJson(frames), new File(outDir, archive.getArchiveId() + ".json"), Charset.defaultCharset());
++count;

View File

@@ -33,8 +33,8 @@ import java.nio.charset.Charset;
import net.runelite.cache.definitions.FramemapDefinition;
import net.runelite.cache.definitions.loaders.FramemapLoader;
import net.runelite.cache.fs.Archive;
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;
@@ -63,14 +63,16 @@ public class FramemapDumper
{
store.load();
Storage storage = store.getStorage();
Index index = store.getIndex(IndexType.FRAMEMAPS);
for (Archive archive : index.getArchives())
{
assert archive.getFiles().size() == 1;
FSFile file = archive.getFiles().get(0);
byte[] archiveData = storage.loadArchive(archive);
byte[] contents = archive.decompress(archiveData);
FramemapLoader loader = new FramemapLoader();
FramemapDefinition framemap = loader.load(file.getFileId(), file.getContents());
FramemapDefinition framemap = loader.load(0, contents);
Files.write(gson.toJson(framemap), new File(outDir, archive.getArchiveId() + ".json"), Charset.defaultCharset());
++count;

View File

@@ -33,8 +33,10 @@ import java.nio.charset.Charset;
import net.runelite.cache.definitions.InventoryDefinition;
import net.runelite.cache.definitions.loaders.InventoryLoader;
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;
@@ -63,10 +65,14 @@ public class InventoryDumper
{
store.load();
Storage storage = store.getStorage();
Index index = store.getIndex(IndexType.CONFIGS);
Archive archive = index.getArchive(ConfigType.INV.getId());
for (FSFile file : archive.getFiles())
byte[] archiveData = storage.loadArchive(archive);
ArchiveFiles files = archive.getFiles(archiveData);
for (FSFile file : files.getFiles())
{
InventoryLoader loader = new InventoryLoader();
InventoryDefinition inv = loader.load(file.getContents());

View File

@@ -33,8 +33,10 @@ import java.nio.charset.Charset;
import net.runelite.cache.definitions.KitDefinition;
import net.runelite.cache.definitions.loaders.KitLoader;
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;
@@ -61,12 +63,16 @@ public class KitDumperTest
{
store.load();
Storage storage = store.getStorage();
Index index = store.getIndex(IndexType.CONFIGS);
Archive archive = index.getArchive(ConfigType.IDENTKIT.getId());
KitLoader loader = new KitLoader();
for (FSFile file : archive.getFiles())
byte[] archiveData = storage.loadArchive(archive);
ArchiveFiles files = archive.getFiles(archiveData);
for (FSFile file : files.getFiles())
{
byte[] b = file.getContents();

View File

@@ -33,6 +33,7 @@ import java.util.ArrayList;
import java.util.List;
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.region.Region;
import net.runelite.cache.util.XteaKeyManager;
@@ -59,13 +60,15 @@ public class MapDumperTest
{
File base = StoreLocation.LOCATION,
outDir = folder.newFolder();
XteaKeyManager keyManager = new XteaKeyManager();
keyManager.loadKeys();
try (Store store = new Store(base))
{
store.load();
Storage storage = store.getStorage();
Index index = store.getIndex(IndexType.MAPS);
XteaKeyManager keyManager = index.getXteaManager();
for (int i = 0; i < MAX_REGIONS; i++)
{
@@ -84,14 +87,7 @@ public class MapDumperTest
continue;
}
assert map.getFiles().size() == 1;
assert land.getFiles().size() == 1;
// maps aren't encrypted, but we don't load archive data of any archive in
// the maps index, so load it
map.decompressAndLoad(null);
byte[] data = map.getFiles().get(0).getContents();
byte[] data = map.decompress(storage.loadArchive(map));
Files.write(data, new File(outDir, "m" + x + "_" + y + ".dat"));
@@ -99,7 +95,7 @@ public class MapDumperTest
{
try
{
land.decompressAndLoad(keys);
data = land.decompress(storage.loadArchive(land), keys);
}
catch (IOException ex)
{
@@ -109,8 +105,6 @@ public class MapDumperTest
logger.info("Decrypted region {} coords {},{}", i, x, y);
data = land.getFiles().get(0).getContents();
Files.write(data, new File(outDir, "l" + x + "_" + y + ".dat"));
}
}
@@ -119,8 +113,10 @@ public class MapDumperTest
private void loadRegions(Store store) throws IOException
{
Storage storage = store.getStorage();
Index index = store.getIndex(IndexType.MAPS);
XteaKeyManager keyManager = index.getXteaManager();
XteaKeyManager keyManager = new XteaKeyManager();
keyManager.loadKeys();
for (int i = 0; i < MAX_REGIONS; ++i)
{
@@ -137,12 +133,7 @@ public class MapDumperTest
continue;
}
assert map.getFiles().size() == 1;
assert land.getFiles().size() == 1;
map.decompressAndLoad(null);
byte[] data = map.getFiles().get(0).getContents();
byte[] data = map.decompress(storage.loadArchive(map));
Region region = new Region(i);
region.loadTerrain(data);
@@ -152,14 +143,13 @@ public class MapDumperTest
{
try
{
land.decompressAndLoad(keys);
data = land.decompress(storage.loadArchive(land), keys);
}
catch (IOException ex)
{
continue;
}
data = land.getFiles().get(0).getContents();
region.loadLocations(data);
}

View File

@@ -27,13 +27,12 @@ package net.runelite.cache;
import com.google.common.io.Files;
import com.google.gson.Gson;
import java.io.File;
import java.io.IOException;
import net.runelite.cache.definitions.loaders.ModelLoader;
import net.runelite.cache.fs.Archive;
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;
@@ -45,8 +44,6 @@ public class ModelDumperTest
{
private static final Logger logger = LoggerFactory.getLogger(ModelDumperTest.class);
private Gson gson = new Gson();
@Rule
public TemporaryFolder folder = StoreLocation.getTemporaryFolder();
@@ -60,20 +57,17 @@ public class ModelDumperTest
{
store.load();
Storage storage = store.getStorage();
Index index = store.getIndex(IndexType.MODELS);
for (Archive archive : index.getArchives())
{
assert archive.getFiles().size() == 1;
FSFile file = archive.getFiles().get(0);
byte[] contents = file.getContents();
byte[] contents = archive.decompress(storage.loadArchive(archive));
ModelLoader loader = new ModelLoader();
loader.load(archive.getArchiveId(), contents);
Files.write(contents, new File(modelDir, archive.getArchiveId() + ".model"));
//Files.write(gson.toJson(loader), new File(modelDir, archive.getArchiveId() + ".json"), Charset.defaultCharset());
++count;
}
}

View File

@@ -33,8 +33,10 @@ import java.nio.charset.Charset;
import net.runelite.cache.definitions.OverlayDefinition;
import net.runelite.cache.definitions.loaders.OverlayLoader;
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;
@@ -63,10 +65,14 @@ public class OverlayDumper
{
store.load();
Storage storage = store.getStorage();
Index index = store.getIndex(IndexType.CONFIGS);
Archive archive = index.getArchive(ConfigType.OVERLAY.getId());
for (FSFile file : archive.getFiles())
byte[] archiveData = storage.loadArchive(archive);
ArchiveFiles files = archive.getFiles(archiveData);
for (FSFile file : files.getFiles())
{
OverlayLoader loader = new OverlayLoader();
OverlayDefinition overlay = loader.load(file.getFileId(), file.getContents());

View File

@@ -33,10 +33,11 @@ import java.nio.charset.Charset;
import net.runelite.cache.definitions.SequenceDefinition;
import net.runelite.cache.definitions.loaders.SequenceLoader;
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 net.runelite.cache.io.InputStream;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
@@ -64,10 +65,14 @@ public class SequenceDumper
{
store.load();
Storage storage = store.getStorage();
Index index = store.getIndex(IndexType.CONFIGS);
Archive archive = index.getArchive(ConfigType.SEQUENCE.getId());
for (FSFile file : archive.getFiles())
byte[] archiveData = storage.loadArchive(archive);
ArchiveFiles files = archive.getFiles(archiveData);
for (FSFile file : files.getFiles())
{
SequenceLoader loader = new SequenceLoader();
SequenceDefinition seq = loader.load(file.getFileId(), file.getContents());

View File

@@ -33,8 +33,8 @@ import java.nio.charset.Charset;
import net.runelite.cache.definitions.loaders.sound.SoundEffectLoader;
import net.runelite.cache.definitions.sound.SoundEffectDefinition;
import net.runelite.cache.fs.Archive;
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;
@@ -61,16 +61,15 @@ public class SoundEffectsDumperTest
{
store.load();
Storage storage = store.getStorage();
Index index = store.getIndex(IndexType.SOUNDEFFECTS);
for (Archive archive : index.getArchives())
{
assert archive.getFiles().size() == 1;
FSFile file = archive.getFiles().get(0);
byte[] contents = archive.decompress(storage.loadArchive(archive));
SoundEffectLoader soundEffectLoader = new SoundEffectLoader();
SoundEffectDefinition soundEffect = soundEffectLoader.load(file.getContents());
SoundEffectDefinition soundEffect = soundEffectLoader.load(contents);
Files.write(gson.toJson(soundEffect), new File(dumpDir, archive.getArchiveId() + ".json"), Charset.defaultCharset());
++count;

View File

@@ -22,15 +22,14 @@
* (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.io.File;
import java.io.IOException;
import java.nio.file.Files;
import net.runelite.cache.fs.Archive;
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;
@@ -55,11 +54,12 @@ public class TitleDumper
{
store.load();
Storage storage = store.getStorage();
Index index = store.getIndex(IndexType.BINARY);
Archive a = index.findArchiveByName("title.jpg");
FSFile file = a.getFiles().get(0);
Archive archive = index.findArchiveByName("title.jpg");
byte[] contents = archive.decompress(storage.loadArchive(archive));
Files.write(outFile.toPath(), file.getContents());
Files.write(outFile.toPath(), contents);
}
logger.info("Dumped to {}", outFile);

View File

@@ -33,8 +33,8 @@ import javax.sound.midi.Sequencer;
import net.runelite.cache.definitions.TrackDefinition;
import net.runelite.cache.definitions.loaders.TrackLoader;
import net.runelite.cache.fs.Archive;
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 net.runelite.cache.util.Djb2Manager;
import org.junit.Ignore;
@@ -66,18 +66,19 @@ public class TrackDumperTest
{
store.load();
Storage storage = store.getStorage();
Index index = store.getIndex(IndexType.TRACK1);
Index index2 = store.getIndex(IndexType.TRACK2);
for (Archive archive : index.getArchives())
{
dumpTrackArchive(dumpDir1, archive);
dumpTrackArchive(dumpDir1, storage, archive);
++idx1;
}
for (Archive archive : index2.getArchives())
{
dumpTrackArchive(dumpDir2, archive);
dumpTrackArchive(dumpDir2, storage, archive);
++idx2;
}
}
@@ -85,14 +86,17 @@ public class TrackDumperTest
logger.info("Dumped {} sound tracks ({} idx1, {} idx2) to {} and {}", idx1 + idx2, idx1, idx2, dumpDir1, dumpDir2);
}
private void dumpTrackArchive(File dumpDir, Archive archive) throws IOException
private void dumpTrackArchive(File dumpDir, Storage storage, Archive archive) throws IOException
{
assert archive.getFiles().size() == 1;
byte[] contents = archive.decompress(storage.loadArchive(archive));
FSFile file = archive.getFiles().get(0);
if (contents == null)
{
return;
}
TrackLoader loader = new TrackLoader();
TrackDefinition def = loader.load(file.getContents());
TrackDefinition def = loader.load(contents);
String name;
if (archive.getNameHash() != 0)

View File

@@ -33,8 +33,10 @@ import java.nio.charset.Charset;
import net.runelite.cache.definitions.UnderlayDefinition;
import net.runelite.cache.definitions.loaders.UnderlayLoader;
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;
@@ -63,10 +65,14 @@ public class UnderlayDumper
{
store.load();
Storage storage = store.getStorage();
Index index = store.getIndex(IndexType.CONFIGS);
Archive archive = index.getArchive(ConfigType.UNDERLAY.getId());
for (FSFile file : archive.getFiles())
byte[] archiveData = storage.loadArchive(archive);
ArchiveFiles files = archive.getFiles(archiveData);
for (FSFile file : files.getFiles())
{
UnderlayLoader loader = new UnderlayLoader();
UnderlayDefinition underlay = loader.load(file.getFileId(), file.getContents());

View File

@@ -33,8 +33,10 @@ import java.nio.charset.Charset;
import net.runelite.cache.definitions.VarbitDefinition;
import net.runelite.cache.definitions.loaders.VarbitLoader;
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;
@@ -63,10 +65,14 @@ public class VarbitDumper
{
store.load();
Storage storage = store.getStorage();
Index index = store.getIndex(IndexType.CONFIGS);
Archive archive = index.getArchive(ConfigType.VARBIT.getId());
for (FSFile file : archive.getFiles())
byte[] archiveData = storage.loadArchive(archive);
ArchiveFiles files = archive.getFiles(archiveData);
for (FSFile file : files.getFiles())
{
VarbitLoader loader = new VarbitLoader();
VarbitDefinition varbit = loader.load(file.getFileId(), file.getContents());

View File

@@ -33,8 +33,10 @@ 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;
@@ -63,10 +65,14 @@ public class WorldMapDumperTest
{
store.load();
Storage storage = store.getStorage();
Index index = store.getIndex(IndexType.WORLDMAP);
Archive archive = index.getArchive(0); // there is also archive 1/2, but their data format is not this
for (FSFile file : archive.getFiles())
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());

View File

@@ -0,0 +1,55 @@
/*
* Copyright (c) 2016-2017, 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.
*
* 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.fs;
import java.io.IOException;
import java.util.Random;
import static net.runelite.cache.fs.jagex.CompressionType.GZ;
import static org.junit.Assert.assertArrayEquals;
import org.junit.Test;
public class ContainerTest
{
@Test
public void testCompress() throws IOException
{
int[] keys = new int[]
{
4, 8, 15, 16
};
Random random = new Random(42L);
byte[] data = new byte[1024];
random.nextBytes(data);
Container container = new Container(GZ, -1);
container.compress(data, keys);
byte[] compressedData = container.data;
container = Container.decompress(compressedData, keys);
assertArrayEquals(data, container.data);
}
}

View File

@@ -44,8 +44,6 @@ public class StoreLoadTest
try (Store store = new Store(StoreLocation.LOCATION))
{
store.load();
System.out.println(store);
}
}

View File

@@ -28,6 +28,7 @@ import java.io.File;
import java.io.IOException;
import java.util.Random;
import net.runelite.cache.StoreLocation;
import net.runelite.cache.index.FileData;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
@@ -47,10 +48,10 @@ public class StoreTest
{
Index index = store.addIndex(0);
Archive archive = index.addArchive(0);
FSFile file = new FSFile(0);
archive.addFile(file);
file.setNameHash(7);
file.setContents("test".getBytes());
archive.setFileData(new FileData[1]);
FileData fileData = archive.getFileData()[0] = new FileData();
fileData.setId(42);
fileData.setNameHash(7);
store.save();
@@ -74,15 +75,14 @@ public class StoreTest
Index index = store.addIndex(0);
Archive archive = index.addArchive(0);
archive.setNameHash(random.nextInt());
archive.setFileData(new FileData[NUMBER_OF_FILES]);
for (int i = 0; i < NUMBER_OF_FILES; ++i)
{
FSFile file = new FSFile(i);
FileData[] fileData = archive.getFileData();
FileData file = fileData[i] = new FileData();
file.setId(i);
file.setNameHash(random.nextInt());
archive.addFile(file);
byte[] data = new byte[random.nextInt(1024)];
random.nextBytes(data);
file.setContents(data);
}
store.save();
@@ -109,39 +109,33 @@ public class StoreTest
Archive archive = index.addArchive(0);
archive.setNameHash(random.nextInt(Integer.MAX_VALUE));
archive.setFileData(new FileData[NUMBER_OF_FILES]);
Archive archive2 = index.addArchive(1);
archive2.setFileData(new FileData[NUMBER_OF_FILES]);
Archive archive3 = index2.addArchive(0);
archive3.setFileData(new FileData[NUMBER_OF_FILES]);
for (int i = 0; i < NUMBER_OF_FILES; ++i)
{
FSFile file = new FSFile(i);
FileData[] fileData = archive.getFileData();
FileData file = fileData[i] = new FileData();
file.setNameHash(random.nextInt(Integer.MAX_VALUE));
archive.addFile(file);
byte[] data = new byte[random.nextInt(1024)];
random.nextBytes(data);
file.setContents(data);
}
for (int i = 0; i < NUMBER_OF_FILES; ++i)
{
FSFile file = new FSFile(i);
FileData[] fileData = archive2.getFileData();
FileData file = fileData[i] = new FileData();
file.setNameHash(random.nextInt(Integer.MAX_VALUE));
archive2.addFile(file);
byte[] data = new byte[random.nextInt(1024)];
random.nextBytes(data);
file.setContents(data);
}
for (int i = 0; i < NUMBER_OF_FILES; ++i)
{
FSFile file = new FSFile(i);
FileData[] fileData = archive3.getFileData();
FileData file = fileData[i] = new FileData();
file.setNameHash(random.nextInt(Integer.MAX_VALUE));
archive3.addFile(file);
byte[] data = new byte[random.nextInt(1024)];
random.nextBytes(data);
file.setContents(data);
}
store.save();

View File

@@ -27,6 +27,7 @@ package net.runelite.cache.fs.jagex;
import java.io.File;
import java.io.IOException;
import net.runelite.cache.StoreLocation;
import net.runelite.cache.fs.Container;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
@@ -43,17 +44,17 @@ public class DataFileTest
File file = folder.newFile();
DataFile df = new DataFile(file);
byte[] compressedData = DataFile.compress("test".getBytes(), CompressionType.NONE, 0, null);
DataFileWriteResult res = df.write(42, 3, compressedData, 0);
Container container = new Container(CompressionType.NONE, 0);
container.compress("test".getBytes(), null);
byte[] compressedData = container.data;
DataFileWriteResult res = df.write(42, 3, compressedData);
compressedData = df.read(42, 3, res.sector, res.compressedLength);
DataFileReadResult res2 = DataFile.decompress(compressedData, null);
Container res2 = Container.decompress(compressedData, null);
byte[] buf = res2.data;
String str = new String(buf);
Assert.assertEquals("test", str);
Assert.assertEquals(res.crc, res2.crc);
}
@Test
@@ -69,11 +70,13 @@ public class DataFileTest
DataFile df = new DataFile(file);
byte[] compressedData = DataFile.compress(b, CompressionType.BZ2, 42, null);
DataFileWriteResult res = df.write(42, 0x1FFFF, compressedData, 42);
Container container = new Container(CompressionType.BZ2, 42);
container.compress(b, null);
byte[] compressedData = container.data;
DataFileWriteResult res = df.write(42, 0x1FFFF, compressedData);
compressedData = df.read(42, 0x1FFFF, res.sector, res.compressedLength);
DataFileReadResult res2 = DataFile.decompress(compressedData, null);
Container res2 = Container.decompress(compressedData, null);
byte[] buf = res2.data;
Assert.assertArrayEquals(b, buf);
@@ -84,11 +87,13 @@ public class DataFileTest
{
DataFile df = new DataFile(folder.newFile());
byte[] compressedData = DataFile.compress("test".getBytes(), CompressionType.GZ, 0, null);
DataFileWriteResult res = df.write(41, 4, compressedData, 0);
Container container = new Container(CompressionType.GZ, 0);
container.compress("test".getBytes(), null);
byte[] compressedData = container.data;
DataFileWriteResult res = df.write(41, 4, compressedData);
compressedData = df.read(41, 4, res.sector, res.compressedLength);
DataFileReadResult res2 = DataFile.decompress(compressedData, null);
Container res2 = Container.decompress(compressedData, null);
byte[] buf = res2.data;
String str = new String(buf);
@@ -100,36 +105,19 @@ public class DataFileTest
{
DataFile df = new DataFile(folder.newFile());
byte[] compressedData = DataFile.compress("test".getBytes(), CompressionType.BZ2, 5, null);
DataFileWriteResult res = df.write(41, 4, compressedData, 0);
Container container = new Container(CompressionType.BZ2, 5);
container.compress("test".getBytes(), null);
byte[] compressedData = container.data;
DataFileWriteResult res = df.write(41, 4, compressedData);
compressedData = df.read(41, 4, res.sector, res.compressedLength);
DataFileReadResult res2 = DataFile.decompress(compressedData, null);
Container res2 = Container.decompress(compressedData, null);
byte[] buf = res2.data;
String str = new String(buf);
Assert.assertEquals("test", str);
}
@Test
public void testCrc() throws IOException
{
File file = folder.newFile();
DataFile df = new DataFile(file);
byte[] compressedData = DataFile.compress("test".getBytes(), CompressionType.NONE, 42, null);
DataFileWriteResult res = df.write(42, 3, compressedData, 0);
compressedData = df.read(42, 3, res.sector, res.compressedLength);
DataFileReadResult res2 = DataFile.decompress(compressedData, null);
byte[] buf = res2.data;
String str = new String(buf);
Assert.assertEquals("test", str);
Assert.assertEquals(res.crc, res2.crc);
Assert.assertEquals(42, res2.revision);
}
@Test
public void testEnc() throws IOException
{
@@ -141,16 +129,17 @@ public class DataFileTest
DataFile df = new DataFile(file);
byte[] compressedData = DataFile.compress("testtesttesttest1".getBytes(), CompressionType.NONE, 42, keys);
DataFileWriteResult res = df.write(42, 3, compressedData, 0);
Container container = new Container(CompressionType.NONE, 42);
container.compress("testtesttesttest1".getBytes(), keys);
byte[] compressedData = container.data;
DataFileWriteResult res = df.write(42, 3, compressedData);
compressedData = df.read(42, 3, res.sector, res.compressedLength);
DataFileReadResult res2 = DataFile.decompress(compressedData, keys);
Container res2 = Container.decompress(compressedData, keys);
byte[] buf = res2.data;
String str = new String(buf);
Assert.assertEquals("testtesttesttest1", str);
Assert.assertEquals(res.crc, res2.crc);
Assert.assertEquals(42, res2.revision);
}
@@ -165,16 +154,17 @@ public class DataFileTest
DataFile df = new DataFile(file);
byte[] compressedData = DataFile.compress("testtesttesttest1".getBytes(), CompressionType.GZ, 42, keys);
DataFileWriteResult res = df.write(42, 3, compressedData, 0);
Container container = new Container(CompressionType.GZ, 42);
container.compress("testtesttesttest1".getBytes(), keys);
byte[] compressedData = container.data;
DataFileWriteResult res = df.write(42, 3, compressedData);
compressedData = df.read(42, 3, res.sector, res.compressedLength);
DataFileReadResult res2 = DataFile.decompress(compressedData, keys);
Container res2 = Container.decompress(compressedData, keys);
byte[] buf = res2.data;
String str = new String(buf);
Assert.assertEquals("testtesttesttest1", str);
Assert.assertEquals(res.crc, res2.crc);
Assert.assertEquals(42, res2.revision);
}
}

View File

@@ -0,0 +1,102 @@
/*
* Copyright (c) 2016-2017, 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.
*
* 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.fs.jagex;
import java.io.File;
import net.runelite.cache.StoreLocation;
import net.runelite.cache.fs.Archive;
import net.runelite.cache.fs.Container;
import net.runelite.cache.fs.Index;
import net.runelite.cache.fs.Store;
import net.runelite.cache.index.FileData;
import org.junit.Test;
import static org.junit.Assert.*;
import org.junit.Rule;
import org.junit.rules.TemporaryFolder;
public class DiskStorageTest
{
@Rule
public TemporaryFolder folder = StoreLocation.getTemporaryFolder();
@Test
public void testSaveArchive() throws Exception
{
File file = folder.newFolder();
DiskStorage storage = new DiskStorage(file);
Archive archive;
Archive archive2;
try (Store store = new Store(storage))
{
Index index = store.addIndex(0);
archive = index.addArchive(0);
archive2 = index.addArchive(1);
FileData[] fileData = new FileData[1];
archive.setFileData(fileData);
fileData[0] = new FileData();
FileData[] fileData2 = new FileData[1];
archive2.setFileData(fileData2);
fileData2[0] = new FileData();
byte[] data = "test".getBytes();
Container container = new Container(archive.getCompression(), -1);
container.compress(data, null);
byte[] compressedData = container.data;
storage.saveArchive(archive, compressedData);
container = new Container(archive.getCompression(), 42);
container.compress(data, null);
compressedData = container.data;
archive2.setRevision(42);
storage.saveArchive(archive2, compressedData);
store.save();
}
storage = new DiskStorage(file);
try (Store store = new Store(storage))
{
store.load();
Index index = store.findIndex(0);
Archive archive2_1 = index.getArchive(0);
Archive archive2_2 = index.getArchive(1);
byte[] comprsesedData = storage.loadArchive(archive2_1);
byte[] data = archive2_1.decompress(comprsesedData);
assertArrayEquals("test".getBytes(), data);
assertEquals(archive.getCrc(), archive2_1.getCrc());
assertEquals(archive.getRevision(), archive2_1.getRevision());
comprsesedData = storage.loadArchive(archive2_2);
data = archive2_2.decompress(comprsesedData);
assertArrayEquals("test".getBytes(), data);
assertEquals(archive2.getCrc(), archive2_2.getCrc());
assertEquals(archive2.getRevision(), archive2_2.getRevision());
}
}
}

View File

@@ -29,6 +29,7 @@ import io.netty.buffer.Unpooled;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import net.runelite.cache.fs.Container;
import net.runelite.cache.fs.jagex.CompressionType;
import net.runelite.cache.fs.jagex.DataFile;
import net.runelite.cache.protocol.decoders.ArchiveResponseDecoder;
@@ -45,7 +46,9 @@ public class ArchiveResponseEncoderTest
Random random = new Random(42L);
random.nextBytes(data);
byte[] compressedData = DataFile.compress(data, CompressionType.NONE, -1, null);
Container container =new Container(CompressionType.NONE, -1);
container.compress(data, null);
byte[] compressedData = container.data;//DataFile.compress(data, CompressionType.NONE, -1, null);
ArchiveResponsePacket archiveResponse = new ArchiveResponsePacket();
archiveResponse.setIndex(0);
@@ -67,7 +70,7 @@ public class ArchiveResponseEncoderTest
Assert.assertEquals(archiveResponse.getArchive(), response.getArchive());
Assert.assertArrayEquals(archiveResponse.getData(), response.getData());
byte[] decompressedData = DataFile.decompress(response.getData(), null).data;
byte[] decompressedData = Container.decompress(response.getData(), null).data;
Assert.assertArrayEquals(data, decompressedData);
}

View File

@@ -32,8 +32,8 @@ import net.runelite.cache.StoreLocation;
import net.runelite.cache.definitions.ScriptDefinition;
import net.runelite.cache.definitions.loaders.ScriptLoader;
import net.runelite.cache.fs.Archive;
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 net.runelite.cache.script.Instructions;
import org.junit.Rule;
@@ -61,17 +61,20 @@ public class DisassemblerTest
{
store.load();
Storage storage = store.getStorage();
Index index = store.getIndex(IndexType.CLIENTSCRIPT);
ScriptLoader loader = new ScriptLoader();
for (Archive archive : index.getArchives())
{
assert archive.getFiles().size() == 1;
byte[] contents = archive.decompress(storage.loadArchive(archive));
FSFile file = archive.getFiles().get(0);
byte[] contents = file.getContents();
if (contents == null)
{
continue;
}
ScriptDefinition script = loader.load(file.getFileId(), contents);
ScriptDefinition script = loader.load(0, contents);
File outFile = new File(outDir, archive.getArchiveId() + ".rs2asm");

View File

@@ -24,15 +24,18 @@
*/
package net.runelite.cache.server;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import net.runelite.cache.StoreLocation;
import net.runelite.cache.client.CacheClient;
import net.runelite.cache.fs.Archive;
import net.runelite.cache.fs.FSFile;
import net.runelite.cache.fs.Container;
import net.runelite.cache.fs.Index;
import net.runelite.cache.fs.Storage;
import net.runelite.cache.fs.Store;
import org.junit.Assert;
import net.runelite.cache.index.FileData;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
@@ -54,7 +57,6 @@ public class CacheServerTest
CacheServer server = new CacheServer(store, REVISION))
{
store.load();
store.rebuildCrc();
server.start();
@@ -75,7 +77,7 @@ public class CacheServerTest
{
addInitialFilesToStore(store);
store.rebuildCrc();
store.save();
server.start();
@@ -88,22 +90,36 @@ public class CacheServerTest
Index index = store2.findIndex(0);
Archive archive = index.getArchive(0);
archive.decompressAndLoad(null); // cache client doesn't decompress archive
FSFile file = archive.getFiles().get(0);
Assert.assertArrayEquals("test".getBytes(), file.getContents());
FileData[] files = archive.getFileData();
FileData file = files[0];
assertEquals(7, file.getNameHash());
Storage storage = store2.getStorage();
byte[] data = storage.loadArchive(archive);
data = archive.decompress(data);
assertArrayEquals("test".getBytes(), data);
assertEquals(store.getIndexes().get(0).getArchive(0).getCrc(), archive.getCrc());
}
}
}
private void addInitialFilesToStore(Store store) throws FileNotFoundException
private void addInitialFilesToStore(Store store) throws FileNotFoundException, IOException
{
Storage storage = store.getStorage();
Index index = store.addIndex(0);
Archive archive = index.addArchive(0);
FSFile file = new FSFile(0);
FileData[] files = new FileData[1];
archive.setFileData(files);
FileData file = files[0] = new FileData();
file.setNameHash(7);
file.setContents("test".getBytes());
archive.addFile(file);
byte[] data = "test".getBytes();
Container container = new Container(archive.getCompression(), -1);
container.compress(data, null);
byte[] compressedData = container.data;
storage.saveArchive(archive, compressedData);
}
}

View File

@@ -24,18 +24,13 @@
*/
package net.runelite.cache.util;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import static org.junit.Assert.assertArrayEquals;
import org.junit.Test;
public class XteaTest
{
@Test
public void test() throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException
public void test()
{
byte[] data = "testtesttest1".getBytes();

View File

@@ -0,0 +1 @@
org.slf4j.simpleLogger.defaultLogLevel=info