Decompiled source of Simple Multi Player v1.5.0

WKMultiPlayerMod.dll

Decompiled 2 hours 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.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
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.0.0")]
[assembly: AssemblyInformationalVersion("1.5.0+2c46e8ef362b1d709da9fc9b8688cf017df8fb0e")]
[assembly: AssemblyProduct("WKMultiPlayerMod")]
[assembly: AssemblyTitle("WKMultiPlayerMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.5.0.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 PitonSyncManager
	{
		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 static readonly Dictionary<string, NetworkedPiton> _pitons = new Dictionary<string, NetworkedPiton>();

		private static ulong _nextLocalId = 1uL;

		private static GameObject _pitonWorldPrefab;

		public static bool ApplyingRemoteState { get; private set; }

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

		public static void RegisterNewLocalPiton(HandItem_Piton source, HashSet<int> knownHandholds)
		{
			if (!MPCore.CanSync() || ApplyingRemoteState || (Object)(object)source == (Object)null || knownHandholds == null)
			{
				return;
			}
			CL_Handhold val = FindNewPitonHandhold(source, knownHandholds);
			if (!((Object)(object)val == (Object)null))
			{
				NetworkedPiton orCreateIdentity = GetOrCreateIdentity(((Component)val).gameObject);
				if (string.IsNullOrEmpty(orCreateIdentity.NetworkId))
				{
					orCreateIdentity.NetworkId = $"{MonoSingleton<MPSteamworks>.Instance.UserSteamId}:{_nextLocalId++}";
					orCreateIdentity.OwnerId = MonoSingleton<MPSteamworks>.Instance.UserSteamId;
					orCreateIdentity.IsRemote = false;
				}
				_pitons[orCreateIdentity.NetworkId] = orCreateIdentity;
				Broadcast(orCreateIdentity, PitonSyncAction.Create, force: true);
			}
		}

		public static void BroadcastHammerUpdate(CL_Handhold handhold)
		{
			if (MPCore.CanSync() && !ApplyingRemoteState && !((Object)(object)handhold == (Object)null))
			{
				NetworkedPiton component = ((Component)handhold).GetComponent<NetworkedPiton>();
				if (!((Object)(object)component == (Object)null) && !string.IsNullOrEmpty(component.NetworkId))
				{
					Broadcast(component, PitonSyncAction.Update, force: true);
				}
			}
		}

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

		public static void HandlePitonState(ulong senderId, DataReader reader)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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)
			PitonSyncAction @byte = (PitonSyncAction)reader.GetByte();
			string @string = 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, 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 PitonSync] Failed to apply {@byte} for {@string}: {ex.Message}");
			}
			finally
			{
				ApplyingRemoteState = false;
			}
		}

		private static void ApplyCreate(ulong senderId, string networkId, Vector3 position, Quaternion rotation, float secureAmount, bool secure, bool active)
		{
			//IL_0022: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: 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)
			if (_pitons.TryGetValue(networkId, out NetworkedPiton value) && (Object)(object)value != (Object)null)
			{
				ApplyState(value, position, rotation, secureAmount, secure, active);
				return;
			}
			GameObject pitonWorldPrefab = GetPitonWorldPrefab();
			if ((Object)(object)pitonWorldPrefab == (Object)null)
			{
				MPMain.LogError("[MP PitonSync] Could not find a piton world prefab.");
				return;
			}
			GameObject val = Object.Instantiate<GameObject>(pitonWorldPrefab, position, rotation);
			Transform currentLevelParentRoot = WorldLoader.GetCurrentLevelParentRoot();
			if ((Object)(object)currentLevelParentRoot != (Object)null)
			{
				val.transform.SetParent(currentLevelParentRoot);
			}
			TryAddPlacedObjectToLevel(val);
			CL_Handhold val2 = val.GetComponent<CL_Handhold>() ?? val.GetComponentInChildren<CL_Handhold>(true);
			NetworkedPiton orCreateIdentity = GetOrCreateIdentity(((Object)(object)val2 != (Object)null) ? ((Component)val2).gameObject : val);
			orCreateIdentity.NetworkId = networkId;
			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 NetworkedPiton value) && !((Object)(object)value == (Object)null))
			{
				ApplyState(value, position, rotation, secureAmount, secure, active);
			}
		}

		private static void ApplyRemove(string networkId)
		{
			if (_pitons.TryGetValue(networkId, out NetworkedPiton 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(NetworkedPiton 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 component = ((Component)identity).GetComponent<CL_Handhold>();
			if ((Object)(object)component != (Object)null)
			{
				component.Initialize();
				component.secureAmount = secureAmount;
				component.secure = secure;
			}
			((Component)identity).gameObject.SetActive(active);
			RecordState(identity, component);
		}

		private static CL_Handhold FindNewPitonHandhold(HandItem_Piton source, HashSet<int> knownHandholds)
		{
			//IL_0002: 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_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_0073: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			RaycastHit aimCircleHit = ((HandItem)source).GetAimCircleHit();
			Vector3 point = ((RaycastHit)(ref aimCircleHit)).point;
			CL_Handhold result = null;
			float num = float.MaxValue;
			CL_Handhold[] array = Object.FindObjectsOfType<CL_Handhold>();
			foreach (CL_Handhold val in array)
			{
				if (!((Object)(object)val == (Object)null) && !knownHandholds.Contains(((Object)((Component)val).gameObject).GetInstanceID()) && LooksLikePiton(source, ((Component)val).gameObject))
				{
					Vector3 val2 = ((Component)val).transform.position - point;
					float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
					if (sqrMagnitude < num)
					{
						result = val;
						num = sqrMagnitude;
					}
				}
			}
			return result;
		}

		private static bool LooksLikePiton(HandItem_Piton source, GameObject obj)
		{
			if ((Object)(object)obj == (Object)null)
			{
				return false;
			}
			if ((Object)(object)source != (Object)null && (Object)(object)source.pitonWorldObject != (Object)null)
			{
				string name = ((Object)source.pitonWorldObject).name;
				if (!string.IsNullOrEmpty(name) && ((Object)obj).name.StartsWith(name, StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
			}
			return ((Object)obj).name.IndexOf("piton", StringComparison.OrdinalIgnoreCase) >= 0;
		}

		private static GameObject GetPitonWorldPrefab()
		{
			if ((Object)(object)_pitonWorldPrefab != (Object)null)
			{
				return _pitonWorldPrefab;
			}
			HandItem_Piton[] array = Resources.FindObjectsOfTypeAll<HandItem_Piton>();
			foreach (HandItem_Piton val in array)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)val.pitonWorldObject != (Object)null)
				{
					_pitonWorldPrefab = val.pitonWorldObject;
					return _pitonWorldPrefab;
				}
			}
			return null;
		}

		private static void TryAddPlacedObjectToLevel(GameObject pitonObject)
		{
			if (!WorldLoader.initialized || (Object)(object)pitonObject == (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] { pitonObject });
			}
			catch (Exception ex)
			{
				MPMain.LogWarning("[MP PitonSync] Could not register remote piton as placed object: " + ex.Message);
			}
		}

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

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

		private static bool HasMeaningfulStateChange(NetworkedPiton 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(NetworkedPiton 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;
			}
		}
	}
}
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.Where((Lobby l) => !LobbyDic.ContainsKey(SteamId.op_Implicit(((Lobby)(ref l)).Id))))
			{
				Lobby lobby2 = item;
				UI_LobbyJoinButton newButton = CreateLobbyButton(lobby2);
				if ((Object)(object)newButton != (Object)null)
				{
					LobbyDic[SteamId.op_Implicit(((Lobby)(ref lobby2)).Id)] = newButton;
					((Lobby)(ref lobby2)).Refresh();
				}
			}
		}

		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(1f);

		public ulong PlayerId { get; set; }

		public string PlayerName { get; set; }

		public GameObject PlayerObject { get; private set; }

		public PlayerData PlayerData
		{
			get
			{
				//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_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Expected O, but got Unknown
				//IL_0039: 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_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0064: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_0074: Unknown result type (might be due to invalid IL or missing references)
				PlayerData val = new PlayerData
				{
					playId = PlayerId,
					TimestampTicks = DateTime.UtcNow.Ticks,
					IsTeleport = true
				};
				val.Position = PlayerObject.transform.position;
				val.Rotation = PlayerObject.transform.rotation;
				val.LeftHand = default(HandData);
				val.RightHand = default(HandData);
				return val;
			}
		}

		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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_007e: Expected O, but got Unknown
			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();
				HandlePlayerData(new PlayerData
				{
					IsTeleport = true,
					Position = new Vector3(0f, 0f, 0f)
				});
				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 due to invalid IL or missing references)
			//IL_0057: Invalid comparison between Unknown and I4
			_remotePlayer = instance.GetComponentInChildren<RemotePlayer>();
			_remoteTag = instance.GetComponentInChildren<RemoteTag>();
			_remoteEntities = instance.GetComponentsInChildren<RemoteEntity>();
			RemoteHand[] componentsInChildren = instance.GetComponentsInChildren<RemoteHand>();
			RemoteHand[] array = componentsInChildren;
			foreach (RemoteHand val in array)
			{
				if ((int)val.hand == 0)
				{
					_remoteLeftHand = val;
				}
				else if ((int)val.hand == 1)
				{
					_remoteRightHand = val;
				}
			}
		}

		private void InitializeAllComponentData()
		{
			_remoteTag.Initialize(PlayerId, PlayerName);
			if (_remoteEntities != null)
			{
				RemoteEntity[] remoteEntities = _remoteEntities;
				foreach (RemoteEntity remoteEntity in remoteEntities)
				{
					remoteEntity.PlayerId = PlayerId;
				}
			}
		}

		public void Destroy()
		{
			PlayerObject = null;
			_remotePlayer = null;
			_remoteLeftHand = null;
			_remoteRightHand = null;
			_remoteTag = null;
			_remoteEntities = null;
		}

		public void HandlePlayerData(PlayerData playerData)
		{
			//IL_00c7: 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_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: 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_0078: 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)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			if (_isDead && _deathTick.IsTickReached)
			{
				PlayerObject.SetActive(true);
				_isDead = false;
			}
			if (playerData.IsTeleport || _initializationCount > 0)
			{
				playerData.IsTeleport = true;
				_initializationCount--;
			}
			if (playerData.IsTeleport)
			{
				_remotePlayer.Teleport(playerData.Position, (Quaternion?)playerData.Rotation);
				Vector3 position = ((HandData)(ref playerData.LeftHand)).Position;
				_remoteLeftHand.Teleport(position);
				Vector3 position2 = ((HandData)(ref playerData.RightHand)).Position;
				_remoteRightHand.Teleport(position2);
			}
			else
			{
				_remotePlayer.UpdateFromPlayerData(playerData.Position, playerData.Rotation);
				_remoteLeftHand.UpdateFromHandData(playerData.LeftHand);
				_remoteRightHand.UpdateFromHandData(playerData.RightHand);
			}
		}

		public void HandleNameTag(string text)
		{
			if (!string.IsNullOrEmpty(text))
			{
				if ((Object)(object)_remoteTag == (Object)null)
				{
					MPMain.LogError(Localization.Get("RPContainer.NameTagComponentMissing"));
				}
				else
				{
					_remoteTag.Message = text;
				}
			}
		}

		public void HandleDeath()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = PlayerObject.transform.position;
			Quaternion rotation = PlayerObject.transform.rotation;
			GameObject assetGameObject = MPAssetManager.GetAssetGameObject("Gib_Medium");
			if ((Object)(object)assetGameObject != (Object)null)
			{
				Object.Instantiate<GameObject>(assetGameObject, position, rotation);
			}
			PlayerObject.SetActive(false);
			_isDead = true;
			_deathTick.Reset();
		}

		public static void AddHandHold(GameObject gameObject)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			ObjectTagger val = gameObject.AddComponent<ObjectTagger>();
			if ((Object)(object)val != (Object)null)
			{
				val.tags.Add("Handhold");
			}
			CL_Handhold val2 = gameObject.AddComponent<CL_Handhold>();
			if ((Object)(object)val2 != (Object)null)
			{
				val2.stopEvent = new UnityEvent();
				val2.activeEvent = new UnityEvent();
			}
			Renderer component = gameObject.GetComponent<Renderer>();
			if ((Object)(object)component != (Object)null)
			{
				gameObject.GetComponent<CL_Handhold>().handholdRenderer = component;
			}
		}
	}
	public class RPFactoryManager : Singleton<RPFactoryManager>
	{
		public class FactoryRegistration
		{
			public BaseRemoteFactory Factory { get; set; }

			public string BundlePath { get; set; }
		}

		public static Dictionary<string, FactoryRegistration> factories = new Dictionary<string, FactoryRegistration>();

		private RPFactoryManager()
		{
			RegisterDefaultFactories();
		}

		public static void RegisterFactory(string factoryId, BaseRemoteFactory factory, string prefabName, string bundlePath)
		{
			if (factories.ContainsKey(factoryId))
			{
				MPMain.LogWarning(Localization.Get("RPFactoryManager.FactoryAlreadyRegistered", factoryId));
				return;
			}
			factory.PrefabName = prefabName;
			factory.FactoryId = factoryId;
			factories.Add(factoryId, new FactoryRegistration
			{
				Factory = factory,
				BundlePath = bundlePath
			});
			MPMain.LogInfo(Localization.Get("RPFactoryManager.FactoryRegistered", factoryId));
		}

		public GameObject Create(string factoryId)
		{
			if (factories.TryGetValue(factoryId, out FactoryRegistration value))
			{
				return value.Factory.Create(value.BundlePath);
			}
			MPMain.LogError(Localization.Get("RPFactoryManager.FactoryNotFound", factoryId));
			if (factories.TryGetValue("default", out FactoryRegistration value2))
			{
				return value.Factory.Create(value2.BundlePath);
			}
			MPMain.LogError(Localization.Get("RPFactoryManager.FactoryNotFound", "default"));
			return null;
		}

		public void Cleanup(GameObject instance)
		{
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			ObjectIdentity component = instance.GetComponent<ObjectIdentity>();
			if ((Object)(object)component == (Object)null || string.IsNullOrEmpty(component.FactoryKey))
			{
				MPMain.LogError(Localization.Get("RPFactoryManager.CannotDetermineFactory"));
				Object.Destroy((Object)(object)instance);
				return;
			}
			if (factories.TryGetValue(component.FactoryKey, out FactoryRegistration value))
			{
				try
				{
					value.Factory.Cleanup(instance);
					return;
				}
				catch (Exception ex)
				{
					MPMain.LogError(Localization.Get("RPFactoryManager.FactoryCleanupException", ((Object)component).name, ex));
					Object.Destroy((Object)(object)instance);
					return;
				}
			}
			MPMain.LogError(Localization.Get("RPFactoryManager.FactoryNotFoundCleanup", ((Object)component).name));
			Object.Destroy((Object)(object)instance);
		}

		private void RegisterDefaultFactories()
		{
			RegisterFactory("default", new SlugcatFactory(), "CapsulePlayerPrefab", Path.Combine(MPMain.path, "player_prefab"));
			RegisterFactory("slugcat", new SlugcatFactory(), "SlugcatPlayerPrefab", Path.Combine(MPMain.path, "player_prefab"));
		}

		public void ListAllFactory()
		{
			foreach (var (text2, factoryRegistration2) in factories)
			{
				MPMain.LogWarning(Localization.Get("RPFactoryManager.DebugFactoryInfo", text2, factoryRegistration2.Factory.PrefabName, factoryRegistration2.BundlePath));
			}
		}
	}
	public class RPManager : Singleton<RPManager>
	{
		private TickTimer _debugTick = new TickTimer(5f);

		internal Dictionary<ulong, RPContainer> Players = new Dictionary<ulong, RPContainer>();

		private Transform _remotePlayersRoot;

		private RPManager()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			_ = Singleton<RPFactoryManager>.Instance;
		}

		public void Initialize(Transform RootTransform)
		{
			_remotePlayersRoot = RootTransform;
		}

		public void ResetAll()
		{
			foreach (RPContainer value in Players.Values)
			{
				Singleton<RPFactoryManager>.Instance.Cleanup(value.PlayerObject);
				value.Destroy();
			}
			Players.Clear();
		}

		public RPContainer PlayerCreate(ulong playId, string prefab)
		{
			if (Players.TryGetValue(playId, out RPContainer value))
			{
				return value;
			}
			RPContainer rPContainer = new RPContainer(playId);
			GameObject val = Singleton<RPFactoryManager>.Instance.Create(prefab);
			if ((Object)(object)val == (Object)null)
			{
				MPMain.LogError(Localization.Get("RPManager.FactoryCreateObjectFailed"));
				return null;
			}
			rPContainer.Initialize(val, _remotePlayersRoot);
			Players[playId] = rPContainer;
			return rPContainer;
		}

		public void PlayerRemove(ulong playId)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_0035: Unknown result type (might be due to invalid IL or missing ref

WKMultiPlayerMod.Shared.dll

Decompiled 2 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
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+2c46e8ef362b1d709da9fc9b8688cf017df8fb0e")]
[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;
		}
	}
}
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
{
	[Serializable]
	public struct HandData
	{
		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 enum HandType
	{
		Left,
		Right
	}
	[Serializable]
	public class PlayerData
	{
		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 static int CalculateSize => 69;

		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 DateTime Timestamp
		{
			get
			{
				return new DateTime(TimestampTicks);
			}
			set
			{
				TimestampTicks = value.Ticks;
			}
		}

		public PlayerData()
		{
			LeftHand = new HandData
			{
				handType = HandType.Left
			};
			RightHand = new HandData
			{
				handType = HandType.Right
			};
		}
	}
}
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(HandData handData)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			_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(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);
				}
			}
		}
	}
}

WKTestMod.dll

Decompiled 2 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using MPTestMod;
using Microsoft.CodeAnalysis;
using Steamworks;
using Steamworks.Data;
using UnityEngine;
using UnityEngine.SceneManagement;
using WKMPMod.Core;
using WKMPMod.Data;
using WKMPMod.RemotePlayer;
using WKMPMod.UI;
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("WKTestMod")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("WKTestMod")]
[assembly: AssemblyTitle("WKTestMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MPTestMod
{
	[BepInPlugin("shenxl.WKTestMod", "WKTest Mod", "1.4.2")]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGUID = "shenxl.WKTestMod";

		public const string ModName = "WKTest Mod";

		public const string ModVersion = "1.4.2";

		private Harmony _harmony;

		internal static ManualLogSource Logger;

		private void Awake()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			Logger.LogInfo((object)"[Test]Plugin shenxl.WKTestMod is loaded!");
			_harmony = new Harmony("shenxl.WKTestMod");
			_harmony.PatchAll();
		}
	}
}
namespace WKTestMod
{
	public class CheatsTest : MonoSingleton<CheatsTest>
	{
		public static void Main(string[] args)
		{
			if (args.Length == 0)
			{
				MPMain.LogError("[Test] 测试命令需要参数");
				return;
			}
			string text = args[0];
			if (1 == 0)
			{
			}
			switch (text)
			{
			case "0":
				RunCommand(delegate
				{
					CreateItem(args[1..]);
				});
				break;
			case "1":
				RunCommand(delegate
				{
					AddItemInInventory(args[1..]);
				});
				break;
			case "2":
				RunCommand(GetInventoryItems);
				break;
			case "3":
				RunCommand(AddItemInInventoryQuaternionTest);
				break;
			default:
				RunCommand(delegate
				{
					MPMain.LogError("[Test] 未知命令: " + args[0]);
				});
				break;
			}
			if (true)
			{
			}
		}

		private static bool RunCommand(Action action)
		{
			action();
			return true;
		}

		public static void CreateItem(string[] args)
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = default(Vector3);
			foreach (string text in args)
			{
				if (!(text != "None"))
				{
					continue;
				}
				GameObject assetGameObject = CL_AssetManager.GetAssetGameObject(text, "");
				if ((Object)(object)assetGameObject != (Object)null)
				{
					((Vector3)(ref val))..ctor(Random.Range(-1f, 1f), Random.Range(0f, 0.5f), Random.Range(-1f, 1f));
					GameObject val2 = Object.Instantiate<GameObject>(assetGameObject, new Vector3(0f, 0.5f, 0f) + val, Random.rotation);
					Rigidbody component = val2.GetComponent<Rigidbody>();
					if ((Object)(object)component != (Object)null)
					{
						Vector3 val3 = new Vector3(Random.Range(-1f, 1f), 1f, Random.Range(-1f, 1f));
						Vector3 normalized = ((Vector3)(ref val3)).normalized;
						float num = Random.Range(3f, 8f);
						component.AddForce(normalized * num, (ForceMode)1);
					}
				}
				else
				{
					MPMain.LogInfo("[Test] 生成物: " + text + " 不存在");
				}
			}
		}

		public static void GetInventoryItems()
		{
			Inventory instance = Inventory.instance;
			if ((Object)(object)instance != (Object)null)
			{
				List<Item> items = instance.GetItems(true, true);
				{
					foreach (Item item in items)
					{
						MPMain.LogInfo("[Test] 物品名称: " + item.itemName + ", 标签: " + item.itemTag + ", 预制体名称: " + item.prefabName);
					}
					return;
				}
			}
			MPMain.LogWarning("[Test] 库存不存在");
		}

		public static void AddItemInInventory(string[] args)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			Inventory instance = Inventory.instance;
			foreach (string text in args)
			{
				if (!(text != "None"))
				{
					continue;
				}
				GameObject assetGameObject = CL_AssetManager.GetAssetGameObject(text, "");
				if ((Object)(object)assetGameObject != (Object)null)
				{
					GameObject val = Object.Instantiate<GameObject>(assetGameObject, new Vector3(0f, 0.5f, 0f), Quaternion.identity);
					Item_Object component = val.GetComponent<Item_Object>();
					Item itemData = component.itemData;
					if ((Object)(object)component != (Object)null)
					{
						component.itemData.bagRotation = Quaternion.LookRotation(itemData.upDirection);
						instance.AddItemToInventoryCenter(component.itemData);
						((Component)component).gameObject.SetActive(false);
					}
					else
					{
						MPMain.LogInfo("[Test] 生成物: " + ((Object)val).name + " 不可放入库存");
					}
				}
				else
				{
					MPMain.LogInfo("[Test] 生成物: " + text + " 不存在");
				}
			}
		}

		public static void AddItemInInventoryQuaternionTest()
		{
			Inventory inventory = Inventory.instance;
			AddItemInInventoryQuaternionTest("Item_Rebar");
			AddItemInInventoryQuaternionTest("Item_Rebar");
			AddItemInInventoryQuaternionTest("Item_Rebar");
			AddItemInInventoryQuaternionTest("Item_Rebar_Explosive");
			AddItemInInventoryQuaternionTest("Item_RebarRope");
			AddItemInInventoryQuaternionTest("Item_Rebar_Holiday");
			AddItemInInventoryQuaternionTest("Item_RebarRope_Holiday");
			void AddItemInInventoryQuaternionTest(string arg)
			{
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				GameObject assetGameObject = CL_AssetManager.GetAssetGameObject(arg, "");
				Item_Object component = assetGameObject.GetComponent<Item_Object>();
				component.itemData.bagRotation = Quaternion.LookRotation(component.itemData.upDirection);
				inventory.AddItemToInventoryCenter(component.itemData);
				((Component)component).gameObject.SetActive(false);
			}
		}
	}
	public class GameTest : MonoSingleton<GameTest>
	{
		public static Dictionary<string, M_Gamemode> gamemodeMap = new Dictionary<string, M_Gamemode>();

		public static Stopwatch sw = new Stopwatch();

		public static void Main(string[] args)
		{
			if (args.Length == 0)
			{
				MPMain.LogError("测试命令需要参数");
				return;
			}
			string text = args[0];
			if (1 == 0)
			{
			}
			switch (text)
			{
			case "0":
				RunCommand(GetAllAssetGameObject);
				break;
			case "1":
				RunCommand(delegate
				{
					GetParticleEffectPrefab(args[1]);
				});
				break;
			case "2":
				RunCommand(GetAllDatabase);
				break;
			case "3":
				RunCommand(delegate
				{
					LoadGamemode(args[1..]);
				});
				break;
			case "4":
				RunCommand(GetAllFX);
				break;
			case "5":
				RunCommand(delegate
				{
					GetAssetGameObject(args[1..]);
				});
				break;
			case "6":
				RunCommand(delegate
				{
					//IL_0017: Unknown result type (might be due to invalid IL or missing references)
					FXManager.PlayParticle(args[1], new Vector3(1f, 1f, 1f), 5);
				});
				break;
			case "7":
				RunCommand(GetAllMap);
				break;
			default:
				RunCommand(delegate
				{
					MPMain.LogError("[Test] 未知命令: " + args[0]);
				});
				break;
			}
			if (true)
			{
			}
		}

		private static bool RunCommand(Action action)
		{
			action();
			return true;
		}

		public static void GetAllDatabase()
		{
			Dictionary<string, (string, string, string, M_Gamemode)> dictionary = new Dictionary<string, (string, string, string, M_Gamemode)>();
			Dictionary<string, M_Gamemode> dictionary2 = new Dictionary<string, M_Gamemode>();
			sw.Start();
			FieldInfo field = typeof(CL_AssetManager).GetField("activeDatabases", BindingFlags.Static | BindingFlags.NonPublic);
			if (field == null)
			{
				MPMain.LogError("[Test] 字段没找到");
				return;
			}
			Dictionary<string, WKDatabaseHolder> dictionary3 = (Dictionary<string, WKDatabaseHolder>)field.GetValue(null);
			string key;
			foreach (KeyValuePair<string, WKDatabaseHolder> item2 in dictionary3)
			{
				item2.Deconstruct(out key, out var value);
				string item = key;
				WKDatabaseHolder val = value;
				foreach (M_Gamemode gamemodeAsset in val.database.gamemodeAssets)
				{
					dictionary[((Object)gamemodeAsset).name] = (item, ((Object)val.database).name, val.id, gamemodeAsset);
				}
			}
			sw.Stop();
			long elapsedTicks = sw.ElapsedTicks;
			sw.Reset();
			sw.Start();
			M_Gamemode[] array = Resources.FindObjectsOfTypeAll<M_Gamemode>();
			M_Gamemode[] array2 = array;
			foreach (M_Gamemode val2 in array2)
			{
				if ((Object)(object)val2 != (Object)null)
				{
					dictionary2[((Object)val2).name] = val2;
				}
			}
			sw.Stop();
			long elapsedTicks2 = sw.ElapsedTicks;
			foreach (KeyValuePair<string, (string, string, string, M_Gamemode)> item3 in dictionary)
			{
				item3.Deconstruct(out key, out var value2);
				string text = key;
				(string, string, string, M_Gamemode) tuple = value2;
				MPMain.LogWarning("[Test] name:" + text + " HolderId:" + tuple.Item1 + " databaseName:" + tuple.Item2 + " databaseId:" + tuple.Item3 + " gamemodeName" + tuple.Item4.gamemodeName);
			}
			foreach (KeyValuePair<string, M_Gamemode> item4 in dictionary2)
			{
				item4.Deconstruct(out key, out var value3);
				string text2 = key;
				M_Gamemode val3 = value3;
				MPMain.LogWarning("[Test] name:" + text2 + " gamemodeName:" + val3.gamemodeName);
			}
			MPMain.LogWarning($"[Test] 方法1耗时: {elapsedTicks} ticks");
			MPMain.LogWarning($"[Test] 方法2耗时: {elapsedTicks2} ticks");
		}

		public static void LoadGamemode(string[] args)
		{
			string key = string.Join(" ", args);
			if (!gamemodeMap.TryGetValue(key, out var value))
			{
				MPMain.LogError("[Test] 未找到对应游戏模式");
			}
			else if ((Object)(object)UI_GamemodeScreen.instance == (Object)null)
			{
				MPMain.LogError("[Test] UI_GamemodeScreen.instance为空");
				CL_GameManager.gamemode = value;
				SettingsManager.SetSetting(new string[2] { "g_iron", "true" });
				SettingsManager.SetSetting(new string[2] { "g_hard", "true" });
				SceneManager.LoadScene(value.gamemodeScene);
			}
			else
			{
				UI_GamemodeScreen.instance.Initialize(value);
				UI_GamemodeScreen.instance.LoadGamemode();
			}
		}

		public static void GetAllAssetGameObject()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			GameObject[] array = Resources.FindObjectsOfTypeAll<GameObject>();
			GameObject[] array2 = array;
			foreach (GameObject val in array2)
			{
				Scene scene = val.scene;
				if (((Scene)(ref scene)).name == null)
				{
					MPMain.LogWarning("[Test]找到预制体 类型: " + (((int)((Object)val).hideFlags == 0) ? "普通预制体" : "内部资源"));
					break;
				}
			}
		}

		public static void GetAssetGameObject(string[] args)
		{
			string text = "";
			if (args.Length < 1)
			{
				MPMain.LogError("[Test]需要至少一个参数: 预制体名称");
				return;
			}
			string text2 = args[0];
			if (args.Length >= 2)
			{
				text = args[1];
			}
			if ((Object)(object)CL_AssetManager.GetAssetGameObject(text2, text) != (Object)null)
			{
				MPMain.LogInfo("[Test]成功获取预制体: " + text2 + " 来自数据库: " + text);
			}
			else
			{
				MPMain.LogError("[Test]获取预制体失败: " + text2 + " 来自数据库: " + text);
			}
		}

		public static void GetParticleEffectPrefab(string prefabName)
		{
			//IL_000b: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ((Component)Camera.main).transform.position + ((Component)Camera.main).transform.forward;
			Quaternion identity = Quaternion.identity;
			GameObject[] array = Resources.FindObjectsOfTypeAll<GameObject>();
			GameObject[] array2 = array;
			foreach (GameObject val2 in array2)
			{
				Scene scene = val2.scene;
				if (((Scene)(ref scene)).name == null && ((Object)val2).name == prefabName)
				{
					ParticleSystem component = val2.GetComponent<ParticleSystem>();
					if ((Object)(object)component != (Object)null)
					{
						MPMain.LogWarning("[Test] 找到粒子特效预制体: " + prefabName);
						Object.Instantiate<GameObject>(val2, val, identity);
						return;
					}
				}
			}
			MPMain.LogWarning("[Test] 找不到粒子特效预制体: " + prefabName);
		}

		public static void GetAllFX()
		{
			FieldInfo field = typeof(FXManager).GetField("particleDict", BindingFlags.Instance | BindingFlags.NonPublic);
			Dictionary<string, ParticleAsset> dictionary = (Dictionary<string, ParticleAsset>)field.GetValue(FXManager.fxMan);
			foreach (KeyValuePair<string, ParticleAsset> item in dictionary)
			{
				MPMain.LogWarning($"[Test] {item}");
			}
		}

		public static void GetAllMap()
		{
			M_Gamemode[] array = Resources.FindObjectsOfTypeAll<M_Gamemode>();
			M_GenerationBranch[] array2 = Resources.FindObjectsOfTypeAll<M_GenerationBranch>();
			M_Region[] array3 = Resources.FindObjectsOfTypeAll<M_Region>();
			M_Subregion[] array4 = Resources.FindObjectsOfTypeAll<M_Subregion>();
			M_Gamemode[] array5 = array;
			foreach (M_Gamemode val in array5)
			{
			}
			M_GenerationBranch[] array6 = array2;
			foreach (M_GenerationBranch val2 in array6)
			{
			}
			M_Region[] array7 = array3;
			foreach (M_Region val3 in array7)
			{
				MPMain.LogWarning("[Test] 区域名称:" + val3.regionName + " 介绍文本:" + val3.introText);
			}
			M_Subregion[] array8 = array4;
			foreach (M_Subregion val4 in array8)
			{
				MPMain.LogWarning("[Test] 区域名称:" + val4.subregionName + " 介绍文本:" + val4.introText);
			}
		}
	}
	public class Patch
	{
		[HarmonyPatch(typeof(ENT_Player), "Damage")]
		public class Patch_ENT_Player_Damage
		{
			public static void Prefix(DamageInfo info)
			{
				//IL_005a: 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)
				if (info == null)
				{
					return;
				}
				Plugin.Logger.LogWarning((object)("[Test] " + $"伤害量:{info.amount} " + "伤害类型:" + info.type + " " + $"伤害位置:{info.position} " + $"冲击力:{info.force}"));
				if ((Object)(object)info.sourceObject != (Object)null)
				{
					Plugin.Logger.LogWarning((object)("[Test]伤害来源:" + ((Object)info.sourceObject).name));
				}
				if (info.tags == null)
				{
					return;
				}
				foreach (string tag in info.tags)
				{
					Plugin.Logger.LogWarning((object)("[Test]伤害标签:" + tag));
				}
			}
		}

		[HarmonyPatch(typeof(MPCore), "Awake")]
		public class Patch_MPCore_Awake
		{
			public static void Postfix()
			{
				_ = MonoSingleton<Test>.Instance;
			}
		}
	}
	public class Patch_WorldLoader
	{
		[HarmonyPatch(typeof(WorldLoader), "GenerateLevels")]
		public class Patch_GenerateLevels
		{
			public static void Prefix(BranchInfo branch, GenerationParameters genParams, WorldLoader __instance, WorldGenerator ___currentGenerator)
			{
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Expected O, but got Unknown
				Plugin.Logger.LogWarning((object)$"[Test] branch:{branch.levelTracker.Count}");
				if (genParams == null)
				{
					Plugin.Logger.LogWarning((object)"[Test] genParams为空");
					genParams = new GenerationParameters();
				}
				if (genParams.forceResetGeneratorToGamemode)
				{
					Plugin.Logger.LogWarning((object)"[Test] 强制重置生成器到当前游戏模式");
					genParams.generator = (WorldGenerator)(object)CL_GameManager.gamemode;
				}
				if (genParams.generator == null)
				{
					if (___currentGenerator == null)
					{
						Plugin.Logger.LogWarning((object)"[Test] 使用游戏模式的生成器");
						genParams.generator = (WorldGenerator)(object)CL_GameManager.gamemode;
					}
					else
					{
						Plugin.Logger.LogWarning((object)"[Test] 使用自带生成器");
						genParams.generator = ___currentGenerator;
					}
				}
				WorldGenerator generator = genParams.generator;
				WorldGenerator val = generator;
				if (!(val is M_GenerationBranch))
				{
					if (val is M_Gamemode)
					{
						Plugin.Logger.LogWarning((object)"[Test] 是M_Gamemode");
					}
					else
					{
						Plugin.Logger.LogWarning((object)"[Test] 无法确定类型");
					}
				}
				else
				{
					Plugin.Logger.LogWarning((object)"[Test] 是M_GenerationBranch");
				}
				List<LevelAssetHolder> list = new List<LevelAssetHolder>();
				int count = branch.levelTracker.Count;
			}
		}

		[HarmonyPatch(typeof(WorldLoader), "IncrementSeed")]
		public class Patch_IncrementSeed
		{
			public static bool Prefix()
			{
				Plugin.Logger.LogWarning((object)"[Test] 拦截种子偏移");
				return false;
			}
		}
	}
	[HarmonyPatch(typeof(M_Gamemode), "Initialize")]
	public class Patch_M_Gamemode_Initialize
	{
		public static void Prefix(M_Gamemode __instance)
		{
			if (__instance.gamemodeObjects == null)
			{
				Plugin.Logger.LogWarning((object)"[Test] 游戏模式相关的游戏对象为空");
				return;
			}
			foreach (GameObject gamemodeObject in __instance.gamemodeObjects)
			{
				Plugin.Logger.LogWarning((object)("[Test] 游戏模式相关的游戏对象:" + ((Object)gamemodeObject).name));
			}
		}
	}
	public class SystemTest : MonoSingleton<SystemTest>
	{
		public static void Main(string[] args)
		{
			if (args.Length == 0)
			{
				MPMain.LogError("测试命令需要参数");
				return;
			}
			string text = args[0];
			if (1 == 0)
			{
			}
			if (!(text == "0"))
			{
				if (text == "1")
				{
					RunCommand(GetPath);
				}
				else
				{
					RunCommand(delegate
					{
						MPMain.LogError("[Test] 未知命令: " + args[0]);
					});
				}
			}
			else
			{
				RunCommand(GetGraphicsAPI);
			}
			if (true)
			{
			}
		}

		private static bool RunCommand(Action action)
		{
			action();
			return true;
		}

		public static void GetGraphicsAPI()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			MPMain.LogWarning($"[Test] 当前图形API: {SystemInfo.graphicsDeviceType}");
			MPMain.LogWarning("[Test] 图形API版本: " + SystemInfo.graphicsDeviceVersion);
			int graphicsShaderLevel = SystemInfo.graphicsShaderLevel;
			MPMain.LogWarning($"[Test] Shader Model: {graphicsShaderLevel / 10}.{graphicsShaderLevel % 10}");
			MPMain.LogWarning($"[Test] 支持计算着色器: {SystemInfo.supportsComputeShaders}");
			MPMain.LogWarning($"[Test] 支持几何着色器: {SystemInfo.supportsGeometryShaders}");
			MPMain.LogWarning($"[Test] 支持曲面细分: {SystemInfo.supportsTessellationShaders}");
			MPMain.LogWarning($"[Test] 支持GPU实例化: {SystemInfo.supportsInstancing}");
			MPMain.LogWarning("[Test] 系统语言:" + Localization.GetGameLanguage());
		}

		public static void GetPath()
		{
			MPMain.LogWarning(Paths.PluginPath);
			MPMain.LogWarning(Assembly.GetExecutingAssembly().Location);
			MPMain.LogWarning(AppDomain.CurrentDomain.BaseDirectory);
			MPMain.LogWarning(Application.dataPath);
			MPMain.LogWarning(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? string.Empty);
			MPMain.LogWarning(MPMain.path);
		}
	}
	public class Test : MonoSingleton<Test>
	{
		public const string NO_ITEM_PREFAB_NAME = "None";

		public static float x = 0f;

		public static float y = 0f;

		public static float z = 0f;

		public static ulong id = 0uL;

		public static Dictionary<string, M_Gamemode> gamemodeMap = new Dictionary<string, M_Gamemode>();

		public static Stopwatch sw = new Stopwatch();

		private void Start()
		{
			SceneManager.sceneLoaded += OnSceneLoaded;
			SteamMatchmaking.OnLobbyCreated += HandleLobbyCreated;
			MPMain.LogInfo("[Test] Test组件启动");
		}

		private void OnDestroy()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
			SteamMatchmaking.OnLobbyCreated -= HandleLobbyCreated;
			MPMain.LogInfo("[Test] Test组件销毁");
			base.OnDestroy();
		}

		public void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			if (((Scene)(ref scene)).name == "Game-Main")
			{
				CommandConsole.BuildCommand("test", (Action<string[]>)Main).NotCheat();
				CommandConsole.BuildCommand("cheatstest", (Action<string[]>)CheatsTest.Main).NotCheat();
				CommandConsole.BuildCommand("systemtest", (Action<string[]>)SystemTest.Main).NotCheat();
				CommandConsole.BuildCommand("gametest", (Action<string[]>)GameTest.Main).NotCheat();
			}
		}

		public static void Main(string[] args)
		{
			if (args.Length == 0)
			{
				Debug.Log((object)"测试命令需要参数");
				return;
			}
			string text = args[0];
			if (1 == 0)
			{
			}
			switch (text)
			{
			case "0":
				RunCommand(GetMPStatus);
				break;
			case "1":
				RunCommand(delegate
				{
					CreateRemotePlayer(args[1..]);
				});
				break;
			case "2":
				RunCommand(delegate
				{
					RemoveRemotePlayer(args[1..]);
				});
				break;
			case "3":
				RunCommand(GetAllFactoryList);
				break;
			case "4":
				RunCommand(CreateTestPrefab);
				break;
			case "5":
				RunCommand(GetHandCosmetic);
				break;
			case "6":
				RunCommand(DisplayMessageTest);
				break;
			case "7":
				RunCommand(SimulationPlayerUpdata);
				break;
			case "8":
				RunCommand(delegate
				{
					MonoSingleton<MPCore>.Instance.ResetStateVariables();
				});
				break;
			default:
				RunCommand(delegate
				{
					Debug.Log((object)("[Test] 未知命令: " + args[0]));
				});
				break;
			}
			if (true)
			{
			}
		}

		private static bool RunCommand(Action action)
		{
			action();
			return true;
		}

		public static void GetMPStatus()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected I4, but got Unknown
			Debug.Log((object)(((int)MPCore.MultiPlayerStatus).ToString() ?? ""));
			Debug.Log((object)$"Is in lobby {MPCore.IsInLobby}");
			Debug.Log((object)$"Is initialized {MPCore.IsInitialized}");
		}

		public static void CreateRemotePlayer(string[] args)
		{
			id++;
			string text = "default";
			if (args.Length >= 1 && ulong.TryParse(args[0], out var result))
			{
				id = result;
			}
			if (args.Length >= 2)
			{
				text = string.Join(" ", args[1..]);
			}
			Singleton<RPManager>.Instance.PlayerCreate(id, text);
			y += 4f;
		}

		public static void RemoveRemotePlayer(string[] args)
		{
			int num = 1;
			if (args.Length >= 1 && int.TryParse(args[0], out var result))
			{
				num = result;
			}
			Singleton<RPManager>.Instance.PlayerRemove((ulong)num);
		}

		public static void CreateTestPrefab()
		{
			AssetBundle val = AssetBundle.LoadFromFile(Path.Combine(MPMain.path, "playerprefab"));
			BaseRemoteFactory.ListAllAssetsInBundle(val);
			GameObject val2 = val.LoadAsset<GameObject>("cl_player");
			Object.Instantiate<GameObject>(val2);
		}

		public static void GetAllFactoryList()
		{
			Singleton<RPFactoryManager>.Instance.ListAllFactory();
		}

		public static void GetHandCosmetic()
		{
			MPMain.LogWarning("左手皮肤id " + CL_CosmeticManager.GetCosmeticInHand(0).cosmeticData.id);
			MPMain.LogWarning("右手皮肤id " + CL_CosmeticManager.GetCosmeticInHand(1).cosmeticData.id);
		}

		public static void SimulationPlayerUpdata()
		{
			byte[] array = new byte[1] { 1 };
			ArraySegment<byte> arraySegment = new ArraySegment<byte>(array);
			MPEventBusNet.NotifyReceive(1uL, arraySegment);
		}

		public static void DisplayMessageTest()
		{
			MonoSingleton<UI_Manager>.Instance.DisplayMessage("[randomchar s=0.2 c=0.1]AAAAAAAAAAAA[/randomchar]", (UIDisplayType)1);
			MonoSingleton<UI_Manager>.Instance.DisplayMessage("[randomchar s=0.2 c=0.1]BBBBBBBBBBBB[/randomchar]", (UIDisplayType)2);
			MonoSingleton<UI_Manager>.Instance.DisplayMessage("[randomchar s=0.2 c=0.1]CCCCCCCCCCCC[/randomchar]", (UIDisplayType)3);
			MonoSingleton<UI_Manager>.Instance.DisplayMessage("[randomchar s=0.2 c=0.1]DDDDDDDDDDDD[/randomchar]", (UIDisplayType)4);
		}

		public void HandleLobbyCreated(Result result, Lobby lobby)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Invalid comparison between Unknown and I4
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Invalid comparison between Unknown and I4
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Invalid comparison between Unknown and I4
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Invalid comparison between Unknown and I4
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Invalid comparison between Unknown and I4
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Invalid comparison between Unknown and I4
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected I4, but got Unknown
			if ((int)result <= 15)
			{
				if ((int)result <= 3)
				{
					if ((int)result == 1)
					{
						MPMain.LogInfo("[Test] create lobby success");
						return;
					}
					if ((int)result == 3)
					{
						MPMain.LogWarning("[Test] No connection to Steam servers. Please check your internet.");
						return;
					}
				}
				else
				{
					if ((int)result == 8)
					{
						MPMain.LogWarning("[Test] Invalid parameters. Check if max players is within 1-250.");
						return;
					}
					if ((int)result == 15)
					{
						MPMain.LogWarning("[Test] Access denied. Your account may be restricted from creating lobbies.");
						return;
					}
				}
			}
			else if ((int)result <= 25)
			{
				if ((int)result == 16)
				{
					MPMain.LogWarning("[Test] Steam servers timed out. Please try again later.");
					return;
				}
				if ((int)result == 25)
				{
					MPMain.LogWarning("[Test] Lobby limit exceeded. Try closing other sessions.");
					return;
				}
			}
			else
			{
				if ((int)result == 84)
				{
					MPMain.LogWarning("[Test] Creating lobbies too fast! Please wait a moment before trying again.");
					return;
				}
				if ((int)result == 112)
				{
					MPMain.LogWarning("[Test] Your Steam account is limited (needs $5 USD spend), social features are restricted.");
					return;
				}
			}
			MPMain.LogWarning($"[Test] Lobby creation failed with Steam EResult: {result} ({(int)result})");
		}
	}
}