Decompiled source of AssetDataPlugin v3.4.0

AssetDataPlugin.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using Bounce.Singletons;
using Bounce.Unmanaged;
using HarmonyLib;
using Newtonsoft.Json;
using TMPro;
using Talespire;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("AssetDataPlugin")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AssetDataPlugin")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("AssetDataPlugin")]
[assembly: ComVisible(false)]
[assembly: Guid("c303405d-e66c-4316-9cdb-4e3ca15c6360")]
[assembly: AssemblyFileVersion("3.4.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("3.4.0.0")]
namespace LordAshes;

[BepInPlugin("org.lordashes.plugins.assetdata", "Asset Data Plug-In", "3.4.0.0")]
public class AssetDataPlugin : BaseUnityPlugin
{
	public static class Backlog
	{
		public class BacklogItem
		{
			public DatumChange request { get; set; }

			public Subscription subscription { get; set; }

			public int failures { get; set; } = 0;

		}

		public static class Checker
		{
			public static bool CheckSourceAsCreature(DatumChange datum)
			{
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0074: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0084: Unknown result type (might be due to invalid IL or missing references)
				//IL_0112: Unknown result type (might be due to invalid IL or missing references)
				//IL_014e: Unknown result type (might be due to invalid IL or missing references)
				if (Internal.diagnostics >= DiagnosticSelection.debug)
				{
					Debug.Log((object)("Asset Data Plugin: Source Creature (" + datum.source + ") Loaded Check"));
				}
				CreatureGuid cid = default(CreatureGuid);
				try
				{
					cid = ((IEnumerable<CreatureBoardAsset>)(object)CreaturePresenter.GetTempReadOnlyViewOfAllCreatureAssets()).Where(delegate(CreatureBoardAsset cba)
					{
						//IL_0001: Unknown result type (might be due to invalid IL or missing references)
						//IL_0006: Unknown result type (might be due to invalid IL or missing references)
						//IL_0027: Unknown result type (might be due to invalid IL or missing references)
						//IL_002c: Unknown result type (might be due to invalid IL or missing references)
						CreatureGuid creatureId = cba.CreatureId;
						int result;
						if (!(((object)(CreatureGuid)(ref creatureId)).ToString() == datum.source))
						{
							UniqueCreatureGuid uniqueId = cba.UniqueId;
							result = ((((object)(UniqueCreatureGuid)(ref uniqueId)).ToString() == datum.source) ? 1 : 0);
						}
						else
						{
							result = 1;
						}
						return (byte)result != 0;
					}).ToArray().ElementAt(0)
						.CreatureId;
					if (((CreatureGuid)(ref cid)).Equals(default(CreatureGuid)))
					{
						if (Internal.diagnostics >= DiagnosticSelection.debug)
						{
							Debug.Log((object)("Asset Data Plugin: CreatureId or UniqueId is Emptry ('" + datum.source + "')"));
						}
						return false;
					}
				}
				catch
				{
					if (Internal.diagnostics >= DiagnosticSelection.debug)
					{
						Debug.Log((object)("Asset Data Plugin: Creature With CreatureId or UniqueId '" + datum.source + "' Does Not Exist"));
					}
					return false;
				}
				GameObject baseLoader = Utility.GetBaseLoader(cid);
				if ((Object)(object)baseLoader == (Object)null)
				{
					if (Internal.diagnostics >= DiagnosticSelection.debug)
					{
						Debug.Log((object)"Asset Data Plugin: Source Creature Loaded Check: Failed (Base Not Loaded)");
					}
					return false;
				}
				GameObject assetLoader = Utility.GetAssetLoader(cid);
				if ((Object)(object)assetLoader == (Object)null)
				{
					if (Internal.diagnostics >= DiagnosticSelection.debug)
					{
						Debug.Log((object)"Asset Data Plugin: Source Creature Loaded Check: Failed (Body Not Loaded)");
					}
					return false;
				}
				return true;
			}

			public static bool CheckSourceAndValueAsCreature(DatumChange datum)
			{
				int result;
				if (CheckSourceAsCreature(new DatumChange
				{
					action = datum.action,
					key = datum.key,
					previous = datum.previous,
					value = datum.value,
					source = datum.source
				}))
				{
					DatumChange datumChange = new DatumChange();
					datumChange.action = datum.action;
					datumChange.key = datum.key;
					datumChange.previous = datum.previous;
					datumChange.value = datum.value;
					datumChange.source = datum.value.ToString().Split(new char[1] { '@' })[0];
					result = (CheckSourceAsCreature(datumChange) ? 1 : 0);
				}
				else
				{
					result = 0;
				}
				return (byte)result != 0;
			}
		}

		public static Dictionary<string, ConcurrentQueue<BacklogItem>> backlog = new Dictionary<string, ConcurrentQueue<BacklogItem>>();

		public static void Process()
		{
			if (backlog.Count == 0)
			{
				return;
			}
			for (int i = 0; i < backlog.Count; i++)
			{
				if (backlog.ElementAt(i).Value.Count == 0)
				{
					if (Internal.diagnostics >= DiagnosticSelection.debug)
					{
						Debug.Log((object)"Asset Data Plugin: Removing Queue");
					}
					backlog.Remove(backlog.ElementAt(i).Key);
					continue;
				}
				if (Internal.diagnostics >= DiagnosticSelection.debug)
				{
					Debug.Log((object)("Asset Data Plugin: Backlog Queue '" + backlog.ElementAt(i).Value.ElementAt(0).subscription.subscription.ToString() + "' Has " + backlog.ElementAt(i).Value.Count + " Items"));
				}
				Next(backlog.ElementAt(i).Key);
			}
		}

		public static int Add(string queueName, BacklogItem request)
		{
			if (!backlog.ContainsKey(queueName))
			{
				backlog.Add(queueName, new ConcurrentQueue<BacklogItem>());
			}
			backlog[queueName].Enqueue(request);
			return backlog.Count;
		}

		public static void Next(string queueName)
		{
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			BacklogItem result = null;
			if (backlog[queueName].TryDequeue(out result))
			{
				if (Internal.diagnostics >= DiagnosticSelection.debug)
				{
					Debug.Log((object)("Asset Data Plugin: Backlog Dequeue Successful. A: " + result.request.action.ToString() + ", S:" + result.request.source + ", K:" + result.request.key + ", V:" + result.request.value));
				}
				if (result.subscription.checker == null)
				{
					if (Internal.diagnostics >= DiagnosticSelection.debug)
					{
						Debug.Log((object)"Asset Data Plugin: No check performed. Sending Notification...");
					}
					SendNotification(result);
					return;
				}
				if (result.subscription.checker(result.request))
				{
					if (Internal.diagnostics >= DiagnosticSelection.debug)
					{
						Debug.Log((object)"Asset Data Plugin: Check passed. Sending Notification...");
					}
					SendNotification(result);
					return;
				}
				result.failures++;
				if (result.failures < Internal.maxRequestAttempts)
				{
					if (Internal.diagnostics >= DiagnosticSelection.debug)
					{
						Debug.Log((object)("Asset Data Plugin: Check Failed Attempt " + result.failures + ". Re-eneueuing..."));
					}
					backlog[queueName].Enqueue(result);
					return;
				}
				if (Internal.diagnostics >= DiagnosticSelection.debug)
				{
					Debug.Log((object)"Asset Data Plugin: Check Failed Final Attempt. Removing...");
				}
				if (Internal.data.ContainsKey(result.request.source))
				{
					Internal.data[result.request.source].Remove(result.request.key);
					if (Internal.data[result.request.source].Count == 0)
					{
						Internal.data.Remove(result.request.source);
					}
					string[] obj = new string[6]
					{
						Internal.pluginPath,
						"AssetData/AssetDataPlugin.",
						null,
						null,
						null,
						null
					};
					CampaignGuid id = CampaignSessionManager.Id;
					obj[2] = ((object)(CampaignGuid)(ref id)).ToString();
					obj[3] = ".";
					obj[4] = ((object)(BoardGuid)(ref BoardSessionManager.CurrentBoardInfo.Id)).ToString();
					obj[5] = ".json";
					File.WriteAllText(string.Concat(obj), JsonConvert.SerializeObject((object)Internal.data, (Formatting)1));
				}
			}
			else if (Internal.diagnostics >= DiagnosticSelection.debug)
			{
				Debug.Log((object)"Asset Data Plugin: Backlog Dequeue Failed. Skipping...");
			}
		}

		public static void SendNotification(BacklogItem item)
		{
			if (item.subscription.callback != null)
			{
				if (Internal.diagnostics >= DiagnosticSelection.high)
				{
					Debug.Log((object)"Asset Data Plugin: Sending Regular Callback");
				}
				try
				{
					item.subscription.callback(item.request);
					return;
				}
				catch (Exception ex)
				{
					Debug.Log((object)"Asset Data Plugin: Exception Sending Regular Callback");
					Debug.Log((object)Convert.ToString(ex));
					Debug.LogException(ex);
					return;
				}
			}
			if (item.subscription.callbackType == null || item.subscription.callbackMethod == null)
			{
				return;
			}
			if (Internal.diagnostics >= DiagnosticSelection.high)
			{
				Debug.Log((object)"Asset Data Plugin: Sending Reflection Callback");
			}
			try
			{
				Type type = Type.GetType(item.subscription.callbackType);
				if (type != null)
				{
					MethodInfo method = type.GetMethod(item.subscription.callbackMethod);
					if (method != null)
					{
						method.Invoke(null, new object[5]
						{
							item.request.action.ToString(),
							item.request.source,
							item.request.key,
							item.request.previous,
							item.request.value
						});
					}
					else
					{
						Debug.LogWarning((object)"Asset Data Plugin: Callback Method Is Not Found");
					}
				}
				else
				{
					Debug.LogWarning((object)"Asset Data Plugin: Callback Type Is Not Found");
				}
			}
			catch (Exception ex2)
			{
				Debug.Log((object)"Asset Data Plugin: Exception Sending Reflection Callback");
				Debug.LogException(ex2);
			}
		}
	}

	public class Subscription
	{
		public Guid subscription { get; set; } = System.Guid.Empty;


		public string pattern { get; set; } = "*";


		public Action<DatumChange> callback { get; set; } = null;


		public string callbackType { get; set; } = null;


		public string callbackMethod { get; set; } = null;


		public Func<DatumChange, bool> checker { get; set; } = null;

	}

	public class Datum
	{
		public string previous { get; set; } = null;


		public string value { get; set; } = null;

	}

	public class DatumChange
	{
		public ChangeAction action { get; set; } = ChangeAction.invalid;


		public string source { get; set; } = null;


		public string key { get; set; } = "";


		public object previous { get; set; } = null;


		public object value { get; set; } = null;

	}

	public class Distributor
	{
		private Type _source = null;

		public Distributor(Type source)
		{
			_source = source;
		}

		public void AddHandler(string key, Func<string, string, SourceRole, string> callback)
		{
			MethodInfo method = _source.GetMethod("AddHandler");
			method.Invoke(null, new object[2] { key, callback });
		}

		public void RemoveHandler(string key)
		{
			MethodInfo method = _source.GetMethod("RemoveHandler");
			method.Invoke(null, new object[1] { key });
		}

		public void SendMessage(string message, NGuid source)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			MethodInfo method = _source.GetMethod("SendMessage");
			method.Invoke(null, new object[2] { message, source });
		}
	}

	public enum ChangeAction
	{
		invalid = -1,
		initial,
		remove,
		add,
		modify
	}

	public enum DiagnosticSelection
	{
		none = 0,
		low = 1,
		high = 2,
		debug = 999
	}

	public static class Internal
	{
		public static DiagnosticSelection diagnostics = DiagnosticSelection.low;

		public static int cutoff = int.MaxValue;

		public static object padlockData = new object();

		public static Dictionary<string, Dictionary<string, Datum>> data = new Dictionary<string, Dictionary<string, Datum>>();

		public static Dictionary<string, Dictionary<string, Datum>> unique = new Dictionary<string, Dictionary<string, Datum>>();

		private static Dictionary<string, string[]> multiPacketBuffer = new Dictionary<string, string[]>();

		public static object padlockSubscriptions = new object();

		public static List<Subscription> subscriptions = new List<Subscription>();

		public static Distributor messageDistributor = null;

		public static string pluginPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "/";

		public const char dividor = '^';

		public static KeyboardShortcut triggerDiagnosticToggle;

		public static KeyboardShortcut triggerSpecificDiagnostic;

		public static KeyboardShortcut triggerDiagnosticSpecificDump;

		public static KeyboardShortcut triggerDiagnosticDump;

		public static KeyboardShortcut triggerSimData;

		public static int maxRequestAttempts = 100;

		public static void Reset()
		{
			try
			{
				if (diagnostics >= DiagnosticSelection.low)
				{
					Debug.Log((object)"Asset Data Plugin: Client Requested Full Reset");
				}
				lock (padlockData)
				{
					Backlog.backlog.Clear();
					ProcessCurrentStates(System.Guid.Empty);
				}
			}
			catch (Exception ex)
			{
				Debug.Log((object)"Asset Data Plugin: Exception In Reset()");
				Debug.LogException(ex);
			}
		}

		public static void Reset(Guid subscriptionId)
		{
			try
			{
				if (diagnostics >= DiagnosticSelection.low)
				{
					Guid guid = subscriptionId;
					Debug.Log((object)("Asset Data Plugin: Client Requested Reset Associated With Subscription " + guid));
				}
				lock (padlockData)
				{
					ProcessCurrentStates(subscriptionId);
				}
			}
			catch (Exception ex)
			{
				Debug.Log((object)"Asset Data Plugin: Exception In Reset(subscriptionId)");
				Debug.LogException(ex);
			}
		}

		public static void Reset(string pattern)
		{
			try
			{
				if (diagnostics >= DiagnosticSelection.low)
				{
					Debug.Log((object)("Asset Data Plugin: Client Requested Reset Associated With Key " + pattern));
				}
				lock (padlockData)
				{
					ProcessCurrentStates(System.Guid.Empty, pattern);
				}
			}
			catch (Exception ex)
			{
				Debug.Log((object)"Asset Data Plugin: Exception In Reset(pattern)");
				Debug.LogException(ex);
			}
		}

		public static void SetInfo(string identity, string key, string value)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (identity.ToUpper() == "SYSTEM")
				{
					return;
				}
				if (diagnostics >= DiagnosticSelection.high)
				{
					Debug.Log((object)("Asset Data Plugin: _SetInfo : Client Set " + key + " on " + identity + " to " + value));
				}
				lock (padlockData)
				{
					Dictionary<string, Dictionary<string, Datum>> dictionary = data;
					string[] obj = new string[6] { pluginPath, "AssetData/AssetDataPlugin.", null, null, null, null };
					CampaignGuid id = CampaignSessionManager.Id;
					obj[2] = ((object)(CampaignGuid)(ref id)).ToString();
					obj[3] = ".";
					obj[4] = ((object)(BoardGuid)(ref BoardSessionManager.CurrentBoardInfo.Id)).ToString();
					obj[5] = ".json";
					string path = string.Concat(obj);
					CreatureBoardAsset creature = GetCreature(identity);
					if ((Object)(object)creature != (Object)null && creature.IsUnique)
					{
						UniqueCreatureGuid uniqueId = creature.UniqueId;
						identity = ((object)(UniqueCreatureGuid)(ref uniqueId)).ToString();
						dictionary = unique;
						path = pluginPath + "AssetData/AssetDataPlugin.Unique.json";
					}
					if (!dictionary.ContainsKey("_Info_"))
					{
						dictionary.Add("_Info_", new Dictionary<string, Datum>());
						dictionary["_Info_"].Add("{Internal.Source.Campaign}", new Datum
						{
							previous = null,
							value = CampaignSessionManager.Info.Alias + " : " + CampaignSessionManager.Info.Description
						});
						dictionary["_Info_"].Add("{Internal.Source.Board}", new Datum
						{
							previous = null,
							value = BoardSessionManager.CurrentBoardInfo.BoardName + " : " + BoardSessionManager.CurrentBoardInfo.Description
						});
					}
					else
					{
						dictionary["_Info_"]["{Internal.Source.Campaign}"] = new Datum
						{
							previous = null,
							value = CampaignSessionManager.Info.Alias + " : " + CampaignSessionManager.Info.Description
						};
						dictionary["_Info_"]["{Internal.Source.Board}"] = new Datum
						{
							previous = null,
							value = BoardSessionManager.CurrentBoardInfo.BoardName + " : " + BoardSessionManager.CurrentBoardInfo.Description
						};
					}
					if (!dictionary.ContainsKey(identity))
					{
						dictionary.Add(identity, new Dictionary<string, Datum>());
						dictionary[identity].Add("{Internal.Source.Timestamp}", new Datum
						{
							previous = null,
							value = DateTime.UtcNow.ToString(CultureInfo.InvariantCulture)
						});
					}
					else
					{
						dictionary[identity]["{Internal.Source.Timestamp}"].value = DateTime.UtcNow.ToString(CultureInfo.InvariantCulture);
					}
					if (!dictionary[identity].ContainsKey(key))
					{
						dictionary[identity].Add(key, new Datum
						{
							previous = null,
							value = value
						});
					}
					else
					{
						dictionary[identity][key].previous = dictionary[identity][key].value;
						dictionary[identity][key].value = value;
					}
					File.WriteAllText(path, JsonConvert.SerializeObject((object)dictionary, (Formatting)1));
				}
			}
			catch (Exception ex)
			{
				Debug.Log((object)"Asset Data Plugin: Exception In _SetInfo");
				Debug.LogException(ex);
			}
		}

		public static void ClearInfo(string identity, string key)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (identity.ToUpper() == "SYSTEM")
				{
					return;
				}
				if (diagnostics >= DiagnosticSelection.high)
				{
					Debug.Log((object)("Asset Data Plugin: _ClearInfo: Client Cleared " + key + " on " + identity));
				}
				lock (padlockData)
				{
					Dictionary<string, Dictionary<string, Datum>> dictionary = data;
					string[] obj = new string[6] { pluginPath, "AssetData/AssetDataPlugin.", null, null, null, null };
					CampaignGuid id = CampaignSessionManager.Id;
					obj[2] = ((object)(CampaignGuid)(ref id)).ToString();
					obj[3] = ".";
					obj[4] = ((object)(BoardGuid)(ref BoardSessionManager.CurrentBoardInfo.Id)).ToString();
					obj[5] = ".json";
					string path = string.Concat(obj);
					CreatureBoardAsset creature = GetCreature(identity);
					if ((Object)(object)creature != (Object)null && creature.IsUnique)
					{
						UniqueCreatureGuid uniqueId = creature.UniqueId;
						identity = ((object)(UniqueCreatureGuid)(ref uniqueId)).ToString();
						dictionary = unique;
						path = pluginPath + "AssetData/AssetDataPlugin.Unique.json";
					}
					if (dictionary.ContainsKey(identity) && dictionary[identity].ContainsKey(key))
					{
						object obj2 = dictionary[identity][key];
						dictionary[identity].Remove(key);
						File.WriteAllText(path, JsonConvert.SerializeObject((object)dictionary, (Formatting)1));
					}
				}
			}
			catch (Exception ex)
			{
				Debug.Log((object)"Asset Data Plugin: Exception In _ClearInfo");
				Debug.LogException(ex);
			}
		}

		public static CreatureBoardAsset GetCreature(string identity)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				CreatureBoardAsset result = null;
				CreaturePresenter.TryGetAsset(new CreatureGuid(identity), ref result);
				return result;
			}
			catch
			{
				return null;
			}
		}

		public static void ProcessCurrentStates(Guid subscription, string pattern = null)
		{
			foreach (KeyValuePair<string, Dictionary<string, Datum>> datum in data)
			{
				if (!(datum.Key.ToUpper() != "_INFO_"))
				{
					continue;
				}
				foreach (KeyValuePair<string, Datum> item in datum.Value)
				{
					if (diagnostics >= DiagnosticSelection.debug)
					{
						Debug.Log((object)("Asset Data Plugin: Processing Campaign/Board Data " + datum.Key + ":" + item.Key + "=" + item.Value.previous + "=>" + item.Value.value));
					}
					DatumUpdate(ChangeAction.initial, datum.Key, item.Key, item.Value.previous, item.Value.value, subscription, pattern);
				}
			}
			foreach (KeyValuePair<string, Dictionary<string, Datum>> item2 in unique)
			{
				if (!item2.Value.ContainsKey("Board") || !(item2.Value["Board"].value.ToString() == ((object)(BoardGuid)(ref BoardSessionManager.CurrentBoardInfo.Id)).ToString()))
				{
					continue;
				}
				foreach (KeyValuePair<string, Datum> item3 in item2.Value)
				{
					if (diagnostics >= DiagnosticSelection.debug)
					{
						Debug.Log((object)("Asset Data Plugin: Processing Unique Data " + item2.Key + ":" + item3.Key + "=" + item3.Value.previous + "=>" + item3.Value.value));
					}
					DatumUpdate(ChangeAction.initial, item2.Key, item3.Key, item3.Value.previous, item3.Value.value, subscription, pattern);
				}
			}
		}

		public static string ProcessRemoteChange(string message, string sender, SourceRole source)
		{
			//IL_06ba: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (diagnostics >= DiagnosticSelection.high)
				{
					Debug.Log((object)("Asset Data Plugin: Remote message = " + message));
				}
				if (message.StartsWith("/org.lordashes.plugins.assetdata "))
				{
					message = message.Substring("/org.lordashes.plugins.assetdata ".Length);
					string[] array = message.Split(new char[1] { '^' });
					if (diagnostics >= DiagnosticSelection.low)
					{
						Debug.Log((object)("Asset Data Plugin: Remote notification of " + array[1] + " on " + array[0] + " (" + array[2] + ") from " + array[3] + " to " + array[4]));
					}
					ChangeAction action = ChangeAction.modify;
					if (diagnostics >= DiagnosticSelection.high)
					{
						if (data.ContainsKey(array[0].Trim()))
						{
							Debug.Log((object)"Asset Data Plugin: Identity Exists: Yes");
							if (data[array[0].Trim()].ContainsKey(array[1]))
							{
								Debug.Log((object)"Asset Data Plugin: Key Exists: Yes");
								if (data[array[0].Trim()][array[1]].value != array[4])
								{
									Debug.Log((object)("Asset Data Plugin: Change: " + data[array[0].Trim()][array[1]].value + " vs " + array[4] + ": Yes"));
								}
								else
								{
									Debug.Log((object)("Asset Data Plugin: Change: " + data[array[0].Trim()][array[1]].value + " vs " + array[4] + ": No"));
								}
							}
							else
							{
								Debug.Log((object)"Asset Data Plugin: Key Exists: No");
							}
						}
						else
						{
							Debug.Log((object)"Asset Data Plugin: Identity Exists: No");
						}
					}
					switch (array[2].ToUpper())
					{
					case "ADD":
						action = ChangeAction.add;
						if (!data.ContainsKey(array[0].Trim()) || !data[array[0].Trim()].ContainsKey(array[1]) || data[array[0].Trim()][array[1]].value != array[4])
						{
							if (diagnostics >= DiagnosticSelection.high)
							{
								Debug.Log((object)"Asset Data Plugin: Remote Add Request Detected");
							}
							if (array[0].Trim().ToUpper() != "SYSTEM")
							{
								SetInfo(array[0], array[1], array[4]);
							}
						}
						break;
					case "MODIFY":
						action = ChangeAction.modify;
						if (!data.ContainsKey(array[0].Trim()) || !data[array[0].Trim()].ContainsKey(array[1]) || data[array[0].Trim()][array[1]].value != array[4])
						{
							if (diagnostics >= DiagnosticSelection.high)
							{
								Debug.Log((object)"Asset Data Plugin: Remote Modify Request Detected");
							}
							if (array[0].Trim().ToUpper() != "SYSTEM")
							{
								SetInfo(array[0].Trim(), array[1], array[4]);
							}
						}
						break;
					case "REMOVE":
						action = ChangeAction.remove;
						if (data.ContainsKey(array[0].Trim()) && data[array[0].Trim()].ContainsKey(array[1]))
						{
							if (diagnostics >= DiagnosticSelection.high)
							{
								Debug.Log((object)"Asset Data Plugin: Remote Clear Request Detected");
							}
							if (array[0].Trim().ToUpper() != "SYSTEM")
							{
								ClearInfo(array[0].Trim(), array[1]);
							}
						}
						break;
					}
					DatumUpdate(action, array[0].Trim(), array[1], array[3], array[4], System.Guid.Empty, null);
				}
				else
				{
					if (diagnostics >= DiagnosticSelection.high)
					{
						Debug.Log((object)"Asset Data Plugin: Multi Packet Message Detected");
					}
					message = message.Substring("/org.lordashes.plugins.assetdata.Multi".Length).Trim();
					string[] array2 = message.Substring(0, message.IndexOf(" ")).Split(new char[1] { ':' });
					message = message.Substring(message.IndexOf(" ") + 1);
					if (!multiPacketBuffer.ContainsKey(array2[0]))
					{
						if (diagnostics >= DiagnosticSelection.high)
						{
							Debug.Log((object)("Asset Data Plugin: New Multi Packet Message Detected. Creating Key " + array2[0] + " For " + array2[2] + " Packets"));
						}
						multiPacketBuffer.Add(array2[0], new string[int.Parse(array2[2], CultureInfo.InvariantCulture)]);
					}
					if (diagnostics >= DiagnosticSelection.high)
					{
						Debug.Log((object)("Asset Data Plugin: Storing Packet " + array2[1] + " Of " + array2[2] + " = " + message));
					}
					multiPacketBuffer[array2[0]][int.Parse(array2[1], CultureInfo.InvariantCulture)] = message;
					bool flag = true;
					for (int i = 0; i < int.Parse(array2[2], CultureInfo.InvariantCulture); i++)
					{
						if (multiPacketBuffer[array2[0]][i] == null)
						{
							if (diagnostics >= DiagnosticSelection.high)
							{
								Debug.Log((object)("Asset Data Plugin: Missing Packet " + i));
							}
							flag = false;
							break;
						}
					}
					if (flag)
					{
						if (diagnostics >= DiagnosticSelection.high)
						{
							Debug.Log((object)"Asset Data Plugin: Entire Multi Packet Message Is Readay. Processing");
						}
						string text = string.Join("", multiPacketBuffer[array2[0]]);
						multiPacketBuffer.Remove(array2[0]);
						ProcessRemoteChange("/org.lordashes.plugins.assetdata " + text, sender, source);
					}
				}
			}
			catch (Exception ex)
			{
				Debug.Log((object)"Asset Data Plugin: Exception In _ProcessRemoteChange");
				Debug.LogException(ex);
			}
			return null;
		}

		public static void DatumUpdate(ChangeAction action, string identity, string key, object previous, object value, Guid subscriptionId, string pattern)
		{
			try
			{
				if (!(key != "{Internal.Source.Timestamp}"))
				{
					return;
				}
				if (diagnostics >= DiagnosticSelection.low)
				{
					Debug.Log((object)("Asset Data Plugin: Datum Changed: " + key + " on " + identity + " changing from " + previous?.ToString() + " to " + value));
				}
				lock (padlockSubscriptions)
				{
					if (diagnostics >= DiagnosticSelection.high)
					{
						Debug.Log((object)"Asset Data Plugin: Queuing Callbacks");
					}
					foreach (Subscription subscription in subscriptions)
					{
						Wildcard wildcard = new Wildcard(subscription.pattern, RegexOptions.IgnoreCase);
						bool flag = wildcard.IsMatch(key);
						bool flag2 = subscription.subscription == subscriptionId || subscriptionId == System.Guid.Empty;
						bool flag3 = subscription.pattern == pattern || pattern == null;
						if (diagnostics >= DiagnosticSelection.high)
						{
							Debug.Log((object)("Asset Data Plugin: Subscription: " + subscription.pattern + ", Key: " + key + ", Match: " + flag + " (Subscription Restriction: " + flag2 + ", Pattern Restriction: " + flag3 + ")"));
						}
						if (flag && flag2 && flag3)
						{
							if (diagnostics >= DiagnosticSelection.debug)
							{
								Debug.Log((object)("Asset Data Plugin: Queuing A: " + action.ToString() + " S: " + identity + " K: " + key + " P: " + previous?.ToString() + " V: " + ((action != ChangeAction.remove) ? value : identity)));
							}
							Backlog.Add(subscription.subscription.ToString(), new Backlog.BacklogItem
							{
								request = new DatumChange
								{
									action = action,
									key = key,
									source = identity,
									previous = previous,
									value = ((action != ChangeAction.remove) ? value : identity)
								},
								subscription = subscription
							});
						}
					}
				}
			}
			catch (Exception ex)
			{
				Debug.Log((object)"Asset Data Plugin: Exception In DatumUpdate");
				Debug.LogException(ex);
			}
		}

		public static void SendPackets(string identity, string key, string action, string value, bool legacy = false)
		{
			//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0404: Unknown result type (might be due to invalid IL or missing references)
			//IL_0646: Unknown result type (might be due to invalid IL or missing references)
			//IL_0529: Unknown result type (might be due to invalid IL or missing references)
			//IL_0359: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			string text = "";
			if (data.ContainsKey(identity) && data[identity].ContainsKey(key))
			{
				text = data[identity][key].value;
			}
			if (diagnostics >= DiagnosticSelection.debug)
			{
				Debug.Log((object)("Asset Data Plugin: SendPackets: identity=" + identity));
				Debug.Log((object)("Asset Data Plugin: SendPackets: key=" + key));
				Debug.Log((object)("Asset Data Plugin: SendPackets: action=" + Convert.ToString(action)));
				Debug.Log((object)("Asset Data Plugin: SendPackets: previois=" + text));
				Debug.Log((object)("Asset Data Plugin: SendPackets: value=" + value));
				Debug.Log((object)("Asset Data Plugin: SendPackets: legacy=" + legacy));
			}
			if (!legacy)
			{
				if (diagnostics >= DiagnosticSelection.debug)
				{
					Debug.Log((object)"Asset Data Plugin: SendPackets: Asset Data Send Mode");
				}
				string text2 = identity.ToString() + "^" + key + "^" + action + "^" + text + "^" + value;
				if (text2.Length > 100)
				{
					float num = (float)text2.Length / 100f;
					if ((double)num != Math.Floor(num))
					{
						num = (float)Math.Floor(num) + 1f;
					}
					Guid guid = System.Guid.NewGuid();
					for (int i = 0; (float)i < num; i++)
					{
						if (text2.Length >= 100)
						{
							if (diagnostics >= DiagnosticSelection.high)
							{
								Debug.Log((object)("Asset Data Plugin: Sending Change To Other Clients (Packet " + (i + 1) + " of " + num + ": " + text2.Substring(0, 100) + ")"));
							}
							messageDistributor.SendMessage("/org.lordashes.plugins.assetdata.Multi " + guid.ToString() + ":" + i + ":" + num + " " + text2.Substring(0, 100), LocalPlayer.Id.Value);
						}
						else
						{
							if (diagnostics >= DiagnosticSelection.high)
							{
								Debug.Log((object)("Asset Data Plugin: Sending Change To Other Clients (Packet " + (i + 1) + " of " + num + ": " + text2 + ")"));
							}
							messageDistributor.SendMessage("/org.lordashes.plugins.assetdata.Multi " + guid.ToString() + ":" + i + ":" + num + " " + text2, LocalPlayer.Id.Value);
						}
						text2 = ((text2.Length < 100) ? "" : text2.Substring(100));
					}
					return;
				}
				if (diagnostics >= DiagnosticSelection.high)
				{
					Debug.Log((object)("Asset Data Plugin: Sending Change To Other Clients (Packet: " + text2 + ")"));
				}
				if (messageDistributor != null)
				{
					try
					{
						messageDistributor.SendMessage("/org.lordashes.plugins.assetdata " + text2, LocalPlayer.Id.Value);
						return;
					}
					catch (Exception ex)
					{
						Debug.LogWarning((object)"Asset Data Plugin: Problem distributing the message via the message distributor");
						Debug.LogException(ex);
						return;
					}
				}
				Debug.LogWarning((object)"Asset Data Plugin: Message cannot be distributed to others becauase no message distribution plugin (e.g. RPC Plugin, Chat Service or similar plugin is present)");
				return;
			}
			if (diagnostics >= DiagnosticSelection.debug)
			{
				Debug.Log((object)"Asset Data Plugin: SendPackets: Legacy Send Mode");
			}
			if (action.ToUpper() != "REMOVE")
			{
				if (diagnostics >= DiagnosticSelection.high)
				{
					Debug.Log((object)("Asset Data Plugin: Sending Legacy Set To Other Clients (Packet: " + identity + ", " + key + ", " + value + ")"));
				}
				if (Legacy.setInfo != null)
				{
					if (diagnostics >= DiagnosticSelection.debug)
					{
						Debug.LogWarning((object)"Asset Data Plugin: SendPackets: Legacy Set Info.");
					}
					try
					{
						if (Legacy.setInfo != null)
						{
							Legacy.setInfo.Invoke(null, new object[3]
							{
								(object)new CreatureGuid(identity),
								key,
								value
							});
						}
						else
						{
							Debug.LogWarning((object)"Asset Data Plugin: Legacy suppot is not available. Ensure Stat Messaging Plugin is installed.");
						}
						return;
					}
					catch (Exception ex2)
					{
						Debug.LogWarning((object)"Asset Data Plugin: Problem using Legacy SetInfo");
						Debug.LogException(ex2);
						return;
					}
				}
				if (diagnostics >= DiagnosticSelection.debug)
				{
					Debug.LogWarning((object)"Asset Data Plugin: SendPackets: Legacy Mode Not Available. Ensure Stat Messaging Is Downlownloaded.");
				}
				return;
			}
			if (diagnostics >= DiagnosticSelection.high)
			{
				Debug.Log((object)("Asset Data Plugin: Sending Legacy Clear To Other Clients (Packet: " + identity + ", " + key + ", " + value + ")"));
			}
			if (Legacy.clearInfo != null)
			{
				if (diagnostics >= DiagnosticSelection.debug)
				{
					Debug.LogWarning((object)"Asset Data Plugin: SendPackets: Legacy Clear Info.");
				}
				try
				{
					if (Legacy.setInfo != null)
					{
						Legacy.clearInfo.Invoke(null, new object[2]
						{
							(object)new CreatureGuid(identity),
							key
						});
					}
					else
					{
						Debug.LogWarning((object)"Asset Data Plugin: Legacy suppot is not available. Ensure Stat Messaging Plugin is installed.");
					}
					return;
				}
				catch (Exception ex3)
				{
					Debug.LogWarning((object)"Asset Data Plugin: Problem using Legacy ClearInfo");
					Debug.LogException(ex3);
					return;
				}
			}
			if (diagnostics >= DiagnosticSelection.debug)
			{
				Debug.LogWarning((object)"Asset Data Plugin: SendPackets: Legacy Mode Not Available. Ensure Stat Messaging Is Downlownloaded.");
			}
		}

		internal static string Sync(string key, string value, SourceRole source)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			if (diagnostics >= DiagnosticSelection.debug)
			{
				Debug.LogWarning((object)"Asset Data Plugin: Sync");
			}
			if (DateTime.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.None, out var _))
			{
				if (LocalClient.IsPartyGm)
				{
					if (diagnostics >= DiagnosticSelection.debug)
					{
						Debug.LogWarning((object)"Asset Data Plugin: Sync: Player Requested Data Sync. This Is The GM. Sending Data...");
					}
					SendInfo("org.lordashes.plugins.assetdata.SyncBoardData", JsonConvert.SerializeObject((object)data));
					Dictionary<string, Dictionary<string, Datum>> dictionary = new Dictionary<string, Dictionary<string, Datum>>();
					foreach (CreatureBoardAsset item in (IEnumerable<CreatureBoardAsset>)CreaturePresenter.GetTempReadOnlyViewOfAllCreatureAssets())
					{
						Dictionary<string, Dictionary<string, Datum>> dictionary2 = unique;
						UniqueCreatureGuid uniqueId = item.UniqueId;
						if (dictionary2.ContainsKey(((object)(UniqueCreatureGuid)(ref uniqueId)).ToString()))
						{
							uniqueId = item.UniqueId;
							string? key2 = ((object)(UniqueCreatureGuid)(ref uniqueId)).ToString();
							Dictionary<string, Dictionary<string, Datum>> dictionary3 = unique;
							uniqueId = item.UniqueId;
							dictionary.Add(key2, dictionary3[((object)(UniqueCreatureGuid)(ref uniqueId)).ToString()]);
						}
					}
					SendInfo("org.lordashes.plugins.assetdata.SyncUniqueData", JsonConvert.SerializeObject((object)dictionary));
				}
				else if (diagnostics >= DiagnosticSelection.debug)
				{
					Debug.LogWarning((object)"Asset Data Plugin: Sync: Player Requested Data Sync. This Is Not The GM. Ignoring...");
				}
			}
			else if (!LocalClient.IsPartyGm)
			{
				if (diagnostics >= DiagnosticSelection.debug)
				{
					Debug.LogWarning((object)"Asset Data Plugin: Sync: Sync Data. This Is Not The GM. Updating...");
				}
				if (!(key == "org.lordashes.plugins.assetdata.SyncBoardData"))
				{
					if (key == "org.lordashes.plugins.assetdata.SyncUniqueData")
					{
						Dictionary<string, Dictionary<string, Datum>> dictionary4 = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, Datum>>>(value);
						foreach (KeyValuePair<string, Dictionary<string, Datum>> item2 in dictionary4)
						{
							if (!unique.ContainsKey(item2.Key))
							{
								unique.Add(item2.Key, item2.Value);
								continue;
							}
							foreach (KeyValuePair<string, Datum> item3 in item2.Value)
							{
								if (!unique[item2.Key].ContainsKey(item3.Key))
								{
									unique[item2.Key].Add(item3.Key, item3.Value);
								}
								else
								{
									unique[item2.Key][item3.Key] = item3.Value;
								}
							}
						}
						if (diagnostics >= DiagnosticSelection.debug)
						{
							Debug.LogWarning((object)"Asset Data Plugin: Sync: Unique Data Updated.");
						}
					}
				}
				else
				{
					data = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, Datum>>>(value);
					ProcessCurrentStates(System.Guid.Empty);
					if (diagnostics >= DiagnosticSelection.debug)
					{
						Debug.LogWarning((object)"Asset Data Plugin: Sync: Board Data Updated.");
					}
				}
			}
			else if (diagnostics >= DiagnosticSelection.debug)
			{
				Debug.LogWarning((object)"Asset Data Plugin: Sync: Sync Data. This Is GM. Ignoring...");
			}
			return null;
		}
	}

	public static class Legacy
	{
		public class LegacyChange
		{
			public string cid { get; set; }

			public string action { get; set; }

			public string key { get; set; }

			public string previous { get; set; }

			public string value { get; set; }
		}

		public static MethodInfo setInfo;

		public static MethodInfo clearInfo;

		public static string GetCreatureName(CreatureBoardAsset asset)
		{
			return GetCreatureName(asset.Name);
		}

		public static string GetCreatureName(string name)
		{
			if (name.Contains("<"))
			{
				name = name.Substring(0, name.IndexOf("<"));
			}
			return name;
		}

		public static string GetStatBlock(CreatureBoardAsset asset)
		{
			return GetStatBlock(asset.Name);
		}

		public static string GetStatBlock(string block)
		{
			if (block.Contains(">"))
			{
				return block.Substring(block.IndexOf(">") + 1);
			}
			return "";
		}

		public static void SubscribeToLegacyMessages()
		{
			if (Internal.diagnostics >= DiagnosticSelection.high)
			{
				Debug.Log((object)"Asset Data Plugin: Checking For Stat Messaging Legacy Support");
			}
			Type type = Type.GetType("LordAshes.StatMessaging, StatMessaging");
			if (type != null)
			{
				try
				{
					setInfo = type.GetMethod("SetInfo");
					clearInfo = type.GetMethod("ClearInfo");
					MethodInfo method = type.GetMethod("ReflectionSubscription");
					object[] parameters = new object[2]
					{
						typeof(Legacy).AssemblyQualifiedName,
						"LegacyCallback"
					};
					method.Invoke(null, parameters);
					if (Internal.diagnostics >= DiagnosticSelection.low)
					{
						Debug.Log((object)"Asset Data Plugin: Legacy Support Active");
					}
					return;
				}
				catch (Exception ex)
				{
					Debug.Log((object)"Asset Data Plugin: Unable To Subscribe To Stat Messaging Legacy Support");
					Debug.LogException(ex);
					return;
				}
			}
			if (Internal.diagnostics >= DiagnosticSelection.low)
			{
				Debug.Log((object)"Asset Data Plugin: Stat Messaging Not Available. Disabling Legacy Support");
			}
		}

		public static void LegacyCallback(string json)
		{
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			if (Internal.diagnostics >= DiagnosticSelection.low)
			{
				Debug.Log((object)("Asset Data Plugin: Legacy Support Received: " + json));
			}
			List<LegacyChange> list = JsonConvert.DeserializeObject<List<LegacyChange>>(json);
			foreach (LegacyChange item in list)
			{
				ChangeAction changeAction = ChangeAction.invalid;
				switch (item.action)
				{
				case "modified":
					changeAction = ChangeAction.modify;
					break;
				case "added":
					changeAction = ChangeAction.add;
					break;
				case "removed":
					changeAction = ChangeAction.remove;
					break;
				}
				string message = "/org.lordashes.plugins.assetdata " + item.cid + "^" + item.key + "^" + changeAction.ToString() + "^" + item.previous + "^" + item.value;
				PlayerGuid id = LocalPlayer.Id;
				Internal.ProcessRemoteChange(message, ((object)(PlayerGuid)(ref id)).ToString(), (SourceRole)999);
			}
		}
	}

	public static class Patches
	{
		[HarmonyPatch(typeof(CreatureManager), "SetCreatureUniqueId")]
		public static class PatcheSetCreatureUniqueId
		{
			public static bool Prefix(CreatureGuid creatureId, UniqueCreatureGuid uniqueId)
			{
				//IL_0172: Unknown result type (might be due to invalid IL or missing references)
				//IL_0177: Unknown result type (might be due to invalid IL or missing references)
				if (Internal.diagnostics >= DiagnosticSelection.high)
				{
					Debug.Log((object)("Asset Data Plugin: Patch: SetCreatureUniqueId: Creature Id " + ((object)(CreatureGuid)(ref creatureId)).ToString() + " To Unique Id " + ((object)(UniqueCreatureGuid)(ref uniqueId)).ToString()));
				}
				bool flag = true;
				if (!Internal.data.ContainsKey(((object)(CreatureGuid)(ref creatureId)).ToString()) && Internal.diagnostics >= DiagnosticSelection.high)
				{
					Debug.Log((object)"Asset Data Plugin: Patch: SetCreatureUniqueId: Asset Has No Campaign:Board Data To Copy");
					return true;
				}
				if (Internal.diagnostics >= DiagnosticSelection.high)
				{
					Debug.Log((object)"Asset Data Plugin: Patch: SetCreatureUniqueId: Set Copy From Campaign:Board Data To Unique Data");
				}
				Internal.unique.Add(((object)(UniqueCreatureGuid)(ref uniqueId)).ToString(), Internal.data[((object)(CreatureGuid)(ref creatureId)).ToString()]);
				Internal.unique[((object)(UniqueCreatureGuid)(ref uniqueId)).ToString()].Add("Board", new Datum
				{
					previous = null,
					value = ((object)(BoardGuid)(ref BoardSessionManager.CurrentBoardInfo.Id)).ToString()
				});
				Internal.data.Remove(((object)(CreatureGuid)(ref creatureId)).ToString());
				File.WriteAllText(Internal.pluginPath + "AssetData/AssetDataPlugin.Unique.json", JsonConvert.SerializeObject((object)Internal.unique, (Formatting)1));
				string[] obj = new string[6]
				{
					Internal.pluginPath,
					"AssetData/AssetDataPlugin.",
					null,
					null,
					null,
					null
				};
				CampaignGuid id = CampaignSessionManager.Id;
				obj[2] = ((object)(CampaignGuid)(ref id)).ToString();
				obj[3] = ".";
				obj[4] = ((object)(BoardGuid)(ref BoardSessionManager.CurrentBoardInfo.Id)).ToString();
				obj[5] = ".json";
				File.WriteAllText(string.Concat(obj), JsonConvert.SerializeObject((object)Internal.data, (Formatting)1));
				return true;
			}
		}

		[HarmonyPatch(typeof(CreaturePresenter), "OnCreatureAdded")]
		public static class PatchOnCreatureAdded
		{
			public static bool Prefix(in CreatureDataV3 creatureData)
			{
				return true;
			}

			public static void Postfix(in CreatureDataV3 creatureData)
			{
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				if (Internal.diagnostics >= DiagnosticSelection.high)
				{
					Debug.Log((object)("Asset Data Plugin: Patch: OnCreatureAdded: " + ((object)(CreatureGuid)(ref creatureData.CreatureId)).ToString() + "/" + ((object)(UniqueCreatureGuid)(ref creatureData.UniqueId)).ToString()));
				}
				CreatureDataV3 val = creatureData;
				if (!((CreatureDataV3)(ref val)).IsUnique || !Internal.unique.ContainsKey(((object)(UniqueCreatureGuid)(ref creatureData.UniqueId)).ToString()))
				{
					return;
				}
				if (!Internal.unique[((object)(UniqueCreatureGuid)(ref creatureData.UniqueId)).ToString()].ContainsKey("Board"))
				{
					Internal.unique[((object)(UniqueCreatureGuid)(ref creatureData.UniqueId)).ToString()].Add("Board", new Datum
					{
						previous = null,
						value = ((object)(BoardGuid)(ref BoardSessionManager.CurrentBoardInfo.Id)).ToString()
					});
				}
				else
				{
					Internal.unique[((object)(UniqueCreatureGuid)(ref creatureData.UniqueId)).ToString()]["Board"] = new Datum
					{
						previous = Internal.unique[((object)(UniqueCreatureGuid)(ref creatureData.UniqueId)).ToString()]["Board"].value,
						value = ((object)(BoardGuid)(ref BoardSessionManager.CurrentBoardInfo.Id)).ToString()
					};
				}
				File.WriteAllText(Internal.pluginPath + "AssetData/AssetDataPlugin.Unique.json", JsonConvert.SerializeObject((object)Internal.unique, (Formatting)1));
				foreach (KeyValuePair<string, Datum> item in Internal.unique[((object)(UniqueCreatureGuid)(ref creatureData.UniqueId)).ToString()])
				{
					if (Internal.diagnostics >= DiagnosticSelection.debug)
					{
						Debug.Log((object)("Asset Data Plugin: Patch: OnCreatureAdded: Triggering A: initial S: " + ((object)(CreatureGuid)(ref creatureData.CreatureId)).ToString() + " K: " + item.Key + " V: " + item.Value.value));
					}
					Internal.DatumUpdate(ChangeAction.initial, ((object)(CreatureGuid)(ref creatureData.CreatureId)).ToString(), item.Key, item.Value.previous, item.Value.value, System.Guid.Empty, null);
				}
			}
		}

		[HarmonyPatch(typeof(CreatureBoardAsset), "RequestDelete")]
		public static class PatcheRequestDelete
		{
			public static bool Prefix()
			{
				return true;
			}

			public static void Postfix(CreatureBoardAsset __instance)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
				//IL_0105: Unknown result type (might be due to invalid IL or missing references)
				//IL_010a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_0189: Unknown result type (might be due to invalid IL or missing references)
				//IL_018e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0127: Unknown result type (might be due to invalid IL or missing references)
				//IL_012c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0148: Unknown result type (might be due to invalid IL or missing references)
				//IL_014d: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
				//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
				//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
				//IL_0203: Unknown result type (might be due to invalid IL or missing references)
				Dictionary<string, Dictionary<string, Datum>> data = Internal.data;
				CreatureGuid creatureId = __instance.CreatureId;
				if (data.ContainsKey(((object)(CreatureGuid)(ref creatureId)).ToString()))
				{
					if (Internal.diagnostics >= DiagnosticSelection.high)
					{
						string[] obj = new string[5]
						{
							"Asset Data Plugin: Patch: Clearing Asset Data For ",
							Legacy.GetCreatureName(__instance.Name),
							" (",
							null,
							null
						};
						creatureId = __instance.CreatureId;
						obj[3] = ((object)(CreatureGuid)(ref creatureId)).ToString();
						obj[4] = ")";
						Debug.Log((object)string.Concat(obj));
					}
					Dictionary<string, Dictionary<string, Datum>> data2 = Internal.data;
					string[] obj2 = new string[6]
					{
						Internal.pluginPath,
						"AssetData/AssetDataPlugin.",
						null,
						null,
						null,
						null
					};
					CampaignGuid id = CampaignSessionManager.Id;
					obj2[2] = ((object)(CampaignGuid)(ref id)).ToString();
					obj2[3] = ".";
					obj2[4] = ((object)(BoardGuid)(ref BoardSessionManager.CurrentBoardInfo.Id)).ToString();
					obj2[5] = ".json";
					string text = string.Concat(obj2);
					creatureId = __instance.CreatureId;
					string text2 = ((object)(CreatureGuid)(ref creatureId)).ToString();
					Dictionary<string, Dictionary<string, Datum>> unique = Internal.unique;
					UniqueCreatureGuid uniqueId = __instance.UniqueId;
					if (unique.ContainsKey(((object)(UniqueCreatureGuid)(ref uniqueId)).ToString()))
					{
						uniqueId = __instance.UniqueId;
						data2[((object)(UniqueCreatureGuid)(ref uniqueId)).ToString()].Clear();
						uniqueId = __instance.UniqueId;
						data2.Remove(((object)(UniqueCreatureGuid)(ref uniqueId)).ToString());
						File.WriteAllText(Internal.pluginPath + "AssetData/AssetDataPlugin.Unique.json", JsonConvert.SerializeObject((object)Internal.unique, (Formatting)1));
					}
					Dictionary<string, Dictionary<string, Datum>> data3 = Internal.data;
					creatureId = __instance.CreatureId;
					if (data3.ContainsKey(((object)(CreatureGuid)(ref creatureId)).ToString()))
					{
						creatureId = __instance.CreatureId;
						data2[((object)(CreatureGuid)(ref creatureId)).ToString()].Clear();
						creatureId = __instance.CreatureId;
						data2.Remove(((object)(CreatureGuid)(ref creatureId)).ToString());
						string[] obj3 = new string[6]
						{
							Internal.pluginPath,
							"AssetData/AssetDataPlugin.",
							null,
							null,
							null,
							null
						};
						id = CampaignSessionManager.Id;
						obj3[2] = ((object)(CampaignGuid)(ref id)).ToString();
						obj3[3] = ".";
						obj3[4] = ((object)(BoardGuid)(ref BoardSessionManager.CurrentBoardInfo.Id)).ToString();
						obj3[5] = ".json";
						File.WriteAllText(string.Concat(obj3), JsonConvert.SerializeObject((object)Internal.data, (Formatting)1));
					}
				}
			}
		}
	}

	public static class Utility
	{
		public static bool isBoardLoaded()
		{
			return SimpleSingletonBehaviour<CameraController>.HasInstance && SingletonStateMBehaviour<BoardSessionManager, State<BoardSessionManager>>.HasInstance && !BoardSessionManager.IsLoading;
		}

		public static Guid GuidFromString(string input)
		{
			using MD5 mD = MD5.Create();
			byte[] b = mD.ComputeHash(Encoding.Default.GetBytes(input));
			return new Guid(b);
		}

		public static GameObject GetBaseLoader(CreatureGuid cid)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				CreatureBoardAsset val = null;
				CreaturePresenter.TryGetAsset(cid, ref val);
				if ((Object)(object)val != (Object)null)
				{
					Transform match = null;
					Traverse(((Component)val).transform, "BaseLoader", 0, 10, ref match);
					if ((Object)(object)match != (Object)null)
					{
						Debug.Log((object)("Asset Data Plugin: Base Loader '" + ((Object)match.GetChild(0)).name + "' Found"));
						return ((Component)match.GetChild(0)).gameObject;
					}
					Debug.LogWarning((object)"Asset Data Plugin: Could Not Find Base Loader");
					return null;
				}
				return null;
			}
			catch
			{
				return null;
			}
		}

		public static GameObject GetAssetLoader(CreatureGuid cid)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				CreatureBoardAsset val = null;
				CreaturePresenter.TryGetAsset(cid, ref val);
				if ((Object)(object)val != (Object)null)
				{
					Transform match = null;
					Traverse(((Component)val).transform, "AssetLoader", 0, 10, ref match);
					if ((Object)(object)match != (Object)null)
					{
						Debug.Log((object)("Asset Data Plugin: Asset Loader '" + ((Object)match.GetChild(0)).name + "' Found"));
						return ((Component)match.GetChild(0)).gameObject;
					}
					Debug.LogWarning((object)"Asset Data Plugin: Could Not Find Asset Loader");
					return null;
				}
				return null;
			}
			catch
			{
				return null;
			}
		}

		public static void Traverse(Transform root, string seek, int depth, int depthMax, ref Transform match)
		{
			try
			{
				if ((Object)(object)match != (Object)null)
				{
					return;
				}
				if (((Object)root).name == seek)
				{
					match = root;
					return;
				}
				foreach (Transform item in ExtensionMethods.Children(root))
				{
					if (depth < depthMax)
					{
						Traverse(item, seek, depth + 1, depthMax, ref match);
					}
				}
			}
			catch
			{
			}
		}

		public static float ParseFloat(string value)
		{
			return float.Parse(value, CultureInfo.InvariantCulture);
		}

		public static string GetCreatureName(string nameBlock)
		{
			if (nameBlock == null)
			{
				return "(Unknown)";
			}
			if (!nameBlock.Contains("<size=0>"))
			{
				return nameBlock;
			}
			return nameBlock.Substring(0, nameBlock.IndexOf("<size=0>")).Trim();
		}

		public static void PostOnMainPage(MemberInfo plugin)
		{
			SceneManager.sceneLoaded += delegate(Scene scene, LoadSceneMode mode)
			{
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Expected O, but got Unknown
				try
				{
					if (((Scene)(ref scene)).name == "UI")
					{
						TextMeshProUGUI uITextByName = GetUITextByName("BETA");
						if (Object.op_Implicit((Object)(object)uITextByName))
						{
							((TMP_Text)uITextByName).text = "INJECTED BUILD - unstable mods";
						}
					}
					else
					{
						TextMeshProUGUI list = GetUITextByName("TextMeshPro Text");
						if (Object.op_Implicit((Object)(object)list))
						{
							BepInPlugin val = (BepInPlugin)Attribute.GetCustomAttribute(plugin, typeof(BepInPlugin));
							if (((TMP_Text)list).text.EndsWith("</size>"))
							{
								TextMeshProUGUI obj = list;
								((TMP_Text)obj).text = ((TMP_Text)obj).text + "\n\nMods Currently Installed:\n";
							}
							TextMeshProUGUI val2 = list;
							((TMP_Text)val2).text = ((TMP_Text)val2).text + "\nLord Ashes' " + val.Name + " - " + val.Version;
							Loofa_Patch(ref list);
						}
					}
				}
				catch (Exception ex)
				{
					Debug.Log((object)ex);
				}
			};
		}

		private static TextMeshProUGUI GetUITextByName(string name)
		{
			TextMeshProUGUI[] array = Object.FindObjectsOfType<TextMeshProUGUI>();
			for (int i = 0; i < array.Length; i++)
			{
				if (((Object)array[i]).name == name)
				{
					return array[i];
				}
			}
			return null;
		}

		private static void Loofa_Patch(ref TextMeshProUGUI list)
		{
			Debug.Log((object)("Asset Data Plugin: Loofa Check: Month " + DateTime.Now.Month + " Day " + DateTime.Now.Day));
			if (DateTime.Now.Month == 4 && DateTime.Now.Day >= 1 && DateTime.Now.Day <= 10)
			{
				string[] array = new string[10] { "Paradise Palace", "Pleasure Oasis", "House Of Pain", "Secret Dungeon", "Top Floor", "Steel Fortress", "Discreet Package Inc", "Toys For Adults", "Scented Candles", "Rigging House" };
				string[] array2 = new string[15]
				{
					"Large Watermelons Asset Pack", "Large Packages Asset Pack", "Red Room Of Fun Asset Pack", "Toys Aren't Just For Kids Asset Pack", "Couldn't Afford The Whole Thing Clothing Asset Pack", "Dungeon Essentials Asset Pack", "Schwartz In All Sizes Asset Pack", "Everything Leather Asset Pack", "Everything Lace Asset Pack", "Seems A Little See Through Asset Pack",
					"Whips And Chains For Riding Asset Pack", "Always Be Prepared Boyscout Asset Pack", "Essential Protection Asset Pack", "Ropes, Chains And Other Straps Asset Pack", "Bounty Chest Asset Pack"
				};
				Random random = new Random();
				for (int i = 0; i < random.Next(1, 5); i++)
				{
					string text = array[random.Next(1, array.Length) - 1];
					string text2 = array2[random.Next(1, array2.Length) - 1];
					TextMeshProUGUI val = list;
					((TMP_Text)val).text = ((TMP_Text)val).text + "\n" + text + "'s " + text2 + " - " + random.Next(1, 3) + "." + random.Next(1, 9) + "." + random.Next(1, 9) + ".0";
				}
			}
		}
	}

	public class Wildcard : Regex
	{
		public Wildcard(string pattern)
			: base(WildcardToRegex(pattern))
		{
		}

		public Wildcard(string pattern, RegexOptions options)
			: base(WildcardToRegex(pattern), options)
		{
		}

		public static string WildcardToRegex(string pattern)
		{
			return "^" + Regex.Escape(pattern).Replace("\\*", ".*").Replace("\\?", ".") + "$";
		}
	}

	public const string Name = "Asset Data Plug-In";

	public const string Guid = "org.lordashes.plugins.assetdata";

	public const string Version = "3.4.0.0";

	public const string Author = "Lord Ashes";

	public bool boardLoaded = false;

	public bool screenDiagnostics = false;

	public string diagnosticsOverrideAssetName = "";

	public IEnumerator GetDistributor(object[] inputs)
	{
		yield return (object)new WaitForSeconds((float)inputs[0]);
		if (Internal.diagnostics >= DiagnosticSelection.high)
		{
			Debug.Log((object)"Asset Data Plugin: Looking For Message Distributor");
		}
		string distributors = ((BaseUnityPlugin)this).Config.Bind<string>("Settings", "Client Distribution Plugins In Order Of preference", "LordAshes.ChatServicePlugin+ChatMessageService, ChatServicePlugin^RPCPlugin.RPC.RPCManager, RPCPlugin", (ConfigDescription)null).Value;
		if (Internal.diagnostics >= DiagnosticSelection.high)
		{
			Debug.Log((object)("Asset Data Plugin: Looking For Message Distributor From " + distributors));
		}
		string[] array = distributors.Split(new char[1] { '^' });
		foreach (string distributor in array)
		{
			try
			{
				if (Internal.diagnostics >= DiagnosticSelection.high)
				{
					Debug.Log((object)("Asset Data Plugin: Testing Message Distributor " + distributor));
				}
				Type type;
				try
				{
					type = Type.GetType(distributor);
					if (type == null)
					{
						throw new Exception("Unable To Get A Reference To " + distributor + " Type (Result Null)");
					}
				}
				catch (Exception)
				{
					throw new Exception("Unable To Get A Reference To " + distributor + " Type (Result Exception)");
				}
				if (Internal.diagnostics >= DiagnosticSelection.high)
				{
					Debug.Log((object)("Asset Data Plugin: Obtained Reference To " + distributor + " Type"));
				}
				try
				{
					if (type.GetMethod("AddHandler") == null)
					{
						throw new Exception("Missing AddHandler Method (Result Null)");
					}
				}
				catch (Exception)
				{
					throw new Exception("Missing AddHandler Method (Result Exception)");
				}
				if (Internal.diagnostics >= DiagnosticSelection.high)
				{
					Debug.Log((object)"Asset Data Plugin: AddHandler Method Present");
				}
				try
				{
					if (type.GetMethod("RemoveHandler") == null)
					{
						throw new Exception("Missing RemoveHandler Method (Result Null)");
					}
				}
				catch (Exception)
				{
					throw new Exception("Missing RemoveHandler Method (Result Exception)");
				}
				if (Internal.diagnostics >= DiagnosticSelection.high)
				{
					Debug.Log((object)"Asset Data Plugin: RemoveHandler Method Present");
				}
				try
				{
					if (type.GetMethod("SendMessage") == null)
					{
						throw new Exception("Missing SendMessage Method (Result Null)");
					}
				}
				catch (Exception)
				{
					throw new Exception("Missing SendMessage Method (Result Exception)");
				}
				if (Internal.diagnostics >= DiagnosticSelection.high)
				{
					Debug.Log((object)"Asset Data Plugin: SendMessage Method Present");
				}
				Internal.messageDistributor = new Distributor(type);
				if (Internal.diagnostics >= DiagnosticSelection.high)
				{
					Debug.Log((object)"Asset Data Plugin: Making Distributor Subscriptions");
				}
				Internal.messageDistributor.AddHandler("/org.lordashes.plugins.assetdata", Internal.ProcessRemoteChange);
				Internal.messageDistributor.AddHandler("/org.lordashes.plugins.assetdata.Multi", Internal.ProcessRemoteChange);
				Internal.messageDistributor.AddHandler("/org.lordashes.plugins.assetdata.SyncBoardData", Internal.Sync);
				Internal.messageDistributor.AddHandler("/org.lordashes.plugins.assetdata.SyncUniqueData", Internal.Sync);
				if (Internal.diagnostics >= DiagnosticSelection.low)
				{
					Debug.Log((object)("Asset Data Plugin: Using Message Distributor " + distributor));
				}
			}
			catch (Exception ex6)
			{
				Exception ex = ex6;
				if (Internal.diagnostics < DiagnosticSelection.high)
				{
					continue;
				}
				Debug.Log((object)("Asset Data Plugin: Distributor '" + distributor + "' rejected because " + ex.Message));
				try
				{
					Type type2 = Type.GetType(distributor);
					if (type2 != null)
					{
						MethodInfo[] methods = type2.GetMethods();
						MethodInfo[] array2 = methods;
						foreach (MethodInfo method in array2)
						{
							Debug.LogWarning((object)("Asset Data Plugin: Distributor '" + distributor + "' has method '" + method.Name + "'"));
						}
					}
				}
				catch (Exception)
				{
				}
				continue;
			}
			break;
		}
		if (Internal.messageDistributor == null)
		{
			Debug.LogError((object)"Asset Data Plugin: No Usable Message Distributor Found");
			string location = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			try
			{
				Debug.Log((object)("Asset Data Plug-In: Loading Asset Bundle " + location + "\\AssetDataWarning"));
				AssetBundle ab = AssetBundle.LoadFromFile(location + "\\AssetDataWarning");
				Debug.Log((object)"Asset Data Plug-In: Creating Prefab");
				GameObject prefab = (GameObject)ab.LoadAsset("assetdatawarning");
				Debug.Log((object)"Asset Data Plug-In: Creating Prefab Instance");
				Object.Instantiate<GameObject>(prefab, Vector3.zero, Quaternion.identity);
			}
			catch (Exception ex6)
			{
				Exception x = ex6;
				Debug.LogError((object)("Asset Data Plug-In: Failaure To Load Warning Asset: " + x.Message));
			}
			SystemMessage.AskForTextInput("Missing Choice Plugin", "Please see Asset Data Plugin docs for mode details", "Exit Talepsire", (Action<string>)delegate
			{
				AppStateManager.ForceQuitNoUiNoSync();
			}, (Action)null, "Understood", (Action)null, "Running in Crippled Mode Only.");
		}
	}

	private void Awake()
	{
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_015d: 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_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0192: Unknown result type (might be due to invalid IL or missing references)
		//IL_022a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0230: Expected O, but got Unknown
		Internal.diagnostics = ((BaseUnityPlugin)this).Config.Bind<DiagnosticSelection>("Settings", "Diagnostics", DiagnosticSelection.low, (ConfigDescription)null).Value;
		Debug.Log((object)("Asset Data Plugin: " + ((object)this).GetType().AssemblyQualifiedName + " is actve. (Diagnostics = " + Internal.diagnostics.ToString() + ")"));
		Internal.cutoff = ((BaseUnityPlugin)this).Config.Bind<int>("Settings", "Number of days to data for unreferenced asset", 30, (ConfigDescription)null).Value;
		Internal.triggerDiagnosticToggle = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Settings", "Toggle Screen Diagnostics", new KeyboardShortcut((KeyCode)100, (KeyCode[])(object)new KeyCode[1] { (KeyCode)305 }), (ConfigDescription)null).Value;
		Internal.triggerSpecificDiagnostic = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Settings", "Show Diagnostics For Asset By Name", new KeyboardShortcut((KeyCode)102, (KeyCode[])(object)new KeyCode[1] { (KeyCode)305 }), (ConfigDescription)null).Value;
		Internal.triggerDiagnosticSpecificDump = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Settings", "Log Selected Asset Data", new KeyboardShortcut((KeyCode)103, (KeyCode[])(object)new KeyCode[1] { (KeyCode)305 }), (ConfigDescription)null).Value;
		Internal.triggerDiagnosticDump = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Settings", "Log Complete Asset Data", new KeyboardShortcut((KeyCode)103, (KeyCode[])(object)new KeyCode[1] { (KeyCode)307 }), (ConfigDescription)null).Value;
		Internal.triggerSimData = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Settings", "Simulate Data", new KeyboardShortcut((KeyCode)103, (KeyCode[])(object)new KeyCode[1] { (KeyCode)303 }), (ConfigDescription)null).Value;
		Internal.maxRequestAttempts = ((BaseUnityPlugin)this).Config.Bind<int>("Settings", "Maximum Request Attempts", 100, (ConfigDescription)null).Value;
		((MonoBehaviour)this).StartCoroutine("GetDistributor", (object)new object[1] { ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "Plugins load time", 3f, (ConfigDescription)null).Value });
		if (!Directory.Exists(Internal.pluginPath + "AssetData"))
		{
			Directory.CreateDirectory(Internal.pluginPath + "AssetData/");
		}
		Harmony val = new Harmony("org.lordashes.plugins.assetdata");
		val.PatchAll();
		((MonoBehaviour)this).StartCoroutine(CheckForLegacySupport());
		((MonoBehaviour)this).StartCoroutine(BacklogLoop());
		Utility.PostOnMainPage(((object)this).GetType());
	}

	private void Update()
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		if (!boardLoaded && Utility.isBoardLoaded() && BoardSessionManager.CurrentBoardInfo.Id != BoardGuid.Empty)
		{
			boardLoaded = true;
			OnCampaignChange();
			Debug.Log((object)"Asset Data Plugin: Campaign/Board Loaded");
		}
		else if (boardLoaded && (!Utility.isBoardLoaded() || BoardSessionManager.CurrentBoardInfo.Id == BoardGuid.Empty))
		{
			boardLoaded = false;
			Backlog.backlog.Clear();
			Debug.Log((object)"Asset Data Plugin: Campaign/Board Unloaded");
		}
		if (((KeyboardShortcut)(ref Internal.triggerDiagnosticToggle)).IsUp())
		{
			screenDiagnostics = !screenDiagnostics;
		}
		else if (((KeyboardShortcut)(ref Internal.triggerSpecificDiagnostic)).IsUp())
		{
			SystemMessage.AskForTextInput("Diagnostics For Asset...", "Enter Asset Identification:", "Apply", (Action<string>)delegate(string name)
			{
				diagnosticsOverrideAssetName = name;
				screenDiagnostics = true;
			}, (Action)null, "Clear", (Action)delegate
			{
				diagnosticsOverrideAssetName = "";
				screenDiagnostics = false;
			}, "");
		}
		else if (((KeyboardShortcut)(ref Internal.triggerDiagnosticSpecificDump)).IsUp())
		{
			Dictionary<string, Dictionary<string, Datum>> data = Internal.data;
			CreatureGuid selectedCreatureId = LocalClient.SelectedCreatureId;
			Debug.Log((object)("Asset Data Plugin:\r\n" + JsonConvert.SerializeObject((object)data[((object)(CreatureGuid)(ref selectedCreatureId)).ToString()])));
		}
		else if (((KeyboardShortcut)(ref Internal.triggerDiagnosticDump)).IsUp())
		{
			Debug.Log((object)("Asset Data Plugin:\r\n" + JsonConvert.SerializeObject((object)Internal.data)));
		}
		else
		{
			if (!((KeyboardShortcut)(ref Internal.triggerSimData)).IsUp())
			{
				return;
			}
			SystemMessage.AskForTextInput("Data Simulation...", "Enter Source:", "Apply", (Action<string>)delegate(string source)
			{
				SystemMessage.AskForTextInput("Diagnostics For Asset...", "Enter Key:", "Apply", (Action<string>)delegate(string key)
				{
					SystemMessage.AskForTextInput("Diagnostics For Asset...", "Enter Value:", "Apply", (Action<string>)delegate(string value)
					{
						SetInfo(source, key, value);
					}, (Action)null, "Clear", (Action)null, "");
				}, (Action)null, "Clear", (Action)null, "");
			}, (Action)null, "Clear", (Action)null, "");
		}
	}

	private void OnGUI()
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (!screenDiagnostics)
			{
				return;
			}
			string text = diagnosticsOverrideAssetName;
			if (text == "")
			{
				CreatureBoardAsset val = null;
				CreaturePresenter.TryGetAsset(LocalClient.SelectedCreatureId, ref val);
				if ((Object)(object)val != (Object)null)
				{
					CreatureGuid creatureId = val.CreatureId;
					text = ((object)(CreatureGuid)(ref creatureId)).ToString();
				}
			}
			if (text != "")
			{
				string text2 = "{}";
				if (Internal.data.ContainsKey(text))
				{
					text2 = JsonConvert.SerializeObject((object)Internal.data[text]);
				}
				GUI.Label(new Rect(10f, 40f, (float)(Screen.width - 10), (float)(Screen.height - 40)), "[" + text + "]: " + text2);
			}
			else
			{
				GUI.Label(new Rect(10f, 40f, (float)(Screen.width - 10), (float)(Screen.height - 40)), "[No Asset Selected]");
			}
		}
		catch (Exception ex)
		{
			Debug.Log((object)("Asset Data Plugin: GUI Exception: " + ex));
		}
	}

	public static Guid Subscribe(string pattern, Action<DatumChange> callback)
	{
		if (Internal.diagnostics >= DiagnosticSelection.low)
		{
			Debug.Log((object)("Asset Data Plugin: Client Subscribed To " + pattern));
		}
		Guid guid = System.Guid.NewGuid();
		lock (Internal.padlockSubscriptions)
		{
			Internal.subscriptions.Add(new Subscription
			{
				subscription = guid,
				pattern = pattern,
				callback = callback,
				callbackType = null,
				callbackMethod = null,
				checker = null
			});
			Reset(guid);
		}
		return guid;
	}

	public static Guid Subscribe(string pattern, Action<DatumChange> callback, Func<DatumChange, bool> checker)
	{
		if (Internal.diagnostics >= DiagnosticSelection.low)
		{
			Debug.Log((object)("Asset Data Plugin: Client Subscribed To " + pattern));
		}
		Guid guid = System.Guid.NewGuid();
		lock (Internal.padlockSubscriptions)
		{
			Internal.subscriptions.Add(new Subscription
			{
				subscription = guid,
				pattern = pattern,
				callback = callback,
				callbackType = null,
				callbackMethod = null,
				checker = checker
			});
			Reset(guid);
		}
		return guid;
	}

	public static Guid SubscribeViaReflection(string pattern, string callbackType, string callbackMethod)
	{
		if (Internal.diagnostics >= DiagnosticSelection.low)
		{
			Debug.Log((object)("Asset Data Plugin: Client Subscribed To " + pattern));
		}
		Guid guid = System.Guid.NewGuid();
		lock (Internal.padlockSubscriptions)
		{
			Internal.subscriptions.Add(new Subscription
			{
				subscription = guid,
				pattern = pattern,
				callback = null,
				callbackType = callbackType,
				callbackMethod = callbackMethod
			});
			Reset(guid);
		}
		return guid;
	}

	public static void Unsubscribe(Guid subscriptionId)
	{
		if (Internal.diagnostics >= DiagnosticSelection.low)
		{
			Guid guid = subscriptionId;
			Debug.Log((object)("Asset Data Plugin: Client Unsubscribed Subscription " + guid));
		}
		lock (Internal.padlockSubscriptions)
		{
			for (int i = 0; i < Internal.subscriptions.Count; i++)
			{
				if (Internal.subscriptions[i].subscription == subscriptionId)
				{
					Internal.subscriptions.RemoveAt(i);
					i--;
				}
			}
		}
	}

	[Obsolete]
	public static void Reset()
	{
		try
		{
			Internal.Reset();
		}
		catch (Exception ex)
		{
			Debug.Log((object)"Asset Data Plugin: Exception In Reset()");
			Debug.LogException(ex);
		}
	}

	public static void Reset(Guid subscriptionId)
	{
		try
		{
			Internal.Reset(subscriptionId);
		}
		catch (Exception ex)
		{
			Debug.Log((object)"Asset Data Plugin: Exception In Reset(subscriptionId)");
			Debug.LogException(ex);
		}
	}

	public static void Reset(string pattern)
	{
		try
		{
			Internal.Reset(pattern);
		}
		catch (Exception ex)
		{
			Debug.Log((object)"Asset Data Plugin: Exception In Reset(pattern)");
			Debug.LogException(ex);
		}
	}

	public static void SetInfo(string identity, string key, string value, bool legacy = false)
	{
		try
		{
			if (Internal.diagnostics >= DiagnosticSelection.low)
			{
				Debug.Log((object)("Asset Data Plugin: SetInfo: Client Requested Set of " + key + " on " + identity + " to " + value));
			}
			lock (Internal.padlockData)
			{
				if (!Internal.data.ContainsKey(identity) || !Internal.data[identity].ContainsKey(key))
				{
					Internal.SendPackets(identity, key, "add", value, legacy);
				}
				else
				{
					Internal.SendPackets(identity, key, "modify", value, legacy);
				}
				Internal.SetInfo(identity, key, value);
			}
		}
		catch (Exception ex)
		{
			Debug.Log((object)"Asset Data Plugin: Exception In SetInfo(string)");
			Debug.LogException(ex);
		}
	}

	public static void SetInfo(string identity, string key, object value, bool legacy = false)
	{
		try
		{
			SetInfo(identity, key, JsonConvert.SerializeObject(value), legacy);
		}
		catch (Exception ex)
		{
			Debug.Log((object)"Asset Data Plugin: Exception In SetInfo(object)");
			Debug.LogException(ex);
		}
	}

	public static void SendInfo(string key, string value)
	{
		try
		{
			SetInfo("SYSTEM", key, value);
		}
		catch (Exception ex)
		{
			Debug.Log((object)"Asset Data Plugin: Exception In SendInfo");
			Debug.LogException(ex);
		}
	}

	public static void SendInfo(string key, object value)
	{
		try
		{
			SetInfo("SYSTEM", key, JsonConvert.SerializeObject(value));
		}
		catch (Exception ex)
		{
			Debug.Log((object)"Asset Data Plugin: Exception In SendInfo");
			Debug.LogException(ex);
		}
	}

	public static void ClearInfo(string identity, string key, bool Legacy = false)
	{
		try
		{
			if (Internal.diagnostics >= DiagnosticSelection.low)
			{
				Debug.Log((object)("Asset Data Plugin: ClearInfo: Client Requested Clear of " + key + " on " + identity));
			}
			Internal.SendPackets(identity, key, "remove", "", Legacy);
			Internal.ClearInfo(identity, key);
		}
		catch (Exception ex)
		{
			Debug.Log((object)"Asset Data Plugin: Exception In ClearInfo");
			Debug.LogException(ex);
		}
	}

	public static string ReadInfo(string identity, string key)
	{
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (Internal.diagnostics >= DiagnosticSelection.low)
			{
				Debug.Log((object)("Asset Data Plugin: ReadInfo: Client Read " + key + " on " + identity));
			}
			lock (Internal.padlockData)
			{
				Dictionary<string, Dictionary<string, Datum>> dictionary = Internal.data;
				string[] obj = new string[6]
				{
					Internal.pluginPath,
					"AssetData/AssetDataPlugin.",
					null,
					null,
					null,
					null
				};
				CampaignGuid id = CampaignSessionManager.Id;
				obj[2] = ((object)(CampaignGuid)(ref id)).ToString();
				obj[3] = ".";
				obj[4] = ((object)(BoardGuid)(ref BoardSessionManager.CurrentBoardInfo.Id)).ToString();
				obj[5] = ".json";
				string text = string.Concat(obj);
				CreatureBoardAsset creature = Internal.GetCreature(identity);
				if ((Object)(object)creature != (Object)null && creature.IsUnique)
				{
					UniqueCreatureGuid uniqueId = creature.UniqueId;
					identity = ((object)(UniqueCreatureGuid)(ref uniqueId)).ToString();
					dictionary = Internal.unique;
					text = Internal.pluginPath + "AssetData/AssetDataPlugin.Unique.json";
				}
				if (!dictionary.ContainsKey(identity))
				{
					return null;
				}
				if (!dictionary[identity].ContainsKey(key))
				{
					return null;
				}
				return dictionary[identity][key].value;
			}
		}
		catch (Exception ex)
		{
			Debug.Log((object)"Asset Data Plugin: Exception In ReadInfo");
			Debug.LogException(ex);
			return null;
		}
	}

	public static T ReadInfo<T>(string identity, string key)
	{
		try
		{
			return JsonConvert.DeserializeObject<T>(ReadInfo(identity, key));
		}
		catch (Exception ex)
		{
			Debug.Log((object)("Asset Data Plugin: Exception In ReadInfo<" + typeof(T).ToString() + ">"));
			Debug.LogException(ex);
			return default(T);
		}
	}

	public static Datum ReadDatum(string identity, string key)
	{
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (Internal.diagnostics >= DiagnosticSelection.low)
			{
				Debug.Log((object)("Asset Data Plugin: ReadInfo: Client Read " + key + " on " + identity));
			}
			lock (Internal.padlockData)
			{
				Dictionary<string, Dictionary<string, Datum>> dictionary = Internal.data;
				string[] obj = new string[6]
				{
					Internal.pluginPath,
					"AssetData/AssetDataPlugin.",
					null,
					null,
					null,
					null
				};
				CampaignGuid id = CampaignSessionManager.Id;
				obj[2] = ((object)(CampaignGuid)(ref id)).ToString();
				obj[3] = ".";
				obj[4] = ((object)(BoardGuid)(ref BoardSessionManager.CurrentBoardInfo.Id)).ToString();
				obj[5] = ".json";
				string text = string.Concat(obj);
				CreatureBoardAsset creature = Internal.GetCreature(identity);
				if ((Object)(object)creature != (Object)null && creature.IsUnique)
				{
					UniqueCreatureGuid uniqueId = creature.UniqueId;
					identity = ((object)(UniqueCreatureGuid)(ref uniqueId)).ToString();
					dictionary = Internal.unique;
					text = Internal.pluginPath + "AssetData/AssetDataPlugin.Unique.json";
				}
				if (!dictionary.ContainsKey(identity))
				{
					return null;
				}
				if (!dictionary[identity].ContainsKey(key))
				{
					return null;
				}
				return dictionary[identity][key];
			}
		}
		catch (Exception ex)
		{
			Debug.Log((object)"Asset Data Plugin: Exception In ReadDatum");
			Debug.LogException(ex);
			return null;
		}
	}

	public IEnumerator CheckForLegacySupport()
	{
		yield return (object)new WaitForSeconds(3f);
		Debug.Log((object)"Asset Data Plugin: Checking For Legacy Support");
		Legacy.SubscribeToLegacyMessages();
	}

	public IEnumerator BacklogLoop()
	{
		while (true)
		{
			yield return (object)new WaitForSeconds(0.25f);
			Backlog.Process();
		}
	}

	public void OnCampaignChange()
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: Unknown result type (might be due to invalid IL or missing references)
		CampaignGuid id;
		if (Internal.diagnostics >= DiagnosticSelection.debug)
		{
			id = CampaignSessionManager.Id;
			Debug.Log((object)("Asset Data Plugin: Campaign = " + ((object)(CampaignGuid)(ref id)).ToString() + " : " + ((BaseState<CampaignSessionManager, State<CampaignSessionManager>>)(object)((StateMBehaviour<CampaignSessionManager, State<CampaignSessionManager>>)(object)SingletonStateMBehaviour<CampaignSessionManager, State<CampaignSessionManager>>.Instance).CurrentState).Name));
		}
		if (Internal.diagnostics >= DiagnosticSelection.debug)
		{
			Debug.Log((object)("Asset Data Plugin: Board = " + ((object)(BoardGuid)(ref BoardSessionManager.CurrentBoardInfo.Id)).ToString() + " : " + BoardSessionManager.CurrentBoardInfo.BoardName));
		}
		if (Internal.diagnostics >= DiagnosticSelection.high)
		{
			Debug.Log((object)"Asset Data Plugin: Checking For Campaign:Board Data File");
		}
		string[] obj = new string[6]
		{
			Internal.pluginPath,
			"AssetData/AssetDataPlugin.",
			null,
			null,
			null,
			null
		};
		id = CampaignSessionManager.Id;
		obj[2] = ((object)(CampaignGuid)(ref id)).ToString();
		obj[3] = ".";
		obj[4] = ((object)(BoardGuid)(ref BoardSessionManager.CurrentBoardInfo.Id)).ToString();
		obj[5] = ".json";
		if (File.Exists(string.Concat(obj)))
		{
			if (Internal.diagnostics >= DiagnosticSelection.high)
			{
				Debug.Log((object)"Asset Data Plugin: Previous Campaign:Board Data Found. Loading Campaign:Board Specific AssetDataPlugin Data...");
			}
			lock (Internal.padlockData)
			{
				string[] obj2 = new string[6]
				{
					Internal.pluginPath,
					"AssetData/AssetDataPlugin.",
					null,
					null,
					null,
					null
				};
				id = CampaignSessionManager.Id;
				obj2[2] = ((object)(CampaignGuid)(ref id)).ToString();
				obj2[3] = ".";
				obj2[4] = ((object)(BoardGuid)(ref BoardSessionManager.CurrentBoardInfo.Id)).ToString();
				obj2[5] = ".json";
				Internal.data = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, Datum>>>(File.ReadAllText(string.Concat(obj2)));
			}
		}
		else
		{
			Internal.data = new Dictionary<string, Dictionary<string, Datum>>();
		}
		if (Internal.diagnostics >= DiagnosticSelection.high)
		{
			Debug.Log((object)"Asset Data Plugin: Checking For Unique Data File");
		}
		if (File.Exists(Internal.pluginPath + "AssetData/AssetDataPlugin.Unique.json"))
		{
			if (Internal.diagnostics >= DiagnosticSelection.high)
			{
				Debug.Log((object)"Asset Data Plugin: Previous Unique Data Found. Loading Unique AssetDataPlugin Data...");
			}
			lock (Internal.padlockData)
			{
				Internal.unique = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, Datum>>>(File.ReadAllText(Internal.pluginPath + "AssetData/AssetDataPlugin.Unique.json"));
			}
		}
		else
		{
			Internal.unique = new Dictionary<string, Dictionary<string, Datum>>();
		}
		if (Internal.cutoff > 0)
		{
			for (int i = 0; i < Internal.data.Keys.Count; i++)
			{
				string text = Internal.data.Keys.ElementAt(i);
				if (Internal.data[text].ContainsKey("{Internal.Source.Timestamp}") && DateTime.UtcNow.Subtract(DateTime.Parse(Internal.data[text]["{Internal.Source.Timestamp}"].value, CultureInfo.InvariantCulture)).TotalDays > (double)Internal.cutoff)
				{
					if (Internal.diagnostics >= DiagnosticSelection.high)
					{
						Debug.Log((object)("Asset Data Plugin: Removing Data For Asset " + text + " (Last Access " + Internal.data[text]["{Internal.Source.Timestamp}"].value + ")"));
					}
					lock (Internal.padlockData)
					{
						Internal.data.Remove(text);
					}
					i--;
				}
			}
		}
		Internal.Reset();
		if (!LocalClient.IsPartyGm)
		{
			if (Internal.diagnostics >= DiagnosticSelection.high)
			{
				Debug.Log((object)"Asset Data Plugin: Request For GM Updates");
			}
			SendInfo("org.lordashes.plugins.assetdata.Sync", DateTime.UtcNow);
		}
	}
}

plugins/SourceRole.dll

Decompiled 2 months ago
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("SourceRole")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SourceRole")]
[assembly: AssemblyCopyright("Copyright ©  2022")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("08b45a92-bf19-40cb-9712-436e153d8fcf")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Talespire;

public enum SourceRole
{
	gm = 0,
	player = 1,
	creature = 2,
	hideVolume = 3,
	other = 888,
	anonymous = 999
}