Skip to content

Commit 662d6e2

Browse files
committed
UopPacker: fix unpacking gumps and sizing of index; add progress bars and update UI slightly.
1 parent a0002df commit 662d6e2

4 files changed

Lines changed: 444 additions & 113 deletions

File tree

UoFiddler.Plugin.UopPacker/Classes/LegacyMulFileConverter.cs

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ private static BinaryWriter OpenOutput(string path)
5656
//
5757
// MUL -> UOP
5858
//
59-
public static void ToUop(string inFile, string inFileIdx, string outFile, FileType type, int typeIndex, CompressionFlag compressionFlag = CompressionFlag.None, string housingBinFile = "")
59+
public static void ToUop(string inFile, string inFileIdx, string outFile, FileType type, int typeIndex, CompressionFlag compressionFlag = CompressionFlag.None, string housingBinFile = "", IProgress<int> progress = null)
6060
{
6161
// Same for all UOP files
6262
const long firstTable = 0x200;
@@ -163,6 +163,10 @@ public static void ToUop(string inFile, string inFileIdx, string outFile, FileTy
163163

164164
string[] hashFormat = GetHashFormat(type, typeIndex, out int _);
165165

166+
int totalEntries = idxEntries.Count;
167+
int lastReportedPct = -1;
168+
progress?.Report(0);
169+
166170
for (int i = 0; i < tableCount; ++i)
167171
{
168172
long thisTable = writer.BaseStream.Position;
@@ -308,6 +312,16 @@ public static void ToUop(string inFile, string inFileIdx, string outFile, FileTy
308312
tableEntries[tableIdx].Hash = HashAdler32(data);
309313
writer.Write(data);
310314
}
315+
316+
if (totalEntries > 0)
317+
{
318+
int pct = (j + 1) * 100 / totalEntries;
319+
if (pct != lastReportedPct)
320+
{
321+
lastReportedPct = pct;
322+
progress?.Report(pct);
323+
}
324+
}
311325
}
312326

313327
long nextTable = writer.BaseStream.Position;
@@ -354,7 +368,7 @@ public static void ToUop(string inFile, string inFileIdx, string outFile, FileTy
354368
//
355369
// UOP -> MUL
356370
//
357-
public void FromUop(string inFile, string outFile, string outFileIdx, FileType type, int typeIndex, string housingBinFile = "")
371+
public void FromUop(string inFile, string outFile, string outFileIdx, FileType type, int typeIndex, string housingBinFile = "", IProgress<int> progress = null)
358372
{
359373
Dictionary<ulong, int> chunkIds = new Dictionary<ulong, int>();
360374
Dictionary<ulong, int> chunkIds2 = new Dictionary<ulong, int>();
@@ -391,6 +405,11 @@ public void FromUop(string inFile, string outFile, string outFileIdx, FileType t
391405
reader.ReadInt32(); // format timestamp? 0xFD23EC43
392406

393407
long nextTable = reader.ReadInt64();
408+
reader.ReadInt32(); // table size (unused)
409+
int totalFileCount = reader.ReadInt32();
410+
int processedCount = 0;
411+
int lastReportedPct = -1;
412+
progress?.Report(0);
394413

395414
do
396415
{
@@ -414,7 +433,8 @@ public void FromUop(string inFile, string outFile, string outFileIdx, FileType t
414433
offsets[i].DecompressedSize = reader.ReadInt32(); // decompressed size
415434
offsets[i].Identifier = reader.ReadUInt64(); // filename hash (HashLittle2)
416435
offsets[i].Hash = reader.ReadUInt32(); // data hash (Adler32)
417-
offsets[i].Compressed = reader.ReadInt16() != 0; // compression method (0 = none, 1 = zlib)
436+
offsets[i].CompressionFlag = reader.ReadInt16(); // compression method (0 = none, 1 = zlib, 3 = mythic)
437+
offsets[i].Compressed = offsets[i].CompressionFlag != 0;
418438
}
419439

420440
// Copy chunks
@@ -452,6 +472,17 @@ public void FromUop(string inFile, string outFile, string outFileIdx, FileType t
452472
writerBin.Write(binDataToWrite, 0, binDataToWrite.Length);
453473
}
454474

475+
if (totalFileCount > 0)
476+
{
477+
++processedCount;
478+
int pct = processedCount * 100 / totalFileCount;
479+
if (pct != lastReportedPct)
480+
{
481+
lastReportedPct = pct;
482+
progress?.Report(pct);
483+
}
484+
}
485+
455486
continue;
456487
}
457488

@@ -480,6 +511,11 @@ public void FromUop(string inFile, string outFile, string outFileIdx, FileType t
480511
chunkData = decompressed;
481512
}
482513

514+
if (offsets[i].CompressionFlag == (short)CompressionFlag.Mythic)
515+
{
516+
chunkData = MythicDecompress.Decompress(chunkData);
517+
}
518+
483519
if (type == FileType.MapLegacyMul)
484520
{
485521
// Write this chunk on the right position (no IDX file to point to it)
@@ -541,6 +577,17 @@ public void FromUop(string inFile, string outFile, string outFileIdx, FileType t
541577
mulWriter.Write(chunkData, dataOffset, chunkData.Length - dataOffset);
542578
}
543579
}
580+
581+
if (totalFileCount > 0)
582+
{
583+
++processedCount;
584+
int pct = processedCount * 100 / totalFileCount;
585+
if (pct != lastReportedPct)
586+
{
587+
lastReportedPct = pct;
588+
progress?.Report(pct);
589+
}
590+
}
544591
}
545592

546593
// Move to next table
@@ -551,10 +598,22 @@ public void FromUop(string inFile, string outFile, string outFileIdx, FileType t
551598
}
552599
while (nextTable != 0);
553600

554-
// Fix index
601+
// Fix index. Only pad up to the highest used entry — `used.Length` is the hash-lookup
602+
// upper bound (often 0x7FFFF), which would otherwise produce a multi-megabyte idx file
603+
// padded with sentinel rows beyond any real entry.
555604
if (idxWriter != null)
556605
{
557-
for (int i = 0; i < used.Length; ++i)
606+
int padCount = 0;
607+
for (int i = used.Length - 1; i >= 0; --i)
608+
{
609+
if (used[i])
610+
{
611+
padCount = i + 1;
612+
break;
613+
}
614+
}
615+
616+
for (int i = 0; i < padCount; ++i)
558617
{
559618
if (used[i])
560619
{

0 commit comments

Comments
 (0)