using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using FFU_Beyond_Reach; using LitJson; using Microsoft.CodeAnalysis; using MonoMod; using Ostranauts.Core; using Ostranauts.Core.Models; using Ostranauts.Tools; using Ostranauts.UI.Mods; using Ostranauts.Utils.Models; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } public class patch_JsonModInfo : JsonModInfo { public Dictionary removeIds { get; set; } public Dictionary> changesMap { get; set; } public string[] requiredAPIs { get; set; } public string[] requiredMods { get; set; } } public static class patch_DataHandler { public enum SyncArrayOp { None, Mod, Add, Ins, Del } public static Dictionary>> dictChangesMap; public static List listLockedCOs = new List(); [MonoModIgnore] public static Dictionary dictModInfos; public const string OP_MOD = "--MOD--"; public const string OP_ADD = "--ADD--"; public const string OP_INS = "--INS--"; public const string OP_DEL = "--DEL--"; [MonoModReplace] public static void Init() { //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Expected O, but got Unknown //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Expected O, but got Unknown DataHandler.loadLog.Length = 0; DataHandler.loadLogError.Length = 0; DataHandler.loadLogWarning.Length = 0; if (DataHandler.bInitialised) { List list = DataHandler.mapCOs.Values.ToList(); foreach (CondOwner item in list) { if (!((Object)(object)item == (Object)null)) { DataHandler.loadLogWarning.Append("Destroying leftover CO: "); DataHandler.loadLogWarning.Append(item.strName); DataHandler.loadLogWarning.AppendLine(); item.Destroy(); } } list.Clear(); list = null; DataHandler.mapCOs.Clear(); if (DataHandler.loadLogWarning.Length > 0) { Debug.LogWarning((object)DataHandler.loadLogWarning.ToString()); } return; } DataHandler.strAssetPath = Application.streamingAssetsPath + "/"; DataHandler.LoadBuildVersion(); TextAsset val = (TextAsset)Resources.Load("version", typeof(TextAsset)); FFU_BR_Defs.GameVersion = (((int)val != 0) ? val.text : null).SafeVersion(); Debug.Log((object)$"Early Access Build: v{FFU_BR_Defs.GameVersion}"); FFU_BR_Defs.InitConfig(); FFU_BR_Defs.ListModdingAPIs(); if (Object.op_Implicit((Object)(object)ObjReader.use)) { ObjReader.use.scaleFactor = new Vector3(0.0625f, 0.0625f, 0.0625f); ObjReader.use.objRotation = new Vector3(90f, 0f, 180f); } dictChangesMap = new Dictionary>>(); DataHandler.SetupDicts(); if (DataHandler._interactionObjectTracker == null) { DataHandler._interactionObjectTracker = new InteractionObjectTracker(); } DataHandler.dictSettings["DefaultUserSettings"] = new JsonUserSettings(); DataHandler.dictSettings["DefaultUserSettings"].Init(); if (File.Exists(Application.persistentDataPath + "/settings.json")) { DataHandler.JsonToData(Application.persistentDataPath + "/settings.json", DataHandler.dictSettings); } else { DataHandler.loadLogWarning.Append("WARNING: settings.json not found. Resorting to default values."); DataHandler.loadLogWarning.AppendLine(); DataHandler.ResetUserSettings(); } if (!DataHandler.dictSettings.ContainsKey("UserSettings") || DataHandler.dictSettings["UserSettings"] == null) { DataHandler.loadLogError.Append("ERROR: Malformed settings.json. Resorting to default values."); DataHandler.loadLogError.AppendLine(); DataHandler.ResetUserSettings(); } DataHandler.dictSettings["DefaultUserSettings"].CopyTo(DataHandler.GetUserSettings()); DataHandler.dictSettings.Remove("DefaultUserSettings"); DataHandler.SaveUserSettings(); DataHandler.LoadMods(); if (FFU_BR_Defs.ModSyncLoading) { foreach (KeyValuePair dictShip in DataHandler.dictShips) { SwitchSlottedItems(dictShip.Value, isTemplate: true); RecoverMissingItems(dictShip.Value); } } Application.SetStackTraceLogType((LogType)3, (StackTraceLogType)0); if (DataHandler.loadLog.Length > 0) { Debug.Log((object)DataHandler.loadLog.ToString()); } Application.SetStackTraceLogType((LogType)3, (StackTraceLogType)1); if (DataHandler.loadLogWarning.Length > 0) { Debug.LogWarning((object)DataHandler.loadLogWarning.ToString()); } if (DataHandler.loadLogError.Length > 0) { Debug.LogError((object)DataHandler.loadLogError.ToString()); } DataHandler.bInitialised = true; DataHandler.InitComplete?.Invoke(); } [MonoModReplace] private static void LoadMods() { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown //IL_03d8: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Expected O, but got Unknown bool flag = false; DataHandler.strModFolder = DataHandler.dictSettings["UserSettings"].strPathMods; if (string.IsNullOrEmpty(DataHandler.strModFolder)) { DataHandler.strModFolder = Path.Combine(Application.dataPath, "Mods/"); DataHandler.loadLogWarning.Append("WARNING: Unrecognized mod folder. Setting mod path to "); DataHandler.loadLogWarning.Append(DataHandler.strModFolder); DataHandler.loadLogWarning.AppendLine(); } string directoryName = Path.GetDirectoryName(DataHandler.strModFolder); directoryName = Path.Combine(directoryName, "loading_order.json"); JsonModInfo val = new JsonModInfo(); val.strName = "Core"; DataHandler.dictModInfos["core"] = val; bool flag2 = (Object)(object)ConsoleToGUI.instance != (Object)null; string text = "Attempting to load " + directoryName.FixPath() + "..."; if (flag2) { ConsoleToGUI.instance.LogInfo(text); } Debug.Log((object)text); if (File.Exists(directoryName)) { string text2 = "loading_order.json found. Beginning mod load."; if (flag2) { ConsoleToGUI.instance.LogInfo(text2); } Debug.Log((object)text2); DataHandler.JsonToData(directoryName, DataHandler.dictModList); if (DataHandler.dictModList.TryGetValue("Mod Loading Order", out var value)) { if (value.aIgnorePatterns != null) { for (int i = 0; i < value.aIgnorePatterns.Length; i++) { value.aIgnorePatterns[i] = DataHandler.PathSanitize(value.aIgnorePatterns[i]); } } DataHandler.SyncSteamWorkshopSubscriptions(value); LoadModInfos(value); List loadOrder = value.GetLoadOrder(); if (loadOrder.Count > 0) { flag = true; } for (int j = 0; j < loadOrder.Count; j++) { string text3 = loadOrder[j]; if (text3.IsCoreEntry()) { string strAssetPath = DataHandler.strAssetPath; string text4 = "Core Assets: " + strAssetPath.Substring(0, strAssetPath.Length - 1).MiniPath().FixPath(); if (flag2) { ConsoleToGUI.instance.LogInfo(text4); } Debug.Log((object)text4); } else { if (!dictModInfos.TryGetValue(text3, out var value2) || DataHandler.IsDuplicate((JsonModInfo)(object)value2)) { continue; } string directory = ((JsonModInfo)value2).GetDirectory(); string iD = ((JsonModInfo)value2).strName.GetID(); Version version = ((JsonModInfo)value2).strModVersion.SafeVersion(); string text5 = directory; if (1 == 0) { } string strAssetPath = ((!Directory.Exists(Path.Combine(directory, "data"))) ? ((Directory.GetDirectories(directory).Length == 0) ? ((!File.Exists(Path.Combine(directory, "mod_info.json"))) ? string.Empty : "Patch") : "Asset") : "Data"); if (1 == 0) { } string text6 = strAssetPath; if (!StringExt.IsNullOrEmpty(iD) && !StringExt.IsNullOrEmpty(text6)) { string text7 = $"{text6} Mod {iD} v{version}: {directory.MiniPath().FixPath()}"; if (flag2) { ConsoleToGUI.instance.LogInfo(text7); } Debug.Log((object)text7); } else { Debug.LogWarning((object)("Invalid Mod: " + directory.MiniPath().FixPath())); } } } } SyncLoadMods(value.aIgnorePatterns); } if (!flag) { string text8 = "No loading_order.json found. Loading default game data from " + DataHandler.strAssetPath; if (flag2) { ConsoleToGUI.instance.LogInfo(text8); } Debug.Log((object)("#Info# " + text8)); JsonModList val2 = new JsonModList(); val2.strName = "Default"; val2.aLoadOrder = new string[1] { "core" }; val2.aIgnorePatterns = Array.Empty(); DataHandler.dictModList["Mod Loading Order"] = val2; if (DataHandler.bSuppressBigShips) { val2.aIgnorePatterns = new string[1] { "LA_" }; } SyncLoadMods(val2.aIgnorePatterns); } } [MonoModReplace] private static void LoadModInfos(JsonModList refModList) { List list = refModList.aLoadOrder.ToList(); for (int i = 0; i < list.Count; i++) { Context val = JsonModList.ParseLoadingOrderEntry(list[i]); string path = val.Path; if (path.IsCoreEntry()) { continue; } if (string.IsNullOrEmpty(path)) { DataHandler.loadLogError.Append("ERROR! Invalid mod folder specified: "); DataHandler.loadLogError.Append(path); DataHandler.loadLogError.Append("; Skipping..."); DataHandler.loadLogError.AppendLine(); continue; } string text = ""; if (Path.IsPathRooted(path)) { text = path; } else { string path2 = path.TrimStart(Path.AltDirectorySeparatorChar); text = Path.GetDirectoryName(DataHandler.strModFolder); text = Path.Combine(text, path2); } Dictionary dictionary = new Dictionary(); string text2 = Path.Combine(text, "mod_info.json"); if (File.Exists(text2)) { DataHandler.JsonToData(text2, dictionary); if (dictionary.Count < 1) { patch_JsonModInfo patch_JsonModInfo2 = new patch_JsonModInfo(); ((JsonModInfo)patch_JsonModInfo2).SetDisabled(val.IsDisabled); ((JsonModInfo)patch_JsonModInfo2).SetEditMode(val.EditMode); ((JsonModInfo)patch_JsonModInfo2).strName = path; dictionary[((JsonModInfo)patch_JsonModInfo2).strName] = patch_JsonModInfo2; DataHandler.loadLogWarning.Append("WARNING: Missing mod_info.json in folder: "); DataHandler.loadLogWarning.Append(path); DataHandler.loadLogWarning.Append("; Using default name: "); DataHandler.loadLogWarning.Append(((JsonModInfo)patch_JsonModInfo2).strName); DataHandler.loadLogWarning.AppendLine(); } using Dictionary.ValueCollection.Enumerator enumerator = dictionary.Values.GetEnumerator(); if (enumerator.MoveNext()) { patch_JsonModInfo current = enumerator.Current; dictModInfos[path] = current; ((JsonModInfo)current).SetDirectory(text); ((JsonModInfo)current).SetDirectoryShort(path); ((JsonModInfo)current).SetDisabled(val.IsDisabled); ((JsonModInfo)current).SetEditMode(val.EditMode); } } else { Debug.LogWarning((object)("Skipped loading mod: " + path)); List list2 = refModList.aLoadOrder.ToList(); list2.Remove(path); refModList.aLoadOrder = list2.ToArray(); DataHandler.SaveModList(); } } } private static void SyncLoadMods(string[] aIgnorePatterns) { //IL_2574: Unknown result type (might be due to invalid IL or missing references) //IL_257a: Invalid comparison between Unknown and I4 if (dictModInfos.Count > 0) { List list = new List(); List list2 = (from MI in dictModInfos.Values where !MI.IsIgnoredEntry() && !StringExt.IsNullOrEmpty(((JsonModInfo)MI).strName.GetID()) select ((JsonModInfo)MI).strName.GetID()).ToList(); List list3 = FFU_BR_API.ModAPIs.Keys.ToList(); int num = list2.IndexOf(FFU_BR_Defs.ModFixes); if (num < 0) { Debug.LogError((object)("Critical '" + FFU_BR_Defs.ModFixes + "' mod is missing from the loading order!")); Debug.LogError((object)"Without it, FFU causes game-breaking issues with original Ostranauts JSONs."); } foreach (KeyValuePair dictModInfo in dictModInfos) { if (dictModInfo.Key.IsCoreEntry() || dictModInfo.Value.IsIgnoredEntry()) { continue; } if (((JsonModInfo)dictModInfo.Value).strGameVersion == null) { Debug.LogWarning((object)("Ignoring mod '" + ((JsonModInfo)dictModInfo.Value).strName + "' - missing required game version!")); list.Add(dictModInfo.Key); continue; } try { Version v = ((JsonModInfo)dictModInfo.Value).strGameVersion.SafeVersion(); if (v.GT(FFU_BR_Defs.GameVersion)) { Debug.LogWarning((object)("Ignoring mod '" + ((JsonModInfo)dictModInfo.Value).strName + "' - outdated Ostranauts version!")); list.Add(dictModInfo.Key); } } catch { Debug.LogWarning((object)("Ignoring mod '" + ((JsonModInfo)dictModInfo.Value).strName + "' - incorrectly assigned game version!")); list.Add(dictModInfo.Key); } } foreach (KeyValuePair dictModInfo2 in dictModInfos) { if (dictModInfo2.Key.IsCoreEntry() || dictModInfo2.Value.IsIgnoredEntry()) { continue; } string iD = ((JsonModInfo)dictModInfo2.Value).strName.GetID(); if (StringExt.IsNullOrEmpty(iD)) { continue; } int num2 = list2.IndexOf(iD); if (dictModInfo2.Value.requiredAPIs == null || dictModInfo2.Value.requiredAPIs.Length == 0) { if (num >= 0 && num2 > num) { Debug.LogWarning((object)("Non-FFU mod '" + iD + "' should be listed before '" + FFU_BR_Defs.ModFixes + "' in loading order!")); } else if (num >= 0 && num2 == num) { Debug.LogWarning((object)("You're using outdated version of '" + FFU_BR_Defs.ModFixes + "' mod!")); Debug.LogWarning((object)"Get the up-to-date version from the official repository:"); Debug.LogWarning((object)FFU_BR_Defs.ModFixesURL); } continue; } if (num >= 0 && num2 < num) { Debug.LogWarning((object)("FFU-based mod '" + iD + "' should be listed after '" + FFU_BR_Defs.ModFixes + "' in loading order!")); } string[] requiredAPIs = dictModInfo2.Value.requiredAPIs; foreach (string text in requiredAPIs) { VersionHelpers.OP oP = _GetOperation(text); if (oP == VersionHelpers.OP.NA) { Debug.LogWarning((object)("Mod '" + iD + "' has invalid API dependency: " + text)); continue; } KeyValuePair keyValuePair = _GetParsedAPI(text, oP); if (StringExt.IsNullOrEmpty(keyValuePair.Key)) { Debug.LogWarning((object)("Mod '" + iD + "' has invalid API dependency: " + text)); continue; } if (list3.IndexOf(keyValuePair.Key) < 0) { Debug.LogWarning((object)("Mod '" + iD + "' requires API '" + keyValuePair.Key + "', but it is missing! Ignoring mod...")); list.Add(dictModInfo2.Key); break; } (string, bool) tuple = _GetResultOP(oP, keyValuePair.Value, FFU_BR_API.ModAPIs[keyValuePair.Key]); var (text2, _) = tuple; if (!tuple.Item2) { Debug.LogWarning((object)("Mod '" + iD + "' requires: " + keyValuePair.Key + " " + text2 + " " + $"{keyValuePair.Value}. Found: {FFU_BR_API.ModAPIs[keyValuePair.Key]}. Mod might work incorrectly!")); } } } foreach (KeyValuePair dictModInfo3 in dictModInfos) { if (dictModInfo3.Key.IsCoreEntry() || dictModInfo3.Value.IsIgnoredEntry()) { continue; } string iD2 = ((JsonModInfo)dictModInfo3.Value).strName.GetID(); if (StringExt.IsNullOrEmpty(iD2)) { continue; } int num4 = list2.IndexOf(iD2); if (dictModInfo3.Value.requiredMods == null || dictModInfo3.Value.requiredMods.Length == 0) { continue; } string[] requiredMods = dictModInfo3.Value.requiredMods; foreach (string text3 in requiredMods) { VersionHelpers.OP oP2 = _GetOperation(text3); if (oP2 == VersionHelpers.OP.NA) { Debug.LogWarning((object)("Mod '" + iD2 + "' has invalid mod dependency: " + text3)); continue; } KeyValuePair parsedMod = _GetParsedAPI(text3, oP2); if (StringExt.IsNullOrEmpty(parsedMod.Key)) { Debug.LogWarning((object)("Mod '" + iD2 + "' has invalid mod dependency: " + text3)); continue; } int num6 = list2.IndexOf(parsedMod.Key); if (num6 < 0) { Debug.LogWarning((object)("Mod '" + iD2 + "' requires mod '" + parsedMod.Key + "', but it is missing! Ignoring mod...")); list.Add(dictModInfo3.Key); break; } if (num6 >= num4) { Debug.LogWarning((object)("Mod '" + iD2 + "' should load after '" + parsedMod.Key + "' dependency! Ignoring mod...")); list.Add(dictModInfo3.Key); break; } patch_JsonModInfo patch_JsonModInfo2 = dictModInfos.Values.Where((patch_JsonModInfo MI) => !MI.IsIgnoredEntry() && ((JsonModInfo)MI).strName.GetID() == parsedMod.Key).First(); (string, bool) tuple3 = _GetResultOP(oP2, parsedMod.Value, ((JsonModInfo)patch_JsonModInfo2).strModVersion.SafeVersion()); var (text4, _) = tuple3; if (!tuple3.Item2) { Debug.LogWarning((object)("Mod '" + iD2 + "' requires: " + parsedMod.Key + " " + text4 + " " + $"{parsedMod.Value}. Found: {((JsonModInfo)dictModInfos[parsedMod.Key]).strModVersion}. Ignoring mod...")); list.Add(dictModInfo3.Key); break; } } } foreach (string item in list) { dictModInfos.Remove(item); } } foreach (KeyValuePair dictModInfo4 in dictModInfos) { if (dictModInfo4.Key.IsCoreEntry() || dictModInfo4.Value.IsIgnoredEntry() || dictModInfo4.Value?.changesMap == null) { continue; } foreach (KeyValuePair> item2 in dictModInfo4.Value.changesMap) { if (!dictChangesMap.ContainsKey(item2.Key)) { dictChangesMap[item2.Key] = new Dictionary>(); } if (item2.Value == null) { continue; } foreach (KeyValuePair item3 in item2.Value) { bool flag = item3.Key.StartsWith("!"); string text5 = (flag ? item3.Key.Substring(1) : item3.Key); if (text5 != "~") { if (!dictChangesMap[item2.Key].ContainsKey(text5)) { dictChangesMap[item2.Key][text5] = new List(); } if (flag && !dictChangesMap[item2.Key][text5].Contains("*IsInverse*")) { dictChangesMap[item2.Key][text5].Add("*IsInverse*"); } if (item3.Value == null || item3.Value.Length == 0) { continue; } if (item3.Value[0] != "~") { string[] value = item3.Value; foreach (string text6 in value) { if (text6.StartsWith("-")) { string cleanEntry = text6.Substring(1); string text7 = dictChangesMap[item2.Key][text5].Find((string x) => x.StartsWith(cleanEntry)); if (!string.IsNullOrEmpty(text7)) { dictChangesMap[item2.Key][text5].Remove(text7); } } else if (text6.StartsWith("*")) { string text8 = text6.Substring(1); string lookupKey = (text8.Contains("|") ? text8.Split("|"[0])[0] : (text8.Contains("=") ? text8.Split("="[0])[0] : text8)); string text9 = dictChangesMap[item2.Key][text5].Find((string x) => x.StartsWith(lookupKey)); if (!string.IsNullOrEmpty(text9)) { int index = dictChangesMap[item2.Key][text5].IndexOf(text9); dictChangesMap[item2.Key][text5][index] = text8; } } else { dictChangesMap[item2.Key][text5].Add(text6); } } } else { dictChangesMap[item2.Key].Remove(text5); } } else { dictChangesMap.Remove(item2.Key); if (item2.Value.Count <= 1) { break; } dictChangesMap[item2.Key] = new Dictionary>(); } } } } if (FFU_BR_Defs.SyncLogging >= FFU_BR_Defs.SyncLogs.ModdedDump) { Debug.Log((object)("Dynamic Changes Map (Dump): " + JsonMapper.ToJson((object)dictChangesMap))); } foreach (KeyValuePair dictModInfo5 in dictModInfos) { if (dictModInfo5.Key.IsCoreEntry()) { DataHandler.aModPaths.Insert(0, DataHandler.strAssetPath); } else if (!dictModInfo5.Value.IsIgnoredEntry()) { DataHandler.aModPaths.Insert(0, dictModInfo5.Value.GetModPath()); } } Dictionary dictionary = new Dictionary(); Dictionary dictionary2 = new Dictionary(); Dictionary dictionary3 = new Dictionary(); Dictionary dictionary4 = new Dictionary(); Dictionary dictionary5 = new Dictionary(); Dictionary dictionary6 = new Dictionary(); Dictionary dictionary7 = new Dictionary(); Dictionary dictionary8 = new Dictionary(); Dictionary dictionary9 = new Dictionary(); Dictionary dictionary10 = new Dictionary(); Dictionary dictionary11 = new Dictionary(); Dictionary dictionary12 = new Dictionary(); foreach (KeyValuePair dictModInfo6 in dictModInfos) { SyncLoadJSONs(dictModInfo6, "ships/", DataHandler.dictShips, aIgnorePatterns); } foreach (KeyValuePair dictModInfo7 in dictModInfos) { SyncLoadJSONs(dictModInfo7, "ads/", DataHandler.dictAds, aIgnorePatterns); } foreach (KeyValuePair dictModInfo8 in dictModInfos) { SyncLoadJSONs(dictModInfo8, "ai_training/", DataHandler.dictAIPersonalities, aIgnorePatterns); } foreach (KeyValuePair dictModInfo9 in dictModInfos) { SyncLoadJSONs(dictModInfo9, "attackmodes/coAttacks/", DataHandler.dictAModes, aIgnorePatterns); } foreach (KeyValuePair dictModInfo10 in dictModInfos) { SyncLoadJSONs(dictModInfo10, "attackmodes/shipAttacks/", DataHandler.dictShipAttacks, aIgnorePatterns); } foreach (KeyValuePair dictModInfo11 in dictModInfos) { SyncLoadJSONs(dictModInfo11, "audioemitters/", DataHandler.dictAudioEmitters, aIgnorePatterns); } foreach (KeyValuePair dictModInfo12 in dictModInfos) { SyncLoadJSONs(dictModInfo12, "blueprints/asteroids/", DataHandler.dictAsteroidBlueprints, aIgnorePatterns); } foreach (KeyValuePair dictModInfo13 in dictModInfos) { SyncLoadJSONs(dictModInfo13, "blueprints/clusters/", DataHandler.dictAsteroidClusterBlueprints, aIgnorePatterns); } foreach (KeyValuePair dictModInfo14 in dictModInfos) { SyncLoadJSONs(dictModInfo14, "careers/", DataHandler.dictCareers, aIgnorePatterns); } foreach (KeyValuePair dictModInfo15 in dictModInfos) { SyncLoadJSONs(dictModInfo15, "chargeprofiles/", DataHandler.dictChargeProfiles, aIgnorePatterns); } foreach (KeyValuePair dictModInfo16 in dictModInfos) { SyncLoadJSONs(dictModInfo16, "colors/", DataHandler.dictJsonColors, aIgnorePatterns); } foreach (KeyValuePair dictModInfo17 in dictModInfos) { SyncLoadJSONs(dictModInfo17, "conditions/", DataHandler.dictConds, aIgnorePatterns); } foreach (KeyValuePair dictModInfo18 in dictModInfos) { SyncLoadJSONs(dictModInfo18, "conditions_simple/", dictionary, aIgnorePatterns); } foreach (KeyValuePair dictModInfo19 in dictModInfos) { SyncLoadJSONs(dictModInfo19, "condowners/", DataHandler.dictCOs, aIgnorePatterns); } foreach (KeyValuePair dictModInfo20 in dictModInfos) { SyncLoadJSONs(dictModInfo20, "condrules/", DataHandler.dictCondRules, aIgnorePatterns); } foreach (KeyValuePair dictModInfo21 in dictModInfos) { SyncLoadJSONs(dictModInfo21, "condtrigs/", DataHandler.dictCTs, aIgnorePatterns); } foreach (KeyValuePair dictModInfo22 in dictModInfos) { SyncLoadJSONs(dictModInfo22, "context/", DataHandler.dictContext, aIgnorePatterns); } foreach (KeyValuePair dictModInfo23 in dictModInfos) { SyncLoadJSONs(dictModInfo23, "cooverlays/", DataHandler.dictCOOverlays, aIgnorePatterns); } foreach (KeyValuePair dictModInfo24 in dictModInfos) { SyncLoadJSONs(dictModInfo24, "crewskins/", dictionary2, aIgnorePatterns); } foreach (KeyValuePair dictModInfo25 in dictModInfos) { SyncLoadJSONs(dictModInfo25, "crime/", DataHandler.dictCrimes, aIgnorePatterns); } foreach (KeyValuePair dictModInfo26 in dictModInfos) { SyncLoadJSONs(dictModInfo26, "explosions/", DataHandler.dictExplosions, aIgnorePatterns); } foreach (KeyValuePair dictModInfo27 in dictModInfos) { SyncLoadJSONs(dictModInfo27, "gasrespires/", DataHandler.dictGasRespires, aIgnorePatterns); } foreach (KeyValuePair dictModInfo28 in dictModInfos) { SyncLoadJSONs(dictModInfo28, "guipropmaps/", DataHandler.dictGUIPropMapUnparsed, aIgnorePatterns); } foreach (KeyValuePair dictModInfo29 in dictModInfos) { SyncLoadJSONs(dictModInfo29, "headlines/", DataHandler.dictHeadlines, aIgnorePatterns); } foreach (KeyValuePair dictModInfo30 in dictModInfos) { SyncLoadJSONs(dictModInfo30, "homeworlds/", DataHandler.dictHomeworlds, aIgnorePatterns); } foreach (KeyValuePair dictModInfo31 in dictModInfos) { SyncLoadJSONs(dictModInfo31, "info/", DataHandler.dictInfoNodes, aIgnorePatterns); } foreach (KeyValuePair dictModInfo32 in dictModInfos) { SyncLoadJSONs(dictModInfo32, "installables/", DataHandler.dictInstallables, aIgnorePatterns); } foreach (KeyValuePair dictModInfo33 in dictModInfos) { SyncLoadJSONs(dictModInfo33, "interaction_overrides/", DataHandler.dictIAOverrides, aIgnorePatterns); } foreach (KeyValuePair dictModInfo34 in dictModInfos) { SyncLoadJSONs(dictModInfo34, "interactions/", DataHandler.dictInteractions, aIgnorePatterns); } foreach (KeyValuePair dictModInfo35 in dictModInfos) { SyncLoadJSONs(dictModInfo35, "items/", DataHandler.dictItemDefs, aIgnorePatterns); } foreach (KeyValuePair dictModInfo36 in dictModInfos) { SyncLoadJSONs(dictModInfo36, "jobitems/", DataHandler.dictJobitems, aIgnorePatterns); } foreach (KeyValuePair dictModInfo37 in dictModInfos) { SyncLoadJSONs(dictModInfo37, "jobs/", DataHandler.dictJobs, aIgnorePatterns); } foreach (KeyValuePair dictModInfo38 in dictModInfos) { SyncLoadJSONs(dictModInfo38, "ledgerdefs/", DataHandler.dictLedgerDefs, aIgnorePatterns); } foreach (KeyValuePair dictModInfo39 in dictModInfos) { SyncLoadJSONs(dictModInfo39, "lifeevents/", DataHandler.dictLifeEvents, aIgnorePatterns); } foreach (KeyValuePair dictModInfo40 in dictModInfos) { SyncLoadJSONs(dictModInfo40, "lights/", DataHandler.dictLights, aIgnorePatterns); } foreach (KeyValuePair dictModInfo41 in dictModInfos) { SyncLoadJSONs(dictModInfo41, "loot/", DataHandler.dictLoot, aIgnorePatterns); } foreach (KeyValuePair dictModInfo42 in dictModInfos) { SyncLoadJSONs(dictModInfo42, "manpages/", dictionary3, aIgnorePatterns); } foreach (KeyValuePair dictModInfo43 in dictModInfos) { SyncLoadJSONs(dictModInfo43, "market/Markets/", DataHandler.dictMarketConfigs, aIgnorePatterns); } foreach (KeyValuePair dictModInfo44 in dictModInfos) { SyncLoadJSONs(dictModInfo44, "market/CoCollections/", DataHandler.dictSupersTemp, aIgnorePatterns); } foreach (KeyValuePair dictModInfo45 in dictModInfos) { SyncLoadJSONs(dictModInfo45, "market/Production/", DataHandler.dictProductionMaps, aIgnorePatterns); } foreach (KeyValuePair dictModInfo46 in dictModInfos) { SyncLoadJSONs(dictModInfo46, "market/CargoSpecs/", DataHandler.dictCargoSpecs, aIgnorePatterns); } foreach (KeyValuePair dictModInfo47 in dictModInfos) { SyncLoadJSONs(dictModInfo47, "music/", DataHandler.dictMusic, aIgnorePatterns); } foreach (KeyValuePair dictModInfo48 in dictModInfos) { SyncLoadJSONs(dictModInfo48, "music_stations/", DataHandler.dictMusicStations, aIgnorePatterns); } foreach (KeyValuePair dictModInfo49 in dictModInfos) { SyncLoadJSONs(dictModInfo49, "names_first/", dictionary4, aIgnorePatterns); } foreach (KeyValuePair dictModInfo50 in dictModInfos) { SyncLoadJSONs(dictModInfo50, "names_full/", dictionary5, aIgnorePatterns); } foreach (KeyValuePair dictModInfo51 in dictModInfos) { SyncLoadJSONs(dictModInfo51, "names_last/", dictionary6, aIgnorePatterns); } foreach (KeyValuePair dictModInfo52 in dictModInfos) { SyncLoadJSONs(dictModInfo52, "names_robots/", dictionary7, aIgnorePatterns); } foreach (KeyValuePair dictModInfo53 in dictModInfos) { SyncLoadJSONs(dictModInfo53, "names_ship/", dictionary8, aIgnorePatterns); } foreach (KeyValuePair dictModInfo54 in dictModInfos) { SyncLoadJSONs(dictModInfo54, "names_ship_adjectives/", dictionary9, aIgnorePatterns); } foreach (KeyValuePair dictModInfo55 in dictModInfos) { SyncLoadJSONs(dictModInfo55, "names_ship_nouns/", dictionary10, aIgnorePatterns); } foreach (KeyValuePair dictModInfo56 in dictModInfos) { SyncLoadJSONs(dictModInfo56, "parallax/", DataHandler.dictParallax, aIgnorePatterns); } foreach (KeyValuePair dictModInfo57 in dictModInfos) { SyncLoadJSONs(dictModInfo57, "pda_apps/", DataHandler.dictPDAAppIcons, aIgnorePatterns); } foreach (KeyValuePair dictModInfo58 in dictModInfos) { SyncLoadJSONs(dictModInfo58, "personspecs/", DataHandler.dictPersonSpecs, aIgnorePatterns); } foreach (KeyValuePair dictModInfo59 in dictModInfos) { SyncLoadJSONs(dictModInfo59, "pledges/", DataHandler.dictPledges, aIgnorePatterns); } foreach (KeyValuePair dictModInfo60 in dictModInfos) { SyncLoadJSONs(dictModInfo60, "plot_beat_overrides/", DataHandler.dictPlotBeatOverrides, aIgnorePatterns); } foreach (KeyValuePair dictModInfo61 in dictModInfos) { SyncLoadJSONs(dictModInfo61, "plot_beats/", DataHandler.dictPlotBeats, aIgnorePatterns); } foreach (KeyValuePair dictModInfo62 in dictModInfos) { SyncLoadJSONs(dictModInfo62, "plot_manager/", DataHandler.dictPlotManager, aIgnorePatterns); } foreach (KeyValuePair dictModInfo63 in dictModInfos) { SyncLoadJSONs(dictModInfo63, "plots/", DataHandler.dictPlots, aIgnorePatterns); } foreach (KeyValuePair dictModInfo64 in dictModInfos) { SyncLoadJSONs(dictModInfo64, "powerinfos/", DataHandler.dictPowerInfo, aIgnorePatterns); } foreach (KeyValuePair dictModInfo65 in dictModInfos) { SyncLoadJSONs(dictModInfo65, "racing/leagues/", DataHandler.dictRacingLeagues, aIgnorePatterns); } foreach (KeyValuePair dictModInfo66 in dictModInfos) { SyncLoadJSONs(dictModInfo66, "racing/tracks/", DataHandler.dictRaceTracks, aIgnorePatterns); } foreach (KeyValuePair dictModInfo67 in dictModInfos) { SyncLoadJSONs(dictModInfo67, "rooms/", DataHandler.dictRoomSpecsTemp, aIgnorePatterns); } foreach (KeyValuePair dictModInfo68 in dictModInfos) { SyncLoadJSONs(dictModInfo68, "shipspecs/", DataHandler.dictShipSpecs, aIgnorePatterns); } foreach (KeyValuePair dictModInfo69 in dictModInfos) { SyncLoadJSONs(dictModInfo69, "slot_effects/", DataHandler.dictSlotEffects, aIgnorePatterns); } foreach (KeyValuePair dictModInfo70 in dictModInfos) { SyncLoadJSONs(dictModInfo70, "slots/", DataHandler.dictSlots, aIgnorePatterns); } foreach (KeyValuePair dictModInfo71 in dictModInfos) { SyncLoadJSONs(dictModInfo71, "star_systems/", DataHandler.dictStarSystems, aIgnorePatterns); } foreach (KeyValuePair dictModInfo72 in dictModInfos) { SyncLoadJSONs(dictModInfo72, "strings/", dictionary11, aIgnorePatterns); } foreach (KeyValuePair dictModInfo73 in dictModInfos) { SyncLoadJSONs(dictModInfo73, "tickers/", DataHandler.dictTickers, aIgnorePatterns); } foreach (KeyValuePair dictModInfo74 in dictModInfos) { SyncLoadJSONs(dictModInfo74, "tips/", DataHandler.dictTips, aIgnorePatterns); } foreach (KeyValuePair dictModInfo75 in dictModInfos) { SyncLoadJSONs(dictModInfo75, "tokens/", DataHandler.dictJsonTokens, aIgnorePatterns); } foreach (KeyValuePair dictModInfo76 in dictModInfos) { SyncLoadJSONs(dictModInfo76, "traitscores/", dictionary12, aIgnorePatterns); } foreach (KeyValuePair dictModInfo77 in dictModInfos) { SyncLoadJSONs(dictModInfo77, "transit/", DataHandler.dictTransit, aIgnorePatterns); } foreach (KeyValuePair dictModInfo78 in dictModInfos) { SyncLoadJSONs(dictModInfo78, "tsv/output/stakes/condtrigs/", DataHandler.dictJCTs, aIgnorePatterns); } foreach (KeyValuePair dictModInfo79 in dictModInfos) { SyncLoadJSONs(dictModInfo79, "tsv/output/stakes/loot/", DataHandler.dictJLoot, aIgnorePatterns); } foreach (KeyValuePair dictModInfo80 in dictModInfos) { SyncLoadJSONs(dictModInfo80, "tsv/output/stakes/interactions/", DataHandler.dictInteractions, aIgnorePatterns); } foreach (KeyValuePair dictModInfo81 in dictModInfos) { SyncLoadJSONs(dictModInfo81, "tsv/output/stakes/conditions/", DataHandler.dictConds, aIgnorePatterns); } foreach (KeyValuePair dictModInfo82 in dictModInfos) { SyncLoadJSONs(dictModInfo82, "tsv/output/stakes/contexts/", DataHandler.dictContext, aIgnorePatterns); } foreach (KeyValuePair dictModInfo83 in dictModInfos) { SyncLoadJSONs(dictModInfo83, "wounds/", DataHandler.dictWounds, aIgnorePatterns); } foreach (KeyValuePair dictModInfo84 in dictModInfos) { SyncLoadJSONs(dictModInfo84, "zone_triggers/", DataHandler.dictZoneTriggers, aIgnorePatterns); } DataHandler.ParseGUIPropMaps(); DataHandler.ParseConditionsSimple(dictionary); DataHandler.ParseTraitScores(dictionary12); DataHandler.ParseSimpleIntoStringDict(dictionary11, DataHandler.dictStrings); DataHandler.ParseSimpleIntoStringDict(dictionary2, DataHandler.dictCrewSkins); DataHandler.ParseSimpleIntoStringDict(dictionary4, DataHandler.dictNamesFirst); DataHandler.ParseSimpleIntoStringDict(dictionary5, DataHandler.dictNamesFull); DataHandler.ParseSimpleIntoStringDict(dictionary6, DataHandler.dictNamesLast); DataHandler.ParseSimpleIntoStringDict(dictionary7, DataHandler.dictNamesRobots); DataHandler.ParseSimpleIntoStringDict(dictionary8, DataHandler.dictNamesShip); DataHandler.ParseSimpleIntoStringDict(dictionary10, DataHandler.dictNamesShipNouns); DataHandler.ParseSimpleIntoStringDict(dictionary9, DataHandler.dictNamesShipAdjectives); DataHandler.ParseManPages(dictionary3); DataHandler.ParseMusic(); DataHandler.ParseJDictLoots(); DataHandler.ParseJDictCTs(); foreach (KeyValuePair dictCO in DataHandler.dictCOs) { if (dictCO.Value.bSlotLocked) { listLockedCOs.Add(dictCO.Value.strName); } } foreach (KeyValuePair dictModInfo85 in dictModInfos) { if ((int)((JsonModInfo)dictModInfo85.Value).GetStatus() == 0) { if (dictModInfo85.Value.IsDuplicateEntry()) { ((JsonModInfo)dictModInfo85.Value).SetStatus((ModStatus)5); } else if (dictModInfo85.Value.IsDisabledEntry()) { ((JsonModInfo)dictModInfo85.Value).SetStatus((ModStatus)3); } else { ((JsonModInfo)dictModInfo85.Value).SetStatus((ModStatus)1); } } } static VersionHelpers.OP _GetOperation(string strAPI) { for (int i = 0; i < strAPI.Length - 1; i++) { if (strAPI[i] == '>' && strAPI[i + 1] == '=') { return VersionHelpers.OP.GE; } if (strAPI[i] == '>') { return VersionHelpers.OP.GT; } if (strAPI[i] == '<' && strAPI[i + 1] == '=') { return VersionHelpers.OP.LE; } if (strAPI[i] == '<') { return VersionHelpers.OP.LT; } if (strAPI[i] == '!' && strAPI[i + 1] == '=') { return VersionHelpers.OP.NE; } if (strAPI[i] == '=') { return VersionHelpers.OP.EQ; } } return VersionHelpers.OP.NA; } static KeyValuePair _GetParsedAPI(string strAPI, VersionHelpers.OP verOP) { if (1 == 0) { } string[] array = verOP switch { VersionHelpers.OP.GT => strAPI.Split(">"), VersionHelpers.OP.GE => strAPI.Split(">="), VersionHelpers.OP.LT => strAPI.Split("<"), VersionHelpers.OP.LE => strAPI.Split("<="), VersionHelpers.OP.EQ => strAPI.Split("="), VersionHelpers.OP.NE => strAPI.Split("!="), _ => new string[2] { string.Empty, string.Empty }, }; if (1 == 0) { } string[] array2 = array; if (array2.Length != 2 || StringExt.IsNullOrEmpty(array2[0]) || StringExt.IsNullOrEmpty(array2[1])) { return new KeyValuePair(string.Empty, new Version("0.0.0.0")); } return new KeyValuePair(array2[0], array2[1].SafeVersion()); } static (string, bool) _GetResultOP(VersionHelpers.OP vOP, Version vRef, Version vCmp) { if (1 == 0) { } (string, bool) result = vOP switch { VersionHelpers.OP.GT => (">", vCmp.GT(vRef)), VersionHelpers.OP.GE => (">=", vCmp.GE(vRef)), VersionHelpers.OP.LT => ("<", vCmp.LT(vRef)), VersionHelpers.OP.LE => ("<=", vCmp.LE(vRef)), VersionHelpers.OP.EQ => ("=", vCmp.EQ(vRef)), VersionHelpers.OP.NE => ("!=", vCmp.NE(vRef)), _ => ("?", false), }; if (1 == 0) { } return result; } } private static void SyncLoadJSONs(KeyValuePair refModInfo, string subFolder, Dictionary dataDict, string[] aIgnorePatterns) { if (refModInfo.Value.IsIgnoredEntry()) { return; } bool flag = !refModInfo.Key.IsCoreEntry(); string text = subFolder.Remove(subFolder.Length - 1); string path = Path.Combine(flag ? ((JsonModInfo)refModInfo.Value).GetDirectory() : DataHandler.strAssetPath, "data"); if (refModInfo.Value?.removeIds != null && refModInfo.Value.removeIds.ContainsKey(text)) { string[] array = refModInfo.Value.removeIds[text]; foreach (string text2 in array) { if (dataDict.Remove(text2)) { Debug.Log((object)("#Info# Removed existing '" + text + "' entry: " + text2)); } } } string path2 = Path.Combine(path, subFolder); if (!Directory.Exists(path2)) { return; } string[] files = Directory.GetFiles(path2, "*.json", SearchOption.AllDirectories); string[] array2 = files; foreach (string text3 in array2) { string text4 = DataHandler.PathSanitize(text3); bool flag2 = false; if (aIgnorePatterns != null) { foreach (string value in aIgnorePatterns) { if (text4.IndexOf(value) >= 0) { flag2 = true; break; } } } if (flag2) { Debug.Log((object)("#Info# Ignore pattern match: " + text4 + "; Skipping...")); continue; } try { SyncToData(text4, text, flag, dataDict, text.IsExtedable()); } catch (Exception ex) { Exception innerException = ex.InnerException; Debug.LogWarning((object)("Data Sync Exception: " + text3 + "\n" + ex.Message + "\n" + ex.StackTrace + ((innerException != null) ? ("\nInner: " + innerException.Message + "\n" + innerException.StackTrace) : ""))); ((JsonModInfo)refModInfo.Value).SetStatus((ModStatus)2); } } } public static void SyncToData(string strFile, string strType, bool isMod, Dictionary dataDict, bool extData) { Debug.Log((object)("#Info# Loading JSON: " + strFile.MiniPath())); bool doLog = FFU_BR_Defs.SyncLogging >= FFU_BR_Defs.SyncLogs.ModChanges; bool flag = FFU_BR_Defs.SyncLogging >= FFU_BR_Defs.SyncLogs.DeepCopy; bool flag2 = FFU_BR_Defs.SyncLogging >= FFU_BR_Defs.SyncLogs.ModdedDump; bool flag3 = FFU_BR_Defs.SyncLogging >= FFU_BR_Defs.SyncLogs.ExtendedDump; bool flag4 = FFU_BR_Defs.SyncLogging >= FFU_BR_Defs.SyncLogs.ContentDump; bool flag5 = FFU_BR_Defs.SyncLogging >= FFU_BR_Defs.SyncLogs.SourceDump; bool noCoreDuplicates = FFU_BR_Defs.NoCoreDuplicates; string text = string.Empty; try { string text2 = File.ReadAllText(strFile, Encoding.UTF8); text += "Converting JSON into Array...\n"; string[] array = (isMod ? text2.Compressed().Split(new string[1] { "},{" }, StringSplitOptions.None) : null); TJson[] array2 = JsonMapper.ToObject(text2); for (int i = 0; i < array2.Length; i++) { TJson val = array2[i]; string rawDataSet = (isMod ? array[i] : null); text += "Getting key: "; string text3 = null; string dataKey = null; PropertyInfo propertyInfo = val.GetType()?.GetProperty("strReference"); PropertyInfo propertyInfo2 = val.GetType()?.GetProperty("strName"); if (propertyInfo2 == null) { JsonLogger.ReportProblem("strName is missing", (ReportTypes)1); continue; } object obj = propertyInfo?.GetValue(val, null); object value = propertyInfo2.GetValue(val, null); text3 = obj?.ToString(); dataKey = value.ToString(); text = text + dataKey + "\n"; if (isMod && dataDict.ContainsKey(dataKey)) { if (flag2) { Debug.Log((object)("Modification Data (Dump/Before): " + JsonMapper.ToJson((object)dataDict[dataKey]))); } try { SyncDataSafe(dataDict[dataKey], val, ref rawDataSet, strType, dataKey, extData, doLog); if (flag2) { Debug.Log((object)("Modification Data (Dump/After): " + JsonMapper.ToJson((object)dataDict[dataKey]))); } } catch (Exception ex) { Exception innerException = ex.InnerException; Debug.LogWarning((object)("Modification sync for Data Block [" + dataKey + "] has failed! Ignoring.\n" + ex.Message + "\n" + ex.StackTrace + ((innerException != null) ? ("\nInner: " + innerException.Message + "\n" + innerException.StackTrace) : ""))); } continue; } if (isMod && !dataDict.ContainsKey(dataKey)) { if (text3 != null && dataDict.ContainsKey(text3)) { string text4 = patch_JsonMapper.ToCopy(dataDict[text3]); if (flag3) { Debug.Log((object)("Reference Data (Dump/Before): " + text4)); } bool isDeepCopySuccess = false; text4 = Regex.Replace(text4, "(\"strName\":)\"[^\"]*\"", delegate(Match match) { isDeepCopySuccess = true; return match.Groups[1].Value + "\"" + dataKey + "\""; }); if (!isDeepCopySuccess) { continue; } TJson val2 = JsonMapper.ToObject(text4); if (flag) { Debug.Log((object)("#Info# Modified Deep Copy Created: " + text3 + " => " + dataKey)); } try { SyncDataSafe(val2, val, ref rawDataSet, strType, dataKey, extData, flag); if (flag3) { Debug.Log((object)("Reference Data (Dump/After): " + JsonMapper.ToJson((object)val2))); } } catch (Exception ex2) { Exception innerException2 = ex2.InnerException; Debug.LogWarning((object)("Reference sync for Data Block [" + dataKey + "] has failed! Ignoring.\n" + ex2.Message + "\n" + ex2.StackTrace + ((innerException2 != null) ? ("\nInner: " + innerException2.Message + "\n" + innerException2.StackTrace) : ""))); } try { dataDict.Add(dataKey, val2); } catch (Exception ex3) { Exception innerException3 = ex3.InnerException; Debug.LogWarning((object)("Reference add of new Data Block [" + dataKey + "] has failed! Ignoring.\n" + ex3.Message + "\n" + ex3.StackTrace + ((innerException3 != null) ? ("\nInner: " + innerException3.Message + "\n" + innerException3.StackTrace) : ""))); } continue; } if (!string.IsNullOrEmpty(text3)) { Debug.LogWarning((object)("Reference key '" + text3 + "' in Data Block [" + dataKey + "] is invalid! Ignoring.")); continue; } if (flag4) { try { Debug.Log((object)("Addendum Data (Dump/Mod): " + JsonMapper.ToJson((object)val))); } catch (Exception ex4) { Exception innerException4 = ex4.InnerException; Debug.LogWarning((object)("Addendum Data (Dump/Mod) for Data Block [" + dataKey + "] has failed! Ignoring.\n" + ex4.Message + "\n" + ex4.StackTrace + ((innerException4 != null) ? ("\nInner: " + innerException4.Message + "\n" + innerException4.StackTrace) : ""))); } } try { dataDict.Add(dataKey, val); } catch (Exception ex5) { Exception innerException5 = ex5.InnerException; Debug.LogWarning((object)("Modded Add of new Data Block [" + dataKey + "] has failed! Ignoring.\n" + ex5.Message + "\n" + ex5.StackTrace + ((innerException5 != null) ? ("\nInner: " + innerException5.Message + "\n" + innerException5.StackTrace) : ""))); } continue; } if (flag5) { try { Debug.Log((object)("Addendum Data (Dump/Core): " + JsonMapper.ToJson((object)val))); } catch (Exception ex6) { Exception innerException6 = ex6.InnerException; Debug.LogWarning((object)("Addendum Data (Dump/Core) for Data Block [" + dataKey + "] has failed! Ignoring.\n" + ex6.Message + "\n" + ex6.StackTrace + ((innerException6 != null) ? ("\nInner: " + innerException6.Message + "\n" + innerException6.StackTrace) : ""))); } } try { if (dataDict.ContainsKey(dataKey)) { if (noCoreDuplicates) { Debug.LogWarning((object)("Core Data Block [" + dataKey + "] already exists! Discarding newer entry.")); continue; } dataDict.Remove(dataKey); Debug.LogWarning((object)("Core Data Block [" + dataKey + "] already exists! Replacing with newer entry.")); dataDict.Add(dataKey, val); } else { dataDict.Add(dataKey, val); } } catch (Exception ex7) { Exception innerException7 = ex7.InnerException; Debug.LogWarning((object)("Core Add of new Data Block [" + dataKey + "] has failed! Ignoring.\n" + ex7.Message + "\n" + ex7.StackTrace + ((innerException7 != null) ? ("\nInner: " + innerException7.Message + "\n" + innerException7.StackTrace) : ""))); } } array2 = null; text2 = null; } catch (Exception ex8) { JsonLogger.ReportProblem(strFile, (ReportTypes)0); if (text.Length > 1000) { text = text.Substring(text.Length - 1000); } Debug.LogError((object)(text + "\n" + ex8.Message + "\n" + ex8.StackTrace.ToString())); } if (strFile.IndexOf("osSGv1") >= 0) { Debug.Log((object)text); } } public static void SyncDataSafe(TJson currDataSet, TJson newDataSet, ref string rawDataSet, string dataType, string dataKey, bool extData, bool doLog = false) { Type type = currDataSet.GetType(); Type type2 = newDataSet.GetType(); PropertyInfo[] properties = type.GetProperties(); foreach (PropertyInfo propertyInfo in properties) { if (!propertyInfo.CanWrite || propertyInfo.Name.IsForbidden()) { continue; } PropertyInfo property = type2.GetProperty(propertyInfo.Name); if (!(property != null)) { continue; } bool useCurrent = false; string name = propertyInfo.Name; object newValue = property.GetValue(newDataSet, null); object currValue = propertyInfo.GetValue(currDataSet, null); if (rawDataSet.IndexOf(name) < 0) { continue; } try { if (currValue != null && newValue is IDictionary) { SyncRecords(ref newValue, ref currValue, ref useCurrent, dataKey, name, dataType, extData, doLog); } else if (currValue != null && newValue is string[]) { SyncArrays(ref newValue, ref currValue, dataKey, name, extData, doLog); } else if (currValue != null && newValue is object[]) { SyncObjects(ref newValue, ref currValue, ref useCurrent, dataKey, name, dataType, extData, doLog); } else if (currValue != null && !(newValue is string) && newValue != null && newValue.GetType().IsClass) { string rawDataSet2 = JsonMapper.ToJson(currValue).Compressed(); SyncDataSafe(currValue, newValue, ref rawDataSet2, dataType, dataKey + "/" + name, extData, doLog); } else if (doLog) { Debug.Log((object)("#Info# Data Block [" + dataKey + "], Property " + $"[{name}]: {currValue.Sanitized()} => {newValue.Sanitized()}")); } if (useCurrent) { propertyInfo.SetValue(currDataSet, currValue, null); } else { propertyInfo.SetValue(currDataSet, newValue, null); } } catch (Exception ex) { Exception innerException = ex.InnerException; Debug.LogWarning((object)("Value sync for Data Block [" + dataKey + "], Property [" + name + "] has failed! Ignoring.\n" + ex.Message + "\n" + ex.StackTrace + ((innerException != null) ? ("\nInner: " + innerException.Message + "\n" + innerException.StackTrace) : ""))); } } BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public; FieldInfo[] fields = type.GetFields(bindingAttr); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.IsLiteral || fieldInfo.Name.IsForbidden()) { continue; } FieldInfo field = type2.GetField(fieldInfo.Name, bindingAttr); if (!(field != null)) { continue; } bool useCurrent2 = false; string name2 = fieldInfo.Name; object newValue2 = field.GetValue(newDataSet); object currValue2 = fieldInfo.GetValue(currDataSet); if (rawDataSet.IndexOf(name2) < 0) { continue; } try { if (currValue2 != null && newValue2 is IDictionary) { SyncRecords(ref newValue2, ref currValue2, ref useCurrent2, dataKey, name2, dataType, extData, doLog); } else if (currValue2 != null && newValue2 is string[]) { SyncArrays(ref newValue2, ref currValue2, dataKey, name2, extData, doLog); } else if (currValue2 != null && newValue2 is object[]) { SyncObjects(ref newValue2, ref currValue2, ref useCurrent2, dataKey, name2, dataType, extData, doLog); } else if (currValue2 != null && !(newValue2 is string) && newValue2 != null && newValue2.GetType().IsClass) { string rawDataSet3 = JsonMapper.ToJson(currValue2).Compressed(); SyncDataSafe(currValue2, newValue2, ref rawDataSet3, dataType, dataKey + "/" + name2, extData, doLog); } else if (doLog) { Debug.Log((object)("#Info# Data Block [" + dataKey + "], Property " + $"[{name2}]: {currValue2.Sanitized()} => {newValue2.Sanitized()}")); } if (useCurrent2) { fieldInfo.SetValue(currDataSet, currValue2); } else { fieldInfo.SetValue(currDataSet, newValue2); } } catch (Exception ex2) { Exception innerException2 = ex2.InnerException; Debug.LogWarning((object)("Value sync for Data Block [" + dataKey + "], Property [" + name2 + "] has failed! Ignoring.\n" + ex2.Message + "\n" + ex2.StackTrace + ((innerException2 != null) ? ("\nInner: " + innerException2.Message + "\n" + innerException2.StackTrace) : ""))); } } } public static void SyncObjects(ref object newValue, ref object currValue, ref bool useCurrent, string dataKey, string propName, string dataType, bool extData, bool doLog) { useCurrent = true; List list = (newValue as Array).Cast().ToList(); List list2 = (currValue as Array).Cast().ToList(); foreach (object item in list) { string targetID = item.GetIdentifier(); if (string.IsNullOrEmpty(targetID)) { if (doLog) { Debug.Log((object)("#Info# Data Block [" + dataKey + "], " + $"Property [{propName}]: {currValue} => {newValue}")); } useCurrent = false; return; } bool flag = targetID.StartsWith("~"); bool flag2 = targetID.StartsWith("*"); if (flag || flag2) { targetID = targetID.Substring(1); item.SetIdentifier(targetID); } int num = list2.FindIndex((object x) => x.GetIdentifier() == targetID); if (num >= 0) { string name = list2[num].GetName(); name = ((name != targetID && name != string.Empty) ? (name + ":" + targetID) : targetID); if (flag) { if (doLog) { Debug.Log((object)("#Info# Object [" + name + "] was removed from Data Block [" + dataKey + "/" + propName + "]")); } list2.RemoveAt(num); } else if (flag2) { if (doLog) { Debug.Log((object)("#Info# Object [" + name + "] was replaced in Data Block [" + dataKey + "/" + propName + "]")); } list2[num] = item; } else { string rawDataSet = JsonMapper.ToJson(item); SyncDataSafe(list2[num], item, ref rawDataSet, dataType, dataKey + "/" + propName + "/" + name, extData, doLog); } } else { string name2 = item.GetName(); name2 = ((name2 != targetID && name2 != string.Empty) ? (name2 + ":" + targetID) : targetID); if (doLog) { Debug.Log((object)("#Info# Object [" + name2 + "] was added to Data Block [" + dataKey + "/" + propName + "]")); } list2.Add(item); } } Array array = Array.CreateInstance(currValue.GetType().GetElementType(), list2.Count); for (int num2 = 0; num2 < list2.Count; num2++) { array.SetValue(list2[num2], num2); } currValue = array; } public static void SyncRecords(ref object newValue, ref object currValue, ref bool useCurrent, string dataKey, string propName, string dataType, bool extData, bool doLog) { useCurrent = true; IDictionary dictionary = (IDictionary)newValue; IDictionary dictionary2 = (IDictionary)currValue; Type[] genericArguments = currValue.GetType().GetGenericArguments(); Type type = ((genericArguments.Count() > 1) ? genericArguments[1] : genericArguments[0]); bool flag = type != typeof(string) && type.IsClass; foreach (object item in dictionary.Keys.Cast().ToList()) { bool flag2 = item.ToString().StartsWith("~"); bool flag3 = item.ToString().StartsWith("*"); object obj = ((flag2 || flag3) ? item.ToString().Substring(1) : item); if (dictionary2.Contains(obj)) { if (flag2) { if (doLog) { Debug.Log((object)($"#Info# Property [{obj}] was removed " + "from Data Block [" + dataKey + "/" + propName + "]")); } dictionary2.Remove(obj); } else if (flag3) { if (doLog) { Debug.Log((object)($"#Info# Property [{obj}] was replaced " + "in Data Block [" + dataKey + "/" + propName + "]")); } dictionary2[obj] = dictionary[item]; } else if (flag) { string rawDataSet = JsonMapper.ToJson(dictionary[obj]); SyncDataSafe(dictionary2[obj], dictionary[obj], ref rawDataSet, dataType, $"{dataKey}/{propName}:{obj}", extData, doLog); } else { if (doLog) { Debug.Log((object)("#Info# Data Block [" + dataKey + "/" + propName + "], " + $"Property [{obj}]: {dictionary2[obj]} => {dictionary[obj]}")); } dictionary2[obj] = dictionary[obj]; } } else { if (doLog) { Debug.Log((object)($"#Info# Property [{obj}], Value [{dictionary[obj]}] " + "was added to Data Block [" + dataKey + "/" + propName + "]")); } dictionary2[obj] = dictionary[obj]; } } } public static void SyncArrays(ref object newValue, ref object currValue, string dataKey, string propName, bool extData, bool doLog) { SyncArrayOp arrayOp = (extData ? SyncArrayOp.Add : SyncArrayOp.None); List list = (currValue as string[]).ToList(); List list2 = (newValue as string[]).ToList(); List list3 = list.ToList(); bool noArrayOps = true; foreach (string item in list2) { if (string.IsNullOrEmpty(item) || !char.IsDigit(item[0]) || !item.Contains('|')) { continue; } List list4 = item.Split('|').ToList(); int.TryParse(list4[0], out var result); if (result > 0) { list4.RemoveAt(0); List list5 = list[result - 1].Split('|').ToList(); SyncArrayOps(list5, list4, ref noArrayOps, dataKey, $"{propName}#{result}", doLog, arrayOp); if (noArrayOps) { Debug.LogWarning((object)("You attempted to modify sub-array in Data Block " + $"[{dataKey}], Property [{propName}#{result}], but performed no array operations. " + "Assume that something went horribly wrong and game is likely to crash.")); } list[result - 1] = string.Join("|", list5.ToArray()); } } SyncArrayOps(list, list2, ref noArrayOps, dataKey, propName, doLog, arrayOp); if (noArrayOps) { if (doLog) { Debug.Log((object)("#Info# Data Block [" + dataKey + "], " + $"Property [{propName}]: String[{list3.Count}] => String[{list2.Count}]")); } newValue = list2.ToArray(); } else { newValue = list.ToArray(); } } public static void SyncArrayOps(List modArray, List refArray, ref bool noArrayOps, string dataKey, string propName, bool doLog, SyncArrayOp arrayOp = SyncArrayOp.None) { int result = 0; foreach (string item in refArray) { if (string.IsNullOrEmpty(item) || (char.IsDigit(item[0]) && item.Contains('|'))) { continue; } if (item.StartsWith("--")) { switch (item.Substring(0, 7)) { case "--MOD--": arrayOp = SyncArrayOp.Mod; break; case "--ADD--": arrayOp = SyncArrayOp.Add; break; case "--INS--": arrayOp = SyncArrayOp.Ins; break; case "--DEL--": arrayOp = SyncArrayOp.Del; break; } if (arrayOp == SyncArrayOp.Ins) { int.TryParse(item.Substring(7), out result); result--; if (result < 0) { Debug.LogWarning((object)("The '--INS--' array operation in Data Block [" + dataKey + "], Property [" + propName + "] received invalid index! Using [0] index.")); result = 0; } } continue; } if (noArrayOps) { noArrayOps = arrayOp == SyncArrayOp.None; } if (noArrayOps) { break; } string[] array = item.Split('='); if (array.Length == 2 && !item.Contains('|') && !string.IsNullOrEmpty(array[1])) { switch (arrayOp) { case SyncArrayOp.Mod: OpModData(modArray, item, dataKey, propName, doLog); break; case SyncArrayOp.Add: OpAddData(modArray, item, dataKey, propName, doLog); break; case SyncArrayOp.Ins: OpInsData(modArray, ref result, item, dataKey, propName, doLog); break; case SyncArrayOp.Del: OpDelData(modArray, item, dataKey, propName, doLog); break; } continue; } switch (arrayOp) { case SyncArrayOp.Mod: Debug.LogWarning((object)("Non-data [" + item + "] in Data Block [" + dataKey + "], Property [" + propName + "] doesn't support '--MOD--' operation! Ignoring.")); break; case SyncArrayOp.Add: OpAddSimple(modArray, item, dataKey, propName, doLog); break; case SyncArrayOp.Ins: OpInsSimple(modArray, ref result, item, dataKey, propName, doLog); break; case SyncArrayOp.Del: OpDelSimple(modArray, item, dataKey, propName, doLog); break; } } } public static void OpModData(List modArray, string refItem, string dataKey, string propName, bool doLog) { string[] array = refItem.Split('='); bool flag = false; for (int i = 0; i < modArray.Count; i++) { if (StringExt.IsNullOrEmpty(modArray[i])) { continue; } string[] array2 = modArray[i].Split('='); if (array2[0] == array[0]) { if (doLog) { Debug.Log((object)("#Info# Data Block [" + dataKey + "], Property [" + propName + "], Parameter [" + array[0] + "]: " + array2[1] + " => " + array[1])); } modArray[i] = refItem; flag = true; break; } } if (!flag) { Debug.LogWarning((object)("Parameter [" + array[0] + "] was not found in Data Block [" + dataKey + "], Property [" + propName + "]! Ignoring.")); } } public static void OpAddData(List modArray, string refItem, string dataKey, string propName, bool doLog) { string[] array = refItem.Split('='); if (doLog) { Debug.Log((object)("#Info# Parameter [" + array[0] + "], Value [" + array[1] + "] was added to Data Block [" + dataKey + "], Property [" + propName + "]")); } modArray.Add(refItem); } public static void OpInsData(List modArray, ref int arrIndex, string refItem, string dataKey, string propName, bool doLog) { string[] array = refItem.Split('='); if (doLog) { Debug.Log((object)("#Info# Parameter [" + array[0] + "], Value [" + array[1] + "] was inserted " + $"into Data Block [{dataKey}], Property [{propName}] at Index [{arrIndex}]")); } if (arrIndex >= modArray.Count) { Debug.LogWarning((object)($"Index [{arrIndex}] for Parameter [{array[0]}] in Data " + "Block [" + dataKey + "], Property [" + propName + "] is invalid! Adding instead.")); modArray.Add(refItem); } else { modArray.Insert(arrIndex, refItem); } arrIndex++; } public static void OpDelData(List modArray, string refItem, string dataKey, string propName, bool doLog) { string[] array = refItem.Split('='); bool flag = false; int index = 0; for (int i = 0; i < modArray.Count; i++) { if (!StringExt.IsNullOrEmpty(modArray[i])) { string[] array2 = modArray[i].Split('='); if (array2[0] == array[0]) { index = i; flag = true; break; } } } if (flag) { if (doLog) { Debug.Log((object)("#Info# Parameter [" + array[0] + "] was removed from Data Block [" + dataKey + "], Property [" + propName + "]")); } modArray.RemoveAt(index); } else { Debug.LogWarning((object)("Parameter [" + array[0] + "] was not found in Data Block [" + dataKey + "], Property [" + propName + "]! Ignoring.")); } } public static void OpAddSimple(List modArray, string refItem, string dataKey, string propName, bool doLog) { bool flag = refItem.ToLower().StartsWith("null"); if (doLog) { Debug.Log((object)("#Info# Parameter [" + refItem + "] was added to Data Block [" + dataKey + "], Property [" + propName + "]")); } if (flag) { modArray.Add(null); } else { modArray.Add(refItem); } } public static void OpInsSimple(List modArray, ref int arrIndex, string refItem, string dataKey, string propName, bool doLog) { bool flag = refItem.ToLower().StartsWith("null"); if (doLog) { Debug.Log((object)("#Info# Parameter [" + refItem + "] was inserted into " + $"Data Block [{dataKey}], Property [{propName}] at Index [{arrIndex}]")); } if (arrIndex >= modArray.Count) { Debug.LogWarning((object)($"Index [{arrIndex}] for Parameter [{refItem}] in Data " + "Block [" + dataKey + "], Property [" + propName + "] is invalid! Adding instead.")); if (flag) { modArray.Add(null); } else { modArray.Add(refItem); } } else if (flag) { modArray.Insert(arrIndex, null); } else { modArray.Insert(arrIndex, refItem); } arrIndex++; } public static void OpDelSimple(List modArray, string refItem, string dataKey, string propName, bool doLog) { bool flag = refItem.ToLower().StartsWith("null"); bool flag2 = false; int index = 0; if (flag) { int num = 0; string[] array = refItem.Split('#'); int result; int num2 = ((array.Length > 1 && int.TryParse(array[1], out result)) ? result : 0); for (int i = 0; i < modArray.Count; i++) { if (StringExt.IsNullOrEmpty(modArray[i])) { num++; if (num >= num2) { index = i; flag2 = true; break; } } } } else { for (int j = 0; j < modArray.Count; j++) { if (!StringExt.IsNullOrEmpty(modArray[j]) && modArray[j].StartsWith(refItem)) { index = j; flag2 = true; break; } } } if (flag2) { if (doLog) { Debug.Log((object)("#Info# Parameter [" + refItem + "] was removed from Data Block [" + dataKey + "], Property [" + propName + "]")); } modArray.RemoveAt(index); } else { Debug.LogWarning((object)("Parameter [" + refItem + "] was not found in Data Block [" + dataKey + "], Property [" + propName + "]!")); } } public static string GetName(this object refObject) { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public; Type type = refObject.GetType(); string empty = string.Empty; empty = type.GetProperty("strName")?.GetValue(refObject, null)?.ToString() ?? string.Empty; if (string.IsNullOrEmpty(empty)) { empty = type.GetField("strName", bindingAttr)?.GetValue(refObject)?.ToString() ?? string.Empty; } return empty; } public static string GetIdentifier(this object refObject) { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public; Type type = refObject.GetType(); string[] array = new string[2] { "strID", "strName" }; string text = string.Empty; string[] array2 = array; foreach (string name in array2) { text = type.GetProperty(name)?.GetValue(refObject, null)?.ToString() ?? string.Empty; if (string.IsNullOrEmpty(text)) { text = type.GetField(name, bindingAttr)?.GetValue(refObject)?.ToString() ?? string.Empty; } if (!string.IsNullOrEmpty(text)) { break; } } return text; } public static bool SetIdentifier(this object refObject, string newIdentifier) { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public; Type type = refObject.GetType(); string[] array = new string[2] { "strID", "strName" }; bool result = false; string[] array2 = array; foreach (string name in array2) { PropertyInfo property = type.GetProperty(name); if (property != null) { property.SetValue(refObject, newIdentifier, null); result = true; break; } FieldInfo field = type.GetField(name, bindingAttr); if (field != null) { field.SetValue(refObject, newIdentifier); result = true; break; } } return result; } public static bool IsForbidden(this string strProp) { if (1 == 0) { } bool result; switch (strProp) { case "strID": case "strName": case "strReference": result = true; break; default: result = false; break; } if (1 == 0) { } return result; } public static object Sanitized(this object refObject) { if (refObject == null) { return "NULL"; } if (refObject is string { Length: 0 }) { return "EMPTY"; } return refObject; } public static string Compressed(this string strValue) { return strValue.Replace("\n", "").Replace("\r", "").Replace("\t", "") .Replace(" ", ""); } public static bool IsCoreEntry(this string modKey) { return modKey.ToLower() == "core" || modKey == "Core"; } public static bool IsIgnoredEntry(this patch_JsonModInfo refModInfo) { return refModInfo.IsDisabledEntry() || refModInfo.IsDuplicateEntry(); } public static bool IsDisabledEntry(this patch_JsonModInfo refModInfo) { return ((JsonModInfo)refModInfo).GetIsDisabled(); } public static bool IsDuplicateEntry(this patch_JsonModInfo refModInfo) { return DataHandler.IsDuplicate((JsonModInfo)(object)refModInfo); } public static bool IsExtedable(this string dataKey) { if (1 == 0) { } bool result; switch (dataKey) { case "conditions_simple": case "names_last": case "names_robots": case "names_first": case "names_full": case "manpages": case "traitscores": case "strings": case "crewskins": case "names_ship": case "names_ship_adjectives": case "names_ship_nouns": result = true; break; default: result = false; break; } if (1 == 0) { } return result; } public static string MiniPath(this string fullPath) { int num = fullPath.ToLower().IndexOf("steamapps"); if (num > 0) { return fullPath.Substring(num + 10); } return fullPath; } public static string FixPath(this string fullPath) { return fullPath.Replace('\\', '/'); } public static string GetID(this string fullName) { if (StringExt.IsNullOrEmpty(fullName)) { return string.Empty; } fullName = Regex.Replace(fullName.Replace(' ', '_'), "[^a-zA-Z0-9_]", string.Empty); return fullName; } public static string GetModPath(this patch_JsonModInfo refModInfo) { string text = ((JsonModInfo)refModInfo).GetDirectory().FixPath(); return text.EndsWith('/') ? text : (text + "/"); } public static bool TryGetCOValue(string strName, out JsonCondOwner refCO) { if (DataHandler.dictCOs.TryGetValue(strName, out var value)) { refCO = value; return true; } if (DataHandler.dictCOOverlays.TryGetValue(strName, out var value2) && DataHandler.dictCOs.TryGetValue(value2.strCOBase, out var value3)) { refCO = value3; return true; } refCO = null; return false; } public static void SwitchSlottedItems(JsonShip aShipRef, bool isTemplate) { if (aShipRef == null) { return; } List list = aShipRef.aItems?.ToList(); List list2 = aShipRef.aCOs?.ToList(); if (list == null) { return; } foreach (JsonItem aItem in list) { if (string.IsNullOrEmpty(aItem.strSlotParentID)) { continue; } JsonItem val = list.Find((JsonItem x) => x.strID == aItem.strSlotParentID); if (val == null || !dictChangesMap.ContainsKey(val.strName) || !dictChangesMap[val.strName].ContainsKey("Switch_Slotted") || dictChangesMap[val.strName]["Switch_Slotted"] == null) { continue; } Dictionary dictionary = (from x in dictChangesMap[val.strName]["Switch_Slotted"] where x.Split("="[0]).Length == 2 select x.Split("="[0])).ToDictionary((string[] x) => x[0], (string[] x) => x[1]); if (!dictionary.ContainsKey(aItem.strName)) { continue; } string text = dictionary[aItem.strName]; if (string.IsNullOrEmpty(text)) { continue; } Debug.Log((object)("#Info# Found the mismatched CO [" + aItem.strName + ":" + aItem.strID + "] for the Parent CO [" + val.strName + ":" + val.strID + "] for remapping! Syncing to the CO [" + text + "] from the template.")); if (!TryGetCOValue(text, out var refCO)) { continue; } aItem.strName = refCO.strName; if (!isTemplate && list2 != null && TryGetCOValue(val.strName, out var refCO2)) { JsonCondOwnerSave val2 = list2.Find((JsonCondOwnerSave x) => x.strID == aItem.strID); if (val2 != null) { val2.strSlotName = refCO.mapSlotEffects.Intersect(refCO2.aSlotsWeHave).First(); val2.strCondID = refCO.strName + aItem.strID; val2.strFriendlyName = refCO.strNameFriendly; val2.strCODef = refCO.strName; } } } if (list2 != null) { aShipRef.aCOs = list2.ToArray(); } aShipRef.aItems = list.ToArray(); } public static void RecoverMissingItems(JsonShip aShipRef) { //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Expected O, but got Unknown if (aShipRef == null) { return; } List list = aShipRef.aItems?.ToList(); List list2 = new List(); if (list == null) { return; } foreach (JsonItem aItem in list) { if (!dictChangesMap.ContainsKey(aItem.strName) || !dictChangesMap[aItem.strName].ContainsKey("Recover_Missing") || dictChangesMap[aItem.strName]["Recover_Missing"] == null || !TryGetCOValue(aItem.strName, out var refCO)) { continue; } List targetKeys = dictChangesMap[aItem.strName]["Recover_Missing"].ToList(); bool isInverse = targetKeys.Remove("*IsInverse*"); bool doAll = targetKeys.Count == 0; if (refCO.aSlotsWeHave == null || refCO.aSlotsWeHave.Length == 0 || refCO.strLoot == null || !DataHandler.dictLoot.ContainsKey(refCO.strLoot)) { continue; } List second = (from x in list.FindAll((JsonItem x) => (x.strSlotParentID == aItem.strID && listLockedCOs.Contains(x.strName)) || targetKeys.Contains(x.strName)) select x.strName).ToList(); List first = (from x in DataHandler.dictLoot[refCO.strLoot].GetAllLootNames() where (doAll && listLockedCOs.Contains(x)) || (!isInverse && targetKeys.Contains(x)) || (isInverse && !targetKeys.Contains(x) && listLockedCOs.Contains(x)) select x).ToList(); List list3 = first.Except(second).ToList(); foreach (string item in list3) { JsonItem val = new JsonItem(); val.strName = item; val.fX = aItem.fX; val.fY = aItem.fY; val.fRotation = 0f; val.strID = Guid.NewGuid().ToString(); val.strSlotParentID = aItem.strID; val.bForceLoad = aItem.bForceLoad; Debug.Log((object)("#Info# Found the missing locked CO [" + item + "] for the Parent CO [" + aItem.strName + ":" + aItem.strID + "] in the list! New ID [" + val.strID + "], adding.")); list2.Add(val); } } list.AddRange(list2); aShipRef.aItems = list.ToArray(); } public static void RecoverMissingCOs(JsonShip aShipRef) { //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Expected O, but got Unknown if (aShipRef == null) { return; } List list = aShipRef.aItems?.ToList(); List list2 = aShipRef.aCOs?.ToList(); if (list == null || list2 == null) { return; } foreach (JsonItem aItem in list) { if (list2.Find((JsonCondOwnerSave x) => x.strID == aItem.strID) != null || string.IsNullOrEmpty(aItem.strSlotParentID)) { continue; } JsonItem val = list.Find((JsonItem x) => x.strID == aItem.strSlotParentID); JsonCondOwnerSave val2 = list2.Find((JsonCondOwnerSave x) => x.strID == aItem.strSlotParentID); if (val == null || val2 == null) { continue; } if (TryGetCOValue(aItem.strName, out var refCO) && TryGetCOValue(val.strName, out var refCO2) && dictChangesMap.ContainsKey(val.strName) && dictChangesMap[val.strName].ContainsKey("Recover_Missing")) { Debug.Log((object)("#Info# Found the CO [" + aItem.strName + ":" + aItem.strID + "] with missing save data! Creating data from template.")); if (refCO.strType == "Item") { JsonCondOwnerSave val3 = new JsonCondOwnerSave(); val3.strID = aItem.strID; val3.strCODef = aItem.strName; val3.strCondID = aItem.strName + aItem.strID; val3.bAlive = true; val3.inventoryX = 0; val3.inventoryY = 0; val3.fDGasTemp = 0.0; val3.nDestTile = 0; val3.strIdleAnim = "Idle"; val3.fMSRedamageAmount = 0.0; val3.fLastICOUpdate = StarSystem.fEpoch; val3.aConds = refCO.aStartingConds.Concat(new string[1] { "DEFAULT" }).ToArray(); val3.strSlotName = refCO.mapSlotEffects.Intersect(refCO2.aSlotsWeHave).First(); JsonItemDef itemDef = DataHandler.GetItemDef(refCO.strItemDef); val3.strIMGPreview = ((itemDef != null) ? itemDef.strImg : null); JsonCondOwnerSave val4 = val3; if (val4.strIMGPreview == null) { string text = (val4.strIMGPreview = "blank"); } val3.strFriendlyName = refCO.strNameFriendly; val3.strRegIDLast = aShipRef.strRegID; list2.Add(val3); } else { Debug.LogWarning((object)("Warning! The [" + aItem.strName + "] isn't item CO and not supported! Ignoring.")); } } else { Debug.LogWarning((object)("Warning! Template CO [" + aItem.strName + "] for parent or item doesn't exist! Ignoring.")); } } aShipRef.aCOs = list2.ToArray(); } public static void SyncConditions(JsonShip aShipRef) { if (aShipRef == null) { return; } List list = aShipRef.aCOs?.ToList(); if (list == null) { return; } foreach (JsonCondOwnerSave item in list) { if (item == null || !dictChangesMap.ContainsKey(item.strCODef) || !dictChangesMap[item.strCODef].ContainsKey("Sync_Conditions") || dictChangesMap[item.strCODef]["Sync_Conditions"] == null || !TryGetCOValue(item.strCODef, out var refCO)) { continue; } List targetKeys = dictChangesMap[item.strCODef]["Sync_Conditions"].ToList(); bool isInverse = targetKeys.Remove("*IsInverse*"); bool doAll = targetKeys.Count == 0; if (refCO.aStartingConds == null || item.aConds == null || refCO.aStartingConds.Length == 0 || item.aConds.Length < 0) { continue; } List list2 = item.aConds.ToList(); List second = item.aConds.Select((string x) => x.Split('=')[0]).ToList(); List first = (from x in refCO.aStartingConds select x.Split('=')[0] into x where doAll || (!isInverse && targetKeys.Contains(x)) || (isInverse && !targetKeys.Contains(x)) select x).ToList(); List list3 = first.Except(second).ToList(); foreach (string newCondKey in list3) { string text = refCO.aStartingConds.ToList().Find((string x) => x.StartsWith(newCondKey + "=")); Debug.Log((object)("#Info# Saved CO [" + item.strCODef + ":" + item.strID + "] is missing [" + text + "] condition! Syncing to the CO from the template.")); list2.Insert(0, text); } if (list3.Count > 0) { item.aConds = list2.ToArray(); } } aShipRef.aCOs = list.ToArray(); } public static void UpdateConditions(JsonShip aShipRef) { if (aShipRef == null) { return; } List list = aShipRef.aCOs?.ToList(); if (list == null) { return; } foreach (JsonCondOwnerSave item2 in list) { if (item2 == null || !dictChangesMap.ContainsKey(item2.strCODef) || !dictChangesMap[item2.strCODef].ContainsKey("Update_Conditions") || dictChangesMap[item2.strCODef]["Update_Conditions"] == null || !TryGetCOValue(item2.strCODef, out var refCO)) { continue; } List targetKeys = dictChangesMap[item2.strCODef]["Update_Conditions"].ToList(); bool isInverse = targetKeys.Remove("*IsInverse*"); bool doAll = targetKeys.Count == 0; if (refCO.aStartingConds == null || item2.aConds == null || refCO.aStartingConds.Length == 0 || item2.aConds.Length < 0) { continue; } List list2 = item2.aConds.ToList(); List second = item2.aConds.Select((string x) => x.Split('=')[0]).ToList(); List first = (from x in refCO.aStartingConds select x.Split('=')[0] into x where doAll || (!isInverse && targetKeys.Contains(x)) || (isInverse && !targetKeys.Contains(x)) select x).ToList(); List list3 = first.Intersect(second).ToList(); foreach (string extCondKey in list3) { string value = refCO.aStartingConds.ToList().Find((string x) => x.StartsWith(extCondKey + "=")); string item = list2.Find((string x) => x.StartsWith(extCondKey + "=")); Debug.Log((object)("#Info# Saved CO [" + item2.strCODef + ":" + item2.strID + "] condition [" + extCondKey + "] received new value from the template CO.")); list2[list2.IndexOf(item)] = value; } if (list3.Count > 0) { item2.aConds = list2.ToArray(); } } aShipRef.aCOs = list.ToArray(); } public static void SyncSlotEffects(JsonShip aShipRef) { if (aShipRef == null) { return; } List aItemList = aShipRef.aItems?.ToList(); List list = aShipRef.aCOs?.ToList(); if (aItemList == null || list == null) { return; } foreach (JsonCondOwnerSave aSavedCO in list) { if (aSavedCO == null || !dictChangesMap.ContainsKey(aSavedCO.strCODef) || !dictChangesMap[aSavedCO.strCODef].ContainsKey("Sync_Slot_Effects") || dictChangesMap[aSavedCO.strCODef]["Sync_Slot_Effects"] == null || dictChangesMap[aSavedCO.strCODef]["Sync_Slot_Effects"].Count <= 0 || !TryGetCOValue(aSavedCO.strCODef, out var _)) { continue; } List list2 = dictChangesMap[aSavedCO.strCODef]["Sync_Slot_Effects"].Where((string x) => x.Contains("=")).ToList(); List list3 = (from x in dictChangesMap[aSavedCO.strCODef]["Sync_Slot_Effects"] where x.StartsWith("!") select x.Substring(1)).ToList(); List list4 = list.FindAll((JsonCondOwnerSave x) => aItemList.Any((JsonItem i) => i.strSlotParentID == aSavedCO.strID && i.strID == x.strID)); foreach (JsonCondOwnerSave item in list4) { List list5 = ((item.aConds != null) ? item.aConds.ToList() : new List()); foreach (string item2 in list2) { string text = item2.Split("|"[0])[0]; string addCondKey = text.Split("="[0])[0]; List list6 = item2.Split("|"[0]).Skip(1).ToList(); if (!list5.Any((string x) => x.StartsWith(addCondKey + "=")) && (list6.Count == 0 || list6.Contains(item.strCODef))) { Debug.Log((object)("#Info# Saved CO [" + item.strCODef + ":" + item.strID + "] got condition [" + text + "] due to the Parent CO [" + aSavedCO.strCODef + ":" + aSavedCO.strID + "] slot effects.")); list5.Insert(0, text); } } foreach (string item3 in list3) { string text2 = item3.Split("|"[0])[0]; string remCondsKey = text2.Split("="[0])[0]; List list7 = item3.Split("|"[0]).Skip(1).ToList(); if (list5.Any((string x) => x.StartsWith(remCondsKey + "=")) && (list7.Count == 0 || list7.Contains(item.strCODef))) { Debug.Log((object)("#Info# Saved CO [" + item.strCODef + ":" + item.strID + "] lost condition [" + text2 + "] due to the Parent CO [" + aSavedCO.strCODef + ":" + aSavedCO.strID + "] slot effects.")); list5.Remove(list5.Find((string x) => x.StartsWith(remCondsKey + "="))); } } if (list2.Count > 0 || list3.Count > 0) { item.aConds = list5.ToArray(); } } } } public static void SyncInvEffects(JsonShip aShipRef) { if (aShipRef == null) { return; } List aItemList = aShipRef.aItems?.ToList(); List list = aShipRef.aCOs?.ToList(); if (aItemList == null || list == null) { return; } foreach (JsonCondOwnerSave aSavedCO in list) { if (aSavedCO == null || !dictChangesMap.ContainsKey(aSavedCO.strCODef) || !dictChangesMap[aSavedCO.strCODef].ContainsKey("Sync_Inv_Effects") || dictChangesMap[aSavedCO.strCODef]["Sync_Inv_Effects"] == null || dictChangesMap[aSavedCO.strCODef]["Sync_Inv_Effects"].Count <= 0 || !TryGetCOValue(aSavedCO.strCODef, out var _)) { continue; } List list2 = dictChangesMap[aSavedCO.strCODef]["Sync_Inv_Effects"].Where((string x) => x.Contains("=")).ToList(); List list3 = (from x in dictChangesMap[aSavedCO.strCODef]["Sync_Inv_Effects"] where x.StartsWith("!") select x.Substring(1)).ToList(); List list4 = list.FindAll((JsonCondOwnerSave x) => aItemList.Any((JsonItem i) => i.strParentID == aSavedCO.strID && i.strID == x.strID)); foreach (JsonCondOwnerSave item in list4) { List list5 = ((item.aConds != null) ? item.aConds.ToList() : new List()); foreach (string item2 in list2) { string text = item2.Split("|"[0])[0]; string addCondKey = text.Split("="[0])[0]; List list6 = item2.Split("|"[0]).Skip(1).ToList(); if (!list5.Any((string x) => x.StartsWith(addCondKey + "=")) && (list6.Count == 0 || list6.Contains(item.strCODef))) { Debug.Log((object)("#Info# Saved CO [" + item.strCODef + ":" + item.strID + "] got condition [" + text + "] due to the Parent CO [" + aSavedCO.strCODef + ":" + aSavedCO.strID + "] inventory effects.")); list5.Insert(0, text); } } foreach (string item3 in list3) { string text2 = item3.Split("|"[0])[0]; string remCondsKey = text2.Split("="[0])[0]; List list7 = item3.Split("|"[0]).Skip(1).ToList(); if (list5.Any((string x) => x.StartsWith(remCondsKey + "=")) && (list7.Count == 0 || list7.Contains(item.strCODef))) { Debug.Log((object)("#Info# Saved CO [" + item.strCODef + ":" + item.strID + "] lost condition [" + text2 + "] due to the Parent CO [" + aSavedCO.strCODef + ":" + aSavedCO.strID + "] inventory effects.")); list5.Remove(list5.Find((string x) => x.StartsWith(remCondsKey + "="))); } } if (list2.Count > 0 || list3.Count > 0) { item.aConds = list5.ToArray(); } } } } } public class patch_Ship : Ship { [MonoModIgnore] public extern patch_Ship(GameObject go); public extern void orig_InitShip(bool bTemplateOnly, Loaded nLoad, string strRegIDNew = null); public void InitShip(bool bTemplateOnly, Loaded nLoad, string strRegIDNew = null) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) if (FFU_BR_Defs.ModSyncLoading && base.json != null) { patch_DataHandler.SwitchSlottedItems(base.json, bTemplateOnly); patch_DataHandler.RecoverMissingItems(base.json); if (!bTemplateOnly) { patch_DataHandler.RecoverMissingCOs(base.json); patch_DataHandler.SyncConditions(base.json); patch_DataHandler.UpdateConditions(base.json); patch_DataHandler.SyncSlotEffects(base.json); patch_DataHandler.SyncInvEffects(base.json); } } orig_InitShip(bTemplateOnly, nLoad, strRegIDNew); } } public class patch_JsonSimple : JsonSimple { public string strReference { get; set; } } public class patch_JsonColor : JsonColor { public string strReference { get; set; } } public class patch_JsonGasRespire : JsonGasRespire { public string strReference { get; set; } } public class patch_JsonPowerInfo : JsonPowerInfo { public string strReference { get; set; } } public class patch_JsonGUIPropMap : JsonGUIPropMap { public string strReference { get; set; } } public class patch_JsonCond : JsonCond { public string strReference { get; set; } } public class patch_JsonItemDef : JsonItemDef { public string strReference { get; set; } } public class patch_CondTrigger : CondTrigger { [MonoModPublic] [MonoModIgnore] public string strFailReason; public string strReference { get; set; } } public class patch_JsonInteraction : JsonInteraction { public string strReference { get; set; } } public class patch_JsonCondOwner : JsonCondOwner { public string strReference { get; set; } } public class patch_JsonRoomSpec : JsonRoomSpec { public string strReference { get; set; } } public class patch_JsonShip : JsonShip { public string strReference { get; set; } } public class patch_Loot : Loot { public string strReference { get; set; } [MonoModReplace] private List> ParseLootDef(string[] aIn) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown List> list = new List>(); foreach (string text in aIn) { if (text == "") { continue; } string[] array = text.Split('|'); List list2 = new List(); string[] array2 = array; foreach (string text2 in array2) { LootUnit val = new LootUnit(); val.bPositive = true; string text3 = text2; if (text[0] == '-') { val.bPositive = false; text3 = text2.Substring(1); } string[] array3 = text3.Split('='); val.strName = array3[0]; if (array3.Length < 2) { if (FFU_BR_Defs.SyncLogging >= FFU_BR_Defs.SyncLogs.DeepCopy) { Debug.Log((object)("#Info# Loot entry '" + ((Loot)this).strName + "' is for patching only and not saved as permanent data.")); } return new List>(); } array3 = array3[1].Split('x'); float.TryParse(array3[0], out val.fChance); if (val.fChance < 0f) { JsonLogger.ReportProblem("[" + ((Loot)this).strName + "] " + text2 + " (loot definition chance can't be negative)", (ReportTypes)1); continue; } if (array3.Length < 2) { JsonLogger.ReportProblem("[" + ((Loot)this).strName + "] " + text2 + " (loot definition is shorter than expected)", (ReportTypes)1); continue; } float result = 0f; if (array3[1].StartsWith("-")) { JsonLogger.ReportProblem("[" + ((Loot)this).strName + "] " + text2 + " (loot definition base value can't be negative)", (ReportTypes)1); continue; } array3 = array3[1].Split('-'); if (float.TryParse(array3[0], out result)) { val.fMin = result; } if (array3.Length > 1) { result = 0f; if (array3.Length > 2) { JsonLogger.ReportProblem("[" + ((Loot)this).strName + "] " + text2 + " (loot definition value is longer than expected)", (ReportTypes)1); continue; } if (float.TryParse(array3[1], out result)) { val.fMax = result; } } if (val.fMax < val.fMin) { val.fMax = val.fMin; } list2.Add(val); } list.Add(list2); } return list; } } public class patch_JsonProductionMap : JsonProductionMap { public string strReference { get; set; } } public class patch_JsonMarketActorConfig : JsonMarketActorConfig { public string strReference { get; set; } } public class patch_JsonCargoSpec : JsonCargoSpec { public string strReference { get; set; } } public class patch_JsonHomeworld : JsonHomeworld { public string strReference { get; set; } } public class patch_JsonCareer : JsonCareer { public string strReference { get; set; } } public class patch_JsonLifeEvent : JsonLifeEvent { public string strReference { get; set; } } public class patch_JsonPersonSpec : JsonPersonSpec { public string strReference { get; set; } } public class patch_JsonShipSpec : JsonShipSpec { public string strReference { get; set; } } public class patch_JsonSlotEffects : JsonSlotEffects { public string strReference { get; set; } } public class patch_JsonSlot : JsonSlot { public string strReference { get; set; } } public class patch_JsonTicker : JsonTicker { public string strReference { get; set; } } public class patch_CondRule : CondRule { public string strReference { get; set; } } public class patch_JsonAudioEmitter : JsonAudioEmitter { public string strReference { get; set; } } public class patch_JsonAd : JsonAd { public string strReference { get; set; } } public class patch_JsonHeadline : JsonHeadline { public string strReference { get; set; } } public class patch_JsonMusic : JsonMusic { public string strReference { get; set; } } public class patch_JsonCOOverlay : JsonCOOverlay { public string strReference { get; set; } } public class patch_JsonDCOCollection : JsonDCOCollection { public string strReference { get; set; } } public class patch_JsonLedgerDef : JsonLedgerDef { public string strReference { get; set; } } public class patch_JsonPledge : JsonPledge { public string strReference { get; set; } } public class patch_JsonJobItems : JsonJobItems { public string strReference { get; set; } } public class patch_JsonJob : JsonJob { public string strReference { get; set; } } public class patch_JsonAIPersonality : JsonAIPersonality { public string strReference { get; set; } } public class patch_JsonTransit : JsonTransit { public string strReference { get; set; } } public class patch_JsonPlotManagerSettings : JsonPlotManagerSettings { public string strReference { get; set; } } public class patch_JsonStarSystemSave : JsonStarSystemSave { public string strReference { get; set; } } public class patch_JsonParallax : JsonParallax { public string strReference { get; set; } } public class patch_JsonContext : JsonContext { public string strReference { get; set; } } public class patch_JsonChargeProfile : JsonChargeProfile { public string strReference { get; set; } } public class patch_JsonWound : JsonWound { public string strReference { get; set; } } public class patch_JsonAttackMode : JsonAttackMode { public string strReference { get; set; } } public class patch_JsonPDAAppIcon : JsonPDAAppIcon { public string strReference { get; set; } } public class patch_JsonZoneTrigger : JsonZoneTrigger { public string strReference { get; set; } } public class patch_JsonTip : JsonTip { public string strReference { get; set; } } public class patch_JsonCrime : JsonCrime { public string strReference { get; set; } } public class patch_JsonPlot : JsonPlot { public string strReference { get; set; } } public class patch_JsonPlotBeat : JsonPlotBeat { public string strReference { get; set; } } public class patch_JsonRaceTrack : JsonRaceTrack { public string strReference { get; set; } } public class patch_JsonRacingLeague : JsonRacingLeague { public string strReference { get; set; } } public class patch_JsonInfoNode : JsonInfoNode { public string strReference { get; set; } } public class patch_JsonInstallable : JsonInstallable { public string strReference { get; set; } } public class patch_JsonInteractionOverride : JsonInteractionOverride { public string strReference { get; set; } } public class patch_JsonPlotBeatOverride : JsonPlotBeatOverride { public string strReference { get; set; } } public class patch_JsonVerbs : JsonVerbs { public string strReference { get; set; } } public class patch_JsonCustomTokens : JsonCustomTokens { public string strReference { get; set; } } public class patch_JsonAsteroidBlueprint : JsonAsteroidBlueprint { public string strReference { get; set; } } public class patch_JsonAsteroidClusterBlueprint : JsonAsteroidClusterBlueprint { public string strReference { get; set; } } public class patch_JsonExplosion : JsonExplosion { public string strReference { get; set; } } public class patch_JsonLight : JsonLight { public string strReference { get; set; } } public class patch_JsonMusicStation : JsonMusicStation { public string strReference { get; set; } } public class patch_JsonShipAttack : JsonShipAttack { public string strReference { get; set; } } public class patch_JsonCondTrigger : JsonCondTrigger { public string strReference { get; set; } } public class patch_JsonLoot : JsonLoot { public string strReference { get; set; } } public class patch_CondOwner : CondOwner { [MonoModPublic] [MonoModIgnore] public List aTickers; [MonoModPublic] [MonoModIgnore] public Dictionary mapCondRules; [MonoModPublic] [MonoModIgnore] public extern void UpdateStats(); } public class patch_Slots : Slots { [MonoModPublic] [MonoModIgnore] public TrackingCollection aSlots; } public class patch_Slot : Slot { [MonoModPublic] [MonoModIgnore] public TrackingCollection aSlots; [MonoModIgnore] public extern patch_Slot(JsonSlot jslot); } public class patch_Powered : Powered { [MonoModPublic] [MonoModIgnore] public CondTrigger ctPowerSource; } namespace LitJson { public class patch_JsonMapper : JsonMapper { [MonoModReplace] private static object ReadValue(Type inst_type, JsonReader reader) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Invalid comparison between Unknown and I4 //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Invalid comparison between Unknown and I4 //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Invalid comparison between Unknown and I4 //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Invalid comparison between Unknown and I4 //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Invalid comparison between Unknown and I4 //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Invalid comparison between Unknown and I4 //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Invalid comparison between Unknown and I4 //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Invalid comparison between Unknown and I4 //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Invalid comparison between Unknown and I4 //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Invalid comparison between Unknown and I4 //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_03ef: Unknown result type (might be due to invalid IL or missing references) //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_0466: Unknown result type (might be due to invalid IL or missing references) //IL_0426: Unknown result type (might be due to invalid IL or missing references) //IL_040e: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Invalid comparison between Unknown and I4 //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Unknown result type (might be due to invalid IL or missing references) //IL_03c4: Unknown result type (might be due to invalid IL or missing references) reader.Read(); if (JsonMapper.bVerbose && reader.Value != null) { Debug.Log((object)reader.Value.ToString()); } if ((int)reader.Token == 5) { return null; } Type underlyingType = Nullable.GetUnderlyingType(inst_type); Type type = underlyingType ?? inst_type; if ((int)reader.Token == 12) { if (inst_type.IsClass || underlyingType != null) { return null; } throw new JsonException($"Can't assign null to an instance of type {inst_type}"); } if ((int)reader.Token == 8 || (int)reader.Token == 6 || (int)reader.Token == 9 || (int)reader.Token == 7 || (int)reader.Token == 10 || (int)reader.Token == 11) { Type type2 = reader.Value.GetType(); if (type.IsAssignableFrom(type2)) { return reader.Value; } if (JsonMapper.custom_importers_table.TryGetValue(type2, out var value) && value.TryGetValue(type, out var value2)) { return value2.Invoke(reader.Value); } if (JsonMapper.base_importers_table.TryGetValue(type2, out value) && value.TryGetValue(type, out value2)) { return value2.Invoke(reader.Value); } if (type.IsEnum) { return Enum.ToObject(type, reader.Value); } MethodInfo convOp = JsonMapper.GetConvOp(type, type2); if (convOp != null) { return convOp.Invoke(null, new object[1] { reader.Value }); } throw new JsonException($"Can't assign value '{reader.Value}' (type {type2}) to type {inst_type}"); } object obj = null; if ((int)reader.Token == 4) { JsonMapper.AddArrayMetadata(inst_type); ArrayMetadata val = JsonMapper.array_metadata[inst_type]; if (!((ArrayMetadata)(ref val)).IsArray && !((ArrayMetadata)(ref val)).IsList) { throw new JsonException($"Type {inst_type} can't act as an array"); } IList list; Type elementType; if (!((ArrayMetadata)(ref val)).IsArray) { list = (IList)Activator.CreateInstance(inst_type); elementType = ((ArrayMetadata)(ref val)).ElementType; } else { list = new ArrayList(); elementType = inst_type.GetElementType(); } while (true) { object obj2 = ReadValue(elementType, reader); if (obj2 == null && (int)reader.Token == 5) { break; } list.Add(obj2); } if (((ArrayMetadata)(ref val)).IsArray) { int count = list.Count; obj = Array.CreateInstance(elementType, count); for (int i = 0; i < count; i++) { ((Array)obj).SetValue(list[i], i); } } else { obj = list; } } else if ((int)reader.Token == 1) { JsonMapper.AddObjectMetadata(type); ObjectMetadata val2 = JsonMapper.object_metadata[type]; obj = Activator.CreateInstance(type); while (true) { reader.Read(); if ((int)reader.Token == 3) { break; } string text = (string)reader.Value; if (((ObjectMetadata)(ref val2)).Properties.TryGetValue(text, out var value3)) { if (value3.IsField) { FieldInfo fieldInfo = (FieldInfo)value3.Info; if (!fieldInfo.IsLiteral && !fieldInfo.IsInitOnly) { fieldInfo.SetValue(obj, ReadValue(value3.Type, reader)); } else { ReadValue(value3.Type, reader); } } else { PropertyInfo propertyInfo = (PropertyInfo)value3.Info; if (propertyInfo.CanWrite) { propertyInfo.SetValue(obj, ReadValue(value3.Type, reader), null); } else { ReadValue(value3.Type, reader); } } } else if (!((ObjectMetadata)(ref val2)).IsDictionary) { if (!reader.SkipNonMembers) { throw new JsonException($"The type {inst_type} doesn't have the property '{text}'"); } JsonMapper.ReadSkip(reader); } else { ((IDictionary)obj).Add(text, ReadValue(((ObjectMetadata)(ref val2)).ElementType, reader)); } } } return obj; } private static void WriteSafe(object obj, JsonWriter writer, bool writer_is_private, int depth) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_04e1: Unknown result type (might be due to invalid IL or missing references) //IL_04e6: Unknown result type (might be due to invalid IL or missing references) //IL_04e9: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0654: Unknown result type (might be due to invalid IL or missing references) //IL_04fa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_07a8: Unknown result type (might be due to invalid IL or missing references) //IL_062e: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) if (depth > JsonMapper.max_nesting_depth) { throw new JsonException($"Max allowed object depth reached while trying to export from type {obj.GetType()}"); } if (obj == null) { writer.Write((string)null); return; } if (obj is IJsonWrapper) { if (writer_is_private) { writer.TextWriter.Write(((IJsonWrapper)obj).ToJson()); } else { ((IJsonWrapper)obj).ToJson(writer); } return; } if (obj is Vector2) { writer.Write((Vector2)obj); return; } if (obj is Vector3) { writer.Write((Vector3)obj); return; } if (obj is Vector4) { writer.Write((Vector4)obj); return; } if (obj is Quaternion) { writer.Write((Quaternion)obj); return; } if (obj is Matrix4x4) { writer.Write((Matrix4x4)obj); return; } if (obj is Ray) { writer.Write((Ray)obj); return; } if (obj is RaycastHit) { writer.Write((RaycastHit)obj); return; } if (obj is Color) { writer.Write((Color)obj); return; } if (obj is Point) { writer.WritePoint((Point)obj); return; } if (obj is string) { writer.Write((string)obj); return; } if (obj is float) { writer.Write((float)obj); return; } if (obj is double) { writer.Write((double)obj); return; } if (obj is int) { writer.Write((int)obj); return; } if (obj is bool) { writer.Write((bool)obj); return; } if (obj is long) { writer.Write((long)obj); return; } if (obj is Array) { writer.WriteArrayStart(); foreach (object item in (Array)obj) { JsonMapper.WriteValue(item, writer, writer_is_private, depth + 1); } writer.WriteArrayEnd(); return; } if (obj is IList) { writer.WriteArrayStart(); foreach (object item2 in (IList)obj) { JsonMapper.WriteValue(item2, writer, writer_is_private, depth + 1); } writer.WriteArrayEnd(); return; } if (obj is IDictionary) { writer.WriteObjectStart(); foreach (DictionaryEntry item3 in (IDictionary)obj) { writer.WritePropertyName((string)item3.Key); JsonMapper.WriteValue(item3.Value, writer, writer_is_private, depth + 1); } writer.WriteObjectEnd(); return; } Type type = obj.GetType(); if (JsonMapper.custom_exporters_table.ContainsKey(type)) { JsonMapper.custom_exporters_table[type].Invoke(obj, writer); return; } if (JsonMapper.base_exporters_table.ContainsKey(type)) { JsonMapper.base_exporters_table[type].Invoke(obj, writer); return; } if (obj is Enum) { Type underlyingType = Enum.GetUnderlyingType(type); if (underlyingType == typeof(long) || underlyingType == typeof(uint) || underlyingType == typeof(ulong)) { writer.Write((ulong)obj); } else { writer.Write((int)obj); } return; } JsonMapper.AddTypeProperties(type); IList list = JsonMapper.type_properties[type]; writer.WriteObjectStart(); foreach (PropertyMetadata item4 in list) { if (item4.IsField) { FieldInfo fieldInfo = (FieldInfo)item4.Info; object obj2 = null; try { obj2 = fieldInfo.GetValue(obj); } catch { if (FFU_BR_Defs.JsonLogging) { string text = fieldInfo.DeclaringType?.FullName ?? ""; string text2 = fieldInfo.Name ?? ""; string text3 = obj?.GetType()?.FullName ?? ""; Debug.Log((object)("#Parser# Failed to Write Field: " + text + "." + text2 + " while serializing " + text3)); } continue; } if (obj2 != null && (!(obj2 is Array) || ((Array)obj2).Length != 0) && (!(obj2 is IList) || ((IList)obj2).Count != 0) && (!(obj2 is IDictionary) || ((IDictionary)obj2).Count != 0) && !fieldInfo.IsLiteral && !fieldInfo.IsInitOnly && !fieldInfo.IsStatic) { writer.WritePropertyName(item4.Info.Name); JsonMapper.WriteValue(obj2, writer, writer_is_private, depth + 1); } continue; } PropertyInfo propertyInfo = (PropertyInfo)item4.Info; object obj4 = null; try { obj4 = propertyInfo.GetValue(obj, null); } catch { if (FFU_BR_Defs.JsonLogging) { string text4 = propertyInfo.DeclaringType?.FullName ?? ""; string text5 = propertyInfo.Name ?? ""; string text6 = propertyInfo.GetGetMethod()?.Name ?? ""; string text7 = obj?.GetType()?.FullName ?? ""; Debug.Log((object)("#Parser# Failed to Write Property: " + text4 + "." + text5 + "/" + text6 + " while serializing " + text7)); } continue; } if (obj4 != null && (!(obj4 is Array) || ((Array)obj4).Length != 0) && (!(obj4 is IList) || ((IList)obj4).Count != 0) && (!(obj4 is IDictionary) || ((IDictionary)obj4).Count != 0) && propertyInfo.CanRead && propertyInfo.CanWrite) { writer.WritePropertyName(item4.Info.Name); JsonMapper.WriteValue(obj4, writer, writer_is_private, depth + 1); } } writer.WriteObjectEnd(); } public static string ToCopy(object obj) { lock (JsonMapper.static_writer_lock) { JsonMapper.static_writer.Reset(); WriteSafe(obj, JsonMapper.static_writer, writer_is_private: true, 0); return ((object)JsonMapper.static_writer).ToString(); } } } } namespace FFU_Beyond_Reach { public static class FFU_BR_API { public static Dictionary ModAPIs; public static readonly object FFU_BR_Core; } public static class FFU_BR_Defs { public enum SyncLogs { None, ModChanges, DeepCopy, ModdedDump, ExtendedDump, ContentDump, SourceDump } public enum ActLogs { None, Interactions, Triggers, Runtime } public static readonly string ModName = "Fight For Universe: Beyond Reach"; public static readonly string ModVersion = "0.6.0.0"; public static Version GameVersion; public static readonly string ModFixes = "Minor_Fixes_Plus"; public static readonly string ModFixesURL = "https://git.soon-tm.info/warstalker/FFU-BR-Data/-/releases"; private static ConfigFile ModDefs = null; public static SyncLogs SyncLogging = SyncLogs.None; public static ActLogs ActLogging = ActLogs.None; public static bool JsonLogging = false; public static bool NoCoreDuplicates = false; public static bool DynamicRandomRange = true; public static int MaxLogTextSize = 16382; public static bool ModSyncLoading = true; public static bool ModifyUpperLimit = false; public static float BonusUpperLimit = 1000f; public static float SuitOxygenNotify = 10f; public static float SuitPowerNotify = 15f; public static bool ShowEachO2Battery = true; public static bool StrictInvSorting = true; public static bool AltTempEnabled = true; public static string AltTempSymbol = "C"; public static float AltTempMult = 1f; public static float AltTempShift = -273.15f; public static bool TowBraceAllowsKeep = true; public static bool OrgInventoryMode = false; public static float[] OrgInventoryTweaks = new float[4] { 0.5f, -30f, 0f, 0f }; public static bool BetterInvTransfer = true; public static bool QuickBarPinning = false; public static float[] QuickBarTweaks = new float[3] { -495f, 340f, 1f }; public static bool NoSkillTraitCost = false; public static bool AllowSuperChars = false; public static float SuperCharMultiplier = 10f; public static string[] SuperCharacters = new string[2] { "Exact Char Name One", "Exact Char Name Two" }; public const string SYM_DIV = "|"; public const string SYM_EQU = "="; public const string SYM_IGN = "*"; public const string SYM_INV = "!"; public const string CMD_SWITCH_SLT = "Switch_Slotted"; public const string CMD_REC_MISSING = "Recover_Missing"; public const string CMD_CONDS_SYN = "Sync_Conditions"; public const string CMD_CONDS_UPD = "Update_Conditions"; public const string CMD_EFFECT_SLT = "Sync_Slot_Effects"; public const string CMD_EFFECT_INV = "Sync_Inv_Effects"; public const string FLAG_INVERSE = "*IsInverse*"; public const string OPT_DEL = "~"; public const string OPT_MOD = "*"; public const string OPT_REM = "-"; public static void ListModdingAPIs() { foreach (KeyValuePair modAPI in FFU_BR_API.ModAPIs) { Debug.Log((object)$"Loaded Modding API: {modAPI.Key} v{modAPI.Value}"); } } public static void LoadModdingAPIs() { Type typeFromHandle = typeof(FFU_BR_API); if (FFU_BR_API.ModAPIs == null) { FFU_BR_API.ModAPIs = new Dictionary(); } FFU_BR_API.ModAPIs.Add("Base_Game", GameVersion); FieldInfo[] fields = typeFromHandle.GetFields(BindingFlags.Static | BindingFlags.Public); FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { string name = fieldInfo.Name; if (1 == 0) { } bool flag; switch (name) { case "FFU_BR_Core": case "FFU_BR_Console": case "FFU_BR_Extended": case "FFU_BR_Fixes": case "FFU_BR_Quality": case "FFU_BR_Super": flag = true; break; default: flag = false; break; } if (1 == 0) { } if (flag) { FFU_BR_API.ModAPIs.Add(fieldInfo.Name, new Version(ModVersion)); } } } public static void InitConfig() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown ModDefs = new ConfigFile(Path.Combine(Paths.ConfigPath, "FFU_Beyond_Reach.cfg"), true); LoadModdingAPIs(); Debug.Log((object)(ModName + " v" + ModVersion)); Debug.Log((object)"Loading Mod Configuration..."); SyncLogging = ModDefs.Bind("ConfigSettings", "SyncLogging", SyncLogging, "Defines what changes will be shown in the log during sync loading.").Value; ActLogging = ModDefs.Bind("ConfigSettings", "ActLogging", ActLogging, "Defines what activity will be shown in the log during gameplay/runtime.").Value; JsonLogging = ModDefs.Bind("ConfigSettings", "JsonLogging", JsonLogging, "Defines if JSON parsing errors will be shown in the log during loading.").Value; NoCoreDuplicates = ModDefs.Bind("ConfigSettings", "NoCoreDuplicates", NoCoreDuplicates, "Defines if default JSON loading behavior is allowed, when newer core entry completely overwrites previously loaded core entry without regard for the contents.").Value; DynamicRandomRange = ModDefs.Bind("ConfigSettings", "DynamicRandomRange", DynamicRandomRange, "By default loot random range is limited to 1f, thus preventing use of loot tables, if total sum of their chances goes beyond 1f. This feature allows to increase max possible random range beyond 1f, to the total sum of all chances in the loot table.").Value; MaxLogTextSize = ModDefs.Bind("ConfigSettings", "MaxLogTextSize", MaxLogTextSize, "Defines the max length of the text in the console. May impact performance.").Value; ModSyncLoading = ModDefs.Bind("ConfigSettings", "ModSyncLoading", ModSyncLoading, "Enables smart loading of modified COs and synchronizing of existing CO saved data with updated CO templates, if they are mapped in the mod info file.").Value; ModifyUpperLimit = ModDefs.Bind("GameplaySettings", "ModifyUpperLimit", ModifyUpperLimit, "Allows to change skill and trait modifier upper limit value.").Value; BonusUpperLimit = ModDefs.Bind("GameplaySettings", "BonusUpperLimit", BonusUpperLimit, "Defines the upper limit for skill and trait modifier. Original value is 10.").Value; SuitOxygenNotify = ModDefs.Bind("GameplaySettings", "SuitOxygenNotify", SuitOxygenNotify, "Specifies the oxygen level threshold (as a percentage) for the gauge of a sealed/airtight suit. When the oxygen level falls below this threshold, the wearer will receive a notification (via occasional beeps) about oxygen usage. If set to 0, no notification will be given at any time.").Value; SuitPowerNotify = ModDefs.Bind("GameplaySettings", "SuitPowerNotify", SuitPowerNotify, "Specifies the power level threshold (as a percentage) for the gauge of a sealed/airtight suit. When the power level falls below this threshold, the wearer will receive a notification (via frequent beeps) about power usage. If set to 0, no notification will be given at any time.").Value; ShowEachO2Battery = ModDefs.Bind("GameplaySettings", "ShowEachO2Battery", ShowEachO2Battery, "Defines whether to show average percentage across all O2/Batteries or calculate each O2/Battery independently and summarize their percentages. Affects how soon notifications will begin.").Value; StrictInvSorting = ModDefs.Bind("GameplaySettings", "StrictInvSorting", StrictInvSorting, "Enables custom, order-based inventory windows sorting that enforces strict UI rendering order.").Value; Debug.Log((object)$"GameplaySettings => ModifyUpperLimit: {ModifyUpperLimit}"); Debug.Log((object)$"GameplaySettings => BonusUpperLimit: {BonusUpperLimit}"); Debug.Log((object)$"GameplaySettings => SuitOxygenNotify: {SuitOxygenNotify}%"); Debug.Log((object)$"GameplaySettings => SuitPowerNotify: {SuitPowerNotify}%"); Debug.Log((object)$"GameplaySettings => ShowEachO2Battery: {ShowEachO2Battery}"); Debug.Log((object)$"GameplaySettings => StrictInvSorting: {StrictInvSorting}"); AltTempEnabled = ModDefs.Bind("QualitySettings", "AltTempEnabled", AltTempEnabled, "Allows to show temperature in alternative measure beside Kelvin value.").Value; AltTempSymbol = ModDefs.Bind("QualitySettings", "AltTempSymbol", AltTempSymbol, "What symbol will represent alternative temperature measure.").Value; AltTempMult = ModDefs.Bind("QualitySettings", "AltTempMult", AltTempMult, "Alternative temperature multiplier for conversion from Kelvin.").Value; AltTempShift = ModDefs.Bind("QualitySettings", "AltTempShift", AltTempShift, "Alternative temperature value shift for conversion from Kelvin.").Value; TowBraceAllowsKeep = ModDefs.Bind("QualitySettings", "TowBraceAllowsKeep", TowBraceAllowsKeep, "Allows to use station keeping command, while tow braced to another vessel.").Value; OrgInventoryMode = ModDefs.Bind("QualitySettings", "OrgInventoryMode", OrgInventoryMode, "Changes inventory layout and makes smart use of available space.").Value; string value = ModDefs.Bind("QualitySettings", "OrgInventoryTweaks", string.Join("|", Array.ConvertAll(OrgInventoryTweaks, (float n) => n.ToString())), "Inventory offsets for tweaking: Top Offset, Bottom Limit, Horizontal Padding, Vertical Padding.").Value; if (value.Split('|').Length == 4) { OrgInventoryTweaks = Array.ConvertAll(value.Split('|'), (string x) => float.TryParse(x, out var result) ? result : 0f); } BetterInvTransfer = ModDefs.Bind("QualitySettings", "BetterInvTransfer", BetterInvTransfer, "Changes behavior of shift-click item transferring in inventory. Items will be auto-transferred to the last inventory window, where player has placed the item manually. Last inventory window is forgotten, when inventory is closed.").Value; QuickBarPinning = ModDefs.Bind("QualitySettings", "QuickBarPinning", QuickBarPinning, "Allows to permanently lock the interactions quick bar, where you desire.").Value; string value2 = ModDefs.Bind("QualitySettings", "QuickBarTweaks", string.Join("|", Array.ConvertAll(QuickBarTweaks, (float n) => n.ToString())), "Quick Bar offsets for tweaking: Horizontal, Vertical, Expanded.").Value; if (value2.Split('|').Length == 3) { QuickBarTweaks = Array.ConvertAll(value2.Split('|'), (string x) => float.TryParse(x, out var result) ? result : 0f); } Debug.Log((object)$"QualitySettings => AltTempEnabled: {AltTempEnabled}"); Debug.Log((object)$"QualitySettings => AltTempSymbol: {AltTempEnabled}"); Debug.Log((object)$"QualitySettings => AltTempMult: {AltTempMult}"); Debug.Log((object)$"QualitySettings => AltTempShift: {AltTempShift}"); Debug.Log((object)$"QualitySettings => TowBraceAllowsKeep: {TowBraceAllowsKeep}"); Debug.Log((object)$"QualitySettings => OrgInventoryMode: {OrgInventoryMode}"); Debug.Log((object)("QualitySettings => OrgInventoryTweaks: " + string.Join(", ", Array.ConvertAll(OrgInventoryTweaks, (float x) => x.ToString())))); Debug.Log((object)$"QualitySettings => BetterInvTransfer: {BetterInvTransfer}"); Debug.Log((object)$"QualitySettings => QuickBarPinning: {QuickBarPinning}"); Debug.Log((object)("QualitySettings => QuickBarTweaks: " + string.Join(", ", Array.ConvertAll(QuickBarTweaks, (float x) => x.ToString())))); NoSkillTraitCost = ModDefs.Bind("SuperSettings", "NoSkillTraitCost", NoSkillTraitCost, "Makes all trait and/or skill changes free, regardless of their cost.").Value; AllowSuperChars = ModDefs.Bind("SuperSettings", "AllowSuperChars", AllowSuperChars, "Allows existence of super characters with extreme performance bonuses.").Value; SuperCharMultiplier = ModDefs.Bind("SuperSettings", "SuperCharMultiplier", SuperCharMultiplier, "Defines the bonus multiplier for super characters performance.").Value; string value3 = ModDefs.Bind("SuperSettings", "SuperCharacters", string.Join("|", SuperCharacters), "Lower-case list of super characters that will receive boost on name basis.").Value; if (!string.IsNullOrEmpty(value3)) { SuperCharacters = value3.Split('|'); } Debug.Log((object)$"SuperSettings => NoSkillTraitCost: {NoSkillTraitCost}"); Debug.Log((object)$"SuperSettings => AllowSuperChars: {AllowSuperChars}"); Debug.Log((object)$"SuperSettings => SuperCharMultiplier: {SuperCharMultiplier}"); Debug.Log((object)("SuperSettings => SuperCharacters: " + string.Join(", ", SuperCharacters))); } } public static class VersionHelpers { public enum OP { NA, GT, GE, LT, LE, EQ, NE } public static bool GT(this Version v1, Version v2) { return v1.Normal().CompareTo(v2.Normal()) > 0; } public static bool GE(this Version v1, Version v2) { return v1.Normal().CompareTo(v2.Normal()) >= 0; } public static bool LT(this Version v1, Version v2) { return v1.Normal().CompareTo(v2.Normal()) < 0; } public static bool LE(this Version v1, Version v2) { return v1.Normal().CompareTo(v2.Normal()) <= 0; } public static bool EQ(this Version v1, Version v2) { return v1.Normal().Equals(v2.Normal()); } public static bool NE(this Version v1, Version v2) { return !v1.Normal().Equals(v2.Normal()); } public static Version SafeVersion(this string vStr) { if (StringExt.IsNullOrEmpty(vStr)) { return new Version("0.0.0.0"); } vStr = Regex.Replace(vStr, "[^0-9.]", string.Empty); if (!vStr.Contains('.')) { vStr += ".0"; } if (vStr.StartsWith('.')) { vStr = "0" + vStr; } if (vStr.EndsWith('.')) { vStr += "0"; } return new Version(vStr); } public static Version Normal(this Version v) { if ((object)v == null) { return new Version("0.0.0.0"); } return new Version(v.Major, v.Minor, (v.Build >= 0) ? v.Build : 0, (v.Revision >= 0) ? v.Revision : 0); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }