Decompiled source of Simple Multi Player v1.6.1

WKMultiPlayerMod.dll

Decompiled 5 days 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.Threading.Tasks;
using BepInEx;
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 UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
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.RemotePlayer;
using WKMPMod.UI;
using WKMPMod.Util;
using WKMPMod.World;

[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.5.7.0")]
[assembly: AssemblyInformationalVersion("1.5.7+378689d40c0165cb73dd7cb4cbfb68f694489001")]
[assembly: AssemblyProduct("WKMultiPlayerMod")]
[assembly: AssemblyTitle("WKMultiPlayerMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.5.7.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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
	}
	public static class ClimbableItemSyncManager
	{
		private const float PeriodicUpdateInterval = 0.15f;

		private const float PositionEpsilonSqr = 0.0004f;

		private const float RotationEpsilon = 0.5f;

		private const float SecureAmountEpsilon = 0.01f;

		private const string CLONE_SUFFIX = "(Clone)";

		public static Stopwatch sw = new Stopwatch();

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

		private static readonly Dictionary<string, NetworkedClimableItem> _pitons = new Dictionary<string, NetworkedClimableItem>();

		private static readonly Dictionary<string, GameObject> _prefabLookup = new Dictionary<string, GameObject>(StringComparer.OrdinalIgnoreCase);

		private static readonly FieldInfo _projectileSourceEntityField = typeof(Projectile).GetField("sourceEntity", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static ulong _nextLocalId = 1uL;

		public static bool ApplyingRemoteState { get; private set; }

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

		public static HashSet<int> CaptureExistingHandholds()
		{
			HashSet<int> hashSet = new HashSet<int>();
			CL_Handhold[] array = Object.FindObjectsOfType<CL_Handhold>();
			foreach (CL_Handhold val in array)
			{
				GameObject climbableRoot = GetClimbableRoot(((Object)(object)val != (Object)null) ? ((Component)val).gameObject : null);
				if ((Object)(object)climbableRoot != (Object)null)
				{
					hashSet.Add(((Object)climbableRoot).GetInstanceID());
				}
			}
			return hashSet;
		}

		public static void RegisterNewLocalPiton(HandItem_Piton source, HashSet<int> knownHandholds)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			if (MPCore.CanSync && !ApplyingRemoteState && !((Object)(object)source == (Object)null) && knownHandholds != null && !((Object)(object)source.pitonWorldObject == (Object)null))
			{
				string text = NormalizePrefabKey(((Object)source.pitonWorldObject).name);
				RaycastHit aimCircleHit = ((HandItem)source).GetAimCircleHit();
				GameObject root = FindBestNewClimbable(((RaycastHit)(ref aimCircleHit)).point, knownHandholds, text, null);
				RegisterLocalClimbable(root, text);
			}
		}

		public static void RegisterNewLocalPiton(HandItem_Piton source)
		{
			if (!MPCore.CanSync || ApplyingRemoteState || (Object)(object)source == (Object)null || CapturedPitons.Count == 0)
			{
				CapturedPitons.Clear();
				return;
			}
			foreach (GameObject capturedPiton in CapturedPitons)
			{
				GameObject climbableRoot = GetClimbableRoot(capturedPiton);
				if (!((Object)(object)climbableRoot == (Object)null))
				{
					RegisterLocalClimbable(climbableRoot, ((Object)source.pitonWorldObject).name);
				}
			}
			CapturedPitons.Clear();
		}

		public static void RegisterNewLocalProjectileClimbable(Projectile source, RaycastHit hit, HashSet<int> knownHandholds)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			if (MPCore.CanSync && !ApplyingRemoteState && !((Object)(object)source == (Object)null) && knownHandholds != null && IsLocalProjectile(source))
			{
				GameObject climbableRoot = GetClimbableRoot(((Component)source).gameObject);
				GameObject fallback = (IsNewClimbableRoot(climbableRoot, knownHandholds) ? climbableRoot : null);
				GameObject val = FindBestNewClimbable(((RaycastHit)(ref hit)).point, knownHandholds, null, fallback);
				RegisterLocalClimbable(val, ((Object)(object)val != (Object)null) ? ((Object)val).name : ((Object)((Component)source).gameObject).name);
			}
		}

		public static void RegisterNewLocalProjectileClimbable(Projectile source, RaycastHit hit)
		{
			if (!MPCore.CanSync || 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, ((Object)(object)climbableRoot != (Object)null) ? ((Object)climbableRoot).name : ((Object)((Component)source).gameObject).name);
				}
			}
			CapturedPitons.Clear();
		}

		public static void BroadcastHammerUpdate(CL_Handhold handhold)
		{
			if (MPCore.CanSync && !ApplyingRemoteState && !((Object)(object)handhold == (Object)null))
			{
				NetworkedClimableItem networkedClimableItem = FindIdentity(handhold);
				if (!((Object)(object)networkedClimableItem == (Object)null) && !string.IsNullOrEmpty(networkedClimableItem.NetworkId))
				{
					Broadcast(networkedClimableItem, PitonSyncAction.Update, force: true);
				}
			}
		}

		public static void BroadcastPeriodicUpdate(CL_Handhold handhold)
		{
			if (!MPCore.CanSync || ApplyingRemoteState || (Object)(object)handhold == (Object)null)
			{
				return;
			}
			NetworkedClimableItem networkedClimableItem = FindIdentity(handhold);
			if ((Object)(object)networkedClimableItem == (Object)null || string.IsNullOrEmpty(networkedClimableItem.NetworkId))
			{
				return;
			}
			if (!((Component)networkedClimableItem).gameObject.activeSelf)
			{
				Broadcast(networkedClimableItem, PitonSyncAction.Remove, force: true);
			}
			else if (!(Time.time - networkedClimableItem.LastSentTime < 0.15f))
			{
				CL_Handhold trackedHandhold = GetTrackedHandhold(((Component)networkedClimableItem).gameObject);
				if (HasMeaningfulStateChange(networkedClimableItem, trackedHandhold))
				{
					Broadcast(networkedClimableItem, PitonSyncAction.Update, force: false);
				}
			}
		}

		public static void HandlePitonState(ulong senderId, DataReader reader)
		{
			//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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			PitonSyncAction @byte = (PitonSyncAction)reader.GetByte();
			string @string = reader.GetString();
			string string2 = reader.GetString();
			Vector3 vector = reader.GetVector3();
			Quaternion quaternion = reader.GetQuaternion();
			float @float = reader.GetFloat();
			bool @bool = reader.GetBool();
			bool bool2 = reader.GetBool();
			if (string.IsNullOrEmpty(@string))
			{
				return;
			}
			ApplyingRemoteState = true;
			try
			{
				switch (@byte)
				{
				case PitonSyncAction.Create:
					ApplyCreate(senderId, @string, string2, vector, quaternion, @float, @bool, bool2);
					break;
				case PitonSyncAction.Update:
					ApplyUpdate(@string, vector, quaternion, @float, @bool, bool2);
					break;
				case PitonSyncAction.Remove:
					ApplyRemove(@string);
					break;
				}
			}
			catch (Exception ex)
			{
				MPMain.LogError($"[MP ClimbableSync] Failed to apply {@byte} for {@string}: {ex.Message}");
			}
			finally
			{
				ApplyingRemoteState = false;
			}
		}

		private static void RegisterLocalClimbable(GameObject root, string prefabKey)
		{
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			string text = NormalizePrefabKey(prefabKey);
			if (!string.IsNullOrEmpty(text))
			{
				NetworkedClimableItem orCreateIdentity = GetOrCreateIdentity(root);
				if (string.IsNullOrEmpty(orCreateIdentity.NetworkId))
				{
					orCreateIdentity.NetworkId = $"{MonoSingleton<MPSteamworks>.Instance.UserSteamId}:{_nextLocalId++}";
					orCreateIdentity.OwnerId = MonoSingleton<MPSteamworks>.Instance.UserSteamId;
					orCreateIdentity.IsRemote = false;
				}
				orCreateIdentity.PrefabKey = text;
				_pitons[orCreateIdentity.NetworkId] = orCreateIdentity;
				Broadcast(orCreateIdentity, PitonSyncAction.Create, force: true);
			}
		}

		private static void ApplyCreate(ulong senderId, string networkId, string prefabKey, Vector3 position, Quaternion rotation, float secureAmount, bool secure, bool active)
		{
			//IL_002f: 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_008f: 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_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			if (_pitons.TryGetValue(networkId, out NetworkedClimableItem value) && (Object)(object)value != (Object)null)
			{
				value.PrefabKey = NormalizePrefabKey(prefabKey);
				ApplyState(value, position, rotation, secureAmount, secure, active);
				return;
			}
			GameObject val = ResolvePrefab(prefabKey);
			if ((Object)(object)val == (Object)null)
			{
				MPMain.LogError("[MP ClimbableSync] Could not resolve prefab '" + prefabKey + "' for " + networkId + ".");
				return;
			}
			GameObject val2 = Object.Instantiate<GameObject>(val, position, rotation);
			Transform currentLevelParentRoot = WorldLoader.GetCurrentLevelParentRoot();
			if ((Object)(object)currentLevelParentRoot != (Object)null)
			{
				val2.transform.SetParent(currentLevelParentRoot);
			}
			TryAddPlacedObjectToLevel(val2);
			NetworkedClimableItem orCreateIdentity = GetOrCreateIdentity(val2);
			orCreateIdentity.NetworkId = networkId;
			orCreateIdentity.PrefabKey = NormalizePrefabKey(prefabKey);
			orCreateIdentity.OwnerId = senderId;
			orCreateIdentity.IsRemote = true;
			_pitons[networkId] = orCreateIdentity;
			ApplyState(orCreateIdentity, position, rotation, secureAmount, secure, active);
		}

		private static void ApplyUpdate(string networkId, Vector3 position, Quaternion rotation, float secureAmount, bool secure, bool active)
		{
			//IL_0021: 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)
			if (_pitons.TryGetValue(networkId, out NetworkedClimableItem value) && !((Object)(object)value == (Object)null))
			{
				ApplyState(value, position, rotation, secureAmount, secure, active);
			}
		}

		private static void ApplyRemove(string networkId)
		{
			if (_pitons.TryGetValue(networkId, out NetworkedClimableItem value) && !((Object)(object)value == (Object)null))
			{
				if ((Object)(object)((Component)value).gameObject != (Object)null)
				{
					((Component)value).gameObject.SetActive(false);
				}
				_pitons.Remove(networkId);
			}
		}

		private static void ApplyState(NetworkedClimableItem identity, Vector3 position, Quaternion rotation, float secureAmount, bool secure, bool active)
		{
			//IL_0009: 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)
			Transform transform = ((Component)identity).transform;
			transform.position = position;
			transform.rotation = rotation;
			CL_Handhold trackedHandhold = GetTrackedHandhold(((Component)identity).gameObject);
			if ((Object)(object)trackedHandhold != (Object)null)
			{
				trackedHandhold.Initialize();
				trackedHandhold.secureAmount = secureAmount;
				trackedHandhold.secure = secure;
			}
			((Component)identity).gameObject.SetActive(active);
			RecordState(identity, trackedHandhold);
		}

		private static GameObject FindBestNewClimbable(Vector3 anchor, HashSet<int> knownHandholds, string preferredName, GameObject fallback)
		{
			//IL_002f: 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)
			GameObject result = null;
			float num = float.MaxValue;
			HashSet<int> hashSet = new HashSet<int>();
			if (IsNewClimbableRoot(fallback, knownHandholds) && NameMatches(((Object)fallback).name, preferredName))
			{
				result = fallback;
				num = GetAnchorPosition(fallback, anchor);
				hashSet.Add(((Object)fallback).GetInstanceID());
			}
			CL_Handhold[] array = Object.FindObjectsOfType<CL_Handhold>();
			foreach (CL_Handhold val in array)
			{
				GameObject climbableRoot = GetClimbableRoot(((Object)(object)val != (Object)null) ? ((Component)val).gameObject : null);
				if (IsNewClimbableRoot(climbableRoot, knownHandholds) && hashSet.Add(((Object)climbableRoot).GetInstanceID()) && NameMatches(((Object)climbableRoot).name, preferredName))
				{
					float anchorPosition = GetAnchorPosition(climbableRoot, anchor);
					if (anchorPosition < num)
					{
						result = climbableRoot;
						num = anchorPosition;
					}
				}
			}
			return result;
		}

		private static bool IsNewClimbableRoot(GameObject root, HashSet<int> knownHandholds)
		{
			return (Object)(object)root != (Object)null && knownHandholds != null && !knownHandholds.Contains(((Object)root).GetInstanceID()) && ContainsTrackedHandhold(root);
		}

		private static 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 static bool ContainsTrackedHandhold(GameObject root)
		{
			return (Object)(object)root != (Object)null && (Object)(object)GetTrackedHandhold(root) != (Object)null;
		}

		private static CL_Handhold GetTrackedHandhold(GameObject root)
		{
			if ((Object)(object)root == (Object)null)
			{
				return null;
			}
			return root.GetComponent<CL_Handhold>() ?? root.GetComponentInChildren<CL_Handhold>(true);
		}

		private static NetworkedClimableItem FindIdentity(CL_Handhold handhold)
		{
			return ((Component)handhold).GetComponent<NetworkedClimableItem>() ?? ((Component)handhold).GetComponentInParent<NetworkedClimableItem>();
		}

		private static float GetAnchorPosition(GameObject root, Vector3 anchor)
		{
			//IL_0024: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			CL_Handhold trackedHandhold = GetTrackedHandhold(root);
			Vector3 val = (((Object)(object)trackedHandhold != (Object)null) ? ((Component)trackedHandhold).transform.position : root.transform.position);
			Vector3 val2 = val - anchor;
			return ((Vector3)(ref val2)).sqrMagnitude;
		}

		private static bool NameMatches(string name, string preferredName)
		{
			if (string.IsNullOrEmpty(preferredName))
			{
				return true;
			}
			string text = NormalizePrefabKey(name);
			string text2 = NormalizePrefabKey(preferredName);
			if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(text2))
			{
				return false;
			}
			return text.Equals(text2, StringComparison.OrdinalIgnoreCase) || text.IndexOf(text2, StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0;
		}

		private static GameObject ResolvePrefab(string prefabKey)
		{
			string text = NormalizePrefabKey(prefabKey);
			if (string.IsNullOrEmpty(text))
			{
				return null;
			}
			if (_prefabLookup.TryGetValue(text, out GameObject value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			RebuildPrefabLookup();
			_prefabLookup.TryGetValue(text, out value);
			return value;
		}

		private static void RebuildPrefabLookup()
		{
			_prefabLookup.Clear();
			HandItem_Piton[] array = Resources.FindObjectsOfTypeAll<HandItem_Piton>();
			foreach (HandItem_Piton val in array)
			{
				if ((Object)(object)val != (Object)null)
				{
					TryRegisterPrefab(val.pitonWorldObject);
				}
			}
			HandItem_Shoot[] array2 = Resources.FindObjectsOfTypeAll<HandItem_Shoot>();
			foreach (HandItem_Shoot val2 in array2)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					TryRegisterPrefab(val2.projectile);
					RegisterProjectileHitPrefabs(val2.projectile);
				}
			}
		}

		private static void RegisterProjectileHitPrefabs(GameObject projectilePrefab)
		{
			if ((Object)(object)projectilePrefab == (Object)null)
			{
				return;
			}
			Projectile component = projectilePrefab.GetComponent<Projectile>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			TryRegisterPrefab(component.hitEffect);
			if (component.customHitEffects == null)
			{
				return;
			}
			foreach (HitEffect customHitEffect in component.customHitEffects)
			{
				if (customHitEffect != null)
				{
					TryRegisterPrefab(customHitEffect.hitEffect);
				}
			}
		}

		private static void TryRegisterPrefab(GameObject prefab)
		{
			if (!((Object)(object)prefab == (Object)null))
			{
				string text = NormalizePrefabKey(((Object)prefab).name);
				if (!string.IsNullOrEmpty(text) && !_prefabLookup.ContainsKey(text))
				{
					_prefabLookup[text] = prefab;
				}
			}
		}

		private static string NormalizePrefabKey(string prefabKey)
		{
			if (string.IsNullOrEmpty(prefabKey))
			{
				return string.Empty;
			}
			string text = prefabKey.Trim();
			if (text.EndsWith("(Clone)", StringComparison.OrdinalIgnoreCase))
			{
				text = text.Substring(0, text.Length - "(Clone)".Length);
			}
			return text.Trim();
		}

		private static bool IsLocalProjectile(Projectile projectile)
		{
			ENT_Player player = ENT_Player.GetPlayer();
			if ((Object)(object)projectile == (Object)null || (Object)(object)player == (Object)null || _projectileSourceEntityField == null)
			{
				return false;
			}
			object? value = _projectileSourceEntityField.GetValue(projectile);
			GameEntity val = (GameEntity)((value is GameEntity) ? value : null);
			return (Object)(object)val == (Object)(object)player;
		}

		private static void TryAddPlacedObjectToLevel(GameObject climbableObject)
		{
			if (!WorldLoader.initialized || (Object)(object)climbableObject == (Object)null)
			{
				return;
			}
			try
			{
				M_Level level = WorldLoader.instance.GetCurrentLevel().GetLevel();
				typeof(M_Level).GetMethod("AddPlacedObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(level, new object[1] { climbableObject });
			}
			catch (Exception ex)
			{
				MPMain.LogWarning("[MP ClimbableSync] Could not register remote climbable as placed object: " + ex.Message);
			}
		}

		private static NetworkedClimableItem GetOrCreateIdentity(GameObject obj)
		{
			NetworkedClimableItem networkedClimableItem = obj.GetComponent<NetworkedClimableItem>();
			if ((Object)(object)networkedClimableItem == (Object)null)
			{
				networkedClimableItem = obj.AddComponent<NetworkedClimableItem>();
			}
			return networkedClimableItem;
		}

		private static void Broadcast(NetworkedClimableItem identity, PitonSyncAction action, bool force)
		{
			//IL_0073: 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)
			if (!((Object)(object)identity == (Object)null) && !string.IsNullOrEmpty(identity.NetworkId))
			{
				CL_Handhold trackedHandhold = GetTrackedHandhold(((Component)identity).gameObject);
				DataWriter writer = MPWriterPool.GetWriter(MonoSingleton<MPSteamworks>.Instance.UserSteamId, 0uL, PacketType.PitonStateSync);
				writer.Put((byte)action);
				writer.Put(identity.NetworkId);
				writer.Put(identity.PrefabKey ?? string.Empty);
				writer.Put(((Component)identity).transform.position);
				writer.Put(((Component)identity).transform.rotation);
				writer.Put(((Object)(object)trackedHandhold != (Object)null) ? trackedHandhold.secureAmount : 0f);
				writer.Put((Object)(object)trackedHandhold != (Object)null && trackedHandhold.secure);
				writer.Put(((Component)identity).gameObject.activeSelf);
				MonoSingleton<MPSteamworks>.Instance.Broadcast(writer, (SendType)8, 0);
				RecordState(identity, trackedHandhold);
				if (force)
				{
					MPMain.LogInfo($"[MP ClimbableSync] Sent {action} for {identity.NetworkId} ({identity.PrefabKey})");
				}
			}
		}

		private static bool HasMeaningfulStateChange(NetworkedClimableItem identity, CL_Handhold handhold)
		{
			//IL_0023: 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_0038: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			if (identity.LastActive != ((Component)identity).gameObject.activeSelf)
			{
				return true;
			}
			Vector3 val = identity.LastPosition - ((Component)identity).transform.position;
			if (((Vector3)(ref val)).sqrMagnitude > 0.0004f)
			{
				return true;
			}
			if (Quaternion.Angle(identity.LastRotation, ((Component)identity).transform.rotation) > 0.5f)
			{
				return true;
			}
			if ((Object)(object)handhold == (Object)null)
			{
				return false;
			}
			if (Mathf.Abs(identity.LastSecureAmount - handhold.secureAmount) > 0.01f)
			{
				return true;
			}
			return identity.LastSecure != handhold.secure;
		}

		private static void RecordState(NetworkedClimableItem identity, CL_Handhold handhold)
		{
			//IL_0014: 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)
			identity.LastSentTime = Time.time;
			identity.LastPosition = ((Component)identity).transform.position;
			identity.LastRotation = ((Component)identity).transform.rotation;
			identity.LastActive = ((Component)identity).gameObject.activeSelf;
			if ((Object)(object)handhold != (Object)null)
			{
				identity.LastSecureAmount = handhold.secureAmount;
				identity.LastSecure = handhold.secure;
			}
		}
	}
}
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 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>> _table;

		private static Dictionary<string, LocalizedValue> _flatCache;

		private const string FILE_PREFIX = "texts";

		private static readonly Random _staticRandom = new Random();

		public static void Load()
		{
			string path = MPMain.path;
			string gameLanguage = GetGameLanguage();
			string text = "texts_" + gameLanguage.ToLower() + ".json";
			string text2 = Path.Combine(path, text);
			if (!File.Exists(text2))
			{
				MPMain.LogError("[Localization] " + text + " file not found at path: " + text2);
				text = "texts_en.json";
				text2 = Path.Combine(path, text);
				if (!File.Exists(text2))
				{
					MPMain.LogError("[Localization] Localization file not found, please confirm that texts_en.json file exists");
					return;
				}
			}
			try
			{
				string text3 = File.ReadAllText(text2);
				Dictionary<string, Dictionary<string, object>> dictionary = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, object>>>(text3);
				_table = new Dictionary<string, Dictionary<string, LocalizedValue>>();
				foreach (KeyValuePair<string, Dictionary<string, object>> item in dictionary)
				{
					_table[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)
						{
							_table[item.Key][item2.Key] = new LocalizedValue(((IEnumerable<JToken>)val).Select((JToken x) => ((object)x).ToString()).ToArray());
						}
						else
						{
							_table[item.Key][item2.Key] = new LocalizedValue(item2.Value?.ToString());
						}
					}
				}
				BuildFlatCache();
				int num = 0;
				foreach (KeyValuePair<string, Dictionary<string, LocalizedValue>> item3 in _table)
				{
					num += item3.Value.Count;
				}
				MPMain.LogInfo($"[Localization] Successfully loaded {_table.Count} categories with {num} entries");
			}
			catch (Exception ex)
			{
				MPMain.LogError("[Localization] Unable to parse localization file: " + ex.Message);
			}
		}

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

		public static bool TryGetValueSplit(string category, string key, out LocalizedValue value)
		{
			if (string.IsNullOrEmpty(category))
			{
				MPMain.LogWarning("[MP Localization] Category is null or empty");
				value = new LocalizedValue("[" + category + "." + key + "]");
				return false;
			}
			if (!_table.TryGetValue(category, out Dictionary<string, LocalizedValue> value2))
			{
				MPMain.LogWarning("[MP Localization] Category not found: " + category);
				value = new LocalizedValue("[" + category + "." + key + "]");
				return false;
			}
			if (!value2.TryGetValue(key, out var value3))
			{
				MPMain.LogWarning("[MP Localization] Key '" + key + "' not found in category '" + category + "'");
				value = new LocalizedValue("[" + category + "." + key + "]");
				return false;
			}
			value = value3;
			return true;
		}

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

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

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

		private static string SafeFormat(string pattern, object[] args)
		{
			if (args == null || args.Length == 0)
			{
				return pattern;
			}
			try
			{
				return string.Format(pattern, args);
			}
			catch (Exception ex)
			{
				MPMain.LogError("[Localization] Format error: " + ex.Message);
				return pattern;
			}
		}

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

		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 GetRandom(string key, params object[] args)
		{
			if (!TryGetValue(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 (!TryGetValue(key, out var value))
			{
				return value.AsString;
			}
			return SafeFormat(value.GetValue(index), args);
		}

		public static bool HasKey(string key)
		{
			return _flatCache.ContainsKey(key);
		}

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

		public static IEnumerable<string> GetAllCategories()
		{
			return _table.Keys;
		}

		public static IEnumerable<string> GetKeysInCategory(string category)
		{
			if (_table.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 ReflectionExtensions
	{
		public static T GetFieldValue<T>(this object obj, string fieldName)
		{
			if (obj == null)
			{
				throw new ArgumentNullException("obj");
			}
			Type type = obj.GetType();
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
			while (type != null)
			{
				FieldInfo field = type.GetField(fieldName, bindingAttr);
				if (field != null)
				{
					return (T)field.GetValue(obj);
				}
				type = type.BaseType;
			}
			throw new Exception($"Field '{fieldName}' not found in type '{obj.GetType()}'");
		}

		public static void SetFieldValue<T>(this object obj, string fieldName, T value)
		{
			Type type = obj.GetType();
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			FieldInfo field = type.GetField(fieldName, bindingAttr);
			if (field != null)
			{
				field.SetValue(obj, value);
			}
		}
	}
}
namespace WKMPMod.UI
{
	[HarmonyPatch(typeof(UI_GamemodeScreen), "Initialize")]
	public class Patch_UI_GamemodeScreen_Initialize
	{
		private static void Postfix(UI_GamemodeScreen __instance, M_Gamemode mode)
		{
			string id = mode.gamemodePanel.id;
			if (!__instance.activePanels.TryGetValue(id, out var value) || (Object)(object)((Component)value).gameObject.GetComponentInChildren<UI_LobbyCreateButton>(true) != (Object)null)
			{
				return;
			}
			Transform val = ((Component)value).transform.Find("Pages/Gamemode_Info_Screen/Tab Selection Hor/Play");
			TextMeshProUGUI componentInChildren = ((Component)val).GetComponentInChildren<TextMeshProUGUI>();
			if (((componentInChildren != null) ? ((TMP_Text)componentInChildren).text : null) != "Play")
			{
				val = ((Component)value).transform.Find("Pages/Gamemode_NewGame_Screen/Tab Selection Hor/Play");
			}
			if ((Object)(object)val != (Object)null)
			{
				GameObject val2 = Object.Instantiate<GameObject>(((Component)val).gameObject, val.parent);
				((Object)val2).name = "Multi Play";
				val2.transform.SetSiblingIndex(val.GetSiblingIndex() + 1);
				UI_LobbyCreateButton uI_LobbyCreateButton = val2.AddComponent<UI_LobbyCreateButton>();
				uI_LobbyCreateButton.gamemodePanel = value;
				TMP_Text componentInChildren2 = val2.GetComponentInChildren<TMP_Text>();
				if ((Object)(object)componentInChildren2 != (Object)null)
				{
					componentInChildren2.text = "Multi Play";
				}
				value.noSaveObjects.Add(val2);
				value.hasSaveObjects.Add(val2);
			}
		}
	}
	[HarmonyPatch(typeof(UI_MenuButton), "Initialize")]
	public class Patch_UI_MenuButton_Initialize
	{
		private static bool Prefix(UI_MenuButton __instance, UI_Menu menu)
		{
			if (UI_Manager.IsCloningMultiplayerMenu && ((Object)((Component)__instance).gameObject).name == "Facility Button")
			{
				return false;
			}
			return true;
		}
	}
	public class UI_LoadingDisplay : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <HideAfterDelay>d__10 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public UI_LoadingDisplay <>4__this;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					<>4__this._remainingTime -= Time.deltaTime;
					break;
				}
				if (<>4__this._remainingTime > 0f)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				((Component)<>4__this).gameObject.SetActive(false);
				<>4__this._hideCoroutine = null;
				return false;
			}

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

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private Coroutine? _hideCoroutine;

		private float _hideTime = -1f;

		private float _remainingTime = 0f;

		private void Awake()
		{
			MPEventBusGame.OnShowLoading += HandleLoadingRequest;
			MPEventBusGame.OnHideLoading += HideImmediately;
			((Component)this).gameObject.SetActive(false);
		}

		private void OnDestroy()
		{
			MPEventBusGame.OnShowLoading -= HandleLoadingRequest;
			MPEventBusGame.OnHideLoading -= HideImmediately;
		}

		private void HandleLoadingRequest(float duration)
		{
			if (duration <= 0f)
			{
				ShowPermanent();
			}
			else
			{
				ShowForSeconds(duration);
			}
		}

		public void ShowPermanent()
		{
			if (_hideCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_hideCoroutine);
				_hideCoroutine = null;
			}
			_hideTime = -1f;
			_remainingTime = 0f;
			((Component)this).gameObject.SetActive(true);
		}

		public void ShowForSeconds(float seconds)
		{
			if (!(seconds <= 0f))
			{
				if (_hideCoroutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(_hideCoroutine);
					_hideCoroutine = null;
				}
				_hideTime = seconds;
				_remainingTime = seconds;
				((Component)this).gameObject.SetActive(true);
				_hideCoroutine = ((MonoBehaviour)this).StartCoroutine(HideAfterDelay());
			}
		}

		public void ExtendDuration(float seconds)
		{
			if (!(_hideTime < 0f) && _hideCoroutine != null)
			{
				_remainingTime += seconds;
				if (_remainingTime <= 0f)
				{
					HideImmediately();
				}
			}
		}

		public void HideImmediately()
		{
			if (_hideCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_hideCoroutine);
				_hideCoroutine = null;
			}
			_hideTime = -1f;
			_remainingTime = 0f;
			((Component)this).gameObject.SetActive(false);
		}

		[IteratorStateMachine(typeof(<HideAfterDelay>d__10))]
		private IEnumerator HideAfterDelay()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <HideAfterDelay>d__10(0)
			{
				<>4__this = this
			};
		}

		public float GetRemainingTime()
		{
			return _remainingTime;
		}

		public bool IsShowing()
		{
			return ((Component)this).gameObject.activeSelf;
		}

		public bool IsPermanent()
		{
			return _hideTime < 0f && ((Component)this).gameObject.activeSelf;
		}
	}
	public class UI_LobbyCreateButton : MonoBehaviour
	{
		public Button? button;

		public UI_GamemodeScreen_Panel? gamemodePanel;

		public List<Button> otherButtons = new List<Button>();

		private void Awake()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			Button component = ((Component)this).GetComponent<Button>();
			if ((Object)(object)component != (Object)null)
			{
				component.onClick = new ButtonClickedEvent();
				button = component;
			}
			else
			{
				button = ((Component)this).gameObject.AddComponent<Button>();
			}
			((UnityEvent)button.onClick).AddListener(new UnityAction(CreateLobby));
		}

		private void Start()
		{
			if (!((Object)(object)((Component)this).transform.parent != (Object)null))
			{
				return;
			}
			Button[] componentsInChildren = ((Component)((Component)this).transform.parent).GetComponentsInChildren<Button>();
			foreach (Button val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)(object)button)
				{
					otherButtons.Add(val);
				}
			}
		}

		public async void CreateLobby()
		{
			string name = SteamClient.Name;
			MPMain.LogInfo(Localization.Get("MPCore.CreatingLobby", name));
			Dictionary<string, string> lobbyData = new Dictionary<string, string>
			{
				{
					"name",
					name + "'s game"
				},
				{
					"gamemode",
					CL_GameManager.gamemode.gamemodeName
				},
				{
					"damageMultiplier",
					JsonUtility.ToJson((object)MPCore.damageRules)
				}
			};
			Creating();
			try
			{
				bool success = await MonoSingleton<MPSteamworks>.Instance.CreateRoomAsync(8, lobbyData);
				if (!((Object)(object)this == (Object)null) && !((Object)(object)((Component)this).gameObject == (Object)null))
				{
					if (success)
					{
						CreateSuccess();
					}
					else
					{
						CreateFailed();
					}
				}
			}
			catch (Exception ex2)
			{
				Exception ex = ex2;
				if (!((Object)(object)this == (Object)null))
				{
					CreateFailed();
					MPMain.LogError(Localization.Get("UI_LobbyCreateButton.CreateLobbyFailed", ex.Message));
				}
			}
		}

		public void Creating()
		{
			MPCore.SetStatus(MPStatus.LobbyConnectionError, MPStatus.JoiningLobby);
			Button? obj = button;
			if (obj != null)
			{
				((Selectable)obj).interactable = false;
			}
			foreach (Button otherButton in otherButtons)
			{
				((Selectable)otherButton).interactable = false;
			}
			MPEventBusGame.NotifyShowLoading(10f);
		}

		public void CreateFailed()
		{
			MPCore.SetStatus(MPStatus.LobbyConnectionError, MPStatus.LobbyConnectionError);
			Button? obj = button;
			if (obj != null)
			{
				((Selectable)obj).interactable = true;
			}
			foreach (Button otherButton in otherButtons)
			{
				((Selectable)otherButton).interactable = true;
			}
			MPEventBusGame.NotifyHideLoading();
		}

		public void CreateSuccess()
		{
			MPCore.SetStatus(MPStatus.LobbyConnectionError, MPStatus.InLobby);
			MPEventBusGame.NotifyHideLoading();
			if ((Object)(object)gamemodePanel == (Object)null)
			{
				MPMain.LogError(Localization.Get("UI_LobbyCreateButton.GameModeDetailPanelNull"));
			}
			else
			{
				gamemodePanel.LoadGamemode();
			}
		}
	}
	public class UI_LobbyJoinButton : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler, ISelectHandler, IDeselectHandler
	{
		[CompilerGenerated]
		private sealed class <ShowAnimation>d__26 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public UI_LobbyJoinButton <>4__this;

			object? IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object? IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Expected O, but got Unknown
				//IL_0051: 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)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(<>4__this.showDelayAnimation);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					ShortcutExtensions.DOPunchScale(((Component)<>4__this).transform, Vector3.one * 0.04f, 0.5f, 5, 0.5f);
					return false;
				}
			}

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

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <TrackAndLoadOwnerInfoCoroutine>d__16 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public UI_LobbyJoinButton <>4__this;

			private Friend <owner>5__1;

			private ulong <ownerId>5__2;

			private Task<Image?> <avatarTask>5__3;

			private Image? <avatarResult>5__4;

			private Texture2D <texture>5__5;

			object? IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object? IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<avatarTask>5__3 = null;
				<avatarResult>5__4 = null;
				<texture>5__5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//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_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_008c: Unknown result type (might be due to invalid IL or missing references)
				//IL_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)
				//IL_0166: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if ((Object)(object)<>4__this == (Object)null)
					{
						return false;
					}
					<owner>5__1 = ((Lobby)(ref <>4__this.lobby)).Owner;
					if (SteamId.op_Implicit(<owner>5__1.Id) == 0L && ulong.TryParse(((Lobby)(ref <>4__this.lobby)).GetData("owner"), out <ownerId>5__2))
					{
						<owner>5__1 = new Friend(SteamId.op_Implicit(<ownerId>5__2));
					}
					<>4__this.hostName.text = (string.IsNullOrEmpty(((Friend)(ref <owner>5__1)).Name) ? "Loading Name..." : ((Friend)(ref <owner>5__1)).Name);
					<avatarTask>5__3 = ((Friend)(ref <owner>5__1)).GetMediumAvatarAsync();
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (!<avatarTask>5__3.IsCompleted)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				if ((Object)(object)<>4__this == (Object)null)
				{
					return false;
				}
				<avatarResult>5__4 = <avatarTask>5__3.Result;
				if (<avatarResult>5__4.HasValue && (Object)(object)<>4__this.hostAvatar != (Object)null)
				{
					<texture>5__5 = SteamManager.ConvertSteamIcon(<avatarResult>5__4.Value);
					<>4__this.hostAvatar.sprite = Sprite.Create(<texture>5__5, new Rect(0f, 0f, (float)((Texture)<texture>5__5).width, (float)((Texture)<texture>5__5).height), new Vector2(0.5f, 0.5f));
					((Behaviour)<>4__this.hostAvatar).enabled = true;
					<>4__this.hostName.text = ((Friend)(ref <owner>5__1)).Name;
					<texture>5__5 = null;
				}
				return false;
			}

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

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public Lobby lobby;

		public M_Gamemode? gamemode;

		public bool isOfficialGamemodes;

		public UI_LerpOpen? runInProgressDisplay;

		private bool isHovering;

		public TMP_Text? unlockText;

		public float showDelayAnimation;

		public Selectable? button;

		public CanvasGroup? group;

		public Image? unlockIcon;

		public TMP_Text? lobbyName;

		public Image? hostAvatar;

		public TMP_Text? hostName;

		public Button? btnComp;

		public Image? lobbyImage;

		public void Initialize(Lobby lobby)
		{
			//IL_000e: 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_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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			this.lobby = lobby;
			((UnityEvent)btnComp.onClick).AddListener((UnityAction)async delegate
			{
				Joining();
				try
				{
					if (await MonoSingleton<MPSteamworks>.Instance.JoinRoomAsync(lobby))
					{
						JoinSuccess();
					}
					else
					{
						JoinFailed();
					}
				}
				catch (Exception ex2)
				{
					Exception ex = ex2;
					MPMain.LogError(Localization.Get("UI_LobbyJoinButton.JoinLobbyFailed", ex.Message));
					JoinFailed();
				}
			});
			isOfficialGamemodes = MPGameModeManager.TryGetGameMode(((Lobby)(ref lobby)).GetData("gamemode"), out M_Gamemode val);
			if ((Object)(object)unlockIcon != (Object)null)
			{
				((Component)unlockIcon).gameObject.SetActive(!isOfficialGamemodes);
			}
			if ((Object)(object)group != (Object)null)
			{
				group.interactable = isOfficialGamemodes;
				group.alpha = (isOfficialGamemodes ? 1f : 0.5f);
			}
			if (isOfficialGamemodes)
			{
				gamemode = val;
				Image component = ((Component)this).GetComponent<Image>();
				if (component != null)
				{
					component.sprite = val.capsuleArt;
				}
			}
			string data = ((Lobby)(ref lobby)).GetData("name");
			TMP_Text? obj = lobbyName;
			if (obj != null)
			{
				string text;
				if (string.IsNullOrEmpty(data))
				{
					SteamId id = ((Lobby)(ref lobby)).Id;
					text = ((object)(SteamId)(ref id)).ToString();
				}
				else
				{
					text = data;
				}
				obj.text = text;
			}
			((MonoBehaviour)this).StartCoroutine(TrackAndLoadOwnerInfoCoroutine());
		}

		[IteratorStateMachine(typeof(<TrackAndLoadOwnerInfoCoroutine>d__16))]
		private IEnumerator TrackAndLoadOwnerInfoCoroutine()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <TrackAndLoadOwnerInfoCoroutine>d__16(0)
			{
				<>4__this = this
			};
		}

		public void OnLobbyDataUpdated(Lobby updatedLobby)
		{
			//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)
			lobby = updatedLobby;
			isOfficialGamemodes = MPGameModeManager.TryGetGameMode(((Lobby)(ref lobby)).GetData("gamemode"), out M_Gamemode val);
			if (!string.IsNullOrEmpty(((Lobby)(ref lobby)).GetData("name")))
			{
				TMP_Text? obj = lobbyName;
				if (obj != null)
				{
					obj.text = ((Lobby)(ref lobby)).GetData("name");
				}
			}
			if ((Object)(object)unlockIcon != (Object)null)
			{
				((Component)unlockIcon).gameObject.SetActive(!isOfficialGamemodes);
			}
			if ((Object)(object)group != (Object)null)
			{
				group.interactable = isOfficialGamemodes;
				group.alpha = (isOfficialGamemodes ? 1f : 0.5f);
			}
			if (isOfficialGamemodes && (Object)(object)val != (Object)null)
			{
				gamemode = val;
				((Component)this).GetComponent<Image>().sprite = val.capsuleArt;
			}
			TMP_Text? obj2 = hostName;
			if (!(((obj2 != null) ? obj2.text : null) == "Fetching..."))
			{
				TMP_Text? obj3 = hostName;
				if (!(((obj3 != null) ? obj3.text : null) == "Loading Name..."))
				{
					return;
				}
			}
			((MonoBehaviour)this).StartCoroutine(TrackAndLoadOwnerInfoCoroutine());
		}

		public void OnPointerEnter(PointerEventData eventData)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)button != (Object)null && button.interactable)
			{
				ShortcutExtensions.DOPunchScale(((Component)this).transform, Vector3.one * 0.04f, 0.25f, 5, 0.5f);
				ShortcutExtensions.DOScale(((Component)this).transform, 1.05f, 0.25f);
			}
			isHovering = true;
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			if ((Object)(object)button != (Object)null && button.interactable)
			{
				ShortcutExtensions.DOScale(((Component)this).transform, 1f, 0.25f);
			}
			isHovering = false;
		}

		public void OnSelect(BaseEventData data)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)button != (Object)null && button.interactable)
			{
				ShortcutExtensions.DOPunchScale(((Component)this).transform, Vector3.one * 0.04f, 0.25f, 5, 0.5f);
				ShortcutExtensions.DOScale(((Component)this).transform, 1.05f, 0.25f);
			}
			isHovering = true;
		}

		public void OnDeselect(BaseEventData data)
		{
			if ((Object)(object)button != (Object)null && button.interactable)
			{
				ShortcutExtensions.DOScale(((Component)this).transform, 1f, 0.25f);
			}
			isHovering = false;
		}

		public void Joining()
		{
			MPCore.SetStatus(MPStatus.LobbyConnectionError, MPStatus.JoiningLobby);
			button.interactable = false;
			UI_LobbyListPane componentInParent = ((Component)this).GetComponentInParent<UI_LobbyListPane>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				componentInParent.SetAllButtonsInteractable(interactable: false);
			}
			MPEventBusGame.NotifyShowLoading(10f);
		}

		public void JoinFailed()
		{
			MPCore.SetStatus(MPStatus.LobbyConnectionError, MPStatus.LobbyConnectionError);
			button.interactable = true;
			UI_LobbyListPane componentInParent = ((Component)this).GetComponentInParent<UI_LobbyListPane>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				componentInParent.SetAllButtonsInteractable(interactable: true);
			}
			MPEventBusGame.NotifyHideLoading();
		}

		public void JoinSuccess()
		{
			MPCore.SetStatus(MPStatus.LobbyConnectionError, MPStatus.InLobby);
			MPEventBusGame.NotifyHideLoading();
		}

		public void Show()
		{
			if ((Object)(object)button != (Object)null && ((Component)button).gameObject.activeInHierarchy)
			{
				((MonoBehaviour)this).StartCoroutine(ShowAnimation());
			}
		}

		[IteratorStateMachine(typeof(<ShowAnimation>d__26))]
		public IEnumerator ShowAnimation()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ShowAnimation>d__26(0)
			{
				<>4__this = this
			};
		}
	}
	public class UI_LobbyListPane : MonoBehaviour
	{
		public const string TEMPLATE_PATH = "Canvas - Screens/Screens/Canvas - Screen - Play/Multi Play Menu/Lobby Pane/Tab Objects/Lobby Pane - Scroll View Tab - Template/Viewport/Content/Mode Selection Button - Challenge 01 - Advanced Course";

		public GameObject? template;

		public Dictionary<ulong, UI_LobbyJoinButton> LobbyDic = new Dictionary<ulong, UI_LobbyJoinButton>();

		public const string CONTENT_PATH = "Viewport/Content";

		public Transform? contentTransform;

		public bool interactable = true;

		private Func<Task> refreshHandle;

		public void Awake()
		{
			refreshHandle = async delegate
			{
				MPEventBusGame.NotifyShowLoading(10f);
				await RefreshLobbyList();
				MPEventBusGame.NotifyHideLoading();
			};
			MPEventBusGame.OnRefreshLobbyList += refreshHandle;
			SteamMatchmaking.OnLobbyDataChanged += OnSteamLobbyDataUpdate;
		}

		public void OnDestroy()
		{
			MPEventBusGame.OnRefreshLobbyList -= refreshHandle;
			SteamMatchmaking.OnLobbyDataChanged -= OnSteamLobbyDataUpdate;
		}

		private void Start()
		{
			try
			{
				SetupTemplate();
			}
			catch (Exception ex)
			{
				MPMain.LogError(Localization.Get("UI_LobbyListPane.ButtonTemplateBuildFailed", ex.Message));
			}
			contentTransform = ((Component)this).transform.Find("Viewport/Content");
		}

		private void OnEnable()
		{
		}

		public async Task RefreshLobbyList()
		{
			List<Lobby> lobbies = await MonoSingleton<MPSteamworks>.Instance.RefreshLobbyListAsync();
			HashSet<ulong> activeIds = lobbies.Select((Lobby lobby) => ((Lobby)(ref lobby)).Id.Value).ToHashSet();
			foreach (ulong id2 in LobbyDic.Keys.Where((ulong id) => !activeIds.Contains(id)).ToList())
			{
				Object.Destroy((Object)(object)((Component)LobbyDic[id2]).gameObject);
				LobbyDic.Remove(id2);
			}
			if ((Object)(object)template == (Object)null)
			{
				MPMain.LogError(Localization.Get("UI_LobbyListPane.LobbyButtonTemplateNull"));
				return;
			}
			foreach (Lobby item in lobbies)
			{
				Lobby lobby2 = item;
				if (LobbyDic.TryGetValue(((Lobby)(ref lobby2)).Id.Value, out UI_LobbyJoinButton existingButton))
				{
					((Lobby)(ref lobby2)).Refresh();
				}
				else
				{
					UI_LobbyJoinButton newButton = CreateLobbyButton(lobby2);
					if ((Object)(object)newButton != (Object)null)
					{
						LobbyDic[((Lobby)(ref lobby2)).Id.Value] = newButton;
						((Lobby)(ref lobby2)).Refresh();
					}
				}
				existingButton = null;
			}
		}

		public UI_LobbyJoinButton? CreateLobbyButton(Lobby lobby)
		{
			//IL_005f: 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)
			if ((Object)(object)template == (Object)null)
			{
				return null;
			}
			GameObject val = Object.Instantiate<GameObject>(template, contentTransform);
			if ((Object)(object)val == (Object)null)
			{
				MPMain.LogError(Localization.Get("UI_LobbyListPane.LobbyButtonCloneFailed"));
				return null;
			}
			((Object)val).name = $"LobbyButton_{((Lobby)(ref lobby)).Id}";
			val.SetActive(true);
			Button val2 = val.GetComponent<Button>() ?? val.AddComponent<Button>();
			UI_LobbyJoinButton component = val.GetComponent<UI_LobbyJoinButton>();
			((Selectable)val2).interactable = interactable;
			if ((Object)(object)component != (Object)null)
			{
				component.Initialize(lobby);
				return component;
			}
			MPMain.LogError(Localization.Get("UI_LobbyListPane.LobbyButtonComponentNotFound", ((Object)val).name));
			Object.Destroy((Object)(object)val);
			return null;
		}

		public void SetAllButtonsInteractable(bool interactable)
		{
			this.interactable = interactable;
			foreach (UI_LobbyJoinButton value in LobbyDic.Values)
			{
				if ((Object)(object)value != (Object)null)
				{
					Button component = ((Component)value).GetComponent<Button>();
					if (component != null)
					{
						((Selectable)component).interactable = interactable;
					}
				}
			}
		}

		private void OnSteamLobbyDataUpdate(Lobby lobby)
		{
			//IL_0009: 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)
			if (LobbyDic.TryGetValue(((Lobby)(ref lobby)).Id.Value, out UI_LobbyJoinButton value) && (Object)(object)value != (Object)null)
			{
				value.OnLobbyDataUpdated(lobby);
			}
		}

		public void SetupTemplate()
		{
			if (!((Object)(object)template != (Object)null) || !((Object)(object)template.GetComponent<UI_LobbyJoinButton>() != (Object)null))
			{
				GameObject obj = GameObject.Find("Canvas - Screens/Screens/Canvas - Screen - Play/Multi Play Menu/Lobby Pane/Tab Objects/Lobby Pane - Scroll View Tab - Template/Viewport/Content/Mode Selection Button - Challenge 01 - Advanced Course");
				template = ((obj != null) ? obj.gameObject : null);
				if ((Object)(object)template == (Object)null)
				{
					throw new Exception("Template not found at path: Canvas - Screens/Screens/Canvas - Screen - Play/Multi Play Menu/Lobby Pane/Tab Objects/Lobby Pane - Scroll View Tab - Template/Viewport/Content/Mode Selection Button - Challenge 01 - Advanced Course");
				}
				UI_LobbyJoinButton uI_LobbyJoinButton = template.AddComponent<UI_LobbyJoinButton>();
				UI_Gamemode_Button val = default(UI_Gamemode_Button);
				if (!template.TryGetComponent<UI_Gamemode_Button>(ref val))
				{
					throw new Exception("UI_Gamemode_Button component missing on template");
				}
				UI_CapsuleButton val2 = default(UI_CapsuleButton);
				if (!template.TryGetComponent<UI_CapsuleButton>(ref val2))
				{
					throw new Exception("UI_CapsuleButton component missing on template");
				}
				uI_LobbyJoinButton.runInProgressDisplay = val.runInProgressDisplay;
				object obj2 = val.unlockText;
				if (obj2 == null)
				{
					Transform obj3 = template.transform.Find("Lock Image/Unlock Requirement");
					obj2 = ((obj3 != null) ? ((Component)obj3).gameObject.GetComponent<TMP_Text>() : null);
				}
				uI_LobbyJoinButton.unlockText = (TMP_Text?)obj2;
				if ((Object)(object)uI_LobbyJoinButton.unlockText == (Object)null)
				{
					throw new Exception("Unlock text component missing");
				}
				uI_LobbyJoinButton.button = template.GetComponent<Selectable>();
				uI_LobbyJoinButton.group = template.GetComponent<CanvasGroup>();
				object obj4 = val2.unlockIcon;
				if (obj4 == null)
				{
					Transform obj5 = template.transform.Find("Lock Image");
					obj4 = ((obj5 != null) ? ((Component)obj5).gameObject.GetComponent<Image>() : null);
				}
				uI_LobbyJoinButton.unlockIcon = (Image?)obj4;
				if ((Object)(object)uI_LobbyJoinButton.unlockIcon == (Object)null)
				{
					throw new Exception("Lock Image component missing");
				}
				uI_LobbyJoinButton.showDelayAnimation = val2.showDelayAnimation;
				object obj6 = val.title;
				if (obj6 == null)
				{
					Transform obj7 = template.transform.Find("Mode Name");
					obj6 = ((obj7 != null) ? ((Component)obj7).gameObject.GetComponent<TMP_Text>() : null);
				}
				uI_LobbyJoinButton.lobbyName = (TMP_Text?)obj6;
				if ((Object)(object)uI_LobbyJoinButton.lobbyName == (Object)null)
				{
					throw new Exception("Mode Name component missing");
				}
				Transform obj8 = template.transform.Find("Roach Counter");
				uI_LobbyJoinButton.hostAvatar = ((obj8 != null) ? ((Component)obj8).GetComponent<Image>() : null);
				if ((Object)(object)uI_LobbyJoinButton.hostAvatar == (Object)null)
				{
					MPMain.LogError(Localization.Get("UI_LobbyJoinButton.RoachCounterNotFound"));
				}
				Transform obj9 = template.transform.Find("Roach Counter/Roaches");
				uI_LobbyJoinButton.hostName = ((obj9 != null) ? ((Component)obj9).GetComponent<TMP_Text>() : null);
				if ((Object)(object)uI_LobbyJoinButton.hostName == (Object)null)
				{
					MPMain.LogError(Localization.Get("UI_LobbyJoinButton.RoachCounterRoachesNotFound"));
				}
				uI_LobbyJoinButton.btnComp = template.GetComponent<Button>() ?? template.AddComponent<Button>();
				uI_LobbyJoinButton.lobbyImage = ((Component)this).GetComponent<Image>();
				if ((Object)(object)uI_LobbyJoinButton.lobbyImage == (Object)null)
				{
					MPMain.LogError(Localization.Get("UI_LobbyJoinButton.RoachCounterNotFound"));
				}
				((UnityEventBase)uI_LobbyJoinButton.btnComp.onClick).RemoveAllListeners();
				Transform obj10 = template.transform.Find("Roach Counter");
				if (obj10 != null)
				{
					((Component)obj10).gameObject.SetActive(true);
				}
				if ((Object)(object)uI_LobbyJoinButton.hostAvatar != (Object)null)
				{
					((Behaviour)uI_LobbyJoinButton.hostAvatar).enabled = false;
				}
				if ((Object)(object)uI_LobbyJoinButton.hostName != (Object)null)
				{
					uI_LobbyJoinButton.hostName.text = "Fetching...";
				}
				if ((Object)(object)uI_LobbyJoinButton.unlockText != (Object)null)
				{
					uI_LobbyJoinButton.unlockText.text = Localization.Get("UI_LobbyJoinButton.CustomGamemodeNotice");
				}
				Transform obj11 = template.transform.Find("Medal");
				Object.Destroy((Object)(object)((obj11 != null) ? ((Component)obj11).gameObject : null));
				Transform obj12 = template.transform.Find("High Score Tracker");
				Object.Destroy((Object)(object)((obj12 != null) ? ((Component)obj12).gameObject : null));
				Object.DestroyImmediate((Object)(object)val);
				Object.DestroyImmediate((Object)(object)val2);
			}
		}
	}
	public class UI_Manager : MonoSingleton<UI_Manager>
	{
		public enum UIDisplayType
		{
			None,
			AscentHeader,
			TipHeader,
			Header,
			HighscoreHeader
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__31_0;

			public static UnityAction <>9__31_1;

			public static UnityAction <>9__33_0;

			internal void <SetupMutators>b__31_0()
			{
				MPEventBusGame.NotifyRefreshLobbyList();
			}

			internal void <SetupMutators>b__31_1()
			{
				Application.OpenURL("https://discord.gg/DVr4h6Gc9w");
			}

			internal void <Initialize>b__33_0()
			{
				MPEventBusGame.NotifyRefreshLobbyList();
			}
		}

		private const string MAIN_MENU_PATH = "Main Menu";

		private const string MAIN_MENU_BUTTONS_PATH = "Main Menu/Main Menu Buttons";

		private const string CANVAS_SCREEN_PLAY_PATH = "Screens/Canvas - Screen - Play";

		private const string PLAY_PANE_PATH = "Play Pane";

		private const string GAMEMODE_SCREEN_PATH = "Screens/Canvas - Screen - Play/Play Menu/GamemodeScreen";

		private const string LOADING_SCREEN_PATH = "Screens";

		public static bool IsCloningMultiplayerMenu;

		private Transform? _mainMenu;

		private Transform? _screens;

		private GameObject? _mpButton;

		private GameObject? _mpScreen;

		private GameObject? _lobbyPaneContainer;

		private GameObject? _screenTabs;

		private GameObject? _screenTabButtons;

		private GameObject? _newTabButton;

		private GameObject? _tabButtonTemplate;

		private GameObject? _screenTabObjects;

		private GameObject? _mpLobbyPane;

		private GameObject? _lobbyPaneTemplate;

		private GameObject? _mutators;

		private GameObject? loadingTemplate;

		private GameObject? newloading;

		protected override void Awake()
		{
			base.Awake();
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		public void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			string name = ((Scene)(ref scene)).name;
			string text = name;
			if (!(text == "Main-Menu"))
			{
				return;
			}
			try
			{
				if ((Object)(object)_mpButton != (Object)null)
				{
					Object.Destroy((Object)(object)_mpButton);
				}
				if ((Object)(object)_mpScreen != (Object)null)
				{
					Object.Destroy((Object)(object)_mpScreen);
				}
				if (!CacheRoots())
				{
					return;
				}
				CreateMenuButton();
				CreateLobbyScreen();
				Initialize();
			}
			catch (Exception ex)
			{
				MPMain.LogError(Localization.Get("UI_Manager.CreateMenuUIFailed", ex.Message));
			}
			try
			{
				CreateLoadingScreen();
			}
			catch (Exception ex2)
			{
				MPMain.LogError(Localization.Get("UI_Manager.CreateMenuUIFailed", ex2.Message));
			}
			MPMain.LogInfo(Localization.Get("UI_Manager.MultiplayerLobbyUIBuildComplete"));
		}

		public bool CacheRoots()
		{
			if ((Object)(object)_screens != (Object)null)
			{
				return true;
			}
			GameObject obj = GameObject.Find("Canvas - Screens");
			_screens = ((obj != null) ? obj.transform : null);
			GameObject obj2 = GameObject.Find("Canvas - Main Menu");
			_mainMenu = ((obj2 != null) ? obj2.transform : null);
			return (Object)(object)_screens != (Object)null && (Object)(object)_mainMenu != (Object)null;
		}

		public void CreateMenuButton()
		{
			GameObject gameObject = ((Component)_mainMenu.Find("Main Menu/Main Menu Buttons")).gameObject;
			if ((Object)(object)gameObject == (Object)null)
			{
				MPMain.LogError(Localization.Get("UI_Manager.MainMenuContainerNotFound"));
				return;
			}
			Transform obj = gameObject.transform.Find("Cosmetics");
			GameObject val = ((obj != null) ? ((Component)obj).gameObject : null);
			if ((Object)(object)val == (Object)null)
			{
				MPMain.LogError(Localization.Get("UI_Manager.ButtonTemplateNotFound"));
				return;
			}
			_mpButton = Object.Instantiate<GameObject>(val, gameObject.transform);
			((Object)_mpButton).name = "Multi Play";
			_mpButton.transform.SetSiblingIndex(1);
			TextMeshProUGUI component = ((Component)_mpButton.transform.Find("Text (TMP)")).GetComponent<TextMeshProUGUI>();
			if (component != null)
			{
				((TMP_Text)component).text = "MULTI PLAY";
			}
		}

		public void CreateLobbyScreen()
		{
			if (PrepareRootContainers() && SetupTabButtons() && SetupTabContents())
			{
				SetupMutators();
				BindTabEvents();
			}
		}

		private bool PrepareRootContainers()
		{
			GameObject gameObject = ((Component)_screens.Find("Screens/Canvas - Screen - Play")).gameObject;
			if ((Object)(object)gameObject == (Object)null)
			{
				return Error(Localization.Get("UI_Manager.PlayScreenContainerNotFound"));
			}
			Transform obj = gameObject.transform.Find("Play Menu");
			GameObject val = ((obj != null) ? ((Component)obj).gameObject : null);
			if ((Object)(object)val == (Object)null)
			{
				return Error(Localization.Get("UI_Manager.PlayMenuTemplateNotFound"));
			}
			IsCloningMultiplayerMenu = true;
			_mpScreen = Object.Instantiate<GameObject>(val, gameObject.transform);
			IsCloningMultiplayerMenu = false;
			((Object)_mpScreen).name = "Multi Play Menu";
			_mpScreen.transform.SetSiblingIndex(0);
			Transform obj2 = _mpScreen.transform.Find("Play Pane");
			_lobbyPaneContainer = ((obj2 != null) ? ((Component)obj2).gameObject : null);
			if ((Object)(object)_lobbyPaneContainer == (Object)null)
			{
				return Error(Localization.Get("UI_Manager.LobbyPaneContainerPathError"));
			}
			((Object)_lobbyPaneContainer).name = "Lobby Pane";
			Object.Destroy((Object)(object)((Component)_mpScreen.transform.Find("GamemodeScreen")).gameObject);
			Object.Destroy((Object)(object)((Component)_lobbyPaneContainer.transform.Find("Facility Button")).gameObject);
			Object.Destroy((Object)(object)((Component)_lobbyPaneContainer.transform.Find("Play Scroll View")).gameObject);
			Object.Destroy((Object)(object)((Component)_lobbyPaneContainer.transform.Find("Tab Selection")).gameObject);
			FixLerpComponent(_lobbyPaneContainer);
			Transform obj3 = _lobbyPaneContainer.transform.Find("Mutators");
			_mutators = ((obj3 != null) ? ((Component)obj3).gameObject : null);
			if ((Object)(object)_mutators == (Object)null)
			{
				return Error(Localization.Get("UI_Manager.MutatorsContainerPathError"));
			}
			return true;
		}

		private bool SetupTabButtons()
		{
			Transform obj = _lobbyPaneContainer.transform.Find("Tabs");
			_screenTabs = ((obj != null) ? ((Component)obj).gameObject : null);
			GameObject? screenTabs = _screenTabs;
			object screenTabButtons;
			if (screenTabs == null)
			{
				screenTabButtons = null;
			}
			else
			{
				Transform obj2 = screenTabs.transform.Find("Tab Buttons");
				screenTabButtons = ((obj2 != null) ? ((Component)obj2).gameObject : null);
			}
			_screenTabButtons = (GameObject?)screenTabButtons;
			if ((Object)(object)_screenTabButtons == (Object)null)
			{
				return Error(Localization.Get("UI_Manager.TabButtonContainerNotFound"));
			}
			Transform obj3 = _screenTabButtons.transform.Find("ModeButton_Custom");
			_tabButtonTemplate = ((obj3 != null) ? ((Component)obj3).gameObject : null);
			if ((Object)(object)_tabButtonTemplate == (Object)null)
			{
				return Error(Localization.Get("UI_Manager.TabButtonTemplateNotFound"));
			}
			((Object)_tabButtonTemplate).name = "ModeButton_Template";
			Transform obj4 = _tabButtonTemplate.transform.Find("Text (TMP)");
			if (obj4 != null)
			{
				TextMeshProUGUI component = ((Component)obj4).gameObject.GetComponent<TextMeshProUGUI>();
				if (component != null)
				{
					((TMP_Text)component).text = "TEMPLATE";
				}
			}
			_newTabButton = Object.Instantiate<GameObject>(_tabButtonTemplate, _screenTabButtons.transform);
			((Object)_newTabButton).name = "ModeButton_Lobby";
			Transform obj5 = _newTabButton.transform.Find("Text (TMP)");
			if (obj5 != null)
			{
				TextMeshProUGUI component2 = ((Component)obj5).gameObject.GetComponent<TextMeshProUGUI>();
				if (component2 != null)
				{
					((TMP_Text)component2).text = "LOBBY";
				}
			}
			_tabButtonTemplate.transform.SetSiblingIndex(1);
			_newTabButton.transform.SetSiblingIndex(2);
			_newTabButton.SetActive(true);
			for (int num = _screenTabButtons.transform.childCount - 2; num > 2; num--)
			{
				Object.Destroy((Object)(object)((Component)_screenTabButtons.transform.GetChild(num)).gameObject);
			}
			return true;
		}

		private bool SetupTabContents()
		{
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Expected O, but got Unknown
			Transform obj = _lobbyPaneContainer.transform.Find("Tab Objects");
			_screenTabObjects = ((obj != null) ? ((Component)obj).gameObject : null);
			if ((Object)(object)_screenTabObjects == (Object)null)
			{
				return Error(Localization.Get("UI_Manager.TabContentContainerNotFound"));
			}
			Transform obj2 = _screenTabObjects.transform.Find("Play Pane - Scroll View Tab - Challenge");
			_lobbyPaneTemplate = ((obj2 != null) ? ((Component)obj2).gameObject : null);
			if ((Object)(object)_lobbyPaneTemplate == (Object)null)
			{
				return Error(Localization.Get("UI_Manager.ContentTemplateNotFound"));
			}
			((Object)_lobbyPaneTemplate).name = "Lobby Pane - Scroll View Tab - Template";
			_lobbyPaneTemplate.transform.SetSiblingIndex(0);
			for (int num = _screenTabObjects.transform.childCount - 1; num > 0; num--)
			{
				((Component)_screenTabObjects.transform.GetChild(num)).gameObject.SetActive(false);
			}
			_mpLobbyPane = Object.Instantiate<GameObject>(_lobbyPaneTemplate, _screenTabObjects.transform);
			((Object)_mpLobbyPane).name = "Lobby Pane - Scroll View Tab - Lobby";
			Transform val = _mpLobbyPane.transform.Find("Viewport/Content");
			if ((Object)(object)val != (Object)null)
			{
				foreach (Transform item in val)
				{
					Transform val2 = item;
					Object.Destroy((Object)(object)((Component)val2).gameObject);
				}
			}
			_mpLobbyPane.AddComponent<UI_LobbyListPane>();
			return true;
		}

		private bool SetupMutators()
		{
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Expected O, but got Unknown
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Expected O, but got Unknown
			if ((Object)(object)_mutators == (Object)null)
			{
				return Error(Localization.Get("UI_Manager.MutatorsContainerNotFound"));
			}
			_mutators.SetActive(true);
			GameObject gameObject = ((Component)Object.Instantiate<Transform>(_mutators.transform.Find("Options"), _mutators.transform)).gameObject;
			((Object)gameObject).name = "Refresh";
			ContentSizeFitter val = gameObject.GetComponent<ContentSizeFitter>() ?? gameObject.AddComponent<ContentSizeFitter>();
			val.horizontalFit = (FitMode)2;
			TextMeshProUGUI val2 = gameObject.GetComponent<TextMeshProUGUI>() ?? gameObject.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val2).enableWordWrapping = false;
			((TMP_Text)val2).overflowMode = (TextOverflowModes)0;
			Transform obj = _mutators.transform.Find("Ironman Toggle/Background/Label (1)");
			object font;
			if (obj == null)
			{
				font = null;
			}
			else
			{
				TextMeshProUGUI component = ((Component)obj).GetComponent<TextMeshProUGUI>();
				font = ((component != null) ? ((TMP_Text)component).font : null);
			}
			((TMP_Text)val2).font = (TMP_FontAsset)font;
			((TMP_Text)val2).text = "Refresh";
			((TMP_Text)val2).fontSize = 24f;
			Button val3 = gameObject.AddComponent<Button>();
			ButtonClickedEvent onClick = val3.onClick;
			object obj2 = <>c.<>9__31_0;
			if (obj2 == null)
			{
				UnityAction val4 = delegate
				{
					MPEventBusGame.NotifyRefreshLobbyList();
				};
				<>c.<>9__31_0 = val4;
				obj2 = (object)val4;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj2);
			GameObject gameObject2 = ((Component)Object.Instantiate<Transform>(_mutators.transform.Find("Options"), _mutators.transform)).gameObject;
			((Object)gameObject2).name = "Discord";
			ContentSizeFitter val5 = gameObject2.GetComponent<ContentSizeFitter>() ?? gameObject2.AddComponent<ContentSizeFitter>();
			val5.horizontalFit = (FitMode)2;
			TextMeshProUGUI val6 = gameObject2.GetComponent<TextMeshProUGUI>() ?? gameObject2.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val6).enableWordWrapping = false;
			((TMP_Text)val6).overflowMode = (TextOverflowModes)0;
			Transform obj3 = _mutators.transform.Find("Ironman Toggle/Background/Label (1)");
			object font2;
			if (obj3 == null)
			{
				font2 = null;
			}
			else
			{
				TextMeshProUGUI component2 = ((Component)obj3).GetComponent<TextMeshProUGUI>();
				font2 = ((component2 != null) ? ((TMP_Text)component2).font : null);
			}
			((TMP_Text)val6).font = (TMP_FontAsset)font2;
			((TMP_Text)val6).text = "MPMod Discord";
			((TMP_Text)val6).fontSize = 24f;
			Button val7 = gameObject2.AddComponent<Button>();
			ButtonClickedEvent onClick2 = val7.onClick;
			object obj4 = <>c.<>9__31_1;
			if (obj4 == null)
			{
				UnityAction val8 = delegate
				{
					Application.OpenURL("https://discord.gg/DVr4h6Gc9w");
				};
				<>c.<>9__31_1 = val8;
				obj4 = (object)val8;
			}
			((UnityEvent)onClick2).AddListener((UnityAction)obj4);
			gameObject.transform.SetSiblingIndex(1);
			gameObject2.transform.SetSiblingIndex(2);
			for (int i = 3; i < _mutators.transform.childCount; i++)
			{
				Object.Destroy((Object)(object)((Component)_mutators.transform.GetChild(i)).gameObject);
			}
			Transform transform = _mutators.transform;
			RectTransform val9 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			if (val9 != null)
			{
				LayoutRebuilder.ForceRebuildLayoutImmediate(val9);
			}
			return true;
		}

		private void BindTabEvents()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Expected O, but got Unknown
			if (!((Object)(object)_screenTabs == (Object)null) && !((Object)(object)_newTabButton == (Object)null) && !((Object)(object)_mpLobbyPane == (Object)null))
			{
				UI_TabGroup component = _screenTabs.GetComponent<UI_TabGroup>();
				if (!((Object)(object)component == (Object)null))
				{
					component.tabs = new List<Tab>
					{
						new Tab
						{
							name = "lobby",
							button = _newTabButton.GetComponent<Button>(),
							tabObject = _mpLobbyPane,
							buttonText = (TMP_Text)(object)((Component)_newTabButton.transform.Find("Text (TMP)")).GetComponent<TextMeshProUGUI>()
						},
						new Tab
						{
							name = "template",
							button = _tabButtonTemplate.GetComponent<Button>(),
							tabObject = _lobbyPaneTemplate,
							buttonText = (TMP_Text)(object)((Component)_tabButtonTemplate.transform.Find("Text (TMP)")).GetComponent<TextMeshProUGUI>(),
							onlyDev = true
						}
					};
				}
			}
		}

		public void Initialize()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			GameObject? mpButton = _mpButton;
			if (mpButton != null)
			{
				Button component = mpButton.GetComponent<Button>();
				if (component != null)
				{
					((UnityEventBase)component.onClick).RemoveAllListeners();
				}
			}
			GameObject? mpButton2 = _mpButton;
			if (mpButton2 != null)
			{
				Button component2 = mpButton2.GetComponent<Button>();
				if (component2 != null)
				{
					ButtonClickedEvent onClick = component2.onClick;
					object obj = <>c.<>9__33_0;
					if (obj == null)
					{
						UnityAction val = delegate
						{
							MPEventBusGame.NotifyRefreshLobbyList();
						};
						<>c.<>9__33_0 = val;
						obj = (object)val;
					}
					((UnityEvent)onClick).AddListener((UnityAction)obj);
				}
			}
			GameObject? mpButton3 = _mpButton;
			UI_MenuButton val2 = ((mpButton3 != null) ? mpButton3.GetComponent<UI_MenuButton>() : null);
			if ((Object)(object)val2 == (Object)null)
			{
				MPMain.LogError(Localization.Get("UI_Manager.MenuButtonComponentNotFound"));
				return;
			}
			GameObject? mpScreen = _mpScreen;
			val2.screen = ((mpScreen != null) ? mpScreen.GetComponent<UI_MenuScreen>() : null);
			GameObject gameObject = ((Component)_mainMenu.Find("Main Menu")).gameObject;
			UI_Menu component3 = gameObject.GetComponent<UI_Menu>();
			val2.Initialize(component3);
		}

		public void CreateLoadingScreen()
		{
			Transform obj = _mainMenu.Find("Loading");
			loadingTemplate = ((obj != null) ? ((Component)obj).gameObject : null);
			if ((Object)(object)loadingTemplate == (Object)null)
			{
				MPMain.LogError(Localization.Get("UI_Manager.LoadingTemplateNotFound"));
				return;
			}
			Transform val = _screens.Find("Screens");
			newloading = Object.Instantiate<GameObject>(loadingTemplate, val);
			newloading.AddComponent<UI_LoadingDisplay>();
			newloading.SetActive(true);
			newloading.transform.SetSiblingIndex(val.childCount - 1);
		}

		private void FixLerpComponent(GameObject target)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			UI_LerpOpen component = target.GetComponent<UI_LerpOpen>();
			if (!((Object)(object)component == (Object)null))
			{
				Type typeFromHandle = typeof(UI_LerpOpen);
				BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.NonPublic;
				string[] array = new string[3] { "rootPositon", "rootPosition", "targetPosition" };
				string[] array2 = new string[2] { "rootScale", "targetSize" };
				string[] array3 = array;
				foreach (string name in array3)
				{
					typeFromHandle.GetField(name, bindingAttr)?.SetValue(component, Vector3.zero);
				}
				string[] array4 = array2;
				foreach (string name2 in array4)
				{
					typeFromHandle.GetField(name2, bindingAttr)?.SetValue(component, Vector3.one);
				}
			}
		}

		private bool Error(string msg)
		{
			MPMain.LogError(msg);
			return false;
		}

		public void DisplayMessage(string message, UIDisplayType type)
		{
			switch (type)
			{
			case UIDisplayType.AscentHeader:
				CL_GameManager.gMan.uiMan.ascentHeader.ShowText(message);
				break;
			case UIDisplayType.TipHeader:
				CL_GameManager.gMan.uiMan.tipHeader.ShowText(message);
				break;
			case UIDisplayType.Header:
				CL_GameManager.gMan.uiMan.header.ShowText(message);
				break;
			case UIDisplayType.HighscoreHeader:
				CL_GameManager.gMan.uiMan.highscoreHeader.ShowText(message);
				break;
			}
		}
	}
}
namespace WKMPMod.RemotePlayer
{
	public abstract class BaseRemoteFactory
	{
		private GameObject _cachedPrefab;

		public string PrefabName { get; set; }

		public string FactoryId { get; set; }

		public GameObject Create(string bundlePath)
		{
			if ((Object)(object)_cachedPrefab == (Object)null)
			{
				_cachedPrefab = LoadAndPrepare(bundlePath);
				if ((Object)(object)_cachedPrefab == (Object)null)
				{
					MPMain.LogError(Localization.Get("RPBaseFactory.PrefabNotLoaded", PrefabName));
					return null;
				}
			}
			return Object.Instantiate<GameObject>(_cachedPrefab);
		}

		public GameObject LoadAndPrepare(string path)
		{
			AssetBundle val = null;
			GameObject val2 = null;
			try
			{
				val = AssetBundle.LoadFromFile(path);
				if ((Object)(object)val == (Object)null)
				{
					MPMain.LogError(Localization.Get("RPBaseFactory.UnableToLoadResources"));
					return null;
				}
				val2 = val.LoadAsset<GameObject>(PrefabName);
				if ((Object)(object)val2 == (Object)null)
				{
					MPMain.LogError(Localization.Get("RPBaseFactory.PrefabNotLoaded", PrefabName));
					return null;
				}
				ProcessPrefabMarkers(val2);
				FixShaders(val2);
				AddFactoryId(val2);
				OnPrepare(val2, val);
			}
			catch (Exception ex)
			{
				MPMain.LogError(Localization.Get("RPBaseFactory.PreFabProcessingError", ex.GetType().Name, ex.Message, ex.StackTrace));
				val2 = null;
			}
			finally
			{
				if ((Object)(object)val != (Object)null)
				{
					val.Unload(false);
				}
			}
			return val2;
		}

		protected abstract void OnPrepare(GameObject prefab, AssetBundle bundle);

		public virtual void Cleanup(GameObject instance)
		{
			Object.Destroy((Object)(object)instance);
		}

		private void FixShaders(GameObject prefab)
		{
			Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if ((Object)(object)((Component)val).GetComponent<TMP_Text>() != (Object)null)
				{
					continue;
				}
				Material[] sharedMaterials = val.sharedMaterials;
				foreach (Material val2 in sharedMaterials)
				{
					if (!((Object)(object)val2 == (Object)null))
					{
						MPMain.LogInfo(Localization.Get("RPBaseFactory.MaterialShaderInfo", ((Object)val2).name, ((Object)val2.shader).name));
						Shader val3 = Shader.Find(((Object)val2.shader).name);
						if ((Object)(object)val3 != (Object)null)
						{
							val2.shader = val3;
							continue;
						}
						MPMain.LogError(Localization.Get("RPBaseFactory.ShaderNotFoundOnRenderer", ((Object)val2.shader).name, ((Object)val).name));
					}
				}
			}
		}

		public void ProcessPrefabMarkers(GameObject prefab)
		{
			MK_RemoteEntity[] componentsInChildren = prefab.GetComponentsInChildren<MK_RemoteEntity>(true);
			MK_RemoteEntity[] array = componentsInChildren;
			foreach (MK_RemoteEntity val in array)
			{
				MapMarkersToRemoteEntity(((Component)val).gameObject, val);
			}
			MK_ObjectTagger[] componentsInChildren2 = prefab.GetComponentsInChildren<MK_ObjectTagger>(true);
			MK_ObjectTagger[] array2 = componentsInChildren2;
			foreach (MK_ObjectTagger val2 in array2)
			{
				MapMarkersToObjectTagger(((Component)val2).gameObject, val2);
			}
			MK_CL_Handhold[] componentsInChildren3 = prefab.GetComponentsInChildren<MK_CL_Handhold>(true);
			MK_CL_Handhold[] array3 = componentsInChildren3;
			foreach (MK_CL_Handhold val3 in array3)
			{
				MapMarkersToCL_Handhold(((Component)val3).gameObject, val3);
			}
			LookAt[] componentsInChildren4 = prefab.GetComponentsInChildren<LookAt>(true);
			LookAt[] array4 = componentsInChildren4;
			foreach (LookAt val4 in array4)
			{
				SetLookAt(((Component)val4).gameObject, val4);
			}
		}

		private void MapMarkersToRemoteEntity(GameObject go, MK_RemoteEntity mk)
		{
			RemoteEntity remoteEntity = go.AddComponent<RemoteEntity>();
			if ((Object)(object)remoteEntity != (Object)null)
			{
				remoteEntity.DamageObject = mk.DamageObject;
			}
			else
			{
				MPMain.LogError(Localization.Get("RPBaseFactory.RemoteEntityAddFailed"));
			}
			Object.DestroyImmediate((Object)(object)mk);
		}

		private void MapMarkersToObjectTagger(GameObject go, MK_ObjectTagger mk)
		{
			ObjectTagger val = go.GetComponent<ObjectTagger>() ?? go.AddComponent<ObjectTagger>();
			if ((Object)(object)val != (Object)null)
			{
				foreach (string tag in mk.tags)
				{
					if (!val.tags.Contains(tag))
					{
						val.tags.Add(tag);
					}
				}
			}
			else
			{
				MPMain.LogError(Localization.Get("RPBaseFactory.ObjectTaggerAddFailed"));
			}
			Object.DestroyImmediate((Object)(object)mk);
		}

		private void MapMarkersToCL_Handhold(GameObject go, MK_CL_Handhold mk)
		{
			CL_Handhold val = go.AddComponent<CL_Handhold>();
			if ((Object)(object)val != (Object)null)
			{
				val.activeEvent = mk.activeEvent;
				val.stopEvent = mk.stopEvent;
				val.handholdRenderer = mk.handholdRenderer ?? go.GetComponent<Renderer>();
			}
			else
			{
				MPMain.LogError(Localization.Get("RPBaseFactory.CL_HandholdAddFailed"));
			}
			Object.DestroyImmediate((Object)(object)mk);
		}

		private void SetLookAt(GameObject go, LookAt mk)
		{
			mk.userScale = MPConfig.NameTagScale;
		}

		private void AddFactoryId(GameObject prefab)
		{
			ObjectIdentity val = prefab.AddComponent<ObjectIdentity>();
			val.FactoryKey = FactoryId;
		}

		public static void ListAllAssetsInBundle(AssetBundle bundle)
		{
			MPMain.LogInfo("--- 开始输出 AssetBundle 内容清单: [" + ((Object)bundle).name + "] ---");
			string[] allAssetNames = bundle.GetAllAssetNames();
			if (allAssetNames.Length == 0)
			{
				MPMain.LogWarning("警告:该 AssetBundle 是空的!");
				return;
			}
			string[] array = allAssetNames;
			foreach (string text in array)
			{
				Object val = bundle.LoadAsset(text);
				string text2 = ((val != (Object)null) ? ((object)val).GetType().Name : "Unknown Type");
				MPMain.LogInfo("[资源清单] 路径: " + text + " | 类型: " + text2);
			}
			MPMain.LogInfo($"--- 清单输出完毕,共计 {allAssetNames.Length} 个资源 ---");
		}
	}
	public class SlugcatFactory : BaseRemoteFactory
	{
		private const string TMP_DISTANCE_FIELD_OVERLAY_MAT = "assets/projects/materials/textmeshpro_distance field overlay.mat";

		private const string GAME_TMP_FONT_ASSET = "Ticketing SDF";

		protected override void OnPrepare(GameObject prefab, AssetBundle bundle)
		{
			FixTMPComponent(prefab, bundle);
		}

		public override void Cleanup(GameObject instance)
		{
			base.Cleanup(instance);
		}

		private void FixTMPComponent(GameObject prefab, AssetBundle bundle)
		{
			TMP_Text[] componentsInChildren = prefab.GetComponentsInChildren<TMP_Text>(true);
			foreach (TMP_Text val in componentsInChildren)
			{
				MPMain.LogInfo(Localization.Get("RPSlugcatFactory.SpecializingTMPComponent", ((Object)val).name));
				TMP_FontAsset val2 = ((IEnumerable<TMP_FontAsset>)Resources.FindObjectsOfTypeAll<TMP_FontAsset>()).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => ((Object)f).name == "Ticketing SDF"));
				if ((Object)(object)val2 == (Object)null)
				{
					MPMain.LogError(Localization.Get("RPSlugcatFactory.FontAssetNotFound", "Ticketing SDF"));
					continue;
				}
				val.font = val2;
				Material val3 = bundle.LoadAsset<Material>("assets/projects/materials/textmeshpro_distance field overlay.mat");
				Material fontMaterial = val.fontMaterial;
				if ((Object)(object)fontMaterial != (Object)null && (Object)(object)val3 != (Object)null)
				{
					fontMaterial.shader = val3.shader;
					MPMain.LogInfo(Localization.Get("RPSlugcatFactory.ImplementOverlayViaShader"));
				}
				else
				{
					MPMain.LogError(Localization.Get("RPSlugcatFactory.UnableToLoadMaterial", "assets/projects/materials/textmeshpro_distance field overlay.mat"));
				}
			}
		}
	}
	public class RPContainer
	{
		private RemotePlayer _remotePlayer;

		private RemoteHand _remoteLeftHand;

		private RemoteHand _remoteRightHand;

		private RemoteTag _remoteTag;

		private RemoteEntity[] _remoteEntities;

		private int _initializationCount = 5;

		private bool _isDead = false;

		private TickTimer _deathTick = new TickTimer(0.5f);

		public ulong PlayerId { get; set; }

		public string PlayerName { get; set; }

		public GameObject PlayerObject { get; private set; }

		public PlayerData PlayerData
		{
			get
			{
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: 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_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: 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_006e: Unknown result type (might be due to invalid IL or missing references)
				//IL_006f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: 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_007f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0084: Unknown result type (might be due to invalid IL or missing references)
				//IL_0085: 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)
				PlayerData val = default(PlayerData);
				val.playId = PlayerId;
				val.TimestampTicks = DateTime.UtcNow.Ticks;
				val.IsTeleport = true;
				PlayerData result = val;
				((PlayerData)(ref result)).Position = PlayerObject.transform.position;
				((PlayerData)(ref result)).Rotation = PlayerObject.transform.rotation;
				result.LeftHand = default(HandData);
				result.RightHand = default(HandData);
				return result;
			}
		}

		public RPContainer(ulong playId)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//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_003f: Unknown result type (might be due to invalid IL or missing references)
			PlayerId = playId;
			Friend val = new Friend(SteamId.op_Implicit(PlayerId));
			PlayerName = ((Friend)(ref val)).Name;
		}

		public bool Initialize(GameObject playerInstance, Transform persistentParent = null)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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)
			if ((Object)(object)playerInstance == (Object)null)
			{
				return false;
			}
			try
			{
				PlayerObject = playerInstance;
				if ((Object)(object)persistentParent != (Object)null)
				{
					PlayerObject.transform.SetParent(persistentParent, false);
				}
				InitializeAllComponent(PlayerObject);
				InitializeAllComponentData();
				PlayerData val = default(PlayerData);
				val.IsTeleport = true;
				((PlayerData)(ref val)).Position = new Vector3(0f, -2f, 0f);
				PlayerData playerData = val;
				HandlePlayerData(ref playerData);
				MPMain.LogInfo(Localization.Get("RPContainer.MappingSucceeded", PlayerId.ToString()));
				return true;
			}
			catch (Exception ex)
			{
				MPMain.LogError(Localization.Get("RPContainer.MappingFailed", PlayerId.ToString(), ex.Message));
				if ((Object)(object)PlayerObject != (Object)null)
				{
					Object.Destroy((Object)(object)PlayerObject);
				}
				return false;
			}
		}

		public void InitializeAllComponent(GameObject instance)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Invalid comparison between Unknown and I4
			//IL_0051: Unknown result type (might be

WKMultiPlayerMod.Shared.dll

Decompiled 5 days ago
using System;
using System.Buffers;
using System.Buffers.Binary;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
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;

[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+c664af9c6db0f762604a4131fc6e270d3b64a4b5")]
[assembly: AssemblyProduct("WKMultiPlayerMod.Shared")]
[assembly: AssemblyTitle("WKMultiPlayerMod.Shared")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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;
		}
	}
}
public enum HandType
{
	Left,
	Right
}
[Serializable]
public struct PlayerData : INetworkSerializable
{
	[Serializable]
	public struct HandData : INetworkSerializable
	{
		public HandType handType;

		public float PosX;

		public float PosY;

		public float PosZ;

		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 void Serialize(DataWriter writer)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			writer.Put((byte)handType);
			writer.Put(Position);
		}

		public void Deserialize(DataReader reader)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			handType = (HandType)reader.GetByte();
			Position = reader.GetVector3();
		}
	}

	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)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		writer.Put(playId).Put(TimestampTicks);
		writer.Put(Position).Put(Rotation);
		writer.Put(LeftHand.Position).Put(RightHand.Position);
		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)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		playId = reader.GetULong();
		TimestampTicks = reader.GetLong();
		Position = reader.GetVector3();
		Rotation = reader.GetQuaternion();
		LeftHand.Position = reader.GetVector3();
		RightHand.Position = reader.GetVector3();
		IsTeleport = reader.GetBool();
	}
}
namespace WKMPMod.Util
{
	public static class DictionaryExtensions
	{
		public static List<ulong> FindByKeySuffix<T>(this Dictionary<ulong, T> dictionary, ulong suffix)
		{
			List<ulong> list = new List<ulong>();
			if (dictionary == null || dictionary.Count == 0)
			{
				return list;
			}
			ulong num = CalculateDivisor(suffix);
			foreach (KeyValuePair<ulong, T> item in dictionary)
			{
				if (item.Key % num == suffix)
				{
					list.Add(item.Key);
				}
			}
			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;

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

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

		public bool IsTickReached => Time.time - _lastTickTime >= _interval;

		public TickTimer(float tick)
		{
			_interval = tick;
			_lastTickTime = 0f - _interval;
		}

		public TickTimer(int hz)
		{
			_interval = 1f / (float)hz;
			_lastTickTime = 0f - _interval;
		}

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

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

		public void Reset()
		{
			_lastTickTime = Time.time;
		}

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

		public void ForceTick()
		{
			_lastTickTime = Time.time;
		}
	}
}
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 float AllActive = 1f;

		public float HammerActive = 1f;

		public float RebarActive = 1f;

		public float ReturnRebarActive = 1f;

		public float RebarExplosionActive = 1f;

		public float ExplosionActive = 1f;

		public float PitonActive = 1f;

		public float FlareActive = 1f;

		public float IceActive = 1f;

		public float OtherActive = 1f;

		public GameObject DamageObject;
	}
}
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 @int = GetInt();
			if (@int <= 0)
			{
				return string.Empty;
			}
			if (@int > AvailableBytes)
			{
				throw new Exception("String length out of range");
			}
			string @string = Encoding.UTF8.GetString(_data.Span.Slice(_position, @int));
			_position += @int;
			return @string;
		}

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

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

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

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

		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 @int = GetInt();
			if (@int <= 0)
			{
				return new List<T>(0);
			}
			List<T> list = new List<T>(@int);
			for (int i = 0; i < @int; 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 @int = GetInt();
			existingList.Clear();
			for (int i = 0; i < @int; 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<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);
	}
}
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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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 = ((!(num < 10f)) ? num : (0.8f * num + 2f));
				float num3 = num2 * baseScale * userScale;
				((Component)this).transform.localScale = new Vector3(num3, num3, num3);
			}
		}
	}
	public class ObjectIdentity : MonoBehaviour
	{
		public string FactoryKey = "";
	}
	public class RemoteHand : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <ResetTeleportFlag>d__10 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public RemoteHand <>4__this;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>4__this._isTeleporting = false;
					return false;
				}
			}

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

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[Header("左右手")]
		public HandType hand;

		[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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: 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 UpdateFromHandData(ref PlayerData.HandData handData)
		{
			//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)
			_isTeleporting = false;
			_targetPosition = handData.Position;
		}

		public void Teleport(Vector3 position)
		{
			//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)
			_isTeleporting = true;
			((Component)this).transform.position = position;
			_targetPosition = position;
			_velocity = Vector3.zero;
			((MonoBehaviour)this).StartCoroutine(ResetTeleportFlag());
		}

		[IteratorStateMachine(typeof(<ResetTeleportFlag>d__10))]
		private IEnumerator ResetTeleportFlag()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ResetTeleportFlag>d__10(0)
			{
				<>4__this = this
			};
		}
	}
	public class RemotePlayer : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <ResetTeleportFlag>d__10 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public RemotePlayer <>4__this;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>4__this._isTeleporting = false;
					return false;
				}
			}

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

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[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());
		}

		[IteratorStateMachine(typeof(<ResetTeleportFlag>d__10))]
		private IEnumerator ResetTeleportFlag()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ResetTeleportFlag>d__10(0)
			{
				<>4__this = this
			};
		}
	}
	public class RemoteTag : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <MessageTimeoutRoutine>d__20 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public RemoteTag <>4__this;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(15f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>4__this._message = "";
					<>4__this.RefreshName();
					<>4__this._messageTimeoutCoroutine = null;
					return false;
				}
			}

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

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private Transform? _cameraTransform;

		private TextMeshPro? _textMeshPro;

		private float _lastUpdateDistance;

		private TickTimer updateTick = new TickTimer(1);

		[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()
		{
			_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));
			}
		}

		[IteratorStateMachine(typeof(<MessageTimeoutRoutine>d__20))]
		private IEnumerator MessageTimeoutRoutine()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <MessageTimeoutRoutine>d__20(0)
			{
				<>4__this = this
			};
		}
	}
	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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_0055: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)target == (Object)null))
			{
				Vector3 val = target.position - ((Component)this).transform.position;
				float magnitude = ((Vector3)(ref val)).magnitude;
				if (!(magnitude < 0.0001f))
				{
					((Component)this).transform.rotation = Quaternion.FromToRotation(Vector3.up, val);
					float num = magnitude / originalLength;
					num = Mathf.Clamp(num, minScale, maxScale);
					((Component)this).transform.localScale = new Vector3(1f, num, 1f);
				}
			}
		}
	}
}