Decompiled source of AssetDataPlugin v3.5.0

AssetDataPlugin.dll

Decompiled 6 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("Nth Dimension")]
[assembly: AssemblyProduct("AssetDataPlugin")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("AssetDataPlugin")]
[assembly: ComVisible(false)]
[assembly: Guid("c303405d-e66c-4316-9cdb-4e3ca15c6360")]
[assembly: AssemblyFileVersion("3.5.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("3.5.0.0")]
namespace LordAshes;

[BepInPlugin("org.lordashes.plugins.assetdata", "Asset Data Plug-In", "3.5.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
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_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
				LoggingPlugin.LogDebug("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)))
					{
						LoggingPlugin.LogDebug("CreatureId or UniqueId is Emptry ('" + datum.source + "')");
						return false;
					}
				}
				catch
				{
					LoggingPlugin.LogDebug("Creature With CreatureId or UniqueId '" + datum.source + "' Does Not Exist");
					return false;
				}
				GameObject baseLoader = Utility.GetBaseLoader(cid);
				if ((Object)(object)baseLoader == (Object)null)
				{
					LoggingPlugin.LogDebug("Source Creature Loaded Check: Failed (Base Not Loaded)");
					return false;
				}
				GameObject assetLoader = Utility.GetAssetLoader(cid);
				if ((Object)(object)assetLoader == (Object)null)
				{
					LoggingPlugin.LogDebug("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)
				{
					LoggingPlugin.LogDebug("Removing Queue");
					backlog.Remove(backlog.ElementAt(i).Key);
					continue;
				}
				LoggingPlugin.LogDebug("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_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			BacklogItem result = null;
			if (backlog[queueName].TryDequeue(out result))
			{
				LoggingPlugin.LogDebug("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)
				{
					LoggingPlugin.LogDebug("No check performed. Sending Notification...");
					SendNotification(result);
					return;
				}
				if (result.subscription.checker(result.request))
				{
					LoggingPlugin.LogDebug("Check passed. Sending Notification...");
					SendNotification(result);
					return;
				}
				result.failures++;
				if (result.failures < Internal.maxRequestAttempts)
				{
					LoggingPlugin.LogDebug("Check Failed Attempt " + result.failures + ". Re-eneueuing...");
					backlog[queueName].Enqueue(result);
					return;
				}
				LoggingPlugin.LogDebug("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] = ".";
					BoardGuid id2 = BoardSessionManager.CurrentBoardInfo.Id;
					obj[4] = ((object)(BoardGuid)(ref id2)).ToString();
					obj[5] = ".json";
					File.WriteAllText(string.Concat(obj), JsonConvert.SerializeObject((object)Internal.data, (Formatting)1));
				}
			}
			else
			{
				LoggingPlugin.LogDebug("Backlog Dequeue Failed. Skipping...");
			}
		}

		public static void SendNotification(BacklogItem item)
		{
			if (item.subscription.callback != null)
			{
				LoggingPlugin.LogTrace("Sending Regular Callback");
				try
				{
					item.subscription.callback(item.request);
					return;
				}
				catch (Exception ex)
				{
					LoggingPlugin.LogInfo("Exception Sending Regular Callback");
					LoggingPlugin.LogInfo(Convert.ToString(ex));
					Debug.LogException(ex);
					return;
				}
			}
			if (item.subscription.callbackType == null || item.subscription.callbackMethod == null)
			{
				return;
			}
			LoggingPlugin.LogTrace("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
					{
						LoggingPlugin.LogWarning("Asset Data Plugin: Callback Method Is Not Found");
					}
				}
				else
				{
					LoggingPlugin.LogWarning("Asset Data Plugin: Callback Type Is Not Found");
				}
			}
			catch (Exception ex2)
			{
				LoggingPlugin.LogInfo("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 static class Internal
	{
		public static DiagnosticLevel diagnostics = (DiagnosticLevel)3;

		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 float rebroadcastRate = 0.1f;

		public static KeyboardShortcut triggerDiagnosticToggle;

		public static KeyboardShortcut triggerSpecificDiagnostic;

		public static KeyboardShortcut triggerDiagnosticSpecificDump;

		public static KeyboardShortcut triggerDiagnosticDump;

		public static KeyboardShortcut triggerSimData;

		public static KeyboardShortcut triggerRebroadcast;

		public static int maxRequestAttempts = 100;

		public static void Reset()
		{
			try
			{
				LoggingPlugin.LogInfo("Client Requested Full Reset");
				lock (padlockData)
				{
					Backlog.backlog.Clear();
					ProcessCurrentStates(System.Guid.Empty);
				}
			}
			catch (Exception ex)
			{
				LoggingPlugin.LogInfo("Exception In Reset()");
				Debug.LogException(ex);
			}
		}

		public static void Reset(Guid subscriptionId)
		{
			try
			{
				Guid guid = subscriptionId;
				LoggingPlugin.LogInfo("Client Requested Reset Associated With Subscription " + guid);
				lock (padlockData)
				{
					ProcessCurrentStates(subscriptionId);
				}
			}
			catch (Exception ex)
			{
				LoggingPlugin.LogInfo("Exception In Reset(subscriptionId)");
				Debug.LogException(ex);
			}
		}

		public static void Reset(string pattern)
		{
			try
			{
				LoggingPlugin.LogInfo("Client Requested Reset Associated With Key " + pattern);
				lock (padlockData)
				{
					ProcessCurrentStates(System.Guid.Empty, pattern);
				}
			}
			catch (Exception ex)
			{
				LoggingPlugin.LogInfo("Exception In Reset(pattern)");
				Debug.LogException(ex);
			}
		}

		public static void SetInfo(string identity, string key, string value)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (identity.ToUpper() == "SYSTEM")
				{
					return;
				}
				LoggingPlugin.LogDebug("_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] = ".";
					BoardGuid id2 = BoardSessionManager.CurrentBoardInfo.Id;
					obj[4] = ((object)(BoardGuid)(ref id2)).ToString();
					obj[5] = ".json";
					string text = string.Concat(obj);
					if (key.Contains(":"))
					{
						text = pluginPath + "AssetData/AssetDataPlugin." + key.Substring(0, key.IndexOf(":")) + ".json";
						key = key.Substring(key.IndexOf(":") + 1);
					}
					CreatureBoardAsset creature = GetCreature(identity);
					if ((Object)(object)creature != (Object)null && creature.IsUnique)
					{
						UniqueCreatureGuid uniqueId = creature.UniqueId;
						identity = ((object)(UniqueCreatureGuid)(ref uniqueId)).ToString();
						dictionary = unique;
						text = 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;
					}
					LoggingPlugin.LogTrace("Asset Data Plug-In: Storing Updated Data In " + text);
					File.WriteAllText(text, JsonConvert.SerializeObject((object)dictionary, (Formatting)1));
				}
			}
			catch (Exception ex)
			{
				LoggingPlugin.LogInfo("Exception In _SetInfo");
				Debug.LogException(ex);
			}
		}

		public static void ClearInfo(string identity, string key)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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)
			try
			{
				if (identity.ToUpper() == "SYSTEM")
				{
					return;
				}
				LoggingPlugin.LogDebug("_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] = ".";
					BoardGuid id2 = BoardSessionManager.CurrentBoardInfo.Id;
					obj[4] = ((object)(BoardGuid)(ref id2)).ToString();
					obj[5] = ".json";
					string text = string.Concat(obj);
					if (key.Contains(":"))
					{
						text = pluginPath + "AssetData/AssetDataPlugin." + key.Substring(0, key.IndexOf(":")) + ".json";
						key = key.Substring(key.IndexOf(":") + 1);
					}
					CreatureBoardAsset creature = GetCreature(identity);
					if ((Object)(object)creature != (Object)null && creature.IsUnique)
					{
						UniqueCreatureGuid uniqueId = creature.UniqueId;
						identity = ((object)(UniqueCreatureGuid)(ref uniqueId)).ToString();
						dictionary = unique;
						text = pluginPath + "AssetData/AssetDataPlugin.Unique.json";
					}
					if (dictionary.ContainsKey(identity) && dictionary[identity].ContainsKey(key))
					{
						object obj2 = dictionary[identity][key];
						dictionary[identity].Remove(key);
						LoggingPlugin.LogTrace("Asset Data Plug-In: Storing Updated Data In " + text);
						File.WriteAllText(text, JsonConvert.SerializeObject((object)dictionary, (Formatting)1));
					}
				}
			}
			catch (Exception ex)
			{
				LoggingPlugin.LogInfo("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)
				{
					LoggingPlugin.LogDebug("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)
				{
					LoggingPlugin.LogDebug("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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Invalid comparison between Unknown and I4
			//IL_05f9: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				LoggingPlugin.LogDebug("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] { '^' });
					LoggingPlugin.LogInfo("Remote notification of " + array[1] + " on " + array[0] + " (" + array[2] + ") from " + array[3] + " to " + array[4]);
					ChangeAction action = ChangeAction.modify;
					if ((int)diagnostics >= 4)
					{
						if (data.ContainsKey(array[0].Trim()))
						{
							LoggingPlugin.LogInfo("Identity Exists: Yes");
							if (data[array[0].Trim()].ContainsKey(array[1]))
							{
								LoggingPlugin.LogInfo("Key Exists: Yes");
								if (data[array[0].Trim()][array[1]].value != array[4])
								{
									LoggingPlugin.LogInfo("Change: " + data[array[0].Trim()][array[1]].value + " vs " + array[4] + ": Yes");
								}
								else
								{
									LoggingPlugin.LogInfo("Change: " + data[array[0].Trim()][array[1]].value + " vs " + array[4] + ": No");
								}
							}
							else
							{
								LoggingPlugin.LogInfo("Key Exists: No");
							}
						}
						else
						{
							LoggingPlugin.LogInfo("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])
						{
							LoggingPlugin.LogDebug("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])
						{
							LoggingPlugin.LogDebug("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]))
						{
							LoggingPlugin.LogDebug("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
				{
					LoggingPlugin.LogDebug("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]))
					{
						LoggingPlugin.LogDebug("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)]);
					}
					LoggingPlugin.LogDebug("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)
						{
							LoggingPlugin.LogDebug("Missing Packet " + i);
							flag = false;
							break;
						}
					}
					if (flag)
					{
						LoggingPlugin.LogDebug("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)
			{
				LoggingPlugin.LogInfo("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;
				}
				LoggingPlugin.LogInfo("Datum Changed: " + key + " on " + identity + " changing from " + previous?.ToString() + " to " + value);
				lock (padlockSubscriptions)
				{
					LoggingPlugin.LogDebug("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;
						LoggingPlugin.LogDebug("Subscription: " + subscription.pattern + ", Key: " + key + ", Match: " + flag + " (Subscription Restriction: " + flag2 + ", Pattern Restriction: " + flag3 + ")");
						if (flag && flag2 && flag3)
						{
							LoggingPlugin.LogDebug("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)
			{
				LoggingPlugin.LogInfo("Exception In DatumUpdate");
				Debug.LogException(ex);
			}
		}

		public static void SendPackets(string identity, string key, string action, string value, bool legacy = false)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Invalid comparison between Unknown and I4
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0565: Unknown result type (might be due to invalid IL or missing references)
			//IL_048d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_031d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: 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 ((int)diagnostics >= 4)
			{
				LoggingPlugin.LogInfo("SendPackets: identity=" + identity);
				LoggingPlugin.LogInfo("SendPackets: key=" + key);
				LoggingPlugin.LogInfo("SendPackets: action=" + Convert.ToString(action));
				LoggingPlugin.LogInfo("SendPackets: previois=" + text);
				LoggingPlugin.LogInfo("SendPackets: value=" + value);
				LoggingPlugin.LogInfo("SendPackets: legacy=" + legacy);
			}
			if (!legacy)
			{
				LoggingPlugin.LogDebug("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)
						{
							LoggingPlugin.LogDebug("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
						{
							LoggingPlugin.LogDebug("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;
				}
				LoggingPlugin.LogDebug("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)
					{
						LoggingPlugin.LogWarning("Asset Data Plugin: Problem distributing the message via the message distributor");
						Debug.LogException(ex);
						return;
					}
				}
				LoggingPlugin.LogWarning("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;
			}
			LoggingPlugin.LogDebug("SendPackets: Legacy Send Mode");
			if (action.ToUpper() != "REMOVE")
			{
				LoggingPlugin.LogDebug("Sending Legacy Set To Other Clients (Packet: " + identity + ", " + key + ", " + value + ")");
				if (Legacy.setInfo != null)
				{
					LoggingPlugin.LogWarning("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
						{
							LoggingPlugin.LogWarning("Asset Data Plugin: Legacy suppot is not available. Ensure Stat Messaging Plugin is installed.");
						}
						return;
					}
					catch (Exception ex2)
					{
						LoggingPlugin.LogWarning("Asset Data Plugin: Problem using Legacy SetInfo");
						Debug.LogException(ex2);
						return;
					}
				}
				LoggingPlugin.LogWarning("Asset Data Plugin: SendPackets: Legacy Mode Not Available. Ensure Stat Messaging Is Downlownloaded.");
				return;
			}
			LoggingPlugin.LogDebug("Sending Legacy Clear To Other Clients (Packet: " + identity + ", " + key + ", " + value + ")");
			if (Legacy.clearInfo != null)
			{
				LoggingPlugin.LogWarning("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
					{
						LoggingPlugin.LogWarning("Asset Data Plugin: Legacy suppot is not available. Ensure Stat Messaging Plugin is installed.");
					}
					return;
				}
				catch (Exception ex3)
				{
					LoggingPlugin.LogWarning("Asset Data Plugin: Problem using Legacy ClearInfo");
					Debug.LogException(ex3);
					return;
				}
			}
			LoggingPlugin.LogWarning("Asset Data Plugin: SendPackets: Legacy Mode Not Available. Ensure Stat Messaging Is Downlownloaded.");
		}

		internal static string Sync(string key, string value, SourceRole source)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			LoggingPlugin.LogWarning("Asset Data Plugin: Sync");
			if (DateTime.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.None, out var _))
			{
				if (LocalClient.IsPartyGm)
				{
					LoggingPlugin.LogWarning("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
				{
					LoggingPlugin.LogWarning("Asset Data Plugin: Sync: Player Requested Data Sync. This Is Not The GM. Ignoring...");
				}
			}
			else if (!LocalClient.IsPartyGm)
			{
				LoggingPlugin.LogWarning("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;
								}
							}
						}
						LoggingPlugin.LogWarning("Asset Data Plugin: Sync: Unique Data Updated.");
					}
				}
				else
				{
					data = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, Datum>>>(value);
					ProcessCurrentStates(System.Guid.Empty);
					LoggingPlugin.LogWarning("Asset Data Plugin: Sync: Board Data Updated.");
				}
			}
			else
			{
				LoggingPlugin.LogWarning("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()
		{
			LoggingPlugin.LogTrace("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);
					LoggingPlugin.LogInfo("Legacy Support Active");
					return;
				}
				catch (Exception ex)
				{
					LoggingPlugin.LogInfo("Unable To Subscribe To Stat Messaging Legacy Support");
					Debug.LogException(ex);
					return;
				}
			}
			LoggingPlugin.LogInfo("Stat Messaging Not Available. Disabling Legacy Support");
		}

		public static void LegacyCallback(string json)
		{
			//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)
			LoggingPlugin.LogInfo("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_013c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0141: Unknown result type (might be due to invalid IL or missing references)
				//IL_0160: 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)
				LoggingPlugin.LogTrace("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()))
				{
					LoggingPlugin.LogTrace("Patch: SetCreatureUniqueId: Asset Has No Campaign:Board Data To Copy");
					return true;
				}
				LoggingPlugin.LogTrace("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] = ".";
				BoardGuid id2 = BoardSessionManager.CurrentBoardInfo.Id;
				obj[4] = ((object)(BoardGuid)(ref id2)).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_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_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				CreatureGuid creatureId = creatureData.CreatureId;
				string? text = ((object)(CreatureGuid)(ref creatureId)).ToString();
				UniqueCreatureGuid uniqueId = creatureData.UniqueId;
				LoggingPlugin.LogTrace("Patch: OnCreatureAdded: " + text + "/" + ((object)(UniqueCreatureGuid)(ref 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()])
				{
					LoggingPlugin.LogDebug("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_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				//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_00b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00db: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
				//IL_017a: Unknown result type (might be due to invalid IL or missing references)
				//IL_017f: 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_011d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0139: Unknown result type (might be due to invalid IL or missing references)
				//IL_013e: Unknown result type (might be due to invalid IL or missing references)
				//IL_019e: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_01be: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
				//IL_0213: Unknown result type (might be due to invalid IL or missing references)
				//IL_0218: 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()))
				{
					string[] obj = new string[5]
					{
						"Patch: Clearing Asset Data For ",
						Legacy.GetCreatureName(__instance.Name),
						" (",
						null,
						null
					};
					creatureId = __instance.CreatureId;
					obj[3] = ((object)(CreatureGuid)(ref creatureId)).ToString();
					obj[4] = ")";
					LoggingPlugin.LogTrace(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] = ".";
					BoardGuid id2 = BoardSessionManager.CurrentBoardInfo.Id;
					obj2[4] = ((object)(BoardGuid)(ref id2)).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] = ".";
						id2 = BoardSessionManager.CurrentBoardInfo.Id;
						obj3[4] = ((object)(BoardGuid)(ref id2)).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)
					{
						LoggingPlugin.LogInfo("Base Loader '" + ((Object)match.GetChild(0)).name + "' Found");
						return ((Component)match.GetChild(0)).gameObject;
					}
					LoggingPlugin.LogWarning("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)
					{
						LoggingPlugin.LogInfo("Asset Loader '" + ((Object)match.GetChild(0)).name + "' Found");
						return ((Component)match.GetChild(0)).gameObject;
					}
					LoggingPlugin.LogWarning("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)
				{
					LoggingPlugin.LogInfo(ex.ToString());
				}
			};
		}

		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)
		{
			LoggingPlugin.LogInfo("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.5.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]);
		LoggingPlugin.LogTrace("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;
		LoggingPlugin.LogTrace("Looking For Message Distributor From " + distributors);
		string[] array = distributors.Split(new char[1] { '^' });
		foreach (string distributor in array)
		{
			try
			{
				LoggingPlugin.LogTrace("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)");
				}
				LoggingPlugin.LogTrace("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)");
				}
				LoggingPlugin.LogTrace("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)");
				}
				LoggingPlugin.LogTrace("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)");
				}
				LoggingPlugin.LogTrace("SendMessage Method Present");
				Internal.messageDistributor = new Distributor(type);
				LoggingPlugin.LogTrace("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);
				LoggingPlugin.LogInfo("Using Message Distributor " + distributor);
			}
			catch (Exception ex6)
			{
				Exception ex = ex6;
				if ((int)Internal.diagnostics < 4)
				{
					continue;
				}
				LoggingPlugin.LogWarning("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)
						{
							LoggingPlugin.LogWarning("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
			{
				LoggingPlugin.LogInfo("Asset Data Plug-In: Loading Asset Bundle " + location + "\\AssetDataWarning");
				AssetBundle ab = AssetBundle.LoadFromFile(location + "\\AssetDataWarning");
				LoggingPlugin.LogInfo("Asset Data Plug-In: Creating Prefab");
				GameObject prefab = (GameObject)ab.LoadAsset("assetdatawarning");
				LoggingPlugin.LogInfo("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_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: Unknown result type (might be due to invalid IL or missing references)
		//IL_0168: Unknown result type (might be due to invalid IL or missing references)
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a8: 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_026a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0270: Expected O, but got Unknown
		Internal.diagnostics = ((BaseUnityPlugin)this).Config.Bind<DiagnosticLevel>("Settings", "Diagnostics", (DiagnosticLevel)3, (ConfigDescription)null).Value;
		LoggingPlugin.LogInfo(((object)this).GetType().AssemblyQualifiedName + " is actve. (Diagnostics = " + ((object)(DiagnosticLevel)(ref 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.triggerRebroadcast = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Settings", "Trigger Rebroadcast", new KeyboardShortcut((KeyCode)97, (KeyCode[])(object)new KeyCode[1] { (KeyCode)303 }), (ConfigDescription)null).Value;
		Internal.rebroadcastRate = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "Rebroadcast Interval", 0.1f, (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)
		//IL_0218: Unknown result type (might be due to invalid IL or missing references)
		//IL_021d: Unknown result type (might be due to invalid IL or missing references)
		//IL_023c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0241: Unknown result type (might be due to invalid IL or missing references)
		if (!boardLoaded && Utility.isBoardLoaded() && BoardSessionManager.CurrentBoardInfo.Id != BoardGuid.Empty)
		{
			boardLoaded = true;
			OnCampaignChange();
			LoggingPlugin.LogInfo("Campaign/Board Loaded");
		}
		else if (boardLoaded && (!Utility.isBoardLoaded() || BoardSessionManager.CurrentBoardInfo.Id == BoardGuid.Empty))
		{
			boardLoaded = false;
			Backlog.backlog.Clear();
			LoggingPlugin.LogInfo("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;
			LoggingPlugin.LogInfo("\r\n" + JsonConvert.SerializeObject((object)data[((object)(CreatureGuid)(ref selectedCreatureId)).ToString()]));
		}
		else if (((KeyboardShortcut)(ref Internal.triggerDiagnosticDump)).IsUp())
		{
			LoggingPlugin.LogInfo("\r\n" + JsonConvert.SerializeObject((object)Internal.data));
		}
		else if (((KeyboardShortcut)(ref Internal.triggerSimData)).IsUp())
		{
			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, "");
		}
		else if (((KeyboardShortcut)(ref Internal.triggerRebroadcast)).IsUp())
		{
			LoggingPlugin.LogInfo("Rebroadcasting Campaign/Board Changes To All Players");
			string[] obj = new string[6]
			{
				Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
				"/AssetData/AssetDataPlugin.",
				null,
				null,
				null,
				null
			};
			CampaignGuid id = CampaignSessionManager.Id;
			obj[2] = ((object)(CampaignGuid)(ref id)).ToString();
			obj[3] = ".";
			BoardGuid id2 = BoardSessionManager.CurrentBoardInfo.Id;
			obj[4] = ((object)(BoardGuid)(ref id2)).ToString();
			obj[5] = ".json";
			string path = string.Concat(obj);
			if (File.Exists(path))
			{
				string text = File.ReadAllText(path);
				Dictionary<string, Dictionary<string, Datum>> changes = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, Datum>>>(text);
				((MonoBehaviour)this).StartCoroutine(Rebroadcast(changes, Internal.rebroadcastRate));
			}
		}
	}

	private IEnumerator Rebroadcast(Dictionary<string, Dictionary<string, Datum>> changes, float interval)
	{
		foreach (KeyValuePair<string, Dictionary<string, Datum>> source in changes)
		{
			if (!(source.Key != "_Info_"))
			{
				continue;
			}
			foreach (KeyValuePair<string, Datum> key in source.Value)
			{
				if (!key.Key.StartsWith("{"))
				{
					SetInfo(source.Key, key.Key, key.Value.value);
					yield return (object)new WaitForSeconds(interval);
				}
			}
		}
	}

	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)
		{
			LoggingPlugin.LogInfo("GUI Exception: " + ex);
		}
	}

	public static Guid Subscribe(string pattern, Action<DatumChange> callback)
	{
		LoggingPlugin.LogInfo("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)
	{
		LoggingPlugin.LogInfo("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)
	{
		LoggingPlugin.LogInfo("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)
	{
		Guid guid = subscriptionId;
		LoggingPlugin.LogInfo("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)
		{
			LoggingPlugin.LogError("Exception In Reset()");
			LoggingPlugin.LogDebug(ex.ToString());
		}
	}

	public static void Reset(Guid subscriptionId)
	{
		try
		{
			Internal.Reset(subscriptionId);
		}
		catch (Exception ex)
		{
			LoggingPlugin.LogError("Exception In Reset(subscriptionId)");
			LoggingPlugin.LogDebug(ex.ToString());
		}
	}

	public static void Reset(string pattern)
	{
		try
		{
			Internal.Reset(pattern);
		}
		catch (Exception ex)
		{
			LoggingPlugin.LogError("Exception In Reset(pattern)");
			LoggingPlugin.LogDebug(ex.ToString());
		}
	}

	public static void SetInfo(string identity, string key, string value, bool legacy = false)
	{
		try
		{
			LoggingPlugin.LogInfo("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)
		{
			LoggingPlugin.LogError("Exception In SetInfo(string)");
			LoggingPlugin.LogDebug(ex.ToString());
		}
	}

	public static void SetInfo(string identity, string key, object value, bool legacy = false)
	{
		try
		{
			SetInfo(identity, key, JsonConvert.SerializeObject(value), legacy);
		}
		catch (Exception ex)
		{
			LoggingPlugin.LogError("Exception In SetInfo(object)");
			LoggingPlugin.LogDebug(ex.ToString());
		}
	}

	public static void SendInfo(string key, string value)
	{
		try
		{
			SetInfo("SYSTEM", key, value);
		}
		catch (Exception ex)
		{
			LoggingPlugin.LogError("Exception In SendInfo");
			LoggingPlugin.LogDebug(ex.ToString());
		}
	}

	public static void SendInfo(string key, object value)
	{
		try
		{
			SetInfo("SYSTEM", key, JsonConvert.SerializeObject(value));
		}
		catch (Exception ex)
		{
			LoggingPlugin.LogError("Exception In SendInfo");
			LoggingPlugin.LogDebug(ex.ToString());
		}
	}

	public static void ClearInfo(string identity, string key, bool Legacy = false)
	{
		try
		{
			LoggingPlugin.LogInfo("ClearInfo: Client Requested Clear of " + key + " on " + identity);
			Internal.SendPackets(identity, key, "remove", "", Legacy);
			Internal.ClearInfo(identity, key);
		}
		catch (Exception ex)
		{
			LoggingPlugin.LogError("Exception In ClearInfo");
			LoggingPlugin.LogDebug(ex.ToString());
		}
	}

	public static string ReadInfo(string identity, string key)
	{
		//IL_0049: 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_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			LoggingPlugin.LogInfo("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] = ".";
				BoardGuid id2 = BoardSessionManager.CurrentBoardInfo.Id;
				obj[4] = ((object)(BoardGuid)(ref id2)).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)
		{
			LoggingPlugin.LogError("Exception In ReadInfo");
			LoggingPlugin.LogDebug(ex.ToString());
			return null;
		}
	}

	public static T ReadInfo<T>(string identity, string key)
	{
		try
		{
			return JsonConvert.DeserializeObject<T>(ReadInfo(identity, key));
		}
		catch (Exception ex)
		{
			LoggingPlugin.LogError("Exception In ReadInfo<" + typeof(T).ToString() + ">");
			LoggingPlugin.LogDebug(ex.ToString());
			return default(T);
		}
	}

	public static Datum ReadDatum(string identity, string key)
	{
		//IL_0049: 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_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			LoggingPlugin.LogInfo("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] = ".";
				BoardGuid id2 = BoardSessionManager.CurrentBoardInfo.Id;
				obj[4] = ((object)(BoardGuid)(ref id2)).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)
		{
			LoggingPlugin.LogError("Exception In ReadDatum");
			LoggingPlugin.LogDebug(ex.ToString());
			return null;
		}
	}

	public IEnumerator CheckForLegacySupport()
	{
		yield return (object)new WaitForSeconds(3f);
		LoggingPlugin.LogInfo("Checking For Legacy Support");
		Legacy.SubscribeToLegacyMessages();
	}

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

	public void OnCampaignChange()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		CampaignGuid id = CampaignSessionManager.Id;
		LoggingPlugin.LogDebug("Campaign = " + ((object)(CampaignGuid)(ref id)).ToString() + " : " + ((BaseState<CampaignSessionManager, State<CampaignSessionManager>>)(object)((StateMBehaviour<CampaignSessionManager, State<CampaignSessionManager>>)(object)SingletonStateMBehaviour<CampaignSessionManager, State<CampaignSessionManager>>.Instance).CurrentState).Name);
		BoardGuid id2 = BoardSessionManager.CurrentBoardInfo.Id;
		LoggingPlugin.LogDebug("Board = " + ((object)(BoardGuid)(ref id2)).ToString() + " : " + BoardSessionManager.CurrentBoardInfo.BoardName);
		LoggingPlugin.LogTrace("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] = ".";
		id2 = BoardSessionManager.CurrentBoardInfo.Id;
		obj[4] = ((object)(BoardGuid)(ref id2)).ToString();
		obj[5] = ".json";
		if (File.Exists(string.Concat(obj)))
		{
			LoggingPlugin.LogTrace("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] = ".";
				id2 = BoardSessionManager.CurrentBoardInfo.Id;
				obj2[4] = ((object)(BoardGuid)(ref id2)).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>>();
		}
		LoggingPlugin.LogTrace("Checking For Unique Data File");
		if (File.Exists(Internal.pluginPath + "AssetData/AssetDataPlugin.Unique.json"))
		{
			LoggingPlugin.LogTrace("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)
				{
					LoggingPlugin.LogTrace("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)
		{
			LoggingPlugin.LogTrace("Request For GM Updates");
			SendInfo("org.lordashes.plugins.assetdata.Sync", DateTime.UtcNow);
		}
	}
}

plugins/SourceRole.dll

Decompiled 6 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
}