Decompiled source of Simple Multi Player v1.8.1

WKMultiPlayerMod.dll

Decompiled 3 weeks ago
using System;
using System.Buffers;
using System.Buffers.Binary;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DG.Tweening;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Steamworks;
using Steamworks.Data;
using TMPro;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using WKMPMod.Asset;
using WKMPMod.Component;
using WKMPMod.Core;
using WKMPMod.Data;
using WKMPMod.MK_Component;
using WKMPMod.NetWork;
using WKMPMod.Patch;
using WKMPMod.RemotePlayer;
using WKMPMod.Team;
using WKMPMod.UI;
using WKMPMod.Util;
using WKMPMod.World;
using WKMPModa.Shared.Component;
using WKMPModa.Shared.Data;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("WKMultiPlayerMod")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.8.1.0")]
[assembly: AssemblyInformationalVersion("1.8.1.0+2fcde0af4a9aa09bb6ab7267cad8d22e0247f903")]
[assembly: AssemblyProduct("WKMultiPlayerMod")]
[assembly: AssemblyTitle("WKMultiPlayerMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.8.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public abstract class Singleton<T> where T : Singleton<T>
{
	private static readonly Lazy<T> _instance = new Lazy<T>(CreateInstance, isThreadSafe: true);

	public static T Instance => _instance.Value;

	public static bool IsCreated => _instance.IsValueCreated;

	private static T CreateInstance()
	{
		try
		{
			ConstructorInfo constructor = typeof(T).GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
			if (constructor == null)
			{
				throw new InvalidOperationException("Singleton<" + typeof(T).Name + ">: Type must have a parameterless constructor");
			}
			return (T)constructor.Invoke(null);
		}
		catch (Exception innerException)
		{
			throw new InvalidOperationException("Singleton<" + typeof(T).Name + ">: Failed to create instance", innerException);
		}
	}

	protected Singleton()
	{
		if (_instance.IsValueCreated)
		{
			throw new InvalidOperationException("Singleton<" + typeof(T).Name + ">: Instance already exists. Use " + typeof(T).Name + ".Instance instead.");
		}
	}
}
namespace WKMPMod.World
{
	public enum PitonSyncAction : byte
	{
		Create,
		Update,
		Remove,
		HammerIn,
		Weaken,
		BreakRequest,
		Break,
		CreateChunkRequest,
		CreateChunk
	}
	public class ClimbableSyncModule : Singleton<ClimbableSyncModule>, ISyncModule
	{
		private static readonly FieldRef<Projectile, GameEntity> _sourceEntityField = AccessTools.FieldRefAccess<Projectile, GameEntity>("sourceEntity");

		private static readonly Action<M_Level, GameObject> _addPlacedObjectMethod = AccessTools.MethodDelegate<Action<M_Level, GameObject>>(AccessTools.Method(typeof(M_Level), "AddPlacedObject", (Type[])null, (Type[])null), (object)null, true);

		private static readonly FieldRef<CL_Handhold, List<Hand>> _handsField = AccessTools.FieldRefAccess<CL_Handhold, List<Hand>>("hands");

		private static readonly FieldRef<CL_Handhold, UT_SoftParent> _softParentField = AccessTools.FieldRefAccess<CL_Handhold, UT_SoftParent>("softParent");

		private static readonly FieldRef<CL_Handhold, float> _offsetAmountField = AccessTools.FieldRefAccess<CL_Handhold, float>("offsetAmount");

		private readonly Dictionary<ulong, ClimbableData> _globalPersistentTable = new Dictionary<ulong, ClimbableData>();

		private readonly Dictionary<ulong, Coroutine> _sendRoutines = new Dictionary<ulong, Coroutine>();

		private const int ChunkItemsPerFrame = 10;

		private static List<GameObject> _capturedPitons = new List<GameObject>();

		private readonly Dictionary<ulong, NetworkedClimable> _handhold = new Dictionary<ulong, NetworkedClimable>();

		private readonly Dictionary<ulong, NetworkedClimable> _localHandhold = new Dictionary<ulong, NetworkedClimable>();

		private readonly List<(NetworkedClimable Identity, float LastTime)> _holdingList = new List<(NetworkedClimable, float)>();

		private static readonly Dictionary<CL_Handhold, NetworkedClimable> _handholdLookup = new Dictionary<CL_Handhold, NetworkedClimable>();

		private ulong _nextLocalId = 1uL;

		private static readonly List<(ulong id, GameObject obj)> _breakItemObject = new List<(ulong, GameObject)>();

		private Coroutine _rebuildClimbable = null;

		private const float PeriodicUpdateInterval = 0.1f;

		private int _maxSyncPerFrame = 10;

		private float _timer = 0f;

		private bool _isSweeping = false;

		private int _sweepIndex = 0;

		private readonly List<NetworkedClimable> _sweepQueue = new List<NetworkedClimable>();

		private readonly List<NetworkedClimable> _batchBuffer = new List<NetworkedClimable>();

		private readonly List<ulong> _pendingRemoveKeys = new List<ulong>();

		public string ModuleName => "ClimbableSync";

		public bool IsEnabled { get; set; } = true;

		public bool ApplyingRemoteState { get; private set; }

		public void OnResetMap()
		{
			ResetState();
			if ((Object)(object)MonoSingleton<WorldSyncManager>.Instance != (Object)null)
			{
				_rebuildClimbable = ((MonoBehaviour)MonoSingleton<WorldSyncManager>.Instance).StartCoroutine(RebuildClimbable());
			}
		}

		public void OnLeave()
		{
			_globalPersistentTable.Clear();
			if ((Object)(object)MonoSingleton<WorldSyncManager>.Instance != (Object)null)
			{
				foreach (Coroutine value in _sendRoutines.Values)
				{
					if (value != null)
					{
						((MonoBehaviour)MonoSingleton<WorldSyncManager>.Instance).StopCoroutine(value);
					}
				}
			}
			_sendRoutines.Clear();
			_nextLocalId = 1uL;
			ResetState();
		}

		public void OnEnd()
		{
			OnLeave();
		}

		private void ResetSweepState()
		{
			_timer = 0f;
			_isSweeping = false;
			_sweepIndex = 0;
			_sweepQueue.Clear();
			_batchBuffer.Clear();
			_pendingRemoveKeys.Clear();
		}

		public void ResetState()
		{
			ResetSweepState();
			_capturedPitons.Clear();
			_handhold.Clear();
			_localHandhold.Clear();
			_holdingList.Clear();
			_handholdLookup.Clear();
			_breakItemObject.Clear();
			ApplyingRemoteState = false;
			if (_rebuildClimbable != null && (Object)(object)MonoSingleton<WorldSyncManager>.Instance != (Object)null)
			{
				((MonoBehaviour)MonoSingleton<WorldSyncManager>.Instance).StopCoroutine(_rebuildClimbable);
				_rebuildClimbable = null;
			}
		}

		public static void SaveCapturedPiton(GameObject go)
		{
			if ((Object)(object)((go != null) ? go.GetComponentInChildren<CL_Handhold>(true) : null) != (Object)null)
			{
				_capturedPitons.Add(go);
			}
		}

		public void RegisterNewLocalPiton()
		{
			if (_capturedPitons.Count == 0)
			{
				return;
			}
			if (!MPCore.IsReady || ApplyingRemoteState)
			{
				_capturedPitons.Clear();
				return;
			}
			foreach (GameObject capturedPiton in _capturedPitons)
			{
				GameObject climbableRoot = GetClimbableRoot(capturedPiton);
				if (!((Object)(object)climbableRoot == (Object)null))
				{
					RegisterLocalClimbable(climbableRoot);
				}
			}
			_capturedPitons.Clear();
		}

		public void RegisterNewLocalProjectileClimbable(Projectile source, RaycastHit hit)
		{
			if (_capturedPitons.Count == 0)
			{
				return;
			}
			if (!MPCore.IsReady || ApplyingRemoteState || (Object)(object)source == (Object)null || !IsLocalProjectile(source))
			{
				_capturedPitons.Clear();
				return;
			}
			foreach (GameObject capturedPiton in _capturedPitons)
			{
				GameObject climbableRoot = GetClimbableRoot(capturedPiton);
				if (!((Object)(object)climbableRoot == (Object)null))
				{
					RegisterLocalClimbable(climbableRoot);
				}
			}
			_capturedPitons.Clear();
		}

		public void OnLocalHandholdGrabbed(NetworkedClimable identity)
		{
			if ((Object)(object)identity == (Object)null || _localHandhold.ContainsKey(identity.NetworkId))
			{
				return;
			}
			for (int i = 0; i < _holdingList.Count; i++)
			{
				if ((Object)(object)_holdingList[i].Identity == (Object)(object)identity)
				{
					return;
				}
			}
			_holdingList.Add((identity, Time.time));
		}

		public void OnLocalHandholdReleased(NetworkedClimable identity)
		{
			if ((Object)(object)identity == (Object)null || _localHandhold.ContainsKey(identity.NetworkId))
			{
				return;
			}
			for (int num = _holdingList.Count - 1; num >= 0; num--)
			{
				if ((Object)(object)_holdingList[num].Identity == (Object)(object)identity)
				{
					List<Hand> obj = _handsField.Invoke(identity.Handhold);
					if (obj != null && obj.Count == 0)
					{
						float weakenTime = Time.time - _holdingList[num].LastTime;
						SendWeaken(identity, weakenTime);
						_holdingList.RemoveAt(num);
					}
					break;
				}
			}
		}

		public static void CreateBreakObject(GameObject gameObject, CL_Handhold handhold)
		{
			if (TryGetNetworkIdentity(handhold, out NetworkedClimable identity) && identity.IsValid)
			{
				Singleton<ClimbableSyncModule>.Instance?._globalPersistentTable.Remove(identity.NetworkId);
			}
			Singleton<ClimbableSyncModule>.Instance?.SendBreakRequest(gameObject, handhold);
		}

		public void OnSyncUpdate(float deltaTime)
		{
			if (!MPCore.CanSync || !IsEnabled)
			{
				ResetSweepState();
				return;
			}
			if (!_isSweeping)
			{
				_timer += deltaTime;
				if (_timer >= 0.1f)
				{
					_timer = Mathf.Max(0f, _timer - 0.1f);
					StartNewSweep();
					HoldWeaken();
				}
			}
			if (_isSweeping)
			{
				FlushNextBatch();
			}
		}

		private void StartNewSweep()
		{
			_sweepQueue.Clear();
			_sweepIndex = 0;
			foreach (NetworkedClimable value in _localHandhold.Values)
			{
				if ((Object)(object)value == (Object)null || (Object)(object)((Component)value).gameObject == (Object)null || !((Component)value).gameObject.activeInHierarchy)
				{
					_pendingRemoveKeys.Add(((Object)(object)value != (Object)null) ? value.NetworkId : 0);
				}
				else if (value.HasMeaningfulChange())
				{
					_sweepQueue.Add(value);
				}
			}
			for (int i = 0; i < _pendingRemoveKeys.Count; i++)
			{
				if (_pendingRemoveKeys[i] != 0)
				{
					BroadcastRemove(_pendingRemoveKeys[i]);
				}
			}
			_pendingRemoveKeys.Clear();
			if (_sweepQueue.Count > 0)
			{
				_isSweeping = true;
			}
		}

		private void FlushNextBatch()
		{
			_batchBuffer.Clear();
			while (_sweepIndex < _sweepQueue.Count && _batchBuffer.Count < _maxSyncPerFrame)
			{
				NetworkedClimable networkedClimable = _sweepQueue[_sweepIndex];
				_sweepIndex++;
				if ((Object)(object)networkedClimable != (Object)null && (Object)(object)((Component)networkedClimable).gameObject != (Object)null && ((Component)networkedClimable).gameObject.activeInHierarchy)
				{
					_batchBuffer.Add(networkedClimable);
				}
			}
			if (_batchBuffer.Count > 0)
			{
				BroadcastUpdate(_batchBuffer);
			}
			if (_sweepIndex >= _sweepQueue.Count)
			{
				_isSweeping = false;
				_sweepQueue.Clear();
			}
		}

		private void HoldWeaken()
		{
			float time = Time.time;
			for (int num = _holdingList.Count - 1; num >= 0; num--)
			{
				var (networkedClimable, num2) = _holdingList[num];
				if (!((Object)(object)networkedClimable == (Object)null) && !((Object)(object)networkedClimable.Handhold == (Object)null))
				{
					List<Hand> obj = _handsField.Invoke(networkedClimable.Handhold);
					if (obj == null || obj.Count != 0)
					{
						float weakenTime = time - num2;
						_holdingList[num] = (networkedClimable, time);
						SendWeaken(networkedClimable, weakenTime);
						continue;
					}
				}
				_holdingList.RemoveAt(num);
			}
		}

		private IEnumerator SendCreateChunksRoutine(ulong clientId)
		{
			List<ClimbableData> itemsToSend = new List<ClimbableData>();
			foreach (KeyValuePair<ulong, NetworkedClimable> kvp in _handhold)
			{
				if ((Object)(object)kvp.Value != (Object)null && kvp.Value.IsValid)
				{
					itemsToSend.Add(kvp.Value.data);
				}
			}
			int index = 0;
			while (index < itemsToSend.Count)
			{
				int count = Mathf.Min(10, itemsToSend.Count - index);
				DataWriter writer = MPWriterPool.GetWriter(MPSteamworks.UserSteamId, clientId, PacketType.PitonStateSync);
				writer.Put((byte)8);
				writer.Put((ushort)count);
				for (int i = 0; i < count; i++)
				{
					writer.Put<ClimbableData>(itemsToSend[index + i]);
				}
				MonoSingleton<MPSteamworks>.Instance.SendToPeer(SteamId.op_Implicit(clientId), writer, (SendType)8, 0);
				index += count;
				yield return null;
			}
			_sendRoutines.Remove(clientId);
		}

		private void RegisterLocalClimbable(GameObject root)
		{
			string text = MPUtil.CleanCloneName(((Object)root).name);
			if (!((Object)(object)root == (Object)null) && !string.IsNullOrEmpty(text))
			{
				NetworkedClimable orCreateIdentity = GetOrCreateIdentity(root);
				if (!orCreateIdentity.IsValid)
				{
					orCreateIdentity.data.networkId = MPUtil.Hash64($"{MPSteamworks.UserSteamId}:{_nextLocalId++}".AsSpan());
					orCreateIdentity.data.ownerId = MPSteamworks.UserSteamId;
					orCreateIdentity.data.prefabKey = text;
					orCreateIdentity.RememberState();
				}
				_handhold[orCreateIdentity.NetworkId] = orCreateIdentity;
				_localHandhold[orCreateIdentity.NetworkId] = orCreateIdentity;
				_globalPersistentTable[orCreateIdentity.NetworkId] = orCreateIdentity.data;
				BroadcastCreate(orCreateIdentity);
			}
		}

		private GameObject GetClimbableRoot(GameObject obj)
		{
			if ((Object)(object)obj == (Object)null)
			{
				return null;
			}
			Transform val = (WorldLoader.initialized ? WorldLoader.GetCurrentLevelParentRoot() : null);
			Transform val2 = obj.transform;
			while ((Object)(object)val2.parent != (Object)null && (Object)(object)val2.parent != (Object)(object)val)
			{
				val2 = val2.parent;
			}
			return ((Component)val2).gameObject;
		}

		private void CreateNetworkClimbable(ClimbableData data)
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			if (_handhold.TryGetValue(data.networkId, out NetworkedClimable value) && (Object)(object)value != (Object)null)
			{
				value.BindData(data);
				return;
			}
			GameObject handholdPrefab = MPAssetManager.GetHandholdPrefab(data.prefabKey);
			if ((Object)(object)handholdPrefab == (Object)null)
			{
				MPMain.LogError($"[MP ClimbableSync] Could not resolve prefab '{data.prefabKey}' for {data.networkId}.");
				return;
			}
			GameObject val = Object.Instantiate<GameObject>(handholdPrefab, data.position, data.rotation);
			TryAddPlacedObjectToLevel(val);
			NetworkedClimable orCreateIdentity = GetOrCreateIdentity(val);
			if (!orCreateIdentity.IsValid)
			{
				orCreateIdentity.data = data;
			}
			_handhold[data.networkId] = orCreateIdentity;
			_globalPersistentTable[data.networkId] = data;
		}

		private IEnumerator RebuildClimbable()
		{
			yield return null;
			yield return (object)new WaitUntil((Func<bool>)(() => WorldLoader.isLoaded || (Object)(object)WorldLoader.instance == (Object)null));
			yield return null;
			foreach (var (_, data) in _globalPersistentTable)
			{
				if (_handhold.TryGetValue(data.networkId, out NetworkedClimable existing) && (Object)(object)existing != (Object)null)
				{
					existing.BindData(data);
					continue;
				}
				GameObject prefab = MPAssetManager.GetHandholdPrefab(data.prefabKey);
				if ((Object)(object)prefab == (Object)null)
				{
					MPMain.LogError($"[MP ClimbableSync] Could not resolve prefab '{data.prefabKey}' for {data.networkId}.");
					continue;
				}
				GameObject climbableObject = Object.Instantiate<GameObject>(prefab, data.position, data.rotation);
				TryAddPlacedObjectToLevel(climbableObject);
				NetworkedClimable identity = GetOrCreateIdentity(climbableObject);
				if (!identity.IsValid)
				{
					identity.data = data;
				}
				_handhold[data.networkId] = identity;
				existing = null;
			}
		}

		public static void RegisterLookup(CL_Handhold handhold, NetworkedClimable identity)
		{
			if ((Object)(object)handhold != (Object)null && (Object)(object)identity != (Object)null)
			{
				_handholdLookup[handhold] = identity;
			}
		}

		public static void UnregisterLookup(CL_Handhold handhold)
		{
			if ((Object)(object)handhold != (Object)null)
			{
				_handholdLookup.Remove(handhold);
			}
		}

		public static bool TryGetNetworkIdentity(CL_Handhold handhold, out NetworkedClimable identity)
		{
			return _handholdLookup.TryGetValue(handhold, out identity);
		}

		public void BroadcastCreate(NetworkedClimable identity)
		{
			if (MPCore.CanSync && !((Object)(object)identity == (Object)null) && identity.IsValid)
			{
				ClimbableData data = identity.data;
				DataWriter writer = MPWriterPool.GetWriter(MPSteamworks.UserSteamId, 0uL, PacketType.PitonStateSync);
				writer.Put((byte)0);
				writer.Put<ClimbableData>(data);
				MonoSingleton<MPSteamworks>.Instance.Broadcast(writer, (SendType)8, 0);
			}
		}

		public void BroadcastUpdate(List<NetworkedClimable> batch)
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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)
			if (!IsEnabled || batch == null || batch.Count == 0)
			{
				return;
			}
			DataWriter writer = MPWriterPool.GetWriter(MPSteamworks.UserSteamId, 0uL, PacketType.PitonStateSync);
			writer.Put((byte)1);
			writer.Put((byte)batch.Count);
			for (int i = 0; i < batch.Count; i++)
			{
				NetworkedClimable networkedClimable = batch[i];
				networkedClimable.RememberState();
				if (_globalPersistentTable.TryGetValue(networkedClimable.NetworkId, out ClimbableData value))
				{
					value.BindData(((Component)networkedClimable).transform.position, ((Component)networkedClimable).transform.rotation, networkedClimable.data.secureAmount, networkedClimable.data.secure);
				}
				writer.Put(networkedClimable.NetworkId);
				writer.Put(((Component)networkedClimable).transform.position);
				writer.Put(((Component)networkedClimable).transform.rotation);
				writer.Put(networkedClimable.data.secureAmount);
				writer.Put(networkedClimable.data.secure);
			}
			MonoSingleton<MPSteamworks>.Instance.Broadcast(writer, (SendType)1, 0);
		}

		public void BroadcastRemove(ulong networkId)
		{
			DataWriter writer = MPWriterPool.GetWriter(MPSteamworks.UserSteamId, 0uL, PacketType.PitonStateSync);
			writer.Put((byte)2);
			writer.Put(networkId);
			MonoSingleton<MPSteamworks>.Instance.Broadcast(writer, (SendType)8, 0);
			_handhold.Remove(networkId);
			_localHandhold.Remove(networkId);
		}

		public void SendBreakRequest(GameObject gameObject, CL_Handhold handhold)
		{
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			if (!MPCore.CanSync || ApplyingRemoteState || (Object)(object)handhold == (Object)null || (Object)(object)gameObject == (Object)null || !TryGetNetworkIdentity(handhold, out NetworkedClimable identity) || !identity.IsValid)
			{
				return;
			}
			if (!_localHandhold.ContainsKey(identity.NetworkId) && identity.data.ownerId != MPSteamworks.UserSteamId)
			{
				Item_Object val = default(Item_Object);
				if (gameObject.TryGetComponent<Item_Object>(ref val))
				{
					_breakItemObject.Add((identity.NetworkId, gameObject));
				}
				DataWriter writer = MPWriterPool.GetWriter(MPSteamworks.UserSteamId, identity.data.ownerId, PacketType.PitonStateSync);
				writer.Put((byte)5);
				writer.Put(identity.NetworkId);
				MonoSingleton<MPSteamworks>.Instance.SendToPeer(SteamId.op_Implicit(identity.data.ownerId), writer, (SendType)8, 0);
			}
			else
			{
				Item_Object itemObject = default(Item_Object);
				if (gameObject.TryGetComponent<Item_Object>(ref itemObject))
				{
					Singleton<DroppedItemModule>.Instance.SyncAndBroadcast(itemObject);
				}
				BroadcastBreak(identity);
			}
		}

		public void BroadcastBreak(NetworkedClimable identity)
		{
			DataWriter writer = MPWriterPool.GetWriter(MPSteamworks.UserSteamId, 0uL, PacketType.PitonStateSync);
			writer.Put((byte)6);
			writer.Put(identity.NetworkId);
			MonoSingleton<MPSteamworks>.Instance.Broadcast(writer, (SendType)8, 0);
			_handhold.Remove(identity.NetworkId);
			_localHandhold.Remove(identity.NetworkId);
			_globalPersistentTable.Remove(identity.NetworkId);
		}

		public void BroadcastHammerIn(CL_Handhold handhold, float amount)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			if (TryGetNetworkIdentity(handhold, out NetworkedClimable identity) && identity.IsValid)
			{
				if (_globalPersistentTable.TryGetValue(identity.NetworkId, out ClimbableData value) && value != null)
				{
					value.position = ((Component)handhold).transform.position;
					value.rotation = ((Component)handhold).transform.rotation;
					value.secureAmount = identity.Handhold.secureAmount;
					value.secure = identity.Handhold.secure;
				}
				if (MPCore.CanSync && !ApplyingRemoteState && !((Object)(object)handhold == (Object)null) && !_localHandhold.ContainsKey(identity.NetworkId))
				{
					DataWriter writer = MPWriterPool.GetWriter(MPSteamworks.UserSteamId, identity.data.ownerId, PacketType.PitonStateSync);
					writer.Put((byte)3);
					writer.Put(identity.NetworkId);
					writer.Put(amount);
					MonoSingleton<MPSteamworks>.Instance.SendToPeer(SteamId.op_Implicit(identity.data.ownerId), writer, (SendType)8, 0);
				}
			}
		}

		public void SendChunkRequest()
		{
			if (!MPSteamworks.IsHost && IsEnabled)
			{
				DataWriter writer = MPWriterPool.GetWriter(MPSteamworks.UserSteamId, MonoSingleton<MPSteamworks>.Instance.HostSteamId, PacketType.PitonStateSync);
				writer.Put((byte)7);
				MonoSingleton<MPSteamworks>.Instance.SendToHost(writer, (SendType)8, 0);
			}
		}

		public void SendWeaken(NetworkedClimable identity, float weakenTime)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			if (identity.data.ownerId != MPSteamworks.UserSteamId)
			{
				DataWriter writer = MPWriterPool.GetWriter(MPSteamworks.UserSteamId, identity.data.ownerId, PacketType.PitonStateSync);
				writer.Put((byte)4);
				writer.Put(identity.NetworkId);
				writer.Put(weakenTime);
				MonoSingleton<MPSteamworks>.Instance.SendToPeer(SteamId.op_Implicit(identity.data.ownerId), writer, (SendType)8, 0);
			}
		}

		public void HandleCreate(ulong senderId, DataReader reader)
		{
			ClimbableData data = reader.Get<ClimbableData>();
			CreateNetworkClimbable(data);
		}

		public void HandleUpdate(DataReader reader)
		{
			//IL_0021: 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)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			byte b = reader.GetByte();
			ApplyingRemoteState = true;
			try
			{
				for (int i = 0; i < b; i++)
				{
					ulong uLong = reader.GetULong();
					Vector3 vector = reader.GetVector3();
					Quaternion quaternion = reader.GetQuaternion();
					float secureAmount = reader.GetFloat();
					bool secure = reader.GetBool();
					if (_handhold.TryGetValue(uLong, out NetworkedClimable value) && (Object)(object)value != (Object)null)
					{
						ApplyState(value, vector, quaternion, secureAmount, secure);
					}
					if (_globalPersistentTable.TryGetValue(uLong, out ClimbableData value2))
					{
						value2?.BindData(vector, quaternion, secureAmount, secure);
					}
				}
			}
			finally
			{
				ApplyingRemoteState = false;
			}
		}

		public void HandleRemove(DataReader reader)
		{
			ulong uLong = reader.GetULong();
			if (_handhold.TryGetValue(uLong, out NetworkedClimable _))
			{
				_handhold.Remove(uLong);
			}
		}

		public void HandlePitonHammerIn(DataReader reader)
		{
			ulong uLong = reader.GetULong();
			float num = reader.GetFloat();
			if (!_localHandhold.TryGetValue(uLong, out NetworkedClimable value) || (Object)(object)value == (Object)null)
			{
				return;
			}
			ApplyingRemoteState = true;
			try
			{
				value.Handhold.HammerIn(num);
				value.data.secureAmount = value.Handhold.secureAmount;
				value.data.secure = value.Handhold.secure;
				if (_globalPersistentTable.TryGetValue(uLong, out ClimbableData value2) && value2 != null)
				{
					value2.secureAmount = value.Handhold.secureAmount;
					value2.secure = value.Handhold.secure;
				}
			}
			finally
			{
				ApplyingRemoteState = false;
			}
		}

		public void HandlePitonBreak(DataReader reader)
		{
			ulong uLong = reader.GetULong();
			for (int i = 0; i < _breakItemObject.Count; i++)
			{
				if (_breakItemObject[i].id == uLong)
				{
					Object.Destroy((Object)(object)_breakItemObject[i].obj);
					_breakItemObject.RemoveAt(i);
					i--;
				}
			}
			if (!_handhold.TryGetValue(uLong, out NetworkedClimable value) || (Object)(object)value == (Object)null)
			{
				return;
			}
			if ((Object)(object)((Component)value).gameObject != (Object)null)
			{
				List<Hand> list = _handsField.Invoke(value.Handhold);
				while (list != null && list.Count > 0)
				{
					list[0].DropHand(false);
				}
				Object.Destroy((Object)(object)((Component)value).gameObject);
			}
			_handhold.Remove(uLong);
			_localHandhold.Remove(uLong);
			_globalPersistentTable.Remove(uLong);
		}

		public void HandlePitonBreakRequest(DataReader reader)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			ulong uLong = reader.GetULong();
			if (!_localHandhold.TryGetValue(uLong, out NetworkedClimable value) || (Object)(object)value == (Object)null)
			{
				return;
			}
			if ((Object)(object)((Component)value).gameObject != (Object)null && (Object)(object)value.Handhold != (Object)null)
			{
				CL_Handhold handhold = value.Handhold;
				List<Hand> list = _handsField.Invoke(handhold);
				while (list != null && list.Count > 0)
				{
					list[0].DropHand(false);
				}
				GameObject val = Object.Instantiate<GameObject>(handhold.breakObject, ((Component)handhold).transform.position, ((Component)handhold).transform.rotation);
				Item_Object itemObject = default(Item_Object);
				if (val.TryGetComponent<Item_Object>(ref itemObject))
				{
					Singleton<DroppedItemModule>.Instance.SyncAndBroadcast(itemObject);
				}
				BroadcastBreak(value);
				Object.Destroy((Object)(object)((Component)value).gameObject);
			}
			_handhold.Remove(uLong);
			_localHandhold.Remove(uLong);
			_globalPersistentTable.Remove(uLong);
		}

		public void HandleCreateChunk(DataReader reader)
		{
			ushort uShort = reader.GetUShort();
			for (int i = 0; i < uShort; i++)
			{
				ClimbableData data = reader.Get<ClimbableData>();
				CreateNetworkClimbable(data);
			}
		}

		public void HandleChunkRequest(ulong senderId)
		{
			if (MPCore.CanSync && MPSteamworks.IsHost && !((Object)(object)MonoSingleton<WorldSyncManager>.Instance == (Object)null) && senderId != 0L && senderId != MPSteamworks.UserSteamId)
			{
				if (_sendRoutines.TryGetValue(senderId, out Coroutine value) && value != null)
				{
					((MonoBehaviour)MonoSingleton<WorldSyncManager>.Instance).StopCoroutine(value);
				}
				_sendRoutines[senderId] = ((MonoBehaviour)MonoSingleton<WorldSyncManager>.Instance).StartCoroutine(SendCreateChunksRoutine(senderId));
			}
		}

		public void HandleWeaken(DataReader reader)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_00c4: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			ulong uLong = reader.GetULong();
			float num = reader.GetFloat();
			if (!_localHandhold.TryGetValue(uLong, out NetworkedClimable value) || (Object)(object)value == (Object)null)
			{
				return;
			}
			CL_Handhold handhold = value.Handhold;
			if ((Object)(object)handhold == (Object)null || handhold.secure)
			{
				return;
			}
			ApplyingRemoteState = true;
			try
			{
				handhold.secureAmount -= num * 0.115f;
				float num2 = num * 0.05f;
				Vector3 val = ((Component)handhold).transform.forward * num2;
				UT_SoftParent val2 = _softParentField.Invoke(handhold);
				if ((Object)(object)val2 != (Object)null)
				{
					val2.SoftMove(val);
				}
				else
				{
					Transform transform = ((Component)handhold).transform;
					transform.position += val;
				}
				_offsetAmountField.Invoke(handhold) += num2;
				value.data.secureAmount = handhold.secureAmount;
				value.data.position = ((Component)handhold).transform.position;
				if (_globalPersistentTable.TryGetValue(uLong, out ClimbableData value2) && value2 != null)
				{
					value2.secureAmount = handhold.secureAmount;
					value2.position = ((Component)handhold).transform.position;
				}
				if (handhold.secureAmount < 0f)
				{
					List<Hand> list = _handsField.Invoke(handhold);
					while (list != null && list.Count > 0)
					{
						list[0].DropHand(false);
					}
					GameObject val3 = Object.Instantiate<GameObject>(handhold.breakObject, ((Component)handhold).transform.position, ((Component)handhold).transform.rotation);
					_handhold.Remove(uLong);
					_localHandhold.Remove(uLong);
					_globalPersistentTable.Remove(uLong);
					Object.Destroy((Object)(object)((Component)handhold).gameObject);
				}
			}
			finally
			{
				ApplyingRemoteState = false;
			}
		}

		public void HandlePitonState(ulong senderId, DataReader reader)
		{
			switch ((PitonSyncAction)reader.GetByte())
			{
			case PitonSyncAction.Create:
				HandleCreate(senderId, reader);
				break;
			case PitonSyncAction.Update:
				HandleUpdate(reader);
				break;
			case PitonSyncAction.Remove:
				HandleRemove(reader);
				break;
			case PitonSyncAction.HammerIn:
				HandlePitonHammerIn(reader);
				break;
			case PitonSyncAction.Weaken:
				HandleWeaken(reader);
				break;
			case PitonSyncAction.BreakRequest:
				HandlePitonBreakRequest(reader);
				break;
			case PitonSyncAction.Break:
				HandlePitonBreak(reader);
				break;
			case PitonSyncAction.CreateChunkRequest:
				HandleChunkRequest(senderId);
				break;
			case PitonSyncAction.CreateChunk:
				HandleCreateChunk(reader);
				break;
			}
		}

		private void ApplyState(NetworkedClimable identity, Vector3 position, Quaternion rotation, float secureAmount, bool secure)
		{
			//IL_0007: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			((Component)identity).transform.SetPositionAndRotation(position, rotation);
			CL_Handhold handhold = identity.Handhold;
			if ((Object)(object)handhold != (Object)null)
			{
				handhold.Initialize();
				handhold.secureAmount = secureAmount;
				handhold.secure = secure;
			}
			identity.data.BindData(position, rotation, secureAmount, secure);
		}

		private bool IsLocalProjectile(Projectile projectile)
		{
			ENT_Player player = ENT_Player.GetPlayer();
			if ((Object)(object)projectile == (Object)null || (Object)(object)player == (Object)null)
			{
				return false;
			}
			GameEntity val = _sourceEntityField.Invoke(projectile);
			return (Object)(object)val == (Object)(object)player;
		}

		private void TryAddPlacedObjectToLevel(GameObject climbableObject)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (!WorldLoader.initialized || (Object)(object)climbableObject == (Object)null)
			{
				return;
			}
			try
			{
				M_Level level = WorldLoader.GetClosestLevelToPosition(climbableObject.transform.position).GetLevel();
				if ((Object)(object)level != (Object)null)
				{
					climbableObject.transform.SetParent(level.GetParentRoot());
					_addPlacedObjectMethod(level, climbableObject);
				}
			}
			catch (Exception ex)
			{
				MPMain.LogWarning("[MP ClimbableSync] Could not register remote climbable as placed object: " + ex.Message);
			}
		}

		private NetworkedClimable GetOrCreateIdentity(GameObject obj)
		{
			return obj.GetComponent<NetworkedClimable>() ?? obj.AddComponent<NetworkedClimable>();
		}
	}
	public enum EnemySyncAction : byte
	{
		StateBatch = 1,
		Damage = 2,
		Kill = 3,
		KillChunkRequest = 5,
		KillChunk = 6,
		Create = 7
	}
	public class EnemySyncModule : Singleton<EnemySyncModule>, ISyncModule
	{
		private readonly Dictionary<ulong, string> _diedEntities = new Dictionary<ulong, string>();

		private readonly Dictionary<ulong, Coroutine> _diedEntityRoutines = new Dictionary<ulong, Coroutine>();

		private const int ChunkItemsPerFrame = 10;

		private readonly Dictionary<ulong, NetworkedEnemy> _enemies = new Dictionary<ulong, NetworkedEnemy>();

		private readonly Dictionary<int, NetworkedEnemy> _byInstanceId = new Dictionary<int, NetworkedEnemy>();

		private float _syncInterval = 0.2f;

		private int _maxSyncPerFrame = 10;

		private float _timer = 0f;

		private bool _isSweeping = false;

		private int _sweepIndex = 0;

		private readonly List<NetworkedEnemy> _sweepQueue = new List<NetworkedEnemy>();

		private readonly List<NetworkedEnemy> _batchBuffer;

		private readonly List<ulong> _localKeysCache = new List<ulong>();

		public string ModuleName => "EnemySync";

		public bool IsEnabled { get; set; }

		public bool ApplyingRemoteState { get; private set; }

		public void OnResetMap()
		{
			ResetState();
		}

		public void OnLeave()
		{
			_diedEntities.Clear();
			if ((Object)(object)MonoSingleton<WorldSyncManager>.Instance != (Object)null)
			{
				foreach (Coroutine value in _diedEntityRoutines.Values)
				{
					if (value != null)
					{
						((MonoBehaviour)MonoSingleton<WorldSyncManager>.Instance).StopCoroutine(value);
					}
				}
			}
			_diedEntityRoutines.Clear();
			ResetState();
		}

		public void OnEnd()
		{
			OnLeave();
		}

		private void ResetSweepState()
		{
			_timer = 0f;
			_isSweeping = false;
			_sweepIndex = 0;
			_sweepQueue.Clear();
			_batchBuffer.Clear();
			_localKeysCache.Clear();
		}

		private EnemySyncModule()
		{
			IsEnabled = MPConfig.EnemySync;
			_syncInterval = Mathf.Max(0.016f, 1f / ((MPConfig.EnemySendFrequency > 0) ? ((float)MPConfig.EnemySendFrequency) : 5f));
			_maxSyncPerFrame = MPConfig.MaxEnemySendCount;
			_batchBuffer = new List<NetworkedEnemy>(_maxSyncPerFrame);
		}

		public void ResetState()
		{
			ResetSweepState();
			_enemies.Clear();
			_byInstanceId.Clear();
			ApplyingRemoteState = false;
		}

		public void OnEntityEnabled(GameEntity entity)
		{
			if (!((Object)(object)entity == (Object)null) && MPCore.IsReady && IsSyncableEnemy(entity))
			{
				EnsureIdentity(entity);
			}
		}

		public void OnEntityDisabled(GameEntity entity)
		{
			if (!((Object)(object)entity == (Object)null) && !ApplyingRemoteState)
			{
				int instanceID = ((Object)entity).GetInstanceID();
				if (_byInstanceId.TryGetValue(instanceID, out NetworkedEnemy value))
				{
					RemoveEnemyRecord(value);
				}
			}
		}

		public void OnEntityKill(GameEntity entity, string type)
		{
			if (!((Object)(object)entity == (Object)null))
			{
				NetworkedEnemy networkedEnemy = default(NetworkedEnemy);
				if (((Component)entity).TryGetComponent<NetworkedEnemy>(ref networkedEnemy) && !_diedEntities.ContainsKey(networkedEnemy.networkId) && MPSteamworks.IsHost)
				{
					_diedEntities[networkedEnemy.networkId] = type;
					BroadcastKill(networkedEnemy, type);
				}
				int instanceID = ((Object)entity).GetInstanceID();
				if (_byInstanceId.TryGetValue(instanceID, out NetworkedEnemy value))
				{
					RemoveEnemyRecord(value);
				}
			}
		}

		public void HandleEnemyState(ulong senderId, DataReader reader)
		{
			EnemySyncAction enemySyncAction = (EnemySyncAction)reader.GetByte();
			try
			{
				switch (enemySyncAction)
				{
				case EnemySyncAction.StateBatch:
					HandleState(reader);
					break;
				case EnemySyncAction.Damage:
					HandleDamage(reader);
					break;
				case EnemySyncAction.Kill:
					HandleKill(reader);
					break;
				case EnemySyncAction.KillChunkRequest:
					HandleChunkRequest(senderId);
					break;
				case EnemySyncAction.KillChunk:
					HandleChunk(reader);
					break;
				default:
					MPMain.LogWarning($"[MP EnemySync] Unknown action: {enemySyncAction}");
					break;
				}
			}
			catch (Exception ex)
			{
				MPMain.LogError($"[MP EnemySync] Failed to apply {enemySyncAction}: {ex.Message}");
			}
		}

		public void OnSyncUpdate(float deltaTime)
		{
			if (!MPSteamworks.IsHost || !MPCore.CanSync || !IsEnabled)
			{
				ResetSweepState();
				return;
			}
			if (!_isSweeping)
			{
				_timer += deltaTime;
				if (_timer >= _syncInterval)
				{
					_timer = Mathf.Max(0f, _timer - _syncInterval);
					StartNewSweep();
				}
			}
			if (_isSweeping)
			{
				FlushNextBatch();
			}
		}

		private void StartNewSweep()
		{
			_sweepQueue.Clear();
			_sweepIndex = 0;
			_localKeysCache.Clear();
			foreach (ulong key2 in _enemies.Keys)
			{
				_localKeysCache.Add(key2);
			}
			for (int i = 0; i < _localKeysCache.Count; i++)
			{
				ulong key = _localKeysCache[i];
				if (_enemies.TryGetValue(key, out NetworkedEnemy value))
				{
					if (value.IsRemoved())
					{
						RemoveEnemyRecord(value);
					}
					else if (value.HasMeaningfulChange())
					{
						_sweepQueue.Add(value);
					}
				}
			}
			if (_sweepQueue.Count > 0)
			{
				_isSweeping = true;
			}
		}

		private void FlushNextBatch()
		{
			_batchBuffer.Clear();
			while (_sweepIndex < _sweepQueue.Count && _batchBuffer.Count < _maxSyncPerFrame)
			{
				NetworkedEnemy networkedEnemy = _sweepQueue[_sweepIndex];
				_sweepIndex++;
				if ((Object)(object)networkedEnemy != (Object)null && (Object)(object)((Component)networkedEnemy).gameObject != (Object)null && ((Component)networkedEnemy).gameObject.activeInHierarchy)
				{
					_batchBuffer.Add(networkedEnemy);
				}
			}
			if (_batchBuffer.Count > 0)
			{
				BroadcastStateBatch(_batchBuffer);
			}
			if (_sweepIndex >= _sweepQueue.Count)
			{
				_isSweeping = false;
				_sweepQueue.Clear();
			}
		}

		private IEnumerator SendDiedEnemiesChunksRoutine(ulong clientId)
		{
			List<KeyValuePair<ulong, string>> list = new List<KeyValuePair<ulong, string>>(_diedEntities);
			int total = list.Count;
			int currentIndex = 0;
			while (currentIndex < total)
			{
				int countToSend = Mathf.Min(10, total - currentIndex);
				DataWriter writer = MPWriterPool.GetWriter(MPSteamworks.UserSteamId, clientId, PacketType.EnemyStateSync);
				writer.Put((byte)6);
				writer.Put(countToSend);
				for (int i = 0; i < countToSend; i++)
				{
					KeyValuePair<ulong, string> item = list[currentIndex + i];
					writer.Put(item.Key);
					writer.Put(item.Value ?? string.Empty);
				}
				MonoSingleton<MPSteamworks>.Instance.SendToPeer(SteamId.op_Implicit(clientId), writer, (SendType)8, 0);
				currentIndex += countToSend;
				yield return null;
			}
			_diedEntityRoutines.Remove(clientId);
		}

		private NetworkedEnemy EnsureIdentity(GameEntity entity)
		{
			Transform transform = ((Component)entity).transform;
			if ((Object)(object)transform == (Object)null)
			{
				return null;
			}
			int instanceID = ((Object)transform).GetInstanceID();
			if (_byInstanceId.TryGetValue(instanceID, out NetworkedEnemy value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			NetworkedEnemy networkedEnemy = ((Component)transform).GetComponent<NetworkedEnemy>() ?? ComponentHolderProtocol.AddComponent<NetworkedEnemy>((Object)(object)transform);
			if (networkedEnemy.networkId == 0)
			{
				networkedEnemy.networkId = BuildStableNetworkId(transform);
			}
			if (_diedEntities.TryGetValue(networkedEnemy.networkId, out string value2))
			{
				if (string.IsNullOrEmpty(value2))
				{
					entity.Kill("diedSync");
				}
				else
				{
					entity.Kill(value2);
				}
				entity.health = 0f;
				return networkedEnemy;
			}
			_enemies[networkedEnemy.networkId] = networkedEnemy;
			_byInstanceId[instanceID] = networkedEnemy;
			return networkedEnemy;
		}

		private void RemoveEnemyRecord(NetworkedEnemy identity)
		{
			if (!((Object)(object)identity == (Object)null))
			{
				if (identity.networkId != 0)
				{
					_enemies.Remove(identity.networkId);
				}
				int instanceID = ((Object)((Component)identity).transform).GetInstanceID();
				_byInstanceId.Remove(instanceID);
			}
		}

		private ulong BuildStableNetworkId(Transform transform)
		{
			return MPUtil.Hash64(MPUtil.BuildTransformPath(transform).AsSpan());
		}

		public void BroadcastEnemyDamage(GameEntity entity, DamageInfo info)
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			if (MPCore.CanSync && IsEnabled && !ApplyingRemoteState && info != null && IsSyncableEnemy(entity))
			{
				NetworkedEnemy networkedEnemy = EnsureIdentity(entity);
				if (!((Object)(object)networkedEnemy == (Object)null) && networkedEnemy.networkId != 0)
				{
					DataWriter writer = MPWriterPool.GetWriter(MPSteamworks.UserSteamId, 0uL, PacketType.EnemyStateSync);
					writer.Put((byte)2);
					writer.Put(networkedEnemy.networkId);
					writer.Put(info.amount);
					writer.Put(info.type);
					writer.Put((IReadOnlyList<string>)info.tags);
					writer.Put(info.position);
					MonoSingleton<MPSteamworks>.Instance.Broadcast(writer, (SendType)8, 0);
				}
			}
		}

		private void BroadcastStateBatch(List<NetworkedEnemy> batch)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			if (IsEnabled && batch != null && batch.Count != 0)
			{
				DataWriter writer = MPWriterPool.GetWriter(MPSteamworks.UserSteamId, 0uL, PacketType.EnemyStateSync);
				writer.Put((byte)1);
				writer.Put((byte)batch.Count);
				for (int i = 0; i < batch.Count; i++)
				{
					NetworkedEnemy networkedEnemy = batch[i];
					writer.Put(networkedEnemy.networkId);
					writer.Put(((Component)networkedEnemy).transform.position);
					writer.Put(((Component)networkedEnemy).transform.rotation);
					writer.Put(networkedEnemy.currentHealth);
					networkedEnemy.RememberState();
				}
				MonoSingleton<MPSteamworks>.Instance.Broadcast(writer, (SendType)1, 0);
			}
		}

		private void BroadcastKill(NetworkedEnemy identity, string type)
		{
			if (MPCore.CanSync && IsEnabled)
			{
				DataWriter writer = MPWriterPool.GetWriter(MPSteamworks.UserSteamId, 0uL, PacketType.EnemyStateSync);
				writer.Put((byte)3);
				writer.Put(identity.networkId);
				writer.Put(type);
				MonoSingleton<MPSteamworks>.Instance.Broadcast(writer, (SendType)8, 0);
			}
		}

		private void SendKillChunkRequest()
		{
			if (!MPSteamworks.IsHost && IsEnabled)
			{
				DataWriter writer = MPWriterPool.GetWriter(MPSteamworks.UserSteamId, MonoSingleton<MPSteamworks>.Instance.HostSteamId, PacketType.EnemyStateSync);
				writer.Put((byte)5);
				MonoSingleton<MPSteamworks>.Instance.SendToHost(writer, (SendType)8, 0);
			}
		}

		private void HandleDamage(DataReader reader)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			ulong uLong = reader.GetULong();
			float num = reader.GetFloat();
			string text = reader.GetString();
			List<string> stringList = reader.GetStringList();
			Vector3 vector = reader.GetVector3();
			if (!_enemies.TryGetValue(uLong, out NetworkedEnemy value) || (Object)(object)value == (Object)null)
			{
				return;
			}
			GameEntity component = ((Component)value).GetComponent<GameEntity>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			DamageInfo val = DamageInfo.CreateDamageInfo(num, text, stringList, (GameEntity)null);
			val.position = vector;
			ApplyingRemoteState = true;
			try
			{
				component.Damage(val);
			}
			finally
			{
				ApplyingRemoteState = false;
			}
		}

		private void HandleState(DataReader reader)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			if (MPSteamworks.IsHost)
			{
				return;
			}
			byte b = reader.GetByte();
			ApplyingRemoteState = true;
			try
			{
				for (int i = 0; i < b; i++)
				{
					ulong uLong = reader.GetULong();
					Vector3 vector = reader.GetVector3();
					Quaternion quaternion = reader.GetQuaternion();
					float health = reader.GetFloat();
					if (_enemies.TryGetValue(uLong, out NetworkedEnemy value) && (Object)(object)value != (Object)null)
					{
						value.ApplyRemoteState(vector, quaternion, health);
					}
				}
			}
			finally
			{
				ApplyingRemoteState = false;
			}
		}

		private void HandleKill(DataReader reader)
		{
			if (MPSteamworks.IsHost)
			{
				return;
			}
			ulong uLong = reader.GetULong();
			string text = reader.GetString();
			if (string.IsNullOrEmpty(text))
			{
				text = "diedSync";
			}
			if (_enemies.TryGetValue(uLong, out NetworkedEnemy value) && !((Object)(object)value == (Object)null))
			{
				GameEntity component = ((Component)value).GetComponent<GameEntity>();
				if (component != null)
				{
					component.Kill(text);
				}
			}
		}

		public void HandleChunkRequest(ulong senderId)
		{
			if (MPCore.CanSync && MPSteamworks.IsHost && !((Object)(object)MonoSingleton<WorldSyncManager>.Instance == (Object)null) && IsEnabled && senderId != 0L && senderId != MPSteamworks.UserSteamId)
			{
				if (_diedEntityRoutines.TryGetValue(senderId, out Coroutine value) && value != null)
				{
					((MonoBehaviour)MonoSingleton<WorldSyncManager>.Instance).StopCoroutine(value);
				}
				_diedEntityRoutines[senderId] = ((MonoBehaviour)MonoSingleton<WorldSyncManager>.Instance).StartCoroutine(SendDiedEnemiesChunksRoutine(senderId));
			}
		}

		private void HandleChunk(DataReader reader)
		{
			if (MPSteamworks.IsHost)
			{
				return;
			}
			int num = reader.GetInt();
			GameEntity val = default(GameEntity);
			for (int i = 0; i < num; i++)
			{
				ulong uLong = reader.GetULong();
				string text = reader.GetString();
				_diedEntities[uLong] = text;
				if (_enemies.TryGetValue(uLong, out NetworkedEnemy value) && (Object)(object)value != (Object)null && ((Component)value).TryGetComponent<GameEntity>(ref val))
				{
					if (string.IsNullOrEmpty(text))
					{
						val.Kill("diedSync");
					}
					else
					{
						val.Kill(text);
					}
				}
			}
		}

		private bool IsSyncableEnemy(GameEntity entity)
		{
			if ((Object)(object)entity == (Object)null || (Object)(object)((Component)entity).gameObject == (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)entity).GetComponent<CL_Prop>() != (Object)null && (Object)(object)((Component)entity).GetComponent<AIGameEntity>() == (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)entity).GetComponent<Item_Object>() != (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)entity).GetComponent<ENT_Player>() != (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)entity).GetComponent<RemoteEntity>() != (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)entity).GetComponent<RPContainerRef>() != (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)entity).GetComponent<DEN_DeathFloor>() != (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)entity).GetComponent<DEN_Roach>() != (Object)null)
			{
				return false;
			}
			ObjectTagger component = ((Component)entity).GetComponent<ObjectTagger>();
			if ((Object)(object)component != (Object)null && component.tags.Contains("Creature"))
			{
				return true;
			}
			MPMain.LogTest("Checking syncable enemy: " + ((Object)entity).name);
			string name = ((Object)entity).name;
			MPMain.LogTest("Sync root name: " + name);
			return name.StartsWith("Denizen_", StringComparison.OrdinalIgnoreCase) || name.StartsWith("DEN_", StringComparison.OrdinalIgnoreCase);
		}
	}
	public enum SceneItemSyncAction : byte
	{
		Create,
		Remove,
		RemoveChunk,
		RemoveChunkRequest
	}
	public enum DroppedItemSyncAction : byte
	{
		Create,
		PickupRequest,
		PickupRemove,
		PickupReject
	}
	public class SceneItemModule : Singleton<SceneItemModule>, ISyncModule
	{
		public const byte SCENE_ITEM = 1;

		private const int TombstonesPerChunk = 20;

		private HashSet<ulong> _sceneTombstones = new HashSet<ulong>();

		private Dictionary<ulong, Item_Object> _sceneItems = new Dictionary<ulong, Item_Object>();

		private Dictionary<string, HashSet<ulong>> _teamTombstones = new Dictionary<string, HashSet<ulong>>();

		private Dictionary<ulong, Coroutine> _sendCoroutines = new Dictionary<ulong, Coroutine>();

		private static readonly HashSet<string> _blacklistedPrefabNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "Item_Flashlight", "Item_Flaregun", "Item_Cryogun", "Item_Handgun", "Item_Handgun_Debug", "Item_10mm_Ammo" };

		private static readonly HashSet<string> _blacklistedItemTags = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "artifact", "disk", "trinket", "notsync" };

		private static readonly HashSet<string> _blacklistedObjectTagger = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "ItemLocked" };

		public string ModuleName => "SceneItemSync";

		public bool IsEnabled { get; set; }

		public void OnResetMap()
		{
			ResetState();
		}

		public void OnLeave()
		{
			if (!MPCore.IsReady)
			{
				_sceneTombstones.Clear();
				_sceneItems.Clear();
				foreach (HashSet<ulong> value in _teamTombstones.Values)
				{
					value.Clear();
				}
				_teamTombstones.Clear();
				foreach (Coroutine value2 in _sendCoroutines.Values)
				{
					if (value2 != null)
					{
						((MonoBehaviour)MonoSingleton<WorldSyncManager>.Instance).StopCoroutine(value2);
					}
				}
				_sendCoroutines.Clear();
			}
			else
			{
				ResetState();
			}
		}

		public void OnEnd()
		{
			OnLeave();
		}

		public void OnSyncUpdate(float deltaTime)
		{
		}

		public void ResetState()
		{
			_sceneItems.Clear();
			_sceneTombstones.Clear();
		}

		public void ChangeTeam()
		{
			_sceneTombstones.Clear();
			HashSet<ulong> value;
			if (!MPSteamworks.IsHost)
			{
				SendSceneRemoveChunkRequest();
			}
			else if (_teamTombstones.TryGetValue(MPCore.CurrentTeam, out value))
			{
				_sceneTombstones = new HashSet<ulong>(value);
			}
		}

		public void OnSceneItemStarted(Item_Object itemObject)
		{
			NetworkedItem networkedItem = default(NetworkedItem);
			if ((Object)(object)itemObject == (Object)null || !MPCore.IsReady || !IsSyncableWorldItem(itemObject) || IsBlacklisted(((Component)itemObject).gameObject) || (((Component)itemObject).TryGetComponent<NetworkedItem>(ref networkedItem) && networkedItem.sceneOrDropped != 1))
			{
				return;
			}
			ulong sceneNetworkId = GetSceneNetworkId(itemObject);
			if (sceneNetworkId != 0)
			{
				if (_sceneTombstones.Contains(sceneNetworkId))
				{
					MPMain.LogInfo($"[ItemSync] Suppressing deleted scene item on load: {sceneNetworkId}");
					((Component)itemObject).gameObject.SetActive(false);
					Object.Destroy((Object)(object)itemObject);
					_sceneItems.Remove(sceneNetworkId);
				}
				else
				{
					_sceneItems[sceneNetworkId] = itemObject;
					NetworkedItem orCreateIdentity = GetOrCreateIdentity(((Component)itemObject).gameObject);
					orCreateIdentity.networkId = sceneNetworkId;
					orCreateIdentity.ownerId = 0uL;
					orCreateIdentity.isRemote = false;
					orCreateIdentity.sceneOrDropped = 1;
				}
			}
		}

		public void NotifyLocalPickup(NetworkedItem identity)
		{
			BroadcastSceneRemove(identity);
			_sceneItems.Remove(identity.networkId);
			identity.networkId = 0uL;
		}

		private ulong GetSceneNetworkId(Item_Object itemObject)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)itemObject == (Object)null || (Object)(object)((Component)itemObject).gameObject == (Object)null)
			{
				return 0uL;
			}
			Scene scene = ((Component)itemObject).gameObject.scene;
			if (((Scene)(ref scene)).IsValid())
			{
				scene = ((Component)itemObject).gameObject.scene;
				if (!string.IsNullOrEmpty(((Scene)(ref scene)).name))
				{
					NetworkedItem component = ((Component)itemObject).GetComponent<NetworkedItem>();
					if ((Object)(object)component != (Object)null && component.sceneOrDropped == 1)
					{
						return component.networkId;
					}
					string text = MPUtil.BuildTransformPath(((Component)itemObject).transform);
					return MPUtil.Hash64(("sceneItem:" + text).AsSpan());
				}
			}
			return 0uL;
		}

		private void BroadcastSceneRemove(NetworkedItem identity)
		{
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			if (identity?.sceneOrDropped != 1)
			{
				return;
			}
			DataWriter writer = MPWriterPool.GetWriter(MPSteamworks.UserSteamId, 0uL, PacketType.SceneItemStateSync);
			writer.Put((byte)1);
			writer.Put(identity.networkId);
			List<ulong> playersMatchingRule = Singleton<RPManager>.Instance.GetPlayersMatchingRule(RuleType.SyncSceneItem, value: true);
			foreach (ulong item in playersMatchingRule)
			{
				if (item != MonoSingleton<MPSteamworks>.Instance.HostSteamId)
				{
					MonoSingleton<MPSteamworks>.Instance.SendToPeer(SteamId.op_Implicit(item), writer, (SendType)8, 0);
				}
			}
			if (!MPSteamworks.IsHost)
			{
				MonoSingleton<MPSteamworks>.Instance.SendToHost(writer, (SendType)8, 0);
				return;
			}
			if (!_teamTombstones.TryGetValue(MPCore.CurrentTeam, out HashSet<ulong> value))
			{
				value = new HashSet<ulong>();
				_teamTombstones[MPCore.CurrentTeam] = value;
			}
			value.Add(identity.networkId);
		}

		private void SendSceneRemoveChunkRequest()
		{
			if (!MPSteamworks.IsHost)
			{
				MPMain.LogInfo("[MP ItemSync] Requesting Scene Tombstone Chunk from Host...");
				DataWriter writer = MPWriterPool.GetWriter(MPSteamworks.UserSteamId, MonoSingleton<MPSteamworks>.Instance.HostSteamId, PacketType.SceneItemStateSync);
				writer.Put((byte)3);
				MonoSingleton<MPSteamworks>.Instance.SendToHost(writer, (SendType)8, 0);
			}
		}

		private IEnumerator SendTombstoneChunksCoroutine(ulong clientId, List<ulong> tombstoneList)
		{
			int total = tombstoneList.Count;
			int currentIndex = 0;
			while (currentIndex < total)
			{
				int countToSend = Mathf.Min(20, total - currentIndex);
				DataWriter writer = MPWriterPool.GetWriter(MPSteamworks.UserSteamId, clientId, PacketType.SceneItemStateSync);
				writer.Put((byte)2);
				writer.Put(countToSend);
				for (int i = 0; i < countToSend; i++)
				{
					writer.Put(tombstoneList[currentIndex + i]);
				}
				MonoSingleton<MPSteamworks>.Instance.SendToPeer(SteamId.op_Implicit(clientId), writer, (SendType)8, 0);
				currentIndex += countToSend;
				yield return null;
			}
			MPMain.LogInfo($"[MP ItemSync] Finished sending {total} tombstones to client {clientId}");
			_sendCoroutines.Remove(clientId);
		}

		public void HandleSceneCreate(ulong senderId, DataReader reader)
		{
		}

		public void HandleSceneRemove(ulong senderId, DataReader reader)
		{
			ulong uLong = reader.GetULong();
			if (MPSteamworks.IsHost)
			{
				string playerTeam = Singleton<RPManager>.Instance.GetPlayerTeam(senderId);
				if (!_teamTombstones.TryGetValue(playerTeam, out HashSet<ulong> value))
				{
					value = new HashSet<ulong>();
					_teamTombstones[playerTeam] = value;
				}
				value.Add(uLong);
				if (!Singleton<RPManager>.Instance.GetPlayerRuleValue(senderId, RuleType.SyncSceneItem))
				{
					return;
				}
			}
			ProcessSceneItemRemoval(uLong);
		}

		public void HandleSceneRemoveChunk(DataReader reader)
		{
			int num = reader.GetInt();
			MPMain.LogInfo($"[MP ItemSync] Received Tombstone Chunk with {num} items.");
			for (int i = 0; i < num; i++)
			{
				ulong uLong = reader.GetULong();
				ProcessSceneItemRemoval(uLong);
			}
		}

		public void HandleSceneRemoveChunkRequest(ulong senderId)
		{
			if (!MPCore.CanSync || !MPSteamworks.IsHost || (Object)(object)MonoSingleton<WorldSyncManager>.Instance == (Object)null || senderId == 0L || senderId == MPSteamworks.UserSteamId)
			{
				return;
			}
			string text = Singleton<RPManager>.Instance.GetPlayerTeam(senderId);
			if (text == string.Empty)
			{
				text = "default";
			}
			if (_teamTombstones.TryGetValue(text, out HashSet<ulong> value) && value.Count != 0)
			{
				if (_sendCoroutines.TryGetValue(senderId, out Coroutine value2) && value2 != null)
				{
					((MonoBehaviour)MonoSingleton<WorldSyncManager>.Instance).StopCoroutine(value2);
				}
				_sendCoroutines[senderId] = ((MonoBehaviour)MonoSingleton<WorldSyncManager>.Instance).StartCoroutine(SendTombstoneChunksCoroutine(senderId, value.ToList()));
			}
		}

		public void HandleItemState(ulong senderId, DataReader reader)
		{
			SceneItemSyncAction sceneItemSyncAction = (SceneItemSyncAction)reader.GetByte();
			try
			{
				switch (sceneItemSyncAction)
				{
				case SceneItemSyncAction.Create:
					MPMain.LogDebug("[MP SceneItemSync] Create");
					HandleSceneCreate(senderId, reader);
					break;
				case SceneItemSyncAction.Remove:
					MPMain.LogDebug("[MP SceneItemSync] Remove");
					HandleSceneRemove(senderId, reader);
					break;
				case SceneItemSyncAction.RemoveChunk:
					MPMain.LogDebug("[MP SceneItemSync] RemoveChunk");
					HandleSceneRemoveChunk(reader);
					break;
				case SceneItemSyncAction.RemoveChunkRequest:
					MPMain.LogDebug("[MP SceneItemSync] RemoveChunkRequest");
					HandleSceneRemoveChunkRequest(senderId);
					break;
				}
			}
			catch (Exception ex)
			{
				MPMain.LogError($"[MP ItemSync] HandleItemState failed for action {sceneItemSyncAction}: {ex.Message}");
			}
		}

		private void ProcessSceneItemRemoval(ulong networkId)
		{
			if (networkId == 0)
			{
				return;
			}
			_sceneTombstones.Add(networkId);
			if (_sceneItems.TryGetValue(networkId, out Item_Object value))
			{
				MPMain.LogInfo($"[MP ItemSync] Suppressing deleted scene item: {networkId}");
				if ((Object)(object)value != (Object)null && (Object)(object)((Component)value).gameObject != (Object)null)
				{
					((Component)value).gameObject.SetActive(false);
					Object.Destroy((Object)(object)((Component)value).gameObject);
				}
				_sceneItems.Remove(networkId);
			}
		}

		public static NetworkedItem GetOrCreateIdentity(GameObject gameObject)
		{
			return gameObject.GetComponent<NetworkedItem>() ?? gameObject.AddComponent<NetworkedItem>();
		}

		public static bool IsBlacklisted(string prefabName)
		{
			if (string.IsNullOrEmpty(prefabName))
			{
				return false;
			}
			return _blacklistedPrefabNames.Contains(MPUtil.CleanCloneName(prefabName));
		}

		public static bool IsBlacklisted(Item item)
		{
			if (item == null)
			{
				return false;
			}
			if (item.itemTags != null)
			{
				foreach (string itemTag in item.itemTags)
				{
					if (_blacklistedItemTags.Contains(itemTag))
					{
						return true;
					}
				}
			}
			return false;
		}

		public static bool IsBlacklisted(ObjectTagger tagger)
		{
			if (tagger?.tags == null)
			{
				return false;
			}
			foreach (string tag in tagger.tags)
			{
				if (_blacklistedObjectTagger.Contains(tag))
				{
					return true;
				}
			}
			return false;
		}

		public static bool IsBlacklisted(GameObject go)
		{
			if ((Object)(object)go == (Object)null)
			{
				return false;
			}
			if (IsBlacklisted(((Object)go).name))
			{
				return true;
			}
			Item_Object val = default(Item_Object);
			if (go.TryGetComponent<Item_Object>(ref val) && IsBlacklisted(val.itemData))
			{
				return true;
			}
			ObjectTagger tagger = default(ObjectTagger);
			if (go.TryGetComponent<ObjectTagger>(ref tagger) && IsBlacklisted(tagger))
			{
				return true;
			}
			return false;
		}

		private static bool IsSyncableWorldItem(Item_Object itemObject)
		{
			//IL_003d: 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)
			if ((Object)(object)itemObject == (Object)null || (Object)(object)((Component)itemObject).gameObject == (Object)null)
			{
				return false;
			}
			if (!((Component)itemObject).gameObject.activeInHierarchy)
			{
				return false;
			}
			Scene scene = ((Component)itemObject).gameObject.scene;
			if (string.IsNullOrEmpty(((Scene)(ref scene)).name))
			{
				return false;
			}
			if (itemObject.itemData == null)
			{
				return false;
			}
			if (itemObject.itemData.inBag)
			{
				return false;
			}
			return true;
		}
	}
	public class DroppedItemModule : Singleton<DroppedItemModule>, ISyncModule
	{
		public const byte DROPPED_ITEM = 2;

		private Dictionary<ulong, NetworkedItem> _p2pItems = new Dictionary<ulong, NetworkedItem>();

		private ulong _nextLocalItemId = 1uL;

		public Func<Item, bool> _inHandMethod = AccessTools.MethodDelegate<Func<Item, bool>>(AccessTools.Method(typeof(Item), "InHand", (Type[])null, (Type[])null), (object)null, true);

		private static readonly HashSet<string> _blacklistedPrefabNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private static readonly HashSet<string> _blacklistedItemTags = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "notsync" };

		private static readonly HashSet<string> _blacklistedObjectTagger = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "ItemLocked" };

		public string ModuleName => "DroppedItemSync";

		public bool IsEnabled { get; set; }

		public void OnResetMap()
		{
			_p2pItems.Clear();
			_nextLocalItemId = 1uL;
		}

		public void OnLeave()
		{
			_p2pItems.Clear();
			_nextLocalItemId = 1uL;
		}

		public void OnEnd()
		{
			OnLeave();
		}

		public void OnSyncUpdate(float deltaTime)
		{
		}

		public void NotifyLocalDrop(Item item)
		{
			if (item != null && MPCore.CanSync)
			{
				Item_Object dropObject = item.GetDropObject(true);
				if (IsSyncableDropItem(dropObject) && !IsBlacklisted(((Component)dropObject).gameObject))
				{
					SyncAndBroadcast(dropObject);
				}
			}
		}

		public void NotifyLocalPickup(NetworkedItem identity)
		{
			if (identity.ownerId == MPSteamworks.UserSteamId)
			{
				BroadcastPickupRemove(MPSteamworks.UserSteamId, identity.networkId, destroyObject: false);
			}
			else
			{
				SendPickupRequest(identity.networkId, identity.ownerId);
			}
		}

		public void SpawnSyncedWorldDrop(string prefabKey, Vector3 position, Quaternion rotation, Vector3 velocity)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (MPCore.CanSync && !string.IsNullOrWhiteSpace(prefabKey))
			{
				var (val, networkedItem) = InstantiateWorldItem(prefabKey, position, rotation, 0uL, 0uL);
				if (!((Object)(object)val == (Object)null))
				{
					SyncAndBroadcast(val);
				}
			}
		}

		public NetworkedItem SyncAndBroadcast(Item_Object itemObject)
		{
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)itemObject == (Object)null || (Object)(object)((Component)itemObject).gameObject == (Object)null)
			{
				return null;
			}
			NetworkedItem orCreateIdentity = GetOrCreateIdentity(((Component)itemObject).gameObject);
			if (orCreateIdentity.networkId == 0L || orCreateIdentity.ownerId == 0)
			{
				orCreateIdentity.networkId = MPUtil.Hash64($"{MPSteamworks.UserSteamId}:{_nextLocalItemId++}".AsSpan());
				orCreateIdentity.prefabKey = GetPrefabKey(itemObject);
				orCreateIdentity.ownerId = MPSteamworks.UserSteamId;
				orCreateIdentity.sceneOrDropped = 2;
				orCreateIdentity.isRemote = false;
				_p2pItems[orCreateIdentity.networkId] = orCreateIdentity;
			}
			else if (!_p2pItems.ContainsKey(orCreateIdentity.networkId))
			{
				orCreateIdentity.ownerId = MPSteamworks.UserSteamId;
				_p2pItems[orCreateIdentity.networkId] = orCreateIdentity;
			}
			BroadcastDropCreate(orCreateIdentity, itemObject, orCreateIdentity.CurrentVelocity);
			return orCreateIdentity;
		}

		public void DespawnAndBroadcast(Item_Object itemObject)
		{
			if (!((Object)(object)itemObject == (Object)null))
			{
				NetworkedItem component = ((Component)itemObject).GetComponent<NetworkedItem>();
				if ((Object)(object)component != (Object)null && component.networkId != 0)
				{
					BroadcastPickupRemove(0uL, component.networkId);
					_p2pItems.Remove(component.networkId);
					component.networkId = 0uL;
				}
				else
				{
					((Component)itemObject).gameObject.SetActive(false);
					Object.Destroy((Object)(object)((Component)itemObject).gameObject);
				}
			}
		}

		private void BroadcastDropCreate(NetworkedItem identity, Item_Object itemObject, Vector3 velocity)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)identity == (Object)null || (Object)(object)itemObject == (Object)null || identity.networkId == 0)
			{
				return;
			}
			DataWriter writer = MPWriterPool.GetWriter(MPSteamworks.UserSteamId, 0uL, PacketType.DroppedItemStateSync);
			writer.Put((byte)0);
			writer.Put(identity.networkId);
			writer.Put(identity.prefabKey);
			writer.Put(((Component)itemObject).transform.position);
			writer.Put(((Component)itemObject).transform.rotation);
			writer.Put(velocity);
			List<ulong> playersMatchingRule = Singleton<RPManager>.Instance.GetPlayersMatchingRule(RuleType.SyncDropItem, value: true);
			foreach (ulong item in playersMatchingRule)
			{
				MonoSingleton<MPSteamworks>.Instance.SendToPeer(SteamId.op_Implicit(item), writer, (SendType)8, 0);
			}
		}

		private void SendPickupRequest(ulong networkId, ulong ownerId)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			DataWriter writer = MPWriterPool.GetWriter(MPSteamworks.UserSteamId, ownerId, PacketType.DroppedItemStateSync);
			writer.Put((byte)1);
			writer.Put(networkId);
			MonoSingleton<MPSteamworks>.Instance.SendToPeer(SteamId.op_Implicit(ownerId), writer, (SendType)8, 0);
		}

		private void SendPickupReject(ulong targetId, ulong networkId)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			DataWriter writer = MPWriterPool.GetWriter(MPSteamworks.UserSteamId, targetId, PacketType.DroppedItemStateSync);
			writer.Put((byte)3);
			writer.Put(networkId);
			MonoSingleton<MPSteamworks>.Instance.SendToPeer(SteamId.op_Implicit(targetId), writer, (SendType)8, 0);
		}

		private void BroadcastPickupRemove(ulong holderId, ulong networkId, bool destroyObject = true)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			DataWriter writer = MPWriterPool.GetWriter(MPSteamworks.UserSteamId, 0uL, PacketType.DroppedItemStateSync);
			writer.Put((byte)2);
			writer.Put(networkId);
			writer.Put(holderId);
			writer.Put(destroyObject);
			List<ulong> playersMatchingRule = Singleton<RPManager>.Instance.GetPlayersMatchingRule(RuleType.SyncDropItem, value: true);
			foreach (ulong item in playersMatchingRule)
			{
				MonoSingleton<MPSteamworks>.Instance.SendToPeer(SteamId.op_Implicit(item), writer, (SendType)8, 0);
			}
		}

		public void HandleDropCreate(ulong senderId, DataReader reader)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: 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_00bd: Unknown result type (might be due to invalid IL or missing references)
			ulong uLong = reader.GetULong();
			string text = reader.GetString();
			Vector3 vector = reader.GetVector3();
			Quaternion quaternion = reader.GetQuaternion();
			Vector3 vector2 = reader.GetVector3();
			if (uLong == 0L || string.IsNullOrEmpty(text))
			{
				return;
			}
			if (_p2pItems.TryGetValue(uLong, out NetworkedItem value) && (Object)(object)value != (Object)null)
			{
				value.ownerId = senderId;
				value.ApplyRemoteState(vector, quaternion, vector2);
				return;
			}
			var (val, networkedItem) = InstantiateWorldItem(text, vector, quaternion, uLong, senderId);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)networkedItem == (Object)null))
			{
				_p2pItems[uLong] = networkedItem;
				networkedItem.ApplyRemoteState(vector, quaternion, vector2);
			}
		}

		public void HandlePickupRequest(ulong requesterId, DataReader reader)
		{
			ulong uLong = reader.GetULong();
			if (uLong != 0)
			{
				MPMain.LogInfo($"[MP ItemSync] PickupRequest from {requesterId} for {uLong}");
				if (!_p2pItems.TryGetValue(uLong, out NetworkedItem value) || (Object)(object)value == (Object)null)
				{
					SendPickupReject(requesterId, uLong);
				}
				else if (value.IsInLocalInventory(_inHandMethod))
				{
					MPMain.LogWarning($"[MP ItemSync] PickupRequest denied: Item {uLong} is already in local inventory.");
					SendPickupReject(requesterId, uLong);
				}
				else if (value.ownerId == MPSteamworks.UserSteamId)
				{
					BroadcastPickupRemove(requesterId, uLong);
					Forget(uLong);
				}
				else
				{
					SendPickupReject(requesterId, uLong);
				}
			}
		}

		public void HandlePickupRemove(ulong senderId, DataReader reader)
		{
			ulong uLong = reader.GetULong();
			ulong uLong2 = reader.GetULong();
			bool shouldRemove = reader.GetBool();
			if (!Singleton<RPManager>.Instance.GetPlayerRuleValue(senderId, RuleType.SyncDropItem) || uLong == 0)
			{
				return;
			}
			if (uLong2 == MPSteamworks.UserSteamId)
			{
				if (_p2pItems.TryGetValue(uLong, out NetworkedItem value) && !((Object)(object)value == (Object)null))
				{
					Item_Object component = ((Component)value).GetComponent<Item_Object>();
					value.networkId = 0uL;
					_p2pItems.Remove(uLong);
				}
			}
			else
			{
				ForceCleanupItemPhysicalAndInventory(uLong, shouldRemove);
			}
		}

		public void HandlePickupReject(DataReader reader)
		{
			ulong uLong = reader.GetULong();
			if (uLong != 0)
			{
				MPMain.LogWarning($"[MP ItemSync] PickupReject received! Rolling back inventory for {uLong}");
				ForceCleanupItemPhysicalAndInventory(uLong, shouldRemove: true);
			}
		}

		public void HandleItemState(ulong senderId, DataReader reader)
		{
			DroppedItemSyncAction droppedItemSyncAction = (DroppedItemSyncAction)reader.GetByte();
			try
			{
				switch (droppedItemSyncAction)
				{
				case DroppedItemSyncAction.Create:
					MPMain.LogDebug("[MP DropItemSync] Create");
					HandleDropCreate(senderId, reader);
					break;
				case DroppedItemSyncAction.PickupRequest:
					MPMain.LogDebug("[MP DropItemSync] PickupRequest");
					HandlePickupRequest(senderId, reader);
					break;
				case DroppedItemSyncAction.PickupRemove:
					MPMain.LogDebug("[MP DropItemSync] PickupRemove");
					HandlePickupRemove(senderId, reader);
					break;
				case DroppedItemSyncAction.PickupReject:
					MPMain.LogDebug("[MP DropItemSync] PickupReject");
					HandlePickupReject(reader);
					break;
				}
			}
			catch (Exception ex)
			{
				MPMain.LogError($"[MP ItemSync] HandleItemState failed for action {droppedItemSyncAction}: {ex.Message}");
			}
		}

		private static (Item_Object, NetworkedItem) InstantiateWorldItem(string prefabKey, Vector3 position, Quaternion rotation, ulong networkId = 0uL, ulong ownerId = 0uL)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			if (!MPUtil.TryGetItemPrefab(prefabKey, out Item_Object item))
			{
				return (null, null);
			}
			bool activeSelf = ((Component)item).gameObject.activeSelf;
			((Component)item).gameObject.SetActive(false);
			Item_Object val = Object.Instantiate<Item_Object>(item, position, rotation);
			((Component)item).gameObject.SetActive(activeSelf);
			if ((Object)(object)val == (Object)null)
			{
				return (null, null);
			}
			NetworkedItem orCreateIdentity = GetOrCreateIdentity(((Component)val).gameObject);
			if (networkId != 0)
			{
				orCreateIdentity.SetupIdentity(networkId, prefabKey, ownerId, 2, isRemote: true);
			}
			LevelInfo closestLevelToPosition = WorldLoader.GetClosestLevelToPosition(position);
			LevelInfo currentLevelFromBounds = WorldLoader.GetCurrentLevelFromBounds();
			if (closestLevelToPosition != currentLevelFromBounds)
			{
				Rigidbody component = ((Component)val).GetComponent<Rigidbody>();
				if (component != null)
				{
					component.useGravity = false;
				}
			}
			if (currentLevelFromBounds != null)
			{
				((Component)val).transform.SetParent(closestLevelToPosition.GetLevel().GetParentRoot());
			}
			if (val.itemData != null)
			{
				val.itemData.InitializeItemData(val);
			}
			((Component)val).gameObject.SetActive(true);
			return (val, orCreateIdentity);
		}

		private static string GetPrefabKey(Item_Object itemObject)
		{
			if (itemObject.itemData != null && !string.IsNullOrEmpty(itemObject.itemData.prefabName))
			{
				return itemObject.itemData.prefabName;
			}
			return MPUtil.CleanCloneName(((Object)((Component)itemObject).gameObject).name);
		}

		public static NetworkedItem GetOrCreateIdentity(GameObject gameObject)
		{
			return gameObject.GetComponent<NetworkedItem>() ?? gameObject.AddComponent<NetworkedItem>();
		}

		public void ForceCleanupItemPhysicalAndInventory(ulong networkId, bool shouldRemove)
		{
			if (networkId != 0 && _p2pItems.TryGetValue(networkId, out NetworkedItem value) && !((Object)(object)value == (Object)null))
			{
				value.ForceCleanup(shouldRemove);
				if (shouldRemove)
				{
					_p2pItems.Remove(networkId);
				}
			}
		}

		private void Forget(ulong networkId)
		{
			if (_p2pItems.TryGetValue(networkId, out NetworkedItem value) && !((Object)(object)value == (Object)null))
			{
				Item_Object component = ((Component)value).GetComponent<Item_Object>();
				if ((Object)(object)((Component)value).gameObject != (Object)null)
				{
					((Component)value).gameObject.SetActive(false);
					Object.Destroy((Object)(object)((Component)value).gameObject);
				}
				_p2pItems.Remove(networkId);
			}
		}

		public static bool IsBlacklisted(string prefabName)
		{
			if (string.IsNullOrEmpty(prefabName))
			{
				return false;
			}
			return _blacklistedPrefabNames.Contains(MPUtil.CleanCloneName(prefabName));
		}

		public static bool IsBlacklisted(Item item)
		{
			if (item == null)
			{
				return false;
			}
			if (item.itemTags != null)
			{
				foreach (string itemTag in item.itemTags)
				{
					if (_blacklistedItemTags.Contains(itemTag))
					{
						return true;
					}
				}
			}
			return false;
		}

		public static bool IsBlacklisted(ObjectTagger tagger)
		{
			if (tagger?.tags == null)
			{
				return false;
			}
			foreach (string tag in tagger.tags)
			{
				if (_blacklistedObjectTagger.Contains(tag))
				{
					return true;
				}
			}
			return false;
		}

		public static bool IsBlacklisted(GameObject go)
		{
			if ((Object)(object)go == (Object)null)
			{
				return false;
			}
			if (IsBlacklisted(((Object)go).name))
			{
				return true;
			}
			Item_Object val = default(Item_Object);
			if (go.TryGetComponent<Item_Object>(ref val) && IsBlacklisted(val.itemData))
			{
				return true;
			}
			ObjectTagger tagger = default(ObjectTagger);
			if (go.TryGetComponent<ObjectTagger>(ref tagger) && IsBlacklisted(tagger))
			{
				return true;
			}
			return false;
		}

		private static bool IsSyncableDropItem(Item_Object itemObject)
		{
			if ((Object)(object)itemObject == (Object)null || (Object)(object)((Component)itemObject).gameObject == (Object)null)
			{
				return false;
			}
			if (!((Component)itemObject).gameObject.activeInHierarchy)
			{
				return false;
			}
			if (itemObject.itemData == null)
			{
				return false;
			}
			if (itemObject.itemData.inBag)
			{
				return false;
			}
			return true;
		}
	}
	public class WorldSyncManager : MonoSingleton<WorldSyncManager>
	{
		private readonly Dictionary<string, ISyncModule> _modules = new Dictionary<string, ISyncModule>();

		protected override void Awake()
		{
			base.Awake();
			SceneManager.sceneLoaded += OnSceneLoaded;
			RegisterModule(Singleton<EnemySyncModule>.Instance);
			RegisterModule(Singleton<ClimbableSyncModule>.Instance);
			RegisterModule(Singleton<SceneItemModule>.Instance);
			RegisterModule(Singleton<DroppedItemModule>.Instance);
		}

		public void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			ResetAll();
		}

		public void RegisterModule(ISyncModule module)
		{
			_modules.Add(module.ModuleName, module);
		}

		public bool TryGetModule(string name, out ISyncModule module)
		{
			return _modules.TryGetValue(name, out module);
		}

		private void LateUpdate()
		{
			if (!MPCore.CanSync)
			{
				return;
			}
			float unscaledDeltaTime = Time.unscaledDeltaTime;
			foreach (ISyncModule value in _modules.Values)
			{
				if (value.IsEnabled)
				{
					value.OnSyncUpdate(unscaledDeltaTime);
				}
			}
		}

		public void ResetAll()
		{
			foreach (ISyncModule value in _modules.Values)
			{
				value.OnResetMap();
			}
		}

		public void LeaveAll()
		{
			foreach (ISyncModule value in _modules.Values)
			{
				value.OnLeave();
			}
		}

		public void EndAll()
		{
			foreach (ISyncModule value in _modules.Values)
			{
				value.OnEnd();
			}
		}
	}
	public interface ISyncModule
	{
		string ModuleName { get; }

		bool IsEnabled { get; set; }

		void OnSyncUpdate(float deltaTime);

		void OnResetMap();

		void OnLeave();

		void OnEnd();
	}
}
namespace WKMPMod.Util
{
	public static class Localization
	{
		public struct LocalizedValue
		{
			private readonly object _data;

			public string[] AsArray => _data as string[];

			public string AsString => _data as string;

			public bool IsArray => _data is string[];

			public int Count => (!IsArray) ? 1 : ((string[])_data).Length;

			public LocalizedValue(object data)
			{
				_data = data;
			}

			public string GetValue(int index = 0)
			{
				if (_data is string[] array)
				{
					return array[Math.Clamp(index, 0, array.Length - 1)];
				}
				return _data?.ToString() ?? string.Empty;
			}

			public string GetValue(Random rand)
			{
				if (_data is string[] array)
				{
					return array[rand.Next(array.Length)];
				}
				return _data?.ToString() ?? string.Empty;
			}
		}

		private static Dictionary<string, Dictionary<string, LocalizedValue>> _enTable = new Dictionary<string, Dictionary<string, LocalizedValue>>();

		private static Dictionary<string, Dictionary<string, LocalizedValue>> _localTable = new Dictionary<string, Dictionary<string, LocalizedValue>>();

		private static Dictionary<string, LocalizedValue> _flatEnCache = new Dictionary<string, LocalizedValue>();

		private static Dictionary<string, LocalizedValue> _flatLocalCache = new Dictionary<string, LocalizedValue>();

		private const string FILE_PREFIX = "texts";

		private static readonly Random _staticRandom = new Random();

		private static bool _isFontPluginLoaded = false;

		public static bool HasFontSupport()
		{
			if (Chainloader.PluginInfos.ContainsKey("mimimi-turret.wk-localization-loader"))
			{
				return true;
			}
			return Chainloader.PluginInfos.Values.Any((PluginInfo info) => info.Metadata.Name.Equals("WKLocalizationLoader", StringComparison.OrdinalIgnoreCase));
		}

		public static void Load()
		{
			string path = MPMain.path;
			_enTable.Clear();
			_localTable.Clear();
			string text = Path.Combine(path, "texts_en.json");
			if (File.Exists(text))
			{
				LoadFileToTable(text, _enTable);
			}
			else
			{
				MPMain.LogWarning("[Localization] Base English file not found at: " + text);
			}
			string gameLanguage = GetGameLanguage();
			if (gameLanguage != "en")
			{
				string text2 = Path.Combine(path, "texts_" + gameLanguage.ToLower() + ".json");
				if (File.Exists(text2))
				{
					LoadFileToTable(text2, _localTable);
					MPMain.LogInfo("[Localization] Loaded local language file for: " + gameLanguage);
				}
			}
			_flatEnCache = BuildFlatCache(_enTable);
			_flatLocalCache = BuildFlatCache(_localTable);
			if (_flatEnCache.Count == 0 && _flatLocalCache.Count == 0)
			{
				MPMain.LogError("[Localization] CRITICAL: No localization files loaded!");
			}
			_isFontPluginLoaded = HasFontSupport();
		}

		private static void LoadFileToTable(string filePath, Dictionary<string, Dictionary<string, LocalizedValue>> targetTable)
		{
			try
			{
				string text = File.ReadAllText(filePath);
				Dictionary<string, Dictionary<string, object>> dictionary = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, object>>>(text);
				if (dictionary == null)
				{
					return;
				}
				foreach (KeyValuePair<string, Dictionary<string, object>> item in dictionary)
				{
					if (!targetTable.ContainsKey(item.Key))
					{
						targetTable[item.Key] = new Dictionary<string, LocalizedValue>();
					}
					foreach (KeyValuePair<string, object> item2 in item.Value)
					{
						object value = item2.Value;
						JArray val = (JArray)((value is JArray) ? value : null);
						if (val != null)
						{
							targetTable[item.Key][item2.Key] = new LocalizedValue(((IEnumerable<JToken>)val).Select((JToken x) => ((object)x).ToString()).ToArray());
						}
						else
						{
							targetTable[item.Key][item2.Key] = new LocalizedValue(item2.Value?.ToString());
						}
					}
				}
			}
			catch (Exception ex)
			{
				MPMain.LogError("[Localization] Unable to parse localization file " + Path.GetFileName(filePath) + ": " + ex.Message);
			}
		}

		private static Dictionary<string, LocalizedValue> BuildFlatCache(Dictionary<string, Dictionary<string, LocalizedValue>> table)
		{
			Dictionary<string, LocalizedValue> dictionary = new Dictionary<string, LocalizedValue>(StringComparer.OrdinalIgnoreCase);
			foreach (KeyValuePair<string, Dictionary<string, LocalizedValue>> item in table)
			{
				foreach (KeyValuePair<string, LocalizedValue> item2 in item.Value)
				{
					dictionary[item.Key + "." + item2.Key] = item2.Value;
				}
			}
			return dictionary;
		}

		public static string SafeFormat(string pattern, params object[] args)
		{
			if (string.IsNullOrEmpty(pattern))
			{
				return string.Empty;
			}
			if (args == null || args.Length == 0)
			{
				return pattern;
			}
			try
			{
				MatchCollection matchCollection = Regex.Matches(pattern, "\\{([0-9]+)\\}");
				int num = -1;
				foreach (Match item in matchCollection)
				{
					if (int.TryParse(item.Groups[1].Value, out var result) && result > num)
					{
						num = result;
					}
				}
				if (num == -1)
				{
					return pattern;
				}
				int num2 = num + 1;
				object[] array = new object[num2];
				for (int i = 0; i < num2; i++)
				{
					array[i] = ((i < args.Length && args[i] != null) ? args[i] : "");
				}
				return string.Format(pattern, array);
			}
			catch (Exception ex)
			{
				MPMain.LogError("[Localization] Format error: " + ex.Message + " | Pattern: " + pattern);
				return pattern;
			}
		}

		public static string GetEnglish(string key, params object[] args)
		{
			if (_flatEnCache.TryGetValue(key, out var value))
			{
				return SafeFormat(value.AsString, args);
			}
			return "[" + key + "]";
		}

		public static bool TryGetValue(string key, out LocalizedValue value)
		{
			if (_flatLocalCache.TryGetValue(key, out value))
			{
				return true;
			}
			if (_flatEnCache.TryGetValue(key, out value))
			{
				return true;
			}
			value = new LocalizedValue("[" + key + "]");
			return false;
		}

		public static bool TryGetValueSmart(string key, out LocalizedValue value)
		{
			if (_isFontPluginLoaded && _flatLocalCache.TryGetValue(key, out value))
			{
				return true;
			}
			if (_flatEnCache.TryGetValue(key, out value))
			{
				return true;
			}
			value = new LocalizedValue("[" + key + "]");
			return false;
		}

		public static string Get(string key, params object[] args)
		{
			if (!TryGetValue(key, out var value))
			{
				return value.AsString;
			}
			return SafeFormat(value.AsString, args);
		}

		public static string GetSmart(string key, params object[] args)
		{
			if (!TryGetValueSmart(key, out var value))
			{
				return value.AsString;
			}
			return SafeFormat(value.AsString, args);
		}

		public static string GetRandom(string key, params object[] args)
		{
			if (!TryGetValueSmart(key, out var value))
			{
				return value.AsString;
			}
			return SafeFormat(value.GetValue(_staticRandom), args);
		}

		public static string GetByIndex(string key, int index, params object[] args)
		{
			if (!TryGetValueSmart(key, out var value))
			{
				return value.AsString;
			}
			return SafeFormat(value.GetValue(index), args);
		}

		public static int GetCount(string key)
		{
			LocalizedValue value;
			return TryGetValueSmart(key, out value) ? value.Count : 0;
		}

		public static string[] GetAll(string key)
		{
			if (!TryGetValueSmart(key, out var value))
			{
				return new string[0];
			}
			return value.IsArray ? value.AsArray : new string[1] { value.AsString };
		}

		public static bool HasLocalKey(string key)
		{
			return _flatLocalCache.ContainsKey(key);
		}

		public static bool HasLocalKey(string category, string key)
		{
			if (_localTable.TryGetValue(category, out Dictionary<string, LocalizedValue> value))
			{
				return value.ContainsKey(key);
			}
			return false;
		}

		public static IEnumerable<string> GetAllLocalCategories()
		{
			return _localTable.Keys;
		}

		public static IEnumerable<string> GetKeysInLocalCategory(string category)
		{
			if (_localTable.TryGetValue(category, out Dictionary<string, LocalizedValue> value))
			{
				return value.Keys;
			}
			return new List<string>();
		}

		public static string GetGameLanguage()
		{
			//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_0007: 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_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Invalid comparison between Unknown and I4
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Invalid comparison between Unknown and I4
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Invalid comparison between Unknown and I4
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Invalid comparison between Unknown and I4
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Invalid comparison between Unknown and I4
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Invalid comparison between Unknown and I4
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Invalid comparison between Unknown and I4
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Invalid comparison between Unknown and I4
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Invalid comparison between Unknown and I4
			SystemLanguage systemLanguage = Application.systemLanguage;
			SystemLanguage val = systemLanguage;
			if ((int)val <= 22)
			{
				if ((int)val <= 14)
				{
					if ((int)val == 6)
					{
						goto IL_0056;
					}
					if ((int)val == 14)
					{
						return "fr";
					}
				}
				else
				{
					if ((int)val == 15)
					{
						return "de";
					}
					if ((int)val == 22)
					{
						return "ja";
					}
				}
			}
			else if ((int)val <= 30)
			{
				if ((int)val == 23)
				{
					return "ko";
				}
				if ((int)val == 30)
				{
					return "ru";
				}
			}
			else
			{
				if ((int)val == 34)
				{
					return "es";
				}
				if ((int)val == 40)
				{
					goto IL_0056;
				}
				if ((int)val == 41)
				{
					return "zh_tw";
				}
			}
			return "en";
			IL_0056:
			return "zh";
		}
	}
	public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>
	{
		private static T _instance;

		private static readonly object _lock = new object();

		private static bool _applicationIsQuitting = false;

		public static T Instance
		{
			get
			{
				//IL_0074: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: Expected O, but got Unknown
				if (_applicationIsQuitting)
				{
					return null;
				}
				lock (_lock)
				{
					if ((Object)(object)_instance == (Object)null)
					{
						_instance = Object.FindObjectOfType<T>();
						if ((Object)(object)_instance == (Object)null)
						{
							GameObject val = new GameObject(typeof(T).Name);
							_instance = val.AddComponent<T>();
							Object.DontDestroyOnLoad((Object)(object)val);
						}
					}
					return _instance;
				}
			}
		}

		protected virtual void Awake()
		{
			if ((Object)(object)_instance == (Object)null)
			{
				_instance = (T)this;
				if ((Object)(object)((Component)this).transform.parent == (Object)null)
				{
					Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
				}
			}
			else if ((Object)(object)_instance != (Object)(object)this)
			{
				Debug.LogWarning((object)("MonoSingleton<" + typeof(T).Name + ">: Duplicate components were found in the scene and have been automatically destroyed"));
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		protected virtual void OnApplicationQuit()
		{
			_applicationIsQuitting = true;
		}

		protected virtual void OnDestroy()
		{
			if ((Object)(object)_instance == (Object)(object)this)
			{
				_instance = null;
			}
		}
	}
	public static class MPUtil
	{
		private const ulong FNV_offset_basis = 14695981039346656037uL;

		private const ulong FNV_prime = 1099511628211uL;

		public static readonly Dictionary<string, Color32> PlayerColorPresets = new Dictionary<string, Color32>(StringComparer.OrdinalIgnoreCase)
		{
			{
				"default",
				new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue)
			},
			{
				"white",
				new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue)
			},
			{
				"red",
				new Color32(byte.MaxValue, (byte)80, (byte)80, byte.MaxValue)
			},
			{
				"orange",
				new Color32(byte.MaxValue, (byte)165, (byte)0, byte.MaxValue)
			},
			{
				"yellow",
				new Color32(byte.MaxValue, (byte)220, (byte)64, byte.MaxValue)
			},
			{
				"green",
				new Color32((byte)80, (byte)220, (byte)120, byte.MaxValue)
			},
			{
				"cyan",
				new Color32((byte)64, (byte)220, byte.MaxValue, byte.MaxValue)
			},
			{
				"blue",
				new Color32((byte)90, (byte)140, byte.MaxValue, byte.MaxValue)
			},
			{
				"purple",
				new Color32((byte)170, (byte)90, byte.MaxValue, byte.MaxValue)
			},
			{
				"pink",
				new Color32(byte.MaxValue, (byte)110, (byte)180, byte.MaxValue)
			},
			{
				"black",
				new Color32((byte)32, (byte)32, (byte)32, byte.MaxValue)
			}
		};

		public static bool TryGetItemPrefab(string prefabName, out Item_Object item)
		{
			item = null;
			if (string.IsNullOrEmpty(prefabName))
			{
				MPMain.LogWarning("[MP] prefabName is null or empty.");
				return false;
			}
			Item_Object val = null;
			try
			{
				val = CL_AssetManager.GetItemObjectPrefab(prefabName, "");
			}
			catch (Exception ex)
			{
				MPMain.LogError("[MP] " + ex.ToString());
			}
			if ((Object)(object)val == (Object)null)
			{
				GameObject assetGameObject = CL_AssetManager.GetAssetGameObject(prefabName, "");
				val = ((assetGameObject != null) ? assetGameObject.GetComponent<Item_Object>() : null);
			}
			if ((Object)(object)val == (Object)null || val.itemData == null)
			{
				MPMain.LogError("[MP] Item_Object or itemData not found for prefab '" + prefabName + "'");
				return false;
			}
			item = val;
			return true;
		}

		public unsafe static ulong Hash64(ReadOnlySpan<char> str)
		{
			if (str.IsEmpty)
			{
				return 0uL;
			}
			ulong num = 14695981039346656037uL;
			fixed (char* ptr = str)
			{
				char* ptr2 = ptr;
				for (char* ptr3 = ptr + str.Length; ptr2 < ptr3; ptr2++)
				{
					num ^= *ptr2;
					num *= 1099511628211L;
				}
			}
			return num;
		}

		public static string CleanCloneName(string prefabKey)
		{
			return string.IsNullOrEmpty(prefabKey) ? string.Empty : prefabKey.Replace("(Clone)", string.Empty).Trim();
		}

		public static string BuildTransformPath(Transform transform)
		{
			if ((Object)(object)transform == (Object)null)
			{
				return string.Empty;
			}
			Stack<string> stack = new Stack<string>();
			Transform val = transform;
			while ((Object)(object)val != (Object)null)
			{
				stack.Push($"{CleanCloneName(((Object)val).name)}[{val.GetSiblingIndex()}]");
				val = val.parent;
			}
			return string.Join("/", stack);
		}

		public static string SerializePlayerColor(Color32 color)
		{
			//IL_0005: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			return $"{color.r},{color.g},{color.b}";
		}

		public static bool TryParsePlayerColor(string value, out Color32 color)
		{
			//IL_0016: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			color = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);
			if (string.IsNullOrWhiteSpace(value))
			{
				return false;
			}
			string[] array = value.Split(',');
			if (array.Length != 3)
			{
				return false;
			}
			if (!TryParseColorChannel(array[0], out var channel) || !TryParseColorChannel(array[1], out var channel2) || !TryParseColorChannel(array[2], out var channel3))
			{
				return false;
			}
			color = new Color32((byte)channel, (byte)channel2, (byte)channel3, byte.MaxValue);
			return true;
		}

		public static bool TryParseColorChannel(string value, out int channel)
		{
			if (int.TryParse(value.Trim(), out channel))
			{
				return channel >= 0 && channel <= 255;
			}
			return false;
		}
	}
	public static class NestedCommandEngine
	{
		public static readonly FieldRef<CommandConsole, IEnumerable> StatesRef;

		public static readonly FieldRef<object, IDictionary> CommandsRef;

		public static readonly FieldRef<object, Action<CommandAutocomplete>> AutocompleteRef;

		public static readonly FieldRef<CommandAutocomplete, List<string>> AutocompleteArgsRef;

		public static readonly Action<CommandAutocomplete, int> SetAutocompleteActiveArgAction;

		public static readonly FieldRef<object, Action<CommandValidator>> ValidatorRef;

		public static readonly FieldRef<CommandValidator, List<string>> ValidatorArgsRef;

		public static readonly Action<CommandValidator, int> SetValidatorActiveArgAction;

		static NestedCommandEngine()
		{
			try
			{
				Type typeFromHandle = typeof(CommandConsole);
				StatesRef = AccessTools.FieldRefAccess<CommandConsole, IEnumerable>("states");
				Type type = AccessTools.Inner(typeFromHandle, "CommandLineState");
				FieldInfo fieldInfo = AccessTools.Field(type, "commands");
				CommandsRef = AccessTools.FieldRefAccess<object, IDictionary>(fieldInfo);
				Type type2 = AccessTools.Inner(typeFromHandle, "Command");
				FieldInfo fieldInfo2 = AccessTools.Field(type2, "autocomplete");
				AutocompleteRef = AccessTools.FieldRefAccess<objec

WKMultiPlayerMod.Shared.dll

Decompiled 3 weeks ago
using System;
using System.Buffers;
using System.Buffers.Binary;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using WKMPMod.Data;
using WKMPMod.Util;
using WKMPModa.Shared.Component;
using WKMPModa.Shared.Data;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("WKMultiPlayerMod.Shared")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+2fcde0af4a9aa09bb6ab7267cad8d22e0247f903")]
[assembly: AssemblyProduct("WKMultiPlayerMod.Shared")]
[assembly: AssemblyTitle("WKMultiPlayerMod.Shared")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace WKMPMod.Util
{
	public static class DictionaryExtensions
	{
		public static List<ulong> FindByKeySuffix(IEnumerable<ulong> dictionary, ulong suffix)
		{
			List<ulong> list = new List<ulong>();
			if (dictionary == null)
			{
				return list;
			}
			ulong num = CalculateDivisor(suffix);
			foreach (ulong item in dictionary)
			{
				if (item % num == suffix)
				{
					list.Add(item);
				}
			}
			return list;
		}

		private static ulong CalculateDivisor(ulong suffix)
		{
			if (suffix == 0)
			{
				return 10uL;
			}
			ulong num;
			for (num = 1uL; num <= suffix; num *= 10)
			{
			}
			return num;
		}

		public static Dictionary<K, byte> SetDifference<K>(Dictionary<K, byte> minuend, Dictionary<K, byte> subtrahend)
		{
			Dictionary<K, byte> dictionary = new Dictionary<K, byte>();
			foreach (var (key, b2) in minuend)
			{
				if (subtrahend.TryGetValue(key, out var value))
				{
					if (b2 > value)
					{
						dictionary[key] = (byte)(b2 - value);
					}
				}
				else
				{
					dictionary[key] = b2;
				}
			}
			return dictionary;
		}
	}
	public class TickTimer
	{
		private float _interval;

		private float _lastTickTime;

		private bool _useUnscaledTime;

		public bool UseUnscaledTime
		{
			get
			{
				return _useUnscaledTime;
			}
			set
			{
				if (_useUnscaledTime != value)
				{
					float num = CurrentTime - _lastTickTime;
					_useUnscaledTime = value;
					_lastTickTime = CurrentTime - num;
				}
			}
		}

		private float CurrentTime => _useUnscaledTime ? Time.unscaledTime : Time.time;

		public float Progress => Mathf.Clamp01((CurrentTime - _lastTickTime) / _interval);

		public float TimeRemaining => Mathf.Max(0f, _interval - (CurrentTime - _lastTickTime));

		public bool IsTickReached => CurrentTime - _lastTickTime >= _interval;

		public TickTimer(float tick, bool useUnscaledTime = false)
		{
			_useUnscaledTime = useUnscaledTime;
			_interval = tick;
			_lastTickTime = CurrentTime - _interval;
		}

		public TickTimer(int hz, bool useUnscaledTime = false)
		{
			_useUnscaledTime = useUnscaledTime;
			_interval = 1f / (float)hz;
			_lastTickTime = CurrentTime - _interval;
		}

		public void SetInterval(float tick)
		{
			_interval = tick;
		}

		public void SetFrequency(float hz)
		{
			_interval = 1f / hz;
		}

		public void Reset()
		{
			_lastTickTime = CurrentTime;
		}

		public bool TryTick()
		{
			if (CurrentTime - _lastTickTime >= _interval)
			{
				_lastTickTime = CurrentTime;
				return true;
			}
			return false;
		}

		public void ForceTick()
		{
			_lastTickTime = CurrentTime;
		}
	}
}
namespace WKMPMod.MK_Component
{
	public class MK_CL_Handhold : MonoBehaviour
	{
		public UnityEvent activeEvent = new UnityEvent();

		public UnityEvent stopEvent = new UnityEvent();

		public Renderer handholdRenderer;
	}
	public class MK_ObjectTagger : MonoBehaviour
	{
		public List<string> tags = new List<string>();
	}
	public class MK_RemoteEntity : MonoBehaviour
	{
		public ulong playerId;
	}
	public class MK_RemoteHand : MonoBehaviour
	{
		[Header("左右手")]
		public byte hand;

		[Header("距离设置")]
		[Tooltip("当当前位置与目标位置超过此距离时直接瞬移")]
		public float teleportThreshold = 50f;

		[Tooltip("平滑移动的最大距离限制")]
		public float fastSmoothDistance = 10f;

		[Header("拉拽参数")]
		public float basePullStrength = 0.2f;

		[Header("肩膀 Transform")]
		public Transform shoulderTransform;

		[Header("身体 Transform")]
		public Transform bodyTransform;

		public void Teleport(Vector3 position)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).transform.position = position;
		}
	}
}
namespace WKMPMod.RemotePlayer
{
	public class DefaultModelExtension : ICustomModelExtension
	{
		private const string DISTANCE_FIELD_OVERLAY_SHADER = "assets/textmesh pro/shaders/tmp_sdf overlay.shader";

		private const string GAME_TMP_FONT_ASSET = "Ticketing SDF";

		public string ModelId => "default";

		public string PrefabAssetName => "CapsulePlayerPrefab";

		public string SpawnEffectAssetName => null;

		public string DeathEffectAssetName => null;

		public string DamageEffectAssetName => null;

		public void OnPrefabLoaded(GameObject prefabTemplate, IAssetHelper assetHelper)
		{
			FixTMPComponent(prefabTemplate, assetHelper);
			DefaultModelBehaviour component = prefabTemplate.GetComponent<DefaultModelBehaviour>();
			if ((Object)(object)component != (Object)null)
			{
				component.OnPrefabLoaded();
			}
		}

		public void OnPlayerInstanceCreated(GameObject playerInstance)
		{
		}

		private void FixTMPComponent(GameObject prefab, IAssetHelper assetHelper)
		{
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			if ((Object)(object)prefab == (Object)null)
			{
				return;
			}
			TMP_FontAsset val = ((IEnumerable<TMP_FontAsset>)Resources.FindObjectsOfTypeAll<TMP_FontAsset>()).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => ((Object)f).name == "Ticketing SDF"));
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogError((object)"SlugcatFactory.FontAssetNotFound: Ticketing SDF");
				return;
			}
			Shader customAsset = assetHelper.GetCustomAsset<Shader>("assets/textmesh pro/shaders/tmp_sdf overlay.shader");
			if ((Object)(object)customAsset == (Object)null)
			{
				Debug.LogError((object)"DefaultFactory.UnableToLoadShader: assets/textmesh pro/shaders/tmp_sdf overlay.shader");
			}
			TMP_Text[] componentsInChildren = prefab.GetComponentsInChildren<TMP_Text>(true);
			TMP_Text[] array = componentsInChildren;
			foreach (TMP_Text val2 in array)
			{
				Debug.Log((object)("DefaultFactory.SpecializingTMPComponent: " + ((Object)val2).name));
				val2.font = val;
				if ((Object)(object)customAsset != (Object)null)
				{
					Material val3 = new Material(((TMP_Asset)val).material);
					val3.shader = customAsset;
					val2.fontSharedMaterial = val3;
					Debug.Log((object)("DefaultFactory.ImplementOverlayViaShader: " + ((Object)val2).name));
				}
			}
		}
	}
	public interface ICustomModelExtension
	{
		string ModelId { get; }

		string PrefabAssetName { get; }

		string SpawnEffectAssetName { get; }

		string DeathEffectAssetName { get; }

		string DamageEffectAssetName { get; }

		void OnPrefabLoaded(GameObject prefab, IAssetHelper assetHelper);

		void OnPlayerInstanceCreated(GameObject playerInstance);
	}
	public interface IAssetHelper
	{
		T GetCustomAsset<T>(string assetName) where T : Object;
	}
	public class SlugcatModelExtension : ICustomModelExtension
	{
		private const string DISTANCE_FIELD_OVERLAY_SHADER = "assets/textmesh pro/shaders/tmp_sdf overlay.shader";

		private const string GAME_TMP_FONT_ASSET = "Ticketing SDF";

		public string ModelId => "slugcat";

		public string PrefabAssetName => "SlugcatPlayerPrefab";

		public string SpawnEffectAssetName => null;

		public string DeathEffectAssetName => null;

		public string DamageEffectAssetName => null;

		public void OnPrefabLoaded(GameObject prefabTemplate, IAssetHelper assetHelper)
		{
			FixTMPComponent(prefabTemplate, assetHelper);
			SlugcatModelBehaviour component = prefabTemplate.GetComponent<SlugcatModelBehaviour>();
			if ((Object)(object)component != (Object)null)
			{
				component.OnPrefabLoaded();
			}
		}

		public void OnPlayerInstanceCreated(GameObject playerInstance)
		{
		}

		private void FixTMPComponent(GameObject prefab, IAssetHelper assetHelper)
		{
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			if ((Object)(object)prefab == (Object)null)
			{
				return;
			}
			TMP_FontAsset val = ((IEnumerable<TMP_FontAsset>)Resources.FindObjectsOfTypeAll<TMP_FontAsset>()).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => ((Object)f).name == "Ticketing SDF"));
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogError((object)"SlugcatFactory.FontAssetNotFound: Ticketing SDF");
				return;
			}
			Shader customAsset = assetHelper.GetCustomAsset<Shader>("assets/textmesh pro/shaders/tmp_sdf overlay.shader");
			if ((Object)(object)customAsset == (Object)null)
			{
				Debug.LogError((object)"SlugcatFactory.UnableToLoadShader: assets/textmesh pro/shaders/tmp_sdf overlay.shader");
			}
			TMP_Text[] componentsInChildren = prefab.GetComponentsInChildren<TMP_Text>(true);
			TMP_Text[] array = componentsInChildren;
			foreach (TMP_Text val2 in array)
			{
				Debug.Log((object)("SlugcatFactory.SpecializingTMPComponent: " + ((Object)val2).name));
				val2.font = val;
				if ((Object)(object)customAsset != (Object)null)
				{
					Material val3 = new Material(((TMP_Asset)val).material);
					val3.shader = customAsset;
					val2.fontSharedMaterial = val3;
					Debug.Log((object)("SlugcatFactory.ImplementOverlayViaShader: " + ((Object)val2).name));
				}
			}
		}
	}
}
namespace WKMPMod.Data
{
	public class DataReader
	{
		private ReadOnlyMemory<byte> _data;

		private int _position;

		public int AvailableBytes => _data.Length - _position;

		public void SetSource(ArraySegment<byte> source)
		{
			_data = source;
			_position = 0;
		}

		public void SetSource(byte[] source)
		{
			_data = source;
			_position = 0;
		}

		public void SetSource(byte[] source, int offset, int length)
		{
			_data = new ReadOnlyMemory<byte>(source, offset, length);
			_position = 0;
		}

		public bool GetBool()
		{
			bool result = _data.Span[_position] != 0;
			_position++;
			return result;
		}

		public byte GetByte()
		{
			byte result = _data.Span[_position];
			_position++;
			return result;
		}

		public short GetShort()
		{
			short result = BinaryPrimitives.ReadInt16LittleEndian(_data.Span.Slice(_position));
			_position += 2;
			return result;
		}

		public ushort GetUShort()
		{
			ushort result = BinaryPrimitives.ReadUInt16LittleEndian(_data.Span.Slice(_position));
			_position += 2;
			return result;
		}

		public int GetInt()
		{
			int result = BinaryPrimitives.ReadInt32LittleEndian(_data.Span.Slice(_position));
			_position += 4;
			return result;
		}

		public uint GetUInt()
		{
			uint result = BinaryPrimitives.ReadUInt32LittleEndian(_data.Span.Slice(_position));
			_position += 4;
			return result;
		}

		public long GetLong()
		{
			long result = BinaryPrimitives.ReadInt64LittleEndian(_data.Span.Slice(_position));
			_position += 8;
			return result;
		}

		public ulong GetULong()
		{
			ulong result = BinaryPrimitives.ReadUInt64LittleEndian(_data.Span.Slice(_position));
			_position += 8;
			return result;
		}

		public float GetFloat()
		{
			int value = BinaryPrimitives.ReadInt32LittleEndian(_data.Span.Slice(_position));
			_position += 4;
			return BitConverter.Int32BitsToSingle(value);
		}

		public double GetDouble()
		{
			long value = BinaryPrimitives.ReadInt64LittleEndian(_data.Span.Slice(_position));
			_position += 8;
			return BitConverter.Int64BitsToDouble(value);
		}

		public byte? GetNullableByte()
		{
			if (!GetBool())
			{
				return null;
			}
			return GetByte();
		}

		public int? GetNullableInt()
		{
			if (!GetBool())
			{
				return null;
			}
			return GetInt();
		}

		public float? GetNullableFloat()
		{
			if (!GetBool())
			{
				return null;
			}
			return GetFloat();
		}

		public Vector3 GetVector3()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			ReadOnlySpan<byte> source = _data.Span.Slice(_position);
			float num = BitConverter.Int32BitsToSingle(BinaryPrimitives.ReadInt32LittleEndian(source));
			float num2 = BitConverter.Int32BitsToSingle(BinaryPrimitives.ReadInt32LittleEndian(source.Slice(4)));
			float num3 = BitConverter.Int32BitsToSingle(BinaryPrimitives.ReadInt32LittleEndian(source.Slice(8)));
			_position += 12;
			return new Vector3(num, num2, num3);
		}

		public Quaternion GetQuaternion()
		{
			//IL_0077: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			ReadOnlySpan<byte> source = _data.Span.Slice(_position);
			float num = BitConverter.Int32BitsToSingle(BinaryPrimitives.ReadInt32LittleEndian(source));
			float num2 = BitConverter.Int32BitsToSingle(BinaryPrimitives.ReadInt32LittleEndian(source.Slice(4)));
			float num3 = BitConverter.Int32BitsToSingle(BinaryPrimitives.ReadInt32LittleEndian(source.Slice(8)));
			float num4 = BitConverter.Int32BitsToSingle(BinaryPrimitives.ReadInt32LittleEndian(source.Slice(12)));
			_position += 16;
			return new Quaternion(num, num2, num3, num4);
		}

		public string GetString()
		{
			int num = GetInt();
			if (num <= 0)
			{
				return string.Empty;
			}
			if (num > AvailableBytes)
			{
				throw new Exception("String length out of range");
			}
			string result = Encoding.UTF8.GetString(_data.Span.Slice(_position, num));
			_position += num;
			return result;
		}

		public ReadOnlySpan<byte> GetBytes()
		{
			int num = GetInt();
			ReadOnlySpan<byte> result = _data.Span.Slice(_position, num);
			_position += num;
			return result;
		}

		public ReadOnlyMemory<byte> GetMemory()
		{
			int num = GetInt();
			ReadOnlyMemory<byte> result = _data.Slice(_position, num);
			_position += num;
			return result;
		}

		public Dictionary<string, byte> GetStringByteDict()
		{
			int num = GetInt();
			Dictionary<string, byte> dictionary = new Dictionary<string, byte>();
			for (int i = 0; i < num; i++)
			{
				string key = GetString();
				byte value = GetByte();
				dictionary[key] = value;
			}
			return dictionary;
		}

		public List<string> GetStringList()
		{
			List<string> list = new List<string>();
			int num = GetInt();
			for (int i = 0; i < num; i++)
			{
				list.Add(GetString());
			}
			return list;
		}

		public Dictionary<string, string> GetStringStringDict()
		{
			int num = GetInt();
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			for (int i = 0; i < num; i++)
			{
				string key = GetString();
				string value = GetString();
				dictionary[key] = value;
			}
			return dictionary;
		}

		public T Get<T>() where T : INetworkSerializable, new()
		{
			T result = new T();
			result.Deserialize(this);
			return result;
		}

		public void GetOut<T>(out T value) where T : struct, INetworkSerializable
		{
			value = default(T);
			value.Deserialize(this);
		}

		public void GetRef<T>(ref T value) where T : struct, INetworkSerializable
		{
			value.Deserialize(this);
		}

		public List<T> GetList<T>() where T : INetworkSerializable, new()
		{
			int num = GetInt();
			if (num <= 0)
			{
				return new List<T>(0);
			}
			List<T> list = new List<T>(num);
			for (int i = 0; i < num; i++)
			{
				T item = new T();
				item.Deserialize(this);
				list.Add(item);
			}
			return list;
		}

		public void GetList<T>(List<T> existingList) where T : INetworkSerializable, new()
		{
			int num = GetInt();
			existingList.Clear();
			for (int i = 0; i < num; i++)
			{
				T item = new T();
				item.Deserialize(this);
				existingList.Add(item);
			}
		}
	}
	public class DataWriter : IDisposable
	{
		private byte[] _buffer;

		private int _position;

		private readonly ArrayPool<byte> _pool;

		public ArraySegment<byte> Data => new ArraySegment<byte>(_buffer, 0, _position);

		public DataWriter(int initialCapacity = 1024)
		{
			_pool = ArrayPool<byte>.Shared;
			_buffer = _pool.Rent(initialCapacity);
			_position = 0;
		}

		public byte[] ToArray()
		{
			byte[] array = new byte[_position];
			Array.Copy(_buffer, 0, array, 0, _position);
			return array;
		}

		public void CopyDataTo(byte[] target, int targetOffset = 0)
		{
			if (target.Length - targetOffset < _position)
			{
				throw new ArgumentException("Target buffer is too small");
			}
			Array.Copy(_buffer, 0, target, targetOffset, _position);
		}

		public void Reset()
		{
			_position = 0;
		}

		public DataWriter Put(bool value)
		{
			EnsureCapacity(1);
			_buffer[_position] = (byte)(value ? 1u : 0u);
			_position++;
			return this;
		}

		public DataWriter Put(byte value)
		{
			EnsureCapacity(1);
			_buffer[_position] = value;
			_position++;
			return this;
		}

		public DataWriter Put(short value)
		{
			EnsureCapacity(2);
			BinaryPrimitives.WriteInt16LittleEndian(_buffer.AsSpan(_position), value);
			_position += 2;
			return this;
		}

		public DataWriter Put(ushort value)
		{
			EnsureCapacity(2);
			BinaryPrimitives.WriteUInt16LittleEndian(_buffer.AsSpan(_position), value);
			_position += 2;
			return this;
		}

		public DataWriter Put(int value)
		{
			EnsureCapacity(4);
			BinaryPrimitives.WriteInt32LittleEndian(_buffer.AsSpan(_position), value);
			_position += 4;
			return this;
		}

		public DataWriter Put(uint value)
		{
			EnsureCapacity(4);
			BinaryPrimitives.WriteUInt32LittleEndian(_buffer.AsSpan(_position), value);
			_position += 4;
			return this;
		}

		public DataWriter Put(long value)
		{
			EnsureCapacity(8);
			BinaryPrimitives.WriteInt64LittleEndian(_buffer.AsSpan(_position), value);
			_position += 8;
			return this;
		}

		public DataWriter Put(ulong value)
		{
			EnsureCapacity(8);
			BinaryPrimitives.WriteUInt64LittleEndian(_buffer.AsSpan(_position), value);
			_position += 8;
			return this;
		}

		public DataWriter Put(float value)
		{
			EnsureCapacity(4);
			int value2 = BitConverter.SingleToInt32Bits(value);
			BinaryPrimitives.WriteInt32LittleEndian(_buffer.AsSpan(_position), value2);
			_position += 4;
			return this;
		}

		public DataWriter Put(double value)
		{
			EnsureCapacity(8);
			long value2 = BitConverter.DoubleToInt64Bits(value);
			BinaryPrimitives.WriteInt64LittleEndian(_buffer.AsSpan(_position), value2);
			_position += 8;
			return this;
		}

		public DataWriter Put(byte? value)
		{
			if (!value.HasValue)
			{
				Put(value: false);
			}
			else
			{
				Put(value: true);
				Put(value.Value);
			}
			return this;
		}

		public DataWriter Put(int? value)
		{
			if (!value.HasValue)
			{
				Put(value: false);
			}
			else
			{
				Put(value: true);
				Put(value.Value);
			}
			return this;
		}

		public DataWriter Put(float? value)
		{
			if (!value.HasValue)
			{
				Put(value: false);
			}
			else
			{
				Put(value: true);
				Put(value.Value);
			}
			return this;
		}

		public DataWriter Put(byte[] value)
		{
			if (value == null)
			{
				return Put(0);
			}
			return Put(value, 0, value.Length);
		}

		public DataWriter Put(byte[] value, int offset, int length)
		{
			if (value == null)
			{
				EnsureCapacity(4);
				BinaryPrimitives.WriteInt32LittleEndian(_buffer.AsSpan(_position), 0);
				_position += 4;
				return this;
			}
			Put(length);
			EnsureCapacity(length);
			Array.Copy(value, offset, _buffer, _position, length);
			_position += length;
			return this;
		}

		public DataWriter Put(ReadOnlySpan<byte> value)
		{
			Put(value.Length);
			EnsureCapacity(value.Length);
			value.CopyTo(_buffer.AsSpan(_position));
			_position += value.Length;
			return this;
		}

		public DataWriter Put(string value)
		{
			if (string.IsNullOrEmpty(value))
			{
				Put(0);
				return this;
			}
			int maxByteCount = Encoding.UTF8.GetMaxByteCount(value.Length);
			EnsureCapacity(maxByteCount + 4);
			int position = _position;
			_position += 4;
			int bytes = Encoding.UTF8.GetBytes(value, 0, value.Length, _buffer, _position);
			BinaryPrimitives.WriteInt32LittleEndian(_buffer.AsSpan(position), bytes);
			_position += bytes;
			return this;
		}

		public DataWriter Put(Vector3 value)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			EnsureCapacity(12);
			Span<byte> destination = _buffer.AsSpan(_position);
			BinaryPrimitives.WriteInt32LittleEndian(destination, BitConverter.SingleToInt32Bits(value.x));
			BinaryPrimitives.WriteInt32LittleEndian(destination.Slice(4), BitConverter.SingleToInt32Bits(value.y));
			BinaryPrimitives.WriteInt32LittleEndian(destination.Slice(8), BitConverter.SingleToInt32Bits(value.z));
			_position += 12;
			return this;
		}

		public DataWriter Put(Quaternion value)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			EnsureCapacity(16);
			Span<byte> destination = _buffer.AsSpan(_position);
			BinaryPrimitives.WriteInt32LittleEndian(destination, BitConverter.SingleToInt32Bits(value.x));
			BinaryPrimitives.WriteInt32LittleEndian(destination.Slice(4), BitConverter.SingleToInt32Bits(value.y));
			BinaryPrimitives.WriteInt32LittleEndian(destination.Slice(8), BitConverter.SingleToInt32Bits(value.z));
			BinaryPrimitives.WriteInt32LittleEndian(destination.Slice(12), BitConverter.SingleToInt32Bits(value.w));
			_position += 16;
			return this;
		}

		public DataWriter Put(Dictionary<string, byte> dict)
		{
			if (dict == null)
			{
				Put(0);
				return this;
			}
			Put(dict.Count);
			foreach (KeyValuePair<string, byte> item in dict)
			{
				Put(item.Key).Put(item.Value);
			}
			return this;
		}

		public DataWriter Put(IReadOnlyList<string> strings)
		{
			if (strings == null)
			{
				Put(0);
				return this;
			}
			Put(strings.Count);
			foreach (string @string in strings)
			{
				Put(@string);
			}
			return this;
		}

		public DataWriter Put(Dictionary<string, string> dict)
		{
			if (dict == null)
			{
				Put(0);
				return this;
			}
			Put(dict.Count);
			foreach (KeyValuePair<string, string> item in dict)
			{
				Put(item.Key).Put(item.Value);
			}
			return this;
		}

		public DataWriter Put<T>(T obj) where T : INetworkSerializable
		{
			obj.Serialize(this);
			return this;
		}

		public DataWriter PutIn<T>(in T obj) where T : struct, INetworkSerializable
		{
			obj.Serialize(this);
			return this;
		}

		public DataWriter Put<T>(IReadOnlyList<T> list) where T : INetworkSerializable
		{
			if (list == null || list.Count == 0)
			{
				Put(0);
				return this;
			}
			Put(list.Count);
			foreach (T item in list)
			{
				item.Serialize(this);
			}
			return this;
		}

		public void EnsureCapacity(int additional)
		{
			if (_position + additional > _buffer.Length)
			{
				byte[] array = _pool.Rent((_position + additional) * 2);
				Array.Copy(_buffer, 0, array, 0, _position);
				_pool.Return(_buffer);
				_buffer = array;
			}
		}

		public void Dispose()
		{
			if (_buffer != null)
			{
				_pool.Return(_buffer);
				_buffer = null;
				_position = 0;
			}
		}
	}
	public interface INetworkSerializable
	{
		void Serialize(DataWriter writer);

		void Deserialize(DataReader reader);
	}
	[Serializable]
	public struct PlayerData : INetworkSerializable
	{
		[Serializable]
		public struct HandData : INetworkSerializable
		{
			public byte handType;

			public byte interactState;

			public float PosX;

			public float PosY;

			public float PosZ;

			public bool handItemUpdate;

			public string itemPrefabName;

			public ulong targetId;

			public float desiredPosX;

			public float desiredPosY;

			public float desiredPosZ;

			public Vector3 Position
			{
				get
				{
					//IL_0012: Unknown result type (might be due to invalid IL or missing references)
					return new Vector3(PosX, PosY, PosZ);
				}
				set
				{
					//IL_0002: Unknown result type (might be due to invalid IL or missing references)
					//IL_000e: 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)
					PosX = value.x;
					PosY = value.y;
					PosZ = value.z;
				}
			}

			public Vector3 DesiredPosition
			{
				get
				{
					//IL_0012: Unknown result type (might be due to invalid IL or missing references)
					return new Vector3(desiredPosX, desiredPosY, desiredPosZ);
				}
				set
				{
					//IL_0002: Unknown result type (might be due to invalid IL or missing references)
					//IL_000e: 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)
					desiredPosX = value.x;
					desiredPosY = value.y;
					desiredPosZ = value.z;
				}
			}

			public void Serialize(DataWriter writer)
			{
				//IL_0010: 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)
				writer.Put(handType);
				writer.Put(Position);
				writer.Put(interactState);
				switch (interactState)
				{
				case 0:
					writer.Put(handItemUpdate);
					if (handItemUpdate)
					{
						writer.Put(itemPrefabName);
					}
					break;
				case 2:
					writer.Put(targetId);
					writer.Put(DesiredPosition);
					break;
				case 4:
					writer.Put(targetId);
					break;
				case 1:
				case 3:
					break;
				}
			}

			public void Deserialize(DataReader reader)
			{
				//IL_000f: 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)
				handType = reader.GetByte();
				Position = reader.GetVector3();
				interactState = reader.GetByte();
				switch (interactState)
				{
				case 0:
					handItemUpdate = reader.GetBool();
					if (handItemUpdate)
					{
						itemPrefabName = reader.GetString();
					}
					else
					{
						itemPrefabName = null;
					}
					break;
				case 2:
					targetId = reader.GetULong();
					DesiredPosition = reader.GetVector3();
					break;
				case 4:
					targetId = reader.GetULong();
					break;
				case 1:
				case 3:
					break;
				}
			}

			public bool IsBeGrabbing(ulong targetPlayerId)
			{
				return interactState == 2 && targetId == targetPlayerId;
			}

			public bool IsBeHanging(ulong targetPlayerId)
			{
				return interactState == 4 && targetId == targetPlayerId;
			}

			public static bool operator ==(HandData left, HandData right)
			{
				if (left.handType != right.handType || left.interactState != right.interactState)
				{
					return false;
				}
				float num = left.PosX - right.PosX;
				float num2 = left.PosY - right.PosY;
				float num3 = left.PosZ - right.PosZ;
				if (num * num + num2 * num2 + num3 * num3 >= 0.0025f)
				{
					return false;
				}
				switch (left.interactState)
				{
				case 0:
					return left.itemPrefabName == right.itemPrefabName;
				case 2:
				{
					if (left.targetId != right.targetId)
					{
						return false;
					}
					float num4 = left.desiredPosX - right.desiredPosX;
					float num5 = left.desiredPosY - right.desiredPosY;
					float num6 = left.desiredPosZ - right.desiredPosZ;
					return num4 * num4 + num5 * num5 + num6 * num6 < 0.0025f;
				}
				case 4:
					return left.targetId == right.targetId;
				default:
					return true;
				}
			}

			public static bool operator !=(HandData left, HandData right)
			{
				return !(left == right);
			}
		}

		private const float POSITION_CHANGE_THRESHOLD_SQR = 0.0025f;

		private const float ROTATION_CHANGE_THRESHOLD_DEG = 0.5f;

		public ulong playId;

		public long TimestampTicks;

		public float PosX;

		public float PosY;

		public float PosZ;

		public float RotX;

		public float RotY;

		public float RotZ;

		public float RotW;

		public HandData LeftHand;

		public HandData RightHand;

		public bool IsTeleport;

		public Vector3 Position
		{
			get
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				return new Vector3(PosX, PosY, PosZ);
			}
			set
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: 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)
				PosX = value.x;
				PosY = value.y;
				PosZ = value.z;
			}
		}

		public Quaternion Rotation
		{
			get
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				return new Quaternion(RotX, RotY, RotZ, RotW);
			}
			set
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: 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_0026: Unknown result type (might be due to invalid IL or missing references)
				RotX = value.x;
				RotY = value.y;
				RotZ = value.z;
				RotW = value.w;
			}
		}

		public void Serialize(DataWriter writer)
		{
			//IL_001b: 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)
			writer.Put(playId).Put(TimestampTicks);
			writer.Put(Position).Put(Rotation);
			writer.PutIn(in LeftHand).PutIn(in RightHand);
			writer.Put(IsTeleport);
		}

		public void Deserialize(DataReader reader)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			playId = reader.GetULong();
			TimestampTicks = reader.GetLong();
			Position = reader.GetVector3();
			Rotation = reader.GetQuaternion();
			reader.GetRef(ref LeftHand);
			reader.GetRef(ref RightHand);
			IsTeleport = reader.GetBool();
		}

		public bool UpdateIfChanged(in PlayerData newData, bool forceUpdate = false)
		{
			//IL_0058: 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)
			if (forceUpdate)
			{
				this = newData;
				return true;
			}
			float num = PosX - newData.PosX;
			float num2 = PosY - newData.PosY;
			float num3 = PosZ - newData.PosZ;
			if (num * num + num2 * num2 + num3 * num3 >= 0.0025f || !IsRotationSimilar(Rotation, newData.Rotation, 0.5f) || LeftHand != newData.LeftHand || RightHand != newData.RightHand)
			{
				this = newData;
				return true;
			}
			return false;
		}

		private static bool IsRotationSimilar(Quaternion a, Quaternion b, float thresholdDegrees)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Cos(thresholdDegrees * (MathF.PI / 180f) * 0.5f);
			float num2 = Mathf.Abs(Quaternion.Dot(a, b));
			return num2 > num;
		}
	}
}
namespace WKMPMod.Component
{
	public class LookAt : MonoBehaviour
	{
		private Camera? mainCamera;

		[Header("锁定大小")]
		public bool maintainScreenSize = true;

		[Header("初始缩放比例")]
		public float baseScale = 0.1f;

		[Header("用户设置缩放比例")]
		public float userScale = 1f;

		private void LateUpdate()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: 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_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)mainCamera == (Object)null)
			{
				mainCamera = Camera.main;
				if ((Object)(object)mainCamera == (Object)null)
				{
					return;
				}
			}
			((Component)this).transform.rotation = ((Component)mainCamera).transform.rotation;
			if (maintainScreenSize)
			{
				float num = Vector3.Distance(((Component)this).transform.position, ((Component)mainCamera).transform.position);
				float num2 = Mathf.Max(num, 0.8f * num + 2f);
				float num3 = num2 * baseScale * userScale;
				Vector3 val = (((Object)(object)((Component)this).transform.parent != (Object)null) ? ((Component)this).transform.parent.lossyScale : Vector3.one);
				float num4 = ((Mathf.Abs(val.x) > 0.0001f) ? val.x : 1f);
				float num5 = ((Mathf.Abs(val.y) > 0.0001f) ? val.y : 1f);
				float num6 = ((Mathf.Abs(val.z) > 0.0001f) ? val.z : 1f);
				((Component)this).transform.localScale = new Vector3(num3 / num4, num3 / num5, num3 / num6);
			}
		}
	}
	public class RemotePlayer : MonoBehaviour
	{
		public ulong playerId;

		[Header("距离设置")]
		[Tooltip("当当前位置与目标位置超过此距离时直接瞬移")]
		public float teleportThreshold = 50f;

		[Tooltip("平滑移动的最大距离限制")]
		public float maxSmoothDistance = 10f;

		private bool _isTeleporting = false;

		private Vector3 _targetPosition;

		private Vector3 _velocity = Vector3.zero;

		private void LateUpdate()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			if (_isTeleporting)
			{
				return;
			}
			float num = Vector3.Distance(((Component)this).transform.position, _targetPosition);
			if (num > teleportThreshold)
			{
				Teleport(_targetPosition);
			}
			else if (((Component)this).transform.position != _targetPosition)
			{
				float num2 = CalculateSmoothTime(num);
				((Component)this).transform.position = Vector3.SmoothDamp(((Component)this).transform.position, _targetPosition, ref _velocity, num2, float.MaxValue, Time.deltaTime);
				if (((Vector3)(ref _velocity)).magnitude < 0.5f && num > 0.05f)
				{
					Vector3 val = _targetPosition - ((Component)this).transform.position;
					Vector3 normalized = ((Vector3)(ref val)).normalized;
					_velocity = normalized * 0.5f;
				}
			}
		}

		private float CalculateSmoothTime(float distance)
		{
			if (distance > maxSmoothDistance)
			{
				return Mathf.Clamp(Mathf.Log(distance) * 0.1f, 0.05f, 0.3f);
			}
			return Mathf.Clamp(distance / 10f, 0.05f, 0.1f);
		}

		public void UpdateFromPlayerData(Vector3 position, Quaternion rotation)
		{
			//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_0015: Unknown result type (might be due to invalid IL or missing references)
			_isTeleporting = false;
			_targetPosition = position;
			((Component)this).transform.rotation = rotation;
		}

		public void UpdateFromPlayerData(ref PlayerData playerData)
		{
			//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_001b: Unknown result type (might be due to invalid IL or missing references)
			_isTeleporting = false;
			_targetPosition = playerData.Position;
			((Component)this).transform.rotation = playerData.Rotation;
		}

		public void Teleport(Vector3 position, Quaternion? rotation = null)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_001d: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			_isTeleporting = true;
			((Component)this).transform.position = position;
			_targetPosition = position;
			_velocity = Vector3.zero;
			if (rotation.HasValue)
			{
				((Component)this).transform.rotation = rotation.Value;
			}
			((MonoBehaviour)this).StartCoroutine(ResetTeleportFlag());
		}

		private IEnumerator ResetTeleportFlag()
		{
			yield return null;
			_isTeleporting = false;
		}
	}
	public class RemoteTag : MonoBehaviour
	{
		private Transform? _cameraTransform;

		private TextMeshPro? _textMeshPro;

		private float _lastUpdateDistance;

		private TickTimer updateTick;

		[Header("Settings")]
		public const float MIN_DISTANCE_LABEL = 10f;

		public const float DISTANCE_CHANGE_THRESHOLD = 1f;

		public const float MESSAGE_TIMEOUT = 15f;

		[Header("Id")]
		public ulong PlayerId;

		[Header("名字")]
		public string PlayerName = "";

		[Header("Message")]
		public string _message = "";

		private Coroutine? _messageTimeoutCoroutine;

		public string Message
		{
			get
			{
				return _message;
			}
			set
			{
				string text = ((value.Length <= 15) ? value : value.Substring(0, 15));
				if (!(_message == text))
				{
					_message = text;
					if (_messageTimeoutCoroutine != null)
					{
						((MonoBehaviour)this).StopCoroutine(_messageTimeoutCoroutine);
					}
					_messageTimeoutCoroutine = ((MonoBehaviour)this).StartCoroutine(MessageTimeoutRoutine());
					RefreshName();
				}
			}
		}

		private void Awake()
		{
			updateTick = new TickTimer(1);
			_textMeshPro = ((Component)this).GetComponent<TextMeshPro>();
			if ((Object)(object)Camera.main != (Object)null)
			{
				_cameraTransform = ((Component)Camera.main).transform;
			}
		}

		private void OnDestroy()
		{
			if (_messageTimeoutCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_messageTimeoutCoroutine);
			}
		}

		private void Update()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			if (!updateTick.TryTick())
			{
				return;
			}
			if ((Object)(object)_cameraTransform == (Object)null)
			{
				if (!((Object)(object)Camera.main != (Object)null))
				{
					Debug.LogError((object)"[MP RemoteTag]No main camera found");
					return;
				}
				_cameraTransform = ((Component)Camera.main).transform;
			}
			float num = Vector3.Distance(((Component)this).transform.position, _cameraTransform.position);
			if (Mathf.Abs(num - _lastUpdateDistance) >= 1f)
			{
				RefreshName(num);
			}
		}

		public void Initialize(ulong playerId, string playerName)
		{
			PlayerId = playerId;
			PlayerName = playerName;
		}

		public void RefreshName()
		{
			//IL_001a: 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)
			if (!((Object)(object)_cameraTransform == (Object)null))
			{
				RefreshName(Vector3.Distance(((Component)this).transform.position, _cameraTransform.position));
			}
		}

		private void RefreshName(float currentDistance)
		{
			_lastUpdateDistance = currentDistance;
			if (!((Object)(object)_textMeshPro == (Object)null))
			{
				string text = currentDistance.ToString("F0");
				if (currentDistance < 10f)
				{
					((TMP_Text)_textMeshPro).text = (string.IsNullOrEmpty(_message) ? PlayerName : (PlayerName + "\n" + _message));
					return;
				}
				((TMP_Text)_textMeshPro).text = (string.IsNullOrEmpty(_message) ? (PlayerName + " (" + text + "m)") : (PlayerName + " (" + text + "m)\n" + _message));
			}
		}

		private IEnumerator MessageTimeoutRoutine()
		{
			yield return (object)new WaitForSeconds(15f);
			_message = "";
			RefreshName();
			_messageTimeoutCoroutine = null;
		}
	}
	public class SimpleArmIK : MonoBehaviour
	{
		[Header("目标设置")]
		public Transform? target;

		public float originalLength = 1f;

		[Header("限制")]
		public float minScale = 0.1f;

		public float maxScale = 10f;

		private void Start()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if (originalLength <= 0f && (Object)(object)target != (Object)null)
			{
				originalLength = Vector3.Distance(((Component)this).transform.position, target.position);
			}
		}

		private void LateUpdate()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)target == (Object)null))
			{
				Vector3 val = ((Component)this).transform.parent.InverseTransformPoint(((Component)this).transform.position);
				Vector3 val2 = ((Component)this).transform.parent.InverseTransformPoint(target.position);
				Vector3 val3 = val2 - val;
				float magnitude = ((Vector3)(ref val3)).magnitude;
				if (!(magnitude < 0.0001f))
				{
					((Component)this).transform.localRotation = Quaternion.FromToRotation(Vector3.up, val3);
					float num = magnitude / originalLength;
					num = Mathf.Clamp(num, minScale, maxScale);
					((Component)this).transform.localScale = new Vector3(1f, num, 1f);
				}
			}
		}
	}
}
namespace WKMPModa.Shared.Data
{
	[Serializable]
	public struct ItemPoseData
	{
		[Header("物品相对于手的 Transform")]
		public Vector3 itemPosition;

		public Quaternion itemRotation;

		public Vector3 itemScale;

		[Header("拿持该物品时手部的姿态偏置")]
		public Quaternion handRotationOffset;

		public static ItemPoseData Default => new ItemPoseData(Vector3.zero, Quaternion.identity, Vector3.one, Quaternion.identity);

		public ItemPoseData(Vector3 pos, Quaternion rot, Vector3 scale, Quaternion handRot)
		{
			//IL_0002: 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_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: 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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			itemPosition = pos;
			itemRotation = rot;
			itemScale = scale;
			handRotationOffset = handRot;
		}
	}
}
namespace WKMPModa.Shared.Component
{
	public abstract class CustomModelBehaviour : MonoBehaviour
	{
		public virtual Dictionary<string, ItemPoseData> HandItemTransform { get; }

		public virtual void OnPrefabLoaded()
		{
		}

		public virtual void ApplyPlayerColor(Color32 color)
		{
		}

		public virtual void SetCrouching(bool isCrouching)
		{
		}

		public virtual void HandlePlayerData(Dictionary<string, string> playerData)
		{
		}
	}
	public class DefaultModelBehaviour : CustomModelBehaviour
	{
		private static Dictionary<string, ItemPoseData> _handItemTransform;

		public static readonly Quaternion HAND_ROT;

		public static readonly ItemPoseData HAMMER_TRANSFROM;

		public static readonly ItemPoseData BARNACLE_HOOK_TRANSFROM;

		public static readonly ItemPoseData HANDGUN_TRANSFROM;

		public static readonly ItemPoseData BOXED_FOOD_TRANSFROM;

		public static readonly ItemPoseData BEANS_TRANSFROM;

		public static readonly ItemPoseData FOOD_TRANSFROM;

		public static readonly ItemPoseData COCOA_TRANSFROM;

		public static readonly ItemPoseData REBAR_TRANSFROM;

		public static readonly ItemPoseData PITON_TRANSFROM;

		public static readonly ItemPoseData BLINK_EYE_TRANSFROM;

		public static readonly ItemPoseData ROACH_TRANSFROM;

		public static readonly ItemPoseData GRUB_TRANSFROM;

		public static readonly ItemPoseData FLOPPY_TRANSFROM;

		public static readonly ItemPoseData NOTE_TRANSFROM;

		private static readonly string[] TintColorProperties;

		[SerializeField]
		internal Renderer[] _tintRenderers;

		public override Dictionary<string, ItemPoseData> HandItemTransform => _handItemTransform;

		static DefaultModelBehaviour()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: 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_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: 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_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_0386: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0451: Unknown result type (might be due to invalid IL or missing references)
			//IL_0456: Unknown result type (might be due to invalid IL or missing references)
			//IL_047b: Unknown result type (might be due to invalid IL or missing references)
			//IL_048f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0494: Unknown result type (might be due to invalid IL or missing references)
			//IL_049e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_050b: Unknown result type (might be due to invalid IL or missing references)
			//IL_051f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0524: Unknown result type (might be due to invalid IL or missing references)
			//IL_0529: Unknown result type (might be due to invalid IL or missing references)
			//IL_053f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0553: Unknown result type (might be due to invalid IL or missing references)
			//IL_0558: Unknown result type (might be due to invalid IL or missing references)
			//IL_055d: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_06cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0719: Unknown result type (might be due to invalid IL or missing references)
			//IL_072d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0732: Unknown result type (might be due to invalid IL or missing references)
			//IL_0737: Unknown result type (might be due to invalid IL or missing references)
			//IL_075c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0770: Unknown result type (might be due to invalid IL or missing references)
			//IL_0775: Unknown result type (might be due to invalid IL or missing references)
			//IL_077a: Unknown result type (might be due to invalid IL or missing references)
			//IL_079f: Unknown result type (might be due to invalid IL or missing references)
			//IL_07b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_07b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_07ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0800: Unknown result type (might be due to invalid IL or missing references)
			//IL_0805: Unknown result type (might be due to invalid IL or missing references)
			//IL_080a: Unknown result type (might be due to invalid IL or missing references)
			//IL_082f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0843: Unknown result type (might be due to invalid IL or missing references)
			//IL_0848: Unknown result type (might be due to invalid IL or missing references)
			//IL_0852: Unknown result type (might be due to invalid IL or missing references)
			//IL_0857: Unknown result type (might be due to invalid IL or missing references)
			//IL_087c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0890: Unknown result type (might be due to invalid IL or missing references)
			//IL_0895: Unknown result type (might be due to invalid IL or missing references)
			//IL_089a: Unknown result type (might be due to invalid IL or missing references)
			//IL_08e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_08f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_08fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0924: Unknown result type (might be due to invalid IL or missing references)
			//IL_0938: Unknown result type (might be due to invalid IL or missing references)
			//IL_093d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0942: Unknown result type (might be due to invalid IL or missing references)
			//IL_0967: Unknown result type (might be due to invalid IL or missing references)
			//IL_097b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0980: Unknown result type (might be due to invalid IL or missing references)
			//IL_0985: Unknown result type (might be due to invalid IL or missing references)
			//IL_09aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_09be: Unknown result type (might be due to invalid IL or missing references)
			//IL_09c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_09c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_09ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a01: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a06: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a0b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a30: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a44: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a49: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a53: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a58: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a7d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a91: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a96: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a9b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bbf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bd3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bd8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bdd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c24: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c38: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c3d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c42: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c67: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c7b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c80: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c85: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c9b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0caf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0cb4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0cbe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0cc3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ce8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0cfc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d01: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d06: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d5e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d72: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d86: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d8b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0db0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0dc4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0dc9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0dce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0df3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e07: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e0c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e11: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e36: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e4a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e4f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e54: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e79: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e8d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e92: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e97: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ecd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ee1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ee6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0eeb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f10: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f24: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f29: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f2e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f53: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f67: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f6c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f71: Unknown result type (might be due to invalid IL or missing references)
			//IL_0fa7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0fbb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0fcf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0fd4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ff9: Unknown result type (might be due to invalid IL or missing references)
			//IL_100d: Unknown result type (might be due to invalid IL or missing references)
			//IL_1012: Unknown result type (might be due to invalid IL or missing references)
			//IL_1017: Unknown result type (might be due to invalid IL or missing references)
			//IL_103c: Unknown result type (might be due to invalid IL or missing references)
			//IL_1050: Unknown result type (might be due to invalid IL or missing references)
			//IL_1055: Unknown result type (might be due to invalid IL or missing references)
			//IL_105a: Unknown result type (might be due to invalid IL or missing references)
			//IL_107f: Unknown result type (might be due to invalid IL or missing references)
			//IL_1093: Unknown result type (might be due to invalid IL or missing references)
			//IL_1098: Unknown result type (might be due to invalid IL or missing references)
			//IL_109d: Unknown result type (might be due to invalid IL or missing references)
			//IL_10c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_10d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_10ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_10ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_1114: Unknown result type (might be due to invalid IL or missing references)
			//IL_1128: Unknown result type (might be due to invalid IL or missing references)
			//IL_112d: Unknown result type (might be due to invalid IL or missing references)
			//IL_1132: Unknown result type (might be due to invalid IL or missing references)
			HAND_ROT = Quaternion.Euler(0f, 315f, 0f);
			HAMMER_TRANSFROM = new ItemPoseData(new Vector3(0f, 0.2f, 0f), Quaternion.Euler(270f, 90f, 0f), Vector3.one, HAND_ROT);
			BARNACLE_HOOK_TRANSFROM = new ItemPoseData(new Vector3(0f, 0f, 0.1f), Quaternion.identity, Vector3.one, HAND_ROT);
			HANDGUN_TRANSFROM = new ItemPoseData(new Vector3(0f, 0.2f, 0.2f), Quaternion.Euler(0f, 180f, 90f), Vector3.one, HAND_ROT);
			BOXED_FOOD_TRANSFROM = new ItemPoseData(new Vector3(0f, 0.2f, 0f), Quaternion.Euler(0f, 45f, 0f), Vector3.one, HAND_ROT);
			BEANS_TRANSFROM = new ItemPoseData(new Vector3(0f, 0.2f, 0f), Quaternion.Euler(0f, 225f, 0f), Vector3.one, HAND_ROT);
			FOOD_TRANSFROM = new ItemPoseData(new Vector3(0f, 0.2f, 0f), Quaternion.Euler(270f, 0f, 0f), Vector3.one, HAND_ROT);
			COCOA_TRANSFROM = new ItemPoseData(new Vector3(-0.2f, 0f, 0f), Quaternion.Euler(0f, 180f, 0f), Vector3.one, HAND_ROT);
			REBAR_TRANSFROM = new ItemPoseData(new Vector3(0f, 0.3f, 0f), Quaternion.Euler(90f, 270f, 0f), Vector3.one, HAND_ROT);
			PITON_TRANSFROM = new ItemPoseData(Vector3.zero, Quaternion.Euler(270f, 180f, 0f), Vector3.one * 1.2f, HAND_ROT);
			BLINK_EYE_TRANSFROM = new ItemPoseData(new Vector3(0f, 0.2f, 0f), Quaternion.Euler(0f, 180f, 0f), Vector3.one, HAND_ROT);
			ROACH_TRANSFROM = new ItemPoseData(new Vector3(0f, 0.1f, 0.1f), Quaternion.Euler(315f, 0f, 0f), Vector3.one, HAND_ROT);
			GRUB_TRANSFROM = new ItemPoseData(new Vector3(-0.1f, 0.1f, 0f), Quaternion.Euler(0f, 0f, 270f), Vector3.one, HAND_ROT);
			FLOPPY_TRANSFROM = new ItemPoseData(new Vector3(0f, 0.2f, 0f), Quaternion.Euler(270f, 0f, 0f), Vector3.one, HAND_ROT);
			NOTE_TRANSFROM = new ItemPoseData(new Vector3(0f, 0.3f, 0f), Quaternion.Euler(270f, 0f, 0f), Vector3.one, HAND_ROT);
			TintColorProperties = new string[3] { "_BaseColor", "_Color", "_MainColor" };
			_handItemTransform = new Dictionary<string, ItemPoseData>
			{
				{
					"None",
					new ItemPoseData(Vector3.zero, Quaternion.identity, Vector3.one, HAND_ROT)
				},
				{ "Item_Hammer", HAMMER_TRANSFROM },
				{ "Item_BanHammer", HAMMER_TRANSFROM },
				{ "Item_Pipewrench", HAMMER_TRANSFROM },
				{ "Item_Hammer_Cosmetic_Wrench", HAMMER_TRANSFROM },
				{ "Item_BarnacleHook", BARNACLE_HOOK_TRANSFROM },
				{ "Item_BarnacleHook_Infinite", BARNACLE_HOOK_TRANSFROM },
				{ "Item_Handgun", HANDGUN_TRANSFROM },
				{ "Item_Handgun_Debug", HANDGUN_TRANSFROM },
				{
					"Item_10mm_Ammo",
					new ItemPoseData(new Vector3(0f, 0.3f, 0f), Quaternion.Euler(270f, 270f, 0f), Vector3.one, HAND_ROT)
				},
				{
					"Item_Injector",
					new ItemPoseData(new Vector3(0f, -0.1f, 0f), Quaternion.Euler(270f, 90f, 0f), Vector3.one * 1.3f, HAND_ROT)
				},
				{
					"Item_Pillbottle",
					new ItemPoseData(new Vector3(0f, 0.2f, 0f), Quaternion.Euler(270f, 0f, 0f), Vector3.one, HAND_ROT)
				},
				{
					"Item_Food_Fruit",
					new ItemPoseData(new Vector3(0.2f, 0f, 0f), Quaternion.Euler(0f, 90f, 270f), Vector3.one, HAND_ROT)
				},
				{
					"Item_Food_Meat",
					new ItemPoseData(Vector3.zero, Quaternion.Euler(0f, 90f, 270f), Vector3.one, HAND_ROT)
				},
				{ "Item_Wine", BOXED_FOOD_TRANSFROM },
				{ "Item_Wine_Empty", BOXED_FOOD_TRANSFROM },
				{ "Item_Milk", BOXED_FOOD_TRANSFROM },
				{ "Item_Milk_Empty", BOXED_FOOD_TRANSFROM },
				{ "Item_Milk_Rho", BOXED_FOOD_TRANSFROM },
				{ "Item_Beans", BEANS_TRANSFROM },
				{ "Item_Beans_Eaten", BEANS_TRANSFROM },
				{ "Item_Beans_Periphery", BEANS_TRANSFROM },
				{ "Item_Food_Bar", FOOD_TRANSFROM },
				{ "Item_Food_Cookie", FOOD_TRANSFROM },
				{ "Item_Cocoa_Full", COCOA_TRANSFROM },
				{ "Item_Cocoa_Empty", COCOA_TRANSFROM },
				{ "Item_Rebar_Explosive", REBAR_TRANSFROM },
				{ "Item_RebarRope", REBAR_TRANSFROM },
				{ "Item_RebarRope_Holiday", REBAR_TRANSFROM },
				{ "Item_Rebar", REBAR_TRANSFROM },
				{ "Item_Rebar_Holiday", REBAR_TRANSFROM },
				{ "Item_Rebar_Bone", REBAR_TRANSFROM },
				{
					"Item_AutoPiton",
					new ItemPoseData(new Vector3(0f, 0f, 0.2f), Quaternion.Euler(0f, 180f, 0f), Vector3.one, HAND_ROT)
				},
				{ "Item_Piton", PITON_TRANSFROM },
				{ "Item_Piton_Holiday", PITON_TRANSFROM },
				{
					"Item_Rubble",
					new ItemPoseData(new Vector3(0f, 0.15f, 0f), Quaternion.Euler(90f, 0f, 0f), Vector3.one, HAND_ROT)
				},
				{
					"Item_Flaregun",
					new ItemPoseData(new Vector3(0f, 0.1f, 0.1f), Quaternion.Euler(90f, 0f, 0f), Vector3.one, HAND_ROT)
				},
				{
					"Item_Flaregun_Ammo",
					new ItemPoseData(new Vector3(0f, 0.2f, 0f), Quaternion.Euler(90f, 90f, 0f), Vector3.one * 1.2f, HAND_ROT)
				},
				{
					"Item_Flashlight",
					new ItemPoseData(new Vector3(0f, 0.2f, 0f), Quaternion.Euler(90f, 0f, 0f), Vector3.one, HAND_ROT)
				},
				{
					"Item_RhoStone",
					new ItemPoseData(new Vector3(0f, 0.2f, 0f), Quaternion.Euler(270f, 0f, 0f), Vector3.one * 1.2f, HAND_ROT)
				},
				{
					"Item_Cleaver",
					new ItemPoseData(new Vector3(0f, 0.4f, 0.1f), Quaternion.Euler(270f, 270f, 0f), Vector3.one, HAND_ROT)
				},
				{ "Item_BlinkEye", BLINK_EYE_TRANSFROM },
				{ "Item_BlinkEye_Marionette", BLINK_EYE_TRANSFROM },
				{
					"Item_Artifact_Translocator",
					new ItemPoseData(new Vector3(0f, 0.1f, 0.3f), Quaternion.Euler(270f, 0f, 0f), Vector3.one, HAND_ROT)
				},
				{
					"Item_Artifact_Rapier",
					new ItemPoseData(new Vector3(0f, 0.1f, 0f), Quaternion.Euler(270f, 90f, 0f), Vector3.one, HAND_ROT)
				},
				{
					"Item_Artifact_Rebar_Return",
					new ItemPoseData(new Vector3(0f, 0.3f, 0f), Quaternion.Euler(270f, 180f, 0f), Vector3.one, HAND_ROT)
				},
				{
					"Item_Artifact_Timepiece",
					new ItemPoseData(new Vector3(0f, 0.2f, 0f), Quaternion.Euler(270f, 0f, 0f), Vector3.one, HAND_ROT)
				},
				{
					"Item_Artifact_Remote",
					new ItemPoseData(new Vector3(0f, 0.15f, 0.15f), Quaternion.Euler(315f, 0f, 0f), Vector3.one, HAND_ROT)
				},
				{
					"Item_Artifact_EVAGlove",
					new ItemPoseData(new Vector3(0f, 0f, -0.2f), Quaternion.Euler(0f, 0f, 0f), Vector3.one * 1.2f, Quaternion.identity)
				},
				{
					"Denizen_Roach_Flying_Ruby",
					new ItemPoseData(new Vector3(0f, 0.1f, 0.1f), Quaternion.Euler(0f, 180f, 0f), Vector3.one, HAND_ROT)
				},
				{ "Denizen_Roach_Platinum", ROACH_TRANSFROM },
				{ "Denizen_Roach_Platinum_Navmesh", ROACH_TRANSFROM },
				{ "Denizen_Roach_Gold", ROACH_TRANSFROM },
				{ "Denizen_Roach_Gold_Navmesh", ROACH_TRANSFROM },
				{ "Denizen_Roach_Lemon", ROACH_TRANSFROM },
				{ "Denizen_SlugGrub", GRUB_TRANSFROM },
				{ "Denizen_SlugGrub_Christmas", GRUB_TRANSFROM },
				{ "Denizen_SlugGrub_Sam", GRUB_TRANSFROM },
				{ "Item_Floppy_T1", FLOPPY_TRANSFROM },
				{ "Item_Floppy_T2", FLOPPY_TRANSFROM },
				{ "Item_Floppy_T3", FLOPPY_TRANSFROM },
				{ "Item_Floppy_Variant", FLOPPY_TRANSFROM },
				{ "Item_Floppy_Test", FLOPPY_TRANSFROM },
				{ "Item_Floppy_T1_Notes", FLOPPY_TRANSFROM },
				{ "Item_Floppy_Lost", FLOPPY_TRANSFROM },
				{
					"Item_EntityScanner",
					new ItemPoseData(new Vector3(0f, 0f, 0.25f), Quaternion.Euler(90f, 90f, 0f), Vector3.one, HAND_ROT)
				},
				{ "Item_CandyCauldron", BLINK_EYE_TRANSFROM },
				{ "Item_CandyCauldron_Empty", BLINK_EYE_TRANSFROM },
				{
					"Item_Cryogun",
					new ItemPoseData(new Vector3(0f, 0.1f, 0.2f), Quaternion.Euler(270f, 180f, 0f), Vector3.one, HAND_ROT)
				},
				{
					"Item_Powercell",
					new ItemPoseData(new Vector3(0f, 0f, 0.1f), Quaternion.Euler(270f, 90f, 0f), Vector3.one, HAND_ROT)
				},
				{
					"Item_Inoculator",
					new ItemPoseData(Vector3.zero, Quaternion.Euler(270f, 90f, 0f), Vector3.one * 1.3f, HAND_ROT)
				},
				{
					"Item_Bandage",
					new ItemPoseData(new Vector3(0f, 0.2f, 0f), Quaternion.Euler(0f, 90f, 90f), Vector3.one, HAND_ROT)
				},
				{ "Item_Note_01", NOTE_TRANSFROM },
				{ "Item_Note_03_Torn", NOTE_TRANSFROM },
				{ "Item_Note_02_Bloody", NOTE_TRANSFROM },
				{
					"Item_Radio",
					new ItemPoseData(new Vector3(0f, 0.3f, 0f), Quaternion.Euler(270f, 0f, 0f), new Vector3(-1f, 1f, 1f), HAND_ROT)
				},
				{
					"Item_Rope",
					new ItemPoseData(new Vector3(0f, 0.1f, 0f), Quaternion.Euler(0f, 45f, 0f), Vector3.one, HAND_ROT)
				},
				{
					"Item_Temp",
					new ItemPoseData(new Vector3(0f, 0.4f, 0f), Quaternion.Euler(45f, 45f, 45f), Vector3.one, HAND_ROT)
				},
				{
					"Item_Trinket_Base",
					new ItemPoseData(new Vector3(0f, 0.4f, 0f), Quaternion.Euler(45f, 45f, 45f), Vector3.one, HAND_ROT)
				},
				{
					"Item_Trinket_Helmet",
					new ItemPoseData(new Vector3(-0.2f, 0.1f, 0.3f), Quaternion.Euler(270f, 180f, 0f), Vector3.one, HAND_ROT)
				},
				{ "Item_Trinket_CalmingBuddy", FLOPPY_TRANSFROM },
				{
					"Item_Trinket_Nugget",
					new ItemPoseData(new Vector3(0f, 0.2f, 0f), Quaternion.Euler(0f, 90f, 0f), Vector3.one, HAND_ROT)
				},
				{
					"Item_Trinket_Carabiner",
					new ItemPoseData(new Vector3(0f, 0.15f, 0f), Quaternion.Euler(0f, 0f, 0f), Vector3.one, HAND_ROT)
				},
				{
					"Item_Trinket_PhotoOfHome",
					new ItemPoseData(new Vector3(0f, 0.2f, 0f), Quaternion.Euler(270f, 180f, 0f), Vector3.one, HAND_ROT)
				},
				{ "Item_Trinket_EmployeeID", FLOPPY_TRANSFROM },
				{
					"Item_Trinket_Chalk",
					new ItemPoseData(new Vector3(0f, 0.2f, 0f), Quaternion.Euler(315f, 0f, 0f), new Vector3(-1f, 1f, 1f), HAND_ROT)
				},
				{
					"Item_Trinket_Headlamp",
					new ItemPoseData(new Vector3(0f, 0.15f, 0f), Quaternion.Euler(315f, 180f, 0f), Vector3.one, HAND_ROT)
				},
				{
					"Item_Trinket_MassDamper",
					new ItemPoseData(new Vector3(0f, 0.15f, -0.1f), Quaternion.Euler(0f, 270f, 0f), Vector3.one, HAND_ROT)
				},
				{
					"Item_Trinket_MoonRock",
					new ItemPoseData(new Vector3(0f, 0.2f, 0f), Quaternion.Euler(270f, 270f, 0f), Vector3.one, HAND_ROT)
				},
				{
					"Item_Trinket_Beta",
					new ItemPoseData(new Vector3(-0.1f, 0.2f, 0f), Quaternion.Euler(270f, 0f, 0f), new Vector3(-1f, 1f, 1f), HAND_ROT)
				},
				{
					"Item_Trinket_ClimbingShoes",
					new ItemPoseData(new Vector3(0f, 0.1f, 0f), Quaternion.Euler(0f, 0f, 90f), Vector3.one, HAND_ROT)
				}
			};
		}

		public override void OnPrefabLoaded()
		{
			List<Renderer> list = new List<Renderer>();
			Renderer[] componentsInChildren = ((Component)this).gameObject.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!Object.op_Implicit((Object)(object)((Component)val).GetComponent<TMP_Text>()))
				{
					list.Add(val);
				}
			}
			_tintRenderers = list.ToArray();
		}

		public override void ApplyPlayerColor(Color32 color)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			Renderer[] tintRenderers = _tintRenderers;
			foreach (Renderer val in tintRenderers)
			{
				Color val2 = (((Object)((Component)val).gameObject).name.StartsWith("Eyes") ? GetContrastColor(Color32.op_Implicit(color)) : Color32.op_Implicit(color));
				Material[] materials = val.materials;
				foreach (Material val3 in materials)
				{
					if ((Object)(object)val3 == (Object)null)
					{
						continue;
					}
					string[] tintColorProperties = TintColorProperties;
					foreach (string text in tintColorProperties)
					{
						if (val3.HasProperty(text))
						{
							Color color2 = val3.GetColor(text);
							val3.SetColor(text, new Color(val2.r, val2.g, val2.b, (float)(int)(byte)Mathf.Clamp(Mathf.RoundToInt(color2.a * 255f), 0, 255)));
						}
					}
				}
			}
		}

		private static Color GetContrastColor(Color color)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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)
			float num = 0.299f * color.r + 0.587f * color.g + 0.114f * color.b;
			return (num > 0.5f) ? Color.black : Color.white;
		}

		public override void SetCrouching(bool isCrouching)
		{
		}

		public override void HandlePlayerData(Dictionary<string, string> playerData)
		{
		}
	}
	public class SlugcatModelBehaviour : CustomModelBehaviour
	{
		private static Dictionary<string, ItemPoseData> _handItemTransform;

		public static readonly Quaternion HAND_ROT;

		public static readonly ItemPoseData HAMMER_TRANSFROM;

		public static readonly ItemPoseData BARNACLE_HOOK_TRANSFROM;

		public static readonly ItemPoseData HANDGUN_TRANSFROM;

		public static readonly ItemPoseData BOXED_FOOD_TRANSFROM;

		public static readonly ItemPoseData BEANS_TRANSFROM;

		public static readonly ItemPoseData FOOD_TRANSFROM;

		public static readonly ItemPoseData COCOA_TRANSFROM;

		public static readonly ItemPoseData REBAR_TRANSFROM;

		public static readonly ItemPoseData PITON_TRANSFROM;

		public static readonly ItemPoseData BLINK_EYE_TRANSFROM;

		public static readonly ItemPoseData ROACH_TRANSFROM;

		public static readonly ItemPoseData GRUB_TRANSFROM;

		public static readonly ItemPoseData FLOPPY_TRANSFROM;

		public static readonly ItemPoseData NOTE_TRANSFROM;

		private static readonly string[] TintColorProperties;

		[SerializeField]
		internal GameObject _gasMask;

		[SerializeField]
		internal GameObject _gearedUp;

		internal Dictionary<string, List<GameObject>> _itemGroups = new Dictionary<string, List<GameObject>>();

		[SerializeField]
		internal Renderer[] _tintRenderers;

		public override Dictionary<string, ItemPoseData> HandItemTransform => _handItemTransform;

		static SlugcatModelBehaviour()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: 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_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: 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_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_0386: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0451: Unknown result type (might be due to invalid IL or missing references)
			//IL_0456: Unknown result type (might be due to invalid IL or missing references)
			//IL_047b: Unknown result type (might be due to invalid IL or missing references)
			//IL_048f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0494: Unknown result type (might be due to invalid IL or missing references)
			//IL_049e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_050b: Unknown result type (might be due to invalid IL or missing references)
			//IL_051f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0524: Unknown result type (might be due to invalid IL or missing references)
			//IL_0529: Unknown result type (might be due to invalid IL or missing references)
			//IL_053f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0553: Unknown result type (might be due to invalid IL or missing references)
			//IL_0558: Unknown result type (might be due to invalid IL or missing references)
			//IL_055d: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_06cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0719: Unknown result type (might be due to invalid IL or missing references)
			//IL_072d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0732: Unknown result type (might be due to invalid IL or missing references)
			//IL_0737: Unknown result type (might be due to invalid IL or missing references)
			//IL_075c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0770: Unknown result type (might be due to invalid IL or missing references)
			//IL_0775: Unknown result type (might be due to invalid IL or missing references)
			//IL_077a: Unknown result type (might be due to invalid IL or missing references)
			//IL_079f: Unknown result type (might be due to invalid IL or missing references)
			//IL_07b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_07b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_07ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0800: Unknown result type (might be due to invalid IL or missing references)
			//IL_0805: Unknown result type (might be due to invalid IL or missing references)
			//IL_080a: Unknown result type (might be due to invalid IL or missing references)
			//IL_082f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0843: Unknown result type (might be due to invalid IL or missing references)
			//IL_0848: Unknown result type (might be due to invalid IL or missing references)
			//IL_0852: Unknown result type (might be due to invalid IL or missing references)
			//IL_0857: Unknown result type (might be due to invalid IL or missing references)
			//IL_087c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0890: Unknown result type (might be due to invalid IL or missing references)
			//IL_0895: Unknown result type (might be due to invalid IL or missing references)
			//IL_089a: Unknown result type (might be due to invalid IL or missing references)
			//IL_08e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_08f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_08fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0924: Unknown result type (might be due to invalid IL or missing references)
			//IL_0938: Unknown result type (might be due to invalid IL or missing references)
			//IL_093d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0942: Unknown result type (might be due to invalid IL or missing references)
			//IL_0967: Unknown result type (might be due to invalid IL or missing references)
			//IL_097b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0980: Unknown result type (might be due to invalid IL or missing references)
			//IL_0985: Unknown result type (might be due to invalid IL or missing references)
			//IL_09aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_09be: Unknown result type (might be due to invalid IL or missing references)
			//IL_09c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_09c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_09ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a01: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a06: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a0b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a30: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a44: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a49: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a53: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a58: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a7d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a91: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a96: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a9b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bbf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bd3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bd8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bdd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c24: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c38: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c3d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c42: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c67: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c7b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c80: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c85: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c9b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0caf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0cb4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0cbe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0cc3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ce8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0cfc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d01: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d06: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d5e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d72: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d86: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d8b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0db0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0dc4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0dc9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0dce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0df3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e07: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e0c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e11: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e36: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e4a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e4f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e54: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e79: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e8d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e92: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e97: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ecd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ee1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ee6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0eeb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f10: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f24: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f29: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f2e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f53: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f67: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f6c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f71: Unknown result type (might be due to invalid IL or missing references)
			//IL_0fa7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0fbb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0fcf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0fd4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ff9: Unknown result type (might be due to invalid IL or missing references)
			//IL_100d: Unknown result type (might be due to invalid IL or missing references)
			//IL_1012: Unknown result type (might be due to invalid IL or missing references)
			//IL_1017: Unknown result type (might be due to invalid IL or missing references)
			//IL_103c: Unknown result type (might be due to invalid IL or missing references)
			//IL_1050: Unknown result type (might be due to invalid IL or missing references)
			//IL_1055: Unknown result type (might be due to invalid IL or missing references)
			//IL_105a: Unknown result type (might be due to invalid IL or missing references)
			//IL_107f: Unknown result type (might be due to invalid IL or missing references)
			//IL_1093: Unknown result type (might be due to invalid IL or missing references)
			//IL_1098: Unknown result type (might be due to invalid IL or missing references)
			//IL_109d: Unknown result type (might be due to invalid IL or missing references)
			//IL_10c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_10d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_10ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_10ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_1114: Unknown result type (might be due to invalid IL or missing references)
			//IL_1128: Unknown result type (might be due to invalid IL or missing references)
			//IL_112d: Unknown result type (might be due to invalid IL or missing references)
			//IL_1132: Unknown result type (might be due to invalid IL or missing references)
			HAND_ROT = Quaternion.Euler(0f, 330f, 0f);
			HAMMER_TRANSFROM = new ItemPoseData(new Vector3(0f, 0.2f, 0f), Quaternion.Euler(270f, 90f, 0f), Vector3.one, HAND_ROT);
			BARNACLE_HOOK_TRANSFROM = new ItemPoseData(new Vector3(0f, 0f, 0.1f), Quaternion.identity, Vector3.one, HAND_ROT);
			HANDGUN_TRANSFROM = new ItemPoseData(new Vector3(0f, 0.2f, 0.2f), Quaternion.Euler(0f, 180f, 90f), Vector3.one, HAND_ROT);
			BOXED_FOOD_TRANSFROM = new ItemPoseData(new Vector3(0f, 0.2f, 0f), Quaternion.Euler(0f, 45f, 0f), Vector3.one, HAND_ROT);
			BEANS_TRANSFROM = new ItemPoseData(new Vector3(0f, 0.2f, 0f), Quaternion.Euler(0f, 225f, 0f), Vector3.one, HAND_ROT);
			FOOD_TRANSFROM = new ItemPoseData(new Vector3(0f, 0.2f, 0f), Quaternion.Euler(270f, 0f, 0f), Vector3.one, HAND_ROT);
			COCOA_TRANSFROM = new ItemPoseDa