Decompiled source of ExchangeItem v1.0.1

Hikaria.ExchangeItem.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using Agents;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Utils;
using CellMenu;
using ExchangeItem.Data;
using ExchangeItem.Handlers;
using ExchangeItem.Patches;
using ExchangeItem.Utils;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Nidhogg.Managers;
using Player;
using SNetwork;
using UnityEngine;

[assembly: AssemblyVersion("1.0.0.0")]
namespace ExchangeItem
{
	internal static class Logs
	{
		public static void LogDebug(object data)
		{
			((BasePlugin)EntryPoint.Instance).Log.LogDebug(data);
		}

		public static void LogError(object data)
		{
			((BasePlugin)EntryPoint.Instance).Log.LogError(data);
		}

		public static void LogFatal(object data)
		{
			((BasePlugin)EntryPoint.Instance).Log.LogFatal(data);
		}

		public static void LogInfo(object data)
		{
			((BasePlugin)EntryPoint.Instance).Log.LogInfo(data);
		}

		public static void LogMessage(object data)
		{
			((BasePlugin)EntryPoint.Instance).Log.LogMessage(data);
		}

		public static void LogWarning(object data)
		{
			((BasePlugin)EntryPoint.Instance).Log.LogWarning(data);
		}
	}
}
namespace ExchangeItem.Data
{
	internal static class ExchangeItemData
	{
		public static PlayerAgent LocalPlayer;

		public static bool IsMaster;

		public static bool AllowExchangeItem;

		public static KeyCode ExchangeItemKey;

		public static bool EnableExchangeItemMessage;

		public static bool CurrentFlashlightState;

		public static string ExchangeItemHint_Exchange;

		public static string ExchangeItemHint_TargetToSource;

		public static string ExchangeItemHint_SourceToTarget;

		public static string ExchangeItemMessage_Exchange;

		public static string ExchangeItemMessage_TargetToSource;

		public static string ExchangeItemMessage_SourceToTarget;

		static ExchangeItemData()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			LocalPlayer = null;
			IsMaster = false;
			AllowExchangeItem = true;
			ExchangeItemKey = (KeyCode)116;
			EnableExchangeItemMessage = true;
			ExchangeItemHint_Exchange = "Swap {0} times {1} with {2} {3} times {4}";
			ExchangeItemMessage_Exchange = "{0} exchanged {1} times {2} with {3} {4} times {5}";
			ExchangeItemHint_Exchange = "Swap {0} times {1} with {2} {3} times {4}";
			ExchangeItemMessage_Exchange = "{0} exchanged {1} times {2} with {3} {4} times {5}";
			ExchangeItemHint_SourceToTarget = "Give {0} times {1} to {2}";
			ExchangeItemMessage_SourceToTarget = "{0} gave {1} {2} times {3}";
			ExchangeItemHint_TargetToSource = "Get {1} times {2} from {0}";
			ExchangeItemMessage_TargetToSource = "{0} took {1} {2} times {3}";
		}
	}
}
namespace ExchangeItem
{
	internal class ConfigManager
	{
		public static ConfigEntry<bool> allowExchangeItemWithOthers;

		public static ConfigEntry<KeyCode> exchangeItemKey;

		public static ConfigEntry<bool> enableExchangeItemMessage;

		public static ConfigEntry<string> exchangeItemHint_Exchange;

		public static ConfigEntry<string> exchangeItemMessage_Exchange;

		public static ConfigEntry<string> exchangeItemHint_SourceToTarget;

		public static ConfigEntry<string> exchangeItemMessage_SourceToTarget;

		public static ConfigEntry<string> exchangeItemHint_TargetToSource;

		public static ConfigEntry<string> exchangeItemMessage_TargetToSource;

		static ConfigManager()
		{
			//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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			Logs.LogInfo("Start loading configuration file");
			ConfigFile val = new ConfigFile(Path.Combine(Paths.ConfigPath, "Hikaria.ExchangeItem.cfg"), true);
			allowExchangeItemWithOthers = val.Bind<bool>("Interaction settings", "Exchange items between players", true, "Default [allowed | prohibited] exchange of items between players, accepted values: [true|false]");
			enableExchangeItemMessage = val.Bind<bool>("Prompt settings", "Tips for exchanging items between players", true, "Default [on | off] prompts for items exchanged between players, accepted values: [true|false]");
			exchangeItemKey = val.Bind<KeyCode>("Key setting", "Exchange item button between players", (KeyCode)116, "Exchange item button between players");
			exchangeItemHint_Exchange = val.Bind<string>("Resource exchange settings", "Exchange resource tips", ExchangeItemData.ExchangeItemHint_Exchange, "Custom exchange resource prompts");
			exchangeItemHint_SourceToTarget = val.Bind<string>("Resource exchange settings", "Give resource tips", ExchangeItemData.ExchangeItemHint_SourceToTarget, "Customize resource prompts");
			exchangeItemHint_TargetToSource = val.Bind<string>("Resource exchange settings", "Get resource tips", ExchangeItemData.ExchangeItemHint_TargetToSource, "Customize resource acquisition prompts");
			exchangeItemMessage_Exchange = val.Bind<string>("Resource exchange settings", "Exchange resource messages", ExchangeItemData.ExchangeItemMessage_Exchange, "Custom exchange resource messages");
			exchangeItemMessage_SourceToTarget = val.Bind<string>("Resource exchange settings", "Give resource message", ExchangeItemData.ExchangeItemMessage_SourceToTarget, "Customize the message given to the resource");
			exchangeItemMessage_TargetToSource = val.Bind<string>("Resource exchange settings", "Get resource information", ExchangeItemData.ExchangeItemMessage_TargetToSource, "Customize resource acquisition messages");
			Logs.LogInfo("Configuration file loaded");
		}

		public bool GetAllowExchangeItem()
		{
			return allowExchangeItemWithOthers.Value;
		}

		public KeyCode GetExchangeItemKey()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return exchangeItemKey.Value;
		}

		public bool GetEnableExchangeItemMessage()
		{
			return enableExchangeItemMessage.Value;
		}

		public string GetExchangeItemHint_Exchange()
		{
			return exchangeItemHint_Exchange.Value;
		}

		public string GetExchangeItemMessage_Exchange()
		{
			return exchangeItemMessage_Exchange.Value;
		}

		public string GetExchangeItemHint_SourceToTarget()
		{
			return exchangeItemHint_SourceToTarget.Value;
		}

		public string GetExchangeItemMessage_SourceToTarget()
		{
			return exchangeItemMessage_SourceToTarget.Value;
		}

		public string GetExchangeItemHint_TargetToSource()
		{
			return exchangeItemHint_TargetToSource.Value;
		}

		public string GetExchangeItemMessage_TargetToSource()
		{
			return exchangeItemMessage_TargetToSource.Value;
		}
	}
}
namespace ExchangeItem.Utils
{
	public abstract class Patch
	{
		[Flags]
		public enum PatchType : byte
		{
			Prefix = 1,
			Postfix = 2,
			Both = 3
		}

		[field: CompilerGenerated]
		protected internal Harmony Harmony
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			set;
		}

		public virtual bool Enabled => true;

		[field: CompilerGenerated]
		public virtual string Name
		{
			[CompilerGenerated]
			get;
		}

		public virtual void Initialize()
		{
		}

		public abstract void Execute();

		public void PatchConstructor<TClass>(PatchType patchType, string prefixMethodName = null, string postfixMethodName = null) where TClass : class
		{
			PatchConstructor<TClass>(null, patchType, prefixMethodName, postfixMethodName);
		}

		public void PatchConstructor<TClass>(global::System.Type[] parameters, PatchType patchType, string prefixMethodName = null, string postfixMethodName = null) where TClass : class
		{
			ConstructorInfo methodBase = AccessTools.Constructor(typeof(TClass), parameters, false);
			PatchMethod<TClass>((MethodBase)(object)methodBase, patchType, prefixMethodName, postfixMethodName);
		}

		public void PatchMethod<TClass>(string methodName, PatchType patchType, global::System.Type[] generics = null, string prefixMethodName = null, string postfixMethodName = null) where TClass : class
		{
			PatchMethod<TClass>(methodName, null, patchType, generics, prefixMethodName, postfixMethodName);
		}

		public void PatchMethod<TClass>(string methodName, global::System.Type[] parameters, PatchType patchType, global::System.Type[] generics = null, string prefixMethodName = null, string postfixMethodName = null) where TClass : class
		{
			MethodInfo methodBase = AccessTools.Method(typeof(TClass), methodName, parameters, generics);
			PatchMethod<TClass>((MethodBase)(object)methodBase, patchType, prefixMethodName, postfixMethodName);
		}

		public void PatchMethod<TClass>(MethodBase methodBase, PatchType patchType, string prefixMethodName = null, string postfixMethodName = null) where TClass : class
		{
			PatchMethod(typeof(TClass), methodBase, patchType, prefixMethodName, postfixMethodName);
		}

		public void PatchMethod(global::System.Type classType, string methodName, PatchType patchType, global::System.Type[] generics = null, string prefixMethodName = null, string postfixMethodName = null)
		{
			PatchMethod(classType, methodName, null, patchType, generics, prefixMethodName, postfixMethodName);
		}

		public void PatchMethod(global::System.Type classType, string methodName, global::System.Type[] parameters, PatchType patchType, global::System.Type[] generics = null, string prefixMethodName = null, string postfixMethodName = null)
		{
			MethodInfo methodBase = AccessTools.Method(classType, methodName, parameters, generics);
			PatchMethod(classType, (MethodBase)(object)methodBase, patchType, prefixMethodName, postfixMethodName);
		}

		public void PatchMethod(global::System.Type classType, MethodBase methodBase, PatchType patchType, string prefixMethodName = null, string postfixMethodName = null)
		{
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Expected O, but got Unknown
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Expected O, but got Unknown
			//IL_00ef: Expected O, but got Unknown
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Expected O, but got Unknown
			string text = ((MemberInfo)classType).Name.Replace("`", "__");
			string text2 = ((object)methodBase).ToString();
			string text3 = (methodBase.IsConstructor ? "ctor" : ((MemberInfo)methodBase).Name);
			MethodInfo val = null;
			MethodInfo val2 = null;
			if ((int)(patchType & PatchType.Prefix) > 0)
			{
				try
				{
					val2 = AccessTools.Method(base.GetType(), prefixMethodName ?? (text + "__" + text3 + "__Prefix"), (global::System.Type[])null, (global::System.Type[])null);
				}
				catch (global::System.Exception ex)
				{
					Logs.LogError($"Unable to obtain prefix patch method for ({text2}): {ex}");
				}
			}
			if ((int)(patchType & PatchType.Postfix) > 0)
			{
				try
				{
					val = AccessTools.Method(base.GetType(), postfixMethodName ?? (text + "__" + text3 + "__Postfix"), (global::System.Type[])null, (global::System.Type[])null);
				}
				catch (global::System.Exception ex2)
				{
					Logs.LogError($"Unable to obtain suffix patch method for ({text2}): {ex2}");
				}
			}
			try
			{
				if (val2 != (MethodInfo)null && val != (MethodInfo)null)
				{
					Harmony.Patch(methodBase, new HarmonyMethod(val2), new HarmonyMethod(val), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				else if (val2 != (MethodInfo)null)
				{
					Harmony.Patch(methodBase, new HarmonyMethod(val2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				else if (val != (MethodInfo)null)
				{
					Harmony.Patch(methodBase, (HarmonyMethod)null, new HarmonyMethod(val), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
			catch (global::System.Exception ex3)
			{
				Logs.LogError($"Unable to patch {text2} method: {ex3}");
			}
		}
	}
}
namespace ExchangeItem.Patches
{
	internal class PlayerJoinLobby : Patch
	{
		private const string PatchName = "PlayerJoinLobby";

		[field: CompilerGenerated]
		public override string Name
		{
			[CompilerGenerated]
			get;
		} = "PlayerJoinLobby";


		[field: CompilerGenerated]
		public static Patch Instance
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		public override void Execute()
		{
			PatchMethod<LocalPlayerAgentSettings>("OnLocalPlayerAgentEnable", PatchType.Postfix);
			PatchMethod<GS_Lobby>("OnMasterChanged", PatchType.Postfix);
			PatchMethod<SNet_SyncManager>("OnPlayerSpawnedAgent", PatchType.Postfix);
		}

		public override void Initialize()
		{
			Instance = this;
		}

		private static void LocalPlayerAgentSettings__OnLocalPlayerAgentEnable__Postfix()
		{
			SNet_IPlayerAgent playerAgent = SNet.LocalPlayer.PlayerAgent;
			PlayerAgent val = ((playerAgent != null) ? ((Il2CppObjectBase)playerAgent).Cast<PlayerAgent>() : null);
			if (!((Object)(object)val == (Object)null))
			{
				GameObject gameObject = ((Component)val).gameObject;
				if ((Object)(object)gameObject != (Object)null)
				{
					ExchangeItemData.LocalPlayer = val;
					Initializer.InstallComponent(gameObject);
				}
				else
				{
					Logs.LogFatal("[LocalPlayerAgentSettings__OnLocalPlayerAgentEnable__Postfix] 获取GameObject失败!");
				}
			}
		}

		private static void GS_Lobby__OnMasterChanged__Postfix()
		{
			ExchangeItemData.IsMaster = SNet.LocalPlayer.IsMaster;
		}

		private static void SNet_SyncManager__OnPlayerSpawnedAgent__Postfix(SNet_Player player)
		{
			if (!((Object)(object)player == (Object)null) && player.PlayerSlotIndex() != -1)
			{
				ExchangeItemData.IsMaster = SNet.LocalPlayer.IsMaster;
				if (!ExchangeItemData.IsMaster && (Object)(object)player == (Object)(object)SNet.LocalPlayer)
				{
					RequestSettingsSync();
				}
				CheckUpdate();
			}
		}

		private static void CheckUpdate()
		{
			NetworkingManager.InvokeEvent<NidhoggNetworkStructs.CheckVersion>("ExchangeItem_CheckVersion", new NidhoggNetworkStructs.CheckVersion
			{
				INTERNAL_VERSION = "10000",
				PLUGIN_VERSION = "1.0.1",
				CHANGE_LOG = "First version released"
			});
		}

		private static void RequestSettingsSync()
		{
			ExchangeItemData.AllowExchangeItem = false;
			NetworkingManager.InvokeEvent<NidhoggNetworkStructs.RequestSettingsSync>("ExchangeItem_RequestSettingsSync", default(NidhoggNetworkStructs.RequestSettingsSync), SNet.Master);
		}
	}
}
namespace ExchangeItem
{
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "Hikaria.ExchangeItem";

		public const string PLUGIN_NAME = "ExchangeItem";

		public const string PLUGIN_VERSION = "1.0.1";

		public const string AUTHOR = "神楽 ひかり";

		public const string BRANCH = "Debug";

		public const string INTERNAL_VERSION = "10000";

		public const string CHANGE_LOG = "第一个版本发布";
	}
}
namespace ExchangeItem.Utils
{
	internal class GameEventLogManager : MonoBehaviour
	{
		private static List<string> GameEventLogs;

		private float _interval;

		private PUI_GameEventLog _puiGameEventLog;

		public static void Speak(string text)
		{
			PlayerChatManager.WantToSentTextMessage(ExchangeItemData.LocalPlayer, text, (PlayerAgent)null);
		}

		private void Update()
		{
			if (_interval > 0f)
			{
				_interval -= Time.deltaTime;
			}
			else if (GameEventLogs.Count > 0)
			{
				_puiGameEventLog.AddLogItem(GameEventLogs[0], (eGameEventChatLogType)2);
				GuiManager.Current.m_playerLayer.m_gameEventLog.AddLogItem(GameEventLogs[0], (eGameEventChatLogType)2);
				GameEventLogs.RemoveAt(0);
				_interval = 1f;
			}
		}

		public static void AddLog(string log)
		{
			GameEventLogs.Add(log);
		}

		private void Start()
		{
			_puiGameEventLog = CM_PageLoadout.Current.m_gameEventLog;
			if (!EntryPoint.IsLogged)
			{
				AddLog("<color=orange>[ExchangeItem]</color> Current version: 1.0.1");
				AddLog("<color=orange>[ExchangeItem]</color> Type /exchhelp to view available commands");
				EntryPoint.IsLogged = true;
			}
		}

		static GameEventLogManager()
		{
			GameEventLogs = new List<string>();
		}

		private static string[] getstr(string strs, int len)
		{
			string[] array = new string[int.Parse(Math.Ceiling((double)strs.Length / (double)len).ToString())];
			for (int i = 0; i < array.Length; i++)
			{
				len = ((len <= strs.Length) ? len : strs.Length);
				array[i] = strs.Substring(0, len);
				strs = strs.Substring(len, strs.Length - len);
			}
			return array;
		}

		public static void AddLogInSeparate(string str, int len = 50)
		{
			if (str.Length > len)
			{
				string[] array = getstr(str, len);
				for (int i = 0; i < array.Length; i++)
				{
					AddLog(array[i]);
				}
			}
			else
			{
				AddLog(str);
			}
		}
	}
}
namespace ExchangeItem
{
	public class Initializer
	{
		public static void InstallComponent(GameObject gameObject)
		{
			if ((Object)(object)gameObject.GetComponent<GameEventLogManager>() == (Object)null)
			{
				Logs.LogInfo("Install components: GameEventLogManager");
				gameObject.AddComponent<GameEventLogManager>();
			}
			if ((Object)(object)gameObject.GetComponent<ChatManager>() == (Object)null)
			{
				Logs.LogInfo("Install components: ChatManager");
				gameObject.AddComponent<ChatManager>();
			}
		}
	}
}
namespace ExchangeItem.Patches
{
	internal class Command : Patch
	{
		private const string PatchName = "Command";

		private static string[] commands;

		[field: CompilerGenerated]
		public override string Name
		{
			[CompilerGenerated]
			get;
		} = "Command";


		[field: CompilerGenerated]
		public static Patch Instance
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		public override void Initialize()
		{
			Instance = this;
		}

		public override void Execute()
		{
			PatchMethod<PlayerChatManager>("PostMessage", PatchType.Prefix);
		}

		private static void PlayerChatManager__PostMessage__Prefix(PlayerChatManager __instance)
		{
			string text = __instance.m_currentValue;
			try
			{
				if (!(text.Substring(0, 5).ToLower() == "/exch"))
				{
					return;
				}
				text = text.Substring(1, text.Length - 1);
				string[] array = text.Split(' ', (StringSplitOptions)0);
				try
				{
					if (array[0].ToLower() == "exch")
					{
						if (array[1].ToLower() == "exch")
						{
							ExchangeItemData.AllowExchangeItem = StringToBool(array[2]);
							if (ExchangeItemData.IsMaster)
							{
								string text2 = string.Concat(new string[5]
								{
									"<color=",
									ExchangeItemData.AllowExchangeItem ? "green" : "red",
									">Resource exchange has been",
									ExchangeItemData.AllowExchangeItem ? "Enable" : "Disable",
									"</color>"
								});
								NetworkingManager.InvokeEvent<NidhoggNetworkStructs.SettingsSync>("ExchangeItem_SettingsSync", new NidhoggNetworkStructs.SettingsSync
								{
									AllowExchangeItem = ExchangeItemData.AllowExchangeItem
								});
								GameEventLogManager.AddLog(text2);
								ChatManager.queue.Add(text2);
							}
							else
							{
								GameEventLogManager.AddLog(string.Concat(new string[5]
								{
									"<color=",
									ExchangeItemData.AllowExchangeItem ? "green" : "red",
									">Resource exchange has been",
									ExchangeItemData.AllowExchangeItem ? "Enable" : "Disable",
									"</color>"
								}));
								GameEventLogManager.AddLog("<color=orange>You are not the homeowner, this setting is only effective for yourself</color>");
							}
							return;
						}
						if (array[1].ToLower() == "hint")
						{
							ExchangeItemData.EnableExchangeItemMessage = StringToBool(array[2]);
							if (ExchangeItemData.IsMaster)
							{
								string text3 = string.Concat(new string[5]
								{
									"<color=",
									ExchangeItemData.EnableExchangeItemMessage ? "green" : "red",
									">Resource exchange message has been",
									ExchangeItemData.EnableExchangeItemMessage ? "Enable" : "Disable",
									"</color>"
								});
								GameEventLogManager.AddLog(text3);
								ChatManager.queue.Add(text3);
							}
							else
							{
								GameEventLogManager.AddLog(string.Concat(new string[5]
								{
									"<color=",
									ExchangeItemData.EnableExchangeItemMessage ? "green" : "red",
									">Resource exchange message has been",
									ExchangeItemData.EnableExchangeItemMessage ? "Enable" : "Disable",
									"</color>"
								}));
								GameEventLogManager.AddLog("<color=orange>You are not the homeowner, this setting is only effective for yourself</color>");
							}
							return;
						}
						if (array[1].ToLower() == "check")
						{
							GameEventLogManager.AddLog(string.Format("Resource exchange{0}", (object)(ExchangeItemData.AllowExchangeItem ? "Enable" : "Disable")));
							GameEventLogManager.AddLog(string.Format("Resource exchange messages{0}", (object)(ExchangeItemData.EnableExchangeItemMessage ? "Enable" : "Disable")));
							return;
						}
					}
					throw new global::System.Exception("Unknown parameters");
				}
				catch (global::System.Exception ex)
				{
					if (text.ToLower() == "exchhelp")
					{
						throw new global::System.Exception("help");
					}
					Logs.LogError("Command execution failed:" + ex.Message);
					GameEventLogManager.AddLog("<color=red>[ExchangeItem]</color> Unknown command, enter /exchhelp to view help");
				}
				finally
				{
					__instance.m_currentValue = "";
				}
			}
			catch (global::System.Exception)
			{
				if (text.ToLower() == "exchhelp")
				{
					GameEventLogManager.AddLog("<color=orange>[ExchangeItem]</color> Available commands are as follows:");
					string[] array2 = commands;
					for (int i = 0; i < array2.Length; i++)
					{
						GameEventLogManager.AddLog(array2[i]);
					}
					__instance.m_currentValue = "";
				}
			}
		}

		public static bool StringToBool(string param)
		{
			param = param.ToLower();
			if (param == "on")
			{
				return true;
			}
			if (!(param == "off"))
			{
				throw new global::System.Exception("Illegal parameter");
			}
			return false;
		}

		static Command()
		{
			commands = new string[4] { "/exchhelp View help", "/exch exch [on|off] Allows prohibiting exchange of items between players", "/exch hint [on|off] Turn on and off resource exchange messages", "/exch check Check the status of various settings" };
		}
	}
}
namespace ExchangeItem.Handlers
{
	internal sealed class ExchangeItemUpdater : MonoBehaviour
	{
		private void Awake()
		{
			ExchangeItemManager.Clear();
		}

		private void OnDestroy()
		{
			ExchangeItemManager.Clear();
		}

		private void FixedUpdate()
		{
			if (ExchangeItemData.AllowExchangeItem)
			{
				UpdatePlayersInSphere();
				UpdateWieldingItem();
			}
		}

		private void UpdatePlayersInSphere()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ExchangeItemData.LocalPlayer.FPSCamera.Position;
			Collider[] array = Il2CppArrayBase<Collider>.op_Implicit((Il2CppArrayBase<Collider>)(object)Physics.OverlapSphere(position, 3f, LayerManager.MASK_GIVE_RESOURCE_PACK));
			if (array == null || array.Length == 0)
			{
				ExchangeItemManager.SetTargetPlayerAgent(null);
				return;
			}
			Vector3 forward = ExchangeItemData.LocalPlayer.FPSCamera.Forward;
			Vector3 zero = Vector3.zero;
			float num = 5f;
			PlayerAgent targetPlayerAgent = null;
			for (int i = 0; i < array.Length; i++)
			{
				iResourcePackReceiver componentInParent = ((Component)array[i]).GetComponentInParent<iResourcePackReceiver>();
				if (componentInParent == null)
				{
					continue;
				}
				PlayerAgent val = ((Il2CppObjectBase)componentInParent).TryCast<PlayerAgent>();
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				zero = ((Agent)val).AimTarget.position;
				if (Vector3.Angle(zero - position, forward) < 45f)
				{
					float num2 = Vector3.Distance(zero, position);
					if (num2 < num)
					{
						num = num2;
						targetPlayerAgent = val;
					}
				}
			}
			ExchangeItemManager.SetTargetPlayerAgent(targetPlayerAgent);
		}

		private void UpdateWieldingItem()
		{
			//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_0021: 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_0066: 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)
			PlayerInventoryBase inventory = ExchangeItemData.LocalPlayer.Inventory;
			if ((Object)(object)inventory != (Object)null)
			{
				InventorySlot wieldedSlot = inventory.WieldedSlot;
				ExchangeItemManager.SetWieldingItem(inventory.WieldedItem, wieldedSlot, EnumTypes.AgentType.LocalAgent);
			}
			else if ((Object)(object)ExchangeItemManager.LocalPlayerInventoryItem != (Object)null)
			{
				ExchangeItemManager.SetWieldingItem(null, (InventorySlot)0, EnumTypes.AgentType.LocalAgent);
			}
			if ((Object)(object)ExchangeItemManager.TargetPlayerAgent != (Object)null)
			{
				PlayerInventoryBase inventory2 = ExchangeItemManager.TargetPlayerAgent.Inventory;
				if ((Object)(object)inventory2 != (Object)null)
				{
					InventorySlot wieldedSlot2 = inventory2.WieldedSlot;
					ExchangeItemManager.SetWieldingItem(inventory2.WieldedItem, wieldedSlot2, EnumTypes.AgentType.TargetAgent);
				}
				else if ((Object)(object)ExchangeItemManager.TargetPlayerInventoryItem != (Object)null)
				{
					ExchangeItemManager.SetWieldingItem(null, (InventorySlot)0, EnumTypes.AgentType.TargetAgent);
				}
			}
		}

		static ExchangeItemUpdater()
		{
		}
	}
}
namespace ExchangeItem.Patches
{
	internal class LocalPlayerPatch : Patch
	{
		private const string PatchName = "LocalPlayerPatch";

		[field: CompilerGenerated]
		public override string Name
		{
			[CompilerGenerated]
			get;
		} = "LocalPlayerPatch";


		[field: CompilerGenerated]
		public static Patch Instance
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		public override void Execute()
		{
			PatchMethod<LocalPlayerAgent>("Setup", PatchType.Postfix);
		}

		public override void Initialize()
		{
			Instance = this;
		}

		private static void LocalPlayerAgent__Setup__Postfix(LocalPlayerAgent __instance)
		{
			GameObject gameObject = ((Component)__instance).gameObject;
			if ((Object)(object)gameObject.GetComponent<ExchangeItemUpdater>() == (Object)null)
			{
				gameObject.AddComponent<ExchangeItemUpdater>();
			}
			if ((Object)(object)gameObject.GetComponent<ExchangeItemHandler>() == (Object)null)
			{
				gameObject.AddComponent<ExchangeItemHandler>();
			}
		}
	}
}
namespace ExchangeItem.Utils
{
	public static class ExchangeItemUtils
	{
		public static void WantToExchangeItem(int sourcePlayerIndex, int targetPlayerIndex, InventorySlot inventorySlot)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: 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_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: 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_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: 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_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: 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_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: 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_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			if (ExchangeItemData.AllowExchangeItem)
			{
				AmmoType val = (AmmoType)(((int)inventorySlot == 4) ? 3 : 5);
				PlayerAgent val2 = default(PlayerAgent);
				PlayerManager.TryGetPlayerAgent(ref sourcePlayerIndex, ref val2);
				PlayerAgent val3 = default(PlayerAgent);
				PlayerManager.TryGetPlayerAgent(ref targetPlayerIndex, ref val3);
				SNet_Player owner = val2.Owner;
				SNet_Player owner2 = val3.Owner;
				PlayerBackpack val4 = default(PlayerBackpack);
				PlayerBackpackManager.TryGetBackpack(owner, ref val4);
				PlayerBackpack val5 = default(PlayerBackpack);
				PlayerBackpackManager.TryGetBackpack(owner2, ref val5);
				BackpackItem val6 = default(BackpackItem);
				bool flag = val4.TryGetBackpackItem(inventorySlot, ref val6);
				BackpackItem val7 = default(BackpackItem);
				bool flag2 = val5.TryGetBackpackItem(inventorySlot, ref val7);
				if (flag2 && flag)
				{
					pItemData_Custom val8 = default(pItemData_Custom);
					val8.ammo = val4.AmmoStorage.GetAmmoInPack(val);
					val8.byteId = val6.Instance.pItemData.custom.byteId;
					val8.byteState = val6.Instance.pItemData.custom.byteState;
					pItemData_Custom val9 = val8;
					val6.Instance.SetCustomData(val9, false);
					val8 = default(pItemData_Custom);
					val8.ammo = val5.AmmoStorage.GetAmmoInPack(val);
					val8.byteId = val7.Instance.pItemData.custom.byteId;
					val8.byteState = val7.Instance.pItemData.custom.byteState;
					pItemData_Custom val10 = val8;
					val7.Instance.SetCustomData(val10, false);
					PlayerBackpackManager.MasterRemoveItem(val6.Instance, owner);
					PlayerBackpackManager.MasterRemoveItem(val7.Instance, owner2);
					PlayerBackpackManager.MasterAddItem(val6.Instance, owner2);
					PlayerBackpackManager.MasterAddItem(val7.Instance, owner);
				}
				else if (!flag2 && flag)
				{
					pItemData_Custom val8 = default(pItemData_Custom);
					val8.ammo = val4.AmmoStorage.GetAmmoInPack(val);
					val8.byteId = val6.Instance.pItemData.custom.byteId;
					val8.byteState = val6.Instance.pItemData.custom.byteState;
					pItemData_Custom val11 = val8;
					val6.Instance.SetCustomData(val11, false);
					PlayerBackpackManager.MasterRemoveItem(val6.Instance, owner);
					PlayerBackpackManager.MasterAddItem(val6.Instance, owner2);
				}
				else if (flag2 && !flag)
				{
					pItemData_Custom val8 = default(pItemData_Custom);
					val8.ammo = val5.AmmoStorage.GetAmmoInPack(val);
					val8.byteId = val7.Instance.pItemData.custom.byteId;
					val8.byteState = val7.Instance.pItemData.custom.byteState;
					pItemData_Custom val12 = val8;
					val7.Instance.SetCustomData(val12, false);
					PlayerBackpackManager.MasterRemoveItem(val7.Instance, owner2);
					PlayerBackpackManager.MasterAddItem(val7.Instance, owner);
				}
			}
		}
	}
}
namespace ExchangeItem.Handlers
{
	internal static class ExchangeItemManager
	{
		[CompilerGenerated]
		private static Action m_OnUpdated;

		[field: CompilerGenerated]
		public static bool InteractionAllowed
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		public static PlayerAgent TargetPlayerAgent
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		public static ItemEquippable LocalPlayerWieldingItem
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		public static InventorySlot LocalPlayerWieldingSlot
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		public static float TargetPlayerAmmoInPack
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		public static float LocalPlayerAmmoInPack
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		public static Item TargetPlayerInventoryItem
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		public static Item LocalPlayerInventoryItem
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		public static ItemEquippable TargetPlayerWieldingItem
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		public static InventorySlot TargetPlayerWieldingSlot
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		public static EnumTypes.ExchangeType ExchangeType
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		public static InventorySlot ExchangeSlot
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		public static event Action OnUpdated
		{
			[CompilerGenerated]
			add
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Expected O, but got Unknown
				Action val = ExchangeItemManager.m_OnUpdated;
				Action val2;
				do
				{
					val2 = val;
					Action val3 = (Action)global::System.Delegate.Combine((global::System.Delegate)(object)val2, (global::System.Delegate)(object)value);
					val = Interlocked.CompareExchange<Action>(ref ExchangeItemManager.m_OnUpdated, val3, val2);
				}
				while (val != val2);
			}
			[CompilerGenerated]
			remove
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Expected O, but got Unknown
				Action val = ExchangeItemManager.m_OnUpdated;
				Action val2;
				do
				{
					val2 = val;
					Action val3 = (Action)global::System.Delegate.Remove((global::System.Delegate)(object)val2, (global::System.Delegate)(object)value);
					val = Interlocked.CompareExchange<Action>(ref ExchangeItemManager.m_OnUpdated, val3, val2);
				}
				while (val != val2);
			}
		}

		public static void Update()
		{
			SetInventoryItem();
			InteractionAllowed = IsInteractionAllowed();
			Action onUpdated = ExchangeItemManager.OnUpdated;
			if (onUpdated != null)
			{
				onUpdated.Invoke();
			}
		}

		private static bool IsInteractionAllowed()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			if (!((Object)(object)TargetPlayerAgent == (Object)null) && ExchangeType != EnumTypes.ExchangeType.Invalid && (int)LocalPlayerWieldingSlot != 4 && ExchangeItemData.AllowExchangeItem && ((Dam_SyncedDamageBase)TargetPlayerAgent.Damage).Health > 0f)
			{
				return ((Dam_SyncedDamageBase)ExchangeItemData.LocalPlayer.Damage).Health > 0f;
			}
			return false;
		}

		public static void Clear()
		{
			InteractionAllowed = false;
			LocalPlayerWieldingItem = null;
			LocalPlayerWieldingSlot = (InventorySlot)0;
			TargetPlayerWieldingItem = null;
			TargetPlayerWieldingSlot = (InventorySlot)0;
			LocalPlayerInventoryItem = null;
			LocalPlayerAmmoInPack = 0f;
			TargetPlayerInventoryItem = null;
			TargetPlayerAmmoInPack = 0f;
			ExchangeType = EnumTypes.ExchangeType.Invalid;
		}

		static ExchangeItemManager()
		{
		}

		public static void SetTargetPlayerAgent(PlayerAgent targetPlayerAgent)
		{
			if ((Object)(object)TargetPlayerAgent != (Object)(object)targetPlayerAgent)
			{
				TargetPlayerAgent = targetPlayerAgent;
				Update();
				return;
			}
			global::System.IntPtr intPtr = global::System.IntPtr.Zero;
			global::System.IntPtr intPtr2 = global::System.IntPtr.Zero;
			if ((Object)(object)TargetPlayerAgent != (Object)null)
			{
				intPtr = ((Il2CppObjectBase)TargetPlayerAgent).Pointer;
			}
			if ((Object)(object)targetPlayerAgent != (Object)null)
			{
				intPtr2 = ((Il2CppObjectBase)targetPlayerAgent).Pointer;
			}
			if (intPtr != intPtr2)
			{
				TargetPlayerAgent = targetPlayerAgent;
				Update();
			}
		}

		public static void SetInventoryItem()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_0070: 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_00d2: 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_012a: Invalid comparison between Unknown and I4
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Invalid comparison between Unknown and I4
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			ExchangeSlot = (InventorySlot)4;
			InventorySlot val = (InventorySlot)4;
			AmmoType val2 = (AmmoType)3;
			if ((int)LocalPlayerWieldingSlot == 5)
			{
				ExchangeSlot = (InventorySlot)5;
				val = (InventorySlot)5;
				val2 = (AmmoType)5;
			}
			while (true)
			{
				BackpackItem val3 = new BackpackItem();
				BackpackItem val4 = new BackpackItem();
				bool flag = false;
				bool flag2 = false;
				if ((Object)(object)TargetPlayerAgent != (Object)null)
				{
					flag2 = PlayerBackpackManager.GetBackpack(TargetPlayerAgent.Owner).TryGetBackpackItem(val, ref val3);
				}
				if ((Object)(object)ExchangeItemData.LocalPlayer != (Object)null)
				{
					flag = PlayerBackpackManager.GetBackpack(ExchangeItemData.LocalPlayer.Owner).TryGetBackpackItem(val, ref val4);
				}
				if (flag2)
				{
					TargetPlayerAmmoInPack = PlayerBackpackManager.GetBackpack(TargetPlayerAgent.Owner).AmmoStorage.GetAmmoInPack(val2);
					TargetPlayerInventoryItem = val3.Instance;
				}
				else
				{
					TargetPlayerInventoryItem = null;
					TargetPlayerAmmoInPack = 0f;
				}
				if (flag)
				{
					LocalPlayerAmmoInPack = PlayerBackpackManager.GetBackpack(ExchangeItemData.LocalPlayer.Owner).AmmoStorage.GetAmmoInPack(val2);
					LocalPlayerInventoryItem = val4.Instance;
				}
				else
				{
					LocalPlayerInventoryItem = null;
					LocalPlayerAmmoInPack = 0f;
				}
				if (!(flag && flag2))
				{
					if (!(!flag && flag2))
					{
						if (!(!flag2 && flag))
						{
							if ((int)val != 4)
							{
								break;
							}
							ExchangeSlot = (InventorySlot)5;
							val = (InventorySlot)5;
							val2 = (AmmoType)5;
							continue;
						}
						ExchangeType = EnumTypes.ExchangeType.SourceToTarget;
						return;
					}
					if ((int)val != 4)
					{
						break;
					}
					ExchangeType = EnumTypes.ExchangeType.TargetToSource;
					return;
				}
				ExchangeType = EnumTypes.ExchangeType.Exchange;
				return;
			}
			ExchangeType = EnumTypes.ExchangeType.Invalid;
		}

		public static void SetWieldingItem(ItemEquippable wieldingItem, InventorySlot slot, EnumTypes.AgentType agentType)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: 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_0011: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			if (agentType == EnumTypes.AgentType.LocalAgent)
			{
				if (LocalPlayerWieldingSlot != slot)
				{
					LocalPlayerWieldingItem = wieldingItem;
					LocalPlayerWieldingSlot = slot;
					Update();
					return;
				}
				global::System.IntPtr intPtr = global::System.IntPtr.Zero;
				global::System.IntPtr intPtr2 = global::System.IntPtr.Zero;
				if ((Object)(object)LocalPlayerWieldingItem != (Object)null)
				{
					intPtr = ((Il2CppObjectBase)LocalPlayerWieldingItem).Pointer;
				}
				if ((Object)(object)wieldingItem != (Object)null)
				{
					intPtr2 = ((Il2CppObjectBase)wieldingItem).Pointer;
				}
				if (intPtr != intPtr2)
				{
					LocalPlayerWieldingItem = wieldingItem;
					LocalPlayerWieldingSlot = slot;
					Update();
				}
			}
			else if (TargetPlayerWieldingSlot != slot)
			{
				TargetPlayerWieldingItem = wieldingItem;
				TargetPlayerWieldingSlot = slot;
				Update();
			}
			else
			{
				global::System.IntPtr intPtr3 = global::System.IntPtr.Zero;
				global::System.IntPtr intPtr4 = global::System.IntPtr.Zero;
				if ((Object)(object)TargetPlayerWieldingItem != (Object)null)
				{
					intPtr3 = ((Il2CppObjectBase)TargetPlayerWieldingItem).Pointer;
				}
				if ((Object)(object)wieldingItem != (Object)null)
				{
					intPtr4 = ((Il2CppObjectBase)wieldingItem).Pointer;
				}
				if (intPtr3 != intPtr4)
				{
					TargetPlayerWieldingItem = wieldingItem;
					TargetPlayerWieldingSlot = slot;
					Update();
				}
			}
		}
	}
}
namespace ExchangeItem
{
	[BepInPlugin("Hikaria.ExchangeItem", "ExchangeItem", "1.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class EntryPoint : BasePlugin
	{
		private static Harmony _harmonyInstance;

		private static readonly Dictionary<global::System.Type, Patch> RegisteredPatches;

		public static bool IsLogged;

		public static string DetectedLatestVersion;

		[field: CompilerGenerated]
		public static EntryPoint Instance
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		public override void Load()
		{
			Instance = this;
			SetConfig(new ConfigManager());
			RegisterPatches();
			RegisterTypesInIl2Cpp();
			RegisterEventsInNidhogg();
			Logs.LogMessage("OK");
		}

		public static void RegisterPatch<T>() where T : Patch, new()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			if (_harmonyInstance == null)
			{
				_harmonyInstance = new Harmony("Hikaria.ExchangeItem");
			}
			if (RegisteredPatches.ContainsKey(typeof(T)))
			{
				Logs.LogMessage($"Ignore duplicate patches: {((MemberInfo)typeof(T)).Name}");
				return;
			}
			T val = new T
			{
				Harmony = _harmonyInstance
			};
			val.Initialize();
			if (val.Enabled)
			{
				Logs.LogMessage($"Applying patch: {val.Name}");
				val.Execute();
			}
			RegisteredPatches[typeof(T)] = val;
		}

		private static void SetConfig(ConfigManager configManager)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			ExchangeItemData.AllowExchangeItem = configManager.GetAllowExchangeItem();
			ExchangeItemData.ExchangeItemKey = configManager.GetExchangeItemKey();
			ExchangeItemData.EnableExchangeItemMessage = configManager.GetEnableExchangeItemMessage();
			ExchangeItemData.ExchangeItemHint_Exchange = configManager.GetExchangeItemHint_Exchange();
			ExchangeItemData.ExchangeItemHint_SourceToTarget = configManager.GetExchangeItemHint_SourceToTarget();
			ExchangeItemData.ExchangeItemHint_TargetToSource = configManager.GetExchangeItemHint_TargetToSource();
			ExchangeItemData.ExchangeItemMessage_Exchange = configManager.GetExchangeItemMessage_Exchange();
			ExchangeItemData.ExchangeItemMessage_SourceToTarget = configManager.GetExchangeItemMessage_SourceToTarget();
			ExchangeItemData.ExchangeItemMessage_TargetToSource = configManager.GetExchangeItemMessage_TargetToSource();
		}

		private static void RegisterPatches()
		{
			RegisterPatch<PlayerJoinLobby>();
			RegisterPatch<LocalPlayerPatch>();
			RegisterPatch<Command>();
		}

		private static void RegisterEventsInNidhogg()
		{
			NetworkingManager.RegisterEvent<NidhoggNetworkStructs.ExchangeItemRequest>("ExchangeItem_ExchangeItem", (Action<ulong, NidhoggNetworkStructs.ExchangeItemRequest>)delegate(ulong senderId, NidhoggNetworkStructs.ExchangeItemRequest packet)
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				ExchangeItemUtils.WantToExchangeItem(packet.sourcePlayerSlotIndex, packet.targetPlayerSlotIndex, packet.inventorySlot);
				if (ExchangeItemData.EnableExchangeItemMessage)
				{
					ChatManager.SpeakInSeparate(packet.message);
				}
				SNet_Player val3 = default(SNet_Player);
				SNet.TryGetPlayer(senderId, ref val3);
				NetworkingManager.InvokeEvent<NidhoggNetworkStructs.AfterExchangeItemInventoryFix>("ExchangeItem_AfterExchangeItemInventoryFix", default(NidhoggNetworkStructs.AfterExchangeItemInventoryFix), val3);
			});
			NetworkingManager.RegisterEvent<NidhoggNetworkStructs.SettingsSync>("ExchangeItem_SettingsSync", (Action<ulong, NidhoggNetworkStructs.SettingsSync>)delegate(ulong senderId, NidhoggNetworkStructs.SettingsSync packet)
			{
				ExchangeItemData.AllowExchangeItem = packet.AllowExchangeItem;
			});
			NetworkingManager.RegisterEvent<NidhoggNetworkStructs.RequestSettingsSync>("ExchangeItem_RequestSettingsSync", (Action<ulong, NidhoggNetworkStructs.RequestSettingsSync>)delegate(ulong senderId, NidhoggNetworkStructs.RequestSettingsSync packet)
			{
				SNet_Player val2 = default(SNet_Player);
				SNet.TryGetPlayer(senderId, ref val2);
				NetworkingManager.InvokeEvent<NidhoggNetworkStructs.SettingsSync>("ExchangeItem_SettingsSync", new NidhoggNetworkStructs.SettingsSync
				{
					AllowExchangeItem = ExchangeItemData.AllowExchangeItem
				}, val2);
			});
			NetworkingManager.RegisterEvent<NidhoggNetworkStructs.CheckVersion>("ExchangeItem_CheckVersion", (Action<ulong, NidhoggNetworkStructs.CheckVersion>)delegate(ulong senderId, NidhoggNetworkStructs.CheckVersion packet)
			{
				int num = Convert.ToInt32("10000");
				int num2 = Convert.ToInt32(packet.INTERNAL_VERSION);
				if (num > num2)
				{
					SNet_Player val = default(SNet_Player);
					SNet.TryGetPlayer(senderId, ref val);
					NetworkingManager.InvokeEvent<NidhoggNetworkStructs.CheckVersion>("ExchangeItem_CheckVersion", new NidhoggNetworkStructs.CheckVersion
					{
						INTERNAL_VERSION = "10000",
						PLUGIN_VERSION = "1.0.1",
						CHANGE_LOG = "First version released"
					}, val);
				}
				if (num < num2 && num2 > Convert.ToInt32(DetectedLatestVersion))
				{
					DetectedLatestVersion = packet.INTERNAL_VERSION;
					GameEventLogManager.AddLog("<#F80>[ExchangeItem] <#0F0>New version detected: " + packet.PLUGIN_VERSION);
					GameEventLogManager.AddLogInSeparate("<#F80>[ExchangeItem] Change log: " + packet.CHANGE_LOG);
					GameEventLogManager.AddLog("<#F80>[ExchangeItem] <#F00>Please update the plug-in in time. Different versions may cause the plug-in to function abnormally.");
				}
			});
			NetworkingManager.RegisterEvent<NidhoggNetworkStructs.AfterExchangeItemInventoryFix>("ExchangeItem_AfterExchangeItemInventoryFix", (Action<ulong, NidhoggNetworkStructs.AfterExchangeItemInventoryFix>)delegate
			{
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				ExchangeItemData.LocalPlayer.Inventory.ReceiveSetFlashlightStatus(ExchangeItemData.CurrentFlashlightState, false);
				GuiManager.PlayerLayer.Inventory.UpdateAllSlots(ExchangeItemData.LocalPlayer.Owner, ExchangeItemData.LocalPlayer.Inventory.WieldedSlot);
			});
		}

		private static void RegisterTypesInIl2Cpp()
		{
			ClassInjector.RegisterTypeInIl2Cpp<GameEventLogManager>();
			ClassInjector.RegisterTypeInIl2Cpp<ChatManager>();
			ClassInjector.RegisterTypeInIl2Cpp<ExchangeItemHandler>();
			ClassInjector.RegisterTypeInIl2Cpp<ExchangeItemUpdater>();
		}

		static EntryPoint()
		{
			RegisteredPatches = new Dictionary<global::System.Type, Patch>();
			IsLogged = false;
			DetectedLatestVersion = "10000";
		}
	}
}
namespace ExchangeItem.Patches
{
	internal class PlayerInteractionBlocker : Patch
	{
		private const string PatchName = "PlayerInteractionBlocker";

		[field: CompilerGenerated]
		public override string Name
		{
			[CompilerGenerated]
			get;
		} = "PlayerInteractionBlocker";


		[field: CompilerGenerated]
		public static Patch Instance
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		public override void Execute()
		{
			PatchMethod<PlayerInteraction>("UpdateWorldInteractions", PatchType.Prefix);
		}

		public override void Initialize()
		{
			Instance = this;
		}

		private static bool PlayerInteraction__UpdateWorldInteractions__Prefix()
		{
			return !ExchangeItemManager.InteractionAllowed;
		}
	}
}
namespace ExchangeItem.Utils
{
	internal class ChatManager : MonoBehaviour
	{
		public static List<string> queue;

		public static int front;

		private void Update()
		{
			try
			{
				if (queue[front] != null)
				{
					GameEventLogManager.Speak(queue[front]);
					front++;
				}
			}
			catch (global::System.Exception)
			{
			}
		}

		static ChatManager()
		{
			queue = new List<string>();
			front = 0;
		}

		private static string[] getstr(string strs, int len)
		{
			string[] array = new string[int.Parse(Math.Ceiling((double)strs.Length / (double)len).ToString())];
			for (int i = 0; i < array.Length; i++)
			{
				len = ((len <= strs.Length) ? len : strs.Length);
				array[i] = strs.Substring(0, len);
				strs = strs.Substring(len, strs.Length - len);
			}
			return array;
		}

		public static void SpeakInSeparate(string str, int len = 50)
		{
			if (str.Length > len)
			{
				string[] array = getstr(str, len);
				foreach (string text in array)
				{
					queue.Add(text);
				}
			}
			else
			{
				queue.Add(str);
			}
		}
	}
	internal static class NidhoggNetworkStructs
	{
		[StructLayout(0, CharSet = 3)]
		public struct ExchangeItemRequest
		{
			public int sourcePlayerSlotIndex;

			public int targetPlayerSlotIndex;

			[MarshalAs(23, SizeConst = 150)]
			public string message;

			public InventorySlot inventorySlot;
		}

		[StructLayout(0, CharSet = 3)]
		public struct SettingsSync
		{
			public bool AllowExchangeItem;
		}

		[StructLayout(0, CharSet = 3)]
		public struct RequestSettingsSync
		{
		}

		[StructLayout(0, CharSet = 3)]
		public struct CheckVersion
		{
			[MarshalAs(23, SizeConst = 10)]
			public string INTERNAL_VERSION;

			[MarshalAs(23, SizeConst = 10)]
			public string PLUGIN_VERSION;

			[MarshalAs(23, SizeConst = 100)]
			public string CHANGE_LOG;
		}

		[StructLayout(0, CharSet = 3)]
		public struct AfterExchangeItemInventoryFix
		{
		}
	}
	internal class EnumTypes
	{
		[Flags]
		public enum Settings : byte
		{
			None = 0,
			AllowExchangeItemWithOthers = 1,
			All = 2
		}

		[Flags]
		public enum ExchangeType : byte
		{
			TargetToSource = 0,
			SourceToTarget = 1,
			Exchange = 2,
			Invalid = 3
		}

		[Flags]
		public enum AgentType : byte
		{
			LocalAgent = 0,
			TargetAgent = 1
		}
	}
}
namespace ExchangeItem.Handlers
{
	internal sealed class ExchangeItemHandler : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <Interaction>d__10__0 : global::System.Collections.Generic.IEnumerator<object>, global::System.IDisposable, global::System.Collections.IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public float interactionTime;

			public ExchangeItemHandler <>4__this;

			private float <timer>5__2;

			private bool <timerInterrupted>5__3;

			object global::System.Collections.Generic.IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object global::System.Collections.IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <Interaction>d__10__0(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void global::System.IDisposable.Dispose()
			{
			}

			private bool MoveNext()
			{
				//IL_0161: Unknown result type (might be due to invalid IL or missing references)
				//IL_0166: 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_0124: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				ExchangeItemHandler exchangeItemHandler = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					SetExchangeItemMessage();
					<timer>5__2 = 0f;
					<timerInterrupted>5__3 = false;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<timer>5__2 <= interactionTime)
				{
					if (ExchangeItemManager.InteractionAllowed)
					{
						SetExchangeItemMessage();
						GuiManager.InteractionLayer.SetTimer(<timer>5__2 / interactionTime);
						<timer>5__2 += Time.deltaTime;
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					<timerInterrupted>5__3 = true;
				}
				if (!<timerInterrupted>5__3)
				{
					ExchangeItemData.CurrentFlashlightState = ExchangeItemData.LocalPlayer.Inventory.FlashlightEnabled;
					if (ExchangeItemData.IsMaster)
					{
						ExchangeItemUtils.WantToExchangeItem(ExchangeItemData.LocalPlayer.PlayerSlotIndex, ExchangeItemManager.TargetPlayerAgent.PlayerSlotIndex, ExchangeItemManager.ExchangeSlot);
						if (ExchangeItemData.EnableExchangeItemMessage)
						{
							ChatManager.SpeakInSeparate(_Message);
						}
						ExchangeItemData.LocalPlayer.Inventory.ReceiveSetFlashlightStatus(ExchangeItemData.CurrentFlashlightState, false);
						GuiManager.PlayerLayer.Inventory.UpdateAllSlots(ExchangeItemData.LocalPlayer.Owner, ExchangeItemData.LocalPlayer.Inventory.WieldedSlot);
					}
					else
					{
						NetworkingManager.InvokeEvent<NidhoggNetworkStructs.ExchangeItemRequest>("ExchangeItem_ExchangeItem", new NidhoggNetworkStructs.ExchangeItemRequest
						{
							sourcePlayerSlotIndex = ExchangeItemData.LocalPlayer.PlayerSlotIndex,
							targetPlayerSlotIndex = ExchangeItemManager.TargetPlayerAgent.PlayerSlotIndex,
							inventorySlot = ExchangeItemManager.ExchangeSlot,
							message = _Message
						}, SNet.Master);
					}
				}
				StopInteraction();
				exchangeItemHandler._InteractionRoutine = null;
				return false;
			}

			bool global::System.Collections.IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void global::System.Collections.IEnumerator.Reset()
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				throw new NotSupportedException();
			}
		}

		private bool _ExchangeItemAllowed;

		private bool _HoldingKey;

		private static string _ExchangeItemMessage;

		private static string _ExchangeItemButton;

		private Coroutine _InteractionRoutine;

		private static string _Message;

		private void Awake()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			ExchangeItemManager.OnUpdated += new Action(ExchangeItemManager_OnUpdated);
		}

		private void Update()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (_ExchangeItemAllowed && !_HoldingKey)
			{
				if (Input.GetKeyDown(ExchangeItemData.ExchangeItemKey))
				{
					StartRoutine();
					_HoldingKey = true;
				}
			}
			else if (Input.GetKeyUp(ExchangeItemData.ExchangeItemKey))
			{
				StopRoutine();
				_HoldingKey = false;
			}
		}

		private void OnDestroy()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			ExchangeItemManager.OnUpdated -= new Action(ExchangeItemManager_OnUpdated);
		}

		[HideFromIl2Cpp]
		private void ExchangeItemManager_OnUpdated()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			_ExchangeItemAllowed = ExchangeItemManager.InteractionAllowed;
			if (_ExchangeItemAllowed)
			{
				UpdateExchangeItemMessage();
				SetExchangeItemMessage();
			}
			else if ((int)ExchangeItemManager.LocalPlayerWieldingSlot != 4 || !_ExchangeItemAllowed)
			{
				GuiManager.InteractionLayer.InteractPromptVisible = false;
				GuiManager.InteractionLayer.SetInteractPrompt("", "", (ePUIMessageStyle)0);
			}
		}

		[HideFromIl2Cpp]
		private static void UpdateExchangeItemMessage()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			_ExchangeItemMessage = TextGen();
			_ExchangeItemButton = $"Press and hold'{ExchangeItemData.ExchangeItemKey}'";
		}

		private static void SetExchangeItemMessage()
		{
			GuiManager.InteractionLayer.InteractPromptVisible = true;
			GuiManager.InteractionLayer.SetInteractPrompt(_ExchangeItemMessage, _ExchangeItemButton, (ePUIMessageStyle)0);
		}

		[HideFromIl2Cpp]
		private void StartRoutine()
		{
			StopRoutine();
			_InteractionRoutine = MonoBehaviourExtensions.StartCoroutine((MonoBehaviour)(object)this, Interaction(0.4f));
			StartInteraction();
		}

		[HideFromIl2Cpp]
		private void StopRoutine()
		{
			if (_InteractionRoutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_InteractionRoutine);
				StopInteraction();
			}
		}

		[HideFromIl2Cpp]
		private static void StartInteraction()
		{
			GuiManager.InteractionLayer.InteractPromptVisible = true;
		}

		[HideFromIl2Cpp]
		private static void StopInteraction()
		{
			GuiManager.InteractionLayer.InteractPromptVisible = false;
		}

		[IteratorStateMachine(typeof(<Interaction>d__10__0))]
		[HideFromIl2Cpp]
		private global::System.Collections.IEnumerator Interaction(float interactionTime)
		{
			SetExchangeItemMessage();
			float timer = 0f;
			bool timerInterrupted = false;
			while (timer <= interactionTime)
			{
				if (!ExchangeItemManager.InteractionAllowed)
				{
					timerInterrupted = true;
					break;
				}
				SetExchangeItemMessage();
				GuiManager.InteractionLayer.SetTimer(timer / interactionTime);
				timer += Time.deltaTime;
				yield return null;
			}
			if (!timerInterrupted)
			{
				ExchangeItemData.CurrentFlashlightState = ExchangeItemData.LocalPlayer.Inventory.FlashlightEnabled;
				if (ExchangeItemData.IsMaster)
				{
					ExchangeItemUtils.WantToExchangeItem(ExchangeItemData.LocalPlayer.PlayerSlotIndex, ExchangeItemManager.TargetPlayerAgent.PlayerSlotIndex, ExchangeItemManager.ExchangeSlot);
					if (ExchangeItemData.EnableExchangeItemMessage)
					{
						ChatManager.SpeakInSeparate(_Message);
					}
					ExchangeItemData.LocalPlayer.Inventory.ReceiveSetFlashlightStatus(ExchangeItemData.CurrentFlashlightState, false);
					GuiManager.PlayerLayer.Inventory.UpdateAllSlots(ExchangeItemData.LocalPlayer.Owner, ExchangeItemData.LocalPlayer.Inventory.WieldedSlot);
				}
				else
				{
					NetworkingManager.InvokeEvent<NidhoggNetworkStructs.ExchangeItemRequest>("ExchangeItem_ExchangeItem", new NidhoggNetworkStructs.ExchangeItemRequest
					{
						sourcePlayerSlotIndex = ExchangeItemData.LocalPlayer.PlayerSlotIndex,
						targetPlayerSlotIndex = ExchangeItemManager.TargetPlayerAgent.PlayerSlotIndex,
						inventorySlot = ExchangeItemManager.ExchangeSlot,
						message = _Message
					}, SNet.Master);
				}
			}
			StopInteraction();
			_InteractionRoutine = null;
		}

		private static string TextGen()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			float num = (((int)ExchangeItemManager.ExchangeSlot == 4) ? 20f : 1f);
			string result = "Illegal operation";
			switch (ExchangeItemManager.ExchangeType)
			{
			case EnumTypes.ExchangeType.TargetToSource:
				result = string.Format("Get {1} times {2} from {0}", (object)ExchangeItemManager.TargetPlayerAgent.PlayerName, (object)(ExchangeItemManager.TargetPlayerAmmoInPack / num), (object)ExchangeItemManager.TargetPlayerInventoryItem.ArchetypeName);
				_Message = string.Format("{0} took {1} {2} times {3}", new object[4]
				{
					ExchangeItemData.LocalPlayer.PlayerName,
					ExchangeItemManager.TargetPlayerAgent.PlayerName,
					ExchangeItemManager.TargetPlayerAmmoInPack / num,
					ExchangeItemManager.TargetPlayerInventoryItem.ArchetypeName
				});
				return result;
			case EnumTypes.ExchangeType.SourceToTarget:
				result = $"Give {ExchangeItemManager.LocalPlayerAmmoInPack / num} times {ExchangeItemManager.LocalPlayerInventoryItem.ArchetypeName} to {ExchangeItemManager.TargetPlayerAgent.PlayerName}";
				_Message = string.Format("{0} gave {1} {2} times {3}", new object[4]
				{
					ExchangeItemData.LocalPlayer.PlayerName,
					ExchangeItemManager.TargetPlayerAgent.PlayerName,
					ExchangeItemManager.LocalPlayerAmmoInPack / num,
					ExchangeItemManager.LocalPlayerInventoryItem.ArchetypeName
				});
				return result;
			case EnumTypes.ExchangeType.Exchange:
				result = string.Format("Swap {0} times {1} with {2} {3} times {4}", new object[5]
				{
					ExchangeItemManager.LocalPlayerAmmoInPack / num,
					ExchangeItemManager.LocalPlayerInventoryItem.ArchetypeName,
					ExchangeItemManager.TargetPlayerAgent.PlayerName,
					ExchangeItemManager.TargetPlayerAmmoInPack / num,
					ExchangeItemManager.TargetPlayerInventoryItem.ArchetypeName
				});
				_Message = string.Format("{0} exchanged {1} times {2} with {3} {4} times {5}", new object[6]
				{
					ExchangeItemData.LocalPlayer.PlayerName,
					ExchangeItemManager.LocalPlayerAmmoInPack / num,
					ExchangeItemManager.LocalPlayerInventoryItem.ArchetypeName,
					ExchangeItemManager.TargetPlayerAgent.PlayerName,
					ExchangeItemManager.TargetPlayerAmmoInPack / num,
					ExchangeItemManager.TargetPlayerInventoryItem.ArchetypeName
				});
				return result;
			default:
				return result;
			}
		}

		static ExchangeItemHandler()
		{
			_ExchangeItemMessage = string.Empty;
			_ExchangeItemButton = string.Empty;
			_Message = string.Empty;
		}
	}
}

Nidhogg.dll

Decompiled a month ago
using System;
using System.CodeDom.Compiler;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using GameData;
using HarmonyLib;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using Nidhogg.Managers;
using Nidhogg.Managers.Impl;
using Nidhogg.Resources;
using SNetwork;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("Nidhogg")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Nidhogg")]
[assembly: AssemblyTitle("Nidhogg")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Nidhogg
{
	[BepInPlugin("com.kasuromi.nidhogg", "Nidhogg", "1.1.1")]
	internal class EntryPoint : BasePlugin
	{
		public override void Load()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			ClassInjector.RegisterTypeInIl2Cpp<NetworkingManagerImpl>();
			new Harmony("com.kasuromi.nidhogg").PatchAll();
		}
	}
	internal static class NidhoggLogger
	{
		private static readonly ManualLogSource _logger;

		static NidhoggLogger()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			_logger = new ManualLogSource("Nidhogg");
			Logger.Sources.Add((ILogSource)(object)_logger);
		}

		private static string Format(object msg)
		{
			return msg.ToString();
		}

		public static void Info(object data)
		{
			_logger.LogMessage((object)Format(data));
		}

		public static void Verbose(object data)
		{
		}

		public static void Debug(object data)
		{
			_logger.LogDebug((object)Format(data));
		}

		public static void Error(object data)
		{
			_logger.LogError((object)Format(data));
		}
	}
	[GeneratedCode("ConstantGenerator", "1.0.0")]
	[CompilerGenerated]
	public static class Constants
	{
		public const ulong VersionSignature = 18374688112852503932uL;

		public const ushort ReplicatorKey = 65533;

		public const string Magic = "NHKSQK";
	}
}
namespace Nidhogg.Resources
{
	public static class ManagerStatus
	{
		public static bool NetworkManagerCreated { get; internal set; }
	}
}
namespace Nidhogg.Managers
{
	internal class CachedEvent
	{
		public string EventName { get; set; }

		public Type Type { get; set; }

		public object OnReceive { get; set; }
	}
	public static class NetworkingManager
	{
		internal static ConcurrentDictionary<string, CachedEvent> s_EventCache;

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static bool IsEventRegistered(string eventName)
		{
			return NetworkingManagerImpl.Instance.EventExists(eventName);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static void RegisterEvent<T>(string eventName, Action<ulong, T> onReceive) where T : struct
		{
			if (ManagerStatus.NetworkManagerCreated)
			{
				NetworkingManagerImpl.Instance.RegisterEvent(eventName, onReceive);
				return;
			}
			if (s_EventCache.ContainsKey(eventName))
			{
				throw new ArgumentException("An event with the name " + eventName + " has already been registered.");
			}
			s_EventCache.TryAdd(eventName, new CachedEvent
			{
				EventName = eventName,
				Type = typeof(T),
				OnReceive = onReceive
			});
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static void InvokeEvent<T>(string eventName, T payload) where T : struct
		{
			//IL_0001: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			SNet_ChannelType val = (SNet_ChannelType)2;
			SNet_SendGroup val2 = default(SNet_SendGroup);
			SNet_SendQuality val3 = default(SNet_SendQuality);
			int num = default(int);
			SNet.GetSendSettings(ref val, ref val2, ref val3, ref num);
			SNet.Core.SendBytes(Il2CppStructArray<byte>.op_Implicit(NetworkingManagerImpl.Instance.MakePacketBytes(eventName, payload)), val2, val3, num);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static void InvokeEvent<T>(string eventName, T payload, SNet_Player target) where T : struct
		{
			//IL_0001: 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)
			SNet_ChannelType val = (SNet_ChannelType)2;
			SNet_SendGroup val2 = default(SNet_SendGroup);
			SNet_SendQuality val3 = default(SNet_SendQuality);
			int num = default(int);
			SNet.GetSendSettings(ref val, ref val2, ref val3, ref num);
			SNet.Core.SendBytes(Il2CppStructArray<byte>.op_Implicit(NetworkingManagerImpl.Instance.MakePacketBytes(eventName, payload)), val3, num, target);
		}

		static NetworkingManager()
		{
			s_EventCache = new ConcurrentDictionary<string, CachedEvent>();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static void InvokeEvent<T>(string eventName, T payload, List<SNet_Player> targets) where T : struct
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			List<SNet_Player> val = new List<SNet_Player>(targets.Count);
			for (int i = 0; i < targets.Count; i++)
			{
				val.Add(targets[i]);
			}
			SNet_ChannelType val2 = (SNet_ChannelType)2;
			SNet_SendGroup val3 = default(SNet_SendGroup);
			SNet_SendQuality val4 = default(SNet_SendQuality);
			int num = default(int);
			SNet.GetSendSettings(ref val2, ref val3, ref val4, ref num);
			SNet.Core.SendBytes(Il2CppStructArray<byte>.op_Implicit(NetworkingManagerImpl.Instance.MakePacketBytes(eventName, payload)), val4, num, val);
		}
	}
}
namespace Nidhogg.Managers.Impl
{
	internal class NetworkingEventInfo<T> where T : struct
	{
		public string Name { get; set; }

		public Action<ulong, T> OnReceive { get; set; }
	}
	internal class NetworkingManagerImpl : MonoBehaviour
	{
		public ushort m_ReplicatorKey = 65533;

		public ulong m_Signature = 18374688112852503932uL;

		private readonly Dictionary<string, object> m_Events = new Dictionary<string, object>();

		private readonly Dictionary<string, Type> m_EventTypes = new Dictionary<string, Type>();

		private static NetworkingManagerImpl s_Instance;

		public static NetworkingManagerImpl Instance
		{
			get
			{
				if ((Object)(object)s_Instance == (Object)null)
				{
					NetworkingManagerImpl networkingManagerImpl = Object.FindObjectOfType<NetworkingManagerImpl>();
					if ((Object)(object)networkingManagerImpl != (Object)null)
					{
						s_Instance = networkingManagerImpl;
					}
				}
				return s_Instance;
			}
		}

		public NetworkingManagerImpl(IntPtr intPtr)
			: base(intPtr)
		{
		}

		private void Awake()
		{
			s_Instance = this;
			foreach (KeyValuePair<string, CachedEvent> item in NetworkingManager.s_EventCache)
			{
				typeof(NetworkingManagerImpl).GetMethod("RegisterEvent").MakeGenericMethod(item.Value.Type).Invoke(this, new object[2]
				{
					item.Key,
					item.Value.OnReceive
				});
			}
		}

		internal static void UnmaskPacket(ref byte[] packetBytes, ulong versionSig, int offset)
		{
			MaskPacket(ref packetBytes, versionSig, offset);
		}

		internal unsafe static void MaskPacket(ref byte[] packetBytes, ulong versionSig, int offset)
		{
			byte* ptr;
			byte[] array;
			if ((array = packetBytes) == null || array.Length == 0)
			{
				ptr = null;
			}
			else
			{
				fixed (byte* ptr2 = &array[0])
				{
					ptr = ptr2;
				}
			}
			MaskPacketImpl(ptr + offset, (uint)(packetBytes.Length - offset), (byte*)(&versionSig));
			array = null;
		}

		internal unsafe static void MaskPacketImpl(byte* pPacket, uint packetLength, byte* pVersion)
		{
			for (int i = 0; i < packetLength; i++)
			{
				pPacket[i] ^= pVersion[i % 8];
			}
		}

		[HideFromIl2Cpp]
		public void HandlePacket(string eventName, ulong senderId, byte[] packetData, int startIndex = 0)
		{
			Type type = m_EventTypes[eventName];
			object obj = m_Events[eventName];
			UnmaskPacket(ref packetData, m_Signature, startIndex);
			int num = Marshal.SizeOf(type);
			IntPtr intPtr = Marshal.AllocHGlobal(num);
			Marshal.Copy(packetData, startIndex, intPtr, num);
			object obj2 = Marshal.PtrToStructure(intPtr, type);
			Marshal.FreeHGlobal(intPtr);
			object value = obj.GetType().GetProperty("OnReceive").GetValue(obj);
			typeof(Action<, >).MakeGenericType(typeof(ulong), type).GetMethod("Invoke").Invoke(value, new object[2] { senderId, obj2 });
		}

		public void RegisterEvent<T>(string eventName, Action<ulong, T> onReceive) where T : struct
		{
			if (EventExists(eventName))
			{
				throw new ArgumentException("An event with the name " + eventName + " has already been registered.");
			}
			NetworkingEventInfo<T> value = new NetworkingEventInfo<T>
			{
				Name = eventName,
				OnReceive = onReceive
			};
			m_Events.Add(eventName, value);
			m_EventTypes.Add(eventName, typeof(T));
		}

		[HideFromIl2Cpp]
		public bool EventExists(string eventName)
		{
			return m_Events.ContainsKey(eventName);
		}

		public byte[] MakePacketBytes<T>(string eventName, T payload) where T : struct
		{
			byte[] bytes = Encoding.UTF8.GetBytes(eventName);
			int num = 18 + bytes.Length + Marshal.SizeOf<T>();
			IntPtr intPtr;
			IntPtr intPtr2 = (intPtr = Marshal.AllocHGlobal(num));
			Marshal.WriteInt16(intPtr, (short)m_ReplicatorKey);
			intPtr += 2;
			Marshal.Copy(Encoding.ASCII.GetBytes("NHKSQK"), 0, intPtr, 6);
			intPtr += 6;
			Marshal.WriteInt64(intPtr, (long)m_Signature);
			intPtr += 8;
			Marshal.WriteInt16(intPtr, (short)bytes.Length);
			intPtr += 2;
			Marshal.Copy(bytes, 0, intPtr, bytes.Length);
			intPtr += bytes.Length;
			Marshal.StructureToPtr(payload, intPtr, fDeleteOld: true);
			byte[] packetBytes = new byte[num];
			Marshal.Copy(intPtr2, packetBytes, 0, num);
			Marshal.FreeHGlobal(intPtr2);
			MaskPacket(ref packetBytes, m_Signature, 18 + bytes.Length);
			return packetBytes;
		}
	}
}
namespace Nidhogg.Hooks
{
	[HarmonyPatch(typeof(GameDataInit))]
	internal class GameDataInitHooks
	{
		[HarmonyPatch("Initialize")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		public static void Initialize_Prefix()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			if (!ManagerStatus.NetworkManagerCreated)
			{
				NidhoggLogger.Verbose("Creating Networking Manager!");
				GameObject val = new GameObject
				{
					name = "Nidhogg Networking Manager Dummy"
				};
				val.AddComponent<NetworkingManagerImpl>();
				Object.DontDestroyOnLoad((Object)val);
				ManagerStatus.NetworkManagerCreated = true;
			}
		}
	}
	[HarmonyPatch(typeof(SNet_Replication))]
	internal class SNet_ReplicationHooks
	{
		[HarmonyPatch("RecieveBytes")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		public static bool RecieveBytes_Prefix(Il2CppStructArray<byte> bytes, uint size, ulong messagerID)
		{
			if (size < 18)
			{
				return true;
			}
			ushort num = BitConverter.ToUInt16(Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)bytes), 0);
			if (NetworkingManagerImpl.Instance.m_ReplicatorKey != num)
			{
				return true;
			}
			string @string = Encoding.ASCII.GetString(Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)bytes), 2, 6);
			if (@string != "NHKSQK")
			{
				NidhoggLogger.Verbose(string.Format("Received invalid magic from {0} ({1} != {2}).", messagerID, @string, "NHKSQK"));
				return true;
			}
			ulong num2 = BitConverter.ToUInt64(Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)bytes), 8);
			if ((num2 & 0xFF00000000000000uL) != 18374686479671623680uL)
			{
				NidhoggLogger.Verbose($"Received invalid version signature from {messagerID}.");
				return true;
			}
			if (num2 != NetworkingManagerImpl.Instance.m_Signature)
			{
				NidhoggLogger.Error($"Received incompatible version signature, cannot unmask packet. Is {messagerID} on the same version?. ({num2} != {NetworkingManagerImpl.Instance.m_Signature})");
				return false;
			}
			ushort num3 = BitConverter.ToUInt16(Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)bytes), 16);
			string string2 = Encoding.UTF8.GetString(Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)bytes), 18, num3);
			if (!NetworkingManager.IsEventRegistered(string2))
			{
				NidhoggLogger.Error($"{messagerID} invoked an event {string2} which isn't registered.");
				return false;
			}
			NetworkingManagerImpl.Instance.HandlePacket(string2, messagerID, Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)bytes), 18 + num3);
			return false;
		}
	}
}