Make rigassets crash safe with staged output, progress logging and no async waits for v0.4.2
This commit is contained in:
@@ -34,7 +34,7 @@ Written to `Sons Of The Forest\UserData\RigProbe\`:
|
|||||||
|
|
||||||
- `characters\index.tsv` one line per character with rig family and player bone match
|
- `characters\index.tsv` one line per character with rig family and player bone match
|
||||||
- `characters\clips.tsv` every loaded animation clip, `characters\controllers.tsv` every loaded animator controller and who uses it
|
- `characters\clips.tsv` every loaded animation clip, `characters\controllers.tsv` every loaded animator controller and who uses it
|
||||||
- `assets.tsv` or `assets_<filter>.tsv`, `assets_locators.tsv` and `assets_known.tsv` (race and clothing GUIDs resolved) from `rigassets`
|
- `assets_locators.tsv`, `assets_known.tsv` (race and clothing GUIDs resolved), `assets_keycounts.tsv` and `assets.tsv` or `assets_<filter>.tsv` from `rigassets`
|
||||||
- `watch\<target>_<time>.log` and `_states.tsv` from `rigwatch`
|
- `watch\<target>_<time>.log` and `_states.tsv` from `rigwatch`
|
||||||
- `characters\rigfamilies.txt` characters grouped by shared skeleton
|
- `characters\rigfamilies.txt` characters grouped by shared skeleton
|
||||||
- `characters\<source>_<name>.json` full data per character
|
- `characters\<source>_<name>.json` full data per character
|
||||||
|
|||||||
+66
-38
@@ -656,12 +656,18 @@ public class RigProbe : SonsMod
|
|||||||
var outDir = Path.Combine(LoaderEnvironment.UserDataDirectory, "RigProbe");
|
var outDir = Path.Combine(LoaderEnvironment.UserDataDirectory, "RigProbe");
|
||||||
Directory.CreateDirectory(outDir);
|
Directory.CreateDirectory(outDir);
|
||||||
|
|
||||||
|
var locators = new List<UnityEngine.AddressableAssets.ResourceLocators.IResourceLocator>();
|
||||||
|
foreach (var locator in Iterate(Addressables.ResourceLocators))
|
||||||
|
if (locator != null)
|
||||||
|
locators.Add(locator);
|
||||||
|
RLog.Msg($"rigassets: {locators.Count} locators");
|
||||||
|
|
||||||
if (filter.StartsWith("key:", StringComparison.OrdinalIgnoreCase))
|
if (filter.StartsWith("key:", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
var key = filter.Substring(4).Trim();
|
var key = filter.Substring(4).Trim();
|
||||||
var one = new StringBuilder();
|
var one = new StringBuilder();
|
||||||
one.AppendLine("label\tkey\tprimaryKey\tinternalId\ttype\tprovider");
|
one.AppendLine("label\tlocator\tkey\tprimaryKey\tinternalId\ttype\tprovider");
|
||||||
var found = ResolveKey(one, key, key);
|
var found = ResolveKey(one, locators, key, key);
|
||||||
var onePath = Path.Combine(outDir, $"assets_key_{Sanitize(key)}.tsv");
|
var onePath = Path.Combine(outDir, $"assets_key_{Sanitize(key)}.tsv");
|
||||||
File.WriteAllText(onePath, one.ToString());
|
File.WriteAllText(onePath, one.ToString());
|
||||||
Say($"RigProbe: {found} locations for {key} written to {onePath}");
|
Say($"RigProbe: {found} locations for {key} written to {onePath}");
|
||||||
@@ -670,14 +676,8 @@ public class RigProbe : SonsMod
|
|||||||
|
|
||||||
var locSb = new StringBuilder();
|
var locSb = new StringBuilder();
|
||||||
locSb.AppendLine("locatorId\ttype\tkeys");
|
locSb.AppendLine("locatorId\ttype\tkeys");
|
||||||
var sb = new StringBuilder();
|
foreach (var locator in locators)
|
||||||
sb.AppendLine("locator\tkey\tprimaryKey\tinternalId\ttype\tprovider");
|
|
||||||
int rows = 0;
|
|
||||||
|
|
||||||
foreach (var locator in Iterate(Addressables.ResourceLocators))
|
|
||||||
{
|
{
|
||||||
if (locator == null)
|
|
||||||
continue;
|
|
||||||
string locType;
|
string locType;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -687,7 +687,31 @@ public class RigProbe : SonsMod
|
|||||||
{
|
{
|
||||||
locType = "?";
|
locType = "?";
|
||||||
}
|
}
|
||||||
|
locSb.AppendLine($"{locator.LocatorId}\t{locType}\t?");
|
||||||
|
RLog.Msg($"rigassets: locator {locator.LocatorId} type {locType}");
|
||||||
|
}
|
||||||
|
var locPath = Path.Combine(outDir, "assets_locators.tsv");
|
||||||
|
File.WriteAllText(locPath, locSb.ToString());
|
||||||
|
|
||||||
|
var known = new StringBuilder();
|
||||||
|
known.AppendLine("label\tlocator\tkey\tprimaryKey\tinternalId\ttype\tprovider");
|
||||||
|
int knownRows = 0;
|
||||||
|
foreach (var (label, key) in KnownKeys())
|
||||||
|
{
|
||||||
|
RLog.Msg($"rigassets: resolving {label} {key}");
|
||||||
|
knownRows += ResolveKey(known, locators, label, key);
|
||||||
|
}
|
||||||
|
File.WriteAllText(Path.Combine(outDir, "assets_known.tsv"), known.ToString());
|
||||||
|
RLog.Msg($"rigassets: {knownRows} known GUID locations");
|
||||||
|
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
sb.AppendLine("locator\tkey\tprimaryKey\tinternalId\ttype\tprovider");
|
||||||
|
int rows = 0;
|
||||||
|
var counts = new StringBuilder();
|
||||||
|
counts.AppendLine("locatorId\tkeys");
|
||||||
|
foreach (var locator in locators)
|
||||||
|
{
|
||||||
|
RLog.Msg($"rigassets: walking keys of {locator.LocatorId}");
|
||||||
int keyCount = 0;
|
int keyCount = 0;
|
||||||
foreach (var keyObj in Iterate(locator.Keys))
|
foreach (var keyObj in Iterate(locator.Keys))
|
||||||
{
|
{
|
||||||
@@ -709,28 +733,19 @@ public class RigProbe : SonsMod
|
|||||||
continue;
|
continue;
|
||||||
foreach (var loc in Iterate(locs.Cast<Il2CppSystem.Collections.Generic.IEnumerable<IResourceLocation>>()))
|
foreach (var loc in Iterate(locs.Cast<Il2CppSystem.Collections.Generic.IEnumerable<IResourceLocation>>()))
|
||||||
{
|
{
|
||||||
if (loc == null)
|
if (loc == null || !Matches(filter, key, loc))
|
||||||
continue;
|
|
||||||
if (!Matches(filter, key, loc))
|
|
||||||
continue;
|
continue;
|
||||||
sb.AppendLine($"{locator.LocatorId}\t{key}\t{LocationRow(loc)}");
|
sb.AppendLine($"{locator.LocatorId}\t{key}\t{LocationRow(loc)}");
|
||||||
rows++;
|
rows++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
locSb.AppendLine($"{locator.LocatorId}\t{locType}\t{keyCount}");
|
counts.AppendLine($"{locator.LocatorId}\t{keyCount}");
|
||||||
|
RLog.Msg($"rigassets: {locator.LocatorId} had {keyCount} keys");
|
||||||
}
|
}
|
||||||
|
|
||||||
var suffix = filter.Length > 0 ? $"_{Sanitize(filter)}" : string.Empty;
|
var suffix = filter.Length > 0 ? $"_{Sanitize(filter)}" : string.Empty;
|
||||||
File.WriteAllText(Path.Combine(outDir, $"assets{suffix}.tsv"), sb.ToString());
|
File.WriteAllText(Path.Combine(outDir, $"assets{suffix}.tsv"), sb.ToString());
|
||||||
File.WriteAllText(Path.Combine(outDir, "assets_locators.tsv"), locSb.ToString());
|
File.WriteAllText(Path.Combine(outDir, "assets_keycounts.tsv"), counts.ToString());
|
||||||
|
|
||||||
var known = new StringBuilder();
|
|
||||||
known.AppendLine("label\tkey\tprimaryKey\tinternalId\ttype\tprovider");
|
|
||||||
int knownRows = 0;
|
|
||||||
foreach (var (label, key) in KnownKeys())
|
|
||||||
knownRows += ResolveKey(known, label, key);
|
|
||||||
File.WriteAllText(Path.Combine(outDir, "assets_known.tsv"), known.ToString());
|
|
||||||
|
|
||||||
Say($"RigProbe: {rows} catalog locations and {knownRows} known GUID locations written to {outDir}");
|
Say($"RigProbe: {rows} catalog locations and {knownRows} known GUID locations written to {outDir}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -773,32 +788,45 @@ public class RigProbe : SonsMod
|
|||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int ResolveKey(StringBuilder sb, string label, string key)
|
private static int ResolveKey(StringBuilder sb, List<UnityEngine.AddressableAssets.ResourceLocators.IResourceLocator> locators, string label, string key)
|
||||||
{
|
{
|
||||||
int rows = 0;
|
int rows = 0;
|
||||||
|
Il2CppSystem.Object keyObj;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var keyObj = new Il2CppSystem.Object(Il2CppInterop.Runtime.IL2CPP.ManagedStringToIl2Cpp(key));
|
keyObj = new Il2CppSystem.Object(Il2CppInterop.Runtime.IL2CPP.ManagedStringToIl2Cpp(key));
|
||||||
var handle = Addressables.LoadResourceLocationsAsync(keyObj, null);
|
|
||||||
var result = handle.WaitForCompletion();
|
|
||||||
if (result != null)
|
|
||||||
{
|
|
||||||
foreach (var loc in Iterate(result.Cast<Il2CppSystem.Collections.Generic.IEnumerable<IResourceLocation>>()))
|
|
||||||
{
|
|
||||||
if (loc == null)
|
|
||||||
continue;
|
|
||||||
sb.AppendLine($"{label}\t{key}\t{LocationRow(loc)}");
|
|
||||||
rows++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
sb.AppendLine($"{label}\t{key}\terror: {e.Message}\t\t\t");
|
sb.AppendLine($"{label}\t\t{key}\terror: {e.Message}\t\t\t");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var locator in locators)
|
||||||
|
{
|
||||||
|
Il2CppSystem.Collections.Generic.IList<IResourceLocation> locs = null;
|
||||||
|
bool ok;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ok = locator.Locate(keyObj, null, out locs);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
if (!ok || locs == null)
|
||||||
|
continue;
|
||||||
|
foreach (var loc in Iterate(locs.Cast<Il2CppSystem.Collections.Generic.IEnumerable<IResourceLocation>>()))
|
||||||
|
{
|
||||||
|
if (loc == null)
|
||||||
|
continue;
|
||||||
|
sb.AppendLine($"{label}\t{locator.LocatorId}\t{key}\t{LocationRow(loc)}");
|
||||||
|
rows++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (rows == 0)
|
if (rows == 0)
|
||||||
sb.AppendLine($"{label}\t{key}\tnot found\t\t\t");
|
sb.AppendLine($"{label}\t\t{key}\tnot found\t\t\t");
|
||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
<AssemblyName>RigProbe</AssemblyName>
|
<AssemblyName>RigProbe</AssemblyName>
|
||||||
<RootNamespace>RigProbe</RootNamespace>
|
<RootNamespace>RigProbe</RootNamespace>
|
||||||
<Version>0.4.1</Version>
|
<Version>0.4.2</Version>
|
||||||
<NoWarn>CS0436;CS1701;CS1702;MSB3277;MSB3106</NoWarn>
|
<NoWarn>CS0436;CS1701;CS1702;MSB3277;MSB3106</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
"id": "RigProbe",
|
"id": "RigProbe",
|
||||||
"name": "RigProbe",
|
"name": "RigProbe",
|
||||||
"author": "JustinOros",
|
"author": "JustinOros",
|
||||||
"version": "0.4.1",
|
"version": "0.4.2",
|
||||||
"description": "Dumps rig, mesh, material and animator data for every Sons of the Forest character to JSON for mod development",
|
"description": "Dumps rig, mesh, material and animator data for every Sons of the Forest character to JSON for mod development",
|
||||||
"gameVersion": "1.0.0",
|
"gameVersion": "1.0.0",
|
||||||
"platform": "Client",
|
"platform": "Client",
|
||||||
|
|||||||
Reference in New Issue
Block a user