Decompiled source of CarryFriend v1.0.0

Zichen-CarryFriend-1.0.0.dll

Decompiled 12 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.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("Zichen-CarryFriend-1.0.0")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Zichen-CarryFriend-1.0.0")]
[assembly: AssemblyTitle("Zichen-CarryFriend-1.0.0")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Zichen_CarryFriend
{
	public enum DisplayLanguage
	{
		中文,
		English
	}
	[BepInPlugin("zichen.carryfriend", "CarryFriend", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(PlayerAvatar), "Start")]
		public static class PlayerAvatarStartPatch
		{
			public static void Postfix(PlayerAvatar __instance)
			{
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)__instance != (Object)null && (Object)(object)__instance.photonView != (Object)null && __instance.photonView.IsMine && (Object)(object)GameObject.Find("Zichen_CarryFriend_Runtime") == (Object)null)
				{
					new GameObject("Zichen_CarryFriend_Runtime").AddComponent<CarryFriendBehaviour>();
					((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Successfully created CarryFriendBehaviour on local player avatar start.");
				}
			}
		}

		internal sealed class CfgI18N
		{
			public string SectionCN;

			public string SectionEN;

			public string KeyCN;

			public string KeyEN;

			public string DescCN;

			public string DescEN;

			public ConfigurationManagerAttributes Attrs;

			public string ValueEN;

			public string ValueCN;

			public ConfigEntry<string> ReadOnlyEntry;
		}

		internal sealed class LiveLabel
		{
			public WeakReference<TextMeshProUGUI> Tmp;

			public CfgI18N I18N;

			public bool IsSection;
		}

		internal sealed class LiveValue
		{
			public WeakReference<Object> InputField;

			public CfgI18N I18N;
		}

		internal static class REPOConfigCreateHook
		{
			public static void Postfix(object[] __args, object __result)
			{
				try
				{
					if (__args != null && __args.Length != 0 && __result != null && __args[0] is string label)
					{
						RegisterLiveLabelIfMatched(label, __result);
					}
				}
				catch
				{
				}
			}
		}

		public const string PluginGuid = "zichen.carryfriend";

		public const string PluginName = "CarryFriend";

		public const string PluginVersion = "1.0.0";

		internal static Plugin Instance;

		internal static ManualLogSource Log;

		private static ConfigEntry<bool> _cfgModEnabled;

		private static ConfigEntry<DisplayLanguage> _cfgLanguage;

		private static ConfigEntry<float> _cfgRequiredHoldTime;

		public static readonly FieldInfo F_TumblePhysGrabObject = AccessTools.Field(typeof(PlayerTumble), "physGrabObject");

		public static readonly FieldInfo F_TumbleRb = AccessTools.Field(typeof(PlayerTumble), "rb");

		public static readonly FieldInfo F_PhysGrabObjectImpactDetector = AccessTools.Field(typeof(PhysGrabObject), "impactDetector");

		private static readonly string[] _chineseModKeywords = new string[6] { "chinese", "简体", "繁體", "繁体", "汉化", "中文" };

		private static readonly string[] _chineseEnvironmentPluginGuids = new string[1] { "gravydevsupreme.xunity.autotranslator" };

		internal static readonly Dictionary<string, CfgI18N> _cfgByEnSection = new Dictionary<string, CfgI18N>(StringComparer.Ordinal);

		internal static readonly Dictionary<string, CfgI18N> _cfgByEnKey = new Dictionary<string, CfgI18N>(StringComparer.Ordinal);

		private static readonly List<CfgI18N> _cfgI18Ns = new List<CfgI18N>(20);

		private static readonly List<LiveLabel> _liveLabels = new List<LiveLabel>(64);

		private static readonly List<LiveValue> _liveValues = new List<LiveValue>(8);

		private static readonly Dictionary<Type, FieldInfo> _labelTmpFieldCache = new Dictionary<Type, FieldInfo>(8);

		private static FieldInfo _inputStringSystemField;

		private static MethodInfo _inputStringSystemSetValue;

		public static bool IsStaticModEnabled()
		{
			if (_cfgModEnabled != null)
			{
				return _cfgModEnabled.Value;
			}
			return false;
		}

		public static bool UseChinese()
		{
			if (_cfgLanguage != null)
			{
				return _cfgLanguage.Value == DisplayLanguage.中文;
			}
			return false;
		}

		public static float RequiredHoldTime()
		{
			if (_cfgRequiredHoldTime == null)
			{
				return 2f;
			}
			return _cfgRequiredHoldTime.Value;
		}

		private void Awake()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			ResetConfigIfVersionChanged();
			BindConfig();
			if (!IsStaticModEnabled())
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"CarryFriend v1.0.0 已禁用。");
				return;
			}
			try
			{
				Harmony val = new Harmony("zichen.carryfriend");
				val.PatchAll(Assembly.GetExecutingAssembly());
				TryHookREPOConfig(val);
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Harmony patch failed: " + ex.Message));
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"CarryFriend v1.0.0 物理重构与多端兼容版已加载(仅在游戏中激活)。");
		}

		private void BindConfig()
		{
			BindReadOnly("Mod Info", "模组信息", "Mod Name", "模组名称", "CarryFriend", "背起队友");
			BindReadOnly("Mod Info", "模组信息", "Mod Version", "模组版本号", "1.0.0", "1.0.0");
			DisplayLanguage defaultVal = DetectDefaultLanguage();
			_cfgLanguage = Bind("Mod Info", "模组信息", "Language", "语言", "Switch display language.", "切换显示语言。", defaultVal);
			_cfgModEnabled = Bind("A.Global", "A.全局设置", "Mod Enabled", "模组启用", "Disable to turn off the whole mod.", "关闭后整个模组全部功能失效。", defaultVal: true);
			_cfgRequiredHoldTime = Bind("B.Timers", "时间设置", "Interact Hold Duration (s)", "按住E背起时间 (秒)", "How long you need to hold Interact (E) to carry a player or head.", "按住交互键E背起队友或死尸头部所需的读条时长。", 1f);
			if (_cfgLanguage != null)
			{
				_cfgLanguage.SettingChanged += delegate
				{
					RefreshAllI18N();
				};
			}
		}

		private static DisplayLanguage DetectDefaultLanguage()
		{
			try
			{
				foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
				{
					string text = pluginInfo.Key ?? string.Empty;
					PluginInfo value = pluginInfo.Value;
					object obj;
					if (value == null)
					{
						obj = null;
					}
					else
					{
						BepInPlugin metadata = value.Metadata;
						obj = ((metadata != null) ? metadata.Name : null);
					}
					if (obj == null)
					{
						obj = string.Empty;
					}
					string text2 = (string)obj;
					string[] chineseModKeywords = _chineseModKeywords;
					foreach (string value2 in chineseModKeywords)
					{
						if (text.IndexOf(value2, StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf(value2, StringComparison.OrdinalIgnoreCase) >= 0)
						{
							return DisplayLanguage.中文;
						}
					}
					chineseModKeywords = _chineseEnvironmentPluginGuids;
					foreach (string b in chineseModKeywords)
					{
						if (string.Equals(text, b, StringComparison.OrdinalIgnoreCase))
						{
							return DisplayLanguage.中文;
						}
					}
				}
			}
			catch
			{
			}
			return DisplayLanguage.English;
		}

		private ConfigEntry<T> Bind<T>(string sectEN, string sectCN, string keyEN, string keyCN, string descEN, string descCN, T defaultVal, AcceptableValueBase acceptableValues = null)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			CfgI18N cfgI18N = NewI18N(sectEN, sectCN, keyEN, keyCN, descEN, descCN, readOnly: false);
			return ((BaseUnityPlugin)this).Config.Bind<T>(sectEN, keyEN, defaultVal, new ConfigDescription(descEN, acceptableValues, new object[1] { cfgI18N.Attrs }));
		}

		private void BindReadOnly(string sectEN, string sectCN, string keyEN, string keyCN, string valueEN, string valueCN)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			CfgI18N cfgI18N = NewI18N(sectEN, sectCN, keyEN, keyCN, "", "", readOnly: true);
			cfgI18N.ValueEN = valueEN;
			cfgI18N.ValueCN = valueCN;
			cfgI18N.ReadOnlyEntry = ((BaseUnityPlugin)this).Config.Bind<string>(sectEN, keyEN, UseChinese() ? valueCN : valueEN, new ConfigDescription("", (AcceptableValueBase)null, new object[1] { cfgI18N.Attrs }));
			string text = (UseChinese() ? valueCN : valueEN);
			if (cfgI18N.ReadOnlyEntry.Value != text)
			{
				cfgI18N.ReadOnlyEntry.Value = text;
			}
		}

		private static CfgI18N NewI18N(string sectEN, string sectCN, string keyEN, string keyCN, string descEN, string descCN, bool readOnly)
		{
			CfgI18N cfgI18N = new CfgI18N
			{
				SectionEN = sectEN,
				SectionCN = sectCN,
				KeyEN = keyEN,
				KeyCN = keyCN,
				DescEN = descEN,
				DescCN = descCN,
				Attrs = (readOnly ? new ConfigurationManagerAttributes
				{
					ReadOnly = true,
					HideDefaultButton = true
				} : new ConfigurationManagerAttributes())
			};
			ApplyI18N(cfgI18N);
			_cfgI18Ns.Add(cfgI18N);
			_cfgByEnSection[sectEN] = cfgI18N;
			_cfgByEnKey[keyEN] = cfgI18N;
			return cfgI18N;
		}

		private static void ApplyI18N(CfgI18N i18n)
		{
			bool flag = UseChinese();
			i18n.Attrs.Category = (flag ? i18n.SectionCN : i18n.SectionEN);
			i18n.Attrs.DispName = (flag ? i18n.KeyCN : i18n.KeyEN);
			i18n.Attrs.Description = (flag ? i18n.DescCN : i18n.DescEN);
			if (i18n.ReadOnlyEntry != null)
			{
				string text = (flag ? i18n.ValueCN : i18n.ValueEN);
				if (i18n.ReadOnlyEntry.Value != text)
				{
					i18n.ReadOnlyEntry.Value = text;
				}
			}
		}

		private static void RefreshAllI18N()
		{
			for (int i = 0; i < _cfgI18Ns.Count; i++)
			{
				ApplyI18N(_cfgI18Ns[i]);
			}
			RefreshLiveLabels();
		}

		private void ResetConfigIfVersionChanged()
		{
			try
			{
				string configFilePath = ((BaseUnityPlugin)this).Config.ConfigFilePath;
				if (File.Exists(configFilePath))
				{
					string text = ReadConfigPluginVersion(configFilePath);
					if (!(text == "1.0.0"))
					{
						((BaseUnityPlugin)this).Config.Clear();
						File.Delete(configFilePath);
						((BaseUnityPlugin)this).Config.Reload();
						((BaseUnityPlugin)this).Logger.LogWarning((object)(string.IsNullOrWhiteSpace(text) ? "Old config without Mod Version, reset to defaults / 旧配置无版本号,已重置。" : ("Config version " + text + " -> 1.0.0, reset to defaults / 配置版本不一致,已重置。")));
					}
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Reset config failed: " + ex.Message));
			}
		}

		private static string ReadConfigPluginVersion(string configPath)
		{
			if (!File.Exists(configPath))
			{
				return null;
			}
			string input = File.ReadAllText(configPath);
			Match match = Regex.Match(input, "(?m)^Mod Version\\s*=\\s*(.+?)\\s*$");
			if (!match.Success)
			{
				match = Regex.Match(input, "(?m)^模组版本号\\s*=\\s*(.+?)\\s*$");
			}
			if (!match.Success)
			{
				return null;
			}
			return match.Groups[1].Value.Trim();
		}

		internal static void TryHookREPOConfig(Harmony h)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			try
			{
				Type type = AccessTools.TypeByName("MenuLib.MenuAPI");
				if (type == null)
				{
					Log.LogInfo((object)"MenuLib 未安装,跳过 REPOConfig 双语劫持。");
					return;
				}
				HarmonyMethod val = new HarmonyMethod(AccessTools.Method(typeof(REPOConfigCreateHook), "Postfix", (Type[])null, (Type[])null));
				HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal) { "CreateREPOLabel", "CreateREPOToggle", "CreateREPOSlider", "CreateREPOInputField", "CreateREPOButton" };
				int num = 0;
				foreach (MethodInfo declaredMethod in AccessTools.GetDeclaredMethods(type))
				{
					if (!hashSet.Contains(declaredMethod.Name))
					{
						continue;
					}
					ParameterInfo[] parameters = declaredMethod.GetParameters();
					if (parameters.Length != 0 && !(parameters[0].ParameterType != typeof(string)))
					{
						try
						{
							h.Patch((MethodBase)declaredMethod, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
							num++;
						}
						catch
						{
						}
					}
				}
				if (num > 0)
				{
					Log.LogInfo((object)$"REPOConfig 双语显示已挂载({num} 个 UI 创建方法)。");
				}
				else
				{
					Log.LogInfo((object)"REPOConfig 没找到可劫持的 UI 方法。");
				}
			}
			catch (Exception ex)
			{
				Log.LogInfo((object)("REPOConfig 劫持失败:" + ex.Message));
			}
		}

		internal static void RegisterLiveLabelIfMatched(string label, object uiElement)
		{
			if (string.IsNullOrEmpty(label) || uiElement == null)
			{
				return;
			}
			CfgI18N value;
			bool flag = _cfgByEnSection.TryGetValue(label, out value);
			if (!flag && !_cfgByEnKey.TryGetValue(label, out value))
			{
				return;
			}
			TextMeshProUGUI labelTmp = GetLabelTmp(uiElement);
			if ((Object)(object)labelTmp == (Object)null)
			{
				return;
			}
			bool flag2 = UseChinese();
			string text = ((!flag) ? (flag2 ? value.KeyCN : value.KeyEN) : (flag2 ? value.SectionCN : value.SectionEN));
			if (!string.IsNullOrEmpty(text))
			{
				try
				{
					((TMP_Text)labelTmp).text = text;
				}
				catch
				{
				}
			}
			_liveLabels.Add(new LiveLabel
			{
				Tmp = new WeakReference<TextMeshProUGUI>(labelTmp),
				I18N = value,
				IsSection = flag
			});
			if (!flag && value.ReadOnlyEntry != null)
			{
				Object val = (Object)((uiElement is Object) ? uiElement : null);
				if (val != null && AccessTools.Field(uiElement.GetType(), "inputStringSystem") != null)
				{
					_liveValues.Add(new LiveValue
					{
						InputField = new WeakReference<Object>(val),
						I18N = value
					});
					TrySetInputFieldValue(val, flag2 ? value.ValueCN : value.ValueEN);
				}
			}
		}

		private static TextMeshProUGUI GetLabelTmp(object uiElement)
		{
			try
			{
				Type type = uiElement.GetType();
				if (!_labelTmpFieldCache.TryGetValue(type, out var value))
				{
					value = AccessTools.Field(type, "labelTMP");
					_labelTmpFieldCache[type] = value;
				}
				object? obj = value?.GetValue(uiElement);
				return (TextMeshProUGUI)((obj is TextMeshProUGUI) ? obj : null);
			}
			catch
			{
				return null;
			}
		}

		internal static void RefreshLiveLabels()
		{
			bool flag = UseChinese();
			for (int num = _liveLabels.Count - 1; num >= 0; num--)
			{
				LiveLabel liveLabel = _liveLabels[num];
				if (!liveLabel.Tmp.TryGetTarget(out var target) || (Object)(object)target == (Object)null || (Object)(object)((Component)target).gameObject == (Object)null)
				{
					_liveLabels.RemoveAt(num);
				}
				else
				{
					string text = ((!liveLabel.IsSection) ? (flag ? liveLabel.I18N.KeyCN : liveLabel.I18N.KeyEN) : (flag ? liveLabel.I18N.SectionCN : liveLabel.I18N.SectionEN));
					try
					{
						((TMP_Text)target).text = text;
					}
					catch
					{
						_liveLabels.RemoveAt(num);
					}
				}
			}
			for (int num2 = _liveValues.Count - 1; num2 >= 0; num2--)
			{
				LiveValue liveValue = _liveValues[num2];
				if (!liveValue.InputField.TryGetTarget(out var target2) || target2 == (Object)null)
				{
					_liveValues.RemoveAt(num2);
				}
				else
				{
					string newVal = (flag ? liveValue.I18N.ValueCN : liveValue.I18N.ValueEN);
					if (!TrySetInputFieldValue(target2, newVal))
					{
						_liveValues.RemoveAt(num2);
					}
				}
			}
		}

		private static bool TrySetInputFieldValue(Object ifObj, string newVal)
		{
			try
			{
				Type type = ((object)ifObj).GetType();
				if (_inputStringSystemField == null || _inputStringSystemField.DeclaringType != type)
				{
					_inputStringSystemField = AccessTools.Field(type, "inputStringSystem");
				}
				if (_inputStringSystemField == null)
				{
					return false;
				}
				object value = _inputStringSystemField.GetValue(ifObj);
				if (value == null)
				{
					return false;
				}
				if (_inputStringSystemSetValue == null || _inputStringSystemSetValue.DeclaringType != value.GetType())
				{
					_inputStringSystemSetValue = AccessTools.Method(value.GetType(), "SetValue", new Type[2]
					{
						typeof(string),
						typeof(bool)
					}, (Type[])null);
				}
				if (_inputStringSystemSetValue == null)
				{
					return false;
				}
				_inputStringSystemSetValue.Invoke(value, new object[2]
				{
					newVal ?? string.Empty,
					false
				});
				return true;
			}
			catch
			{
				return false;
			}
		}
	}
	public class CarryFriendBehaviour : MonoBehaviour
	{
		private const byte CarryEventCode = 188;

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

		private readonly Dictionary<int, List<Collider>> CarryTriggerColliders = new Dictionary<int, List<Collider>>();

		private readonly Dictionary<int, float> CarryStartTimes = new Dictionary<int, float>();

		private bool _isCarrying;

		private PlayerAvatar _myCarriedPlayer;

		private PlayerDeathHead _myCarriedHead;

		private bool _isBeingCarried;

		private PlayerAvatar _myCarrier;

		private float _holdTimer;

		private object _currentTargetObj;

		private string _currentTargetName = "";

		private bool _isHostModInstalled;

		private float _releaseTimer;

		private float _hostModMissingPromptTimer;

		private float _offlineCleanupTimer;

		private void Start()
		{
			_isHostModInstalled = PhotonNetwork.IsMasterClient;
			_releaseTimer = 0f;
			_hostModMissingPromptTimer = 0f;
			_offlineCleanupTimer = 0f;
			try
			{
				PhotonNetwork.NetworkingClient.EventReceived += OnEvent;
				Plugin.Log.LogInfo((object)"CarryFriendBehaviour EventReceived subscribed.");
				if (!PhotonNetwork.IsMasterClient && SemiFunc.IsMultiplayer())
				{
					SendCarryEventToHost(PhotonNetwork.LocalPlayer.ActorNumber, 0, 0, 3);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Failed to subscribe EventReceived in CarryFriendBehaviour: " + ex.Message));
			}
		}

		private void OnDestroy()
		{
			try
			{
				PhotonNetwork.NetworkingClient.EventReceived -= OnEvent;
				Plugin.Log.LogInfo((object)"CarryFriendBehaviour EventReceived unsubscribed.");
			}
			catch
			{
			}
			ResetState();
		}

		private void CleanupOfflineCarries()
		{
			if (ActiveCarries.Count == 0)
			{
				return;
			}
			List<int> list = new List<int>();
			foreach (KeyValuePair<int, int> activeCarry in ActiveCarries)
			{
				int key = activeCarry.Key;
				int value = activeCarry.Value;
				PlayerAvatar val = FindPlayerAvatarByViewID(value);
				if ((Object)(object)val == (Object)null || GetPlayerIsDisabled(val))
				{
					list.Add(key);
					continue;
				}
				PlayerAvatar val2 = FindPlayerAvatarByViewID(key);
				PlayerDeathHead val3 = FindDeathHeadByViewID(key);
				if ((Object)(object)val2 == (Object)null && (Object)(object)val3 == (Object)null)
				{
					list.Add(key);
				}
				else if ((Object)(object)val2 != (Object)null && (GetPlayerIsDisabled(val2) || GetPlayerDeadSet(val2)))
				{
					list.Add(key);
				}
				else if ((Object)(object)val3 != (Object)null && (Object)(object)val3.playerAvatar != (Object)null && !GetPlayerDeadSet(val3.playerAvatar))
				{
					list.Add(key);
				}
			}
			if (list.Count <= 0)
			{
				return;
			}
			PlayerAvatar instance = PlayerAvatar.instance;
			int num = (((Object)(object)instance != (Object)null && (Object)(object)instance.photonView != (Object)null) ? instance.photonView.ViewID : 0);
			foreach (int item in list)
			{
				Plugin.Log.LogInfo((object)$"Cleaning up offline/destroyed carry: Target ViewID {item}");
				ActiveCarries.Remove(item);
				CarryStartTimes.Remove(item);
				if (CarryTriggerColliders.TryGetValue(item, out var value2))
				{
					if (value2 != null)
					{
						foreach (Collider item2 in value2)
						{
							if ((Object)(object)item2 != (Object)null)
							{
								item2.isTrigger = false;
							}
						}
					}
					CarryTriggerColliders.Remove(item);
				}
				if (!((Object)(object)instance != (Object)null))
				{
					continue;
				}
				if (item == num)
				{
					if (_isBeingCarried)
					{
						_isBeingCarried = false;
						_myCarrier = null;
						PlayerTumble playerTumble = GetPlayerTumble(instance);
						if ((Object)(object)playerTumble != (Object)null)
						{
							playerTumble.TumbleRequest(false, false);
						}
						instance.TumbleStop();
						instance.UpdateState(false, false, false, false, false);
					}
				}
				else if ((Object)(object)_myCarriedPlayer != (Object)null && (Object)(object)_myCarriedPlayer.photonView != (Object)null && _myCarriedPlayer.photonView.ViewID == item)
				{
					if (_isCarrying)
					{
						_isCarrying = false;
						_myCarriedPlayer = null;
						_myCarriedHead = null;
						_releaseTimer = 0f;
					}
				}
				else if ((Object)(object)_myCarriedHead != (Object)null && (Object)(object)((Component)_myCarriedHead).GetComponent<PhotonView>() != (Object)null && ((Component)_myCarriedHead).GetComponent<PhotonView>().ViewID == item && _isCarrying)
				{
					_isCarrying = false;
					_myCarriedPlayer = null;
					_myCarriedHead = null;
					_releaseTimer = 0f;
				}
			}
		}

		private void Update()
		{
			if (Plugin.IsStaticModEnabled())
			{
				_offlineCleanupTimer += Time.deltaTime;
				if (_offlineCleanupTimer >= 3f)
				{
					_offlineCleanupTimer = 0f;
					CleanupOfflineCarries();
				}
				if (_hostModMissingPromptTimer > 0f)
				{
					_hostModMissingPromptTimer -= Time.deltaTime;
				}
				UpdateCarryLogic();
			}
		}

		private void FixedUpdate()
		{
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: 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)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_033b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0340: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_036d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_039f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.IsStaticModEnabled())
			{
				return;
			}
			if (_isBeingCarried && (Object)(object)_myCarrier != (Object)null)
			{
				PlayerAvatar instance = PlayerAvatar.instance;
				if ((Object)(object)instance != (Object)null)
				{
					PlayerTumble playerTumble = GetPlayerTumble(instance);
					if ((Object)(object)playerTumble != (Object)null)
					{
						if (!GetPlayerIsTumbling(instance))
						{
							playerTumble.TumbleRequest(true, false);
						}
						playerTumble.TumbleOverrideTime(0.5f);
						PhysGrabObject tumblePhysGrabObject = GetTumblePhysGrabObject(playerTumble);
						Rigidbody tumbleRb = GetTumbleRb(playerTumble);
						Rigidbody component = ((Component)_myCarrier).GetComponent<Rigidbody>();
						if ((Object)(object)tumblePhysGrabObject != (Object)null && (Object)(object)tumbleRb != (Object)null && (Object)(object)component != (Object)null)
						{
							tumblePhysGrabObject.OverrideMaterial(SemiFunc.PhysicMaterialSlippery(), 0.1f);
							tumblePhysGrabObject.OverrideZeroGravity(0.2f);
							DisablePhysGrabObjectImpact(tumblePhysGrabObject, 0.2f);
							playerTumble.OverrideEnemyHurt(0.1f);
							if ((Object)(object)instance.physGrabber != (Object)null)
							{
								instance.physGrabber.OverrideDisableSpecialGrabPowers(0.2f);
								playerTumble.OverrideTumbleUIDisable(0.2f);
							}
							tumblePhysGrabObject.OverrideMass(0.05f, 0.1f);
							Vector3 val = ((Component)_myCarrier).transform.position - ((Component)_myCarrier).transform.forward * 0.45f + ((Component)_myCarrier).transform.up * 1.2f;
							Quaternion val2 = ((Component)_myCarrier).transform.rotation * Quaternion.Euler(15f, 180f, 0f);
							Vector3 pointVelocity = component.GetPointVelocity(tumbleRb.position);
							tumbleRb.velocity = pointVelocity;
							Vector3 val3 = val - tumbleRb.position;
							tumbleRb.velocity += val3 / Time.fixedDeltaTime * 0.08f;
							tumbleRb.angularVelocity = component.angularVelocity;
							Vector3 val4 = SemiFunc.PhysFollowRotation(((Component)playerTumble).transform, val2, tumbleRb, 0.5f);
							tumbleRb.AddTorque(val4, (ForceMode)2);
						}
					}
				}
			}
			if (!_isCarrying || !((Object)(object)_myCarriedHead != (Object)null))
			{
				return;
			}
			PlayerAvatar instance2 = PlayerAvatar.instance;
			if (!((Object)(object)instance2 != (Object)null))
			{
				return;
			}
			PhysGrabObject component2 = ((Component)_myCarriedHead).GetComponent<PhysGrabObject>();
			Rigidbody val5 = (((Object)(object)component2 != (Object)null) ? component2.rb : null);
			Rigidbody component3 = ((Component)instance2).GetComponent<Rigidbody>();
			if ((Object)(object)component2 != (Object)null && (Object)(object)val5 != (Object)null && (Object)(object)component3 != (Object)null)
			{
				PhotonView component4 = ((Component)_myCarriedHead).GetComponent<PhotonView>();
				if ((Object)(object)component4 != (Object)null && !component4.IsMine)
				{
					component4.RequestOwnership();
				}
				component2.OverrideMaterial(SemiFunc.PhysicMaterialSlippery(), 0.1f);
				component2.OverrideZeroGravity(0.2f);
				DisablePhysGrabObjectImpact(component2, 0.2f);
				component2.OverrideMass(0.05f, 0.1f);
				Vector3 val6 = ((Component)instance2).transform.position - ((Component)instance2).transform.forward * 0.35f + ((Component)instance2).transform.up * 0.4f;
				Quaternion rotation = ((Component)instance2).transform.rotation;
				Vector3 pointVelocity2 = component3.GetPointVelocity(val5.position);
				val5.velocity = pointVelocity2;
				Vector3 val7 = val6 - val5.position;
				val5.velocity += val7 / Time.fixedDeltaTime * 0.08f;
				val5.angularVelocity = component3.angularVelocity;
				Vector3 val8 = SemiFunc.PhysFollowRotation(((Component)_myCarriedHead).transform, rotation, val5, 0.5f);
				val5.AddTorque(val8, (ForceMode)2);
			}
		}

		private void LateUpdate()
		{
			//IL_0071: 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_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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.IsStaticModEnabled())
			{
				return;
			}
			foreach (KeyValuePair<int, int> activeCarry in ActiveCarries)
			{
				int key = activeCarry.Key;
				int value = activeCarry.Value;
				PlayerAvatar val = FindPlayerAvatarByViewID(key);
				PlayerAvatar val2 = FindPlayerAvatarByViewID(value);
				if (!((Object)(object)val != (Object)null) || !((Object)(object)val2 != (Object)null) || GetPlayerIsLocal(val))
				{
					continue;
				}
				Vector3 position = ((Component)val2).transform.position - ((Component)val2).transform.forward * 0.45f + ((Component)val2).transform.up * 1.2f;
				Quaternion rotation = ((Component)val2).transform.rotation * Quaternion.Euler(15f, 180f, 0f);
				((Component)val).transform.position = position;
				((Component)val).transform.rotation = rotation;
				Rigidbody component = ((Component)val).GetComponent<Rigidbody>();
				if ((Object)(object)component != (Object)null)
				{
					component.isKinematic = true;
					component.position = position;
					component.rotation = rotation;
					component.velocity = Vector3.zero;
					component.angularVelocity = Vector3.zero;
				}
				PlayerTumble playerTumble = GetPlayerTumble(val);
				if (!((Object)(object)playerTumble != (Object)null))
				{
					continue;
				}
				bool flag = false;
				if (CarryStartTimes.TryGetValue(key, out var value2) && Time.time - value2 < 1.5f)
				{
					flag = true;
				}
				if (flag || GetPlayerIsTumbling(val))
				{
					if (!GetPlayerIsTumbling(val))
					{
						playerTumble.TumbleRequest(true, false);
					}
					playerTumble.TumbleOverrideTime(0.5f);
				}
				Rigidbody tumbleRb = GetTumbleRb(playerTumble);
				if ((Object)(object)tumbleRb != (Object)null)
				{
					tumbleRb.isKinematic = true;
					tumbleRb.position = position;
					tumbleRb.rotation = rotation;
					tumbleRb.velocity = Vector3.zero;
					tumbleRb.angularVelocity = Vector3.zero;
				}
			}
		}

		private void UpdateCarryLogic()
		{
			//IL_0446: Unknown result type (might be due to invalid IL or missing references)
			//IL_044d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0452: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			PlayerAvatar instance = PlayerAvatar.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			if (!Input.GetKey((KeyCode)101))
			{
				_holdTimer = 0f;
				_currentTargetObj = null;
				_releaseTimer = 0f;
			}
			if (_isCarrying || _isBeingCarried)
			{
				_holdTimer = 0f;
				_currentTargetObj = null;
			}
			if (!_isCarrying)
			{
				_releaseTimer = 0f;
			}
			if (_isBeingCarried)
			{
				if ((Object)(object)_myCarrier == (Object)null)
				{
					Plugin.Log.LogWarning((object)"Carrier is unexpectedly null. Resetting being carried state locally.");
					_isBeingCarried = false;
					PlayerTumble playerTumble = GetPlayerTumble(instance);
					if ((Object)(object)playerTumble != (Object)null)
					{
						playerTumble.TumbleRequest(false, false);
					}
					instance.TumbleStop();
					instance.UpdateState(false, false, false, false, false);
					return;
				}
				if (GetPlayerDeadSet(_myCarrier) || GetPlayerIsDisabled(_myCarrier) || GetPlayerDeadSet(instance))
				{
					if (PhotonNetwork.IsMasterClient || !SemiFunc.IsMultiplayer())
					{
						SendCarryEvent(_myCarrier.photonView.ViewID, instance.photonView.ViewID, 1, 2);
					}
					else
					{
						SendCarryEventToHost(_myCarrier.photonView.ViewID, instance.photonView.ViewID, 1, 6);
					}
					return;
				}
				bool flag = false;
				if (Input.GetKeyDown((KeyCode)32))
				{
					flag = true;
				}
				if ((Input.GetMouseButtonDown(0) || Input.GetKeyDown((KeyCode)101)) && (Object)(object)instance.localCamera != (Object)null)
				{
					Transform transform = ((Component)instance.localCamera).transform;
					RaycastHit val = default(RaycastHit);
					if (Physics.Raycast(new Ray(transform.position, transform.forward), ref val, 3f, LayerMask.GetMask(new string[3] { "Default", "Player", "PhysGrabObject" }), (QueryTriggerInteraction)2))
					{
						PlayerAvatar val2 = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<PlayerAvatar>();
						if ((Object)(object)val2 == (Object)null)
						{
							PlayerTumble componentInParent = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<PlayerTumble>();
							if ((Object)(object)componentInParent != (Object)null)
							{
								val2 = componentInParent.playerAvatar;
							}
						}
						if ((Object)(object)val2 == (Object)null)
						{
							PlayerHealthGrab componentInParent2 = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<PlayerHealthGrab>();
							if ((Object)(object)componentInParent2 != (Object)null)
							{
								val2 = componentInParent2.playerAvatar;
							}
						}
						if ((Object)(object)val2 != (Object)null && (Object)(object)val2 == (Object)(object)_myCarrier)
						{
							flag = true;
						}
					}
				}
				if (flag)
				{
					if (PhotonNetwork.IsMasterClient || !SemiFunc.IsMultiplayer())
					{
						SendCarryEvent(_myCarrier.photonView.ViewID, instance.photonView.ViewID, 1, 2);
					}
					else
					{
						SendCarryEventToHost(_myCarrier.photonView.ViewID, instance.photonView.ViewID, 1, 6);
					}
				}
			}
			else if (_isCarrying)
			{
				if ((Object)(object)_myCarriedPlayer == (Object)null && (Object)(object)_myCarriedHead == (Object)null)
				{
					Plugin.Log.LogWarning((object)"Carried target is unexpectedly null. Resetting carrier state locally.");
					_isCarrying = false;
					_releaseTimer = 0f;
					return;
				}
				if (GetPlayerDeadSet(instance))
				{
					ForceReleaseAllCarried();
					return;
				}
				if ((Object)(object)_myCarriedPlayer != (Object)null)
				{
					int viewID = _myCarriedPlayer.photonView.ViewID;
					float num = 0f;
					if (CarryStartTimes.TryGetValue(viewID, out var value))
					{
						num = Time.time - value;
					}
					if (num > 1.5f && !GetPlayerIsTumbling(_myCarriedPlayer))
					{
						Plugin.Log.LogInfo((object)"Un-modded passenger stood up (space key), releasing.");
						ForceReleaseAllCarried();
						return;
					}
					if ((Object)(object)instance.healthGrab != (Object)null && (Object)(object)_myCarriedPlayer.physGrabber != (Object)null)
					{
						StaticGrabObject value2 = Traverse.Create((object)instance.healthGrab).Field<StaticGrabObject>("staticGrabObject").Value;
						if ((Object)(object)value2 != (Object)null)
						{
							PhysGrabber physGrabber = _myCarriedPlayer.physGrabber;
							if (physGrabber.grabbed && ((Object)(object)Traverse.Create((object)physGrabber).Field<StaticGrabObject>("grabbedStaticGrabObject").Value == (Object)(object)value2 || (Object)(object)physGrabber.grabbedObjectTransform == (Object)(object)value2.colliderTransform))
							{
								Plugin.Log.LogInfo((object)"Un-modded passenger grabbed back health box, releasing.");
								ForceReleaseAllCarried();
								return;
							}
						}
					}
				}
				if ((SemiFunc.InputDown((InputKey)10) || SemiFunc.InputDown((InputKey)2)) && (Object)(object)instance.localCamera != (Object)null)
				{
					Transform transform2 = ((Component)instance.localCamera).transform;
					RaycastHit val3 = default(RaycastHit);
					if (Physics.Raycast(new Ray(transform2.position, transform2.forward), ref val3, 4f, LayerMask.GetMask(new string[3] { "Default", "Player", "PhysGrabObject" }), (QueryTriggerInteraction)2))
					{
						PlayerAvatar val4 = ((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent<PlayerAvatar>();
						if ((Object)(object)val4 == (Object)null)
						{
							PlayerTumble componentInParent3 = ((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent<PlayerTumble>();
							if ((Object)(object)componentInParent3 != (Object)null)
							{
								val4 = componentInParent3.playerAvatar;
							}
						}
						if ((Object)(object)val4 != (Object)null && (Object)(object)val4 == (Object)(object)_myCarriedPlayer)
						{
							ForceReleaseAllCarried();
							return;
						}
					}
				}
				if ((Object)(object)_myCarriedHead != (Object)null)
				{
					PhysGrabObject component = ((Component)_myCarriedHead).GetComponent<PhysGrabObject>();
					if ((Object)(object)component != (Object)null && component.playerGrabbing != null && component.playerGrabbing.Count > 0)
					{
						bool flag2 = false;
						foreach (PhysGrabber item in component.playerGrabbing)
						{
							if ((Object)(object)item != (Object)null && (Object)(object)item.playerAvatar != (Object)null && (Object)(object)item.playerAvatar != (Object)(object)instance)
							{
								flag2 = true;
								break;
							}
						}
						if (flag2)
						{
							if (PhotonNetwork.IsMasterClient || !SemiFunc.IsMultiplayer())
							{
								SendCarryEvent(instance.photonView.ViewID, ((Component)_myCarriedHead).GetComponent<PhotonView>().ViewID, 2, 2);
							}
							else
							{
								SendCarryEventToHost(instance.photonView.ViewID, ((Component)_myCarriedHead).GetComponent<PhotonView>().ViewID, 2, 6);
							}
						}
					}
				}
				if (Input.GetKey((KeyCode)101))
				{
					_releaseTimer += Time.deltaTime;
					float num2 = Plugin.RequiredHoldTime();
					if (_releaseTimer >= num2)
					{
						ForceReleaseAllCarried();
						_releaseTimer = 0f;
					}
				}
				else
				{
					_releaseTimer = 0f;
				}
			}
			else
			{
				if (_isCarrying || _isBeingCarried || GetPlayerDeadSet(instance) || GetPlayerIsTumbling(instance))
				{
					return;
				}
				if (ScanTarget(out var targetPlayer, out var targetHead, out var targetName))
				{
					int num3 = (((Object)(object)targetPlayer != (Object)null) ? targetPlayer.photonView.ViewID : ((Component)targetHead).GetComponent<PhotonView>().ViewID);
					int targetType = (((Object)(object)targetPlayer != (Object)null) ? 1 : 2);
					if (!ActiveCarries.ContainsKey(num3))
					{
						object obj = ((object)targetPlayer) ?? ((object)targetHead);
						if (_currentTargetObj != obj)
						{
							_currentTargetObj = obj;
							_currentTargetName = targetName;
							_holdTimer = 0f;
						}
						if (Input.GetKey((KeyCode)101))
						{
							if (_holdTimer == 0f && !PhotonNetwork.IsMasterClient && SemiFunc.IsMultiplayer())
							{
								SendCarryEventToHost(PhotonNetwork.LocalPlayer.ActorNumber, 0, 0, 3);
							}
							_holdTimer += Time.deltaTime;
							float num4 = Plugin.RequiredHoldTime();
							if (_holdTimer >= num4)
							{
								if (PhotonNetwork.IsMasterClient || !SemiFunc.IsMultiplayer())
								{
									SendCarryEvent(instance.photonView.ViewID, num3, targetType, 1);
								}
								else if (_isHostModInstalled)
								{
									SendCarryEventToHost(instance.photonView.ViewID, num3, targetType, 5);
								}
								else
								{
									_hostModMissingPromptTimer = 2.5f;
									Plugin.Log.LogWarning((object)"Host has not installed CarryFriend mod. Carry request rejected.");
								}
								_holdTimer = 0f;
								_currentTargetObj = null;
							}
						}
						else
						{
							_holdTimer = 0f;
						}
						return;
					}
				}
				_currentTargetObj = null;
				_holdTimer = 0f;
			}
		}

		private void ForceReleaseAllCarried()
		{
			PlayerAvatar instance = PlayerAvatar.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			int num = 0;
			int targetType = 0;
			if ((Object)(object)_myCarriedPlayer != (Object)null)
			{
				num = _myCarriedPlayer.photonView.ViewID;
				targetType = 1;
			}
			else if ((Object)(object)_myCarriedHead != (Object)null)
			{
				num = ((Component)_myCarriedHead).GetComponent<PhotonView>().ViewID;
				targetType = 2;
			}
			if (num != 0)
			{
				if (PhotonNetwork.IsMasterClient || !SemiFunc.IsMultiplayer())
				{
					SendCarryEvent(instance.photonView.ViewID, num, targetType, 2);
				}
				else
				{
					SendCarryEventToHost(instance.photonView.ViewID, num, targetType, 6);
				}
			}
		}

		private string GetPlayerName(PlayerAvatar player)
		{
			if ((Object)(object)player == (Object)null)
			{
				if (!Plugin.UseChinese())
				{
					return "Unknown Player";
				}
				return "未知玩家";
			}
			try
			{
				string value = Traverse.Create((object)player).Field<string>("playerName").Value;
				if (!string.IsNullOrWhiteSpace(value))
				{
					return value.Trim();
				}
			}
			catch
			{
			}
			try
			{
				PhotonView photonView = player.photonView;
				object obj2;
				if (photonView == null)
				{
					obj2 = null;
				}
				else
				{
					Player owner = photonView.Owner;
					obj2 = ((owner != null) ? owner.NickName : null);
				}
				string text = (string)obj2;
				if (!string.IsNullOrWhiteSpace(text))
				{
					return text.Trim();
				}
			}
			catch
			{
			}
			try
			{
				string text2 = SemiFunc.PlayerGetName(player);
				if (!string.IsNullOrWhiteSpace(text2))
				{
					return text2.Trim();
				}
			}
			catch
			{
			}
			string name = ((Object)player).name;
			if (!string.IsNullOrWhiteSpace(name))
			{
				return name.Trim();
			}
			if (!Plugin.UseChinese())
			{
				return "Player";
			}
			return "玩家";
		}

		private bool ScanTarget(out PlayerAvatar targetPlayer, out PlayerDeathHead targetHead, out string targetName)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0340: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			targetPlayer = null;
			targetHead = null;
			targetName = "";
			PlayerAvatar instance = PlayerAvatar.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.localCamera == (Object)null)
			{
				return false;
			}
			Transform transform = ((Component)instance.localCamera).transform;
			Ray val = default(Ray);
			((Ray)(ref val))..ctor(transform.position, transform.forward);
			float num = 3.5f;
			int mask = LayerMask.GetMask(new string[3] { "Default", "Player", "PhysGrabObject" });
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Raycast(val, ref val2, num, mask, (QueryTriggerInteraction)1))
			{
				PlayerDeathHead componentInParent = ((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<PlayerDeathHead>();
				if ((Object)(object)componentInParent != (Object)null)
				{
					targetHead = componentInParent;
					if ((Object)(object)componentInParent.playerAvatar != (Object)null)
					{
						targetName = GetPlayerName(componentInParent.playerAvatar) + (Plugin.UseChinese() ? " (尸体)" : " (Corpse)");
					}
					else
					{
						targetName = (Plugin.UseChinese() ? "死亡队友" : "Dead Teammate");
					}
					return true;
				}
				PlayerAvatar val3 = ((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<PlayerAvatar>();
				if ((Object)(object)val3 == (Object)null)
				{
					PlayerTumble componentInParent2 = ((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<PlayerTumble>();
					if ((Object)(object)componentInParent2 != (Object)null)
					{
						val3 = componentInParent2.playerAvatar;
					}
				}
				if ((Object)(object)val3 != (Object)null && (Object)(object)val3 != (Object)(object)instance)
				{
					int num2 = (((Object)(object)val3.photonView != (Object)null) ? val3.photonView.ViewID : 0);
					bool flag = ActiveCarries.ContainsKey(num2);
					bool flag2 = false;
					foreach (int value in ActiveCarries.Values)
					{
						if (value == num2)
						{
							flag2 = true;
							break;
						}
					}
					if (!GetPlayerDeadSet(val3) && !GetPlayerIsDisabled(val3) && !flag && !flag2)
					{
						targetPlayer = val3;
						targetName = GetPlayerName(val3);
						return true;
					}
				}
			}
			if ((Object)(object)GameDirector.instance != (Object)null && GameDirector.instance.PlayerList != null)
			{
				PlayerAvatar val4 = null;
				float num3 = 20f;
				float num4 = 3.5f;
				foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
				{
					if ((Object)(object)player == (Object)null || (Object)(object)player == (Object)(object)instance || GetPlayerDeadSet(player) || GetPlayerIsDisabled(player))
					{
						continue;
					}
					int num5 = (((Object)(object)player.photonView != (Object)null) ? player.photonView.ViewID : 0);
					if (ActiveCarries.ContainsKey(num5))
					{
						continue;
					}
					bool flag3 = false;
					foreach (int value2 in ActiveCarries.Values)
					{
						if (value2 == num5)
						{
							flag3 = true;
							break;
						}
					}
					if (flag3)
					{
						continue;
					}
					Vector3 position = ((Component)player).transform.position;
					PlayerTumble playerTumble = GetPlayerTumble(player);
					if ((Object)(object)playerTumble != (Object)null && GetPlayerIsTumbling(player))
					{
						position = ((Component)playerTumble).transform.position;
					}
					if (Vector3.Distance(transform.position, position) <= num4)
					{
						Vector3 val5 = position - transform.position;
						Vector3 normalized = ((Vector3)(ref val5)).normalized;
						float num6 = Vector3.Angle(transform.forward, normalized);
						if (num6 < num3)
						{
							num3 = num6;
							val4 = player;
						}
					}
				}
				if ((Object)(object)val4 != (Object)null)
				{
					targetPlayer = val4;
					targetName = GetPlayerName(val4);
					return true;
				}
			}
			return false;
		}

		private bool IsGrabingTarget(PlayerAvatar local, object target)
		{
			if ((Object)(object)local == (Object)null || (Object)(object)local.physGrabber == (Object)null || target == null)
			{
				return false;
			}
			try
			{
				if (Traverse.Create((object)local.physGrabber).Field<bool>("grabbed").Value)
				{
					PhysGrabObject value = Traverse.Create((object)local.physGrabber).Field<PhysGrabObject>("grabbedPhysGrabObject").Value;
					Rigidbody value2 = Traverse.Create((object)local.physGrabber).Field<Rigidbody>("grabbedObject").Value;
					PlayerDeathHead val = (PlayerDeathHead)((target is PlayerDeathHead) ? target : null);
					if (val != null)
					{
						PhysGrabObject component = ((Component)val).GetComponent<PhysGrabObject>();
						if ((Object)(object)value != (Object)null && (Object)(object)component != (Object)null && (Object)(object)value == (Object)(object)component)
						{
							return true;
						}
						Rigidbody val2 = (((Object)(object)component != (Object)null) ? component.rb : null);
						if ((Object)(object)value2 != (Object)null && (Object)(object)val2 != (Object)null && (Object)(object)value2 == (Object)(object)val2)
						{
							return true;
						}
					}
					else
					{
						PlayerAvatar val3 = (PlayerAvatar)((target is PlayerAvatar) ? target : null);
						if (val3 != null)
						{
							PlayerTumble playerTumble = GetPlayerTumble(val3);
							PhysGrabObject tumblePhysGrabObject = GetTumblePhysGrabObject(playerTumble);
							if ((Object)(object)value != (Object)null && (Object)(object)tumblePhysGrabObject != (Object)null && (Object)(object)value == (Object)(object)tumblePhysGrabObject)
							{
								return true;
							}
							Rigidbody component2 = ((Component)val3).GetComponent<Rigidbody>();
							if ((Object)(object)value2 != (Object)null && (Object)(object)component2 != (Object)null && (Object)(object)value2 == (Object)(object)component2)
							{
								return true;
							}
							Rigidbody tumbleRb = GetTumbleRb(playerTumble);
							if ((Object)(object)value2 != (Object)null && (Object)(object)tumbleRb != (Object)null && (Object)(object)value2 == (Object)(object)tumbleRb)
							{
								return true;
							}
						}
					}
				}
			}
			catch
			{
			}
			if (SemiFunc.InputHold((InputKey)10) && ScanTarget(out var targetPlayer, out var targetHead, out var _) && (((object)targetPlayer) ?? ((object)targetHead)) == target)
			{
				return true;
			}
			return false;
		}

		private void SetCollisionIgnore(PlayerAvatar carrier, PlayerAvatar carriedPlayer, bool ignore)
		{
			if ((Object)(object)carrier == (Object)null || (Object)(object)carriedPlayer == (Object)null)
			{
				return;
			}
			try
			{
				Collider[] componentsInChildren = ((Component)carrier).GetComponentsInChildren<Collider>(true);
				Collider[] componentsInChildren2 = ((Component)carriedPlayer).GetComponentsInChildren<Collider>(true);
				PlayerTumble playerTumble = GetPlayerTumble(carriedPlayer);
				List<Collider> list = new List<Collider>(componentsInChildren2);
				Collider[] colliders;
				if ((Object)(object)playerTumble != (Object)null && playerTumble.colliders != null)
				{
					colliders = playerTumble.colliders;
					foreach (Collider val in colliders)
					{
						if ((Object)(object)val != (Object)null && !list.Contains(val))
						{
							list.Add(val);
						}
					}
				}
				colliders = componentsInChildren;
				foreach (Collider val2 in colliders)
				{
					if ((Object)(object)val2 == (Object)null)
					{
						continue;
					}
					foreach (Collider item in list)
					{
						if (!((Object)(object)item == (Object)null) && !((Object)(object)val2 == (Object)(object)item))
						{
							Physics.IgnoreCollision(val2, item, ignore);
						}
					}
				}
			}
			catch
			{
			}
		}

		private void SetCollisionIgnoreHead(PlayerAvatar carrier, PlayerDeathHead carriedHead, bool ignore)
		{
			if ((Object)(object)carrier == (Object)null || (Object)(object)carriedHead == (Object)null)
			{
				return;
			}
			try
			{
				Collider[] componentsInChildren = ((Component)carrier).GetComponentsInChildren<Collider>(true);
				Collider[] componentsInChildren2 = ((Component)carriedHead).GetComponentsInChildren<Collider>(true);
				Collider[] array = componentsInChildren;
				foreach (Collider val in array)
				{
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					Collider[] array2 = componentsInChildren2;
					foreach (Collider val2 in array2)
					{
						if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val == (Object)(object)val2))
						{
							Physics.IgnoreCollision(val, val2, ignore);
						}
					}
				}
			}
			catch
			{
			}
		}

		private void SendCarryEvent(int carrierViewId, int targetViewId, int targetType, int actionType)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if (!SemiFunc.IsMultiplayer())
			{
				HandleCarryAction(carrierViewId, targetViewId, targetType, actionType);
				return;
			}
			try
			{
				object[] array = new object[4] { carrierViewId, targetViewId, targetType, actionType };
				RaiseEventOptions val = new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)1
				};
				PhotonNetwork.RaiseEvent((byte)188, (object)array, val, SendOptions.SendReliable);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Failed to send carry event: " + ex.Message));
			}
		}

		private void SendCarryEventToHost(int carrierViewId, int targetViewId, int targetType, int actionType)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if (!SemiFunc.IsMultiplayer())
			{
				HandleCarryAction(carrierViewId, targetViewId, targetType, actionType);
				return;
			}
			try
			{
				object[] array = new object[4] { carrierViewId, targetViewId, targetType, actionType };
				RaiseEventOptions val = new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)2
				};
				PhotonNetwork.RaiseEvent((byte)188, (object)array, val, SendOptions.SendReliable);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Failed to send carry event to host: " + ex.Message));
			}
		}

		private void OnEvent(EventData photonEvent)
		{
			if (photonEvent.Code != 188)
			{
				return;
			}
			try
			{
				object[] array = (object[])photonEvent.CustomData;
				if (array == null || array.Length != 4)
				{
					return;
				}
				int num = (int)array[0];
				int num2 = (int)array[1];
				int targetType = (int)array[2];
				int num3 = (int)array[3];
				switch (num3)
				{
				case 3:
					if (PhotonNetwork.IsMasterClient)
					{
						int targetViewId = num;
						SendCarryEvent(PhotonNetwork.LocalPlayer.ActorNumber, targetViewId, 0, 4);
					}
					break;
				case 4:
				{
					int num4 = num2;
					if (PhotonNetwork.LocalPlayer != null && num4 == PhotonNetwork.LocalPlayer.ActorNumber)
					{
						_isHostModInstalled = true;
						Plugin.Log.LogInfo((object)"Successfully verified that the Host has CarryFriend installed!");
					}
					break;
				}
				case 5:
					if (PhotonNetwork.IsMasterClient && !ActiveCarries.ContainsKey(num2))
					{
						SendCarryEvent(num, num2, targetType, 1);
					}
					break;
				case 6:
					if (PhotonNetwork.IsMasterClient)
					{
						SendCarryEvent(num, num2, targetType, 2);
					}
					break;
				default:
					HandleCarryAction(num, num2, targetType, num3);
					break;
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Error processing carry event: " + ex.Message));
			}
		}

		private void HandleCarryAction(int carrierViewId, int targetViewId, int targetType, int actionType)
		{
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			PlayerAvatar val = FindPlayerAvatarByViewID(carrierViewId);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			switch (actionType)
			{
			case 1:
				ActiveCarries[targetViewId] = carrierViewId;
				CarryStartTimes[targetViewId] = Time.time;
				break;
			case 2:
				ActiveCarries.Remove(targetViewId);
				CarryStartTimes.Remove(targetViewId);
				break;
			}
			switch (targetType)
			{
			case 1:
			{
				PlayerAvatar val3 = FindPlayerAvatarByViewID(targetViewId);
				if ((Object)(object)val3 == (Object)null)
				{
					break;
				}
				switch (actionType)
				{
				case 1:
				{
					try
					{
						List<Collider> list = new List<Collider>();
						Collider[] componentsInChildren = ((Component)val3).GetComponentsInChildren<Collider>(true);
						foreach (Collider val6 in componentsInChildren)
						{
							if ((Object)(object)val6 != (Object)null && val6.enabled && !val6.isTrigger)
							{
								val6.isTrigger = true;
								list.Add(val6);
							}
						}
						CarryTriggerColliders[targetViewId] = list;
					}
					catch
					{
					}
					SetCollisionIgnore(val, val3, ignore: true);
					PlayerTumble playerTumble3 = GetPlayerTumble(val3);
					if ((Object)(object)playerTumble3 != (Object)null)
					{
						playerTumble3.TumbleRequest(true, false);
						playerTumble3.TumbleOverrideTime(0.5f);
					}
					if (GetPlayerIsLocal(val3))
					{
						_myCarrier = val;
						_isBeingCarried = true;
					}
					else
					{
						if (!GetPlayerIsLocal(val))
						{
							break;
						}
						_myCarriedPlayer = val3;
						_isCarrying = true;
						_myCarriedHead = null;
						if ((Object)(object)val.physGrabber != (Object)null)
						{
							try
							{
								val.physGrabber.ReleaseObject(-1, 0.2f);
								break;
							}
							catch
							{
								break;
							}
						}
					}
					break;
				}
				case 2:
				{
					if (CarryTriggerColliders.TryGetValue(targetViewId, out var value))
					{
						foreach (Collider item in value)
						{
							if ((Object)(object)item != (Object)null)
							{
								item.isTrigger = false;
							}
						}
						CarryTriggerColliders.Remove(targetViewId);
					}
					SetCollisionIgnore(val, val3, ignore: false);
					if (GetPlayerIsLocal(val3))
					{
						PlayerTumble playerTumble = GetPlayerTumble(val3);
						if ((Object)(object)playerTumble != (Object)null)
						{
							playerTumble.TumbleRequest(false, false);
						}
						val3.TumbleStop();
						if ((Object)(object)PlayerController.instance != (Object)null)
						{
							PlayerController.instance.Crouching = false;
							Traverse.Create((object)PlayerController.instance).Field<bool>("toggleCrouch").Value = false;
							Traverse.Create((object)PlayerController.instance).Field<float>("crouchOverrideTimer").Value = 0f;
						}
						val3.UpdateState(false, false, false, false, false);
						Rigidbody val4 = (((Object)(object)PlayerController.instance != (Object)null) ? PlayerController.instance.rb : null);
						if ((Object)(object)val4 != (Object)null)
						{
							val4.isKinematic = false;
							Vector3 val5 = -((Component)val).transform.forward * 2.5f + Vector3.up * 1.2f;
							val4.AddForce(val5, (ForceMode)2);
						}
						_myCarrier = null;
						_isBeingCarried = false;
					}
					else if (GetPlayerIsLocal(val))
					{
						_myCarriedPlayer = null;
						_isCarrying = false;
					}
					if (!GetPlayerIsLocal(val3))
					{
						Rigidbody component2 = ((Component)val3).GetComponent<Rigidbody>();
						if ((Object)(object)component2 != (Object)null)
						{
							component2.isKinematic = false;
						}
						PlayerTumble playerTumble2 = GetPlayerTumble(val3);
						if ((Object)(object)playerTumble2 != (Object)null)
						{
							playerTumble2.TumbleRequest(false, false);
						}
						val3.TumbleStop();
						val3.UpdateState(false, false, false, false, false);
					}
					break;
				}
				}
				break;
			}
			case 2:
			{
				PlayerDeathHead val2 = FindDeathHeadByViewID(targetViewId);
				if ((Object)(object)val2 == (Object)null)
				{
					break;
				}
				switch (actionType)
				{
				case 1:
				{
					SetCollisionIgnoreHead(val, val2, ignore: true);
					if (!GetPlayerIsLocal(val))
					{
						break;
					}
					_myCarriedHead = val2;
					_myCarriedPlayer = null;
					_isCarrying = true;
					PhotonView component = ((Component)val2).GetComponent<PhotonView>();
					if ((Object)(object)component != (Object)null && !component.IsMine)
					{
						component.RequestOwnership();
					}
					if ((Object)(object)val.physGrabber != (Object)null)
					{
						try
						{
							val.physGrabber.ReleaseObject(-1, 0.2f);
							break;
						}
						catch
						{
							break;
						}
					}
					break;
				}
				case 2:
					SetCollisionIgnoreHead(val, val2, ignore: false);
					if (GetPlayerIsLocal(val))
					{
						_myCarriedHead = null;
						_isCarrying = false;
					}
					break;
				}
				break;
			}
			}
		}

		private PlayerAvatar FindPlayerAvatarByViewID(int viewId)
		{
			if ((Object)(object)GameDirector.instance == (Object)null || GameDirector.instance.PlayerList == null)
			{
				return null;
			}
			foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
			{
				if ((Object)(object)player != (Object)null && (Object)(object)player.photonView != (Object)null && player.photonView.ViewID == viewId)
				{
					return player;
				}
			}
			return null;
		}

		private PlayerDeathHead FindDeathHeadByViewID(int viewId)
		{
			PhotonView val = PhotonView.Find(viewId);
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return ((Component)val).GetComponent<PlayerDeathHead>();
		}

		private void ResetState()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				foreach (KeyValuePair<int, int> activeCarry in ActiveCarries)
				{
					PlayerAvatar val = FindPlayerAvatarByViewID(activeCarry.Key);
					if ((Object)(object)val != (Object)null)
					{
						try
						{
							((Component)val).transform.localScale = Vector3.one;
						}
						catch
						{
						}
						Rigidbody component = ((Component)val).GetComponent<Rigidbody>();
						if ((Object)(object)component != (Object)null)
						{
							component.isKinematic = false;
						}
						PlayerTumble playerTumble = GetPlayerTumble(val);
						if ((Object)(object)playerTumble != (Object)null)
						{
							playerTumble.TumbleRequest(false, false);
						}
						val.TumbleStop();
						val.UpdateState(false, false, false, false, false);
					}
				}
				PlayerAvatar instance = PlayerAvatar.instance;
				if ((Object)(object)instance != (Object)null)
				{
					PlayerTumble playerTumble2 = GetPlayerTumble(instance);
					if ((Object)(object)playerTumble2 != (Object)null)
					{
						playerTumble2.TumbleRequest(false, false);
					}
					instance.TumbleStop();
					if ((Object)(object)PlayerController.instance != (Object)null)
					{
						((Behaviour)PlayerController.instance).enabled = true;
						PlayerController.instance.Crouching = false;
						Traverse.Create((object)PlayerController.instance).Field<bool>("toggleCrouch").Value = false;
						Traverse.Create((object)PlayerController.instance).Field<float>("crouchOverrideTimer").Value = 0f;
						Rigidbody rb = PlayerController.instance.rb;
						if ((Object)(object)rb != (Object)null)
						{
							rb.isKinematic = false;
						}
					}
					instance.UpdateState(false, false, false, false, false);
					if ((Object)(object)_myCarrier != (Object)null)
					{
						SetCollisionIgnore(_myCarrier, instance, ignore: false);
						try
						{
							((Component)instance).transform.localScale = Vector3.one;
						}
						catch
						{
						}
					}
				}
				if ((Object)(object)_myCarriedPlayer != (Object)null && (Object)(object)instance != (Object)null)
				{
					SetCollisionIgnore(instance, _myCarriedPlayer, ignore: false);
					try
					{
						((Component)_myCarriedPlayer).transform.localScale = Vector3.one;
					}
					catch
					{
					}
				}
				if ((Object)(object)_myCarriedHead != (Object)null && (Object)(object)instance != (Object)null)
				{
					SetCollisionIgnoreHead(instance, _myCarriedHead, ignore: false);
				}
				foreach (KeyValuePair<int, List<Collider>> carryTriggerCollider in CarryTriggerColliders)
				{
					if (carryTriggerCollider.Value == null)
					{
						continue;
					}
					foreach (Collider item in carryTriggerCollider.Value)
					{
						if ((Object)(object)item != (Object)null)
						{
							item.isTrigger = false;
						}
					}
				}
				CarryTriggerColliders.Clear();
			}
			catch
			{
			}
			_isBeingCarried = false;
			_myCarrier = null;
			_isCarrying = false;
			_myCarriedPlayer = null;
			_myCarriedHead = null;
			_holdTimer = 0f;
			_currentTargetObj = null;
			ActiveCarries.Clear();
			CarryStartTimes.Clear();
		}

		private bool GetPlayerIsLocal(PlayerAvatar player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			if ((Object)(object)player.photonView != (Object)null)
			{
				return player.photonView.IsMine;
			}
			return Traverse.Create((object)player).Field<bool>("isLocal").Value;
		}

		private bool GetPlayerDeadSet(PlayerAvatar player)
		{
			if ((Object)(object)player != (Object)null)
			{
				return Traverse.Create((object)player).Field<bool>("deadSet").Value;
			}
			return false;
		}

		private bool GetPlayerIsDisabled(PlayerAvatar player)
		{
			if ((Object)(object)player != (Object)null)
			{
				return Traverse.Create((object)player).Field<bool>("isDisabled").Value;
			}
			return false;
		}

		private bool GetPlayerIsTumbling(PlayerAvatar player)
		{
			if ((Object)(object)player != (Object)null)
			{
				return Traverse.Create((object)player).Field<bool>("isTumbling").Value;
			}
			return false;
		}

		private PlayerTumble GetPlayerTumble(PlayerAvatar player)
		{
			if (!((Object)(object)player != (Object)null))
			{
				return null;
			}
			return Traverse.Create((object)player).Field<PlayerTumble>("tumble").Value;
		}

		private PhysGrabObject GetTumblePhysGrabObject(PlayerTumble tumble)
		{
			if (!((Object)(object)tumble != (Object)null))
			{
				return null;
			}
			object? obj = Plugin.F_TumblePhysGrabObject?.GetValue(tumble);
			return (PhysGrabObject)((obj is PhysGrabObject) ? obj : null);
		}

		private Rigidbody GetTumbleRb(PlayerTumble tumble)
		{
			if (!((Object)(object)tumble != (Object)null))
			{
				return null;
			}
			object? obj = Plugin.F_TumbleRb?.GetValue(tumble);
			return (Rigidbody)((obj is Rigidbody) ? obj : null);
		}

		private void DisablePhysGrabObjectImpact(PhysGrabObject physGrabObject, float duration)
		{
			if ((Object)(object)physGrabObject == (Object)null)
			{
				return;
			}
			object obj = Plugin.F_PhysGrabObjectImpactDetector?.GetValue(physGrabObject);
			if (obj == null)
			{
				return;
			}
			try
			{
				obj.GetType().GetMethod("ImpactDisable", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(obj, new object[1] { duration });
			}
			catch
			{
			}
		}

		private void OnGUI()
		{
			if (!Plugin.IsStaticModEnabled())
			{
				return;
			}
			if (_currentTargetObj != null && _holdTimer > 0f)
			{
				float num = Plugin.RequiredHoldTime();
				string label = (Plugin.UseChinese() ? ("正在背起 " + _currentTargetName) : ("Carrying " + _currentTargetName));
				DrawProgressBar(label, _holdTimer / num);
			}
			if (_isCarrying && _releaseTimer > 0f)
			{
				float num2 = Plugin.RequiredHoldTime();
				string text = "";
				if ((Object)(object)_myCarriedPlayer != (Object)null)
				{
					text = GetPlayerName(_myCarriedPlayer);
				}
				else if ((Object)(object)_myCarriedHead != (Object)null)
				{
					text = ((!((Object)(object)_myCarriedHead.playerAvatar != (Object)null)) ? (Plugin.UseChinese() ? "死亡队友" : "Dead Teammate") : (GetPlayerName(_myCarriedHead.playerAvatar) + (Plugin.UseChinese() ? " (尸体)" : " (Corpse)")));
				}
				string label2 = (Plugin.UseChinese() ? ("正在放下 " + text) : ("Releasing " + text));
				DrawProgressBar(label2, _releaseTimer / num2);
			}
			if (_hostModMissingPromptTimer > 0f)
			{
				string text2 = (Plugin.UseChinese() ? "房主未安装背人模组,无法背起!" : "Host has not installed CarryFriend, carry disabled!");
				DrawWarningBar(text2);
			}
		}

		private void DrawProgressBar(string label, float progress)
		{
			//IL_0054: 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_0067: Expected O, but got Unknown
			//IL_007a: 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_00f2: Expected O, but got Unknown
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Expected O, but got Unknown
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: 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)
			//IL_00c6: Expected O, but got Unknown
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			progress = Mathf.Clamp01(progress);
			float num = Screen.width;
			float num2 = Screen.height;
			float num3 = 320f;
			float num4 = 26f;
			float num5 = (num - num3) / 2f;
			float num6 = (num2 - num4) / 2f + 120f;
			Texture2D background = MakeTex((int)num3, (int)num4, new Color(0.12f, 0.12f, 0.12f, 0.65f));
			GUIStyle val = new GUIStyle();
			val.normal.background = background;
			GUI.Box(new Rect(num5, num6, num3, num4), "", val);
			float num7 = num3 * progress;
			if (num7 > 0f)
			{
				Texture2D background2 = MakeTex((int)num7, (int)num4, new Color(0.12f, 0.78f, 0.44f, 0.85f));
				GUIStyle val2 = new GUIStyle();
				val2.normal.background = background2;
				GUI.Box(new Rect(num5, num6, num7, num4), "", val2);
			}
			GUIStyle val3 = new GUIStyle();
			val3.alignment = (TextAnchor)4;
			val3.normal.textColor = Color.white;
			val3.fontSize = 13;
			val3.fontStyle = (FontStyle)1;
			Rect val4 = default(Rect);
			((Rect)(ref val4))..ctor(num5, num6, num3, num4);
			Rect val5 = new Rect(((Rect)(ref val4)).x + 1f, ((Rect)(ref val4)).y + 1f, ((Rect)(ref val4)).width, ((Rect)(ref val4)).height);
			GUIStyle val6 = new GUIStyle(val3);
			val6.normal.textColor = Color.black;
			GUI.Label(val5, label, val6);
			GUI.Label(val4, label, val3);
		}

		private void DrawWarningBar(string text)
		{
			//IL_004c: 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_005f: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Expected O, but got Unknown
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			float num = Screen.width;
			float num2 = Screen.height;
			float num3 = 360f;
			float num4 = 30f;
			float num5 = (num - num3) / 2f;
			float num6 = (num2 - num4) / 2f + 120f;
			Texture2D background = MakeTex((int)num3, (int)num4, new Color(0.18f, 0.05f, 0.05f, 0.85f));
			GUIStyle val = new GUIStyle();
			val.normal.background = background;
			GUI.Box(new Rect(num5, num6, num3, num4), "", val);
			GUIStyle val2 = new GUIStyle();
			val2.alignment = (TextAnchor)4;
			val2.normal.textColor = new Color(1f, 0.22f, 0.22f, 0.95f);
			val2.fontSize = 13;
			val2.fontStyle = (FontStyle)1;
			Rect val3 = default(Rect);
			((Rect)(ref val3))..ctor(num5, num6, num3, num4);
			Rect val4 = new Rect(((Rect)(ref val3)).x + 1f, ((Rect)(ref val3)).y + 1f, ((Rect)(ref val3)).width, ((Rect)(ref val3)).height);
			GUIStyle val5 = new GUIStyle(val2);
			val5.normal.textColor = Color.black;
			GUI.Label(val4, text, val5);
			GUI.Label(val3, text, val2);
		}

		private Texture2D MakeTex(int width, int height, Color col)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			Color[] array = (Color[])(object)new Color[width * height];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = col;
			}
			Texture2D val = new Texture2D(width, height);
			val.SetPixels(array);
			val.Apply();
			return val;
		}
	}
	internal sealed class ConfigurationManagerAttributes
	{
		public int? Order;

		public bool? ReadOnly;

		public bool? Browsable;

		public bool? HideDefaultButton;

		public string Category;

		public string DispName;

		public string Description;
	}
}