From 99256902e9eabea69aeffdd838029fc6ebe77229 Mon Sep 17 00:00:00 2001 From: Collin Smith Date: Tue, 3 Dec 2019 21:30:06 -0800 Subject: [PATCH] Added D2 finder to search for cofs in d2 files or dump d2 file entries --- .idea/runConfigurations/D2_Finder.xml | 10 ++ core/src/com/riiablo/codec/D2.java | 7 +- tools/src/com/riiablo/codec/D2Finder.java | 114 ++++++++++++++++++++++ 3 files changed, 127 insertions(+), 4 deletions(-) create mode 100644 .idea/runConfigurations/D2_Finder.xml create mode 100644 tools/src/com/riiablo/codec/D2Finder.java diff --git a/.idea/runConfigurations/D2_Finder.xml b/.idea/runConfigurations/D2_Finder.xml new file mode 100644 index 00000000..6fc55eb9 --- /dev/null +++ b/.idea/runConfigurations/D2_Finder.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/core/src/com/riiablo/codec/D2.java b/core/src/com/riiablo/codec/D2.java index 2241167c..5b5f27a5 100644 --- a/core/src/com/riiablo/codec/D2.java +++ b/core/src/com/riiablo/codec/D2.java @@ -4,6 +4,7 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.utils.GdxRuntimeException; import com.badlogic.gdx.utils.StreamUtils; +import com.riiablo.util.BufferUtils; import org.apache.commons.io.EndianUtils; import org.apache.commons.io.IOUtils; @@ -14,13 +15,11 @@ import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; -import com.riiablo.util.BufferUtils; - public class D2 { private static final String TAG = "D2"; - private static final boolean DEBUG = true; + private static final boolean DEBUG = !true; private static final boolean DEBUG_BLOCKS = DEBUG && true; - private static final boolean DEBUG_ENTRIES = DEBUG && false; + private static final boolean DEBUG_ENTRIES = DEBUG && true; Block blocks[]; diff --git a/tools/src/com/riiablo/codec/D2Finder.java b/tools/src/com/riiablo/codec/D2Finder.java new file mode 100644 index 00000000..b20b9957 --- /dev/null +++ b/tools/src/com/riiablo/codec/D2Finder.java @@ -0,0 +1,114 @@ +package com.riiablo.codec; + +import com.badlogic.gdx.Application; +import com.badlogic.gdx.ApplicationAdapter; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.assets.AssetManager; +import com.badlogic.gdx.backends.headless.HeadlessApplication; +import com.badlogic.gdx.backends.headless.HeadlessApplicationConfiguration; +import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.utils.Array; +import com.riiablo.Riiablo; +import com.riiablo.mpq.MPQFileHandleResolver; +import com.riiablo.util.DebugUtils; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.tuple.Pair; + +import java.io.PrintWriter; +import java.util.Arrays; + +public class D2Finder extends ApplicationAdapter { + private static final String TAG = "D2Viewer"; + + public static void main(String[] args) { + HeadlessApplicationConfiguration config = new HeadlessApplicationConfiguration(); + new HeadlessApplication(new D2Finder(args), config); + } + + String[] cofs; + + D2Finder(String[] args) { + Riiablo.home = new FileHandle(args[0]); + if (args.length > 1) { + this.cofs = Arrays.copyOfRange(args, 1, args.length); + } + } + + @Override + public void create() { + Gdx.app.setLogLevel(Application.LOG_DEBUG); + + Riiablo.home = Gdx.files.absolute(Riiablo.home.path()); + Riiablo.assets = new AssetManager(); + Riiablo.mpqs = new MPQFileHandleResolver(); + + String[] d2Names = { "animdata", "eanimdata" }; + Array> d2s = new Array<>(); + for (String d2Name : d2Names) { + String path = "data\\global\\" + d2Name + ".d2"; + FileHandle handle = Riiablo.mpqs.resolve(path); + D2 d2 = D2.loadFromFile(handle); + d2s.add(Pair.of(d2Name, d2)); + } + + if (cofs == null) { + for (Pair pair : d2s) { + dump(pair.getValue(), pair.getKey()); + } + } else { + for (String cof : cofs) { + Gdx.app.log(TAG, cof); + int i = 0; + for (Pair pair : d2s) { + if (lookup(cof, pair.getValue(), pair.getKey()) != null) i++; + } + if (i == 0) Gdx.app.log(TAG, cof + " was not found in any file!"); + } + } + + Gdx.app.exit(); + } + + private void dump(D2 lib, String libName) { + if (lib == null) return; + FileHandle handle = Gdx.files.local(libName + ".tmp"); + PrintWriter writer = null; + try { + writer = new PrintWriter(handle.write(false)); + writer.println("cof" + + '\t' + "framesPerDir" + + '\t' + "b1" + + '\t' + "b2" + + '\t' + "data" + ); + for (D2.Block block : lib.blocks) { + Gdx.app.log(TAG, "Writing " + block.numEntries + " to " + handle); + for (D2.Entry entry : block.entries) { + writer.println(entry.cof + + '\t' + entry.framesPerDir + + '\t' + (entry.b1 & 0xFF) + + '\t' + (entry.b2 & 0xFF) + + '\t' + DebugUtils.toByteArray(entry.data) + ); + } + } + } catch (Throwable t) { + Gdx.app.error(TAG, t.getMessage(), t); + } finally { + IOUtils.closeQuietly(writer); + } + } + + private D2.Entry lookup(String cof, D2 lib, String libName) { + if (lib == null) return null; + D2.Entry resolved = lib.getEntry(cof); + if (resolved != null) Gdx.app.log(TAG, " " + libName + " : " + resolved); + return resolved; + } + + @Override + public void dispose() { + Riiablo.assets.dispose(); + } +}