Decompiled source of CarryFriend v1.0.3

Zichen-CarryFriend-1.0.3.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
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;
using UnityEngine.SceneManagement;

[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.3")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+1918d1347cd2a511075b90d16314e1559b166911")]
[assembly: AssemblyProduct("Zichen-CarryFriend-1.0.3")]
[assembly: AssemblyTitle("Zichen-CarryFriend-1.0.3")]
[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.3")]
	public class Plugin : BaseUnityPlugin
	{
		public delegate void ImpactDisableDelegate(PhysGrabObjectImpactDetector detector, float duration);

		[HarmonyPatch(typeof(PlayerAvatar), "Start")]
		public static class PlayerAvatarStartPatch
		{
			public static void Postfix(PlayerAvatar __instance)
			{
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Expected O, but got Unknown
				try
				{
					if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.photonView == (Object)null)
					{
						return;
					}
					int viewID = __instance.photonView.ViewID;
					if (viewID <= 0)
					{
						return;
					}
					if (__instance.photonView.IsMine)
					{
						GameObject val = GameObject.Find("Zichen_CarryFriend_Runtime");
						if ((Object)(object)val == (Object)null)
						{
							val = new GameObject("Zichen_CarryFriend_Runtime");
							val.AddComponent<CarryFriendBehaviour>();
							((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Successfully created CarryFriendBehaviour on local player avatar start.");
							return;
						}
						CarryFriendBehaviour component = val.GetComponent<CarryFriendBehaviour>();
						if ((Object)(object)component != (Object)null)
						{
							component.LocalPlayerRespawnReset();
						}
					}
					else if ((Object)(object)CarryFriendBehaviour.Instance != (Object)null)
					{
						CarryFriendBehaviour.Instance.ClearPlayerCarryState(viewID);
					}
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)Instance).Logger.LogError((object)("Error in PlayerAvatar.Start Postfix: " + ex.Message));
				}
			}
		}

		[HarmonyPatch(typeof(PlayerAvatar), "OnDestroy")]
		public static class PlayerAvatarOnDestroyPatch
		{
			public static void Postfix(PlayerAvatar __instance)
			{
				if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.photonView == (Object)null)
				{
					return;
				}
				try
				{
					if ((Object)(object)CarryFriendBehaviour.Instance != (Object)null)
					{
						CarryFriendBehaviour.Instance.ClearPlayerCarryState(__instance.photonView.ViewID);
					}
				}
				catch
				{
				}
			}
		}

		[HarmonyPatch(typeof(PlayerDeathHead), "OnDestroy")]
		public static class PlayerDeathHeadOnDestroyPatch
		{
			public static void Postfix(PlayerDeathHead __instance)
			{
				if ((Object)(object)__instance == (Object)null)
				{
					return;
				}
				try
				{
					PhotonView component = ((Component)__instance).GetComponent<PhotonView>();
					if ((Object)(object)component != (Object)null && (Object)(object)CarryFriendBehaviour.Instance != (Object)null)
					{
						CarryFriendBehaviour.Instance.ClearPlayerCarryState(component.ViewID);
					}
				}
				catch
				{
				}
			}
		}

		internal sealed class CfgI18N
		{
			public string SectionCN;

			public string SectionEN;

			public string KeyCN;

			public string KeyEN;

			public string DisplayEN;

			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.3";

		internal static Plugin Instance;

		internal static ManualLogSource Log;

		private static ConfigEntry<bool> _cfgModEnabled;

		private static ConfigEntry<DisplayLanguage> _cfgLanguage;

		private static ConfigEntry<float> _cfgRequiredHoldTime;

		private static ConfigEntry<int> _cfgMaxCarryCount;

		private static ConfigEntry<float> _cfgCarryHeightOffset;

		public static int HostMaxCarryCount = 1;

		public static float HostRequiredHoldTime = 0.6f;

		public static float HostCarryHeightOffset = 1.1f;

		public static readonly Dictionary<int, float> TumbleEnforceTimers = new Dictionary<int, float>();

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

		public static readonly FieldRef<PlayerTumble, PhysGrabObject> Ref_TumblePhysGrabObject = AccessTools.FieldRefAccess<PlayerTumble, PhysGrabObject>("physGrabObject");

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

		public static readonly FieldRef<PlayerTumble, Rigidbody> Ref_TumbleRb = AccessTools.FieldRefAccess<PlayerTumble, Rigidbody>("rb");

		public static readonly FieldInfo F_WingsCurrentState = AccessTools.Field(typeof(ItemUpgradePlayerTumbleWingsLogic), "currentState");

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

		public static readonly FieldRef<PhysGrabObject, PhysGrabObjectImpactDetector> Ref_PhysGrabObjectImpactDetector = AccessTools.FieldRefAccess<PhysGrabObject, PhysGrabObjectImpactDetector>("impactDetector");

		public static ImpactDisableDelegate Delegate_ImpactDisable = null;

		public static readonly FieldInfo F_IsLocal = AccessTools.Field(typeof(PlayerAvatar), "isLocal");

		public static readonly FieldRef<PlayerAvatar, bool> Ref_IsLocal = AccessTools.FieldRefAccess<PlayerAvatar, bool>("isLocal");

		public static readonly FieldInfo F_DeadSet = AccessTools.Field(typeof(PlayerAvatar), "deadSet");

		public static readonly FieldRef<PlayerAvatar, bool> Ref_DeadSet = AccessTools.FieldRefAccess<PlayerAvatar, bool>("deadSet");

		public static readonly FieldInfo F_IsDisabled = AccessTools.Field(typeof(PlayerAvatar), "isDisabled");

		public static readonly FieldRef<PlayerAvatar, bool> Ref_IsDisabled = AccessTools.FieldRefAccess<PlayerAvatar, bool>("isDisabled");

		public static readonly FieldInfo F_IsTumbling = AccessTools.Field(typeof(PlayerAvatar), "isTumbling");

		public static readonly FieldRef<PlayerAvatar, bool> Ref_IsTumbling = AccessTools.FieldRefAccess<PlayerAvatar, bool>("isTumbling");

		public static readonly FieldInfo F_Tumble = AccessTools.Field(typeof(PlayerAvatar), "tumble");

		public static readonly FieldRef<PlayerAvatar, PlayerTumble> Ref_Tumble = AccessTools.FieldRefAccess<PlayerAvatar, PlayerTumble>("tumble");

		public static readonly FieldInfo F_OverrideTumbleUIDisableTimer = AccessTools.Field(typeof(PlayerTumble), "overrideTumbleUIDisableTimer");

		public static readonly FieldRef<PlayerTumble, float> Ref_OverrideTumbleUIDisableTimer = AccessTools.FieldRefAccess<PlayerTumble, float>("overrideTumbleUIDisableTimer");

		public static readonly FieldInfo F_TumbleOverrideTimer = AccessTools.Field(typeof(PlayerTumble), "tumbleOverrideTimer");

		public static readonly FieldRef<PlayerTumble, float> Ref_TumbleOverrideTimer = AccessTools.FieldRefAccess<PlayerTumble, float>("tumbleOverrideTimer");

		public static readonly FieldInfo F_HealthGrabStaticGrabObject = AccessTools.Field(typeof(PlayerHealthGrab), "staticGrabObject");

		public static readonly FieldRef<PlayerHealthGrab, StaticGrabObject> Ref_HealthGrabStaticGrabObject = AccessTools.FieldRefAccess<PlayerHealthGrab, StaticGrabObject>("staticGrabObject");

		public static readonly FieldInfo F_PhysGrabberGrabbedStaticGrabObject = AccessTools.Field(typeof(PhysGrabber), "grabbedStaticGrabObject");

		public static readonly FieldRef<PhysGrabber, StaticGrabObject> Ref_PhysGrabberGrabbedStaticGrabObject = AccessTools.FieldRefAccess<PhysGrabber, StaticGrabObject>("grabbedStaticGrabObject");

		public static readonly FieldInfo F_PlayerName = AccessTools.Field(typeof(PlayerAvatar), "playerName");

		public static readonly FieldRef<PlayerAvatar, string> Ref_PlayerName = AccessTools.FieldRefAccess<PlayerAvatar, string>("playerName");

		public static readonly FieldInfo F_ClientRotation = AccessTools.Field(typeof(PlayerAvatar), "clientRotation");

		public static readonly FieldRef<PlayerAvatar, Quaternion> Ref_ClientRotation = AccessTools.FieldRefAccess<PlayerAvatar, Quaternion>("clientRotation");

		public static readonly FieldInfo F_ClientRotationCurrent = AccessTools.Field(typeof(PlayerAvatar), "clientRotationCurrent");

		public static readonly FieldRef<PlayerAvatar, Quaternion> Ref_ClientRotationCurrent = AccessTools.FieldRefAccess<PlayerAvatar, Quaternion>("clientRotationCurrent");

		public static readonly FieldInfo F_PhysGrabberGrabbed = AccessTools.Field(typeof(PhysGrabber), "grabbed");

		public static readonly FieldRef<PhysGrabber, bool> Ref_PhysGrabberGrabbed = AccessTools.FieldRefAccess<PhysGrabber, bool>("grabbed");

		public static readonly FieldInfo F_PhysGrabberGrabbedPhysGrabObject = AccessTools.Field(typeof(PhysGrabber), "grabbedPhysGrabObject");

		public static readonly FieldRef<PhysGrabber, PhysGrabObject> Ref_PhysGrabberGrabbedPhysGrabObject = AccessTools.FieldRefAccess<PhysGrabber, PhysGrabObject>("grabbedPhysGrabObject");

		public static readonly FieldInfo F_PhysGrabberGrabbedObject = AccessTools.Field(typeof(PhysGrabber), "grabbedObject");

		public static readonly FieldRef<PhysGrabber, Rigidbody> Ref_PhysGrabberGrabbedObject = AccessTools.FieldRefAccess<PhysGrabber, Rigidbody>("grabbedObject");

		public static readonly FieldInfo F_PlayerControllerToggleCrouch = AccessTools.Field(typeof(PlayerController), "toggleCrouch");

		public static readonly FieldRef<PlayerController, bool> Ref_PlayerControllerToggleCrouch = AccessTools.FieldRefAccess<PlayerController, bool>("toggleCrouch");

		public static readonly FieldInfo F_PlayerControllerCrouchOverrideTimer = AccessTools.Field(typeof(PlayerController), "crouchOverrideTimer");

		public static readonly FieldRef<PlayerController, float> Ref_PlayerControllerCrouchOverrideTimer = AccessTools.FieldRefAccess<PlayerController, float>("crouchOverrideTimer");

		public static readonly FieldInfo F_TumbleIsPlayerInputTriggered = AccessTools.Field(typeof(PlayerTumble), "isPlayerInputTriggered");

		public static readonly FieldRef<PlayerTumble, bool> Ref_TumbleIsPlayerInputTriggered = AccessTools.FieldRefAccess<PlayerTumble, bool>("isPlayerInputTriggered");

		public static readonly FieldRef<PlayerAvatar, Vector3> Ref_ClientPosition = AccessTools.FieldRefAccess<PlayerAvatar, Vector3>("clientPosition");

		public static readonly FieldRef<PlayerAvatar, Vector3> Ref_ClientPositionCurrent = AccessTools.FieldRefAccess<PlayerAvatar, Vector3>("clientPositionCurrent");

		public static readonly FieldRef<PlayerAvatar, bool> Ref_IsCrouching = AccessTools.FieldRefAccess<PlayerAvatar, bool>("isCrouching");

		public static readonly FieldRef<PlayerAvatar, bool> Ref_IsSprinting = AccessTools.FieldRefAccess<PlayerAvatar, bool>("isSprinting");

		public static readonly FieldRef<PlayerAvatar, bool> Ref_IsCrawling = AccessTools.FieldRefAccess<PlayerAvatar, bool>("isCrawling");

		public static readonly FieldRef<PlayerAvatar, bool> Ref_IsSliding = AccessTools.FieldRefAccess<PlayerAvatar, bool>("isSliding");

		public static readonly FieldRef<PlayerAvatar, bool> Ref_IsMoving = AccessTools.FieldRefAccess<PlayerAvatar, bool>("isMoving");

		internal static readonly Dictionary<int, PlayerTumble> CarriedTumbleCache = new Dictionary<int, PlayerTumble>();

		internal static readonly Dictionary<int, Rigidbody> CarriedAvatarRbCache = new Dictionary<int, Rigidbody>();

		internal static readonly Dictionary<int, Rigidbody> CarriedTumbleRbCache = new Dictionary<int, Rigidbody>();

		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 0.6f;
			}
			return _cfgRequiredHoldTime.Value;
		}

		public static int MaxCarryCount()
		{
			if (_cfgMaxCarryCount == null)
			{
				return 1;
			}
			return _cfgMaxCarryCount.Value;
		}

		public static float CarryHeightOffset()
		{
			if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient)
			{
				return HostCarryHeightOffset;
			}
			if (_cfgCarryHeightOffset == null)
			{
				return 1.1f;
			}
			return _cfgCarryHeightOffset.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.3 已禁用。");
				return;
			}
			try
			{
				Harmony val = new Harmony("zichen.carryfriend");
				val.PatchAll(Assembly.GetExecutingAssembly());
				TryHookREPOConfig(val);
				MethodInfo methodInfo = AccessTools.Method(typeof(PhysGrabObjectImpactDetector), "ImpactDisable", new Type[1] { typeof(float) }, (Type[])null);
				if (methodInfo != null)
				{
					Delegate_ImpactDisable = (ImpactDisableDelegate)Delegate.CreateDelegate(typeof(ImpactDisableDelegate), methodInfo);
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Harmony patch or delegate compilation failed: " + ex.Message));
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"CarryFriend v1.0.3 物理重构与多端兼容分拆版已加载(仅在游戏中激活)。");
		}

		private void BindConfig()
		{
			DisplayLanguage defaultVal = DetectDefaultLanguage();
			_cfgLanguage = Bind("A.Mod Info", "A.模组信息", "Carry Friend Language", "语言", "Switch display language.", "切换显示语言。", defaultVal, null, "Language");
			BindReadOnly("A.Mod Info", "A.模组信息", "Carry Friend Mod Name", "模组名称", "CarryFriend", "背起队友", "Mod Name");
			BindReadOnly("A.Mod Info", "A.模组信息", "Carry Friend Mod Version", "模组版本号", "1.0.3", "1.0.3", "Mod Version");
			_cfgModEnabled = Bind("B.Global", "B.全局设置", "Mod Enabled", "模组启用", "Disable to turn off the whole mod.", "关闭后整个模组全部功能失效。", defaultVal: true);
			_cfgRequiredHoldTime = Bind("C.Timers", "C.时间设置", "Interact Hold Duration (s)", "按住E背起时间 (秒)", "How long you need to hold Interact (E) to carry a player or head.", "按住交互键E背起队友或死尸头部所需的读条时长。", 0.6f);
			_cfgMaxCarryCount = Bind("D.Rules", "D.规则设置", "Max Carry Count", "最大背负数量", "Maximum number of players/heads a single person can carry (1-3). Managed by Host.", "单人同时背负的最大数量 (1-3)。由房主控制生效。", 1, (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 3));
			_cfgCarryHeightOffset = Bind("D.Rules", "D.规则设置", "Carry Height Offset", "被背起挂载高度", "Height offset for carried players/heads (0.1 - 2.0).", "被背载队友的挂载垂直高度偏置偏移量 (0.1 - 2.0)。", 1.1f, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f));
			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, string displayEN = null)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			CfgI18N cfgI18N = NewI18N(sectEN, sectCN, keyEN, keyCN, descEN, descCN, readOnly: false, displayEN);
			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, string displayEN = null)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			CfgI18N cfgI18N = NewI18N(sectEN, sectCN, keyEN, keyCN, "", "", readOnly: true, displayEN);
			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, string displayEN = null)
		{
			ConfigurationManagerAttributes attrs = (readOnly ? new ConfigurationManagerAttributes
			{
				ReadOnly = true,
				HideDefaultButton = true
			} : new ConfigurationManagerAttributes());
			CfgI18N cfgI18N = new CfgI18N
			{
				SectionEN = sectEN,
				SectionCN = sectCN,
				KeyEN = keyEN,
				KeyCN = keyCN,
				DisplayEN = displayEN,
				DescEN = descEN,
				DescCN = descCN,
				Attrs = attrs
			};
			ApplyI18N(cfgI18N);
			_cfgI18Ns.Add(cfgI18N);
			_cfgByEnSection[sectEN] = cfgI18N;
			_cfgByEnKey[keyEN] = cfgI18N;
			return cfgI18N;
		}

		private static void ApplyI18N(CfgI18N i18n)
		{
			if (i18n?.Attrs == null)
			{
				return;
			}
			i18n.Attrs.Category = i18n.SectionEN;
			i18n.Attrs.DispName = ((!string.IsNullOrEmpty(i18n.DisplayEN)) ? i18n.DisplayEN : i18n.KeyEN);
			i18n.Attrs.Description = i18n.DescEN;
			if (i18n.ReadOnlyEntry != null)
			{
				string text = (UseChinese() ? 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.3"))
					{
						((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.3, 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)^(?:Carry Friend )?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));
			}
		}

		private static string FixNamingForLookup(string input)
		{
			if (string.IsNullOrEmpty(input))
			{
				return input;
			}
			input = Regex.Replace(input, "([a-z])([A-Z])", "$1 $2");
			input = Regex.Replace(input, "([A-Z])([A-Z][a-z])", "$1 $2");
			input = Regex.Replace(input, "\\s+", " ");
			input = Regex.Replace(input, "([A-Z]\\.)\\s([A-Z]\\.)", "$1$2");
			return input.Trim();
		}

		internal static void RegisterLiveLabelIfMatched(string label, object uiElement)
		{
			if (string.IsNullOrEmpty(label) || uiElement == null)
			{
				return;
			}
			string text = label.Trim().Replace("▼", "").Replace("▶", "")
				.Replace(" ", "");
			CfgI18N cfgI18N = null;
			for (int i = 0; i < _cfgI18Ns.Count; i++)
			{
				CfgI18N cfgI18N2 = _cfgI18Ns[i];
				string value = cfgI18N2.SectionEN?.Replace(" ", "");
				string value2 = cfgI18N2.SectionCN?.Replace(" ", "");
				if ((!string.IsNullOrEmpty(value) && text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) || (!string.IsNullOrEmpty(value2) && text.IndexOf(value2, StringComparison.OrdinalIgnoreCase) >= 0))
				{
					cfgI18N = cfgI18N2;
					break;
				}
			}
			bool flag = cfgI18N != null;
			CfgI18N value3 = null;
			if (flag)
			{
				value3 = cfgI18N;
			}
			else if (!_cfgByEnKey.TryGetValue(label, out value3))
			{
				string text2 = FixNamingForLookup(label);
				if (!_cfgByEnKey.TryGetValue(text2, out value3))
				{
					foreach (KeyValuePair<string, CfgI18N> item in _cfgByEnKey)
					{
						if (string.Equals(item.Key, label, StringComparison.OrdinalIgnoreCase) || string.Equals(item.Key, text2, StringComparison.OrdinalIgnoreCase))
						{
							value3 = item.Value;
							break;
						}
					}
				}
			}
			if (value3 == null)
			{
				return;
			}
			TextMeshProUGUI labelTmp = GetLabelTmp(uiElement);
			if ((Object)(object)labelTmp == (Object)null)
			{
				return;
			}
			bool flag2 = UseChinese();
			string text3 = ((!flag) ? (flag2 ? value3.KeyCN : ((!string.IsNullOrEmpty(value3.DisplayEN)) ? value3.DisplayEN : value3.KeyEN)) : (flag2 ? value3.SectionCN : value3.SectionEN));
			if (!string.IsNullOrEmpty(text3))
			{
				try
				{
					((TMP_Text)labelTmp).text = text3;
				}
				catch
				{
				}
			}
			_liveLabels.Add(new LiveLabel
			{
				Tmp = new WeakReference<TextMeshProUGUI>(labelTmp),
				I18N = value3,
				IsSection = flag
			});
			if (!flag && value3.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 = value3
					});
					TrySetInputFieldValue(val, flag2 ? value3.ValueCN : value3.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 : ((!string.IsNullOrEmpty(liveLabel.I18N.DisplayEN)) ? liveLabel.I18N.DisplayEN : 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;
			}
		}
	}
	[HarmonyPatch(typeof(HurtCollider), "PlayerHurt")]
	internal static class HurtColliderPlayerHurtPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(HurtCollider __instance, PlayerAvatar _player)
		{
			PlayerTumble componentInParent = ((Component)__instance).GetComponentInParent<PlayerTumble>();
			if ((Object)(object)componentInParent != (Object)null && (Object)(object)componentInParent.playerAvatar != (Object)null && (Object)(object)componentInParent.playerAvatar.photonView != (Object)null && CarryFriendBehaviour.IsPassenger(componentInParent.playerAvatar.photonView.ViewID))
			{
				return false;
			}
			PlayerDeathHead componentInParent2 = ((Component)__instance).GetComponentInParent<PlayerDeathHead>();
			if ((Object)(object)componentInParent2 != (Object)null)
			{
				PhotonView component = ((Component)componentInParent2).GetComponent<PhotonView>();
				if ((Object)(object)component != (Object)null && CarryFriendBehaviour.IsPassenger(component.ViewID))
				{
					return false;
				}
			}
			return true;
		}
	}
	public static class CarryFriendPhysHelper
	{
		public static bool IsPassengerImpactDetector(PhysGrabObjectImpactDetector detector)
		{
			if ((Object)(object)detector == (Object)null)
			{
				return false;
			}
			int instanceID = ((Object)detector).GetInstanceID();
			if (!CarryFriendBehaviour.DetectorTumbleCache.TryGetValue(instanceID, out var value))
			{
				value = ((Component)detector).GetComponentInParent<PlayerTumble>();
				CarryFriendBehaviour.DetectorTumbleCache[instanceID] = value;
			}
			if ((Object)(object)value != (Object)null && (Object)(object)value.playerAvatar != (Object)null && (Object)(object)value.playerAvatar.photonView != (Object)null && CarryFriendBehaviour.IsPassenger(value.playerAvatar.photonView.ViewID))
			{
				return true;
			}
			if (!CarryFriendBehaviour.DetectorHeadCache.TryGetValue(instanceID, out var value2))
			{
				value2 = ((Component)detector).GetComponentInParent<PlayerDeathHead>();
				CarryFriendBehaviour.DetectorHeadCache[instanceID] = value2;
			}
			if ((Object)(object)value2 != (Object)null)
			{
				PhotonView component = ((Component)value2).GetComponent<PhotonView>();
				if ((Object)(object)component != (Object)null && CarryFriendBehaviour.IsPassenger(component.ViewID))
				{
					return true;
				}
			}
			PhysGrabObject componentInParent = ((Component)detector).GetComponentInParent<PhysGrabObject>();
			if ((Object)(object)componentInParent != (Object)null && (Object)(object)GameDirector.instance != (Object)null && GameDirector.instance.PlayerList != null)
			{
				foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
				{
					if ((Object)(object)player != (Object)null && (Object)(object)player.photonView != (Object)null && (Object)(object)player.physGrabber != (Object)null && CarryFriendBehaviour.IsPassenger(player.photonView.ViewID) && Plugin.Ref_PhysGrabberGrabbed != null && Plugin.Ref_PhysGrabberGrabbed.Invoke(player.physGrabber))
					{
						PhysGrabObject val = ((Plugin.Ref_PhysGrabberGrabbedPhysGrabObject != null) ? Plugin.Ref_PhysGrabberGrabbedPhysGrabObject.Invoke(player.physGrabber) : null);
						if ((Object)(object)val != (Object)null && (Object)(object)val == (Object)(object)componentInParent)
						{
							return true;
						}
					}
				}
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(PhysGrabObjectImpactDetector), "OnCollisionStay")]
	internal static class PhysGrabObjectImpactDetectorOnCollisionStayPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(PhysGrabObjectImpactDetector __instance, Collision collision)
		{
			if (CarryFriendPhysHelper.IsPassengerImpactDetector(__instance))
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(SemiFunc), "InputMovementX")]
	internal static class SemiFuncInputMovementXPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(ref float __result)
		{
			if ((Object)(object)CarryFriendBehaviour.Instance != (Object)null && CarryFriendBehaviour.Instance.IsPassengerLocal())
			{
				__result = 0f;
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(SemiFunc), "InputMovementY")]
	internal static class SemiFuncInputMovementYPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(ref float __result)
		{
			if ((Object)(object)CarryFriendBehaviour.Instance != (Object)null && CarryFriendBehaviour.Instance.IsPassengerLocal())
			{
				__result = 0f;
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(SemiFunc), "InputMovement")]
	internal static class SemiFuncInputMovementPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(ref Vector2 __result)
		{
			//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)
			if ((Object)(object)CarryFriendBehaviour.Instance != (Object)null && CarryFriendBehaviour.Instance.IsPassengerLocal())
			{
				__result = Vector2.zero;
				return false;
			}
			return true;
		}
	}
	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;
	}
	[HarmonyPatch(typeof(ItemUpgradePlayerTumbleWingsLogic), "LoopSound")]
	internal static class ItemUpgradePlayerTumbleWingsLogicLoopSoundPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(ItemUpgradePlayerTumbleWingsLogic __instance)
		{
			if ((Object)(object)CarryFriendBehaviour.Instance != (Object)null && (Object)(object)__instance.playerAvatar != (Object)null && (Object)(object)__instance.playerAvatar.photonView != (Object)null && CarryFriendBehaviour.IsPassenger(__instance.playerAvatar.photonView.ViewID))
			{
				__instance.soundWingsLoop.Stop();
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ItemUpgradePlayerTumbleWingsLogic), "Update")]
	internal static class ItemUpgradePlayerTumbleWingsLogicUpdatePatch
	{
		[HarmonyPostfix]
		private static void Postfix(ItemUpgradePlayerTumbleWingsLogic __instance)
		{
			if (!((Object)(object)CarryFriendBehaviour.Instance != (Object)null) || !((Object)(object)__instance.playerAvatar != (Object)null) || !((Object)(object)__instance.playerAvatar.photonView != (Object)null) || !((Object)(object)__instance.transformWings != (Object)null))
			{
				return;
			}
			if (CarryFriendBehaviour.IsPassenger(__instance.playerAvatar.photonView.ViewID))
			{
				if (((Component)__instance.transformWings).gameObject.activeSelf)
				{
					((Component)__instance.transformWings).gameObject.SetActive(false);
				}
			}
			else
			{
				if (((Component)__instance.transformWings).gameObject.activeSelf || !(Plugin.F_WingsCurrentState != null))
				{
					return;
				}
				try
				{
					object value = Plugin.F_WingsCurrentState.GetValue(__instance);
					if (value != null)
					{
						int num = (int)value;
						if (num == 0 || num == 2)
						{
							((Component)__instance.transformWings).gameObject.SetActive(true);
						}
					}
				}
				catch
				{
				}
			}
		}
	}
	[HarmonyPatch(typeof(PlayerAvatar), "ReviveRPC")]
	internal static class PlayerAvatarReviveRPCPatch
	{
		[HarmonyPostfix]
		private static void Postfix(PlayerAvatar __instance)
		{
			try
			{
				if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.photonView == (Object)null))
				{
					int viewID = __instance.photonView.ViewID;
					if (viewID > 0 && (Object)(object)CarryFriendBehaviour.Instance != (Object)null)
					{
						CarryFriendBehaviour.Instance.ClearPlayerCarryState(viewID);
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Error in PlayerAvatar.ReviveRPC Postfix: " + ex.Message));
			}
		}
	}
	public class CarryFriendBehaviour : MonoBehaviour
	{
		private struct PendingCollisionRestore
		{
			public int CarrierViewId;

			public int CarriedViewId;

			public float RestoreTime;

			public bool IsHead;
		}

		public static CarryFriendBehaviour Instance;

		private const byte CarryEventCode = 188;

		private static int _scanLayerMask = -1;

		private static readonly Quaternion CarriedPlayerRotOffset = Quaternion.Euler(15f, 180f, 0f);

		internal 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 float _configSyncTimer;

		private readonly List<int> _myCarriedTargets = new List<int>();

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

		private readonly List<List<int>> _listPool = new List<List<int>>();

		private int _listPoolIndex;

		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 _isRKeyHold;

		private bool _isHostModInstalled;

		private float _releaseTimer;

		private float _hostModMissingPromptTimer;

		private float _offlineCleanupTimer;

		private float _orphanCheckTimer;

		private float _collisionIgnoreRefreshTimer;

		private Rigidbody _myCarrierRb;

		private PhysGrabObject _myCarriedHeadPgo;

		private PhotonView _myCarriedHeadPv;

		private PlayerTumble _localTumble;

		private PhysGrabObject _localTumblePgo;

		private float _passengerStateTick;

		private float _lateUpdateTick;

		private float _lateUpdateOverrideTick;

		internal static readonly Dictionary<int, Collider> CarriedHurtColliderCache = new Dictionary<int, Collider>();

		private static readonly List<PendingCollisionRestore> PendingRestores = new List<PendingCollisionRestore>();

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

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

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

		internal static readonly Dictionary<int, PlayerTumble> DetectorTumbleCache = new Dictionary<int, PlayerTumble>();

		internal static readonly Dictionary<int, PlayerDeathHead> DetectorHeadCache = new Dictionary<int, PlayerDeathHead>();

		private float _physThrottle;

		private const float PhysThrottleInterval = 0.1f;

		private float _deadCheckTimer;

		private bool _cachedCarrierDead;

		private bool _cachedSelfDead;

		private bool _cachedSelfTumbling;

		private bool _handshakeSent;

		private static PhysicMaterial _slipperyMat = null;

		private static Texture2D _bgTex1x1 = null;

		private static Texture2D _fillTex1x1 = null;

		private static Texture2D _fillReleaseTex1x1 = null;

		private static Texture2D _warnBgTex1x1 = null;

		private static GUIStyle _boxBgStyle = null;

		private static GUIStyle _boxFillStyle = null;

		private static GUIStyle _boxFillReleaseStyle = null;

		private static GUIStyle _boxWarnBgStyle = null;

		private static GUIStyle _labelStyle = null;

		private static GUIStyle _shadowStyle = null;

		private static GUIStyle _warnLabelStyle = null;

		private static GUIStyle _warnShadowStyle = null;

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

		private static readonly Dictionary<int, Collider[]> _colliderCache = new Dictionary<int, Collider[]>();

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

		private static int ScanLayerMask
		{
			get
			{
				if (_scanLayerMask == -1)
				{
					_scanLayerMask = LayerMask.GetMask(new string[3] { "Default", "Player", "PhysGrabObject" });
				}
				return _scanLayerMask;
			}
		}

		private static PhysicMaterial SlipperyMat
		{
			get
			{
				if (!((Object)(object)_slipperyMat != (Object)null))
				{
					return _slipperyMat = SemiFunc.PhysicMaterialSlippery();
				}
				return _slipperyMat;
			}
		}

		private List<int> GetPoolList()
		{
			if (_listPoolIndex >= _listPool.Count)
			{
				_listPool.Add(new List<int>());
			}
			List<int> list = _listPool[_listPoolIndex++];
			list.Clear();
			return list;
		}

		public List<int> GetMyCarriedTargets()
		{
			_myCarriedTargets.Clear();
			PlayerAvatar instance = PlayerAvatar.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.photonView == (Object)null)
			{
				return _myCarriedTargets;
			}
			int viewID = instance.photonView.ViewID;
			foreach (KeyValuePair<int, int> activeCarry in ActiveCarries)
			{
				if (activeCarry.Value == viewID)
				{
					_myCarriedTargets.Add(activeCarry.Key);
				}
			}
			if (_myCarriedTargets.Count > 1)
			{
				for (int i = 0; i < _myCarriedTargets.Count - 1; i++)
				{
					for (int j = 0; j < _myCarriedTargets.Count - i - 1; j++)
					{
						float value;
						float num = (CarryStartTimes.TryGetValue(_myCarriedTargets[j], out value) ? value : 0f);
						float value2;
						float num2 = (CarryStartTimes.TryGetValue(_myCarriedTargets[j + 1], out value2) ? value2 : 0f);
						if (num > num2)
						{
							int value3 = _myCarriedTargets[j];
							_myCarriedTargets[j] = _myCarriedTargets[j + 1];
							_myCarriedTargets[j + 1] = value3;
						}
					}
				}
			}
			return _myCarriedTargets;
		}

		private void Start()
		{
			Instance = this;
			_isHostModInstalled = PhotonNetwork.IsMasterClient;
			_releaseTimer = 0f;
			_hostModMissingPromptTimer = 0f;
			_offlineCleanupTimer = 0f;
			try
			{
				PhotonNetwork.NetworkingClient.EventReceived += OnEvent;
				if (!PhotonNetwork.IsMasterClient && SemiFunc.IsMultiplayer())
				{
					SendCarryEventToHost(PhotonNetwork.LocalPlayer.ActorNumber, 0, 0, 3);
				}
				SceneManager.sceneLoaded += OnSceneLoaded;
			}
			catch
			{
			}
		}

		private void OnDestroy()
		{
			try
			{
				PhotonNetwork.NetworkingClient.EventReceived -= OnEvent;
				SceneManager.sceneLoaded -= OnSceneLoaded;
			}
			catch
			{
			}
			ResetState();
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			ResetState();
		}

		public static bool IsPassenger(int viewId)
		{
			if ((Object)(object)Instance == (Object)null)
			{
				return false;
			}
			return Instance.ActiveCarries.ContainsKey(viewId);
		}

		private void CleanupOfflineCarries()
		{
			if (_isCarrying)
			{
				List<int> myCarriedTargets = GetMyCarriedTargets();
				if (myCarriedTargets.Count == 0)
				{
					_isCarrying = false;
					_myCarriedPlayer = null;
					_myCarriedHead = null;
					_releaseTimer = 0f;
				}
				else
				{
					_myCarriedPlayer = null;
					_myCarriedHead = null;
					foreach (int item in myCarriedTargets)
					{
						PlayerAvatar val = FindPlayerAvatarByViewID(item);
						if ((Object)(object)val != (Object)null)
						{
							_myCarriedPlayer = val;
							break;
						}
						PlayerDeathHead val2 = FindPlayerDeathHeadByViewID(item);
						if ((Object)(object)val2 != (Object)null)
						{
							_myCarriedHead = val2;
							break;
						}
					}
					if ((Object)(object)_myCarriedPlayer == (Object)null && (Object)(object)_myCarriedHead == (Object)null)
					{
						_isCarrying = false;
						_releaseTimer = 0f;
					}
				}
			}
			if (_isBeingCarried && (Object)(object)_myCarrier == (Object)null)
			{
				_isBeingCarried = false;
				_myCarrier = null;
				PlayerAvatar instance = PlayerAvatar.instance;
				if ((Object)(object)instance != (Object)null)
				{
					PlayerTumble playerTumble = GetPlayerTumble(instance);
					if ((Object)(object)playerTumble != (Object)null)
					{
						playerTumble.TumbleRequest(false, false);
					}
					instance.TumbleStop();
					if ((Object)(object)PlayerController.instance != (Object)null)
					{
						((Behaviour)PlayerController.instance).enabled = true;
					}
					instance.UpdateState(false, false, false, false, false);
				}
			}
			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 val3 = FindPlayerAvatarByViewID(value);
				if ((Object)(object)val3 == (Object)null || GetPlayerIsDisabled(val3))
				{
					list.Add(key);
					continue;
				}
				PlayerAvatar val4 = FindPlayerAvatarByViewID(key);
				PlayerDeathHead val5 = FindDeathHeadByViewID(key);
				if ((Object)(object)val4 == (Object)null && (Object)(object)val5 == (Object)null)
				{
					list.Add(key);
					continue;
				}
				if ((Object)(object)val4 != (Object)null && ((GetPlayerIsDisabled(val4) && !GetPlayerIsTumbling(val4)) || GetPlayerDeadSet(val4)))
				{
					list.Add(key);
					continue;
				}
				if ((Object)(object)val5 != (Object)null && (Object)(object)val5.playerAvatar != (Object)null && !GetPlayerDeadSet(val5.playerAvatar))
				{
					list.Add(key);
					continue;
				}
				int num = (((Object)(object)PlayerAvatar.instance != (Object)null && (Object)(object)PlayerAvatar.instance.photonView != (Object)null) ? PlayerAvatar.instance.photonView.ViewID : 0);
				if (num != 0 && key == num && !_isBeingCarried)
				{
					list.Add(key);
				}
			}
			if (list.Count <= 0)
			{
				return;
			}
			PlayerAvatar instance2 = PlayerAvatar.instance;
			int num2 = (((Object)(object)instance2 != (Object)null && (Object)(object)instance2.photonView != (Object)null) ? instance2.photonView.ViewID : 0);
			foreach (int item2 in list)
			{
				ActiveCarries.Remove(item2);
				CarryStartTimes.Remove(item2);
				if (CarryTriggerColliders.TryGetValue(item2, out var value2))
				{
					if (value2 != null)
					{
						foreach (Collider item3 in value2)
						{
							if ((Object)(object)item3 != (Object)null)
							{
								item3.isTrigger = false;
							}
						}
					}
					CarryTriggerColliders.Remove(item2);
				}
				if (!((Object)(object)instance2 != (Object)null))
				{
					continue;
				}
				if (item2 == num2)
				{
					if (_isBeingCarried)
					{
						_isBeingCarried = false;
						_myCarrier = null;
						PlayerTumble playerTumble2 = GetPlayerTumble(instance2);
						if ((Object)(object)playerTumble2 != (Object)null)
						{
							playerTumble2.TumbleRequest(false, false);
						}
						instance2.TumbleStop();
						if ((Object)(object)PlayerController.instance != (Object)null)
						{
							((Behaviour)PlayerController.instance).enabled = true;
						}
						instance2.UpdateState(false, false, false, false, false);
					}
				}
				else if ((Object)(object)_myCarriedPlayer != (Object)null && (Object)(object)_myCarriedPlayer.photonView != (Object)null && _myCarriedPlayer.photonView.ViewID == item2)
				{
					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 == item2 && _isCarrying)
				{
					_isCarrying = false;
					_myCarriedPlayer = null;
					_myCarriedHead = null;
					_releaseTimer = 0f;
				}
			}
		}

		private void Update()
		{
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.IsStaticModEnabled())
			{
				return;
			}
			if (!_handshakeSent && SemiFunc.IsMultiplayer() && PhotonNetwork.InRoom && PhotonNetwork.LocalPlayer != null)
			{
				_handshakeSent = true;
				if (!PhotonNetwork.IsMasterClient)
				{
					SendCarryEventToHost(PhotonNetwork.LocalPlayer.ActorNumber, 0, 0, 3);
				}
				else
				{
					_isHostModInstalled = true;
				}
			}
			if (PhotonNetwork.IsMasterClient)
			{
				Plugin.HostMaxCarryCount = Plugin.MaxCarryCount();
				_configSyncTimer -= Time.deltaTime;
				if (_configSyncTimer <= 0f)
				{
					_configSyncTimer = 5f;
					object[] array = new object[4]
					{
						Plugin.HostMaxCarryCount,
						Plugin.RequiredHoldTime(),
						Plugin.CarryHeightOffset(),
						7
					};
					RaiseEventOptions val = new RaiseEventOptions
					{
						Receivers = (ReceiverGroup)1
					};
					try
					{
						PhotonNetwork.RaiseEvent((byte)188, (object)array, val, SendOptions.SendReliable);
					}
					catch
					{
					}
				}
			}
			for (int num = PendingRestores.Count - 1; num >= 0; num--)
			{
				PendingCollisionRestore pendingCollisionRestore = PendingRestores[num];
				if (Time.time >= pendingCollisionRestore.RestoreTime)
				{
					PendingRestores.RemoveAt(num);
					try
					{
						PlayerAvatar val2 = FindPlayerAvatarByViewID(pendingCollisionRestore.CarrierViewId);
						if (pendingCollisionRestore.IsHead)
						{
							PlayerDeathHead val3 = FindPlayerDeathHeadByViewID(pendingCollisionRestore.CarriedViewId);
							if ((Object)(object)val2 != (Object)null && (Object)(object)val3 != (Object)null)
							{
								SetCollisionIgnoreHead(val2, val3, ignore: false);
							}
						}
						else
						{
							PlayerAvatar val4 = FindPlayerAvatarByViewID(pendingCollisionRestore.CarriedViewId);
							if ((Object)(object)val2 != (Object)null && (Object)(object)val4 != (Object)null)
							{
								SetCollisionIgnore(val2, val4, ignore: false);
							}
						}
					}
					catch
					{
					}
				}
			}
			_offlineCleanupTimer += Time.deltaTime;
			if (_offlineCleanupTimer >= 3f)
			{
				_offlineCleanupTimer = 0f;
				CleanupOfflineCarries();
			}
			_orphanCheckTimer += Time.deltaTime;
			if (_orphanCheckTimer >= 1f)
			{
				_orphanCheckTimer = 0f;
				PlayerAvatar instance = PlayerAvatar.instance;
				if ((Object)(object)instance != (Object)null)
				{
					if (_isBeingCarried && ((Object)(object)_myCarrier == (Object)null || (Object)(object)((Component)_myCarrier).gameObject == (Object)null || !((Component)_myCarrier).gameObject.activeInHierarchy || ((Object)(object)_myCarrier.photonView != (Object)null && _myCarrier.photonView.ViewID <= 0)))
					{
						_isBeingCarried = false;
						_myCarrier = null;
						PlayerTumble playerTumble = GetPlayerTumble(instance);
						if ((Object)(object)playerTumble != (Object)null)
						{
							playerTumble.TumbleRequest(false, false);
						}
						instance.TumbleStop();
						if ((Object)(object)PlayerController.instance != (Object)null)
						{
							((Behaviour)PlayerController.instance).enabled = true;
						}
						instance.UpdateState(false, false, false, false, false);
					}
					if (_isCarrying && (Object)(object)_myCarriedPlayer != (Object)null && ((Object)(object)((Component)_myCarriedPlayer).gameObject == (Object)null || !((Component)_myCarriedPlayer).gameObject.activeInHierarchy || ((Object)(object)_myCarriedPlayer.photonView != (Object)null && _myCarriedPlayer.photonView.ViewID <= 0)))
					{
						_isCarrying = false;
						_myCarriedPlayer = null;
						_myCarriedHead = null;
						_releaseTimer = 0f;
						try
						{
							if ((Object)(object)instance.healthGrab != (Object)null)
							{
								StaticGrabObject val5 = ((Plugin.Ref_HealthGrabStaticGrabObject != null) ? Plugin.Ref_HealthGrabStaticGrabObject.Invoke(instance.healthGrab) : null);
								if ((Object)(object)val5 != (Object)null)
								{
									((Behaviour)val5).enabled = false;
								}
							}
						}
						catch
						{
						}
					}
				}
			}
			if (_hostModMissingPromptTimer > 0f)
			{
				_hostModMissingPromptTimer -= Time.deltaTime;
			}
			UpdateCarryLogic();
		}

		private void FixedUpdate()
		{
			//IL_06f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0701: Unknown result type (might be due to invalid IL or missing references)
			//IL_0708: Unknown result type (might be due to invalid IL or missing references)
			//IL_070d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0719: Unknown result type (might be due to invalid IL or missing references)
			//IL_0720: Unknown result type (might be due to invalid IL or missing references)
			//IL_0725: Unknown result type (might be due to invalid IL or missing references)
			//IL_0731: Unknown result type (might be due to invalid IL or missing references)
			//IL_0738: Unknown result type (might be due to invalid IL or missing references)
			//IL_073d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0749: Unknown result type (might be due to invalid IL or missing references)
			//IL_074e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0754: Unknown result type (might be due to invalid IL or missing references)
			//IL_0759: Unknown result type (might be due to invalid IL or missing references)
			//IL_075e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0762: Unknown result type (might be due to invalid IL or missing references)
			//IL_076b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0770: Unknown result type (might be due to invalid IL or missing references)
			//IL_0775: Unknown result type (might be due to invalid IL or missing references)
			//IL_077a: Unknown result type (might be due to invalid IL or missing references)
			//IL_077f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0786: Unknown result type (might be due to invalid IL or missing references)
			//IL_0790: Unknown result type (might be due to invalid IL or missing references)
			//IL_0795: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_07b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_07bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_037b: Unknown result type (might be due to invalid IL or missing references)
			//IL_038c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03db: Unknown result type (might be due to invalid IL or missing references)
			//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04af: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_041f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0424: Unknown result type (might be due to invalid IL or missing references)
			//IL_0429: Unknown result type (might be due to invalid IL or missing references)
			//IL_042d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0434: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_043d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0442: Unknown result type (might be due to invalid IL or missing references)
			//IL_0447: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0453: Unknown result type (might be due to invalid IL or missing references)
			//IL_045d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0462: Unknown result type (might be due to invalid IL or missing references)
			//IL_0470: Unknown result type (might be due to invalid IL or missing references)
			//IL_0480: Unknown result type (might be due to invalid IL or missing references)
			//IL_0489: Unknown result type (might be due to invalid IL or missing references)
			//IL_048e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0492: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.IsStaticModEnabled())
			{
				return;
			}
			_physThrottle += Time.fixedDeltaTime;
			bool flag = _physThrottle >= 0.1f;
			if (flag)
			{
				_physThrottle = 0f;
			}
			if (_isBeingCarried && (Object)(object)_myCarrier != (Object)null)
			{
				PlayerAvatar instance = PlayerAvatar.instance;
				if ((Object)(object)instance != (Object)null)
				{
					if ((Object)(object)_localTumble == (Object)null)
					{
						_localTumble = GetPlayerTumble(instance);
					}
					PlayerTumble localTumble = _localTumble;
					if ((Object)(object)localTumble != (Object)null)
					{
						if (flag)
						{
							SetPassengerTumbleOverrideTime(localTumble, 0.5f);
						}
						if ((Object)(object)_localTumblePgo == (Object)null)
						{
							_localTumblePgo = GetTumblePhysGrabObject(localTumble);
						}
						PhysGrabObject localTumblePgo = _localTumblePgo;
						int num = (((Object)(object)instance.photonView != (Object)null) ? instance.photonView.ViewID : 0);
						Rigidbody value;
						Rigidbody val = ((Plugin.CarriedTumbleRbCache.TryGetValue(num, out value) && (Object)(object)value != (Object)null) ? value : GetTumbleRb(localTumble));
						Rigidbody val2 = (((Object)(object)_myCarrierRb != (Object)null && (Object)(object)((Component)_myCarrierRb).gameObject != (Object)null) ? _myCarrierRb : (_myCarrierRb = ((Component)_myCarrier).GetComponent<Rigidbody>()));
						if ((Object)(object)localTumblePgo != (Object)null && (Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null)
						{
							if (flag)
							{
								localTumblePgo.OverrideMaterial(SlipperyMat, 0.1f);
								localTumblePgo.OverrideZeroGravity(0.2f);
								DisablePhysGrabObjectImpact(localTumblePgo, 0.2f);
								localTumble.OverrideEnemyHurt(0.1f);
								if ((Object)(object)instance.physGrabber != (Object)null)
								{
									localTumble.OverrideTumbleUIDisable(0.2f);
								}
								localTumblePgo.OverrideMass(0.05f, 0.1f);
							}
							float num2 = 0f;
							float num3 = 0.45f;
							float num4 = Plugin.CarryHeightOffset();
							int num5 = 1;
							int num6 = 0;
							int num7 = (((Object)(object)_myCarrier.photonView != (Object)null) ? _myCarrier.photonView.ViewID : 0);
							if (num7 != 0 && num != 0)
							{
								List<int> list = new List<int>();
								foreach (KeyValuePair<int, int> activeCarry in ActiveCarries)
								{
									if (activeCarry.Value == num7)
									{
										list.Add(activeCarry.Key);
									}
								}
								list.Sort();
								num5 = list.Count;
								num6 = list.IndexOf(num);
								if (num6 < 0)
								{
									num6 = 0;
								}
								switch (num5)
								{
								case 1:
									num2 = 0f;
									num3 = 0.45f;
									num4 = Plugin.CarryHeightOffset();
									break;
								case 2:
									num2 = ((num6 == 0) ? (-0.38f) : 0.38f);
									num3 = 0.38f;
									num4 = Plugin.CarryHeightOffset();
									break;
								case 3:
									switch (num6)
									{
									case 0:
										num2 = -0.38f;
										num3 = 0.38f;
										num4 = Plugin.CarryHeightOffset();
										break;
									case 1:
										num2 = 0f;
										num3 = 0.52f;
										num4 = Plugin.CarryHeightOffset();
										break;
									default:
										num2 = 0.38f;
										num3 = 0.38f;
										num4 = Plugin.CarryHeightOffset();
										break;
									}
									break;
								}
							}
							float num8 = 180f;
							switch (num5)
							{
							case 2:
								num8 = ((num6 == 0) ? 215f : 145f);
								break;
							case 3:
								num8 = num6 switch
								{
									0 => 215f, 
									1 => 180f, 
									_ => 145f, 
								};
								break;
							}
							Quaternion val3 = ((Component)_myCarrier).transform.rotation * Quaternion.Euler(15f, num8, 0f);
							Vector3 val4 = ((Component)_myCarrier).transform.position - ((Component)_myCarrier).transform.forward * num3 + ((Component)_myCarrier).transform.up * num4 + ((Component)_myCarrier).transform.right * num2;
							if (GetPlayerIsTumbling(instance))
							{
								if (val.isKinematic)
								{
									val.isKinematic = false;
								}
								Vector3 pointVelocity = val2.GetPointVelocity(val.position);
								val.velocity = pointVelocity;
								Vector3 val5 = val4 - val.position;
								val.velocity += val5 / Time.fixedDeltaTime * 0.08f;
								val.angularVelocity = val2.angularVelocity;
								Vector3 val6 = SemiFunc.PhysFollowRotation(((Component)localTumble).transform, val3, val, 0.5f);
								val.AddTorque(val6, (ForceMode)2);
							}
							else
							{
								if (!val.isKinematic)
								{
									val.isKinematic = true;
								}
								val.position = val4;
								val.rotation = val3;
								((Component)instance).transform.position = val4;
								((Component)instance).transform.rotation = val3;
							}
						}
					}
				}
			}
			if (_isCarrying)
			{
				PlayerAvatar instance2 = PlayerAvatar.instance;
				if ((Object)(object)instance2 != (Object)null)
				{
					List<int> myCarriedTargets = GetMyCarriedTargets();
					int count = myCarriedTargets.Count;
					for (int i = 0; i < count; i++)
					{
						int num9 = myCarriedTargets[i];
						PlayerDeathHead value2 = null;
						if (!_lateHeadCache.TryGetValue(num9, out value2) || (Object)(object)value2 == (Object)null)
						{
							value2 = FindPlayerDeathHeadByViewID(num9);
							if ((Object)(object)value2 != (Object)null)
							{
								_lateHeadCache[num9] = value2;
							}
						}
						if (!((Object)(object)value2 != (Object)null))
						{
							continue;
						}
						PhysGrabObject component = ((Component)value2).GetComponent<PhysGrabObject>();
						Rigidbody val7 = (((Object)(object)component != (Object)null) ? component.rb : null);
						Rigidbody val8 = (((Object)(object)PlayerController.instance != (Object)null && (Object)(object)PlayerController.instance.rb != (Object)null) ? PlayerController.instance.rb : ((Component)instance2).GetComponent<Rigidbody>());
						if (!((Object)(object)component != (Object)null) || !((Object)(object)val7 != (Object)null) || !((Object)(object)val8 != (Object)null))
						{
							continue;
						}
						PhotonView component2 = ((Component)value2).GetComponent<PhotonView>();
						if ((Object)(object)component2 != (Object)null && !component2.IsMine)
						{
							component2.RequestOwnership();
						}
						if (flag)
						{
							component.OverrideMaterial(SlipperyMat, 0.1f);
							component.OverrideZeroGravity(0.2f);
							DisablePhysGrabObjectImpact(component, 0.2f);
							component.OverrideMass(0.05f, 0.1f);
						}
						float num10 = 0f;
						float num11 = 0.5f;
						float num12 = 0.4f;
						switch (count)
						{
						case 1:
							num10 = 0f;
							num11 = 0.5f;
							num12 = 0.4f;
							break;
						case 2:
							num10 = ((i == 0) ? (-0.55f) : 0.55f);
							num11 = 0.6f;
							num12 = 0.4f;
							break;
						case 3:
							switch (i)
							{
							case 0:
								num10 = -0.75f;
								num11 = 0.6f;
								num12 = 0.4f;
								break;
							case 1:
								num10 = 0f;
								num11 = 0.75f;
								num12 = 0.55f;
								break;
							default:
								num10 = 0.75f;
								num11 = 0.6f;
								num12 = 0.4f;
								break;
							}
							break;
						}
						Vector3 val9 = ((Component)instance2).transform.position - ((Component)instance2).transform.forward * num11 + ((Component)instance2).transform.up * num12 + ((Component)instance2).transform.right * num10;
						Quaternion rotation = ((Component)instance2).transform.rotation;
						Vector3 pointVelocity2 = val8.GetPointVelocity(val7.position);
						val7.velocity = pointVelocity2;
						Vector3 val10 = val9 - val7.position;
						val7.velocity += val10 / Time.fixedDeltaTime * 0.08f;
						val7.angularVelocity = val8.angularVelocity;
						Vector3 val11 = SemiFunc.PhysFollowRotation(((Component)value2).transform, rotation, val7, 0.5f);
						val7.AddTorque(val11, (ForceMode)2);
					}
				}
			}
			ExecuteDistributedHeadCarryDummy();
		}

		private void LateUpdate()
		{
			//IL_076d: Unknown result type (might be due to invalid IL or missing references)
			//IL_076f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0779: Unknown result type (might be due to invalid IL or missing references)
			//IL_077e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0783: Unknown result type (might be due to invalid IL or missing references)
			//IL_078f: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0395: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0401: Unknown result type (might be due to invalid IL or missing references)
			//IL_0406: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_041d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0437: Unknown result type (might be due to invalid IL or missing references)
			//IL_0439: Unknown result type (might be due to invalid IL or missing references)
			//IL_0451: Unknown result type (might be due to invalid IL or missing references)
			//IL_0453: Unknown result type (might be due to invalid IL or missing references)
			//IL_046b: Unknown result type (might be due to invalid IL or missing references)
			//IL_046d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0485: Unknown result type (might be due to invalid IL or missing references)
			//IL_0487: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0501: Unknown result type (might be due to invalid IL or missing references)
			//IL_0585: Unknown result type (might be due to invalid IL or missing references)
			//IL_0587: Unknown result type (might be due to invalid IL or missing references)
			//IL_0549: Unknown result type (might be due to invalid IL or missing references)
			//IL_0556: Unknown result type (might be due to invalid IL or missing references)
			//IL_059f: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a1: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.IsStaticModEnabled())
			{
				return;
			}
			_lateUpdateTick -= Time.deltaTime;
			bool flag = _lateUpdateTick <= 0f;
			if (flag)
			{
				_lateUpdateTick = 1f;
			}
			_lateUpdateOverrideTick -= Time.deltaTime;
			bool flag2 = _lateUpdateOverrideTick <= 0f;
			if (flag2)
			{
				_lateUpdateOverrideTick = 0.1f;
			}
			_listPoolIndex = 0;
			_carrierGroups.Clear();
			foreach (KeyValuePair<int, int> activeCarry in ActiveCarries)
			{
				int key = activeCarry.Key;
				int value = activeCarry.Value;
				if (!_carrierGroups.TryGetValue(value, out var value2))
				{
					value2 = GetPoolList();
					_carrierGroups[value] = value2;
				}
				value2.Add(key);
			}
			foreach (KeyValuePair<int, List<int>> carrierGroup in _carrierGroups)
			{
				List<int> value3 = carrierGroup.Value;
				if (value3.Count > 1)
				{
					for (int i = 0; i < value3.Count - 1; i++)
					{
						for (int j = 0; j < value3.Count - i - 1; j++)
						{
							float value4;
							float num = (CarryStartTimes.TryGetValue(value3[j], out value4) ? value4 : 0f);
							float value5;
							float num2 = (CarryStartTimes.TryGetValue(value3[j + 1], out value5) ? value5 : 0f);
							if (num > num2)
							{
								int value6 = value3[j];
								value3[j] = value3[j + 1];
								value3[j + 1] = value6;
							}
						}
					}
				}
				int key2 = carrierGroup.Key;
				if (!_lateAvatarCache.TryGetValue(key2, out var value7) || (Object)(object)value7 == (Object)null)
				{
					value7 = FindPlayerAvatarByViewID(key2);
					if ((Object)(object)value7 != (Object)null)
					{
						_lateAvatarCache[key2] = value7;
					}
				}
				if ((Object)(object)value7 == (Object)null)
				{
					continue;
				}
				int count = value3.Count;
				for (int k = 0; k < count; k++)
				{
					int num3 = value3[k];
					if (!ActiveCarries.ContainsKey(num3))
					{
						continue;
					}
					if (!_lateAvatarCache.TryGetValue(num3, out var value8) || (Object)(object)value8 == (Object)null)
					{
						value8 = FindPlayerAvatarByViewID(num3);
						if ((Object)(object)value8 != (Object)null)
						{
							_lateAvatarCache[num3] = value8;
						}
					}
					if (!((Object)(object)value8 != (Object)null))
					{
						continue;
					}
					float num4 = 0f;
					float num5 = 0.45f;
					float num6 = Plugin.CarryHeightOffset();
					switch (count)
					{
					case 1:
						num4 = 0f;
						num5 = 0.45f;
						num6 = Plugin.CarryHeightOffset();
						break;
					case 2:
						num4 = ((k == 0) ? (-0.38f) : 0.38f);
						num5 = 0.38f;
						num6 = Plugin.CarryHeightOffset();
						break;
					case 3:
						switch (k)
						{
						case 0:
							num4 = -0.38f;
							num5 = 0.38f;
							num6 = Plugin.CarryHeightOffset();
							break;
						case 1:
							num4 = 0f;
							num5 = 0.52f;
							num6 = Plugin.CarryHeightOffset();
							break;
						default:
							num4 = 0.38f;
							num5 = 0.38f;
							num6 = Plugin.CarryHeightOffset();
							break;
						}
						break;
					}
					float num7 = 180f;
					switch (count)
					{
					case 2:
						num7 = ((k == 0) ? 215f : 145f);
						break;
					case 3:
						num7 = k switch
						{
							0 => 215f, 
							1 => 180f, 
							_ => 145f, 
						};
						break;
					}
					Quaternion val = ((Component)value7).transform.rotation * Quaternion.Euler(15f, num7, 0f);
					Vector3 val2 = ((Component)value7).transform.position - ((Component)value7).transform.forward * num5 + ((Component)value7).transform.up * num6 + ((Component)value7).transform.right * num4;
					((Component)value8).transform.position = val2;
					((Component)value8).transform.rotation = val;
					if (Plugin.Ref_ClientPosition != null)
					{
						Plugin.Ref_ClientPosition.Invoke(value8) = val2;
					}
					if (Plugin.Ref_ClientPositionCurrent != null)
					{
						Plugin.Ref_ClientPositionCurrent.Invoke(value8) = val2;
					}
					if (Plugin.Ref_ClientRotation != null)
					{
						Plugin.Ref_ClientRotation.Invoke(value8) = val;
					}
					if (Plugin.Ref_ClientRotationCurrent != null)
					{
						Plugin.Ref_ClientRotationCurrent.Invoke(value8) = val;
					}
					EnsurePassengerCollidersAreTriggers(value8);
					if (!Plugin.CarriedAvatarRbCache.TryGetValue(num3, out var value9) || (Object)(object)value9 == (Object)null)
					{
						value9 = ((Component)value8).GetComponent<Rigidbody>();
						if ((Object)(object)value9 != (Object)null)
						{
							Plugin.CarriedAvatarRbCache[num3] = value9;
						}
					}
					if ((Object)(object)value9 != (Object)null)
					{
						bool isKinematic = value9.isKinematic;
						if (!value9.isKinematic)
						{
							value9.isKinematic = true;
						}
						value9.position = val2;
						value9.rotation = val;
						if (Time.frameCount % 120 == 0)
						{
							Plugin.Log.LogInfo((object)$"[CarryFriend LOG] LateUpdate passenger {num3}: isKinematic={value9.isKinematic} (was {isKinematic}), position={value9.position}, targetPos={val2}");
						}
					}
					if (!GetPlayerIsLocal(value8))
					{
						try
						{
							if (Plugin.Ref_ClientPosition != null)
							{
								Plugin.Ref_ClientPosition.Invoke(value8) = val2;
							}
							if (Plugin.Ref_ClientPositionCurrent != null)
							{
								Plugin.Ref_ClientPositionCurrent.Invoke(value8) = val2;
							}
						}
						catch
						{
						}
					}
					if (!Plugin.CarriedTumbleCache.TryGetValue(num3, out var value10) || (Object)(object)value10 == (Object)null)
					{
						value10 = GetPlayerTumble(value8);
						if ((Object)(object)value10 != (Object)null)
						{
							Plugin.CarriedTumbleCache[num3] = value10;
						}
					}
					if ((Object)(object)value10 != (Object)null)
					{
						if (!GetPlayerIsTumbling(value8) && (!Plugin.TumbleEnforceTimers.TryGetValue(num3, out var value11) || Time.time - value11 >= 0.8f))
						{
							Plugin.TumbleEnforceTimers[num3] = Time.time;
							value10.TumbleRequest(true, false);
							Plugin.Log.LogInfo((object)$"[CarryFriend LOG] Enforced tumble state on passenger {num3} (vanilla player stood up)");
						}
						if (flag2)
						{
							SetPassengerTumbleOverrideTime(value10, 0.5f);
						}
						value10.OverrideDisableTumbleMoveSound(0.2f);
						if (!Plugin.CarriedTumbleRbCache.TryGetValue(num3, out var value12) || (Object)(object)value12 == (Object)null)
						{
							value12 = GetTumbleRb(value10);
							if ((Object)(object)value12 != (Object)null)
							{
								Plugin.CarriedTumbleRbCache[num3] = value12;
							}
						}
						if ((Object)(object)value12 != (Object)null)
						{
							if (!value12.isKinematic)
							{
								value12.isKinematic = true;
							}
							value12.position = val2;
							value12.rotation = val;
						}
						if (flag && (Object)(object)value10.hurtCollider != (Object)null)
						{
							((Component)value10.hurtCollider).gameObject.SetActive(false);
							Collider value13;
							Collider val3 = ((CarriedHurtColliderCache.TryGetValue(num3, out value13) && (Object)(object)value13 != (Object)null) ? value13 : ((Component)value10.hurtCollider).GetComponent<Collider>());
							if ((Object)(object)val3 != (Object)null)
							{
								CarriedHurtColliderCache[num3] = val3;
								if (val3.enabled)
								{
									val3.enabled = false;
								}
							}
						}
					}
					if (GetPlayerIsLocal(value8) && (Object)(object)PlayerController.instance != (Object)null)
					{
						try
						{
							Vector3 position = val2 + Vector3.down * 0.3f;
							((Component)PlayerController.instance).transform.position = position;
							((Component)PlayerController.instance).transform.rotation = val;
							Rigidbody rb = PlayerController.instance.rb;
							if ((Object)(object)rb != (Object)null)
							{
								if (!rb.isKinematic)
								{
									rb.isKinematic = true;
								}
								rb.position = position;
								rb.rotation = val;
							}
							if ((Object)(object)PlayerController.instance.CollisionController != (Object)null)
							{
								PlayerController.instance.CollisionController.OverrideDisableFallLoop(0.2f);
							}
						}
						catch
						{
						}
					}
					if (!flag)
					{
						continue;
					}
					try
					{
						if (!CarryTriggerColliders.TryGetValue(num3, out var value14))
						{
							value14 = new List<Collider>();
							CarryTriggerColliders[num3] = value14;
						}
						Collider[] componentsInChildren = ((Component)value8).GetComponentsInChildren<Collider>(true);
						foreach (Collider val4 in componentsInChildren)
						{
							if ((Object)(object)val4 != (Object)null && val4.enabled && !val4.isTrigger)
							{
								val4.isTrigger = true;
								if (!value14.Contains(val4))
								{
									value14.Add(val4);
								}
							}
						}
					}
					catch
					{
					}
				}
			}
		}

		private void EnsurePassengerCollidersAreTriggers(PlayerAvatar carriedPlayer)
		{
			if ((Object)(object)carriedPlayer == (Object)null || (Object)(object)carriedPlayer.photonView == (Object)null)
			{
				return;
			}
			int viewID = carriedPlayer.photonView.ViewID;
			try
			{
				if (!CarryTriggerColliders.TryGetValue(viewID, out var value))
				{
					value = new List<Collider>();
					CarryTriggerColliders[viewID] = value;
				}
				Collider[] componentsInChildren = ((Component)carriedPlayer).GetComponentsInChildren<Collider>(true);
				foreach (Collider val in componentsInChildren)
				{
					if ((Object)(object)val != (Object)null && val.enabled && !val.isTrigger)
					{
						val.isTrigger = true;
						if (!value.Contains(val))
						{
							value.Add(val);
						}
					}
				}
				PlayerTumble playerTumble = GetPlayerTumble(carriedPlayer);
				if (!((Object)(object)playerTumble != (Object)null))
				{
					return;
				}
				componentsInChildren = ((Component)playerTumble).GetComponentsInChildren<Collider>(true);
				foreach (Collider val2 in componentsInChildren)
				{
					if ((Object)(object)val2 != (Object)null && val2.enabled && !val2.isTrigger)
					{
						val2.isTrigger = true;
						if (!value.Contains(val2))
						{
							value.Add(val2);
						}
					}
				}
				if (playerTumble.colliders == null)
				{
					return;
				}
				componentsInChildren = playerTumble.colliders;
				foreach (Collider val3 in componentsInChildren)
				{
					if ((Object)(object)val3 != (Object)null && val3.enabled && !val3.isTrigger)
					{
						val3.isTrigger = true;
						if (!value.Contains(val3))
						{
							value.Add(val3);
						}
					}
				}
			}
			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
			{
			}
		}

		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
			{
			}
		}

		private void SendCarryEventToPlayer(int targetActorNumber, int carrierViewId, int targetViewId, int targetType, int actionType)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (!SemiFunc.IsMultiplayer())
			{
				return;
			}
			try
			{
				object[] array = new object[4] { carrierViewId, targetViewId, targetType, actionType };
				RaiseEventOptions val = new RaiseEventOptions();
				val.TargetActors = new int[1] { targetActorNumber };
				RaiseEventOptions val2 = val;
				PhotonNetwork.RaiseEvent((byte)188, (object)array, val2, SendOptions.SendReliable);
			}
			catch
			{
			}
		}

		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 = Convert.ToInt32(array[3]);
				if (num == 7)
				{
					Plugin.HostMaxCarryCount = Convert.ToInt32(array[0]);
					try
					{
						Plugin.HostRequiredHoldTime = Convert.ToSingle(array[1]);
						Plugin.HostCarryHeightOffset = Convert.ToSingle(array[2]);
						return;
					}
					catch
					{
						return;
					}
				}
				int num2 = Convert.ToInt32(array[0]);
				int num3 = Convert.ToInt32(array[1]);
				int targetType = Convert.ToInt32(array[2]);
				switch (num)
				{
				case 3:
				{
					if (!PhotonNetwork.IsMasterClient)
					{
						break;
					}
					int num4 = num2;
					SendCarryEvent(PhotonNetwork.LocalPlayer.ActorNumber, num4, 0, 4);
					{
						foreach (KeyValuePair<int, int> activeCarry in ActiveCarries)
						{
							SendCarryEventToPlayer(num4, activeCarry.Value, activeCarry.Key, 1, 1);
						}
						break;
					}
				}
				case 4:
				{
					int num5 = num3;
					if (PhotonNetwork.LocalPlayer != null && num5 == PhotonNetwork.LocalPlayer.ActorNumber)
					{
						_isHostModInstalled = true;
					}
					break;
				}
				case 5:
					if (PhotonNetwork.IsMasterClient)
					{
						ProcessCarryTransfer(num2, num3, targetType);
					}
					break;
				case 6:
					if (PhotonNetwork.IsMasterClient && num2 != 0 && num3 != 0)
					{
						SendCarryEvent(num2, num3, targetType, 2);
					}
					break;
				default:
					HandleCarryAction(num2, num3, targetType, num);
					break;
				}
			}
			catch
			{
			}
		}

		private void HandleCarryAction(int carrierViewId, int targetViewId, int targetType, int actionType)
		{
			//IL_046f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0474: Unknown result type (might be due to invalid IL or missing references)
			//IL_047e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0483: Unknown result type (might be due to invalid IL or missing references)
			//IL_048d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0492: Unknown result type (might be due to invalid IL or missing references)
			//IL_0497: Unknown result type (might be due to invalid IL or missing references)
			//IL_049b: Unknown result type (might be due to invalid IL or missing references)
			//IL_10c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_10cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_10d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_10db: Unknown result type (might be due to invalid IL or missing references)
			//IL_10e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_10f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_10f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_110e: Unknown result type (might be due to invalid IL or missing references)
			//IL_1134: Unknown result type (might be due to invalid IL or missing references)
			//IL_1147: Unknown result type (might be due to invalid IL or missing references)
			//IL_1153: Unknown result type (might be due to invalid IL or missing references)
			//IL_115f: Unknown result type (might be due to invalid IL or missing references)
			PlayerAvatar instance = PlayerAvatar.instance;
			int num = 0;
			int totalPassengers = 1;
			if (actionType == 2 && targetType == 1)
			{
				List<int> list = new List<int>();
				foreach (KeyValuePair<int, int> activeCarry in ActiveCarries)
				{
					if (activeCarry.Value == carrierViewId)
					{
						list.Add(activeCarry.Key);
					}
				}
				if (!list.Contains(targetViewId))
				{
					list.Add(targetViewId);
				}
				list.Sort();
				totalPassengers = list.Count;
				num = list.IndexOf(targetViewId);
				if (num < 0)
				{
					num = 0;
				}
			}
			if (actionType == 2)
			{
				ActiveCarries.Remove(targetViewId);
				CarryStartTimes.Remove(targetViewId);
				_lateAvatarCache.Remove(targetViewId);
				_lateHeadCache.Remove(targetViewId);
				CarriedHurtColliderCache.Remove(targetViewId);
				_wasTumblingOnCarryStart.Remove(targetViewId);
				if (CarryTriggerColliders.TryGetValue(targetViewId, out var value) && value != null)
				{
					foreach (Collider item in value)
					{
						if ((Object)(object)item != (Object)null)
						{
							item.isTrigger = false;
						}
					}
					CarryTriggerColliders.Remove(targetViewId);
				}
				if ((Object)(object)instance != (Object)null && (Object)(object)instance.photonView != (Object)null && instance.photonView.ViewID == carrierViewId)
				{
					int num2 = 0;
					PlayerAvatar val = null;
					PlayerDeathHead val2 = null;
					foreach (KeyValuePair<int, int> activeCarry2 in ActiveCarries)
					{
						if (activeCarry2.Value == carrierViewId)
						{
							num2++;
							if ((Object)(object)val == (Object)null)
							{
								val = FindPlayerAvatarByViewID(activeCarry2.Key);
							}
							if ((Object)(object)val2 == (Object)null)
							{
								val2 = FindPlayerDeathHeadByViewID(activeCarry2.Key);
							}
						}
					}
					if (num2 == 0)
					{
						_myCarriedPlayer = null;
						_myCarriedHead = null;
						_myCarriedHeadPv = null;
						_myCarriedHeadPgo = null;
						_isCarrying = false;
						try
						{
							if ((Object)(object)instance != (Object)null && (Object)(object)instance.healthGrab != (Object)null)
							{
								StaticGrabObject val3 = ((Plugin.Ref_HealthGrabStaticGrabObject != null) ? Plugin.Ref_HealthGrabStaticGrabObject.Invoke(instance.healthGrab) : null);
								if ((Object)(object)val3 != (Object)null)
								{
									((Behaviour)val3).enabled = false;
								}
							}
						}
						catch
						{
						}
					}
					else
					{
						_myCarriedPlayer = val;
						_myCarriedHead = val2;
						if ((Object)(object)val2 != (Object)null)
						{
							_myCarriedHeadPv = ((Component)val2).GetComponent<PhotonView>();
							_myCarriedHeadPgo = ((Component)val2).GetComponent<PhysGrabObject>();
						}
						else
						{
							_myCarriedHeadPv = null;
							_myCarriedHeadPgo = null;
						}
					}
					_releaseTimer = 0f;
				}
				if ((Object)(object)instance != (Object)null && (Object)(object)instance.photonView != (Object)null && instance.photonView.ViewID == targetViewId)
				{
					PlayerTumble val4 = (((Object)(object)instance != (Object)null) ? GetPlayerTumble(instance) : null);
					if ((Object)(object)val4 != (Object)null)
					{
						val4.TumbleRequest(false, false);
						Rigidbody tumbleRb = GetTumbleRb(val4);
						if ((Object)(object)tumbleRb != (Object)null)
						{
							tumbleRb.isKinematic = false;
						}
					}
					if ((Object)(object)instance != (Object)null)
					{
						instance.TumbleStop();
						try
						{
							Rigidbody component = ((Component)instance).GetComponent<Rigidbody>();
							if ((Object)(object)component != (Object)null)
							{
								component.isKinematic = false;
							}
						}
						catch
						{
						}
						if ((Object)(object)PlayerController.instance != (Object)null)
						{
							((Behaviour)PlayerController.instance).enabled = true;
							PlayerController.instance.Crouching = false;
							if (Plugin.Ref_PlayerControllerToggleCrouch != null)
							{
								Plugin.Ref_PlayerControllerToggleCrouch.Invoke(PlayerController.instance) = false;
							}
							if (Plugin.Ref_PlayerControllerCrouchOverrideTimer != null)
							{
								Plugin.Ref_PlayerControllerCrouchOverrideTimer.Invoke(PlayerController.instance) = 0f;
							}
						}
						instance.UpdateState(false, false, false, false, false);
						Rigidbody val5 = (((Object)(object)PlayerController.instance != (Object)null) ? PlayerController.instance.rb : null);
						if ((Object)(object)val5 != (Object)null)
						{
							val5.isKinematic = false;
							PlayerAvatar val6 = FindPlayerAvatarByViewID(carrierViewId);
							if ((Object)(object)val6 != (Object)null)
							{
								Vector3 val7 = -((Component)val6).transform.forward * 2.5f + Vector3.up * 1.2f;
								val5.AddForce(val7, (ForceMode)2);
							}
						}
					}
					_myCarrier = null;
					_myCarrierRb = null;
					_isBeingCarried = false;
					_localTumble = null;
					_localTumblePgo = null;
					_passengerStateTick = 0f;
				}
			}
			PlayerAvatar val8 = FindPlayerAvatarByViewID(carrierViewId);
			if ((Object)(object)val8 == (Object)null)
			{
				return;
			}
			if (actionType == 1)
			{
				Plugin.CarriedTumbleCache.Remove(targetViewId);
				Plugin.CarriedTumbleCache.Remove(carrierViewId);
				Plugin.CarriedAvatarRbCache.Remove(targetViewId);
				Plugin.CarriedAvatarRbCache.Remove(carrierViewId);
				Plugin.CarriedTumbleRbCache.Remove(targetViewId);
				Plugin.CarriedTumbleRbCache.Remove(carrierViewId);
				_lateAvatarCache.Remove(targetViewId);
				_lateAvatarCache.Remove(carrierViewId);
				_lateHeadCache.Remove(targetViewId);
				_lateHeadCache.Remove(carrierViewId);
				CarriedHurtColliderCache.Remove(targetViewId);
				CarriedHurtColliderCache.Remove(carrierViewId);
				_wasTumblingOnCarryStart.Remove(targetViewId);
				_wasTumblingOnCarryStart.Remove(carrierViewId);
				_avatarTumbleCache.Remove(targetViewId);
				_avatarTumbleCache.Remove(carrierViewId);
				_playerNameCache.Remove(targetViewId);
				_playerNameCache.Remove(carrierViewId);
				_colliderCache.Remove(targetViewId);
				_colliderCache.Remove(carrierViewId);
				DetectorTumbleCache.Remove(targetViewId);
				DetectorTumbleCache.Remove(carrierViewId);
				DetectorHeadCache.Remove(targetViewId);
				DetectorHeadCache.Remove(carrierViewId);
				if (CarryTriggerColliders.TryGetValue(targetViewId, out var value2) && value2 != null)
				{
					foreach (Collider item2 in value2)
					{
						if ((Object)(object)item2 != (Object)null)
						{
							item2.isTrigger = false;
						}
					}
					CarryTriggerColliders.Remove(targetViewId);
				}
				if (CarryTriggerColliders.TryGetValue(carrierViewId, out var value3) && value3 != null)
				{
					foreach (Collider item3 in value3)
					{
						if ((Object)(object)item3 != (Object)null)
						{
							item3.isTrigger = false;
						}
					}
					CarryTriggerColliders.Remove(carrierViewId);
				}
				List<int> list2 = new List<int>();
				foreach (KeyValuePair<int, int> activeCarry3 in ActiveCarries)
				{
					if (activeCarry3.Key == targetViewId)
					{
						list2.Add(activeCarry3.Key);
					}
					if (activeCarry3.Value == targetViewId)
					{
						list2.Add(activeCarry3.Key);
					}
				}
				foreach (int item4 in list2)
				{
					ActiveCarries.Remove(item4);
					CarryStartTimes.Remove(item4);
					_lateAvatarCache.Remove(item4);
					_lateHeadCache.Remove(item4);
					CarriedHurtColliderCache.Remove(item4);
					Plugin.CarriedTumbleCache.Remove(item4);
					Plugin.CarriedTumbleRbCache.Remove(item4);
					Plugin.CarriedAvatarRbCache.Remove(item4);
					if (!CarryTriggerColliders.TryGetValue(item4, out var value4) || value4 == null)
					{
						continue;
					}
					foreach (Collider item5 in value4)
					{
						if ((Object)(object)item5 != (Object)null)
						{
							item5.isTrigger = false;
						}
					}
					CarryTriggerColliders.Remove(item4);
				}
				List<int> list3 = new List<int>();
				foreach (KeyValuePair<int, int> activeCarry4 in ActiveCarries)
				{
					if (activeCarry4.Value == carrierViewId && activeCarry4.Key != targetViewId)
					{
						list3.Add(activeCarry4.Key);
					}
				}
				if (list3.Count >= Plugin.HostMaxCarryCount)
				{
					list3.Sort(delegate(int x, int y)
					{
						float value7;
						float num8 = (CarryStartTimes.TryGetValue(x, out value7) ? value7 : 0f);
						float value9;
						float value8 = (CarryStartTimes.TryGetValue(y, out value9) ? value9 : 0f);
						return num8.CompareTo(value8);
					});
					int num3 = list3.Count - Plugin.HostMaxCarryCount + 1;
					for (int num4 = 0; num4 < num3 && num4 < list3.Count; num4++)
					{
						int num5 = list3[num4];
						FindPlayerAvatarByViewID(num5);
						try
						{
							if (CarryTriggerColliders.TryGetValue(num5, out var value5) && value5 != null)
							{
								foreach (Collider item6 in value5)
								{
									if ((Object)(object)item6 != (Object)null)
									{
										item6.isTrigger = false;
									}
								}
								CarryTriggerColliders.Remove(num5);
							}
						}
						catch
						{
						}
						ActiveCarries.Remove(num5);
						CarryStartTimes.Remove(num5);
						_lateAvatarCache.Remove(num5);
						_lateHeadCache.Remove(num5);
						CarriedHurtColliderCache.Remove(num5);
						Plugin.CarriedTumbleCache.Remove(num5);
						Plugin.CarriedTumbleRbCache.Remove(num5);
						Plugin.CarriedAvatarRbCache.Remove(num5);
					}
				}
				if (GetPlayerIsLocal(FindPlayerAvatarByViewID(targetViewId)))
				{
					if (_isBeingCarried)
					{
						try
						{
							PlayerTumble val9 = _localTumble ?? GetPlayerTumble(instance);
							if ((Object)(object)val9 != (Object)null)
							{
								val9.TumbleRequest(false, false);
							}
						}
						catch
						{
						}
						try
						{
							if (instance != null)
							{
								instance.TumbleStop();
							}
						}
						catch
						{
						}
					}
					_isBeingCarried = false;
					_myCarrier = null;
					_myCarrierRb = null;
					_localTumble = null;
					_localTumblePgo = null;
					_passengerStateTick = 0f;
					_cachedCarrierDead = false;
					_cachedSelfDead = false;
					_deadCheckTimer = 0f;
					try
					{
						if ((Object)(object)PlayerController.instance != (Object)null)
						{
							((Behaviour)PlayerController.instance).enabled = true;
							PlayerController.instance.Crouching = false;
							if (Plugin.Ref_PlayerControllerToggleCrouch != null)
							{
								Plugin.Ref_PlayerControllerToggleCrouch.Invoke(PlayerController.instance) = false;
							}
							if (Plugin.Ref_PlayerControllerCrouchOverrideTimer != null)
							{
								Plugin.Ref_PlayerControllerCrouchOverrideTimer.Invoke(PlayerController.instance) = 0f;
							}
							if ((Object)(object)PlayerController.instance.rb != (Object)null)
							{
								PlayerController.instance.rb.isKinematic = false;
							}
						}
					}
					catch
					{
					}
				}
				if (GetPlayerIsLocal(val8))
				{
					if (_isCarrying)
					{
						try
						{
							if ((Object)(object)val8.healthGrab != (Object)null)
							{
								StaticGrabObject val10 = ((Plugin.Ref_HealthGrabStaticGrabObject != null) ? Plugin.Ref_HealthGrabStaticGrabObject.Invoke(val8.healthGrab) : null);
								if ((Object)(object)val10 != (Object)null)
								{
									((Behaviour)val10).enabled = false;
								}
							}
						}
						catch
						{
						}
					}
					_isCarrying = false;
					_myCarriedPlayer = null;
					_myCarriedHead = null;
					_myCarriedHeadPgo = null;
					_myCarriedHeadPv = null;
					_cachedSelfDead = false;
					_deadCheckTimer = 0f;
					_releaseTimer = 0f;
				}
				ActiveCarries[targetViewId] = carrierViewId;
				CarryStartTimes[targetViewId] = Time.time;
				_lateAvatarCache[carrierViewId] = val8;
				PendingRestores.RemoveAll((PendingCollisionRestore x) => x.CarrierViewId == carrierViewId && x.CarriedViewId == targetViewId);
			}
			switch (targetType)
			{
			case 1:
			{
				PlayerAvatar val13 = FindPlayerAvatarByViewID(targetViewId);
				int num7 = (((Object)(object)instance != (Object)null && (Object)(object)instance.photonView != (Object)null) ? instance.photonView.ViewID : 0);
				if (actionType == 1 && num7 != 0 && targetViewId == num7)
				{
					_myCarrier = val8;
					_myCarrierRb = (((Object)(object)val8 != (Object)null) ? ((Component)val8).GetComponent<Rigidbody>() : null);
					_isBeingCarried = true;
				}
				if ((Object)(object)val13 == (Object)null)
				{
					break;
				}
				switch (actionType)
				{
				case 1:
				{
					try
					{
						List<Collider> list4 = new List<Collider>();
						Collider[] componentsInChildren2 = ((Component)val13).GetComponentsInChildren<Collider>(true);
						Collider[] componentsInChildren = componentsInChildren2;
						foreach (Collider val14 in componentsInChildren)
						{
							if ((Object)(object)val14 != (Object)null && val14.enabled && !val14.isTrigger)
							{
								val14.isTrigger = true;
								list4.Add(val14);
							}
						}
						CarryTriggerColliders[targetViewId] = list4;
						Plugin.Log.LogInfo((object)$"[CarryFriend LOG] Set {list4.Count} colliders of player {targetViewId} to triggers. Total in child: {componentsInChildren2.Length}");
					}
					catch (Exception ex)
					{
						Plugin.Log.LogError((object)("[CarryFriend LOG] Error setting triggers: " + ex.Message));
					}
					SetCollisionIgnore(val8, val13, ignore: true);
					_collisionIgnoreRefreshTimer = 0.5f;
					PlayerTumble playerTumble = GetPlayerTumble(val13);
					bool value6 = (Object)(object)pla