Skip to content

Commit ad4aacf

Browse files
Add binary serialization cache for FlatTypeIndex and AssetIndex
1 parent fbadcaf commit ad4aacf

3 files changed

Lines changed: 1434 additions & 285 deletions

File tree

Maple2.File.Parser/Flat/Convert/AssetIndex.cs

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
using System.Diagnostics;
1+
using System.Diagnostics;
22
using System.Text.RegularExpressions;
33
using Maple2.File.IO;
44
using Maple2.File.IO.Crypto.Common;
55

66
namespace Maple2.File.Parser.Flat.Convert;
77

88
public class AssetIndex {
9+
private const uint MAGIC = 0x00495341;
10+
private const int VERSION = 1;
11+
912
private static Regex extractRegex = new("^<(urn:uuid:[0-9a-f-]+)> <.+> \"(.+)\".$");
1013

1114
private readonly Dictionary<string, List<string>> llidLookup;
@@ -50,7 +53,6 @@ public AssetIndex(M2dReader reader) {
5053

5154
Dictionary<string, string> value = ParseNtFile(reader.GetString(entry));
5255
if (key == "llid") {
53-
// We need llid => uuid lookup here.
5456
foreach ((string k, string v) in value) {
5557
if (!llidLookup.ContainsKey(v)) {
5658
llidLookup.Add(v, new List<string>());
@@ -64,6 +66,73 @@ public AssetIndex(M2dReader reader) {
6466
}
6567
}
6668

69+
private AssetIndex(Dictionary<string, List<string>> llidLookup, Dictionary<string, Dictionary<string, string>> ntLookup) {
70+
this.llidLookup = llidLookup;
71+
this.ntLookup = ntLookup;
72+
}
73+
74+
public void Serialize(BinaryWriter writer) {
75+
writer.Write(MAGIC);
76+
writer.Write(VERSION);
77+
78+
writer.Write(llidLookup.Count);
79+
foreach (var kvp in llidLookup) {
80+
writer.Write(kvp.Key ?? string.Empty);
81+
writer.Write(kvp.Value.Count);
82+
foreach (string llid in kvp.Value) {
83+
writer.Write(llid ?? string.Empty);
84+
}
85+
}
86+
87+
writer.Write(ntLookup.Count);
88+
foreach (var kvp in ntLookup) {
89+
writer.Write(kvp.Key ?? string.Empty);
90+
writer.Write(kvp.Value.Count);
91+
foreach (var innerKvp in kvp.Value) {
92+
writer.Write(innerKvp.Key ?? string.Empty);
93+
writer.Write(innerKvp.Value ?? string.Empty);
94+
}
95+
}
96+
}
97+
98+
public static AssetIndex Deserialize(BinaryReader reader) {
99+
uint magic = reader.ReadUInt32();
100+
if (magic != MAGIC) {
101+
throw new InvalidDataException($"Invalid AssetIndex magic: expected {MAGIC:X}, got {magic:X}");
102+
}
103+
104+
int version = reader.ReadInt32();
105+
if (version != VERSION) {
106+
throw new InvalidDataException($"Unsupported AssetIndex version: {version}");
107+
}
108+
109+
int llidCount = reader.ReadInt32();
110+
var llidLookup = new Dictionary<string, List<string>>(llidCount);
111+
for (int i = 0; i < llidCount; i++) {
112+
string key = reader.ReadString();
113+
int valueCount = reader.ReadInt32();
114+
var values = new List<string>(valueCount);
115+
for (int j = 0; j < valueCount; j++) {
116+
values.Add(reader.ReadString());
117+
}
118+
llidLookup[key] = values;
119+
}
120+
121+
int ntCount = reader.ReadInt32();
122+
var ntLookup = new Dictionary<string, Dictionary<string, string>>(ntCount);
123+
for (int i = 0; i < ntCount; i++) {
124+
string key = reader.ReadString();
125+
int innerCount = reader.ReadInt32();
126+
var innerDict = new Dictionary<string, string>(innerCount);
127+
for (int j = 0; j < innerCount; j++) {
128+
innerDict[reader.ReadString()] = reader.ReadString();
129+
}
130+
ntLookup[key] = innerDict;
131+
}
132+
133+
return new AssetIndex(llidLookup, ntLookup);
134+
}
135+
67136
public (string Name, string Path, string Tags) GetFields(string llid) {
68137
llid = llid.Replace("urn:llid:", "");
69138
if (!llidLookup.TryGetValue(llid, out List<string> uuids)) {

0 commit comments

Comments
 (0)