Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of WikiDumpMods v1.0.4
WikiDumpMods.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using UnityEngine; [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace WikiDumpMods; internal sealed class Baseline { public string GameVersion; public string Created; public string Path; public string Source; public bool Partial; public readonly HashSet<string> Covered = new HashSet<string>(); public readonly HashSet<string> Keys = new HashSet<string>(); public readonly Dictionary<string, Dictionary<string, string>> Fp = new Dictionary<string, Dictionary<string, string>>(); private Func<Stream> _open; public bool Contains(string key) { return Keys.Contains(key); } public void Save(string path) { JObj jObj = new JObj(); jObj["format"] = 2; jObj["gameVersion"] = GameVersion; jObj["created"] = Created; jObj["source"] = Source ?? "WikiDumpMods vanilla run"; jObj["partial"] = false; JArr jArr = new JArr(); foreach (string item in Keys.OrderBy<string, string>((string x) => x, StringComparer.Ordinal)) { jArr.Add(item); } jObj["keys"] = jArr; Directory.CreateDirectory(System.IO.Path.GetDirectoryName(path)); using FileStream stream = File.Create(path); using GZipStream stream2 = new GZipStream(stream, CompressionMode.Compress); using StreamWriter streamWriter = new StreamWriter(stream2, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); Json.Write(streamWriter, jObj, -1); streamWriter.Write('\n'); foreach (KeyValuePair<string, Dictionary<string, string>> item2 in Fp.OrderBy<KeyValuePair<string, Dictionary<string, string>>, string>((KeyValuePair<string, Dictionary<string, string>> x) => x.Key, StringComparer.Ordinal)) { JObj jObj2 = new JObj(); foreach (KeyValuePair<string, string> item3 in item2.Value) { jObj2[item3.Key] = item3.Value; } Json.Write(streamWriter, new JObj { { "k", item2.Key }, { "fp", jObj2 } }, -1); streamWriter.Write('\n'); } } public static Baseline Load(string path) { if (!File.Exists(path)) { return null; } return Open(() => File.OpenRead(path), path); } public static Baseline LoadEmbedded(Assembly asm, string resource) { if (asm == null || asm.GetManifestResourceInfo(resource) == null) { return null; } return Open(() => asm.GetManifestResourceStream(resource), "embedded:" + resource); } private static Baseline Open(Func<Stream> open, string label) { Baseline baseline = new Baseline(); baseline.Path = label; baseline._open = open; Baseline baseline2 = baseline; using StreamReader streamReader = baseline2.Reader(); if (!(JsonParse.Parse(streamReader.ReadLine()) is JObj jObj)) { return null; } baseline2.GameVersion = jObj["gameVersion"] as string; baseline2.Created = jObj["created"] as string; baseline2.Source = jObj["source"] as string; baseline2.Partial = jObj["partial"] is bool && (bool)jObj["partial"]; foreach (object item in (jObj["keys"] as JArr) ?? new JArr()) { if (item is string) { baseline2.Keys.Add((string)item); } } foreach (object item2 in (jObj["covered"] as JArr) ?? new JArr()) { if (item2 is string) { baseline2.Covered.Add((string)item2); } } return baseline2; } private StreamReader Reader() { Stream stream = _open(); BufferedStream bufferedStream = new BufferedStream(stream); int num = bufferedStream.ReadByte(); int num2 = bufferedStream.ReadByte(); bufferedStream.Seek(0L, SeekOrigin.Begin); Stream stream2 = ((num != 31 || num2 != 139) ? ((Stream)bufferedStream) : ((Stream)new GZipStream(bufferedStream, CompressionMode.Decompress))); return new StreamReader(stream2, Encoding.UTF8); } public IEnumerable<KeyValuePair<string, Dictionary<string, string>>> EachFingerprint() { if (_open == null) { yield break; } using StreamReader r = Reader(); r.ReadLine(); while (true) { string text; string line = (text = r.ReadLine()); if (text == null) { break; } if (line.Length == 0) { continue; } JObj o = JsonParse.Parse(line) as JObj; JObj fp = ((o != null) ? (o["fp"] as JObj) : null); if (fp == null) { continue; } Dictionary<string, string> d = new Dictionary<string, string>(); foreach (KeyValuePair<string, object> item in fp) { d[item.Key] = item.Value as string; } yield return new KeyValuePair<string, Dictionary<string, string>>(o["k"] as string, d); } } } internal static class JsonParse { public static object Parse(string s) { int i = 0; return Val(s, ref i); } private static void Ws(string s, ref int i) { while (i < s.Length && char.IsWhiteSpace(s[i])) { i++; } } private static object Val(string s, ref int i) { Ws(s, ref i); if (i >= s.Length) { throw new FormatException("unexpected end"); } switch (s[i]) { case '{': { JObj jObj = new JObj(); i++; Ws(s, ref i); if (s[i] == '}') { i++; return jObj; } while (true) { Ws(s, ref i); string k = Str(s, ref i); Ws(s, ref i); if (s[i] != ':') { throw new FormatException("':' expected at " + i); } i++; jObj[k] = Val(s, ref i); Ws(s, ref i); if (s[i] != ',') { break; } i++; } if (s[i] == '}') { i++; return jObj; } throw new FormatException("',' or '}' expected at " + i); } case '[': { JArr jArr = new JArr(); i++; Ws(s, ref i); if (s[i] == ']') { i++; return jArr; } while (true) { jArr.Add(Val(s, ref i)); Ws(s, ref i); if (s[i] != ',') { break; } i++; } if (s[i] == ']') { i++; return jArr; } throw new FormatException("',' or ']' expected at " + i); } case '"': return Str(s, ref i); default: { if (string.CompareOrdinal(s, i, "true", 0, 4) == 0) { i += 4; return true; } if (string.CompareOrdinal(s, i, "false", 0, 5) == 0) { i += 5; return false; } if (string.CompareOrdinal(s, i, "null", 0, 4) == 0) { i += 4; return null; } int num = i; while (i < s.Length && "+-0123456789.eE".IndexOf(s[i]) >= 0) { i++; } return double.Parse(s.Substring(num, i - num), CultureInfo.InvariantCulture); } } } private static string Str(string s, ref int i) { if (s[i] != '"') { throw new FormatException("string expected at " + i); } i++; StringBuilder stringBuilder = new StringBuilder(); while (s[i] != '"') { char c = s[i++]; if (c != '\\') { stringBuilder.Append(c); continue; } char c2 = s[i++]; switch (c2) { case 'n': stringBuilder.Append('\n'); break; case 'r': stringBuilder.Append('\r'); break; case 't': stringBuilder.Append('\t'); break; case 'b': stringBuilder.Append('\b'); break; case 'f': stringBuilder.Append('\f'); break; case 'u': stringBuilder.Append((char)int.Parse(s.Substring(i, 4), NumberStyles.HexNumber)); i += 4; break; default: stringBuilder.Append(c2); break; } } i++; return stringBuilder.ToString(); } } internal sealed class DumpOptions { public string OutDir; public string BaselinePath; public string[] Languages = new string[2] { "English", "Ukrainian" }; public bool Icons = true; public string IconColor = "LinearToSRGB"; public bool ScanVanillaLocations = true; public bool IncludeVanilla; public bool Tooltips = true; public bool ModStatics = true; public bool ForceBaseline; public string ConfigDir; public int RawDepth = 4; public string PluginVersion; public string SelfGuid; } internal sealed class Dumper { private readonly DumpOptions _opt; private readonly List<ModEntry> _mods; private readonly Action<string> _log; private readonly Action<string> _hud; private Registry _r; private Origin _o; private Loc _loc; private DataIndex _ix; private Icons _icons; private readonly JObj _manifest = new JObj(); private readonly JArr _errors = new JArr(); private readonly Dictionary<string, JObj> _tooltips = new Dictionary<string, JObj>(); private readonly Dictionary<string, JArr> _iconFiles = new Dictionary<string, JArr>(); private readonly Dictionary<string, HashSet<string>> _modTokens = new Dictionary<string, HashSet<string>>(); private readonly Dictionary<string, JObj> _modContent = new Dictionary<string, JObj>(); private readonly Stopwatch _sw = new Stopwatch(); public bool BaselineMode; public string Summary; private bool _restoreWarning; private bool _tooltipErr; private readonly JObj _locDiag = new JObj(); private int _locLoaded; private int _locFailed; private static readonly string[] PerLevel = new string[4] { "m_armor|m_armorPerLevel", "m_maxDurability|m_durabilityPerLevel", "m_blockPower|m_blockPowerPerLevel", "m_deflectionForce|m_deflectionForcePerLevel" }; public Dumper(DumpOptions opt, List<ModEntry> mods, Action<string> log, Action<string> hud) { _opt = opt; _mods = mods; _log = log ?? ((Action<string>)delegate { }); _hud = hud ?? ((Action<string>)delegate { }); } private string P(params string[] parts) { return Path.Combine(_opt.OutDir, Path.Combine(parts)); } private void Step(string name, Action a) { long elapsedMilliseconds = _sw.ElapsedMilliseconds; try { a(); } catch (Exception ex) { Exception ex2 = ((!(ex is TargetInvocationException) || ex.InnerException == null) ? ex : ex.InnerException); _errors.Add(new JObj { { "section", name }, { "error", ex2.GetType().Name + ": " + ex2.Message }, { "stack", ex2.StackTrace } }); _log("section " + name + " failed: " + ex2); } JObj jObj = _manifest.Obj("timingsMs"); jObj[name] = ((!(jObj[name] is long)) ? 0 : ((long)jObj[name])) + (_sw.ElapsedMilliseconds - elapsedMilliseconds); } private bool InScope(string key) { return _opt.IncludeVanilla || _o.IsModKey(key); } private string ModOfKey(string key) { OriginInfo originInfo = _o.Get(key); return (!originInfo.IsMod) ? null : (originInfo.Mod ?? "unknown"); } private JObj Content(string mod) { if (!_modContent.TryGetValue(mod, out var value)) { value = (_modContent[mod] = new JObj()); } return value; } private void Track(string key, string kind, string name, string token) { string text = ModOfKey(key); if (text == null) { return; } Content(text).Arr(kind).Add(name); foreach (string item in _loc.Tokens(token)) { if (!_modTokens.TryGetValue(text, out var value)) { value = (_modTokens[text] = new HashSet<string>()); } value.Add(item); } } public IEnumerator Run() { _sw.Start(); Directory.CreateDirectory(_opt.OutDir); CleanOutput(); _hud("WikiDumpMods: збираю дані…"); _manifest["plugin"] = _opt.PluginVersion; _manifest["gameVersion"] = GameVersion(); _manifest["dumpedAtUtc"] = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss"); _manifest["includeVanilla"] = _opt.IncludeVanilla; BaselineMode = _opt.ForceBaseline || _mods.All((ModEntry m) => m.Guid == _opt.SelfGuid || m.Guid == "com.jotunn.jotunn"); JArr present = new JArr(); foreach (ModEntry mod in _mods) { present.Add(mod.Guid + " " + mod.Version); } _manifest["plugins"] = present; _manifest["mode"] = ((!BaselineMode) ? "mods" : "vanilla-baseline"); Step("registry", delegate { _r = Registry.Collect(); }); yield return null; if (_r == null) { Finish(); yield break; } foreach (string problem in _r.Problems) { _errors.Add(new JObj { { "section", "registry" }, { "error", problem } }); } _o = new Origin(_mods); if (!BaselineMode) { Step("baseline.load", delegate { _o.Baseline = Baseline.Load(_opt.BaselinePath) ?? Baseline.LoadEmbedded(typeof(Dumper).Assembly, "WikiDumpMods.vanilla_baseline.jsonl.gz"); if (_o.Baseline != null && _o.Baseline.GameVersion != GameVersion()) { _errors.Add(new JObj { { "section", "baseline" }, { "warning", "baseline is for game " + _o.Baseline.GameVersion + ", running " + GameVersion() + ": things the update added may show as modded" } }); } }); } JObj jotunn = new JObj(); JObj statics = new JObj(); Step("origin", delegate { //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Expected O, but got Unknown //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Expected O, but got Unknown jotunn = _o.FromJotunn(); statics = _o.FromStatics(); _o.FromBundles(); foreach (GameObject value2 in _r.Prefabs.Values) { _o.Inspect((Object)(object)value2); } foreach (object recipe in _r.Recipes) { _o.Inspect((Object)recipe); } foreach (object statusEffect in _r.StatusEffects) { _o.Inspect((Object)statusEffect); } foreach (GameObject value3 in _r.Prefabs.Values) { _o.Registered.Add("prefab:" + ((Object)value3).name); } _o.BaselineCovers = delegate(string key) { if (!key.StartsWith("prefab:")) { return true; } string text3 = key.Substring(7); if (_r.Items.ContainsKey(text3)) { return true; } if (!_r.Networked.Contains(text3)) { return false; } if (!_r.Prefabs.TryGetValue(text3, out var value)) { return false; } foreach (string item in _o.Baseline.Covered) { if (Object.op_Implicit((Object)(object)Refl.Comp(value, item))) { return true; } } return false; }; foreach (object recipe2 in _r.Recipes) { _o.Registered.Add(Origin.KeyOf(recipe2)); } foreach (object statusEffect2 in _r.StatusEffects) { _o.Registered.Add(Origin.KeyOf(statusEffect2)); } foreach (object location in _r.Locations) { string text = Refl.S(Refl.Get(location, "m_prefabName")); if (text != null) { _o.Registered.Add("loc:" + text); } } foreach (object @event in _r.Events) { string text2 = Refl.S(Refl.Get(@event, "m_name")); if (text2 != null) { _o.Registered.Add("event:" + text2); } } foreach (object recipe3 in _r.Recipes) { _o.Inherit(Origin.KeyOf(recipe3), Origin.KeyOf(Refl.Get(recipe3, "m_item")), "result item", markModded: true); } foreach (GameObject value4 in _r.Items.Values) { string[] array = new string[4] { "m_consumeStatusEffect", "m_equipStatusEffect", "m_setStatusEffect", "m_attackStatusEffect" }; foreach (string name in array) { _o.Inherit(Origin.KeyOf(Refl.Get(Registry.Shared(value4), name)), "prefab:" + ((Object)value4).name, "used by item", markModded: false); } } }); yield return null; if (BaselineMode) { Step("baseline.write", WriteBaseline); Finish(); yield break; } _loc = new Loc { Original = Loc.Current() }; Step("localization", delegate { Languages(); }); yield return null; IEnumerator it = BuildIndex(); while (it.MoveNext()) { yield return it.Current; } Step("origin.refine", delegate { _o.Refine(_r, _ix.Refs); }); yield return null; IEnumerator it2 = BuildIndex(); while (it2.MoveNext()) { yield return it2.Current; } JArr locations = new JArr(); JArr rooms = new JArr(); int n = 0; foreach (object zl in _r.Locations) { Step("locations", delegate { JObj jObj = Location(zl, room: false); if (jObj != null) { locations.Add(jObj); } }); int num; n = (num = n + 1); if (num % 10 == 0) { yield return null; } } foreach (object rd in _r.Rooms) { Step("rooms", delegate { JObj jObj = Location(rd, room: true); if (jObj != null) { rooms.Add(jObj); } }); int num; n = (num = n + 1); if (num % 10 == 0) { yield return null; } } if (_opt.Icons) { _icons = new Icons(_opt.IconColor); Step("icons", ExportIcons); yield return null; } _hud("WikiDumpMods: записую файли…"); Step("items", WriteItems); yield return null; Step("pieces", WritePieces); yield return null; Step("creatures", WriteCreatures); yield return null; Step("status_effects", WriteStatusEffects); yield return null; Step("recipes", WriteRecipes); yield return null; Step("world", delegate { WriteWorld(locations, rooms); }); yield return null; Step("vanilla_links", WriteVanillaLinks); yield return null; Step("vanilla_changes", WriteVanillaChanges); yield return null; Step("references", WriteReferences); yield return null; Step("raw_prefabs", WriteRaw); yield return null; Step("localization.files", WriteLocalization); yield return null; Step("origin.file", delegate { WriteOrigin(jotunn, statics); }); yield return null; Step("mods", WriteMods); yield return null; if (_icons != null) { _icons.Dispose(); } Finish(); } private IEnumerator BuildIndex() { _ix = new DataIndex(_r, _o, _loc); Step("index.recipes", _ix.BuildRecipes); yield return null; Step("index.prefabs", _ix.BuildPrefabs); yield return null; Step("index.spawns", _ix.BuildSpawns); yield return null; int n = 0; foreach (GameObject go in _r.Prefabs.Values.ToList()) { Step("index.references", delegate { _ix.ScanReferences(go); }); int num; n = (num = n + 1); if (num % 60 == 0) { yield return null; } } foreach (object so in _r.Recipes.Concat(_r.StatusEffects)) { Step("index.references", delegate { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown _ix.ScanReferencesOf((Object)so); }); } yield return null; } private void CleanOutput() { string[] array = new string[4] { "icons", "raw", "mods", "localization" }; foreach (string text in array) { string path = P(text); try { if (Directory.Exists(path)) { Directory.Delete(path, recursive: true); } } catch { } } string[] files = Directory.GetFiles(_opt.OutDir, "*.json"); foreach (string path2 in files) { if (!string.Equals(Path.GetFullPath(path2), Path.GetFullPath(_opt.BaselinePath ?? ""), StringComparison.OrdinalIgnoreCase)) { try { File.Delete(path2); } catch { } } } } private void Finish() { if (_locLoaded + _locFailed > 0) { _manifest["locationLoading"] = new JObj { { "loaded", _locLoaded }, { "failed", _locFailed }, { "diagnostics", _locDiag } }; } _manifest["errors"] = _errors; _manifest["totalMs"] = _sw.ElapsedMilliseconds; if (_icons != null) { _manifest["icons"] = new JObj { { "saved", _icons.Saved }, { "reused", _icons.Reused }, { "failed", _icons.Failed }, { "lastError", _icons.LastError }, { "colorMode", _opt.IconColor } }; } if (_o != null && _o.Baseline != null) { _manifest["baseline"] = new JObj { { "path", _o.Baseline.Path }, { "gameVersion", _o.Baseline.GameVersion }, { "created", _o.Baseline.Created } }; } else if (!BaselineMode) { _manifest["baseline"] = "none (modded/vanilla split uses heuristics; see README)"; } Json.WriteFile(P("manifest.json"), _manifest, pretty: true); Summary = ((!BaselineMode) ? ("WikiDumpMods: готово" + ((_errors.Count <= 0) ? "" : (" (помилок: " + _errors.Count + ")")) + ((!_restoreWarning) ? "" : ". Перезапусти гру: частина перекладів модів зникла")) : "WikiDumpMods: збережено ванільний еталон"); _hud(Summary); _log(Summary + " in " + _sw.ElapsedMilliseconds + " ms -> " + _opt.OutDir); } private static string GameVersion() { object[][] array = new object[2][] { new object[0], new object[1] { false } }; foreach (object[] args in array) { string text = Refl.CallStatic("Version", "GetVersionString", args) as string; if (!string.IsNullOrEmpty(text)) { return text; } } object obj = Refl.GetStatic("Version", "CurrentVersion"); return (obj == null) ? "?" : obj.ToString(); } private void Languages() { string text = _loc.Original ?? "English"; List<string> list = new List<string>(); list.Add(text); List<string> list2 = list; string[] languages = _opt.Languages; foreach (string text2 in languages) { if (!string.IsNullOrEmpty(text2) && !list2.Contains(text2.Trim())) { list2.Add(text2.Trim()); } } List<string> tokens = AllTokens(); _loc.Mod = new ModTexts(list2); try { string configDir = _opt.ConfigDir; _loc.Mod.Collect(_mods, configDir, _opt.OutDir); _manifest["translationSources"] = _loc.Mod.SourcesRead; } catch (Exception ex) { _errors.Add(new JObj { { "section", "localization.files" }, { "error", ex.Message } }); } bool flag = false; try { foreach (string item in list2) { if (item != text) { if (!Loc.Switch(item)) { _errors.Add(new JObj { { "section", "localization" }, { "error", "language not available: " + item } }); continue; } flag = true; } _loc.Capture(item); _loc.ResolveTokens(item, tokens); if (_opt.Tooltips) { Tooltips(item); } } } finally { if (flag) { Loc.Switch(text); } } if (flag && _loc.Resolved.TryGetValue(text, out var value)) { int num = 0; JArr jArr = new JArr(); foreach (KeyValuePair<string, string> item2 in value) { if (item2.Value != null) { num++; if (Loc.GameLocalize(item2.Key) == null && jArr.Count < 50) { jArr.Add(item2.Key); } } } _manifest["languageRestore"] = new JObj { { "language", text }, { "tokensChecked", num }, { "lostAfterRestore", jArr } }; if (jArr.Count > 0) { _restoreWarning = true; } } _manifest["languages"] = new JArr(); foreach (string language in _loc.Languages) { ((JArr)_manifest["languages"]).Add(language); } } private List<string> AllTokens() { HashSet<string> hs = new HashSet<string>(); Action<object> action = delegate(object obj) { foreach (string item in _loc.Tokens(obj as string)) { hs.Add(item); } }; foreach (GameObject value in _r.Prefabs.Values) { action(DataIndex.DisplayToken(value)); object o = Registry.Shared(value); action(Refl.Get(o, "m_name")); action(Refl.Get(o, "m_description")); action(Refl.Get(o, "m_setName")); Component o2 = Refl.Comp(value, "Piece"); action(Refl.Get(o2, "m_name")); action(Refl.Get(o2, "m_description")); string[] array = new string[10] { "Character", "CraftingStation", "Smelter", "CookingStation", "Trader", "OfferingBowl", "Container", "Pickable", "Fermenter", "Incinerator" }; foreach (string typeName in array) { Component o3 = Refl.Comp(value, typeName); action(Refl.Get(o3, "m_name")); action(Refl.Get(o3, "m_overrideName")); } } foreach (object statusEffect in _r.StatusEffects) { action(Refl.Get(statusEffect, "m_name")); action(Refl.Get(statusEffect, "m_tooltip")); } foreach (object @event in _r.Events) { action(Refl.Get(@event, "m_startMessage")); action(Refl.Get(@event, "m_endMessage")); } return hs.ToList(); } private void Tooltips(string lang) { //IL_03b5: Unknown result type (might be due to invalid IL or missing references) Type tID = Refl.T("ItemDrop+ItemData"); MethodInfo methodInfo = ((!(tID == null)) ? (from m in tID.GetMethods(BindingFlags.Static | BindingFlags.Public) where m.Name == "GetTooltip" && m.GetParameters().Length >= 2 && m.GetParameters()[0].ParameterType == tID orderby m.GetParameters().Length select m).FirstOrDefault() : null); foreach (GameObject value in _r.Items.Values) { if (!InScope("prefab:" + ((Object)value).name)) { continue; } object obj = Registry.ItemData(value); if (obj == null || methodInfo == null) { continue; } int num = Math.Max(1, Refl.I(Refl.Get(Registry.Shared(value), "m_maxQuality"), 1)); JObj jObj = new JObj(); for (int num2 = 1; num2 <= num; num2++) { try { ParameterInfo[] parameters = methodInfo.GetParameters(); object[] array = new object[parameters.Length]; for (int num3 = 0; num3 < parameters.Length; num3++) { Type parameterType = parameters[num3].ParameterType; if (num3 == 0) { array[num3] = obj; } else if (parameterType == typeof(int) && parameters[num3].Name.IndexOf("quality", StringComparison.OrdinalIgnoreCase) >= 0) { array[num3] = num2; } else if (parameterType == typeof(bool)) { array[num3] = parameters[num3].Name.IndexOf("craft", StringComparison.OrdinalIgnoreCase) >= 0; } else if (parameterType == typeof(float)) { array[num3] = 0f; } else if (parameterType == typeof(int)) { array[num3] = ((!parameters[num3].IsOptional) ? ((object)(-1)) : parameters[num3].DefaultValue); } else { array[num3] = ((!parameters[num3].IsOptional) ? null : parameters[num3].DefaultValue); } } jObj[num2.ToString()] = methodInfo.Invoke(null, array) as string; } catch (Exception ex) { jObj[num2.ToString()] = null; if (!_tooltipErr) { _tooltipErr = true; _errors.Add(new JObj { { "section", "tooltips" }, { "error", (ex.InnerException ?? ex).Message } }); } } } TipFor("item:" + ((Object)value).name)[lang] = jObj; } foreach (object statusEffect in _r.StatusEffects) { if (InScope(Origin.KeyOf(statusEffect))) { string text = null; try { text = Refl.Call(statusEffect, "GetTooltipString") as string; } catch { } if (text != null) { TipFor("se:" + ((Object)statusEffect).name)[lang] = text; } } } } private static string Localize(string s) { object obj = Refl.Singleton("Localization"); return (obj != null) ? ((Refl.Call(obj, "Localize", s) as string) ?? s) : s; } private JObj LocalizedTips(JObj tips) { JObj jObj = new JObj(); foreach (KeyValuePair<string, object> tip in tips) { if (tip.Value is string) { jObj[tip.Key] = _loc.Text((string)tip.Value, tip.Key) ?? tip.Value; } else { if (!(tip.Value is JObj jObj2)) { continue; } JObj jObj3 = new JObj(); foreach (KeyValuePair<string, object> item in jObj2) { jObj3[item.Key] = ((!(item.Value is string)) ? null : (_loc.Text((string)item.Value, tip.Key) ?? item.Value)); } jObj[tip.Key] = jObj3; } } return jObj; } private JObj TipFor(string key) { if (!_tooltips.TryGetValue(key, out var value)) { value = (_tooltips[key] = new JObj()); } return value; } private Dictionary<string, Dictionary<string, string>> Fingerprints(bool onlyVanilla) { Dictionary<string, Dictionary<string, string>> fp = new Dictionary<string, Dictionary<string, string>>(); Action<string, object> action = delegate(string k, object node) { if (node != null) { Dictionary<string, string> dictionary = new Dictionary<string, string>(); Ser.Flatten(node, "", dictionary); fp[k] = dictionary; } }; foreach (GameObject value in _r.Items.Values) { if (!onlyVanilla || !_o.IsModKey("prefab:" + ((Object)value).name)) { action("item:" + ((Object)value).name, Ser.Node(Registry.Shared(value), 3)); } } foreach (object recipe in _r.Recipes) { string text = Origin.KeyOf(recipe); if (!onlyVanilla || !_o.IsModKey(text)) { action(text, Ser.Node(recipe, 2)); } } foreach (object statusEffect in _r.StatusEffects) { string text2 = Origin.KeyOf(statusEffect); if (!onlyVanilla || !_o.IsModKey(text2)) { action(text2, Ser.Node(statusEffect, 2)); } } foreach (GameObject value2 in _r.Prefabs.Values) { if (onlyVanilla && _o.IsModKey("prefab:" + ((Object)value2).name)) { continue; } string[] array = new string[24] { "Piece", "Character", "CharacterDrop", "Container", "Pickable", "DropOnDestroyed", "MineRock5", "MineRock", "TreeBase", "TreeLog", "Trader", "Smelter", "CookingStation", "Fermenter", "Incinerator", "MonsterAI", "Tameable", "CraftingStation", "StationExtension", "WearNTear", "Plant", "Fish", "OfferingBowl", "SpawnArea" }; foreach (string text3 in array) { Component val = Refl.Comp(value2, text3); if (Object.op_Implicit((Object)(object)val)) { action(text3 + ":" + ((Object)value2).name, Ser.Node(val, (!(text3 == "Character") && !(text3 == "MonsterAI")) ? 3 : 2)); } } } return fp; } private void WriteBaseline() { Baseline baseline = new Baseline(); baseline.GameVersion = GameVersion(); baseline.Created = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss"); baseline.Source = "WikiDumpMods " + _opt.PluginVersion + " vanilla run"; Baseline baseline2 = baseline; foreach (GameObject value in _r.Prefabs.Values) { baseline2.Keys.Add("prefab:" + ((Object)value).name); } foreach (object recipe in _r.Recipes) { baseline2.Keys.Add(Origin.KeyOf(recipe)); } foreach (object statusEffect in _r.StatusEffects) { baseline2.Keys.Add(Origin.KeyOf(statusEffect)); } foreach (object location in _r.Locations) { string text = Refl.S(Refl.Get(location, "m_prefabName")); if (text != null) { baseline2.Keys.Add("loc:" + text); } } foreach (object @event in _r.Events) { string text2 = Refl.S(Refl.Get(@event, "m_name")); if (text2 != null) { baseline2.Keys.Add("event:" + text2); } } foreach (KeyValuePair<string, Dictionary<string, string>> item in Fingerprints(onlyVanilla: false)) { baseline2.Fp[item.Key] = item.Value; } baseline2.Save(_opt.BaselinePath); _manifest["baselineWritten"] = new JObj { { "path", _opt.BaselinePath }, { "keys", baseline2.Keys.Count }, { "fingerprints", baseline2.Fp.Count } }; } private void WriteVanillaChanges() { JObj jObj = new JObj(); if (_o.Baseline == null) { jObj["note"] = "No vanilla baseline: run once with only WikiDumpMods installed to enable this file (see README)."; Json.WriteFile(P("vanilla_changes.json"), jObj, pretty: true); return; } jObj["baseline"] = new JObj { { "path", _o.Baseline.Path }, { "source", _o.Baseline.Source }, { "gameVersion", _o.Baseline.GameVersion }, { "partial", _o.Baseline.Partial } }; if (_o.Baseline.GameVersion != GameVersion()) { jObj["warning"] = "baseline game version " + _o.Baseline.GameVersion + " differs from " + GameVersion() + ": some changes may come from the game update, not from mods"; } Dictionary<string, Dictionary<string, string>> dictionary = Fingerprints(onlyVanilla: true); JArr jArr = new JArr(); foreach (KeyValuePair<string, Dictionary<string, string>> item in _o.Baseline.EachFingerprint()) { if (item.Key == null || !dictionary.TryGetValue(item.Key, out var value)) { continue; } JArr jArr2 = Diff(item.Value, value); if (jArr2.Count != 0) { string key = item.Key.Substring(item.Key.IndexOf(':') + 1); _r.Prefabs.TryGetValue(key, out var value2); JObj jObj2 = new JObj(); jObj2.Add("key", item.Key); JObj jObj3 = jObj2; if (Object.op_Implicit((Object)(object)value2)) { jObj3.Opt("names", _loc.Names(DataIndex.DisplayToken(value2))); } jObj3["changes"] = jArr2; jArr.Add(jObj3); } } jObj["note"] = "Values that differ from the unmodded game. Which mod made a change cannot be read from the data; see mods.json -> harmonyPatches for candidates. Fields one side does not record are not compared."; jObj["changed"] = jArr; Json.WriteFile(P("vanilla_changes.json"), jObj, pretty: false); _manifest.Obj("counts")["vanillaChanged"] = jArr.Count; } private static JArr Diff(Dictionary<string, string> old, Dictionary<string, string> cur) { JArr jArr = new JArr(); foreach (KeyValuePair<string, string> item in cur) { if (old.TryGetValue(item.Key, out var value)) { if (item.Key.EndsWith(".#")) { if (value != item.Value) { jArr.Add(new JObj { { "path", item.Key }, { "vanilla", value }, { "now", item.Value } }); } continue; } string text = NormVal(value); string text2 = NormVal(item.Value); if (text != null && text2 != null && !Same(text, text2)) { jArr.Add(new JObj { { "path", item.Key }, { "vanilla", Show(text) }, { "now", Show(text2) } }); } } else if (BeyondList(item.Key, old)) { string text3 = NormVal(item.Value); if (text3 != null) { jArr.Add(new JObj { { "path", item.Key }, { "vanilla", null }, { "now", Show(text3) } }); } } } foreach (KeyValuePair<string, string> item2 in old) { if (!cur.ContainsKey(item2.Key) && BeyondList(item2.Key, cur)) { string text4 = NormVal(item2.Value); if (text4 != null) { jArr.Add(new JObj { { "path", item2.Key }, { "vanilla", Show(text4) }, { "now", null } }); } } } return jArr; } private static bool BeyondList(string path, Dictionary<string, string> other) { for (int num = path.LastIndexOf('['); num > 0; num = path.LastIndexOf('[', num - 1)) { int num2 = path.IndexOf(']', num); int result2; if (num2 > num && int.TryParse(path.Substring(num + 1, num2 - num - 1), out var result) && other.TryGetValue(path.Substring(0, num) + ".#", out var value)) { return int.TryParse(value, out result2) && result >= result2; } } return false; } private static string NormVal(string v) { if (v == null || v == "null") { return "null"; } object obj; try { obj = JsonParse.Parse(v); } catch { return "s:" + v; } if (obj is JObj jObj) { string[] array = new string[2] { "$go", "$sprite" }; foreach (string k in array) { if (jObj[k] is string) { return "s:" + jObj[k]; } } if (jObj.Has("$comp")) { return "s:" + jObj["go"]; } if (jObj.Has("$so") || jObj.Has("$asset")) { return "s:" + jObj["name"]; } return null; } if (obj is double) { return "n:" + ((double)obj).ToString("R", CultureInfo.InvariantCulture); } if (obj is bool) { return "b:" + ((!(bool)obj) ? "false" : "true"); } if (!(obj is string text)) { return "null"; } if (text.StartsWith("$depth") || text.StartsWith("$cycle") || text == "<cycle>" || text.StartsWith("$error")) { return null; } return "s:" + text; } private static bool Same(string a, string b) { if (a == b) { return true; } if (a.StartsWith("n:") && b.StartsWith("n:")) { double num = double.Parse(a.Substring(2), CultureInfo.InvariantCulture); double num2 = double.Parse(b.Substring(2), CultureInfo.InvariantCulture); return Math.Abs(num - num2) <= 0.0001 * Math.Max(1.0, Math.Abs(num)); } return false; } private static object Show(string n) { if (n == "null") { return null; } if (n.StartsWith("n:")) { return double.Parse(n.Substring(2), CultureInfo.InvariantCulture); } if (n.StartsWith("b:")) { return n == "b:true"; } return n.Substring(2); } private JObj Location(object holder, bool room) { string text = Refl.S(Refl.Get(holder, "m_prefabName")); List<object> list = new List<object>(); try { GameObject val = null; if (text == null || room) { val = Registry.LoadSoft(holder, list, _locDiag); text = text ?? ((!Object.op_Implicit((Object)(object)val)) ? null : ((Object)val).name); } if (text == null) { return null; } string text2 = ((!room) ? "loc:" : "room:") + text; bool flag = _o.IsModKey(text2); if (!flag && !_opt.ScanVanillaLocations && !_opt.IncludeVanilla) { return null; } if (!Object.op_Implicit((Object)(object)val)) { val = Registry.LoadSoft(holder, list, _locDiag); } if (Object.op_Implicit((Object)(object)val)) { _locLoaded++; } else { _locFailed++; } if (Object.op_Implicit((Object)(object)val)) { _o.Inspect((Object)(object)val); } if (Object.op_Implicit((Object)(object)val) && _o.IsMod(val)) { flag = true; } JObj jObj = new JObj(); jObj.Add("location", text); JObj jObj2 = jObj; JArr source = ((!Object.op_Implicit((Object)(object)val)) ? new JArr() : _ix.ScanContainer(val, jObj2)); List<JObj> list2 = (from JObj f in source where (f["item"] is string && _o.IsModKey("prefab:" + f["item"])) || (f["creature"] is string && _o.IsModKey("prefab:" + f["creature"])) select f).ToList(); if (!flag && !_opt.IncludeVanilla && list2.Count == 0) { return null; } JObj jObj3 = new JObj(); jObj3["name"] = text; if (flag) { jObj3["mod"] = ModOfKey(text2) ?? _o.ModOf(val) ?? "unknown"; } if (Ser.Node(holder, 2) is JObj jObj4) { jObj4.Remove("m_prefab"); jObj3["meta"] = jObj4; } if (Object.op_Implicit((Object)(object)val)) { Component val2 = Refl.Comp(val, "Location"); if (Object.op_Implicit((Object)(object)val2)) { jObj3["location"] = Ser.Node(val2, 2); } } JArr jArr = new JArr(); foreach (JObj item in (!flag && !_opt.IncludeVanilla) ? list2 : source.Cast<JObj>()) { jArr.Add(item); } jObj3["contents"] = jArr; if (flag) { Content(ModOfKey(text2) ?? _o.ModOf(val) ?? "unknown").Arr((!room) ? "locations" : "dungeonRooms").Add(text); } return jObj3; } finally { foreach (object item2 in list) { try { Refl.Call(item2, "Release"); } catch { } } } } private void Icon(string key, string mod, string kind, string name, object sprite, int variant) { if (sprite == null) { return; } string relPath = "icons/" + Icons.SafeName(mod ?? "vanilla") + "/" + kind + "/" + Icons.SafeName(name) + ((variant <= 0) ? "" : ("_" + variant)) + ".png"; string text = _icons.Save(sprite, _opt.OutDir, relPath); if (text != null) { if (!_iconFiles.TryGetValue(key, out var value)) { value = (_iconFiles[key] = new JArr()); } value.Add(text); } } private void ExportIcons() { //IL_027a: Unknown result type (might be due to invalid IL or missing references) if (!_icons.Ready) { _errors.Add(new JObj { { "section", "icons" }, { "error", "Unity texture API not found" } }); return; } foreach (GameObject value2 in _r.Items.Values) { string key = "prefab:" + ((Object)value2).name; if (!InScope(key)) { continue; } int num = 0; foreach (object item in Refl.Enum(Refl.Get(Registry.Shared(value2), "m_icons"))) { Icon(key, ModOfKey(key), "items", ((Object)value2).name, item, num++); } } foreach (GameObject value3 in _r.Prefabs.Values) { string key2 = "prefab:" + ((Object)value3).name; if (InScope(key2)) { Component val = Refl.Comp(value3, "Piece"); if (Object.op_Implicit((Object)(object)val) && !_r.Items.ContainsKey(((Object)value3).name)) { Icon(key2, ModOfKey(key2), "pieces", ((Object)value3).name, Refl.Get(val, "m_icon"), 0); } Component val2 = Refl.Comp(value3, "CraftingStation"); if (Object.op_Implicit((Object)(object)val2) && !Object.op_Implicit((Object)(object)val)) { Icon(key2, ModOfKey(key2), "stations", ((Object)value3).name, Refl.Get(val2, "m_icon"), 0); } } } foreach (object statusEffect in _r.StatusEffects) { string key3 = Origin.KeyOf(statusEffect); if (InScope(key3)) { Icon(key3, ModOfKey(key3), "status", ((Object)statusEffect).name, Refl.Get(statusEffect, "m_icon"), 0); } } if (_r.Prefabs.TryGetValue("Player", out var value)) { foreach (object item2 in Refl.Enum(Refl.Get(Refl.Comp(value, "Skills"), "m_skills"))) { string text = Refl.S(Refl.Get(item2, "m_skill")); if (text != null && (_opt.IncludeVanilla || !IsVanillaSkill(text))) { Icon("skill:" + text, null, "skills", text, Refl.Get(item2, "m_icon"), 0); } } } foreach (ModEntry mod in _mods) { if (mod.Folder == null) { continue; } string text2 = Path.Combine(mod.Folder, "icon.png"); if (File.Exists(text2)) { string text3 = "icons/" + Icons.SafeName(mod.Guid) + "/mod_icon.png"; try { Directory.CreateDirectory(Path.GetDirectoryName(P(text3))); File.Copy(text2, P(text3), overwrite: true); _iconFiles["mod:" + mod.Guid] = new JArr { text3 }; } catch { } } } } private static bool IsVanillaSkill(string s) { Type type = Refl.T("Skills+SkillType"); return type != null && type.IsEnum && Enum.GetNames(type).Contains(s); } private JArr IconsOf(string key) { JArr value; return (!_iconFiles.TryGetValue(key, out value)) ? null : value; } private JArr QualityStats(object shared) { JArr jArr = new JArr(); int num = Math.Max(1, Refl.I(Refl.Get(shared, "m_maxQuality"), 1)); object obj = Refl.Get(shared, "m_damages"); object obj2 = Refl.Get(shared, "m_damagesPerLevel"); for (int i = 1; i <= num; i++) { JObj jObj = new JObj(); jObj.Add("quality", i); JObj jObj2 = jObj; if (obj != null) { JObj jObj3 = new JObj(); FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public); foreach (FieldInfo fieldInfo in fields) { if (!(fieldInfo.FieldType != typeof(float))) { float num2 = (float)fieldInfo.GetValue(obj) + ((obj2 != null) ? ((float)fieldInfo.GetValue(obj2)) : 0f) * (float)(i - 1); if ((double)Math.Abs(num2) > 1E-06) { jObj3[fieldInfo.Name.Substring(2)] = num2; } } } jObj2.Opt("damage", jObj3); } string[] perLevel = PerLevel; foreach (string text in perLevel) { string[] array = text.Split('|'); object obj3 = Refl.Get(shared, array[0]); if (obj3 != null) { float num3 = Refl.F(obj3) + Refl.F(Refl.Get(shared, array[1])) * (float)(i - 1); if ((double)Math.Abs(num3) > 1E-06) { jObj2[array[0].Substring(2)] = num3; } } } jArr.Add(jObj2); } return jArr; } private JArr RecipesFor(string item, int maxQ) { JArr jArr = new JArr(); if (!_ix.Sources.TryGetValue(item, out var value)) { return jArr; } foreach (JObj item2 in value) { if ((string)item2["type"] != "craft") { continue; } JObj jObj2 = new JObj(); foreach (KeyValuePair<string, object> item3 in item2) { jObj2[item3.Key] = item3.Value; } int num = Math.Max(1, Refl.I(item2["minStationLevel"], 1)); JArr jArr2 = new JArr(); for (int i = 1; i <= maxQ; i++) { JObj jObj3 = new JObj(); jObj3.Add("quality", i); jObj3.Add("stationLevel", num + i - 1); JObj jObj4 = jObj3; JArr jArr3 = new JArr(); foreach (JObj item4 in (JArr)item2["requirements"]) { int num2 = ((i > 1) ? ((i - 1) * Refl.I(item4["amountPerLevel"])) : Refl.I(item4["amount"])); if (num2 > 0) { jArr3.Add(new JObj { { "prefab", item4["prefab"] }, { "name", item4["name"] }, { "amount", num2 } }); } } jObj4["cost"] = jArr3; jArr2.Add(jObj4); } jObj2["perQuality"] = jArr2; jArr.Add(jObj2); } return jArr; } private JArr SourcesExceptCraft(string item) { JArr jArr = new JArr(); if (_ix.Sources.TryGetValue(item, out var value)) { foreach (JObj item2 in value) { if ((string)item2["type"] != "craft") { jArr.Add(item2); } } } return jArr; } private JArr Of(Dictionary<string, JArr> d, string k) { JArr value; return (!d.TryGetValue(k, out value)) ? new JArr() : value; } private void WriteItems() { JArr jArr = new JArr(); Dictionary<string, List<GameObject>> dictionary = new Dictionary<string, List<GameObject>>(); foreach (GameObject value3 in _r.Items.Values) { string text = Refl.S(Refl.Get(Registry.Shared(value3), "m_setName")); if (!string.IsNullOrEmpty(text)) { if (!dictionary.TryGetValue(text, out var value)) { value = (dictionary[text] = new List<GameObject>()); } value.Add(value3); } } foreach (GameObject value4 in _r.Items.Values) { string text2 = "prefab:" + ((Object)value4).name; if (!InScope(text2)) { continue; } object obj = Registry.Shared(value4); string text3 = Refl.S(Refl.Get(obj, "m_name")); JObj jObj = new JObj(); jObj["prefab"] = ((Object)value4).name; jObj["mod"] = ModOfKey(text2); jObj["modName"] = _o.ModName(ModOfKey(text2)); jObj["names"] = _loc.Names(text3); jObj.Opt("description", _loc.Names(Refl.S(Refl.Get(obj, "m_description")))); jObj["itemType"] = Refl.S(Refl.Get(obj, "m_itemType")); jObj.Opt("icons", IconsOf(text2)); int num = Math.Max(1, Refl.I(Refl.Get(obj, "m_maxQuality"), 1)); jObj["maxQuality"] = num; jObj["perQuality"] = QualityStats(obj); jObj.Opt("recipes", RecipesFor(((Object)value4).name, num)); jObj.Opt("obtain", SourcesExceptCraft(((Object)value4).name)); jObj.Opt("usedIn", Of(_ix.Uses, ((Object)value4).name)); string text4 = Refl.S(Refl.Get(obj, "m_setName")); if (!string.IsNullOrEmpty(text4)) { JObj jObj2 = new JObj(); jObj2.Add("name", text4); jObj2.Add("size", Refl.I(Refl.Get(obj, "m_setSize"))); JObj jObj3 = jObj2; jObj3.Opt("effect", Refl.UName(Refl.Get(obj, "m_setStatusEffect"))); JArr jArr2 = new JArr(); foreach (GameObject item in dictionary[text4]) { jArr2.Add(_ix.Who(item)); } jObj3["members"] = jArr2; jObj["set"] = jObj3; } JObj jObj4 = new JObj(); string[] array = new string[4] { "m_consumeStatusEffect", "m_equipStatusEffect", "m_setStatusEffect", "m_attackStatusEffect" }; foreach (string text5 in array) { jObj4.Opt(text5.Substring(2), Refl.UName(Refl.Get(obj, text5))); } jObj.Opt("statusEffects", jObj4); if (_tooltips.TryGetValue("item:" + ((Object)value4).name, out var value2)) { jObj["tooltips"] = LocalizedTips(value2); } jObj.Opt("referencedBy", Of(_ix.Refs, text2)); jObj["origin"] = _o.Get(text2).ToJson(); jObj["shared"] = Ser.Node(obj, 5); JObj jObj5 = new JObj(); Component[] components = value4.GetComponents(typeof(MonoBehaviour)); foreach (Component val in components) { string name = ((object)val).GetType().Name; switch (name) { case "ItemDrop": case "ZNetView": case "ZSyncTransform": continue; } if (!((object)val).GetType().Assembly.GetName().Name.StartsWith("Unity")) { jObj5[name] = Ser.Node(val, 3); } } jObj.Opt("components", jObj5); Track(text2, "items", ((Object)value4).name, text3); jArr.Add(jObj); } Json.WriteFile(P("items.json"), jArr, pretty: false); _manifest.Obj("counts")["items"] = jArr.Count; } private void WritePieces() { JArr jArr = new JArr(); Dictionary<string, JArr> dictionary = new Dictionary<string, JArr>(); foreach (KeyValuePair<string, JArr> source in _ix.Sources) { foreach (JObj item in source.Value) { if ((string)item["type"] != "craft") { continue; } string text = ((item["station"] is JObj jObj2) ? (jObj2["prefab"] as string) : null); if (text != null) { if (!dictionary.TryGetValue(text, out var value)) { value = (dictionary[text] = new JArr()); } value.Add(new JObj { { "item", source.Key }, { "recipe", item["recipe"] }, { "minStationLevel", item["minStationLevel"] } }); } } } Dictionary<string, JArr> dictionary2 = new Dictionary<string, JArr>(); foreach (GameObject value6 in _r.Prefabs.Values) { Component o = Refl.Comp(value6, "StationExtension"); string text2 = Refl.UName(Refl.Get(o, "m_craftingStation")); if (text2 != null) { if (!dictionary2.TryGetValue(text2, out var value2)) { value2 = (dictionary2[text2] = new JArr()); } value2.Add(_ix.Who(value6)); } } foreach (GameObject value7 in _r.Prefabs.Values) { Component val = Refl.Comp(value7, "Piece"); if (!Object.op_Implicit((Object)(object)val) || _r.Items.ContainsKey(((Object)value7).name)) { continue; } string text3 = "prefab:" + ((Object)value7).name; bool flag = Refl.Enum(Refl.Get(val, "m_resources")).Any((object q) => _o.IsMod(Refl.Get(q, "m_resItem"))); bool flag2 = dictionary.ContainsKey(((Object)value7).name) && dictionary[((Object)value7).name].Cast<JObj>().Any((JObj x) => _o.IsModKey("prefab:" + x["item"])); if (!InScope(text3) && !flag && !flag2) { continue; } string text4 = Refl.S(Refl.Get(val, "m_name")); JObj jObj3 = new JObj(); jObj3["prefab"] = ((Object)value7).name; jObj3["mod"] = ModOfKey(text3); jObj3["modName"] = _o.ModName(ModOfKey(text3)); if (!InScope(text3)) { jObj3["vanillaWithModdedLinks"] = true; } jObj3["names"] = _loc.Names(text4); jObj3.Opt("description", _loc.Names(Refl.S(Refl.Get(val, "m_description")))); jObj3.Opt("icons", IconsOf(text3)); if (_r.PieceTools.TryGetValue(((Object)value7).name, out var value3)) { JArr jArr4 = new JArr(); foreach (string item2 in value3) { jArr4.Add(_ix.Who(_r.Prefabs[item2])); } jObj3["builtWith"] = jArr4; } jObj3["category"] = Refl.S(Refl.Get(val, "m_category")); jObj3.Opt("station", _ix.Station(Refl.Get(val, "m_craftingStation"))); jObj3["requirements"] = DataIndex.Requirements(Refl.Get(val, "m_resources"), _ix.Who); jObj3["comfort"] = Refl.I(Refl.Get(val, "m_comfort")); jObj3["comfortGroup"] = Refl.S(Refl.Get(val, "m_comfortGroup")); if (dictionary.TryGetValue(((Object)value7).name, out var value4)) { jObj3["craftsHere"] = value4; } if (dictionary2.TryGetValue(((Object)value7).name, out var value5)) { jObj3["extensions"] = value5; } jObj3.Opt("obtain", SourcesExceptCraft(((Object)value7).name)); jObj3.Opt("referencedBy", Of(_ix.Refs, text3)); jObj3["origin"] = _o.Get(text3).ToJson(); JObj jObj4 = new JObj(); Component[] components = value7.GetComponents(typeof(MonoBehaviour)); foreach (Component val2 in components) { string name = ((object)val2).GetType().Name; if (!(name == "ZNetView") && !((object)val2).GetType().Assembly.GetName().Name.StartsWith("Unity")) { jObj4[name] = Ser.Node(val2, 3); } } jObj3["components"] = jObj4; if (InScope(text3)) { Track(text3, "pieces", ((Object)value7).name, text4); } jArr.Add(jObj3); } Json.WriteFile(P("pieces.json"), jArr, pretty: false); _manifest.Obj("counts")["pieces"] = jArr.Count; } private void WriteCreatures() { JArr jArr = new JArr(); foreach (GameObject value2 in _r.Prefabs.Values) { Component val = Refl.Comp(value2, "Character"); if (!Object.op_Implicit((Object)(object)val)) { continue; } string text = "prefab:" + ((Object)value2).name; bool flag = Refl.Enum(Refl.Get(Refl.Comp(value2, "CharacterDrop"), "m_drops")).Any((object d) => _o.IsMod(Refl.Get(d, "m_prefab"))); bool flag2 = Refl.Enum(Refl.Get(Refl.Comp(value2, "MonsterAI"), "m_consumeItems")).Any((object i) => _o.IsMod(i)); if ((!InScope(text) && !flag && !flag2) || ((Object)value2).name == "Player") { continue; } string text2 = Refl.S(Refl.Get(val, "m_name")); JObj jObj = new JObj(); jObj["prefab"] = ((Object)value2).name; jObj["mod"] = ModOfKey(text); jObj["modName"] = _o.ModName(ModOfKey(text)); if (!InScope(text)) { jObj["vanillaWithModdedLinks"] = true; } jObj["names"] = _loc.Names(text2); jObj["health"] = Refl.F(Refl.Get(val, "m_health")); jObj["faction"] = Refl.S(Refl.Get(val, "m_faction")); jObj["boss"] = Refl.B(Refl.Get(val, "m_boss")); jObj.Opt("bossEvent", Refl.S(Refl.Get(val, "m_bossEvent"))); jObj.Opt("defeatSetGlobalKey", Refl.S(Refl.Get(val, "m_defeatSetGlobalKey"))); jObj["damageModifiers"] = Ser.Node(Refl.Get(val, "m_damageModifiers"), 2); Component val2 = Refl.Comp(value2, "Humanoid"); if (Object.op_Implicit((Object)(object)val2)) { JArr jArr2 = new JArr(); string[] array = new string[4] { "m_defaultItems", "m_randomWeapon", "m_randomArmor", "m_randomShield" }; foreach (string text3 in array) { foreach (object item in Refl.Enum(Refl.Get(val2, text3))) { GameObject val3 = (GameObject)((item is GameObject) ? item : null); if (Object.op_Implicit((Object)(object)val3)) { object obj = Registry.Shared(val3); JObj jObj2 = new JObj(); jObj2.Add("slot", text3.Substring(2)); jObj2.Add("prefab", ((Object)val3).name); JObj jObj3 = jObj2; jObj3.Opt("names", _loc.Names(Refl.S(Refl.Get(obj, "m_name")))); jObj3["itemType"] = Refl.S(Refl.Get(obj, "m_itemType")); jObj3.Opt("damage", QualityStats(obj)[0]); jObj3["attack"] = Ser.Node(Refl.Get(obj, "m_attack"), 2); jArr2.Add(jObj3); } } } foreach (object item2 in Refl.Enum(Refl.Get(val2, "m_randomSets"))) { JArr jArr3 = new JArr(); foreach (object item3 in Refl.Enum(Refl.Get(item2, "m_items"))) { jArr3.Add(Refl.UName(item3)); } jArr2.Add(new JObj { { "slot", "randomSet" }, { "items", jArr3 } }); } jObj.Opt("equipmentAndAttacks", jArr2); } JArr jArr4 = new JArr(); foreach (KeyValuePair<string, JArr> source in _ix.Sources) { foreach (JObj item4 in source.Value) { if (!((string)item4["type"] == "creatureDrop") || !(item4["from"] is JObj) || !((string)((JObj)item4["from"])["prefab"] == ((Object)value2).name)) { continue; } JObj jObj2 = new JObj(); jObj2.Add("item", source.Key); JObj jObj5 = jObj2; if (_r.Items.TryGetValue(source.Key, out var value)) { jObj5["names"] = _loc.Names(Refl.S(Refl.Get(Registry.Shared(value), "m_name"))); } foreach (KeyValuePair<string, object> item5 in item4) { if (item5.Key != "type" && item5.Key != "from" && item5.Key != "component") { jObj5[item5.Key] = item5.Value; } } jArr4.Add(jObj5); } } jObj.Opt("drops", jArr4); jObj.Opt("spawns", Of(_ix.Spawns, ((Object)value2).name)); string[] array2 = new string[6] { "MonsterAI", "AnimalAI", "Tameable", "Procreation", "Growup", "Saddle" }; foreach (string text4 in array2) { Component val4 = Refl.Comp(value2, text4); if (Object.op_Implicit((Object)(object)val4)) { jObj[text4] = Ser.Node(val4, 2); } } List<object> list = Refl.Enum(Refl.Get(Refl.Comp(value2, "MonsterAI"), "m_consumeItems")).Select((Func<object, object>)((object x) => _ix.Who(x))).ToList(); if (list.Count > 0) { JArr jArr5 = new JArr(); jArr5.AddRange(list); jObj["eats"] = jArr5; } jObj.Opt("referencedBy", Of(_ix.Refs, text)); jObj["origin"] = _o.Get(text).ToJson(); jObj["character"] = Ser.Node(val, 3); if (InScope(text)) { Track(text, "creatures", ((Object)value2).name, text2); } jArr.Add(jObj); } Json.WriteFile(P("creatures.json"), jArr, pretty: false); _manifest.Obj("counts")["creatures"] = jArr.Count; } private void WriteStatusEffects() { //IL_012e: Unknown result type (might be due to invalid IL or missing references) Dictionary<string, JArr> dictionary = new Dictionary<string, JArr>(); foreach (GameObject value4 in _r.Items.Values) { object o = Registry.Shared(value4); string[] array = new string[4] { "m_consumeStatusEffect", "m_equipStatusEffect", "m_setStatusEffect", "m_attackStatusEffect" }; foreach (string text in array) { string text2 = Refl.UName(Refl.Get(o, text)); if (text2 != null) { if (!dictionary.TryGetValue(text2, out var value)) { value = (dictionary[text2] = new JArr()); } JObj jObj = _ix.Who(value4); jObj["as"] = text.Substring(2); value.Add(jObj); } } } JArr jArr2 = new JArr(); foreach (object statusEffect in _r.StatusEffects) { string text3 = Origin.KeyOf(statusEffect); string name = ((Object)statusEffect).name; if (InScope(text3) || (dictionary.ContainsKey(name) && dictionary[name].Cast<JObj>().Any((JObj u) => u["mod"] != null))) { string text4 = Refl.S(Refl.Get(statusEffect, "m_name")); JObj jObj2 = new JObj(); jObj2["name"] = name; jObj2["type"] = statusEffect.GetType().Name; jObj2["mod"] = ModOfKey(text3); jObj2["modName"] = _o.ModName(ModOfKey(text3)); jObj2.Opt("names", _loc.Names(text4)); jObj2.Opt("tooltipText", _loc.Names(Refl.S(Refl.Get(statusEffect, "m_tooltip")))); if (_tooltips.TryGetValue(text3, out var value2)) { jObj2["tooltips"] = LocalizedTips(value2); } jObj2.Opt("icons", IconsOf(text3)); if (dictionary.TryGetValue(name, out var value3)) { jObj2["usedBy"] = value3; } jObj2.Opt("referencedBy", Of(_ix.Refs, text3)); jObj2["origin"] = _o.Get(text3).ToJson(); jObj2["fields"] = Ser.Node(statusEffect, 3); if (InScope(text3)) { Track(text3, "statusEffects", name, text4); } jArr2.Add(jObj2); } } Json.WriteFile(P("status_effects.json"), jArr2, pretty: false); _manifest.Obj("counts")["statusEffects"] = jArr2.Count; } private void WriteRecipes() { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) JArr jArr = new JArr(); foreach (object recipe in _r.Recipes) { string key = Origin.KeyOf(recipe); object obj = Refl.Get(recipe, "m_item"); if (InScope(key) || _o.IsMod(obj) || _o.IsMod(Refl.Get(recipe, "m_craftingStation")) || Refl.Enum(Refl.Get(recipe, "m_resources")).Any((object q) => _o.IsMod(Refl.Get(q, "m_resItem")))) { JObj jObj = new JObj(); jObj["name"] = ((Object)recipe).name; jObj["mod"] = ModOfKey(key); jObj["modName"] = _o.ModName(ModOfKey(key)); jObj["result"] = ((obj != null) ? _ix.Who(obj) : null); jObj["amount"] = Refl.I(Refl.Get(recipe, "m_amount"), 1); jObj["enabled"] = Refl.B(Refl.Get(recipe, "m_enabled")); jObj.Opt("station", _ix.Station(Refl.Get(recipe, "m_craftingStation"))); jObj.Opt("repairStation", _ix.Station(Refl.Get(recipe, "m_repairStation"))); jObj["minStationLevel"] = Refl.I(Refl.Get(recipe, "m_minStationLevel"), 1); jObj["requireOnlyOneIngredient"] = Refl.B(Refl.Get(recipe, "m_requireOnlyOneIngredient")); jObj["requirements"] = DataIndex.Requirements(Refl.Get(recipe, "m_resources"), _ix.Who); jObj["origin"] = _o.Get(key).ToJson(); jObj["fields"] = Ser.Node(recipe, 2); if (InScope(key)) { Track(key, "recipes", jObj["name"] as string, null); } jArr.Add(jObj); } } Json.WriteFile(P("recipes.json"), jArr, pretty: false); _manifest.Obj("counts")["recipes"] = jArr.Count; } private void WriteWorld(JArr locations, JArr rooms) { JObj jObj = new JObj(); JObj jObj2 = new JObj(); foreach (KeyValuePair<string, JArr> spawn in _ix.Spawns) { string key = "prefab:" + spawn.Key; if (InScope(key)) { jObj2[spawn.Key] = spawn.Value; } } jObj["spawnsByCreature"] = jObj2; JArr jArr = new JArr(); foreach (object @event in _r.Events) { string text = Refl.S(Refl.Get(@event, "m_name")); string k = "event:" + text; bool flag = _o.IsModKey(k); bool flag2 = Refl.Enum(Refl.Get(@event, "m_spawn")).Any((object sd) => _o.IsMod(Refl.Get(sd, "m_prefab"))); if (flag || flag2 || _opt.IncludeVanilla) { JObj jObj3 = new JObj(); jObj3.Add("name", text); jObj3.Add("modded", flag); jObj3.Add("involvesModdedCreatures", flag2); JObj jObj4 = jObj3; jObj4.Opt("startMessage", _loc.Names(Refl.S(Refl.Get(@event, "m_startMessage")))); jObj4.Opt("endMessage", _loc.Names(Refl.S(Refl.Get(@event, "m_endMessage")))); jObj4["fields"] = Ser.Node(@event, 3); jArr.Add(jObj4); } } jObj["events"] = jArr; jObj["locations"] = locations; jObj["dungeonRooms"] = rooms; Json.WriteFile(P("world.json"), jObj, pretty: false); _manifest.Obj("counts")["locations"] = locations.Count; _manifest.Obj("counts")["dungeonRooms"] = rooms.Count; _manifest.Obj("counts")["events"] = jArr.Count; } private void WriteVanillaLinks() { JArr jArr = new JArr(); foreach (GameObject value in _r.Items.Values) { string k = "prefab:" + ((Object)value).name; if (!_o.IsModKey(k)) { List<JObj> list = Of(_ix.Sources, ((Object)value).name).Cast<JObj>().Where(ModRecord).ToList(); List<JObj> list2 = Of(_ix.Uses, ((Object)value).name).Cast<JObj>().Where(ModRecord).ToList(); if (list.Count != 0 || list2.Count != 0) { JObj jObj = new JObj(); jObj.Add("prefab", ((Object)value).name); jObj.Add("names", _loc.Names(Refl.S(Refl.Get(Registry.Shared(value), "m_name")))); JObj jObj2 = jObj; JArr jArr2 = new JArr(); jArr2.AddRange(list.Cast<object>()); jObj2.Opt("newWaysToObtain", jArr2); JArr jArr3 = new JArr(); jArr3.AddRange(list2.Cast<object>()); jObj2.Opt("newUses", jArr3); jArr.Add(jObj2); } } } Json.WriteFile(P("vanilla_items_linked.json"), jArr, pretty: false); } private static bool ModRecord(JObj r) { if (r["mod"] != null) { return true; } foreach (KeyValuePair<string, object> item in r) { if (item.Value is JObj jObj && (jObj["mod"] != null || ModRecord(jObj))) { return true; } if (!(item.Value is JArr jArr)) { continue; } foreach (object item2 in jArr) { if (item2 is JObj && ModRecord((JObj)item2)) { return true; } } } return false; } private void WriteReferences() { JObj jObj = new JObj(); foreach (KeyValuePair<string, JArr> @ref in _ix.Refs) { jObj[@ref.Key] = @ref.Value; } Json.WriteFile(P("references.json"), jObj, pretty: false); } private void WriteRaw() { Dictionary<string, JObj> dictionary = new Dictionary<string, JObj>(); foreach (GameObject value2 in _r.Prefabs.Values) { string text = "prefab:" + ((Object)value2).name; if (!_o.IsModKey(text)) { continue; } string key = ModOfKey(text); if (!dictionary.TryGetValue(key, out var value)) { value = (dictionary[key] = new JObj()); } JObj jObj2 = new JObj(); Component[] componentsInChildren = value2.GetComponentsInChildren(typeof(MonoBehaviour), true); foreach (Component val in componentsInChildren) { if (Object.op_Implicit((Object)(object)val) && !((object)val).GetType().Assembly.GetName().Name.StartsWith("Unity")) { string text2 = ((object)val).GetType().Name + ((!((Object)(object)val.gameObject == (Object)(object)value2)) ? ("@" + ((Object)val.gameObject).name) : ""); int num = 2; string text3 = text2; while (jObj2.Has(text2)) { text2 = text3 + "#" + num++; } jObj2[text2] = Ser.Node(val, _opt.RawDepth); } } value[((Object)value2).name] = jObj2; } foreach (KeyValuePair<string, JObj> item in dictionary) { Json.WriteFile(P("raw", Icons.SafeName(item.Key) + ".json"), item.Value, pretty: false); } } private void WriteLocalization() { foreach (KeyValuePair<string, Dictionary<string, string>> table in _loc.Tables) { JObj jObj = new JObj(); foreach (KeyValuePair<string, string> item in table.Value.OrderBy<KeyValuePair<string, string>, string>((KeyValuePair<string, string> x) => x.Key, StringComparer.Ordinal)) { jObj[item.Key] = item.Value; } Json.WriteFile(P("localization", table.Key + ".json"), jObj, pretty: false); } JObj jObj2 = new JObj(); string text = ((!_loc.Languages.Contains("English")) ? _loc.Languages.FirstOrDefault() : "English"); foreach (KeyValuePair<string, HashSet<string>> modToken in _modTokens) { JObj jObj3 = new JObj(); foreach (string language in _loc.Languages) { JArr jArr = new JArr(); JArr jArr2 = new JArr(); foreach (string item2 in modToken.Value.OrderBy((string x) => x)) { string text2 = _loc.Text("$" + item2, language); if (text2 == null) { jArr.Add(item2); } else if (language != text && text2 == _loc.Text("$" + item2, text)) { jArr2.Add(item2); } } JObj jObj4 = new JObj(); jObj4.Opt("noText", jArr); jObj4.Opt("sameAsEnglish", jArr2); jObj3.Opt(language, jObj4); } jObj2.Opt(modToken.Key, jObj3); JObj jObj5 = new JObj(); foreach (string item3 in modToken.Value.OrderBy((string x) => x)) { JObj jObj6 = new JObj(); JObj jObj7 = new JObj(); foreach (string language2 in _loc.Languages) { jObj6[language2] = _loc.Word(item3, language2, out var source); jObj7[language2] = source; } jObj6["source"] = jObj7; jObj5[item3] = jObj6; } Json.WriteFile(P("localization", "mod_" + Icons.SafeName(modToken.Key) + ".json"), jObj5, pretty: false); } Json.WriteFile(P("localization", "missing_translations.json"), jObj2, pretty: true); } private void WriteOrigin(JObj jotunn, JObj statics) { JObj jObj = new JObj(); jObj["note"] = "status: mod | vanilla_replaced. Signals: jotunn/manager = registered by that mod (exact); bundle = asset ships in that mod's AssetBundle; runtime-clone = created at runtime (owner may be unknown); not-in-vanilla-baseline = absent from the unmodded game; static = owner hint only."; jObj["jotunn"] = jotunn; jObj["managerLibraries"] = statics; jObj["bundles"] = _o.Bundles; JObj jObj2 = new JObj(); foreach (OriginInfo item in (from x in _o.All() where x.IsMod select x).OrderBy<OriginInfo, string>((OriginInfo x) => x.Key, StringComparer.Ordinal)) { jObj2[item.Key] = item.ToJson(); } jObj["modded"] = jObj2; JArr jArr = new JArr(); jArr.AddRange(_r.DuplicatePrefabs.Cast<object>()); jObj.Opt("duplicatePrefabNames", jArr); Json.WriteFile(P("origin.json"), jObj, pretty: false); } private void WriteMods() { Dictionary<string, JArr> dictionary = HarmonyOwners(); JArr jArr = new JArr(); foreach (ModEntry item in _mods.OrderBy((ModEntry x) => x.Name)) { JObj jObj = new JObj(); jObj["guid"] = item.Guid; jObj["name"] = item.Name; jObj["version"] = item.Version; jObj["folder"] = item.FolderName; jObj["dll"] = ((item.DllPath != null) ? Path.GetFileName(item.DllPath) : null); jObj.Opt("icon", IconsOf("mod:" + item.Guid)); if (item.Folder != null) { string path = Path.Combine(item.Folder, "manifest.json"); if (File.Exists(path)) { try { jObj["thunderstore"] = JsonParse.Parse(File.ReadAllText(path)); } catch { jObj["thunderstore"] = File.ReadAllText(path); } } string path2 = Path.Combine(item.Folder, "README.md"); if (File.Exists(path2)) { try { jObj["readme"] = File.ReadAllText(path2); } catch { } } string path3 = Path.Combine(item.Folder, "CHANGELOG.md"); if (File.Exists(path3)) { try { jObj["changelog"] = File.ReadAllText(path3); } catch { } } } jObj.Opt("config", ConfigOf(item)); JArr jArr2 = new JArr(); jArr2.AddRange(item.BundleNames.Cast<object>()); jObj.Opt("assetBundles", jArr2); if (dictionary.TryGetValue(item.Guid, out var value)) { jObj["harmonyPatches"] = value; } if (_modContent.TryGetValue(item.Guid, out var value2)) { jObj["content"] = value2; } if (_opt.ModStatics && item.Asm != null && item.Guid != _opt.SelfGuid) { jObj.Opt("staticData", Statics(item)); } jArr.Add(jObj); } if (_modContent.TryGetValue("unknown", out var value3)) { jArr.Add(new JObj { { "guid", "unknown" }, { "name", "(modded, owner not determinable)" }, { "content", value3 } }); } JArr jArr3 = new JArr(); foreach (KeyValuePair<string, JArr> kv in dictionary) { if (!_mods.Any((ModEntry m) => m.Guid == kv.Key)) { jArr3.Add(new JObj { { "owner", kv.Key }, { "patches", kv.Value } }); } } Json.WriteFile(P("mods.json"), new JObj { { "mods", jArr }, { "otherHarmonyOwners", jArr3 } }, pretty: true); foreach (KeyValuePair<string, JObj> item2 in _modContent) { Json.WriteFile(P("mods", Icons.SafeName(item2.Key) + ".json"), item2.Value, pretty: true); } } private JArr ConfigOf(ModEntry m) { JArr jArr = new JArr(); object v = Refl.Get(m.Instance, "Config"); foreach (object item in Refl.Enum(v)) { object o = Refl.Get(item, "Key"); object obj = Refl.Get(item, "Value"); if (obj != null) { object o2 = Refl.Get(obj, "Description"); JObj jObj = new JObj(); jObj.Add("section", Refl.S(Refl.Get(o, "Section"))); jObj.Add("key", Refl.S(Refl.Get(o, "Key"))); jObj.Add("value", Ser.Node(Refl.Get(obj, "BoxedValue"), 1)); jObj.Add("default", Ser.Node(Refl.Get(obj, "DefaultValue"), 1)); jObj.Add("type", (!(Refl.Get(obj, "SettingType") as Type == null)) ? ((Type)Refl.Get(obj, "SettingType")).Name : null); jObj.Add("description", Refl.S(Refl.Get(o2, "Description"))); JObj jObj2 = jObj; object obj2 = Refl.Get(o2, "AcceptableValues"); if (obj2 != null) { jObj2["acceptable"] = Refl.S(Refl.Call(obj2, "ToDescriptionString")); } jArr.Add(jObj2); } } return jArr; } private Dictionary<string, JArr> HarmonyOwners() { Dictionary<string, JArr> dictionary = new Dictionary<string, JArr>(); Type type = Refl.T("HarmonyLib.Harmony"); if (type == null) { return dictionary; } object v = Refl.Invoke(type, null, "GetAllPatchedMethods", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, new object[0]); foreach (object item in Refl.Enum(v)) { object obj = Refl.Invoke(type, null, "GetPatchInfo", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, new object[1] { item }); if (obj == null) { continue; } MethodBase methodBase = item as MethodBase; string v2 = ((!(methodBase == null)) ? (((!(methodBase.DeclaringType == null)) ? methodBase.DeclaringType.FullName : "") + "." + methodBase.Name) : Refl.S(item)); string[] array = new string[4] { "Prefixes", "Postfixes", "Transpilers", "Finalizers" }; foreach (string text in array) { foreach (object item2 in Refl.Enum(Refl.Get(obj, text))) { string key = Refl.S(Refl.Get(item2, "owner")) ?? "?"; if (!dictionary.TryGetValue(key, out var value)) { value = (dictionary[key] = new JArr()); } value.Add(new JObj { { "target", v2 }, { "kind", text.TrimEnd('s').Replace("Prefixe", "Prefix") } }); } } } return dictionary; } private JObj Statics(ModEntry m) { JObj jObj = new JObj(); Type[] array; try { array = m.Asm.GetTypes(); } catch (ReflectionTypeLoadException ex) { array = ex.Types.Where((Type x) => x != null).ToArray(); } catch { return jObj; } int num = 400; int maxList = Ser.MaxList; Ser.MaxList = 300; try { Type[] array2 = array; foreach (Type type in array2) { if (type.IsGenericTypeDefinition || type.Name.StartsWith("<")) { continue; } string text = type.Namespace ?? ""; if (!Origin.SafeStatics(type, m, text.EndsWith("Manager")) || text.StartsWith("ServerSync") || text.StartsWith("Microsoft") || text.StartsWith("System") || text.StartsWith("YamlDotNet") || text.StartsWith("Newtonsoft")) { continue; } FieldInfo[] fields; try { fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } catch { continue; } FieldInfo[] array3 = fields; foreach (FieldInfo fieldInfo in array3) { if (num <= 0) { return jObj; } if (fieldInfo.IsLiteral || fieldInfo.Name.StartsWith("<") || typeof(Delegate).IsAssignableFrom(fieldInfo.FieldType) || typeof(Object).IsAssignableFrom(fieldInfo.FieldType)) { continue; } string text2 = fieldInfo.FieldType.Namespace ?? ""; if ((text2.StartsWith("System") && !fieldInfo.FieldType.IsPrimitive && fieldInfo.FieldType != typeof(string) && !fieldInfo.FieldType.IsEnum && !typeof(IEnumerable).IsAssignableFrom(fieldInfo.FieldType)) || (fieldInfo.FieldType.FullName != null && (fieldInfo.FieldType.FullName.StartsWith("BepInEx") || fieldInfo.FieldType.FullName.StartsWith("HarmonyLib")))) { continue; } object value; try { value = fieldInfo.GetValue(null); } catch { continue; } if (value != null) { object obj4; try { obj4 = Ser.Node(value, 0, 3, new HashSet<object>(RefEq.I), privateToo: true); } catch { continue; } if (obj4 != null && (!(obj4 is JArr) || ((JArr)obj4).Count != 0) && (!(obj4 is JObj) || ((JObj)obj4).Count != 0)) { jObj[type.FullName + "." + fieldInfo.Name] = obj4; num--; } } } } return jObj; } finally { Ser.MaxList = maxList; } } } internal sealed class Registry { public readonly Dictionary<string, GameObject> Prefabs = new Dictionary<string, GameObject>(); public readonly List<string> DuplicatePrefabs = new List<string>(); public readonly HashSet<string> Networked = new HashSet<string>(); public readonly Dictionary<string, GameObject> Items = new Dictionary<string, GameObject>(); public readonly List<object> Recipes = new List<object>(); public readonly List<object> StatusEffects = new List<object>(); public readonly List<object> Locations = new List<object>(); public readonly List<object> Rooms = new List<object>(); public readonly List<object> SpawnLists = new List<object>(); public readonly List<object> Events = new List<object>(); public readonly Dictionary<string, List<string>> PieceTools = new Dictionary<string, List<string>>(); public readonly List<string> Problems = new List<string>(); public static Registry Collect() { //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Expected O, but got Unknown //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Expected O, but got Unknown Registry registry = new Registry(); object obj = Refl.Singleton("ZNetScene"); object obj2 = Refl.Singleton("ObjectDB"); if (obj == null) { registry.Problems.Add("ZNetScene not ready"); } if (obj2 == null) { registry.Problems.Add("ObjectDB not ready"); } foreach (object item in Refl.Enum(Refl.Get(obj, "m_prefabs"))) { registry.AddPrefab((GameObject)((item is GameObject) ? item : null)); } if (Refl.Get(obj, "m_namedPrefabs") is IDictionary dictionary) { foreach (object value2 in dictionary.Values) { registry.AddPrefab((GameObject)((value2 is GameObject) ? value2 : null)); } } foreach (string key in registry.Prefabs.Keys) { registry.Networked.Add(key); } foreach (object item2 in Refl.Enum(Refl.Get(obj2, "m_items"))) { GameObject val = (GameObject)((item2 is GameObject) ? item2 : null); if (Object.op_Implicit((Object)(object)val)) { if (!registry.Items.ContainsKey(((Object)val).name)) { registry.Items[((Object)val).name] = val; } if (!registry.Prefabs.ContainsKey(((Object)val).name)) { registry.Prefabs[((Object)val).name] = val; } } } foreach (GameObject value3 in registry.Prefabs.Values) { if (!registry.Items.ContainsKey(((Object)value3).name) && Object.op_Implicit((Object)(object)Refl.Comp(value3, "ItemDrop"))) { registry.Items[((Object)value3).name] = value3; } } foreach (object item3 in Refl.Enum(Refl.Get(obj2, "m_recipes"))) { if (item3 is Object && Object.op_Implicit((Object)item3)) { registry.Recipes.Add(item3); } } foreach (object item4 in Refl.Enum(Refl.Get(obj2, "m_StatusEffects"))) { if (item4 is Object && Object.op_Implicit((Object)item4)) { registry.StatusEffects.Add(item4); } } foreach (GameObject value4 in registry.Items.Values) { object o = Refl.Get(Shared(value4), "m_buildPieces"); foreach (object item5 in Refl.Enum(Refl.Get(o, "m_pieces"))) { GameObject val2 = (GameObject)((item5 is GameObject) ? item5 : null); if (Object.op_Implicit((Object)(object)val2)) { if (!registry.PieceTools.TryGetValue(((Object)val2).name, out var value)) { value = (registry.PieceTools[((Object)val2).name] = new List<string>()); } if (!value.Contains(((Object)value4).name)) { value.Add(((Object)value4).name); } if (!registry.Prefabs.ContainsKey(((Object)val2).name)) { registry.Prefabs[((Object)val2).name] = val2; } } } } object o2 = Refl.Singleton("ZoneSystem"); foreach (object item6 in Refl.Enum(Refl.Get(o2, "m_locations"))) { if (item6 != null) { registry.Locations.Add(item6); } } object o3 = Refl.Singleton("DungeonDB"); object v = Refl.Get(o3, "m_rooms") ?? Refl.Call(o3, "GetRooms") ?? Refl.CallStatic("DungeonDB", "GetRooms"); foreach (object item7 in Refl.Enum(v)) { if (item7 != null) { registry.Rooms.Add(item7); } } HashSet<object> hashSet = new HashSet<object>(RefEq.I); Type type = Refl.T("SpawnSystemList"); if (type != null) { foreach (object item8 in FindAll(type)) { if (hashSet.Add(item8)) { registry.SpawnLists.Add(item8); } } foreach (GameObject value5 in registry.Prefabs.Values) { Component[] array = Refl.Comps(value5, "SpawnSystem", children: true); foreach (Component o4 in array) { foreach (object item9 in Refl.Enum(Refl.Get(o4, "m_spawnLists"))) { if (item9 != null && hashSet.Add(item9)) { registry.SpawnLists.Add(item9); } } } } } object o5 = Refl.Singleton("RandEventSystem"); foreach (object item10 in Refl.Enum(Refl.Get(o5, "m_events"))) { if (item10 != null) { registry.Events.Add(item10); } } return registry; } private void AddPrefab(GameObject go) { if (!Object.op_Implicit((Object)(object)go)) { return; } if (Prefabs.TryGetValue(((Object)go).name, out var value)) { if (!object.ReferenceEquals(value, go) && !DuplicatePrefabs.Contains(((Object)go).name)) { DuplicatePrefabs.Add(((Object)go).name); } } else { Prefabs[((Object)go).name] = go; } } public static IEnumerable<object> FindAll(Type t) { Type type = Refl.T("UnityEngine.Resources"); object v = ((!(type == null)) ? Refl.Invoke(type, null, "FindObjectsOfTypeAll", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, new object[1] { t }) : null); return (from o in Refl.Enum(v) where o is Object && Object.op_Implicit((Object)o) select o).ToList(); } public static object ItemData(GameObject go) { return Refl.Get(Refl.Comp(go, "ItemDrop"), "m_itemData"); } public static object Shared(GameObject go) { return Refl.Get(ItemData(go), "m_shared"); } public static GameObject LoadSoft(object holder, List<object> toRelease, JObj diag = null) { object obj = Refl.Get(holder, "m_prefab"); GameObject val = Refl.GO(obj); if (Object.op_Implicit((Object)(object)val)) { return val; } if (obj == null) { if (diag != null) { diag["m_prefab"] = "null"; } return null; } try { Type type = obj.GetType(); if (diag != null && !diag.Has("type")) { diag["type"] = type.FullName; JArr jArr = new JArr(); MemberInfo[] members = type.GetMembers(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MemberInfo memberInfo in members) { if (!(memberInfo is ConstructorInfo) && !memberInfo.Name.StartsWith("<")) { jArr.Add(string.Concat(memberInfo.MemberType, " ", memberInfo.Name)); } } diag["members"] = jArr; } GameObject val2 = Refl.GO(Refl.Get(obj, "Asset")); if (Object.op_Implicit((Object)(object)val2)) { return val2; } MethodInfo methodInfo = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "Load" && m.GetParameters().Length == 0); if (methodInfo == null) { if (diag != null) { diag["error"] = "no Load()"; } return null; } methodInfo.Invoke(obj, null); toRelease.Add(obj); object obj2 = Refl.Get(obj, "Asset"); val = Refl.GO(obj2); if (!Object.op_Implicit((Object)(object)val) && diag != null) { diag["error"] = "Asset after Load(): " + ((obj2 != null) ? obj2.GetType().Name : "null"); } return val; } catch (Exception ex) { if (diag != null) { diag["error"] = (ex.InnerException ?? ex).GetType().Name + ": " + (ex.InnerException ?? ex).Message; } return null; } } } internal sealed class Loc { public readonly Dictionary<string, Dictionary<string, string>> Tables = new Dictionary<string, Dictionary<string, string>>(); public readonly List<string> Languages = new List<string>(); public string Original; private static readonly Regex Token = new Regex("\\$[A-Za-z0-9_]+", RegexOptions.Compiled); public readonly Dictionary<string, Dictionary<string, string>> Resolved = new Dictionary<string, Dictionary<string, string>>(); public ModTexts Mod; public static string Current() { return Refl.Call(Refl.Singleton("Localization"), "GetSelectedLanguage") as string; } public static bool Switch(string lang) { object obj = Refl.Call(Refl.Singleton("Localization"), "SetupLanguage", lang); return !(obj is bool) || (bool)obj; } public string Word(string token, string lang, out string source) { source = null; string source2 = null; string text = ((Mod != null) ? Mod.Get(lang, token, out source2) : null); if (text != null && source2.StartsWith("config:")) { source = source2; return text; } if (Resolved.TryGetValue(lang, out var value) && value.TryGetValue(token, out var value2) && value2 != null) { source = "game"; return value2; } if (text != null) { source = source2; return text; } if (Tables.TryGetValue(lang, out value) && value.TryGetValue(token, out value2) && value2 != null) { source = "vanilla"; return value2; } return null; } public static string GameLocalize(string token) { object obj = Refl.Singleton("Localization"); if (obj == null) { return null; } string text = Refl.Call(obj, "Localize", "$" + token) as string; if (string.IsNullOrEmpty(text) || text == "$" + token || text == token || text == "[" + token + "]" || text == "[$" + token + "]") { return null; } return text; } public void ResolveTokens(string lang, IEnumerable<string> tokens) { if (!Resolved.TryGetValue(lang, out var value)) { value = (Resolved[lang] = new Dictionary<string, string>()); } foreach (string token in tokens) { if (!value.ContainsKey(token)) { value[token] = GameLocalize(token); } } } public static string LocalizeText(string text) { if (string.IsNullOrEmpty(text)) { return text; } object obj = Refl.Singleton("Localization"); return (obj != null) ? ((Refl.Call(obj, "Localize", text) as string) ?? text) : text; } public void Capture(string lang) { Dictionary<string, string> dictionary = new Dictionary<string, string>(); if (Refl.Get(Refl.Singleton("Localization"), "m_translations") is IDictionary dictionary2) { foreach (DictionaryEntry item in dictionary2) { if (item.Key != null) { dictionary[item.Key.ToString()] = ((item.Value != null) ? item.Value.ToString() : null); } } } Tables[lang] = dictionary; if (!Languages.Contains(lang)) { Languages.Add(lang); } } public string Text(string raw, string lang) { if (string.IsNullOrEmpty(raw)) { return null; } if (!Languages.Contains(lang)) { return null; } bool any = false; string text = Token.Replace(raw, delegate(Match m) { string source; string text2 = Word(m.Value.Substring(1), lang, out source); if (text2 != null) { any = true; return text2; } return m.Value; }); if (!raw.Contains("$")) { return raw; } return (!any) ? null : text; } public JObj Names(string raw) { if (string.IsNullOrEmpty(raw)) { return null; } JObj jObj = new JObj(); jObj["token"] = raw; foreach (string language in Languages) { jObj[language] = Text(raw, language); } return jObj; } public IEnumerable<string> Tokens(string raw) { if (string.IsNullOrEmpty(raw)) { yield break; } IEnumerator enumerator = Token.Matches(raw).GetEnumerator(); try { while (enumerator.MoveNext()) { Match m = (Match)enumerator.Current; yield return m.Value.Substring(1); } } finally { IDisposable disposable2; IDisposable disposable = (disposable2 = enumerator as IDisposable); if (disposable2 != null) { disposable.Dispose(); } } } } internal sealed class Icons : IDisposable { private readonly Type _tSprite; private readonly Type _tTex2D; private readonly Type _tRT; private readonly Type _tRTFmt; private readonly Type _tRTRW; private readonly Type _tTexFmt; private readonly Type _tRect; private readonly Type _tGraphics; private readonly Type _tImgConv; private readonly Type _tObject; private readonly Type _tTexture; private readonly Type _tColor; private readonly string _mode; private readonly LinkedList<KeyValuePair<object, object>> _cache = new LinkedList<KeyValuePair<object, object>>(); private readonly Dictionary<string, string> _savedBySprite = new Dictionary<string, string>(); private bool _floatFailed; public int Saved; public int Failed; public int Reused; public string LastError; public bool Ready => _tSprite != null && _tTex2D != null && _tRT != null && _tGraphics != null && _tImgConv != null && _tRect != null && _tColor != null; private bool LinearRead => !_mode.Equals("sRGB", StringComparison.OrdinalIgnoreCase); private bool Convert => _mode.Equals("LinearToSRGB", StringComparison.OrdinalIgnoreCase); public Icons(string mode) { _mode = (mode ?? "LinearToSRGB").Trim(); _tSprite = Refl.T("UnityEngine.Sprite"); _tTex2D = Refl.T("UnityEngine.Texture2D"); _tTexture = Refl.T("UnityEngine.Texture"); _tRT = Refl.T("UnityEngine.RenderTexture"); _tRTFmt = Refl.T("UnityEngine.RenderTextureFormat"); _tRTRW = Refl.T("UnityEngine.RenderTextureReadWrite"); _tTexFmt = Refl.T("UnityEngine.TextureFormat"); _tRect = Refl.T("UnityEngine.Rect"); _tGraphics = Refl.T("UnityEngine.Graphics"); _tImgConv = Refl.T("UnityEngine.ImageConversion"); _tObject = Refl.T("UnityEngine.Object"); _tColor = Refl.T("UnityEngine.Color"); } private static object SCall(Type t, string name, Type[] sig, params object[] args) { MethodInfo method = t.GetMethod(name, BindingFlags.Static | BindingFlags.Public, null, sig, null); if (method == null) { throw new MissingMethodException(t.Name + "." + name); } return method.Invoke(null, args); } private static object ICall(object o, string name, Type[] sig, params object[] args) { MethodInfo method = o.GetType().GetMethod(name, BindingFlags.Instance | BindingFlags.Public, null, sig, null); if (method == null) { throw new MissingMethodException(o.GetType().Name + "." + name); } return method.Invoke(o, args); } private object Readable(object tex) { foreach (KeyValuePair<object, object> item in _cache) { if (object.ReferenceEquals(item.Key, tex)) { _cache.Remove(item); _cache.AddFirst(item); return item.Value; } } int w = Refl.I(Refl.Get(tex, "width")); int h = Refl.I(Refl.Get(tex, "height")); object obj = null; if (LinearRead && Convert && !_floatFailed) { try { obj = Blit(tex, w, h, "ARGBFloat", "RGBAFloat"); } catch { _floatFailed = true; } } if (obj == null) { obj = Blit(tex, w, h, "ARGB32", "RGBA32"); } _cache.AddFirst(new KeyValuePair<object, object>(tex, obj)); while (_cache.Count > 4) { Destroy(_cache.Last.Value.Value); _cache.RemoveLast(); } return obj; } private object Blit(object tex, int w, int h, string rtFormat, string texFormat) { object obj = Enum.Parse(_tRTRW, (!LinearRead) ? "sRGB" : "Linear"); object obj2 = SCall(_tRT, "GetTemporary", new Type[5] { typeof(int), typeof(int), typeof(int), _tRTFmt, _tRTRW }, w, h, 0, Enum.Parse(_tRTFmt, rtFormat), obj); PropertyInfo property = _tRT.GetProperty("active"); object value = property.GetValue(null, null); try { SCall(_tGraphics, "Blit", new Type[2] { _tTexture, _tRT }, tex, obj2); property.SetValue(null, obj2, null); object obj3 = Activator.CreateInstance(_tTex2D, w, h, Enum.Parse(_tTexFmt, texFormat), false, LinearRead); object obj4 = Activator.CreateInstance(_tRect, 0f, 0f, (float)w, (float)h); ICall(obj3, "ReadPixels", new Type[3] { _tRect, typeof(int), typeof(int) }, obj4, 0, 0); ICall(obj3, "Apply", Type.EmptyTypes); return obj3; } finally { property.SetValue(null, value, null); SCall(_tRT, "ReleaseTemporary", new Type[1] { _tRT }, obj2); } } private static float ToSrgb(float c) { if (c <= 0f) { return 0f; } if (c >= 1f) { return 1f; } return (!(c <= 0.0031308f)) ? (1.055f * (float)Math.Pow(c, 5.0 / 12.0) - 0.055f) : (c * 12.92f); } public string Save(object sprite, string outRoot, string relPath) { if (sprite == null || !_tSprite.IsInstanceOfType(sprite)) { return null; } Object val = (Object)((sprite is Object) ? sprite : null); if (object.ReferenceEquals(val, null) || !Object.op_Implicit(val)) { return null; } string key = val.GetInstanceID().ToString(); if (_savedBySprite.TryGetValue(key, out var value)) { Reused++; return value; } try { object obj = Refl.Get(sprite, "texture"); if (obj == null) { Failed++; LastError = "sprite has no texture"; return null; } object obj2 = null; try { obj2 = Refl.Get(sprite, "textureRect"); } catch { } if (obj2 == null) { obj2 = Refl.Get(sprite, "rect"); } int num = (int)Math.Round(Refl.F(Refl.Get(obj2, "x"))); int num2 = (int)Math.Round(Refl.F(Refl.Get(obj2, "y"))); int num3 = (int)Math.Round(Refl.F(Refl.Get(obj2, "width"))); int num4 = (int)Math.Round(Refl.F(Refl.Get(obj2, "height"))); if (num3 <= 0 || num4 <= 0) { Failed++; LastError = "empty sprite rect"; return null; } object o = Readable(obj); Array array = (Array)ICall(o, "GetPixels", new Type[5] { typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) }, num, num2, num3, num4, 0); if (Convert) { Color[] array2 = (Color[])array; for (int i = 0; i < array2.Length; i++) { array2[i].r = ToSrgb(array2[i].r); array2[i].g = ToSrgb(array2[i].g); array2[i].b = ToSrgb(array2[i].b); } } object obj4 = Activator.CreateInstance(_tTex2D, num3, num4, Enum.Parse(_tTexFmt, "RGBA32"), false, LinearRead); ICall(obj4, "SetPixels", new Type[1] { _tColor.MakeArrayType() }, array); ICall(obj4, "Apply", Type.EmptyTypes); byte[] bytes = (byte[])SCall(_tImgConv, "EncodeToPNG", new Type[1] { _tTex2D }, obj4); Destroy(obj4); string path = Path.Combine(outRoot, relPath.Replace('/', Path.DirectorySeparatorChar)); Directory.CreateDirectory(Path.GetDirectoryName(path)); File.WriteAllBytes(path, bytes); Saved++; _savedBySprite[key] = relPath; return relPath; } catch (Exception ex) { Failed++; Exception ex2 = ex.InnerException ?? ex; LastError = ex2.GetType().Name + ": " + ex2.Message; return null; } } private void Destroy(object o) { try { SCall(_tObject, "Destroy", new Type[1] { _tObject }, o); } catch { } } public void Dispose() { foreach (KeyValuePair<object, object> item in _cache) { Destroy(item.Value); } _cache.Clear(); } public static string SafeName(string s) { if (string.IsNullOrEmpty(s)) { return "_"; } char[] invalidFileNameChars = Path.GetInvalidFileNameChars(); foreach (char oldChar in invalidFileNameChars) { s = s.Replace(oldChar, '_'); } return s.Replace(' ', '_'); } } internal sealed class DataIndex { public readonly Dictionary<string, JArr> Sources = new Dictionary<string, JArr>(); public readonly Dictionary<string, JArr> Uses = new Dictionary<string, JArr>(); public readonly Dictionary<string, JArr> Spawns = new Dictionary<string, JArr>(); public readonly Dictionary<string, JArr> Refs = new Dictionary<string, JArr>(); private readonly Registry _r; private readonly Origin _o; private readonly Loc _loc; private static readonly string[] Interesting = new string[31] { "CharacterDrop", "Container", "Pickable", "PickableItem", "DropOnDestroyed", "MineRock", "MineRock5", "TreeBase", "TreeLog", "LootSpawner", "Destructible", "Beehive", "SapCollector", "Smelter", "CookingStation", "Fermenter", "Incinerator", "Trader", "Fireplace", "ShieldGenerator", "Turret", "MonsterAI", "OfferingBowl", "ItemStand", "Plant", "Fish", "SpawnArea", "CreatureSpawner", "Humanoid", "Procreation", "Growup" }; public DataIndex(Registry r, Origin o, Loc loc) { _r = r; _o = o; _loc = loc; } private static void Add(Dictionary<string, JArr> d, string key, JObj rec) { if (key != null) { if (!d.TryGetValue(key, out var value)) { value = (d[key] = new JArr()); } value.Add(rec); } } private string Mod(object o) { return _o.ModOf(o); } public JObj Who(object o) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) GameObject val = Refl.GO(o); JObj jObj = new JObj(); if (Object.op_Implicit((Object)(object)val)) { jObj["prefab"] = ((Object)val).name; } else if (o is Object) { jObj["object"] = ((Object)o).name; } string text = DisplayToken(val); if (text != null) { jObj["name"] = _loc.Names(text); } string text2 = Origin.KeyOf((!Object.op_Implicit((Object)(object)val)) ? o : val); if (text2 != null) { OriginInfo originInfo = _o.Get(text2); if (originInfo.IsMod) { jObj["mod"] = originInfo.Mod ?? "unknown"; } } return jObj; } public static string DisplayToken(GameObject go) { if (!Object.op_Implicit((Object)(object)go)) { return null; } string[][] array = new string[11][] { new string[2] { "Character", "m_name" }, new string[2] { "Piece", "m_name" }, new string[2] { "CraftingStation", "m_name" }, new string[2] { "Pickable", "m_overrideName" }, new string[2] { "Smelter", "m_name" }, new string[2] { "CookingStation", "m_name" }, new string[2] { "Trader", "m_name" }, new string[2] { "OfferingBowl", "m_name" }, new string[2] { "Container", "m_name" }, new string[2] { "MineRock", "m_name" }, new string[2] { "Location", "m_discoverLabel" } }; foreach (string[] array2 in array) { string text = Refl.S(Refl.Get(Refl.Comp(go, array2[0]), array2[1])); if (!string.IsNullOrEmpty(text)) { return text; } } object o = Registry.Shared(go); string text2 = Refl.S(Refl.Get(o, "m_name")); return (!string.IsNullOrEmpty(text2)) ? text2 : null; } private static string Name(object o) { return Refl.UName(o); } public static JArr Requirements(object reqs, Func<object, JObj> who) { JArr jArr = new JArr(); foreach (object item in Refl.Enum(reqs)) { object obj = Refl.Get(item, "m_resItem"); if (Name(obj) != null) { JObj jObj = who(obj); jObj["amount"] = Refl.I(Refl.Get(item, "m_amount")); jObj["amountPerLevel"] = Refl.I(Refl.Get(item, "m_amountPerLevel")); jObj["recover"] = Refl.B(Refl.Get(item, "m_recover")); object obj2 = Refl.Get(item, "m_extraAmountOnlyOneIngredient"); if (obj2 != null) { jObj["extraAmountOnlyOneIngredient"] = Refl.I(obj2); } jArr.Add(jObj); } } return jArr; } public JObj Station(object station) { if (Name(station) == null) { return null; } JObj jObj = Who(station); string text = Refl.S(Refl.Get(station, "m_name")); if (text != null) { jObj["name"] = _loc.Names(text); } return jObj; } public void BuildRecipes() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) foreach (object recipe in _r.Recipes) { object obj = Refl.Get(recipe, "m_item"); string text = Name(obj); JObj jObj = new JObj(); jObj["type"] = "craft"; jObj["recipe"] = ((Object)recipe).name; jObj["enabled"] = Refl.B(Refl.Get(recipe, "m_enabled")); jObj["amount"] = Refl.I(Refl.Get(recipe, "m_amount"), 1); jObj.Opt("station", Station(Refl.Get(recipe, "m_craftingStation"))); jObj.Opt("repairStation", Station(Refl.Get(recipe, "m_repairStation"))); jObj["minStationLevel"] = Refl.I(Refl.Get(recipe, "m_minStationLevel"), 1); jObj["requireOnlyOneIngredient"] = Refl.B(Refl.Get(recipe, "m_requireOnlyOneIngredient")); object obj2 = Refl.Get(recipe, "m_qualityResultAmountMultiplier"); if (obj2 != null) { jObj["qualityResultAmountMultiplier"] = Refl.F(obj2); } jObj["requirements"] = Requirements(Refl.Get(recipe, "m_resources"), Who); string key = Origin.KeyOf(recipe); OriginInfo originInfo = _o.Get(key); if (originInfo.IsMod) { jObj["mod"] = originInfo.Mod ?? "unknown"; } if (text != null) { Add(Sources, text, jObj); } foreach (object item in Refl.Enum(Refl.Get(recipe, "m_resources"))) { string text2 = Name(Refl.Get(item, "m_resItem")); if (text2 != null) { JObj jObj2 = new JObj(); jObj2.Add("type", "ingredient"); jObj2.Add("recipe", jObj["recipe"]); JObj jObj3 = jObj2; jObj3["result"] = ((obj != null) ? Who(obj) : null); jObj3["amount"] = Refl.I(Refl.Get(item, "m_amount")); jObj3["amountPerLevel"] = Refl.I(Refl.Get(item, "m_amountPerLevel")); jObj3.Opt("station", jObj["station"]); jObj3.Opt("mod", jObj["mod"]); Add(Uses, text2, jObj3); } } } foreach (GameObject value in _r.Prefabs.Values) { Component val = Refl.Comp(value, "Piece"); if (!Object.op_Implicit((Object)(object)val)) { continue; } foreach (object item2 in Refl.Enum(Refl.Get(val, "m_resources"))) { string text3 = Name(Refl.Get(item2, "m_resItem")); if (text3 != null) { JObj jObj2 = new JObj(); jObj2.Add("type", "buildMaterial"); jObj2.Add("piece", Who(value)); JObj jObj4 = jObj2; jObj4["amount"] = Refl.I(Refl.Get(item2, "m_amount")); jObj4["recover"] = Refl.B(Refl.Get(item2, "m_recover")); jObj4.Opt("station", Station(Refl.Get(val, "m_craftingStation"))); Add(Uses, text3, jObj4); } } } } public void BuildPrefabs() { foreach (GameObject value in _r.Prefabs.Values) { Scan(value, null, children: false, 1f); } } public JArr ScanContainer(GameObject root, JObj where) { JArr jArr = new JArr(); Scan(root, where, children: true, 1f, jArr); return jArr; } private void Scan(GameObject go, JObj where, bool children, float chance, JArr found = null) { if (!Object.op_Implicit((Object)(object)go)) { return; } string[] interesting = Interesting; foreach (string text in interesting) { Component[] array = Refl.Comps(go, text, children); foreach (Component val in array) { if (!Object.op_Implicit((Object)(object)val)) { continue; } GameObject gameObject = val.gameObject; float num = ((!children) ? 1f : RandomSpawnOdds(val, go)); JObj jObj = new JObj(); jObj["from"] = Who((where != null) ? gameObject : go); if (where != null) { jObj["in"] = where; jObj["object"] = ((Object)gameObject).name; if (num < 1f) { jObj["presenceChance"] = num; } } jObj["component"] = text; try { Handle(text, val, jObj, found); } catch (Exception ex) { jObj["error"] = ex.GetType().Name; } } } } private static float RandomSpawnOdds(Component c, GameObject root) { float num = 1f; Type type = Refl.T("RandomSpawn"); if (type == null) { return 1f; } Transform val = c.transform; while ((Object)(object)val != (Object)null) { Component component = ((Component)val).gameObject.GetComponent(type); if (Object.op_Implicit((Object)(object)component)) { num *= Mathf01(Refl.F(Refl.Get(component, "m_chance"), 100f) / 100f); } if (object.ReferenceEquals(((Component)val).gameObject, root)) { break; } val = val.parent; } return num; } private static float Mathf01(float v) { return (v < 0f) ? 0f : ((!(v > 1f)) ? v : 1f); } private JObj Clone(JObj ctx, string type) { JObj jObj = new JObj(); jObj.Add("type", type); JObj jObj2 = jObj; foreach (KeyValuePair<string, object> item in ctx) { jObj2[item.Key] = item.Value; } return jObj2; } private void Src(string item, JObj rec, JArr found) { if (item == null) { return; } Add(Sources, item, rec); if (found == null) { return; } JObj jObj = new JObj(); jObj.Add("item", item); JObj jObj2 = jObj; foreach (KeyValuePair<s