Decompiled source of FFU Core v0.6.0

monomod/Assembly-CSharp.FFU_BR.mm.dll

Decompiled 13 hours ago
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<string, string[]> removeIds { get; set; }

	public Dictionary<string, Dictionary<string, string[]>> 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<string, Dictionary<string, List<string>>> dictChangesMap;

	public static List<string> listLockedCOs = new List<string>();

	[MonoModIgnore]
	public static Dictionary<string, patch_JsonModInfo> 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<CondOwner> 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<string, Dictionary<string, List<string>>>();
		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<JsonUserSettings>(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<string, JsonShip> 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<JsonModList>(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<string> 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<string>();
			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<string> 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<string, patch_JsonModInfo> dictionary = new Dictionary<string, patch_JsonModInfo>();
			string text2 = Path.Combine(text, "mod_info.json");
			if (File.Exists(text2))
			{
				DataHandler.JsonToData<patch_JsonModInfo>(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<string, patch_JsonModInfo>.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<string> 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<string> list = new List<string>();
			List<string> list2 = (from MI in dictModInfos.Values
				where !MI.IsIgnoredEntry() && !StringExt.IsNullOrEmpty(((JsonModInfo)MI).strName.GetID())
				select ((JsonModInfo)MI).strName.GetID()).ToList();
			List<string> 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<string, patch_JsonModInfo> 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<string, patch_JsonModInfo> 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<string, Version> 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<string, patch_JsonModInfo> 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<string, Version> 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<string, patch_JsonModInfo> dictModInfo4 in dictModInfos)
		{
			if (dictModInfo4.Key.IsCoreEntry() || dictModInfo4.Value.IsIgnoredEntry() || dictModInfo4.Value?.changesMap == null)
			{
				continue;
			}
			foreach (KeyValuePair<string, Dictionary<string, string[]>> item2 in dictModInfo4.Value.changesMap)
			{
				if (!dictChangesMap.ContainsKey(item2.Key))
				{
					dictChangesMap[item2.Key] = new Dictionary<string, List<string>>();
				}
				if (item2.Value == null)
				{
					continue;
				}
				foreach (KeyValuePair<string, string[]> 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<string>();
						}
						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<string, List<string>>();
					}
				}
			}
		}
		if (FFU_BR_Defs.SyncLogging >= FFU_BR_Defs.SyncLogs.ModdedDump)
		{
			Debug.Log((object)("Dynamic Changes Map (Dump): " + JsonMapper.ToJson((object)dictChangesMap)));
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> 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<string, JsonSimple> dictionary = new Dictionary<string, JsonSimple>();
		Dictionary<string, JsonSimple> dictionary2 = new Dictionary<string, JsonSimple>();
		Dictionary<string, JsonSimple> dictionary3 = new Dictionary<string, JsonSimple>();
		Dictionary<string, JsonSimple> dictionary4 = new Dictionary<string, JsonSimple>();
		Dictionary<string, JsonSimple> dictionary5 = new Dictionary<string, JsonSimple>();
		Dictionary<string, JsonSimple> dictionary6 = new Dictionary<string, JsonSimple>();
		Dictionary<string, JsonSimple> dictionary7 = new Dictionary<string, JsonSimple>();
		Dictionary<string, JsonSimple> dictionary8 = new Dictionary<string, JsonSimple>();
		Dictionary<string, JsonSimple> dictionary9 = new Dictionary<string, JsonSimple>();
		Dictionary<string, JsonSimple> dictionary10 = new Dictionary<string, JsonSimple>();
		Dictionary<string, JsonSimple> dictionary11 = new Dictionary<string, JsonSimple>();
		Dictionary<string, JsonSimple> dictionary12 = new Dictionary<string, JsonSimple>();
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo6 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo6, "ships/", DataHandler.dictShips, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo7 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo7, "ads/", DataHandler.dictAds, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo8 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo8, "ai_training/", DataHandler.dictAIPersonalities, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo9 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo9, "attackmodes/coAttacks/", DataHandler.dictAModes, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo10 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo10, "attackmodes/shipAttacks/", DataHandler.dictShipAttacks, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo11 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo11, "audioemitters/", DataHandler.dictAudioEmitters, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo12 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo12, "blueprints/asteroids/", DataHandler.dictAsteroidBlueprints, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo13 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo13, "blueprints/clusters/", DataHandler.dictAsteroidClusterBlueprints, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo14 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo14, "careers/", DataHandler.dictCareers, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo15 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo15, "chargeprofiles/", DataHandler.dictChargeProfiles, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo16 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo16, "colors/", DataHandler.dictJsonColors, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo17 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo17, "conditions/", DataHandler.dictConds, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo18 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo18, "conditions_simple/", dictionary, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo19 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo19, "condowners/", DataHandler.dictCOs, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo20 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo20, "condrules/", DataHandler.dictCondRules, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo21 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo21, "condtrigs/", DataHandler.dictCTs, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo22 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo22, "context/", DataHandler.dictContext, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo23 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo23, "cooverlays/", DataHandler.dictCOOverlays, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo24 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo24, "crewskins/", dictionary2, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo25 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo25, "crime/", DataHandler.dictCrimes, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo26 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo26, "explosions/", DataHandler.dictExplosions, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo27 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo27, "gasrespires/", DataHandler.dictGasRespires, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo28 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo28, "guipropmaps/", DataHandler.dictGUIPropMapUnparsed, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo29 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo29, "headlines/", DataHandler.dictHeadlines, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo30 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo30, "homeworlds/", DataHandler.dictHomeworlds, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo31 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo31, "info/", DataHandler.dictInfoNodes, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo32 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo32, "installables/", DataHandler.dictInstallables, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo33 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo33, "interaction_overrides/", DataHandler.dictIAOverrides, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo34 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo34, "interactions/", DataHandler.dictInteractions, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo35 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo35, "items/", DataHandler.dictItemDefs, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo36 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo36, "jobitems/", DataHandler.dictJobitems, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo37 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo37, "jobs/", DataHandler.dictJobs, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo38 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo38, "ledgerdefs/", DataHandler.dictLedgerDefs, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo39 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo39, "lifeevents/", DataHandler.dictLifeEvents, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo40 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo40, "lights/", DataHandler.dictLights, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo41 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo41, "loot/", DataHandler.dictLoot, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo42 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo42, "manpages/", dictionary3, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo43 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo43, "market/Markets/", DataHandler.dictMarketConfigs, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo44 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo44, "market/CoCollections/", DataHandler.dictSupersTemp, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo45 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo45, "market/Production/", DataHandler.dictProductionMaps, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo46 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo46, "market/CargoSpecs/", DataHandler.dictCargoSpecs, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo47 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo47, "music/", DataHandler.dictMusic, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo48 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo48, "music_stations/", DataHandler.dictMusicStations, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo49 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo49, "names_first/", dictionary4, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo50 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo50, "names_full/", dictionary5, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo51 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo51, "names_last/", dictionary6, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo52 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo52, "names_robots/", dictionary7, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo53 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo53, "names_ship/", dictionary8, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo54 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo54, "names_ship_adjectives/", dictionary9, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo55 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo55, "names_ship_nouns/", dictionary10, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo56 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo56, "parallax/", DataHandler.dictParallax, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo57 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo57, "pda_apps/", DataHandler.dictPDAAppIcons, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo58 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo58, "personspecs/", DataHandler.dictPersonSpecs, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo59 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo59, "pledges/", DataHandler.dictPledges, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo60 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo60, "plot_beat_overrides/", DataHandler.dictPlotBeatOverrides, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo61 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo61, "plot_beats/", DataHandler.dictPlotBeats, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo62 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo62, "plot_manager/", DataHandler.dictPlotManager, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo63 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo63, "plots/", DataHandler.dictPlots, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo64 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo64, "powerinfos/", DataHandler.dictPowerInfo, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo65 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo65, "racing/leagues/", DataHandler.dictRacingLeagues, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo66 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo66, "racing/tracks/", DataHandler.dictRaceTracks, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo67 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo67, "rooms/", DataHandler.dictRoomSpecsTemp, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo68 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo68, "shipspecs/", DataHandler.dictShipSpecs, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo69 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo69, "slot_effects/", DataHandler.dictSlotEffects, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo70 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo70, "slots/", DataHandler.dictSlots, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo71 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo71, "star_systems/", DataHandler.dictStarSystems, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo72 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo72, "strings/", dictionary11, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo73 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo73, "tickers/", DataHandler.dictTickers, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo74 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo74, "tips/", DataHandler.dictTips, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo75 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo75, "tokens/", DataHandler.dictJsonTokens, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo76 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo76, "traitscores/", dictionary12, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo77 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo77, "transit/", DataHandler.dictTransit, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo78 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo78, "tsv/output/stakes/condtrigs/", DataHandler.dictJCTs, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo79 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo79, "tsv/output/stakes/loot/", DataHandler.dictJLoot, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo80 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo80, "tsv/output/stakes/interactions/", DataHandler.dictInteractions, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo81 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo81, "tsv/output/stakes/conditions/", DataHandler.dictConds, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo82 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo82, "tsv/output/stakes/contexts/", DataHandler.dictContext, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> dictModInfo83 in dictModInfos)
		{
			SyncLoadJSONs(dictModInfo83, "wounds/", DataHandler.dictWounds, aIgnorePatterns);
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> 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<string, JsonCondOwner> dictCO in DataHandler.dictCOs)
		{
			if (dictCO.Value.bSlotLocked)
			{
				listLockedCOs.Add(dictCO.Value.strName);
			}
		}
		foreach (KeyValuePair<string, patch_JsonModInfo> 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<string, Version> _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, Version>(string.Empty, new Version("0.0.0.0"));
			}
			return new KeyValuePair<string, Version>(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<TJson>(KeyValuePair<string, patch_JsonModInfo> refModInfo, string subFolder, Dictionary<string, TJson> 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<TJson>(string strFile, string strType, bool isMod, Dictionary<string, TJson> 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<TJson[]>(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<TJson>(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>(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<object> list = (newValue as Array).Cast<object>().ToList();
		List<object> list2 = (currValue as Array).Cast<object>().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<object>().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<string> list = (currValue as string[]).ToList();
		List<string> list2 = (newValue as string[]).ToList();
		List<string> list3 = list.ToList();
		bool noArrayOps = true;
		foreach (string item in list2)
		{
			if (string.IsNullOrEmpty(item) || !char.IsDigit(item[0]) || !item.Contains('|'))
			{
				continue;
			}
			List<string> list4 = item.Split('|').ToList();
			int.TryParse(list4[0], out var result);
			if (result > 0)
			{
				list4.RemoveAt(0);
				List<string> 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<string> modArray, List<string> 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<string> 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<string> 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<string> 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<string> 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<string> 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<string> 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<string> 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<JsonItem> list = aShipRef.aItems?.ToList();
		List<JsonCondOwnerSave> 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<string, string> 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<JsonItem> list = aShipRef.aItems?.ToList();
		List<JsonItem> list2 = new List<JsonItem>();
		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<string> 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<string> 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<string> 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<string> 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<JsonItem> list = aShipRef.aItems?.ToList();
		List<JsonCondOwnerSave> 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<JsonCondOwnerSave> 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<string> 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<string> list2 = item.aConds.ToList();
			List<string> second = item.aConds.Select((string x) => x.Split('=')[0]).ToList();
			List<string> 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<string> 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<JsonCondOwnerSave> 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<string> 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<string> list2 = item2.aConds.ToList();
			List<string> second = item2.aConds.Select((string x) => x.Split('=')[0]).ToList();
			List<string> 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<string> 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<JsonItem> aItemList = aShipRef.aItems?.ToList();
		List<JsonCondOwnerSave> 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<string> list2 = dictChangesMap[aSavedCO.strCODef]["Sync_Slot_Effects"].Where((string x) => x.Contains("=")).ToList();
			List<string> list3 = (from x in dictChangesMap[aSavedCO.strCODef]["Sync_Slot_Effects"]
				where x.StartsWith("!")
				select x.Substring(1)).ToList();
			List<JsonCondOwnerSave> list4 = list.FindAll((JsonCondOwnerSave x) => aItemList.Any((JsonItem i) => i.strSlotParentID == aSavedCO.strID && i.strID == x.strID));
			foreach (JsonCondOwnerSave item in list4)
			{
				List<string> list5 = ((item.aConds != null) ? item.aConds.ToList() : new List<string>());
				foreach (string item2 in list2)
				{
					string text = item2.Split("|"[0])[0];
					string addCondKey = text.Split("="[0])[0];
					List<string> 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<string> 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<JsonItem> aItemList = aShipRef.aItems?.ToList();
		List<JsonCondOwnerSave> 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<string> list2 = dictChangesMap[aSavedCO.strCODef]["Sync_Inv_Effects"].Where((string x) => x.Contains("=")).ToList();
			List<string> list3 = (from x in dictChangesMap[aSavedCO.strCODef]["Sync_Inv_Effects"]
				where x.StartsWith("!")
				select x.Substring(1)).ToList();
			List<JsonCondOwnerSave> list4 = list.FindAll((JsonCondOwnerSave x) => aItemList.Any((JsonItem i) => i.strParentID == aSavedCO.strID && i.strID == x.strID));
			foreach (JsonCondOwnerSave item in list4)
			{
				List<string> list5 = ((item.aConds != null) ? item.aConds.ToList() : new List<string>());
				foreach (string item2 in list2)
				{
					string text = item2.Split("|"[0])[0];
					string addCondKey = text.Split("="[0])[0];
					List<string> 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<string> 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<List<LootUnit>> 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<LootUnit>> list = new List<List<LootUnit>>();
		foreach (string text in aIn)
		{
			if (text == "")
			{
				continue;
			}
			string[] array = text.Split('|');
			List<LootUnit> list2 = new List<LootUnit>();
			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<List<LootUnit>>();
				}
				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<JsonTicker> aTickers;

	[MonoModPublic]
	[MonoModIgnore]
	public Dictionary<string, CondRule> mapCondRules;

	[MonoModPublic]
	[MonoModIgnore]
	public extern void UpdateStats();
}
public class patch_Slots : Slots
{
	[MonoModPublic]
	[MonoModIgnore]
	public TrackingCollection<Slot> aSlots;
}
public class patch_Slot : Slot
{
	[MonoModPublic]
	[MonoModIgnore]
	public TrackingCollection<Slot> 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))
				{
					retu