Skip to content

Commit 5e513b1

Browse files
committed
Still create chunks even if object counting fails
1 parent 2a7409e commit 5e513b1

File tree

1 file changed

+21
-4
lines changed

1 file changed

+21
-4
lines changed

UndertaleModLib/UndertaleChunkTypes.cs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Collections.Generic;
44
using System.IO;
55
using UndertaleModLib.Models;
6+
using static UndertaleModLib.UndertaleReader;
67

78
namespace UndertaleModLib
89
{
@@ -62,23 +63,36 @@ public static UndertaleChunk Unserialize(UndertaleReader reader)
6263
string name = "(unknown)";
6364
try
6465
{
66+
// Read name and length
6567
name = reader.ReadChars(4);
6668
uint length = reader.ReadUInt32();
6769

68-
UndertaleChunk chunk = reader.undertaleData.FORM.Chunks[name];
70+
// Find chunk instance, or create one if not already created (when errors occur during object counting)
71+
if (!reader.undertaleData.FORM.Chunks.TryGetValue(name, out UndertaleChunk chunk))
72+
{
73+
if (!UndertaleChunkFORM.ChunkConstructors.TryGetValue(name, out Func<UndertaleChunk> instantiator))
74+
{
75+
throw new IOException($"Unknown chunk \"{name}\"");
76+
}
77+
chunk = instantiator();
78+
reader.undertaleData.FORM.Chunks[name] = chunk;
79+
}
6980
Util.DebugUtil.Assert(chunk.Name == name,
7081
$"Chunk name mismatch: expected \"{name}\", got \"{chunk.Name}\".");
7182
chunk.Length = length;
7283

84+
// Read chunk contents
7385
reader.SubmitMessage("Reading chunk " + chunk.Name);
74-
var lenReader = reader.EnsureLengthFromHere(chunk.Length);
86+
EnsureLengthOperation lenReader = reader.EnsureLengthFromHere(chunk.Length);
7587
reader.CopyChunkToBuffer(length);
7688
chunk.UnserializeChunk(reader);
7789

90+
// Process padding
7891
reader.SwitchReaderType(false);
7992
if (name != "FORM" && name != reader.LastChunkName)
8093
{
8194
UndertaleGeneralInfo generalInfo = name == "GEN8" ? ((UndertaleChunkGEN8)chunk).Object : reader.undertaleData.GeneralInfo;
95+
8296
// These versions introduced new padding
8397
// all chunks now start on 16-byte boundaries
8498
// (but the padding is included with length of previous chunk)
@@ -101,6 +115,7 @@ public static UndertaleChunk Unserialize(UndertaleReader reader)
101115
}
102116
}
103117

118+
// Ensure full length was read
104119
lenReader.ToHere();
105120

106121
return chunk;
@@ -119,25 +134,27 @@ public static (uint, UndertaleChunk) CountChunkChildObjects(UndertaleReader read
119134
string name = "(unknown)";
120135
try
121136
{
137+
// Read name and length
122138
name = reader.ReadChars(4);
123139
uint length = reader.ReadUInt32();
124140

141+
// Create chunk instance
125142
if (!UndertaleChunkFORM.ChunkConstructors.TryGetValue(name, out Func<UndertaleChunk> instantiator))
126143
{
127144
throw new IOException($"Unknown chunk \"{name}\"");
128145
}
129-
130146
UndertaleChunk chunk = instantiator();
131147
Util.DebugUtil.Assert(chunk.Name == name,
132148
$"Chunk name mismatch: expected \"{name}\", got \"{chunk.Name}\".");
133149
chunk.Length = length;
134150

151+
// Count objects in chunk
135152
long chunkStart = reader.Position;
136-
137153
reader.SubmitMessage("Counting objects of chunk " + chunk.Name);
138154
reader.CopyChunkToBuffer(length);
139155
uint count = chunk.UnserializeObjectCount(reader);
140156

157+
// Advance beyond chunk length (parts of the chunk may have been skipped)
141158
reader.SwitchReaderType(false);
142159
reader.Position = chunkStart + chunk.Length;
143160

0 commit comments

Comments
 (0)