Skip to content

Commit ea783ad

Browse files
committed
strings
1 parent 196a654 commit ea783ad

File tree

4 files changed

+133
-58
lines changed

4 files changed

+133
-58
lines changed

BlueprintExplorer/BlueprintDB.cs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public partial class BlueprintDB
2020
{
2121
private static BlueprintDB _Instance;
2222
public static BlueprintDB Instance => _Instance ??= new();
23+
public readonly Dictionary<string, string> Strings = new();
2324

2425
public readonly Dictionary<string, string> GuidToFullTypeName = new();
2526

@@ -42,8 +43,8 @@ public enum GoingToLoad
4243
}
4344

4445
private readonly string filenameRoot = "blueprints_raw";
45-
private const int LatestVersion = 3;
46-
private readonly string version = "1.1.4d_bbpe3";
46+
private const int LatestVersion = 4;
47+
private readonly string version = "1.1.4d_bbpe4";
4748
private readonly string extension = "binz";
4849

4950
string FileName => $"{filenameRoot}_{version}.{extension}";
@@ -117,8 +118,6 @@ public async Task<bool> TryConnect(ConnectionProgress progress)
117118
}
118119
}
119120

120-
File.WriteAllText("all_types.json", JsonSerializer.Serialize(GuidToFullTypeName, writeOptions));
121-
122121
using var bpDump = ZipFile.OpenRead(@"D:\WOTR-1.1-DEBUG\blueprints.zip");
123122

124123
Dictionary<string, string> TypenameToGuid = new();
@@ -346,6 +345,16 @@ FileStream OpenFile()
346345
if (bbpeVersion >= 3)
347346
fullNameCount = batchReader.ReadInt32();
348347

348+
if (bbpeVersion >= 4) {
349+
byte[] raw = new byte[batchReader.ReadInt32()];
350+
int compressedSize = batchReader.ReadInt32();
351+
byte[] compressed = batchReader.ReadBytes(compressedSize);
352+
LZ4Codec.Decode(compressed.AsSpan(), raw.AsSpan());
353+
var stringDictRaw = JsonSerializer.Deserialize<JsonElement>(raw).GetProperty("strings");
354+
foreach (var kv in stringDictRaw.EnumerateObject())
355+
Strings[kv.Name] = kv.Value.GetString();
356+
}
357+
349358
for (int i = 0; i < componentDict.Length; i++)
350359
{
351360
string val = batchReader.ReadString();
@@ -355,8 +364,8 @@ FileStream OpenFile()
355364

356365
for (int i = 0; i < fullNameCount; i++)
357366
{
358-
string val = batchReader.ReadString();
359367
string key = batchReader.ReadString();
368+
string val = batchReader.ReadString();
360369
GuidToFullTypeName[key] = val;
361370
}
362371

@@ -367,7 +376,6 @@ FileStream OpenFile()
367376
float loadTime = watch.ElapsedMilliseconds;
368377
Console.WriteLine($"Loaded {cache.Count} blueprints in {watch.ElapsedMilliseconds}ms");
369378

370-
371379
binary.Dispose();
372380
file.Dispose();
373381

@@ -616,9 +624,15 @@ private void WriteBlueprints()
616624
}
617625
}
618626

627+
var rawLangDict = File.ReadAllBytes(@"D:\WOTR-1.1-DEBUG\Wrath_Data\StreamingAssets\Localization\enGB.json");
628+
int langDictCompressed = LZ4Codec.Encode(rawLangDict.AsSpan(), scratchpad.AsSpan(), LZ4Level.L10_OPT);
629+
619630
toc[^1] = (int)binary.BaseStream.Position;
620631
binary.Write(uniqueComponents.Count);
621632
binary.Write(GuidToFullTypeName.Count);
633+
binary.Write(rawLangDict.Length);
634+
binary.Write(langDictCompressed);
635+
binary.Write(scratchpad, 0, langDictCompressed);
622636

623637
foreach (var kv in uniqueComponents)
624638
{
@@ -632,6 +646,8 @@ private void WriteBlueprints()
632646
binary.Write(kv.Value);
633647
}
634648

649+
650+
635651
binary.Seek(tocAt, SeekOrigin.Begin);
636652
foreach (var t in toc)
637653
binary.Write(t);

BlueprintExplorer/BlueprintHandle.cs

Lines changed: 85 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public static string TypeString(this JsonElement elem)
4848
return elem.Str("$type").ParseTypeString();
4949
}
5050

51-
public static (string Guid, string Name, string FullName) NewTypeStr(this JsonElement elem, string context = null, Dictionary<string, List<string>> nameToFullNames = null, Func<string, string, string, List<string>, string> manualOverride = null)
51+
public static (string Guid, string Name, string FullName) NewTypeStr(this JsonElement elem, bool strict = true)
5252
{
5353
var raw = elem.Str("$type");
5454
var comma = raw.IndexOf(',');
@@ -59,21 +59,10 @@ public static (string Guid, string Name, string FullName) NewTypeStr(this JsonEl
5959
if (db.GuidToFullTypeName.TryGetValue(guid, out var fullTypeName))
6060
return (guid, shortName, fullTypeName);
6161

62-
if (nameToFullNames != null)
63-
{
64-
if (!nameToFullNames.TryGetValue(shortName, out var candidates))
65-
throw new Exception($"Could not get fullname candidates for type: {shortName}, context: {context}");
62+
if (strict)
63+
throw new Exception($"Cannot find type with that name: {shortName}");
6664

67-
string fullType = null;
68-
if (candidates.Count == 1)
69-
fullType = candidates[0];
70-
else
71-
fullType = manualOverride(guid, shortName, context, candidates);
72-
db.GuidToFullTypeName[guid] = fullType;
73-
return (guid, shortName, fullType);
74-
}
75-
76-
throw new Exception($"Cannot find type with that name: {shortName}");
65+
return (null, null, null);
7766
}
7867

7968
public static bool True(this JsonElement elem, string child)
@@ -110,22 +99,30 @@ public static bool IsEmptyContainer(this JsonElement elem)
11099
return (elem.ValueKind == JsonValueKind.Array && elem.GetArrayLength() == 0) || (elem.ValueKind == JsonValueKind.Object && elem.EnumerateObject().Count() == 0);
111100
}
112101

113-
public static void Visit(this JsonElement elem, Action<int, JsonElement> arrayIt, Action<string, JsonElement> objIt, Action<string> valIt)
102+
public static void Visit(this JsonElement elem, Action<int, JsonElement> arrayIt, Action<string, JsonElement> objIt, Action<string> valIt, bool autoRecurse = false)
114103
{
115104
if (elem.ValueKind == JsonValueKind.Array)
116105
{
117106
int index = 0;
118107
foreach (JsonElement entry in elem.EnumerateArray())
108+
{
119109
arrayIt(index++, entry);
110+
if (autoRecurse)
111+
entry.Visit(arrayIt, objIt, valIt, true);
112+
}
120113
}
121-
else if (elem.ValueKind == JsonValueKind.Object && elem.EnumerateObject().Count() > 0)
114+
else if (elem.ValueKind == JsonValueKind.Object && elem.EnumerateObject().Any())
122115
{
123116
foreach (var entry in elem.EnumerateObject())
117+
{
124118
objIt(entry.Name, entry.Value);
119+
if (autoRecurse)
120+
entry.Value.Visit(arrayIt, objIt, valIt, true);
121+
}
125122
}
126123
else
127124
{
128-
valIt(elem.GetRawText());
125+
valIt?.Invoke(elem.GetRawText());
129126
}
130127
}
131128
}
@@ -234,13 +231,13 @@ public override void SetValue(object component, object value)
234231

235232
public override string Description => _Description;
236233

237-
public override bool IsReadOnly => !(PropertyType == typeof(LocalisedStringProxy));
234+
public override bool IsReadOnly => !(PropertyType == typeof(LocalisedStringProxy) || PropertyType == typeof(NestedProxyWithString));
238235

239236
public override string Category => _Category;
240237

241238
public override object GetEditor(Type editorBaseType)
242239
{
243-
if (this.PropertyType == typeof(LocalisedStringProxy))
240+
if (PropertyType == typeof(LocalisedStringProxy) || PropertyType == typeof(NestedProxyWithString))
244241
return new LocalisedStringEditor();
245242
else
246243
return base.GetEditor(editorBaseType);
@@ -298,7 +295,13 @@ public void Add(string category, string name, string value, string description =
298295
}
299296
public void Add(string category, string name, JsonElement value, string description = "", Type parentType = null)
300297
{
301-
AddInternal(category, name, new NestedProxy(value), description, parentType);
298+
var strValue = NestedProxy.ParseAsString(value);
299+
NestedProxy proxy;
300+
if (strValue == null)
301+
proxy = new NestedProxy(value);
302+
else
303+
proxy = new NestedProxyWithString(value, strValue);
304+
AddInternal(category, name, proxy, description, parentType);
302305
}
303306

304307
public PropertyDescriptorCollection Build()
@@ -373,46 +376,82 @@ private static HashSet<string> FindTypedProperties(Type type)
373376
}
374377

375378
internal readonly JsonElement node;
376-
private string _ShortValue = "";
379+
protected string _ShortValue = "";
377380
public HashSet<string> TypedProperties;
378381
Type BlueprintType;
379382

380383
private static Regex ParseType = new(@"(.*)\.(.*), (.*)");
381384

382385
public override string ToString() => _ShortValue;
383386

387+
public static string ParseAsString(JsonElement node)
388+
{
389+
if (node.ValueKind != JsonValueKind.Object)
390+
return null;
391+
392+
if (node.TryGetProperty("m_Key", out var strKey) && node.TryGetProperty("Shared", out var sharedString) && node.TryGetProperty("m_OwnerString", out _))
393+
{
394+
var key = strKey.GetString();
395+
if (key.Length == 0 && sharedString.ValueKind == JsonValueKind.Object && sharedString.TryGetProperty("stringkey", out var sharedKey))
396+
key = sharedKey.GetString();
397+
398+
if (key.Length > 0)
399+
{
400+
if (BlueprintDB.Instance.Strings.TryGetValue(key, out var str))
401+
return str;
402+
else
403+
return "<string-not-present>";
404+
}
405+
else
406+
{
407+
return "<null-string>";
408+
}
409+
}
410+
return null;
411+
}
412+
384413
internal NestedProxy(JsonElement rootNode)
385414
{
386415
node = rootNode;
387416

388417
if (node.ValueKind == JsonValueKind.Object)
389418
{
390-
if (node.TryGetProperty("$type", out var typeVal))
419+
if (node.TryGetProperty("$type", out _))
391420
{
392-
var typeMatch = ParseType.Match(typeVal.GetString());
393-
if (typeMatch.Success)
421+
var type = node.NewTypeStr();
422+
if (type.Name == "ActionList")
394423
{
395-
if (typeMatch.Groups[1].Value == "ActionList")
396-
node = node.GetProperty("Actions");
397-
else
398-
{
399-
BlueprintType = Materializer.FindWrathType($"{typeMatch.Groups[1]}.{typeMatch.Groups[2]}");
400-
TypedProperties = FindTypedProperties(BlueprintType);
401-
}
402-
403-
//if (IsActionList)
404-
// _ShortValue = $"[{node.GetProperty("Actions").GetArrayLength()}] {typeMatch.Groups[1].Value}.Actions [{typeMatch.Groups[2].Value}]";
405-
if (node.ValueKind == JsonValueKind.Array)
406-
_ShortValue = $"[{node.GetArrayLength()}] {typeMatch.Groups[2].Value} [{typeMatch.Groups[3].Value}]";
407-
else
408-
_ShortValue = $"{typeMatch.Groups[2].Value} [{typeMatch.Groups[3].Value}]";
424+
node = node.GetProperty("Actions").GetProperty("Actions");
409425
}
410426
else
411427
{
412-
_ShortValue = typeVal.GetString();
428+
//BlueprintType = Materializer.FindWrathType($"{typeMatch.Groups[1]}.{typeMatch.Groups[2]}");
429+
//TypedProperties = FindTypedProperties(BlueprintType);
413430
}
431+
432+
//if (IsActionList)
433+
// _ShortValue = $"[{node.GetProperty("Actions").GetArrayLength()}] {typeMatch.Groups[1].Value}.Actions [{typeMatch.Groups[2].Value}]";
434+
if (node.ValueKind == JsonValueKind.Array)
435+
_ShortValue = $"[{node.GetArrayLength()}]";
436+
else
437+
_ShortValue = $"{type.Name}";
414438
}
415439
}
440+
else if (node.ValueKind == JsonValueKind.Array)
441+
{
442+
_ShortValue = "[" + node.GetArrayLength() + "]";
443+
}
444+
}
445+
446+
}
447+
448+
[TypeConverter(typeof(NestedConverter))]
449+
[EditorAttribute(typeof(LocalisedStringEditor), typeof(System.Drawing.Design.UITypeEditor))]
450+
internal class NestedProxyWithString : NestedProxy
451+
{
452+
internal NestedProxyWithString(JsonElement rootNode, string value) : base(rootNode)
453+
{
454+
_ShortValue = value;
416455
}
417456

418457
}
@@ -428,14 +467,14 @@ public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext contex
428467

429468
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
430469
{
431-
var proxy = value as LocalisedStringProxy;
470+
var proxy = value as NestedProxyWithString;
432471
IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
433472
if (edSvc != null)
434473
{
435474
// Display an angle selection control and retrieve the value.
436475
var label = new RichTextBox();
437476
var output = new StringBuilder();
438-
label.Text = proxy.Value.Replace("\\n", Environment.NewLine);
477+
label.Text = proxy.ToString().Replace("\\n", Environment.NewLine);
439478
label.Size = new System.Drawing.Size(400, 300);
440479
edSvc.DropDownControl(label);
441480
}
@@ -624,20 +663,20 @@ public IEnumerable<string> Objects
624663
}
625664
}
626665

627-
public static IEnumerable<string> VisitObjects(JsonElement node, string context = null, Dictionary<string, List<string>> nameToFullNames = null, Func<string, string, string, List<string>, string> manualOverride = null) {
666+
public static IEnumerable<string> VisitObjects(JsonElement node, string context = null) {
628667
if (node.ValueKind == JsonValueKind.Array) {
629668
int index = 0;
630669
foreach (var elem in node.EnumerateArray()) {
631-
foreach (var n in VisitObjects(elem, context + "/" + index.ToString(), nameToFullNames, manualOverride))
670+
foreach (var n in VisitObjects(elem, context + "/" + index.ToString()))
632671
yield return n;
633672
index++;
634673
}
635674
}
636675
else if (node.ValueKind == JsonValueKind.Object) {
637676
if (node.TryGetProperty("$type", out var _))
638-
yield return node.NewTypeStr(context, nameToFullNames, manualOverride).Name;
677+
yield return node.NewTypeStr().Guid;
639678
foreach (var elem in node.EnumerateObject()) {
640-
foreach (var n in VisitObjects(elem.Value, context + "/" + elem.Name, nameToFullNames, manualOverride))
679+
foreach (var n in VisitObjects(elem.Value, context + "/" + elem.Name))
641680
yield return n;
642681
}
643682
}

BlueprintExplorer/Form1.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,14 @@ void DarkenControls(params Control []controls)
125125

126126
var loadType = BlueprintDB.Instance.GetLoadType();
127127

128-
var loadString = "LOADING";
129-
130-
if (loadType == BlueprintDB.GoingToLoad.FromWeb)
131-
loadString = "DOWNLOADING";
132-
else if (loadType == BlueprintDB.GoingToLoad.FromNewImport)
133-
loadString = "IMPORTING";
128+
var loadString = loadType switch
129+
{
130+
BlueprintDB.GoingToLoad.FromLocalFile => "LOADING (debug)",
131+
BlueprintDB.GoingToLoad.FromSettingsFile => "LOADING (local)",
132+
BlueprintDB.GoingToLoad.FromWeb => "DOWNLOADING",
133+
BlueprintDB.GoingToLoad.FromNewImport => "IMPORTING",
134+
_ => throw new Exception(),
135+
};
134136

135137
var progress = new BlueprintDB.ConnectionProgress();
136138

BlueprintExplorer/Form1.resx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,22 @@
7575
<metadata name="From.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
7676
<value>True</value>
7777
</metadata>
78+
<metadata name="BPName.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
79+
<value>True</value>
80+
</metadata>
81+
<metadata name="BPType.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
82+
<value>True</value>
83+
</metadata>
84+
<metadata name="BPNamespace.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
85+
<value>True</value>
86+
</metadata>
87+
<metadata name="Score.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
88+
<value>True</value>
89+
</metadata>
90+
<metadata name="BPGuid.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
91+
<value>True</value>
92+
</metadata>
93+
<metadata name="From.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
94+
<value>True</value>
95+
</metadata>
7896
</root>

0 commit comments

Comments
 (0)