-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathTOC.cs
More file actions
458 lines (432 loc) · 15.7 KB
/
TOC.cs
File metadata and controls
458 lines (432 loc) · 15.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Ionic.Zlib;
namespace SMPCTool
{
// Token: 0x0200001C RID: 28
public class TOC
{
// Token: 0x060000A2 RID: 162 RVA: 0x0000DE14 File Offset: 0x0000C014
public TOC(string fileName)
{
this.Filename = fileName;
}
// Token: 0x060000A3 RID: 163 RVA: 0x0000DE30 File Offset: 0x0000C030
public void Compress(string fileName)
{
BinaryReader binaryReader = new BinaryReader(File.OpenRead(this.decompressedFileName));
List<byte> list = ZlibStream.CompressBuffer(binaryReader.ReadBytes((int)binaryReader.BaseStream.Length)).ToList<byte>();
list.InsertRange(0, BitConverter.GetBytes((int)binaryReader.BaseStream.Length));
list.InsertRange(0, new byte[]
{
175,
18,
175,
119
});
File.WriteAllBytes(fileName, list.ToArray());
binaryReader.Close();
binaryReader.Dispose();
}
// Token: 0x060000A4 RID: 164 RVA: 0x0000DEBC File Offset: 0x0000C0BC
public void Decompress(string fileName)
{
Console.WriteLine("Decompressing TOC...");
BinaryReader binaryReader = new BinaryReader(File.OpenRead(this.Filename));
uint num = binaryReader.ReadUInt32();
int count = binaryReader.ReadInt32();
byte[] bytes = ZlibStream.UncompressBuffer(binaryReader.ReadBytes(count));
binaryReader.Close();
binaryReader.Dispose();
File.WriteAllBytes(fileName, bytes);
this.decompressedFileName = fileName;
Console.WriteLine("Done decompressing TOC!");
}
// Token: 0x060000A5 RID: 165 RVA: 0x0000DF2C File Offset: 0x0000C12C
public void ParseDecompressed()
{
bool flag = !File.Exists(this.decompressedFileName);
if (flag)
{
Console.WriteLine("ERROR: Trying to access non-existing decompressed TOC!!!");
}
else
{
Console.WriteLine("Parsing decompressed TOC...");
BinaryReader binaryReader = new BinaryReader(File.OpenRead(this.decompressedFileName));
string text = "";
int num = binaryReader.ReadInt32();
int num2 = binaryReader.ReadInt32();
int num3 = binaryReader.ReadInt32();
int num4 = binaryReader.ReadInt32();
text += "TOC\n{\n\t";
text = text + "Filename: " + this.Filename + "\n\n\t";
text += "Header\n\t{\n\t\t";
text = text + "Magic: 0x" + num.ToString("X2") + "\n\t\t";
text = text + "Hash: 0x" + num2.ToString("X2") + "\n\t\t";
text = text + "Length: 0x" + num3.ToString("X2") + "\n\t\t";
text = text + "Number of Sections: " + num4.ToString();
text += "\n\t}\n}\n\n";
int hash = binaryReader.ReadInt32();
this.ArchiveFileSectionOffsetOffset = (int)binaryReader.BaseStream.Position;
int num5 = binaryReader.ReadInt32();
this.ArchiveFileSectionLenOffset = (int)binaryReader.BaseStream.Position;
int num6 = binaryReader.ReadInt32();
this.ArchiveFileSectionOffset = num5;
this.ArchiveFileSectionLen = num6;
this.Sections.Add(new Section
{
Hash = hash,
Offset = num5,
Size = num6
});
this.ParseArchiveFiles(num5, num6);
text += "ArchiveFiles\n{\n\t";
text += "Header\n\t{\n\t\t";
text = text + "Hash: 0x" + hash.ToString("X2") + "\n\t\t";
text = text + "Offset: 0x" + num5.ToString("X2") + "\n\t\t";
text = text + "Length: 0x" + num6.ToString("X2") + "\n\t\t";
text = text + "Count: " + this.ArchiveFiles.Count.ToString() + "\n";
text += "\t}\n\n\t";
text += "ArchiveFileEntries\n\t{\n";
foreach (ArchiveFile archiveFile in this.ArchiveFiles)
{
text += "\t\tArchiveFileEntry\n\t\t{\n\t\t\t";
string str = text;
string str2 = "InstallBucket: ";
byte installBucket = archiveFile.InstallBucket;
text = str + str2 + installBucket.ToString() + "\n\t\t\t";
string str3 = text;
string str4 = "Chunkmap: ";
uint chunkmap = archiveFile.Chunkmap;
text = str3 + str4 + chunkmap.ToString() + "\n\t\t\t";
text = text + "Filename: " + archiveFile.Filename + "\n\t\t\t";
text += "\n\t\t}\n\n";
}
text += "\t}\n}\n\n";
int hash2 = binaryReader.ReadInt32();
int offset = binaryReader.ReadInt32();
int num7 = binaryReader.ReadInt32();
this.Sections.Add(new Section
{
Hash = hash2,
Offset = offset,
Size = num7
});
this.ParseAssetIDs(offset, num7);
text += "AssetIDs\n{\n\t";
text += "Header\n\t{\n\t\t";
text = text + "Hash: 0x" + hash2.ToString("X2") + "\n\t\t";
text = text + "Offset: 0x" + offset.ToString("X2") + "\n\t\t";
text = text + "Length: 0x" + num7.ToString("X2") + "\n\t\t";
text = text + "Count: " + this.AssetIDs.Count.ToString() + "\n";
text += "\t}\n}\n\n";
int hash3 = binaryReader.ReadInt32();
int offset2 = binaryReader.ReadInt32();
int num8 = binaryReader.ReadInt32();
this.Sections.Add(new Section
{
Hash = hash3,
Offset = offset2,
Size = num8
});
this.ParseSizeEntries(offset2, num8);
text += "SizeEntries\n{\n\t";
text += "Header\n\t{\n\t\t";
text = text + "Hash: 0x" + hash3.ToString("X2") + "\n\t\t";
text = text + "Offset: 0x" + offset2.ToString("X2") + "\n\t\t";
text = text + "Length: 0x" + num8.ToString("X2") + "\n\t\t";
text = text + "Count: " + this.SizeEntries.Count.ToString() + "\n";
text += "\t}\n}\n\n";
int hash4 = binaryReader.ReadInt32();
int offset3 = binaryReader.ReadInt32();
int num9 = binaryReader.ReadInt32();
this.Sections.Add(new Section
{
Hash = hash4,
Offset = offset3,
Size = num9
});
this.ParseKeyAssets(offset3, num9);
text += "KeyAssets\n{\n\t";
text += "Header\n\t{\n\t\t";
text = text + "Hash: 0x" + hash4.ToString("X2") + "\n\t\t";
text = text + "Offset: 0x" + offset3.ToString("X2") + "\n\t\t";
text = text + "Length: 0x" + num9.ToString("X2") + "\n\t\t";
text = text + "Count: " + this.KeyAssets.Count.ToString() + "\n";
text += "\t}\n}\n\n";
int hash5 = binaryReader.ReadInt32();
int offset4 = binaryReader.ReadInt32();
int num10 = binaryReader.ReadInt32();
this.Sections.Add(new Section
{
Hash = hash5,
Offset = offset4,
Size = num10
});
this.ParseOffsetEntries(offset4, num10);
text += "OffsetEntries\n{\n\t";
text += "Header\n\t{\n\t\t";
text = text + "Hash: 0x" + hash5.ToString("X2") + "\n\t\t";
text = text + "Offset: 0x" + offset4.ToString("X2") + "\n\t\t";
text = text + "Length: 0x" + num10.ToString("X2") + "\n\t\t";
text = text + "Count: " + this.OffsetEntries.Count.ToString() + "\n";
text += "\t}\n}\n\n";
int hash6 = binaryReader.ReadInt32();
int offset5 = binaryReader.ReadInt32();
int num11 = binaryReader.ReadInt32();
this.Sections.Add(new Section
{
Hash = hash6,
Offset = offset5,
Size = num11
});
this.ParseSpansEntries(offset5, num11);
text += "SpansEntries\n{\n\t";
text += "Header\n\t{\n\t\t";
text = text + "Hash: 0x" + hash6.ToString("X2") + "\n\t\t";
text = text + "Offset: 0x" + offset5.ToString("X2") + "\n\t\t";
text = text + "Length: 0x" + num11.ToString("X2") + "\n\t\t";
text = text + "Count: " + this.SpansEntries.Count.ToString() + "\n";
text += "\t}\n}\n\n";
string[] array = File.ReadAllLines("AssetHashes.txt");
Dictionary<ulong, string> dictionary = new Dictionary<ulong, string>();
foreach (string text2 in array)
{
string[] array3 = text2.Split(new char[]
{
','
});
string text3 = array3[0];
ulong key = Convert.ToUInt64(array3[1]);
string value = array3[0];
bool flag2 = !dictionary.ContainsKey(key);
if (flag2)
{
dictionary.Add(key, value);
}
}
uint[] array4 = new uint[this.SizeEntries.Count];
for (int j = 0; j < this.SizeEntries.Count; j++)
{
array4[j] = this.SizeEntries[j].FileCtr;
}
this.TOCMaps = new TOCMap[this.ArchiveFiles.Count];
for (int k = 0; k < this.SizeEntries.Count; k++)
{
int archiveIndex = this.OffsetEntries[(int)array4[k]].ArchiveIndex;
int archiveIndexTOCOffset = this.OffsetEntries[(int)array4[k]].ArchiveIndexTOCOffset;
string filename = this.ArchiveFiles[archiveIndex].Filename;
uint archiveOffset = this.OffsetEntries[(int)array4[k]].ArchiveOffset;
int archiveOffsetTOCOffset = this.OffsetEntries[(int)array4[k]].ArchiveOffsetTOCOffset;
uint fileSize = this.SizeEntries[k].FileSize;
int fileSizeTOCOffset = this.SizeEntries[k].FileSizeTOCOffset;
ulong fileAssetID = this.AssetIDs[k];
TOCMapEntry tocmapEntry = new TOCMapEntry();
tocmapEntry.ArchiveIndex = archiveIndex;
tocmapEntry.ArchiveIndexTOCOffset = archiveIndexTOCOffset;
tocmapEntry.ArchiveName = filename;
tocmapEntry.FileOffset = archiveOffset;
tocmapEntry.FileOffsetTOCOffset = archiveOffsetTOCOffset;
tocmapEntry.FileSize = (int)fileSize;
tocmapEntry.FileSizeTOCOffset = fileSizeTOCOffset;
tocmapEntry.FileAssetID = fileAssetID;
bool flag3 = !dictionary.TryGetValue(tocmapEntry.FileAssetID, out tocmapEntry.FileName);
if (flag3)
{
tocmapEntry.FileName = "0x" + fileAssetID.ToString("X2");
}
bool flag4 = this.TOCMaps[archiveIndex] == null;
if (flag4)
{
this.TOCMaps[archiveIndex] = new TOCMap();
}
this.TOCMaps[archiveIndex].TOCMapEntries.Add(tocmapEntry);
}
File.WriteAllText(Globals.TemporaryDirectory + "toc.txt", text);
binaryReader.Close();
binaryReader.Dispose();
Console.WriteLine("Done parsing decompressed TOC!");
}
}
// Token: 0x060000A6 RID: 166 RVA: 0x0000E974 File Offset: 0x0000CB74
private string BinaryReaderReadNTString(BinaryReader br)
{
string text = "";
for (;;)
{
byte b = br.ReadByte();
bool flag = b == 0;
if (flag)
{
break;
}
string str = text;
char c = (char)b;
text = str + c.ToString();
}
return text;
}
// Token: 0x060000A7 RID: 167 RVA: 0x0000E9BC File Offset: 0x0000CBBC
private void ParseArchiveFiles(int offset, int length)
{
BinaryReader binaryReader = new BinaryReader(File.OpenRead(this.decompressedFileName));
binaryReader.BaseStream.Position = (long)offset;
this.ArchiveFiles = new List<ArchiveFile>();
for (int i = 0; i < length / 72; i++)
{
ArchiveFile item = default(ArchiveFile);
binaryReader.ReadBytes(3);
item.InstallBucket = binaryReader.ReadByte();
item.Chunkmap = binaryReader.ReadUInt32();
long position = binaryReader.BaseStream.Position;
item.Filename = this.BinaryReaderReadNTString(binaryReader);
binaryReader.BaseStream.Position = position + 7L;
binaryReader.ReadBytes(57);
this.ArchiveFiles.Add(item);
}
binaryReader.Close();
binaryReader.Dispose();
}
// Token: 0x060000A8 RID: 168 RVA: 0x0000EA84 File Offset: 0x0000CC84
private void ParseAssetIDs(int offset, int length)
{
BinaryReader binaryReader = new BinaryReader(File.OpenRead(this.decompressedFileName));
binaryReader.BaseStream.Position = (long)offset;
this.AssetIDs = new List<ulong>();
for (int i = 0; i < length / 8; i++)
{
ulong item = binaryReader.ReadUInt64();
this.AssetIDs.Add(item);
}
binaryReader.Close();
binaryReader.Dispose();
}
// Token: 0x060000A9 RID: 169 RVA: 0x0000EAF4 File Offset: 0x0000CCF4
private void ParseSizeEntries(int offset, int length)
{
BinaryReader binaryReader = new BinaryReader(File.OpenRead(this.decompressedFileName));
binaryReader.BaseStream.Position = (long)offset;
this.SizeEntries = new List<SizeEntry>();
for (int i = 0; i < length / 12; i++)
{
SizeEntry item = default(SizeEntry);
item.FileCtrInc = binaryReader.ReadUInt32();
item.FileSizeTOCOffset = (int)binaryReader.BaseStream.Position;
item.FileSize = binaryReader.ReadUInt32();
item.FileCtr = binaryReader.ReadUInt32();
this.SizeEntries.Add(item);
}
binaryReader.Close();
binaryReader.Dispose();
}
// Token: 0x060000AA RID: 170 RVA: 0x0000EBA0 File Offset: 0x0000CDA0
private void ParseKeyAssets(int offset, int length)
{
BinaryReader binaryReader = new BinaryReader(File.OpenRead(this.decompressedFileName));
binaryReader.BaseStream.Position = (long)offset;
this.KeyAssets = new List<ulong>();
for (int i = 0; i < length / 8; i++)
{
ulong item = binaryReader.ReadUInt64();
this.KeyAssets.Add(item);
}
binaryReader.Close();
binaryReader.Dispose();
}
// Token: 0x060000AB RID: 171 RVA: 0x0000EC10 File Offset: 0x0000CE10
private void ParseOffsetEntries(int offset, int length)
{
BinaryReader binaryReader = new BinaryReader(File.OpenRead(this.decompressedFileName));
binaryReader.BaseStream.Position = (long)offset;
this.OffsetEntries = new List<OffsetEntry>();
for (int i = 0; i < length / 8; i++)
{
OffsetEntry item = default(OffsetEntry);
item.ArchiveIndexTOCOffset = (int)binaryReader.BaseStream.Position;
item.ArchiveIndex = binaryReader.ReadInt32();
item.ArchiveOffsetTOCOffset = (int)binaryReader.BaseStream.Position;
item.ArchiveOffset = binaryReader.ReadUInt32();
this.OffsetEntries.Add(item);
}
binaryReader.Close();
binaryReader.Dispose();
}
// Token: 0x060000AC RID: 172 RVA: 0x0000ECC0 File Offset: 0x0000CEC0
private void ParseSpansEntries(int offset, int length)
{
BinaryReader binaryReader = new BinaryReader(File.OpenRead(this.decompressedFileName));
binaryReader.BaseStream.Position = (long)offset;
this.SpansEntries = new List<SpansEntry>();
for (int i = 0; i < length / 8; i++)
{
SpansEntry item = default(SpansEntry);
item.AssetIndex = binaryReader.ReadUInt32();
item.Count = binaryReader.ReadUInt32();
this.SpansEntries.Add(item);
}
binaryReader.Close();
binaryReader.Dispose();
}
// Token: 0x060000AD RID: 173 RVA: 0x0000ED4C File Offset: 0x0000CF4C
public void GenerateCSV(string fileName)
{
List<string> list = new List<string>();
list.Add("Asset Path,Asset ID,Archive File,Segment Offset,File Size");
for (int i = 0; i < this.TOCMaps.Length; i++)
{
bool flag = this.TOCMaps[i] == null;
if (!flag)
{
foreach (TOCMapEntry tocmapEntry in this.TOCMaps[i].TOCMapEntries)
{
list.Add(string.Concat(new string[]
{
"\"",
tocmapEntry.FileName,
"\",0x",
tocmapEntry.FileAssetID.ToString("X2"),
",",
tocmapEntry.ArchiveName,
",0x",
tocmapEntry.FileOffset.ToString("X2"),
",0x",
tocmapEntry.FileSize.ToString("X2")
}));
}
}
}
File.WriteAllLines(fileName, list);
}
// Token: 0x040000AD RID: 173
public string Filename;
// Token: 0x040000AE RID: 174
public int ArchiveFileSectionOffset;
// Token: 0x040000AF RID: 175
public int ArchiveFileSectionOffsetOffset;
// Token: 0x040000B0 RID: 176
public int ArchiveFileSectionLen;
// Token: 0x040000B1 RID: 177
public int ArchiveFileSectionLenOffset;
// Token: 0x040000B2 RID: 178
public List<ArchiveFile> ArchiveFiles;
// Token: 0x040000B3 RID: 179
public List<ulong> AssetIDs;
// Token: 0x040000B4 RID: 180
public List<SizeEntry> SizeEntries;
// Token: 0x040000B5 RID: 181
public List<ulong> KeyAssets;
// Token: 0x040000B6 RID: 182
public List<OffsetEntry> OffsetEntries;
// Token: 0x040000B7 RID: 183
public List<SpansEntry> SpansEntries;
// Token: 0x040000B8 RID: 184
public List<Section> Sections = new List<Section>();
// Token: 0x040000B9 RID: 185
public TOCMap[] TOCMaps;
// Token: 0x040000BA RID: 186
public string decompressedFileName;
}
}