Sfoglia il codice sorgente

fixed small bug, added unpacker

UwU 1 mese fa
parent
commit
a04546b557
2 ha cambiato i file con 72 aggiunte e 1 eliminazioni
  1. 1 1
      src/WallpaperEngine/Media/DBusMediaSource.cpp
  2. 71 0
      tools/unpack_pkg.py

+ 1 - 1
src/WallpaperEngine/Media/DBusMediaSource.cpp

@@ -295,7 +295,7 @@ void DBusMediaSource::detectPlayer () {
 	);
 
 	if (reply == nullptr) {
-	    return;
+	    continue;
 	}
 
 	Data::Utils::ScopeGuard guard2 ([reply] { dbus_message_unref (reply); });

+ 71 - 0
tools/unpack_pkg.py

@@ -0,0 +1,71 @@
+#!/usr/bin/env python3
+"""Extracts files out of a Wallpaper Engine .pkg container (scene.pkg, general.pkg, etc).
+
+Usage:
+    unpack_pkg.py <path-to.pkg> <output-dir> [name-filter ...]
+
+With no filters, everything is extracted. Filters are substring matches against
+the stored filename (case-insensitive), e.g.:
+
+    unpack_pkg.py scene.pkg out scene.json
+    unpack_pkg.py scene.pkg out models/spiritblossomahribase_puppet.mdl
+"""
+import struct
+import sys
+import os
+
+
+def read_u32(f):
+    return struct.unpack('<I', f.read(4))[0]
+
+
+def read_sized_string(f):
+    n = read_u32(f)
+    return f.read(n).decode('utf-8', errors='replace')
+
+
+def extract(pkg_path, out_dir, name_filters=None):
+    with open(pkg_path, 'rb') as f:
+        header = read_sized_string(f)
+        if not header.startswith('PKGV'):
+            raise ValueError(f"expected PKGV header, got {header!r}")
+
+        count = read_u32(f)
+        entries = []
+        for _ in range(count):
+            name = read_sized_string(f)
+            offset = read_u32(f)
+            length = read_u32(f)
+            entries.append((name, offset, length))
+
+        base = f.tell()
+        os.makedirs(out_dir, exist_ok=True)
+
+        for name, offset, length in entries:
+            if name_filters and not any(want.lower() in name.lower() for want in name_filters):
+                continue
+            f.seek(base + offset)
+            data = f.read(length)
+            dest = os.path.join(out_dir, name.replace('\\', '/'))
+            os.makedirs(os.path.dirname(dest), exist_ok=True)
+            with open(dest, 'wb') as out:
+                out.write(data)
+            print(f"extracted {name} ({length} bytes)")
+
+        return entries
+
+
+if __name__ == '__main__':
+    if len(sys.argv) < 3:
+        print(__doc__)
+        sys.exit(1)
+
+    pkg_path = sys.argv[1]
+    out_dir = sys.argv[2]
+    filters = sys.argv[3:] or None
+
+    all_entries = extract(pkg_path, out_dir, filters)
+
+    if filters is None:
+        for entry_name, _, entry_length in all_entries:
+            print(entry_name, entry_length)