universal-game-modder 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ACCEPTABLE_USE.md +49 -0
- package/CHANGELOG.md +119 -0
- package/LICENSE +21 -0
- package/LICENSE-EULA.md +62 -0
- package/README.md +162 -0
- package/VERIFICATION.md +132 -0
- package/dist/backends/child-pool.js +91 -0
- package/dist/backends/mcp-child.js +102 -0
- package/dist/backends/mcp-child.js.map +1 -0
- package/dist/core/config.d.ts +10 -0
- package/dist/core/config.js +48 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/engine-detector.d.ts +13 -0
- package/dist/core/engine-detector.js +247 -0
- package/dist/core/engine-detector.js.map +1 -0
- package/dist/core/event-bus.js +18 -0
- package/dist/core/file-classifier.js +394 -0
- package/dist/core/model-db.js +517 -0
- package/dist/core/model-db.js.map +1 -0
- package/dist/core/router.d.ts +6 -0
- package/dist/core/router.js +143 -0
- package/dist/core/router.js.map +1 -0
- package/dist/core/session.js +114 -0
- package/dist/decoders/audio-export.js +57 -0
- package/dist/decoders/mesh-export.d.ts +20 -0
- package/dist/decoders/mesh-export.js +174 -0
- package/dist/decoders/mesh-export.js.map +1 -0
- package/dist/decoders/native/disassembler.js +85 -0
- package/dist/decoders/native/disassembler.js.map +1 -0
- package/dist/decoders/png-encode.d.ts +17 -0
- package/dist/decoders/png-encode.js +33 -0
- package/dist/decoders/texture-decode.js +278 -0
- package/dist/decoders/texture-decode.js.map +1 -0
- package/dist/decoders/unity/audioclip.d.ts +55 -0
- package/dist/decoders/unity/audioclip.js +87 -0
- package/dist/decoders/unity/audioclip.js.map +1 -0
- package/dist/decoders/unity/binary-reader.d.ts +45 -0
- package/dist/decoders/unity/binary-reader.js +141 -0
- package/dist/decoders/unity/binary-reader.js.map +1 -0
- package/dist/decoders/unity/mesh.js +198 -0
- package/dist/decoders/unity/mesh.js.map +1 -0
- package/dist/decoders/unity/ress-reader.d.ts +33 -0
- package/dist/decoders/unity/ress-reader.js +82 -0
- package/dist/decoders/unity/ress-reader.js.map +1 -0
- package/dist/decoders/unity/serialized-file.d.ts +65 -0
- package/dist/decoders/unity/serialized-file.js +144 -0
- package/dist/decoders/unity/texture2d.js +185 -0
- package/dist/decoders/unity/vertex-data.d.ts +54 -0
- package/dist/decoders/unity/vertex-data.js +174 -0
- package/dist/decoders/unity/vertex-data.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +23 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.js +66 -0
- package/dist/tools/decode-tools.d.ts +29 -0
- package/dist/tools/decode-tools.js +441 -0
- package/dist/tools/delegates/jar-editor.d.ts +2 -0
- package/dist/tools/delegates/jar-editor.js +276 -0
- package/dist/tools/delegates/unity-decompiler.d.ts +2 -0
- package/dist/tools/delegates/unity-decompiler.js +291 -0
- package/dist/tools/delegates/unreal-assets.d.ts +2 -0
- package/dist/tools/delegates/unreal-assets.js +122 -0
- package/dist/tools/detection-tools.d.ts +2 -0
- package/dist/tools/detection-tools.js +164 -0
- package/dist/tools/detection-tools.js.map +1 -0
- package/dist/tools/index.d.ts +8 -0
- package/dist/tools/index.js +30 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/native/index.d.ts +2 -0
- package/dist/tools/native/index.js +1201 -0
- package/dist/tools/native-comprehension-tools.js +298 -0
- package/dist/tools/native-comprehension-tools.js.map +1 -0
- package/dist/tools/unpack-tools.d.ts +2 -0
- package/dist/tools/unpack-tools.js +382 -0
- package/dist/tools/workflow-tools.d.ts +2 -0
- package/dist/tools/workflow-tools.js +434 -0
- package/dist/utils/logger.d.ts +11 -0
- package/dist/utils/logger.js +49 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/path-utils.d.ts +15 -0
- package/dist/utils/path-utils.js +24 -0
- package/dist/utils/path-utils.js.map +1 -0
- package/dist/utils/steam-finder.d.ts +8 -0
- package/dist/utils/steam-finder.js +32 -0
- package/dist/web/web-server.d.ts +1 -0
- package/dist/web/web-server.js +369 -0
- package/licenses/THIRD-PARTY-NOTICES.md +35 -0
- package/llms-install.md +34 -0
- package/package.json +69 -0
- package/server.json +20 -0
- package/setup.ps1 +34 -0
- package/ugm.config.json +9 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* texture-decode.ts — turn raw Unity texture bytes + a TextureFormat into RGBA pixels.
|
|
3
|
+
*
|
|
4
|
+
* Two paths:
|
|
5
|
+
* 1. UNCOMPRESSED formats (RGBA32, RGB24, Alpha8, ARGB32, BGRA32, RGB565, R8, R16...)
|
|
6
|
+
* are unpacked here directly — no WASM needed. Baldi is overwhelmingly RGBA32, so
|
|
7
|
+
* this path carries most of the corpus.
|
|
8
|
+
* 2. COMPRESSED formats (DXT/BC, ETC, ASTC, PVRTC, ATC, EAC, and the Crunched variants)
|
|
9
|
+
* are decoded by texture2ddecoder-wasm. Crunched formats are unpacked first
|
|
10
|
+
* (unpack_unity_crunch) then decoded by their base codec. The WASM decoders emit
|
|
11
|
+
* BGRA; we swap to RGBA on the way out so the PNG encoder gets a consistent layout.
|
|
12
|
+
*
|
|
13
|
+
* Output is ALWAYS tightly-packed RGBA8 (width*height*4 bytes), top-left origin. Unity
|
|
14
|
+
* stores textures bottom-up, so the caller (png-encode) flips vertically.
|
|
15
|
+
*
|
|
16
|
+
* A format we cannot decode returns { ok:false, reason } rather than throwing — the
|
|
17
|
+
* decode_assets tool turns that into a decoded=0 asset row with a note (never a silent drop).
|
|
18
|
+
*/
|
|
19
|
+
import { initialize, decode_bc1, decode_bc3, decode_bc4, decode_bc5, decode_bc6, decode_bc7, decode_etc1, decode_etc2, decode_etc2a1, decode_etc2a8, decode_pvrtc, decode_astc, decode_atc_rgb4, decode_atc_rgba8, unpack_unity_crunch, } from 'texture2ddecoder-wasm';
|
|
20
|
+
import { TextureFormat } from './unity/texture2d.js';
|
|
21
|
+
let wasmReady = false;
|
|
22
|
+
async function ensureWasm() {
|
|
23
|
+
if (!wasmReady) {
|
|
24
|
+
await initialize();
|
|
25
|
+
wasmReady = true;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** BGRA (or BGRA-ish) -> RGBA in place-ish (returns a new Buffer). */
|
|
29
|
+
function bgraToRgba(bgra, width, height) {
|
|
30
|
+
const n = width * height * 4;
|
|
31
|
+
const out = Buffer.allocUnsafe(n);
|
|
32
|
+
for (let i = 0; i < n; i += 4) {
|
|
33
|
+
out[i] = bgra[i + 2]; // R <- B
|
|
34
|
+
out[i + 1] = bgra[i + 1]; // G
|
|
35
|
+
out[i + 2] = bgra[i]; // B <- R
|
|
36
|
+
out[i + 3] = bgra[i + 3]; // A
|
|
37
|
+
}
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
/** ASTC block dimensions per format. */
|
|
41
|
+
function astcBlock(fmt) {
|
|
42
|
+
switch (fmt) {
|
|
43
|
+
case TextureFormat.ASTC_RGB_4x4:
|
|
44
|
+
case TextureFormat.ASTC_RGBA_4x4:
|
|
45
|
+
return [4, 4];
|
|
46
|
+
case TextureFormat.ASTC_RGB_5x5:
|
|
47
|
+
case TextureFormat.ASTC_RGBA_5x5:
|
|
48
|
+
return [5, 5];
|
|
49
|
+
case TextureFormat.ASTC_RGB_6x6:
|
|
50
|
+
case TextureFormat.ASTC_RGBA_6x6:
|
|
51
|
+
return [6, 6];
|
|
52
|
+
case TextureFormat.ASTC_RGB_8x8:
|
|
53
|
+
case TextureFormat.ASTC_RGBA_8x8:
|
|
54
|
+
return [8, 8];
|
|
55
|
+
case TextureFormat.ASTC_RGB_10x10:
|
|
56
|
+
case TextureFormat.ASTC_RGBA_10x10:
|
|
57
|
+
return [10, 10];
|
|
58
|
+
case TextureFormat.ASTC_RGB_12x12:
|
|
59
|
+
case TextureFormat.ASTC_RGBA_12x12:
|
|
60
|
+
return [12, 12];
|
|
61
|
+
default:
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/** Decode an uncompressed Unity texture format directly to RGBA8. Returns null if not uncompressed. */
|
|
66
|
+
function decodeUncompressed(data, fmt, width, height) {
|
|
67
|
+
const px = width * height;
|
|
68
|
+
const out = Buffer.alloc(px * 4);
|
|
69
|
+
const need = (bytes) => data.length >= bytes;
|
|
70
|
+
switch (fmt) {
|
|
71
|
+
case TextureFormat.RGBA32: {
|
|
72
|
+
if (!need(px * 4))
|
|
73
|
+
return null;
|
|
74
|
+
data.copy(out, 0, 0, px * 4);
|
|
75
|
+
return out;
|
|
76
|
+
}
|
|
77
|
+
case TextureFormat.ARGB32: {
|
|
78
|
+
if (!need(px * 4))
|
|
79
|
+
return null;
|
|
80
|
+
for (let i = 0; i < px; i++) {
|
|
81
|
+
const s = i * 4;
|
|
82
|
+
out[s] = data[s + 1];
|
|
83
|
+
out[s + 1] = data[s + 2];
|
|
84
|
+
out[s + 2] = data[s + 3];
|
|
85
|
+
out[s + 3] = data[s];
|
|
86
|
+
}
|
|
87
|
+
return out;
|
|
88
|
+
}
|
|
89
|
+
case TextureFormat.BGRA32: {
|
|
90
|
+
if (!need(px * 4))
|
|
91
|
+
return null;
|
|
92
|
+
for (let i = 0; i < px; i++) {
|
|
93
|
+
const s = i * 4;
|
|
94
|
+
out[s] = data[s + 2];
|
|
95
|
+
out[s + 1] = data[s + 1];
|
|
96
|
+
out[s + 2] = data[s];
|
|
97
|
+
out[s + 3] = data[s + 3];
|
|
98
|
+
}
|
|
99
|
+
return out;
|
|
100
|
+
}
|
|
101
|
+
case TextureFormat.RGB24: {
|
|
102
|
+
if (!need(px * 3))
|
|
103
|
+
return null;
|
|
104
|
+
for (let i = 0; i < px; i++) {
|
|
105
|
+
out[i * 4] = data[i * 3];
|
|
106
|
+
out[i * 4 + 1] = data[i * 3 + 1];
|
|
107
|
+
out[i * 4 + 2] = data[i * 3 + 2];
|
|
108
|
+
out[i * 4 + 3] = 255;
|
|
109
|
+
}
|
|
110
|
+
return out;
|
|
111
|
+
}
|
|
112
|
+
case TextureFormat.Alpha8: {
|
|
113
|
+
if (!need(px))
|
|
114
|
+
return null;
|
|
115
|
+
for (let i = 0; i < px; i++) {
|
|
116
|
+
out[i * 4] = 255;
|
|
117
|
+
out[i * 4 + 1] = 255;
|
|
118
|
+
out[i * 4 + 2] = 255;
|
|
119
|
+
out[i * 4 + 3] = data[i];
|
|
120
|
+
}
|
|
121
|
+
return out;
|
|
122
|
+
}
|
|
123
|
+
case TextureFormat.R8: {
|
|
124
|
+
if (!need(px))
|
|
125
|
+
return null;
|
|
126
|
+
for (let i = 0; i < px; i++) {
|
|
127
|
+
out[i * 4] = data[i];
|
|
128
|
+
out[i * 4 + 1] = data[i];
|
|
129
|
+
out[i * 4 + 2] = data[i];
|
|
130
|
+
out[i * 4 + 3] = 255;
|
|
131
|
+
}
|
|
132
|
+
return out;
|
|
133
|
+
}
|
|
134
|
+
case TextureFormat.RGB565: {
|
|
135
|
+
if (!need(px * 2))
|
|
136
|
+
return null;
|
|
137
|
+
for (let i = 0; i < px; i++) {
|
|
138
|
+
const v = data.readUInt16LE(i * 2);
|
|
139
|
+
const r = (v >> 11) & 0x1f;
|
|
140
|
+
const g = (v >> 5) & 0x3f;
|
|
141
|
+
const b = v & 0x1f;
|
|
142
|
+
out[i * 4] = (r << 3) | (r >> 2);
|
|
143
|
+
out[i * 4 + 1] = (g << 2) | (g >> 4);
|
|
144
|
+
out[i * 4 + 2] = (b << 3) | (b >> 2);
|
|
145
|
+
out[i * 4 + 3] = 255;
|
|
146
|
+
}
|
|
147
|
+
return out;
|
|
148
|
+
}
|
|
149
|
+
default:
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Decode any supported Unity texture format to tightly-packed RGBA8.
|
|
155
|
+
* `data` is the raw (possibly streamed) texture bytes; `fmt` is the Unity TextureFormat int.
|
|
156
|
+
*/
|
|
157
|
+
export async function decodeTexture(data, fmt, width, height) {
|
|
158
|
+
if (width <= 0 || height <= 0)
|
|
159
|
+
return { ok: false, reason: `bad dimensions ${width}x${height}` };
|
|
160
|
+
if (data.length === 0)
|
|
161
|
+
return { ok: false, reason: 'no pixel data' };
|
|
162
|
+
// 1) Uncompressed fast path (no WASM).
|
|
163
|
+
const direct = decodeUncompressed(data, fmt, width, height);
|
|
164
|
+
if (direct)
|
|
165
|
+
return { ok: true, rgba: direct };
|
|
166
|
+
// 2) Crunched -> unpack to the base codec stream first.
|
|
167
|
+
let payload = data;
|
|
168
|
+
let effFmt = fmt;
|
|
169
|
+
try {
|
|
170
|
+
if (fmt === TextureFormat.DXT1Crunched) {
|
|
171
|
+
const u = await unpackCrunch(data);
|
|
172
|
+
if (!u)
|
|
173
|
+
return { ok: false, reason: 'DXT1Crunched unpack failed' };
|
|
174
|
+
payload = u;
|
|
175
|
+
effFmt = TextureFormat.DXT1;
|
|
176
|
+
}
|
|
177
|
+
else if (fmt === TextureFormat.DXT5Crunched) {
|
|
178
|
+
const u = await unpackCrunch(data);
|
|
179
|
+
if (!u)
|
|
180
|
+
return { ok: false, reason: 'DXT5Crunched unpack failed' };
|
|
181
|
+
payload = u;
|
|
182
|
+
effFmt = TextureFormat.DXT5;
|
|
183
|
+
}
|
|
184
|
+
else if (fmt === TextureFormat.ETC_RGB4Crunched) {
|
|
185
|
+
const u = await unpackCrunch(data);
|
|
186
|
+
if (!u)
|
|
187
|
+
return { ok: false, reason: 'ETC_RGB4Crunched unpack failed' };
|
|
188
|
+
payload = u;
|
|
189
|
+
effFmt = TextureFormat.ETC_RGB4;
|
|
190
|
+
}
|
|
191
|
+
else if (fmt === TextureFormat.ETC2_RGBA8Crunched) {
|
|
192
|
+
const u = await unpackCrunch(data);
|
|
193
|
+
if (!u)
|
|
194
|
+
return { ok: false, reason: 'ETC2_RGBA8Crunched unpack failed' };
|
|
195
|
+
payload = u;
|
|
196
|
+
effFmt = TextureFormat.ETC2_RGBA8;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
catch (e) {
|
|
200
|
+
return { ok: false, reason: `crunch unpack threw: ${e.message}` };
|
|
201
|
+
}
|
|
202
|
+
// 3) Compressed (WASM). All WASM decoders emit BGRA -> swap to RGBA.
|
|
203
|
+
try {
|
|
204
|
+
await ensureWasm();
|
|
205
|
+
let bgra = null;
|
|
206
|
+
switch (effFmt) {
|
|
207
|
+
case TextureFormat.DXT1:
|
|
208
|
+
bgra = await decode_bc1(payload, width, height);
|
|
209
|
+
break;
|
|
210
|
+
case TextureFormat.DXT5:
|
|
211
|
+
bgra = await decode_bc3(payload, width, height);
|
|
212
|
+
break;
|
|
213
|
+
case TextureFormat.BC4:
|
|
214
|
+
bgra = await decode_bc4(payload, width, height);
|
|
215
|
+
break;
|
|
216
|
+
case TextureFormat.BC5:
|
|
217
|
+
bgra = await decode_bc5(payload, width, height);
|
|
218
|
+
break;
|
|
219
|
+
case TextureFormat.BC6H:
|
|
220
|
+
bgra = await decode_bc6(payload, width, height);
|
|
221
|
+
break;
|
|
222
|
+
case TextureFormat.BC7:
|
|
223
|
+
bgra = await decode_bc7(payload, width, height);
|
|
224
|
+
break;
|
|
225
|
+
case TextureFormat.ETC_RGB4:
|
|
226
|
+
bgra = await decode_etc1(payload, width, height);
|
|
227
|
+
break;
|
|
228
|
+
case TextureFormat.ETC2_RGB:
|
|
229
|
+
bgra = await decode_etc2(payload, width, height);
|
|
230
|
+
break;
|
|
231
|
+
case TextureFormat.ETC2_RGBA1:
|
|
232
|
+
bgra = await decode_etc2a1(payload, width, height);
|
|
233
|
+
break;
|
|
234
|
+
case TextureFormat.ETC2_RGBA8:
|
|
235
|
+
bgra = await decode_etc2a8(payload, width, height);
|
|
236
|
+
break;
|
|
237
|
+
case TextureFormat.ATC_RGB4:
|
|
238
|
+
bgra = await decode_atc_rgb4(payload, width, height);
|
|
239
|
+
break;
|
|
240
|
+
case TextureFormat.ATC_RGBA8:
|
|
241
|
+
bgra = await decode_atc_rgba8(payload, width, height);
|
|
242
|
+
break;
|
|
243
|
+
case TextureFormat.PVRTC_RGB2:
|
|
244
|
+
case TextureFormat.PVRTC_RGBA2:
|
|
245
|
+
bgra = await decode_pvrtc(payload, width, height, true);
|
|
246
|
+
break;
|
|
247
|
+
case TextureFormat.PVRTC_RGB4:
|
|
248
|
+
case TextureFormat.PVRTC_RGBA4:
|
|
249
|
+
bgra = await decode_pvrtc(payload, width, height, false);
|
|
250
|
+
break;
|
|
251
|
+
default: {
|
|
252
|
+
const block = astcBlock(effFmt);
|
|
253
|
+
if (block) {
|
|
254
|
+
bgra = await decode_astc(payload, width, height, block[0], block[1]);
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
return {
|
|
258
|
+
ok: false,
|
|
259
|
+
reason: `unsupported TextureFormat ${TextureFormat[fmt] ?? fmt}`,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
if (!bgra)
|
|
265
|
+
return { ok: false, reason: `decoder returned null for ${TextureFormat[effFmt] ?? effFmt}` };
|
|
266
|
+
return { ok: true, rgba: bgraToRgba(bgra, width, height) };
|
|
267
|
+
}
|
|
268
|
+
catch (e) {
|
|
269
|
+
return { ok: false, reason: `decode threw: ${e.message}` };
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
async function unpackCrunch(data) {
|
|
273
|
+
await ensureWasm();
|
|
274
|
+
// Unity uses a modified crunch; unpack_unity_crunch is the Unity-specific variant.
|
|
275
|
+
const u = await unpack_unity_crunch(data);
|
|
276
|
+
return u ? Buffer.from(u) : null;
|
|
277
|
+
}
|
|
278
|
+
//# sourceMappingURL=texture-decode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"texture-decode.js","sourceRoot":"","sources":["../../src/decoders/texture-decode.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* audioclip.ts — parse a Unity AudioClip object (Unity 2020.3 / format v22, typeTree DISABLED).
|
|
3
|
+
*
|
|
4
|
+
* AudioClip stores its audio in a streamed resource (.resource / .resS), referenced by an
|
|
5
|
+
* m_Resource { source, offset, size, compressionFormat } block. The audio is NOT inside the
|
|
6
|
+
* .assets file — the .assets holds only the metadata + the pointer.
|
|
7
|
+
*
|
|
8
|
+
* SCOPE (PR-2.3 first slice): extract the metadata (name, channels, frequency, bits) and the
|
|
9
|
+
* StreamedResource pointer. The actual sample bytes are pulled by the caller via the .resource
|
|
10
|
+
* stream reader. Two on-disk formats are handled downstream without a codec library:
|
|
11
|
+
* - PCM (compressionFormat 0): raw little-endian samples -> wrap in a WAV header.
|
|
12
|
+
* - Vorbis (compressionFormat 1): the bytes ARE a complete Ogg-Vorbis stream -> write .ogg.
|
|
13
|
+
* Other compression formats (ADPCM/MP3/etc.) are reported unsupported (noted decoded=0 row).
|
|
14
|
+
*
|
|
15
|
+
* Reference field order: Unity 2020.3 AudioClip (AssetStudio AudioClip.cs), little-endian.
|
|
16
|
+
* m_Name : AlignedString
|
|
17
|
+
* m_LoadType : Int32
|
|
18
|
+
* m_Channels : Int32
|
|
19
|
+
* m_Frequency : Int32
|
|
20
|
+
* m_BitsPerSample : Int32
|
|
21
|
+
* m_Length : float
|
|
22
|
+
* m_IsTrackerFormat : bool ; align(4)
|
|
23
|
+
* m_SubsoundIndex : Int32
|
|
24
|
+
* m_PreloadAudioData : bool ; m_LoadInBackground : bool ; m_Legacy3D : bool ; align(4)
|
|
25
|
+
* m_Resource : StreamedResource { m_Source:AlignedString, m_Offset:UInt64, m_Size:UInt64 }
|
|
26
|
+
* m_CompressionFormat : Int32
|
|
27
|
+
*/
|
|
28
|
+
import type { ObjectInfo, SerializedFileHeader } from './serialized-file.js';
|
|
29
|
+
/** Unity AudioCompressionFormat. */
|
|
30
|
+
export declare enum AudioCompressionFormat {
|
|
31
|
+
PCM = 0,
|
|
32
|
+
Vorbis = 1,
|
|
33
|
+
ADPCM = 2,
|
|
34
|
+
MP3 = 3,
|
|
35
|
+
VAG = 4,
|
|
36
|
+
HEVAG = 5,
|
|
37
|
+
XMA = 6,
|
|
38
|
+
AAC = 7,
|
|
39
|
+
GCADPCM = 8,
|
|
40
|
+
ATRAC9 = 9
|
|
41
|
+
}
|
|
42
|
+
export interface ParsedAudioClip {
|
|
43
|
+
name: string;
|
|
44
|
+
channels: number;
|
|
45
|
+
frequency: number;
|
|
46
|
+
bitsPerSample: number;
|
|
47
|
+
length: number;
|
|
48
|
+
compressionFormat: number;
|
|
49
|
+
compressionName: string;
|
|
50
|
+
/** stream pointer into the sibling .resource/.resS. */
|
|
51
|
+
source: string;
|
|
52
|
+
offset: bigint;
|
|
53
|
+
size: number;
|
|
54
|
+
}
|
|
55
|
+
export declare function parseAudioClip(buf: Buffer, header: SerializedFileHeader, obj: ObjectInfo): ParsedAudioClip;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* audioclip.ts — parse a Unity AudioClip object (Unity 2020.3 / format v22, typeTree DISABLED).
|
|
3
|
+
*
|
|
4
|
+
* AudioClip stores its audio in a streamed resource (.resource / .resS), referenced by an
|
|
5
|
+
* m_Resource { source, offset, size, compressionFormat } block. The audio is NOT inside the
|
|
6
|
+
* .assets file — the .assets holds only the metadata + the pointer.
|
|
7
|
+
*
|
|
8
|
+
* SCOPE (PR-2.3 first slice): extract the metadata (name, channels, frequency, bits) and the
|
|
9
|
+
* StreamedResource pointer. The actual sample bytes are pulled by the caller via the .resource
|
|
10
|
+
* stream reader. Two on-disk formats are handled downstream without a codec library:
|
|
11
|
+
* - PCM (compressionFormat 0): raw little-endian samples -> wrap in a WAV header.
|
|
12
|
+
* - Vorbis (compressionFormat 1): the bytes ARE a complete Ogg-Vorbis stream -> write .ogg.
|
|
13
|
+
* Other compression formats (ADPCM/MP3/etc.) are reported unsupported (noted decoded=0 row).
|
|
14
|
+
*
|
|
15
|
+
* Reference field order: Unity 2020.3 AudioClip (AssetStudio AudioClip.cs), little-endian.
|
|
16
|
+
* m_Name : AlignedString
|
|
17
|
+
* m_LoadType : Int32
|
|
18
|
+
* m_Channels : Int32
|
|
19
|
+
* m_Frequency : Int32
|
|
20
|
+
* m_BitsPerSample : Int32
|
|
21
|
+
* m_Length : float
|
|
22
|
+
* m_IsTrackerFormat : bool ; align(4)
|
|
23
|
+
* m_SubsoundIndex : Int32
|
|
24
|
+
* m_PreloadAudioData : bool ; m_LoadInBackground : bool ; m_Legacy3D : bool ; align(4)
|
|
25
|
+
* m_Resource : StreamedResource { m_Source:AlignedString, m_Offset:UInt64, m_Size:UInt64 }
|
|
26
|
+
* m_CompressionFormat : Int32
|
|
27
|
+
*/
|
|
28
|
+
import { BinaryReader } from './binary-reader.js';
|
|
29
|
+
/** Unity AudioCompressionFormat. */
|
|
30
|
+
export var AudioCompressionFormat;
|
|
31
|
+
(function (AudioCompressionFormat) {
|
|
32
|
+
AudioCompressionFormat[AudioCompressionFormat["PCM"] = 0] = "PCM";
|
|
33
|
+
AudioCompressionFormat[AudioCompressionFormat["Vorbis"] = 1] = "Vorbis";
|
|
34
|
+
AudioCompressionFormat[AudioCompressionFormat["ADPCM"] = 2] = "ADPCM";
|
|
35
|
+
AudioCompressionFormat[AudioCompressionFormat["MP3"] = 3] = "MP3";
|
|
36
|
+
AudioCompressionFormat[AudioCompressionFormat["VAG"] = 4] = "VAG";
|
|
37
|
+
AudioCompressionFormat[AudioCompressionFormat["HEVAG"] = 5] = "HEVAG";
|
|
38
|
+
AudioCompressionFormat[AudioCompressionFormat["XMA"] = 6] = "XMA";
|
|
39
|
+
AudioCompressionFormat[AudioCompressionFormat["AAC"] = 7] = "AAC";
|
|
40
|
+
AudioCompressionFormat[AudioCompressionFormat["GCADPCM"] = 8] = "GCADPCM";
|
|
41
|
+
AudioCompressionFormat[AudioCompressionFormat["ATRAC9"] = 9] = "ATRAC9";
|
|
42
|
+
})(AudioCompressionFormat || (AudioCompressionFormat = {}));
|
|
43
|
+
export function parseAudioClip(buf, header, obj) {
|
|
44
|
+
const little = header.endianess === 0;
|
|
45
|
+
const start = Number(header.dataOffset + obj.byteStart);
|
|
46
|
+
const end = start + obj.byteSize;
|
|
47
|
+
if (start < 0 || end > buf.length) {
|
|
48
|
+
throw new RangeError(`parseAudioClip: object range [${start}, ${end}] outside buffer ${buf.length}`);
|
|
49
|
+
}
|
|
50
|
+
const r = new BinaryReader(buf.subarray(start, end), !little, 0);
|
|
51
|
+
const name = r.readAlignedString();
|
|
52
|
+
/* m_LoadType */ r.readInt32();
|
|
53
|
+
const channels = r.readInt32();
|
|
54
|
+
const frequency = r.readInt32();
|
|
55
|
+
const bitsPerSample = r.readInt32();
|
|
56
|
+
const length = r.buf.readFloatLE(r.pos);
|
|
57
|
+
r.pos += 4;
|
|
58
|
+
r.readUInt8(); // m_IsTrackerFormat
|
|
59
|
+
r.align(4);
|
|
60
|
+
r.readInt32(); // m_SubsoundIndex
|
|
61
|
+
r.readUInt8(); // m_PreloadAudioData
|
|
62
|
+
r.readUInt8(); // m_LoadInBackground
|
|
63
|
+
r.readUInt8(); // m_Legacy3D
|
|
64
|
+
r.align(4);
|
|
65
|
+
// m_Resource (StreamedResource)
|
|
66
|
+
const source = r.readAlignedString();
|
|
67
|
+
const offset = r.readUInt64();
|
|
68
|
+
const sizeBig = r.readUInt64();
|
|
69
|
+
const compressionFormat = r.readInt32();
|
|
70
|
+
const size = Number(sizeBig);
|
|
71
|
+
if (channels <= 0 || channels > 32 || frequency <= 0 || frequency > 384000 || size < 0) {
|
|
72
|
+
throw new RangeError(`parseAudioClip("${name}"): implausible fields (ch=${channels} freq=${frequency} size=${size}) — field-order mismatch`);
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
name,
|
|
76
|
+
channels,
|
|
77
|
+
frequency,
|
|
78
|
+
bitsPerSample,
|
|
79
|
+
length,
|
|
80
|
+
compressionFormat,
|
|
81
|
+
compressionName: AudioCompressionFormat[compressionFormat] ?? `comp${compressionFormat}`,
|
|
82
|
+
source,
|
|
83
|
+
offset,
|
|
84
|
+
size,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=audioclip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audioclip.js","sourceRoot":"","sources":["../../../src/decoders/unity/audioclip.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* binary-reader.ts — a minimal, bounds-checked binary reader for Unity serialized files.
|
|
3
|
+
*
|
|
4
|
+
* Unity serialized files (.assets) mix endianness: the HEADER is big-endian, the
|
|
5
|
+
* METADATA + object data are written in the endianness declared by the header's
|
|
6
|
+
* m_Endianess byte (little-endian on desktop/Windows). This reader supports both and
|
|
7
|
+
* lets the caller flip endianness per-field, exactly as the format requires.
|
|
8
|
+
*
|
|
9
|
+
* Every read is bounds-checked: a read past the buffer throws a precise RangeError
|
|
10
|
+
* rather than returning silent garbage. This is the anti-silent-corruption discipline —
|
|
11
|
+
* the bug that killed the candidate library (asset-studio-web) was an unchecked offset
|
|
12
|
+
* walk that produced "Out of bounds" only by luck; here every primitive is guarded.
|
|
13
|
+
*/
|
|
14
|
+
export declare class BinaryReader {
|
|
15
|
+
readonly buf: Buffer;
|
|
16
|
+
pos: number;
|
|
17
|
+
/** true => big-endian for multi-byte reads; false => little-endian. */
|
|
18
|
+
bigEndian: boolean;
|
|
19
|
+
constructor(buf: Buffer, bigEndian?: boolean, pos?: number);
|
|
20
|
+
get length(): number;
|
|
21
|
+
get remaining(): number;
|
|
22
|
+
private ensure;
|
|
23
|
+
seek(pos: number): void;
|
|
24
|
+
skip(n: number): void;
|
|
25
|
+
/** Align the cursor up to the next multiple of `n` (Unity aligns to 4 after many fields). */
|
|
26
|
+
align(n?: number): void;
|
|
27
|
+
readUInt8(): number;
|
|
28
|
+
readInt8(): number;
|
|
29
|
+
readUInt16(): number;
|
|
30
|
+
readInt16(): number;
|
|
31
|
+
readUInt32(): number;
|
|
32
|
+
readInt32(): number;
|
|
33
|
+
readUInt64(): bigint;
|
|
34
|
+
readInt64(): bigint;
|
|
35
|
+
readBytes(n: number): Buffer;
|
|
36
|
+
/** Read a NUL-terminated ASCII/UTF-8 string starting at the cursor. */
|
|
37
|
+
readCString(maxLen?: number): string;
|
|
38
|
+
/** Read a NUL-terminated string at an absolute offset WITHOUT moving the cursor. */
|
|
39
|
+
peekCStringAt(offset: number, maxLen?: number): string;
|
|
40
|
+
/**
|
|
41
|
+
* Read a Unity "aligned string": an Int32 length prefix, the bytes, then align(4).
|
|
42
|
+
* Used for m_Name and m_StreamData.path inside object payloads.
|
|
43
|
+
*/
|
|
44
|
+
readAlignedString(): string;
|
|
45
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* binary-reader.ts — a minimal, bounds-checked binary reader for Unity serialized files.
|
|
3
|
+
*
|
|
4
|
+
* Unity serialized files (.assets) mix endianness: the HEADER is big-endian, the
|
|
5
|
+
* METADATA + object data are written in the endianness declared by the header's
|
|
6
|
+
* m_Endianess byte (little-endian on desktop/Windows). This reader supports both and
|
|
7
|
+
* lets the caller flip endianness per-field, exactly as the format requires.
|
|
8
|
+
*
|
|
9
|
+
* Every read is bounds-checked: a read past the buffer throws a precise RangeError
|
|
10
|
+
* rather than returning silent garbage. This is the anti-silent-corruption discipline —
|
|
11
|
+
* the bug that killed the candidate library (asset-studio-web) was an unchecked offset
|
|
12
|
+
* walk that produced "Out of bounds" only by luck; here every primitive is guarded.
|
|
13
|
+
*/
|
|
14
|
+
export class BinaryReader {
|
|
15
|
+
buf;
|
|
16
|
+
pos;
|
|
17
|
+
/** true => big-endian for multi-byte reads; false => little-endian. */
|
|
18
|
+
bigEndian;
|
|
19
|
+
constructor(buf, bigEndian = false, pos = 0) {
|
|
20
|
+
this.buf = buf;
|
|
21
|
+
this.bigEndian = bigEndian;
|
|
22
|
+
this.pos = pos;
|
|
23
|
+
}
|
|
24
|
+
get length() {
|
|
25
|
+
return this.buf.length;
|
|
26
|
+
}
|
|
27
|
+
get remaining() {
|
|
28
|
+
return this.buf.length - this.pos;
|
|
29
|
+
}
|
|
30
|
+
ensure(n) {
|
|
31
|
+
if (this.pos + n > this.buf.length) {
|
|
32
|
+
throw new RangeError(`BinaryReader: read of ${n} byte(s) at offset ${this.pos} exceeds buffer length ${this.buf.length}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
seek(pos) {
|
|
36
|
+
if (pos < 0 || pos > this.buf.length) {
|
|
37
|
+
throw new RangeError(`BinaryReader: seek to ${pos} out of range [0, ${this.buf.length}]`);
|
|
38
|
+
}
|
|
39
|
+
this.pos = pos;
|
|
40
|
+
}
|
|
41
|
+
skip(n) {
|
|
42
|
+
this.seek(this.pos + n);
|
|
43
|
+
}
|
|
44
|
+
/** Align the cursor up to the next multiple of `n` (Unity aligns to 4 after many fields). */
|
|
45
|
+
align(n = 4) {
|
|
46
|
+
const rem = this.pos % n;
|
|
47
|
+
if (rem !== 0)
|
|
48
|
+
this.skip(n - rem);
|
|
49
|
+
}
|
|
50
|
+
readUInt8() {
|
|
51
|
+
this.ensure(1);
|
|
52
|
+
const v = this.buf.readUInt8(this.pos);
|
|
53
|
+
this.pos += 1;
|
|
54
|
+
return v;
|
|
55
|
+
}
|
|
56
|
+
readInt8() {
|
|
57
|
+
this.ensure(1);
|
|
58
|
+
const v = this.buf.readInt8(this.pos);
|
|
59
|
+
this.pos += 1;
|
|
60
|
+
return v;
|
|
61
|
+
}
|
|
62
|
+
readUInt16() {
|
|
63
|
+
this.ensure(2);
|
|
64
|
+
const v = this.bigEndian ? this.buf.readUInt16BE(this.pos) : this.buf.readUInt16LE(this.pos);
|
|
65
|
+
this.pos += 2;
|
|
66
|
+
return v;
|
|
67
|
+
}
|
|
68
|
+
readInt16() {
|
|
69
|
+
this.ensure(2);
|
|
70
|
+
const v = this.bigEndian ? this.buf.readInt16BE(this.pos) : this.buf.readInt16LE(this.pos);
|
|
71
|
+
this.pos += 2;
|
|
72
|
+
return v;
|
|
73
|
+
}
|
|
74
|
+
readUInt32() {
|
|
75
|
+
this.ensure(4);
|
|
76
|
+
const v = this.bigEndian ? this.buf.readUInt32BE(this.pos) : this.buf.readUInt32LE(this.pos);
|
|
77
|
+
this.pos += 4;
|
|
78
|
+
return v;
|
|
79
|
+
}
|
|
80
|
+
readInt32() {
|
|
81
|
+
this.ensure(4);
|
|
82
|
+
const v = this.bigEndian ? this.buf.readInt32BE(this.pos) : this.buf.readInt32LE(this.pos);
|
|
83
|
+
this.pos += 4;
|
|
84
|
+
return v;
|
|
85
|
+
}
|
|
86
|
+
readUInt64() {
|
|
87
|
+
this.ensure(8);
|
|
88
|
+
const v = this.bigEndian ? this.buf.readBigUInt64BE(this.pos) : this.buf.readBigUInt64LE(this.pos);
|
|
89
|
+
this.pos += 8;
|
|
90
|
+
return v;
|
|
91
|
+
}
|
|
92
|
+
readInt64() {
|
|
93
|
+
this.ensure(8);
|
|
94
|
+
const v = this.bigEndian ? this.buf.readBigInt64BE(this.pos) : this.buf.readBigInt64LE(this.pos);
|
|
95
|
+
this.pos += 8;
|
|
96
|
+
return v;
|
|
97
|
+
}
|
|
98
|
+
readBytes(n) {
|
|
99
|
+
this.ensure(n);
|
|
100
|
+
const out = this.buf.subarray(this.pos, this.pos + n);
|
|
101
|
+
this.pos += n;
|
|
102
|
+
return out;
|
|
103
|
+
}
|
|
104
|
+
/** Read a NUL-terminated ASCII/UTF-8 string starting at the cursor. */
|
|
105
|
+
readCString(maxLen = 4096) {
|
|
106
|
+
const start = this.pos;
|
|
107
|
+
let end = start;
|
|
108
|
+
const hardStop = Math.min(this.buf.length, start + maxLen);
|
|
109
|
+
while (end < hardStop && this.buf[end] !== 0)
|
|
110
|
+
end++;
|
|
111
|
+
const s = this.buf.toString('utf8', start, end);
|
|
112
|
+
// advance past the string and its NUL terminator (if present)
|
|
113
|
+
this.pos = end < this.buf.length ? end + 1 : end;
|
|
114
|
+
return s;
|
|
115
|
+
}
|
|
116
|
+
/** Read a NUL-terminated string at an absolute offset WITHOUT moving the cursor. */
|
|
117
|
+
peekCStringAt(offset, maxLen = 4096) {
|
|
118
|
+
if (offset < 0 || offset >= this.buf.length)
|
|
119
|
+
return '';
|
|
120
|
+
let end = offset;
|
|
121
|
+
const hardStop = Math.min(this.buf.length, offset + maxLen);
|
|
122
|
+
while (end < hardStop && this.buf[end] !== 0)
|
|
123
|
+
end++;
|
|
124
|
+
return this.buf.toString('utf8', offset, end);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Read a Unity "aligned string": an Int32 length prefix, the bytes, then align(4).
|
|
128
|
+
* Used for m_Name and m_StreamData.path inside object payloads.
|
|
129
|
+
*/
|
|
130
|
+
readAlignedString() {
|
|
131
|
+
const len = this.readInt32();
|
|
132
|
+
if (len < 0 || len > this.remaining) {
|
|
133
|
+
throw new RangeError(`BinaryReader.readAlignedString: implausible length ${len} at offset ${this.pos} (remaining ${this.remaining})`);
|
|
134
|
+
}
|
|
135
|
+
const s = this.buf.toString('utf8', this.pos, this.pos + len);
|
|
136
|
+
this.pos += len;
|
|
137
|
+
this.align(4);
|
|
138
|
+
return s;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=binary-reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binary-reader.js","sourceRoot":"","sources":["../../../src/decoders/unity/binary-reader.ts"],"names":[],"mappings":"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"}
|