public Archive getArchive(int id) { for (Archive a : archives) { if (a.getArchiveId() == id) { return a; } } return null; }
@Override public void saveArchive(Archive archive, byte[] bytes) throws IOException { data.put((long) archive.getIndex().getId() << 32 | archive.getArchiveId(), bytes); } }
@Override public byte[] loadArchive(Archive archive) throws IOException { return data.get((long) archive.getIndex().getId() << 32 | archive.getArchiveId()); }
logger.warn("crc mismatch for archive {}/{}", index.getId(), this.getArchiveId()); throw new IOException("CRC mismatch for " + index.getId() + "/" + this.getArchiveId()); index.getId(), this.getArchiveId(), this.getRevision(), container.revision);
@Override public byte[] loadArchive(Archive archive) throws IOException { Index index = archive.getIndex(); IndexFile indexFile = getIndex(index.getId()); assert indexFile.getIndexFileId() == index.getId(); IndexEntry entry = indexFile.read(archive.getArchiveId()); if (entry == null) { logger.debug("can't read archive " + archive.getArchiveId() + " from index " + index.getId()); return null; } assert entry.getId() == archive.getArchiveId(); logger.trace("Loading archive {} for index {} from sector {} length {}", archive.getArchiveId(), index.getId(), entry.getSector(), entry.getLength()); byte[] archiveData = data.read(index.getId(), entry.getId(), entry.getSector(), entry.getLength()); return archiveData; }
for (Archive archive : idx.getArchives()) br.printf("id=%d\n", archive.getArchiveId()); br.printf("namehash=%d\n", archive.getNameHash()); br.printf("revision=%d\n", archive.getRevision());
continue; case "contents": data.put((long) idx.getId() << 32 | archive.getArchiveId(), Base64.getDecoder().decode(value)); continue;
public void load() throws IOException { InterfaceLoader loader = new InterfaceLoader(); Storage storage = store.getStorage(); Index index = store.getIndex(IndexType.INTERFACES); int max = index.getArchives().stream().mapToInt(a -> a.getArchiveId()).max().getAsInt(); interfaces = new InterfaceDefinition[max + 1][]; for (Archive archive : index.getArchives()) { int archiveId = archive.getArchiveId(); byte[] archiveData = storage.loadArchive(archive); ArchiveFiles files = archive.getFiles(archiveData); InterfaceDefinition[] ifaces = interfaces[archiveId]; if (ifaces == null) { ifaces = interfaces[archiveId] = new InterfaceDefinition[archive.getFileData().length]; } for (FSFile file : files.getFiles()) { int fileId = file.getFileId(); int widgetId = (archiveId << 16) + fileId; InterfaceDefinition iface = loader.load(widgetId, file.getContents()); ifaces[fileId] = iface; } } }
@Override public void saveArchive(Archive a, byte[] archiveData) throws IOException { Index index = a.getIndex(); IndexFile indexFile = getIndex(index.getId()); assert indexFile.getIndexFileId() == index.getId(); DataFileWriteResult res = data.write(index.getId(), a.getArchiveId(), archiveData); indexFile.write(new IndexEntry(indexFile, a.getArchiveId(), res.sector, res.compressedLength)); byte compression = archiveData[0]; int compressedSize = Ints.fromBytes(archiveData[1], archiveData[2], archiveData[3], archiveData[4]); // don't crc the appended revision, if it is there int length = 1 // compression type + 4 // compressed size + compressedSize + (compression != CompressionType.NONE ? 4 : 0); Crc32 crc = new Crc32(); crc.update(archiveData, 0, length); a.setCrc(crc.getHash()); logger.trace("Saved archive {}/{} at sector {}, compressed length {}", index.getId(), a.getArchiveId(), res.sector, res.compressedLength); } }
public void load() throws IOException { Storage storage = store.getStorage(); Index index = store.getIndex(IndexType.SPRITES); for (Archive a : index.getArchives()) { byte[] contents = a.decompress(storage.loadArchive(a)); SpriteLoader loader = new SpriteLoader(); SpriteDefinition[] defs = loader.load(a.getArchiveId(), contents); for (SpriteDefinition sprite : defs) { sprites.put(sprite.getId(), sprite); } } }
@Test public void test() throws IOException { File modelDir = folder.newFolder("models"); int count = 0; try (Store store = new Store(StoreLocation.LOCATION)) { store.load(); Storage storage = store.getStorage(); Index index = store.getIndex(IndexType.MODELS); for (Archive archive : index.getArchives()) { 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")); ++count; } } logger.info("Dumped {} models to {}", count, modelDir); } }
private void loadSprites() throws IOException { Storage storage = store.getStorage(); Index index = store.getIndex(IndexType.SPRITES); final int mapsceneHash = Djb2.hash("mapscene"); for (Archive a : index.getArchives()) { byte[] contents = a.decompress(storage.loadArchive(a)); SpriteLoader loader = new SpriteLoader(); SpriteDefinition[] sprites = loader.load(a.getArchiveId(), contents); for (SpriteDefinition sprite : sprites) { if (sprite.getHeight() <= 0 || sprite.getWidth() <= 0) { continue; } if (a.getNameHash() == mapsceneHash) { BufferedImage spriteImage = new BufferedImage(sprite.getWidth(), sprite.getHeight(), BufferedImage.TYPE_INT_ARGB); spriteImage.setRGB(0, 0, sprite.getWidth(), sprite.getHeight(), sprite.getPixels(), 0, sprite.getWidth()); // scale image down so it fits Image scaledImage = spriteImage.getScaledInstance(MAPICON_MAX_WIDTH, MAPICON_MAX_HEIGHT, 0); assert scaledMapIcons.containsKey(sprite.getFrame()) == false; scaledMapIcons.put(sprite.getFrame(), scaledImage); } } } }
@Test public void test() throws IOException { File dumpDir = folder.newFolder(); int count = 0; try (Store store = new Store(StoreLocation.LOCATION)) { store.load(); Storage storage = store.getStorage(); Index index = store.getIndex(IndexType.SOUNDEFFECTS); for (Archive archive : index.getArchives()) { byte[] contents = archive.decompress(storage.loadArchive(archive)); SoundEffectLoader soundEffectLoader = new SoundEffectLoader(); SoundEffectDefinition soundEffect = soundEffectLoader.load(contents); Files.write(gson.toJson(soundEffect), new File(dumpDir, archive.getArchiveId() + ".json"), Charset.defaultCharset()); ++count; } } logger.info("Dumped {} sound effects to {}", count, dumpDir); } }
ScriptDefinition script = loader.load(archive.getArchiveId(), contents); File outFile = new File(outDir, archive.getArchiveId() + ".rs2asm");
FramemapDefinition framemap = loader.load(0, contents); Files.write(gson.toJson(framemap), new File(outDir, archive.getArchiveId() + ".json"), Charset.defaultCharset()); ++count;
private void dumpTrackArchive(File dumpDir, Storage storage, Archive archive) throws IOException { byte[] contents = archive.decompress(storage.loadArchive(archive)); if (contents == null) { return; } TrackLoader loader = new TrackLoader(); TrackDefinition def = loader.load(contents); String name; if (archive.getNameHash() != 0) { name = djb2.getName(archive.getNameHash()); if (name == null) { name = "name-" + archive.getNameHash(); } } else { name = "archive-" + archive.getArchiveId(); } File dest = new File(dumpDir, name + ".midi"); assert !dest.exists(); Files.write(def.midi, dest); }
public IndexData toIndexData() { IndexData data = new IndexData(); data.setProtocol(protocol); data.setRevision(revision); data.setNamed(named); ArchiveData[] archiveDatas = new ArchiveData[archives.size()]; data.setArchives(archiveDatas); int idx = 0; for (Archive archive : archives) { ArchiveData ad = archiveDatas[idx++] = new ArchiveData(); ad.setId(archive.getArchiveId()); ad.setNameHash(archive.getNameHash()); ad.setCrc(archive.getCrc()); ad.setRevision(archive.getRevision()); FileData[] files = archive.getFileData(); ad.setFiles(files); } return data; } }
@Override public void save(Store store) throws IOException { for (Index index : store.getIndexes()) { IndexEntry entry = cacheDao.createIndex(con, cacheEntry, index.getId(), index.getCrc(), index.getRevision()); for (Archive archive : index.getArchives()) { ArchiveEntry archiveEntry = cacheDao.findArchive(con, entry, archive.getArchiveId(), archive.getNameHash(), archive.getCrc(), archive.getRevision()); if (archiveEntry == null) { byte[] hash = archive.getHash(); archiveEntry = cacheDao.createArchive(con, entry, archive.getArchiveId(), archive.getNameHash(), archive.getCrc(), archive.getRevision(), hash); for (FileData file : archive.getFileData()) { cacheDao.associateFileToArchive(con, archiveEntry, file.getId(), file.getNameHash()); } } cacheDao.associateArchiveToIndex(con, archiveEntry, entry); } } }
FramemapDefinition framemap = fmloader.load(framemapArchive.getArchiveId(), framemapContents); Files.write(gson.toJson(frames), new File(outDir, archive.getArchiveId() + ".json"), Charset.defaultCharset()); ++count;
archive.getIndex().getId(), archive.getArchiveId(), hash, archive.getCrc()); throw new RuntimeException("crc mismatch");