Decompiled source of Online Mod v1.0.0

Online_Mod.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using BepInEx;
using DM;
using GamepadUI.StateManager.Core;
using HarmonyLib;
using Landfall.TABS;
using Landfall.TABS.AI;
using Landfall.TABS.AI.Components;
using Landfall.TABS.AI.Systems;
using Landfall.TABS.Budget;
using Landfall.TABS.Budget.Wallets;
using Landfall.TABS.GameMode;
using Landfall.TABS.GameState;
using Landfall.TABS.Services;
using Landfall.TABS.UnitPlacement;
using Landfall.TABS.WinConditions;
using Landfall.TABS.Workshop;
using Microsoft.CodeAnalysis;
using Photon.Bolt;
using Photon.Bolt.Internal;
using Photon.Bolt.Matchmaking;
using Photon.Bolt.Utils;
using TFBG;
using TFBGames;
using UIStateManager;
using UdpKit;
using UdpKit.Platform;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Multiplayer16")]
[assembly: AssemblyDescription("16人联机Mod for TABS")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Multiplayer16")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("a1b2c3d4-e5f6-7890-abcd-ef1234567890")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[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 Multiplayer16
{
	internal static class AssemblyHelper
	{
		public static Assembly GetGameAssembly()
		{
			try
			{
				return Assembly.LoadFrom("E:\\SteamLibrary\\steamapps\\common\\Totally Accurate Battle Simulator\\TotallyAccurateBattleSimulator_Data\\Managed\\Assembly-CSharp.dll");
			}
			catch
			{
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly in assemblies)
				{
					if (assembly.GetName().Name == "Assembly-CSharp")
					{
						return assembly;
					}
				}
			}
			return null;
		}

		public static Assembly GetBoltUserAssembly()
		{
			try
			{
				return Assembly.LoadFrom("E:\\SteamLibrary\\steamapps\\common\\Totally Accurate Battle Simulator\\TotallyAccurateBattleSimulator_Data\\Managed\\bolt.user.dll");
			}
			catch
			{
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly in assemblies)
				{
					if (assembly.GetName().Name == "bolt.user")
					{
						return assembly;
					}
				}
			}
			return null;
		}
	}
	internal static class BattleRestartPatches
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__6_1;

			internal void <ShowRestartConfirm>b__6_1()
			{
				_restartConfirmOpen = false;
			}
		}

		private static Harmony _harmony;

		private static bool _restartConfirmOpen;

		private static readonly FieldRef<NetworkBattleController, bool> BattleStarted = AccessTools.FieldRefAccess<NetworkBattleController, bool>("m_battleStarted");

		public static void ApplyPatches()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected O, but got Unknown
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Expected O, but got Unknown
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Expected O, but got Unknown
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Expected O, but got Unknown
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Expected O, but got Unknown
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Expected O, but got Unknown
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Expected O, but got Unknown
			_harmony = new Harmony("Multiplayer16.BattleRestart");
			MethodInfo methodInfo = AccessTools.Method(typeof(OnlineMultiplayerGameMode), "RequestEndBattle", (Type[])null, (Type[])null);
			if (methodInfo != null)
			{
				_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(BattleRestartPatches), "RequestEndBattlePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo2 = AccessTools.Method(typeof(OnlineMultiplayerGameMode), "BeginEndingMatch", (Type[])null, (Type[])null);
			if (methodInfo2 != null)
			{
				_harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(BattleRestartPatches), "BeginEndingMatchPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo3 = AccessTools.Method(typeof(OnlineMultiplayerGameMode), "OnCountDownTimerEnded", (Type[])null, (Type[])null);
			if (methodInfo3 != null)
			{
				_harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(typeof(BattleRestartPatches), "OnCountDownTimerEndedPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Debug.Log((object)"[Multiplayer16] 已Patch OnlineMultiplayerGameMode.OnCountDownTimerEnded (禁用10秒等待)");
			}
			MethodInfo methodInfo4 = AccessTools.Method(typeof(NetworkBattleController), "SetReadyForPlacement", (Type[])null, (Type[])null);
			if (methodInfo4 != null)
			{
				_harmony.Patch((MethodBase)methodInfo4, new HarmonyMethod(typeof(BattleRestartPatches), "SetReadyForPlacementPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Debug.Log((object)"[Multiplayer16] 已Patch NetworkBattleController.SetReadyForPlacement (禁用原版自动回放置)");
			}
			MethodInfo methodInfo5 = AccessTools.Method(typeof(NetworkBattleController), "ServerStartPlacement", (Type[])null, (Type[])null);
			if (methodInfo5 != null)
			{
				_harmony.Patch((MethodBase)methodInfo5, new HarmonyMethod(typeof(BattleRestartPatches), "ServerStartPlacementPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Debug.Log((object)"[Multiplayer16] 已Patch NetworkBattleController.ServerStartPlacement (防重复延迟广播)");
			}
			MethodInfo methodInfo6 = AccessTools.Method(typeof(OnlineMultiplayerGameMode), "OnEnterPlacementState", (Type[])null, (Type[])null);
			if (methodInfo6 != null)
			{
				_harmony.Patch((MethodBase)methodInfo6, (HarmonyMethod)null, new HarmonyMethod(typeof(BattleRestartPatches), "OnlineOnEnterPlacementStatePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo7 = AccessTools.Method(typeof(NetworkBattleController), "OnLocalOrRemotePrematurelyEndedBattle", (Type[])null, (Type[])null);
			if (methodInfo7 != null)
			{
				_harmony.Patch((MethodBase)methodInfo7, new HarmonyMethod(typeof(BattleRestartPatches), "OnLocalOrRemotePrematurelyEndedBattlePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo8 = AccessTools.Method(typeof(NetworkBattleController), "OnEvent", new Type[1] { typeof(StartPlacementEvent) }, (Type[])null);
			if (methodInfo8 != null)
			{
				_harmony.Patch((MethodBase)methodInfo8, new HarmonyMethod(typeof(BattleRestartPatches), "OnEventStartPlacementPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Debug.Log((object)"[Multiplayer16] 已Patch NetworkBattleController.OnEvent(StartPlacementEvent)");
			}
			MethodInfo methodInfo9 = AccessTools.Method(typeof(BaseGameMode), "OnEnterPlacementState", (Type[])null, (Type[])null);
			if (methodInfo9 != null)
			{
				_harmony.Patch((MethodBase)methodInfo9, new HarmonyMethod(typeof(BattleRestartPatches), "OnEnterPlacementStatePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Debug.Log((object)"[Multiplayer16] 已Patch BaseGameMode.OnEnterPlacementState (战斗返回时跳过序列器)");
			}
			Debug.Log((object)"[Multiplayer16] BattleRestartPatches: 主机 Tab 战斗中确认重启");
		}

		private static bool RequestEndBattlePrefix(OnlineMultiplayerGameMode __instance, ref bool __runOriginal)
		{
			if (BoltNetwork.IsClient && !BoltNetwork.IsServer)
			{
				__runOriginal = false;
				return false;
			}
			if (BoltNetwork.IsServer)
			{
				if (_restartConfirmOpen && IsBattleInProgress(__instance))
				{
					__runOriginal = false;
					return false;
				}
				if (IsBattleInProgress(__instance))
				{
					ShowRestartConfirm(__instance);
					__runOriginal = false;
					return false;
				}
				if (CampaignModeSystem.TryHostContinueAfterWin(__instance))
				{
					__runOriginal = false;
					return false;
				}
				HostReturnToPlacement(__instance);
				__runOriginal = false;
				return false;
			}
			return true;
		}

		private static bool IsBattleInProgress(OnlineMultiplayerGameMode gameMode)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Invalid comparison between Unknown and I4
			if (gameMode == null || ((BaseGameMode)gameMode).MatchOver)
			{
				return false;
			}
			GameStateManager service = ServiceLocator.GetService<GameStateManager>();
			if (service != null)
			{
				return (int)service.GameState == 1;
			}
			return false;
		}

		private static void ShowRestartConfirm(OnlineMultiplayerGameMode gameMode)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			ModalPanel service = ServiceLocator.GetService<ModalPanel>();
			if ((Object)(object)service == (Object)null)
			{
				HostReturnToPlacement(gameMode);
				return;
			}
			_restartConfirmOpen = true;
			try
			{
				string empty = string.Empty;
				UnityAction val = delegate
				{
					_restartConfirmOpen = false;
					HostReturnToPlacement(gameMode);
				};
				object obj = <>c.<>9__6_1;
				if (obj == null)
				{
					UnityAction val2 = delegate
					{
						_restartConfirmOpen = false;
					};
					<>c.<>9__6_1 = val2;
					obj = (object)val2;
				}
				service.Choice(empty, "是否要重启战斗", val, (UnityAction)obj, new string[2] { "是", "否" });
			}
			catch (Exception ex)
			{
				_restartConfirmOpen = false;
				Debug.LogWarning((object)("[Multiplayer16] 重启确认弹窗失败: " + ex.Message));
				HostReturnToPlacement(gameMode);
			}
		}

		private static void CloseRestartConfirmIfOpen()
		{
			if (!_restartConfirmOpen)
			{
				return;
			}
			_restartConfirmOpen = false;
			try
			{
				ModalPanel service = ServiceLocator.GetService<ModalPanel>();
				if (service != null)
				{
					service.ForcePopUpClose();
				}
			}
			catch
			{
			}
		}

		private static void BeginEndingMatchPostfix(OnlineMultiplayerGameMode __instance, Team winningTeam)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			CampaignModeSystem.NotifyWinner(winningTeam);
			if (!BoltNetwork.IsRunning || __instance == null)
			{
				return;
			}
			try
			{
				__instance.Unsubscribe();
				CountdownTimerService service = ServiceLocator.GetService<CountdownTimerService>();
				if (service != null)
				{
					service.Unsubscribe();
				}
			}
			catch
			{
			}
		}

		private static bool OnCountDownTimerEndedPrefix(ref bool __runOriginal)
		{
			if (!BoltNetwork.IsRunning)
			{
				return true;
			}
			__runOriginal = false;
			return false;
		}

		private static bool SetReadyForPlacementPrefix(ref bool __runOriginal)
		{
			if (!BoltNetwork.IsRunning)
			{
				return true;
			}
			__runOriginal = false;
			return false;
		}

		private static bool ServerStartPlacementPrefix(ref bool __runOriginal)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (!BoltNetwork.IsRunning)
			{
				return true;
			}
			GameStateManager service = ServiceLocator.GetService<GameStateManager>();
			if (service != null && (int)service.GameState == 0)
			{
				__runOriginal = false;
				return false;
			}
			return true;
		}

		private static void OnlineOnEnterPlacementStatePostfix(OnlineMultiplayerGameMode __instance)
		{
			if (ShouldFastReturnFromBattle())
			{
				RestoreTimeImmediate();
			}
		}

		private static bool ShouldFastReturnFromBattle()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			if (!IsOnlineClient())
			{
				return false;
			}
			GameStateManager service = ServiceLocator.GetService<GameStateManager>();
			if (service != null)
			{
				return (int)service.PreviousGameState == 1;
			}
			return false;
		}

		private static void RestoreTimeImmediate()
		{
			try
			{
				ITimeService service = ServiceLocator.GetService<ITimeService>();
				if (service != null)
				{
					service.Unlock();
				}
				if (service != null)
				{
					service.UnPause();
				}
				if (service != null)
				{
					service.SetState(1f, 0f, true);
				}
				BoltRuntimeSettings.instance.overrideTimeScale = true;
			}
			catch
			{
			}
		}

		internal static void HostReturnToPlacement(OnlineMultiplayerGameMode gameMode)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			CloseRestartConfirmIfOpen();
			if (!BoltNetwork.IsServer || gameMode == null)
			{
				return;
			}
			GameStateManager service = ServiceLocator.GetService<GameStateManager>();
			if (service != null && (int)service.GameState == 0)
			{
				return;
			}
			CleanupBattleEndForReturnToPlacement(gameMode);
			if (service != null)
			{
				service.EnterPlacementState();
			}
			try
			{
				StartPlacementEvent obj = StartPlacementEvent.Create((GlobalTargets)4, (ReliabilityModes)2);
				if (obj != null)
				{
					((Event)obj).Send();
				}
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[Multiplayer16] 主机返回放置失败: " + ex.Message));
			}
		}

		internal static void CleanupBattleEndForReturnToPlacement(OnlineMultiplayerGameMode gameMode)
		{
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Invalid comparison between Unknown and I4
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Invalid comparison between Unknown and I4
			if (gameMode == null)
			{
				return;
			}
			try
			{
				CountdownTimerService service = ServiceLocator.GetService<CountdownTimerService>();
				if (service != null)
				{
					service.Unsubscribe();
				}
			}
			catch
			{
			}
			try
			{
				gameMode.Unsubscribe();
			}
			catch
			{
			}
			((BaseGameMode)gameMode).MatchOver = false;
			try
			{
				object obj3 = AccessTools.Property(typeof(BaseGameMode), "CurtainController")?.GetValue(gameMode);
				AccessTools.Method(obj3?.GetType(), "OpenCurtains", (Type[])null, (Type[])null)?.Invoke(obj3, null);
			}
			catch
			{
			}
			try
			{
				AccessTools.Method(typeof(OnlineMultiplayerGameMode), "SetTimeToPaused", (Type[])null, (Type[])null)?.Invoke(gameMode, new object[1] { false });
			}
			catch
			{
			}
			RestoreTimeImmediate();
			NetworkBattleController service2 = ServiceLocator.GetService<NetworkBattleController>();
			if ((Object)(object)service2 == (Object)null)
			{
				return;
			}
			try
			{
				BattleStarted.Invoke(service2) = false;
			}
			catch
			{
			}
			try
			{
				NetworkGamePhase phase = service2.Phase;
				if ((int)phase == 4 || (int)phase == 5)
				{
					typeof(NetworkBattleController).GetMethod("SetPhase", BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(service2, new object[1] { (object)(NetworkGamePhase)1 });
				}
			}
			catch
			{
			}
		}

		private static void OnEventStartPlacementPrefix()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Invalid comparison between Unknown and I4
			if (!IsOnlineClient())
			{
				return;
			}
			try
			{
				GameModeService service = ServiceLocator.GetService<GameModeService>();
				BaseGameMode obj = ((service != null) ? service.CurrentGameMode : null);
				OnlineMultiplayerGameMode val = (OnlineMultiplayerGameMode)(object)((obj is OnlineMultiplayerGameMode) ? obj : null);
				if (val != null)
				{
					GameStateManager service2 = ServiceLocator.GetService<GameStateManager>();
					if (service2 != null && (int)service2.GameState == 1)
					{
						Debug.Log((object)"[Multiplayer16] 客机收到 StartPlacementEvent(自战斗返回),清理结算状态");
						CleanupBattleEndForReturnToPlacement(val);
						ForceSnapPlacementCamera();
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[Multiplayer16] StartPlacementEvent 清理结算状态失败: " + ex.Message));
			}
		}

		private static bool OnEnterPlacementStatePrefix(BaseGameMode __instance, ref bool __runOriginal)
		{
			if (ShouldFastReturnFromBattle())
			{
				OnlineMultiplayerGameMode val = (OnlineMultiplayerGameMode)(object)((__instance is OnlineMultiplayerGameMode) ? __instance : null);
				if (val != null)
				{
					Debug.Log((object)"[Multiplayer16] 客机自战斗返回放置: 跳过 TaskSequencer");
					FastFinishClientPlacementSetup(val);
					__runOriginal = false;
					return false;
				}
			}
			return true;
		}

		private static void FastFinishClientPlacementSetup(OnlineMultiplayerGameMode gameMode)
		{
			AccessTools.Method(typeof(BaseGameMode), "ResetMatchVariables", (Type[])null, (Type[])null)?.Invoke(gameMode, null);
			BattleBudget battleBudget = ((BaseGameMode)gameMode).BattleBudget;
			if (battleBudget != null)
			{
				battleBudget.ResetBudgetAll();
			}
			UnitPlacementBrush brush = ((BaseGameMode)gameMode).Brush;
			if (brush != null)
			{
				brush.OnEnterPlacementState();
			}
		}

		private static bool IsOnlineClient()
		{
			if (BoltNetwork.IsRunning && BoltNetwork.IsClient)
			{
				return !BoltNetwork.IsServer;
			}
			return false;
		}

		private static void ForceSnapPlacementCamera()
		{
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				SandboxPlacementCamera val = Object.FindObjectOfType<SandboxPlacementCamera>();
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				((MonoBehaviour)val).StopAllCoroutines();
				AccessTools.Field(typeof(SandboxPlacementCamera), "m_isGoingToPos")?.SetValue(val, false);
				AccessTools.Field(typeof(SandboxPlacementCamera), "<IsResettingRotation>k__BackingField")?.SetValue(val, false);
				if (val.IsInFreeLook())
				{
					AccessTools.Method(typeof(SandboxPlacementCamera), "ExitFreeLook", (Type[])null, (Type[])null)?.Invoke(val, null);
					AccessTools.Field(typeof(SandboxPlacementCamera), "m_isGoingToPos")?.SetValue(val, false);
					if (AccessTools.Field(typeof(SandboxPlacementCamera), "cameraPlacementStartPosition")?.GetValue(val) is Vector3 position)
					{
						((Component)val).transform.position = position;
					}
				}
			}
			catch
			{
			}
		}

		private static bool OnLocalOrRemotePrematurelyEndedBattlePrefix(NetworkBattleController __instance, ref bool __runOriginal)
		{
			return true;
		}
	}
	internal static class BattleRestartUnitSync
	{
		private static Harmony _harmony;

		public static void ApplyPatches()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected O, but got Unknown
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Expected O, but got Unknown
			_harmony = new Harmony("Multiplayer16.BattleRestartUnitSync");
			MethodInfo methodInfo = AccessTools.Method(typeof(BrushBehaviourOnlineMultiplayer), "PlaceLayoutUnit", (Type[])null, (Type[])null);
			if (methodInfo != null)
			{
				_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(BattleRestartUnitSync), "PlaceLayoutUnitPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Debug.Log((object)"[Multiplayer16] 已Patch BrushBehaviourOnlineMultiplayer.PlaceLayoutUnit (仅主机还原布局)");
			}
			MethodInfo methodInfo2 = AccessTools.Method(typeof(TeamLayouts), "AddUnitToLayout", (Type[])null, (Type[])null);
			if (methodInfo2 != null)
			{
				_harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(BattleRestartUnitSync), "AddUnitToLayoutPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo3 = AccessTools.Method(typeof(TeamLayouts), "RemoveUnitFromLayout", (Type[])null, (Type[])null);
			if (methodInfo3 != null)
			{
				_harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(typeof(BattleRestartUnitSync), "RemoveUnitFromLayoutPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo4 = AccessTools.Method(typeof(OnlineMultiplayerGameMode), "OnEnterNewScene", (Type[])null, (Type[])null);
			if (methodInfo4 != null)
			{
				_harmony.Patch((MethodBase)methodInfo4, (HarmonyMethod)null, new HarmonyMethod(typeof(BattleRestartUnitSync), "OnEnterNewScenePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			Debug.Log((object)"[Multiplayer16] BattleRestartUnitSync 补丁应用完成");
		}

		private static uint GetLocalOwnerId()
		{
			if (!BoltNetwork.IsServer)
			{
				return PossessionSync.GetMyServerConnectionId();
			}
			return 0u;
		}

		private static bool PlaceLayoutUnitPrefix(BrushBehaviourOnlineMultiplayer __instance, TABSLayoutUnit unit, Team team, Quaternion unitRotation)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (!BoltNetwork.IsRunning || __instance == null || unit == null)
			{
				return true;
			}
			if (!BoltNetwork.IsServer)
			{
				return false;
			}
			UnitPlacementBrush unitPlacementBrush = ((BrushBehaviourBase)__instance).UnitPlacementBrush;
			if (unitPlacementBrush == null)
			{
				return false;
			}
			bool flag = !unit.CampaignUnit;
			unitPlacementBrush.PlaceLayoutUnitInternal(unit, team, true, unitRotation, flag);
			return false;
		}

		private static void AddUnitToLayoutPostfix(Unit unit)
		{
			if (BoltNetwork.IsRunning && ((unit != null) ? unit.RuntimeReference : null) != null)
			{
				uint connectionId;
				uint ownerConnectionId = (UnitPlacementSync.TryConsumePendingLayoutOwner(out connectionId) ? connectionId : GetLocalOwnerId());
				UnitOwnershipSystem.RecordLayoutOwner(((RuntimeReference)unit.RuntimeReference).Guid, ownerConnectionId);
			}
		}

		private static void RemoveUnitFromLayoutPostfix(RuntimeReference reference)
		{
			if (reference != null)
			{
				UnitOwnershipSystem.ClearLayoutOwner(reference.Guid);
			}
		}

		private static void OnEnterNewScenePostfix()
		{
			UnitOwnershipSystem.ClearAllLayoutOwners();
		}
	}
	internal static class BlindModePatches
	{
		public static void ApplyPatches()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			Harmony val = new Harmony("Multiplayer16.BlindMode");
			MethodInfo methodInfo = AccessTools.Method(typeof(NetworkUnitsManager), "ApplyProjectMarsBlindModeSettings", (Type[])null, (Type[])null);
			if (methodInfo != null)
			{
				val.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(BlindModePatches), "ApplyProjectMarsBlindModeSettingsPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo2 = AccessTools.Method(typeof(OnlineMultiplayerGameMode), "ShowBlindPlacementUnits", (Type[])null, (Type[])null);
			if (methodInfo2 != null)
			{
				val.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(BlindModePatches), "ShowBlindPlacementUnitsPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			Debug.Log((object)"[Multiplayer16] BlindModePatches: 黑箱模式按本方队伍隐藏");
		}

		private static bool ApplyProjectMarsBlindModeSettingsPrefix(Unit spawnedUnit, Team spawnedUnitTeam)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)spawnedUnit == (Object)null || !BoltNetwork.IsRunning)
			{
				return false;
			}
			NetworkBattleController service = ServiceLocator.GetService<NetworkBattleController>();
			if ((Object)(object)service == (Object)null || !service.blindMode)
			{
				return false;
			}
			if (spawnedUnitTeam == PlayerTeamMapping.GetLocalPlayerTeam())
			{
				return false;
			}
			spawnedUnit.IsSpawnedInBlindPlacement = true;
			ShowProjectile[] componentsInChildren = ((Component)spawnedUnit).GetComponentsInChildren<ShowProjectile>();
			if (componentsInChildren != null)
			{
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					if ((Object)(object)componentsInChildren[i] != (Object)null)
					{
						componentsInChildren[i].IsInBlindGame = true;
					}
				}
			}
			spawnedUnit.GetAllRenderers();
			if ((Object)(object)spawnedUnit.SpawnEffects != (Object)null)
			{
				((Component)spawnedUnit.SpawnEffects).gameObject.SetActive(false);
			}
			spawnedUnit.ShowRenderers(false);
			return false;
		}

		private static bool ShowBlindPlacementUnitsPrefix()
		{
			if (!BoltNetwork.IsRunning || TABSSceneManager.IsInMainMenuScene())
			{
				return false;
			}
			NetworkBattleController service = ServiceLocator.GetService<NetworkBattleController>();
			if ((Object)(object)service == (Object)null || !service.blindMode)
			{
				return false;
			}
			Unit[] array = Object.FindObjectsOfType<Unit>();
			if (array == null)
			{
				return false;
			}
			foreach (Unit val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				val.IsSpawnedInBlindPlacement = false;
				ShowProjectile[] componentsInChildren = ((Component)val).GetComponentsInChildren<ShowProjectile>();
				if (componentsInChildren != null)
				{
					for (int j = 0; j < componentsInChildren.Length; j++)
					{
						if ((Object)(object)componentsInChildren[j] != (Object)null)
						{
							componentsInChildren[j].IsInBlindGame = false;
						}
					}
				}
				val.ShowRenderers(true);
			}
			return false;
		}
	}
	internal static class BoltConnectionPatches
	{
		private static uint _handledConnectId;

		private static int _handledConnectFrame;

		private static uint _handledDisconnectId;

		private static int _handledDisconnectFrame;

		private static readonly HashSet<uint> VerifyingConnections = new HashSet<uint>();

		public static void ApplyPatches()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			Harmony val = new Harmony("Multiplayer16.BoltConnection");
			MethodInfo methodInfo = AccessTools.Method(typeof(GlobalEventListener), "ConnectRequest", (Type[])null, (Type[])null);
			if (methodInfo != null)
			{
				HarmonyMethod val2 = new HarmonyMethod(typeof(BoltConnectionPatches), "ConnectRequestPrefix", (Type[])null);
				val.Patch((MethodBase)methodInfo, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Debug.Log((object)"[Multiplayer16] 已Patch GlobalEventListener.ConnectRequest");
			}
			MethodInfo methodInfo2 = AccessTools.Method(typeof(GlobalEventListener), "Connected", (Type[])null, (Type[])null);
			if (methodInfo2 != null)
			{
				HarmonyMethod val3 = new HarmonyMethod(typeof(BoltConnectionPatches), "ConnectedPostfix", (Type[])null);
				val.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, val3, (HarmonyMethod)null, (HarmonyMethod)null);
				Debug.Log((object)"[Multiplayer16] 已Patch GlobalEventListener.Connected");
			}
			MethodInfo methodInfo3 = AccessTools.Method(typeof(GlobalEventListener), "Disconnected", (Type[])null, (Type[])null);
			if (methodInfo3 != null)
			{
				HarmonyMethod val4 = new HarmonyMethod(typeof(BoltConnectionPatches), "DisconnectedPostfix", (Type[])null);
				val.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, val4, (HarmonyMethod)null, (HarmonyMethod)null);
				Debug.Log((object)"[Multiplayer16] 已Patch GlobalEventListener.Disconnected");
			}
			Debug.Log((object)"[Multiplayer16] BoltConnection 补丁应用完成");
		}

		private static bool ConnectRequestPrefix(UdpEndPoint endpoint, IProtocolToken token)
		{
			if (!BoltNetwork.IsServer || !BoltNetwork.IsRunning)
			{
				return true;
			}
			try
			{
				string currentRoomPassword = RoomPasswordSystem.GetCurrentRoomPassword();
				if (string.IsNullOrEmpty(currentRoomPassword))
				{
					return true;
				}
				Debug.Log((object)("[Multiplayer16] 服务器端:收到连接请求(房间有暗号: " + currentRoomPassword + "),将在Connected阶段验证"));
				return true;
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[Multiplayer16] ConnectRequestPrefix 错误: " + ex.Message));
				return true;
			}
		}

		private static void ConnectedPostfix(BoltConnection connection)
		{
			if (connection == null)
			{
				return;
			}
			int frameCount = Time.frameCount;
			if (_handledConnectId == connection.ConnectionId && _handledConnectFrame == frameCount)
			{
				return;
			}
			_handledConnectId = connection.ConnectionId;
			_handledConnectFrame = frameCount;
			if (BoltNetwork.IsServer)
			{
				if (!VerifyAndAcceptConnection(connection))
				{
					Debug.LogWarning((object)$"[Multiplayer16] 服务器端:连接 {connection.ConnectionId} 未通过暗号验证,已断开");
					return;
				}
				RoomPasswordSystem.MarkConnectionAuthorized(connection.ConnectionId);
				EnsurePasswordRoomStaysOpen();
			}
			PlayerTeamMapping.RegisterPlayer(connection);
			RoomPasswordSystem.SendMapStartToConnectionIfNeeded(connection);
			PossessionSync.OnClientConnected(connection);
		}

		private static void EnsurePasswordRoomStaysOpen()
		{
			if (!BoltNetwork.IsServer || !BoltNetwork.IsRunning)
			{
				return;
			}
			try
			{
				UdpSession currentSession = BoltMatchmaking.CurrentSession;
				if (currentSession == null || !(((object)currentSession).GetType().Name == "PhotonSession"))
				{
					return;
				}
				MethodInfo method = ((object)currentSession).GetType().GetMethod("GetProtocolToken");
				if (!(method != null))
				{
					return;
				}
				object obj = method.Invoke(currentSession, null);
				if (obj == null || !(obj.GetType().Name == "PhotonRoomProperties"))
				{
					return;
				}
				Type type = obj.GetType();
				bool flag = false;
				try
				{
					MethodInfo method2 = type.GetMethod("GetValue", new Type[1] { typeof(string) });
					if (method2 != null)
					{
						object obj2 = method2.MakeGenericMethod(typeof(string)).Invoke(obj, new object[1] { "MP16_Password" });
						flag = obj2 != null && !string.IsNullOrEmpty(obj2.ToString());
					}
				}
				catch
				{
				}
				if (!flag)
				{
					return;
				}
				PropertyInfo property = type.GetProperty("IsOpen");
				bool flag2 = false;
				if (property != null && property.CanWrite && !(bool)property.GetValue(obj))
				{
					property.SetValue(obj, true);
					flag2 = true;
				}
				if (flag2)
				{
					IProtocolToken val = (IProtocolToken)((obj is IProtocolToken) ? obj : null);
					if (val != null)
					{
						BoltMatchmaking.UpdateSession(val);
						Debug.Log((object)"[Multiplayer16] 玩家连接后,确保暗号房间保持开放(不设为可见,阻止快速匹配)");
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[Multiplayer16] EnsurePasswordRoomStaysOpen 错误: " + ex.Message));
			}
		}

		private static bool VerifyAndAcceptConnection(BoltConnection connection)
		{
			try
			{
				UdpSession currentSession = BoltMatchmaking.CurrentSession;
				if (currentSession == null || ((object)currentSession).GetType().Name != "PhotonSession")
				{
					return true;
				}
				string currentRoomPassword = RoomPasswordSystem.GetCurrentRoomPassword();
				if (!VerifyingConnections.Add(connection.ConnectionId) && RoomPasswordSystem.IsConnectionAuthorized(connection.ConnectionId))
				{
					return true;
				}
				GameModeSwitchPatches.CoroutineRunner coroutineRunner = GameModeSwitchPatches.GetCoroutineRunner();
				if ((Object)(object)coroutineRunner != (Object)null)
				{
					((MonoBehaviour)coroutineRunner).StartCoroutine(ImmediatePasswordVerification(connection, currentRoomPassword));
					return true;
				}
				Debug.LogWarning((object)"[Multiplayer16] 无法找到 MonoBehaviour,无法进行服务器端验证");
				DisconnectUnauthorizedConnection(connection);
				return false;
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[Multiplayer16] VerifyAndAcceptConnection 错误: " + ex.Message));
				if (connection != null)
				{
					DisconnectUnauthorizedConnection(connection);
				}
				return false;
			}
		}

		private static IEnumerator ImmediatePasswordVerification(BoltConnection connection, string roomPassword)
		{
			Debug.Log((object)$"[Multiplayer16] 服务器端:等待连接 {connection.ConnectionId} 发送 Mod 握手包...");
			float timeout = 15f;
			for (float elapsed = 0f; elapsed < timeout; elapsed += 0.5f)
			{
				if (connection == null)
				{
					yield break;
				}
				if (RoomPasswordSystem.IsConnectionAuthorized(connection.ConnectionId))
				{
					Debug.Log((object)$"[Multiplayer16] 服务器端:连接 {connection.ConnectionId} 已通过 Mod 握手验证");
					yield break;
				}
				yield return (object)new WaitForSeconds(0.5f);
			}
			if (!RoomPasswordSystem.IsConnectionAuthorized(connection.ConnectionId))
			{
				Debug.LogWarning((object)$"[Multiplayer16] 服务器端:连接 {connection.ConnectionId} 验证超时(未收到 Mod 握手包),判定为非 Mod 玩家,断开连接");
				DisconnectUnauthorizedConnection(connection);
			}
		}

		private static void SendRoomLockedAndDisconnect(BoltConnection connection)
		{
			if (connection == null)
			{
				return;
			}
			try
			{
				PlayerInfoEvent val = PlayerInfoEvent.Create(connection, (ReliabilityModes)2);
				if (val != null)
				{
					byte[] array = new byte[4];
					BitConverter.GetBytes(3405643785u).CopyTo(array, 0);
					((Event)val).BinaryData = array;
					val.PlayerName = "ROOM_LOCKED";
					((Event)val).Send();
				}
			}
			catch
			{
			}
			GameModeSwitchPatches.CoroutineRunner coroutineRunner = GameModeSwitchPatches.GetCoroutineRunner();
			if ((Object)(object)coroutineRunner != (Object)null)
			{
				((MonoBehaviour)coroutineRunner).StartCoroutine(DelayedDisconnectLocked(connection));
			}
			else
			{
				DisconnectUnauthorizedConnection(connection);
			}
		}

		private static IEnumerator DelayedDisconnectLocked(BoltConnection connection)
		{
			yield return (object)new WaitForSecondsRealtime(0.2f);
			DisconnectUnauthorizedConnection(connection);
		}

		private static void DisconnectUnauthorizedConnection(BoltConnection connection)
		{
			if (connection == null || RoomPasswordSystem.IsConnectionAuthorized(connection.ConnectionId))
			{
				return;
			}
			try
			{
				Debug.LogWarning((object)$"[Multiplayer16] 服务器端:断开未授权连接 {connection.ConnectionId}(房间需要暗号)");
				connection.Disconnect();
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[Multiplayer16] DisconnectUnauthorizedConnection 错误: " + ex.Message));
			}
		}

		private static void DisconnectedPostfix(BoltConnection connection)
		{
			if (connection != null)
			{
				int frameCount = Time.frameCount;
				if (_handledDisconnectId == connection.ConnectionId && _handledDisconnectFrame == frameCount)
				{
					return;
				}
				_handledDisconnectId = connection.ConnectionId;
				_handledDisconnectFrame = frameCount;
				VerifyingConnections.Remove(connection.ConnectionId);
				RoomPasswordSystem.ClearConnectionAuthorization(connection.ConnectionId);
				PossessionSync.OnClientDisconnected(connection.ConnectionId);
				PlayerTeamMapping.UnregisterPlayer(connection.ConnectionId);
			}
			if (BoltMatchmaking.CurrentSession == null && !RoomPasswordSystem.IsCreatingRoom)
			{
				PossessionSync.ClearSessionPlayers();
				GameModeSwitchPatches.Reset();
				Debug.Log((object)"[Multiplayer16] 检测到会话已断开,重置游戏模式切换标志");
			}
		}
	}
	internal static class BugDlcPatches
	{
		public static void ApplyPatches()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Expected O, but got Unknown
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Expected O, but got Unknown
			Harmony val = new Harmony("Multiplayer16.BugDlc");
			MethodInfo methodInfo = AccessTools.Method(typeof(GameModeService), "IsGameModeRestricted", (Type[])null, (Type[])null);
			if (methodInfo != null)
			{
				val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(BugDlcPatches), "IsGameModeRestrictedPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
				Debug.Log((object)"[Multiplayer16] 已Patch GameModeService.IsGameModeRestricted (主机允许 Bug DLC)");
			}
			MethodInfo methodInfo2 = AccessTools.Method(typeof(SettingsHandler), "GetSettingsForTab", (Type[])null, (Type[])null);
			if (methodInfo2 != null)
			{
				val.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(BugDlcPatches), "GetSettingsForTabPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Debug.Log((object)"[Multiplayer16] 已Patch SettingsHandler.GetSettingsForTab (联机 Bug DLC)");
			}
			MethodInfo methodInfo3 = AccessTools.Method(typeof(SettingsHandler), "OpenSettingsMenu", new Type[1] { typeof(int) }, (Type[])null);
			if (methodInfo3 != null)
			{
				val.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(typeof(BugDlcPatches), "OpenSettingsMenuPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
				Debug.Log((object)"[Multiplayer16] 已Patch SettingsHandler.OpenSettingsMenu (去掉联机 Bug 不可用提示)");
			}
			MethodInfo methodInfo4 = AccessTools.Method(typeof(SettingsInstance), "SaveSettings", (Type[])null, (Type[])null);
			if (methodInfo4 != null)
			{
				val.Patch((MethodBase)methodInfo4, new HarmonyMethod(typeof(BugDlcPatches), "SaveSettingsPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			Debug.Log((object)"[Multiplayer16] BugDlc 补丁应用完成");
		}

		public static void RestoreClientBugSettings()
		{
			try
			{
				GlobalSettingsHandler service = ServiceLocator.GetService<GlobalSettingsHandler>();
				SettingsInstance[] array = ((service != null) ? service.BugsSettings : null);
				if (array == null)
				{
					return;
				}
				SettingsProfileManager service2 = ServiceLocator.GetService<SettingsProfileManager>();
				SettingsProfile val = ((service2 != null) ? service2.CurrentSettingsProfile : null);
				SettingsInstance[] array2 = array;
				foreach (SettingsInstance val2 in array2)
				{
					if (val2 != null)
					{
						val2.DisableChanges = false;
						if ((Object)(object)val != (Object)null)
						{
							val2.LoadSettings(val);
						}
					}
				}
			}
			catch
			{
			}
		}

		public static void LockClientBugs()
		{
			try
			{
				GlobalSettingsHandler service = ServiceLocator.GetService<GlobalSettingsHandler>();
				SettingsInstance[] array = ((service != null) ? service.BugsSettings : null);
				if (array != null)
				{
					ApplyClientLock(array);
				}
			}
			catch
			{
			}
		}

		private static void IsGameModeRestrictedPostfix(ref bool __result)
		{
			if (__result && BoltNetwork.IsRunning && BoltNetwork.IsServer)
			{
				__result = false;
			}
		}

		private static bool GetSettingsForTabPrefix(int tabID, ref SettingsInstance[] __result)
		{
			if (tabID != 4 || !BoltNetwork.IsRunning || !BoltNetwork.IsServer || !Bugs._DLC_ACTIVATED)
			{
				return true;
			}
			GlobalSettingsHandler service = ServiceLocator.GetService<GlobalSettingsHandler>();
			SettingsInstance[] array = ((service != null) ? service.BugsSettings : null);
			if (array == null || array.Length == 0)
			{
				return true;
			}
			__result = array;
			return false;
		}

		private static void OpenSettingsMenuPostfix(SettingsHandler __instance, int tabID)
		{
			if (tabID != 4 || !BoltNetwork.IsRunning || !BoltNetwork.IsServer)
			{
				return;
			}
			try
			{
				AccessTools.Method(typeof(SettingsHandler), "ShowCenterMessage", (Type[])null, (Type[])null)?.Invoke(__instance, new object[2] { false, null });
			}
			catch
			{
			}
		}

		private static bool SaveSettingsPrefix(SettingsInstance __instance)
		{
			if (!BoltNetwork.IsClient || !BoltNetwork.IsRunning || __instance == null)
			{
				return true;
			}
			string settingsKey = __instance.m_settingsKey;
			if (!string.IsNullOrEmpty(settingsKey) && settingsKey.StartsWith("BUG_"))
			{
				return false;
			}
			return true;
		}

		private static void ApplyClientLock(SettingsInstance[] bugs)
		{
			if (!BoltNetwork.IsClient)
			{
				return;
			}
			foreach (SettingsInstance val in bugs)
			{
				if (val != null)
				{
					val.DisableChanges = true;
					val.currentValue = 0;
					val.currentSliderValue = 0f;
				}
			}
		}
	}
	internal static class CampaignModeSystem
	{
		internal const uint MARKER = 3405643787u;

		internal const string EVENT_NAME = "CAMP_STATE";

		private static Harmony _harmony;

		private static Team _lastWinner = (Team)(-1);

		private static readonly PropertyInfo SelectedCampaignProp = AccessTools.Property(typeof(CampaignPlayerDataHolder), "SelectedCampaign");

		private static readonly FieldInfo LevelIndexField = AccessTools.Field(typeof(CampaignPlayerDataHolder), "_LevelIndex");

		private static readonly PropertyInfo AutoLoadProp = AccessTools.Property(typeof(CampaignPlayerDataHolder), "AutoLoadNextLevel");

		private static readonly PropertyInfo LastLoadedLevelProp = AccessTools.Property(typeof(CampaignHandler), "LastLoadedLevel");

		private static int _lastSceneLoadedLevelIndex = int.MinValue;

		public static bool HasBoundCampaign
		{
			get
			{
				if ((Object)(object)CampaignPlayerDataHolder.SelectedCampaign != (Object)null)
				{
					return GameRoomModeState.IsCampaign;
				}
				return false;
			}
		}

		public static void Initialize()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected O, but got Unknown
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Expected O, but got Unknown
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Expected O, but got Unknown
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Expected O, but got Unknown
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Expected O, but got Unknown
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Expected O, but got Unknown
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Expected O, but got Unknown
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Expected O, but got Unknown
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Expected O, but got Unknown
			//IL_034e: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Expected O, but got Unknown
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c0: Expected O, but got Unknown
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0407: Expected O, but got Unknown
			//IL_0442: Unknown result type (might be due to invalid IL or missing references)
			//IL_044e: Expected O, but got Unknown
			//IL_0488: Unknown result type (might be due to invalid IL or missing references)
			//IL_0495: Expected O, but got Unknown
			//IL_04d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04dc: Expected O, but got Unknown
			_harmony = new Harmony("Multiplayer16.CampaignMode");
			MethodInfo methodInfo = AccessTools.Method(typeof(UIMapSelector), "Start", (Type[])null, (Type[])null);
			if (methodInfo != null)
			{
				_harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(CampaignModeSystem), "UiMapSelectorStartPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo2 = AccessTools.Method(typeof(MapSelectionCanvas), "GetGameModeUI", (Type[])null, (Type[])null);
			if (methodInfo2 != null)
			{
				_harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(CampaignModeSystem), "GetGameModeUiPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo3 = AccessTools.Method(typeof(LevelSelection), "SetLevelGridForCurrentGameType", (Type[])null, (Type[])null);
			if (methodInfo3 != null)
			{
				_harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(typeof(CampaignModeSystem), "SetLevelGridPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo4 = AccessTools.Method(typeof(LevelSelection), "SpawnCampaignLevelCell", (Type[])null, (Type[])null);
			if (methodInfo4 != null)
			{
				_harmony.Patch((MethodBase)methodInfo4, new HarmonyMethod(typeof(CampaignModeSystem), "SpawnCampaignLevelCellPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo5 = AccessTools.Method(typeof(CampaignPlayerDataHolder), "StartedPlayingNewCampaign", (Type[])null, (Type[])null);
			if (methodInfo5 != null)
			{
				_harmony.Patch((MethodBase)methodInfo5, new HarmonyMethod(typeof(CampaignModeSystem), "StartedPlayingNewCampaignPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo6 = AccessTools.Method(typeof(TABSSceneManager), "LoadCampaign", (Type[])null, (Type[])null);
			if (methodInfo6 != null)
			{
				_harmony.Patch((MethodBase)methodInfo6, new HarmonyMethod(typeof(CampaignModeSystem), "LoadCampaignPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo7 = AccessTools.Method(typeof(CampaignPlayerDataHolder), "LoadCampaignLevelWithIndex", (Type[])null, (Type[])null);
			if (methodInfo7 != null)
			{
				_harmony.Patch((MethodBase)methodInfo7, new HarmonyMethod(typeof(CampaignModeSystem), "LoadCampaignLevelWithIndexPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo8 = AccessTools.Method(typeof(CampaignPlayerDataHolder), "LoadNextCampaignLevel", (Type[])null, (Type[])null);
			if (methodInfo8 != null)
			{
				_harmony.Patch((MethodBase)methodInfo8, new HarmonyMethod(typeof(CampaignModeSystem), "LoadNextCampaignLevelPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo9 = AccessTools.Method(typeof(PlacementUI), "EnterPlacementState", (Type[])null, (Type[])null);
			if (methodInfo9 != null)
			{
				_harmony.Patch((MethodBase)methodInfo9, (HarmonyMethod)null, new HarmonyMethod(typeof(CampaignModeSystem), "EnterPlacementStatePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo10 = AccessTools.Method(typeof(PlacementUI), "ShowUI", (Type[])null, (Type[])null);
			if (methodInfo10 != null)
			{
				_harmony.Patch((MethodBase)methodInfo10, (HarmonyMethod)null, new HarmonyMethod(typeof(CampaignModeSystem), "ShowUiPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo11 = AccessTools.Method(typeof(PlacementFactionBar), "Spawn", Type.EmptyTypes, (Type[])null);
			if (methodInfo11 != null)
			{
				_harmony.Patch((MethodBase)methodInfo11, new HarmonyMethod(typeof(CampaignModeSystem), "FactionBarSpawnPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo12 = AccessTools.Method(typeof(PlacementFactionBar), "SpawnFaction", (Type[])null, (Type[])null);
			if (methodInfo12 != null)
			{
				_harmony.Patch((MethodBase)methodInfo12, (HarmonyMethod)null, new HarmonyMethod(typeof(CampaignModeSystem), "SpawnFactionPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo13 = AccessTools.Method(typeof(PlacementUI), "DrawFactionUnit", new Type[2]
			{
				typeof(UnitBlueprint),
				typeof(bool)
			}, (Type[])null);
			if (methodInfo13 != null)
			{
				_harmony.Patch((MethodBase)methodInfo13, new HarmonyMethod(typeof(CampaignModeSystem), "DrawFactionUnitPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo14 = AccessTools.Method(typeof(PlacementUI), "AssignInitialUnitToBrush", (Type[])null, (Type[])null);
			if (methodInfo14 != null)
			{
				_harmony.Patch((MethodBase)methodInfo14, new HarmonyMethod(typeof(CampaignModeSystem), "AssignInitialUnitToBrushPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo15 = AccessTools.Method(typeof(BattleRadialButton), "UpdateData", (Type[])null, (Type[])null);
			if (methodInfo15 != null)
			{
				_harmony.Patch((MethodBase)methodInfo15, (HarmonyMethod)null, new HarmonyMethod(typeof(CampaignModeSystem), "BattleRadialButtonUpdateDataPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo16 = AccessTools.Method(typeof(BattleRadialMenu), "BuildCaches", (Type[])null, (Type[])null);
			if (methodInfo16 != null)
			{
				_harmony.Patch((MethodBase)methodInfo16, new HarmonyMethod(typeof(CampaignModeSystem), "BuildCachesPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo17 = AccessTools.Method(typeof(OnlineMultiplayerGameMode), "OnEnterNewScene", (Type[])null, (Type[])null);
			if (methodInfo17 != null)
			{
				_harmony.Patch((MethodBase)methodInfo17, (HarmonyMethod)null, new HarmonyMethod(typeof(CampaignModeSystem), "OnEnterNewScenePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			CampaignSelectionUI.Ensure();
			Debug.Log((object)"[Multiplayer16] CampaignModeSystem 已初始化");
		}

		public static void Bind(TABSCampaignAsset campaign, int levelIndex)
		{
			if ((Object)(object)campaign == (Object)null)
			{
				return;
			}
			TABSCampaignLevelAsset[] levelsInCampaign = campaign.LevelsInCampaign;
			if (levelsInCampaign != null && levelsInCampaign.Length != 0)
			{
				if (levelIndex < 0)
				{
					levelIndex = 0;
				}
				if (levelIndex >= levelsInCampaign.Length)
				{
					levelIndex = levelsInCampaign.Length - 1;
				}
				SelectedCampaignProp?.SetValue(null, campaign);
				LevelIndexField?.SetValue(null, levelIndex);
				AutoLoadProp?.SetValue(null, true);
				SetLastLoadedLevel(levelsInCampaign[levelIndex]);
			}
		}

		public static void SetLastLoadedLevel(TABSCampaignLevelAsset level)
		{
			LastLoadedLevelProp?.SetValue(null, level);
		}

		public static void NotifyWinner(Team winningTeam)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			_lastWinner = winningTeam;
		}

		public static bool TryHostContinueAfterWin(OnlineMultiplayerGameMode gameMode)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (!GameRoomModeState.IsCampaign || !BoltNetwork.IsServer)
			{
				return false;
			}
			if ((int)_lastWinner != 0)
			{
				return false;
			}
			TABSCampaignAsset selectedCampaign = CampaignPlayerDataHolder.SelectedCampaign;
			if (((selectedCampaign != null) ? selectedCampaign.LevelsInCampaign : null) == null)
			{
				return false;
			}
			int num = GetBoundLevelIndex() + 1;
			if (num >= selectedCampaign.LevelsInCampaign.Length)
			{
				return false;
			}
			try
			{
				CampaignPlayerDataHolder.CompletedCurrentLevel();
			}
			catch
			{
			}
			if (gameMode != null)
			{
				BattleRestartPatches.CleanupBattleEndForReturnToPlacement(gameMode);
			}
			HostLoadLevel(num);
			return true;
		}

		public static void ShowCampaignPicker(Action<TABSCampaignAsset> onSelected, Action onCancel = null)
		{
			CampaignSelectionUI.Ensure();
			CampaignSelectionUI.Instance?.Show(onSelected, onCancel);
		}

		public static void HostStartCampaign(TABSCampaignAsset campaign)
		{
			if (!((Object)(object)campaign == (Object)null) && BoltNetwork.IsServer)
			{
				GameModeSwitchPatches.EnsureOnlineGameModeState();
				Bind(campaign, 0);
				HostLoadCurrentBoundLevel();
			}
		}

		public static void HostLoadLevel(int index)
		{
			if (BoltNetwork.IsServer)
			{
				TABSCampaignAsset selectedCampaign = CampaignPlayerDataHolder.SelectedCampaign;
				if (!((Object)(object)selectedCampaign == (Object)null))
				{
					Bind(selectedCampaign, index);
					HostLoadCurrentBoundLevel();
				}
			}
		}

		public static void HostLoadCurrentBoundLevel()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if (!BoltNetwork.IsServer)
			{
				return;
			}
			TABSCampaignLevelAsset val = TryGetBoundLevel();
			if (!((Object)(object)val == (Object)null))
			{
				SetLastLoadedLevel(val);
				BroadcastState();
				MapAsset mapAsset = val.MapAsset;
				if (!((Object)(object)mapAsset == (Object)null))
				{
					GameModeSwitchPatches.RequestForceMapReload();
					RoomPasswordSystem.StartGameWithMap(mapAsset.m_MapType, mapAsset.m_mapIndex);
				}
			}
		}

		public static byte[] AppendToMapStart(byte[] data)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			if (!GameRoomModeState.IsCampaign || data == null)
			{
				return data;
			}
			TABSCampaignAsset selectedCampaign = CampaignPlayerDataHolder.SelectedCampaign;
			if (((selectedCampaign != null) ? selectedCampaign.Entity : null) == null)
			{
				return data;
			}
			byte[] array = new byte[12];
			BitConverter.GetBytes(selectedCampaign.Entity.GUID.m_modID).CopyTo(array, 0);
			BitConverter.GetBytes(selectedCampaign.Entity.GUID.m_ID).CopyTo(array, 4);
			BitConverter.GetBytes(GetBoundLevelIndex()).CopyTo(array, 8);
			byte[] array2 = new byte[data.Length + array.Length];
			Buffer.BlockCopy(data, 0, array2, 0, data.Length);
			Buffer.BlockCopy(array, 0, array2, data.Length, array.Length);
			return array2;
		}

		public static void TryApplyFromMapStart(byte[] data, int nameStart, ushort nameLen)
		{
			int num = nameStart + nameLen;
			if (data != null && data.Length >= num + 12)
			{
				int modId = BitConverter.ToInt32(data, num);
				int campaignId = BitConverter.ToInt32(data, num + 4);
				int levelIndex = BitConverter.ToInt32(data, num + 8);
				ApplyRemote(modId, campaignId, levelIndex);
			}
		}

		public static void TryApplyPacket(byte[] data)
		{
			if (data != null && data.Length >= 16)
			{
				int modId = BitConverter.ToInt32(data, 4);
				int campaignId = BitConverter.ToInt32(data, 8);
				int levelIndex = BitConverter.ToInt32(data, 12);
				ApplyRemote(modId, campaignId, levelIndex);
			}
		}

		public static void ApplyRemote(int modId, int campaignId, int levelIndex)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				ContentDatabase obj = ContentDatabase.Instance();
				TABSCampaignAsset val = ((obj != null) ? obj.GetCampaign(new DatabaseID(modId, campaignId)) : null);
				if ((Object)(object)val == (Object)null)
				{
					foreach (TABSCampaignAsset allCampaign in ContentDatabase.Instance().GetAllCampaigns())
					{
						if (((allCampaign != null) ? allCampaign.Entity : null) != null && allCampaign.Entity.GUID.m_ID == campaignId && allCampaign.Entity.GUID.m_modID == modId)
						{
							val = allCampaign;
							break;
						}
					}
				}
				if ((Object)(object)val != (Object)null)
				{
					Bind(val, levelIndex);
				}
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[Multiplayer16] 应用战役状态失败: " + ex.Message));
			}
		}

		public static void SendToConnection(BoltConnection dest)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			if (!BoltNetwork.IsServer || dest == null)
			{
				return;
			}
			TABSCampaignAsset selectedCampaign = CampaignPlayerDataHolder.SelectedCampaign;
			if (!GameRoomModeState.IsCampaign || ((selectedCampaign != null) ? selectedCampaign.Entity : null) == null)
			{
				return;
			}
			try
			{
				byte[] array = new byte[16];
				BitConverter.GetBytes(3405643787u).CopyTo(array, 0);
				BitConverter.GetBytes(selectedCampaign.Entity.GUID.m_modID).CopyTo(array, 4);
				BitConverter.GetBytes(selectedCampaign.Entity.GUID.m_ID).CopyTo(array, 8);
				BitConverter.GetBytes(GetBoundLevelIndex()).CopyTo(array, 12);
				PlayerInfoEvent val = PlayerInfoEvent.Create(dest, (ReliabilityModes)2);
				if (val != null)
				{
					val.PlayerName = "CAMP_STATE";
					((Event)val).BinaryData = array;
					((Event)val).Send();
				}
			}
			catch
			{
			}
		}

		public static void BroadcastState()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			if (!BoltNetwork.IsServer || !BoltNetwork.IsRunning || BoltNetwork.Connections == null)
			{
				return;
			}
			TABSCampaignAsset selectedCampaign = CampaignPlayerDataHolder.SelectedCampaign;
			if (((selectedCampaign != null) ? selectedCampaign.Entity : null) == null)
			{
				return;
			}
			byte[] array = new byte[16];
			BitConverter.GetBytes(3405643787u).CopyTo(array, 0);
			BitConverter.GetBytes(selectedCampaign.Entity.GUID.m_modID).CopyTo(array, 4);
			BitConverter.GetBytes(selectedCampaign.Entity.GUID.m_ID).CopyTo(array, 8);
			BitConverter.GetBytes(GetBoundLevelIndex()).CopyTo(array, 12);
			foreach (BoltConnection connection in BoltNetwork.Connections)
			{
				if (connection == null)
				{
					continue;
				}
				try
				{
					PlayerInfoEvent val = PlayerInfoEvent.Create(connection, (ReliabilityModes)2);
					if (val != null)
					{
						val.PlayerName = "CAMP_STATE";
						((Event)val).BinaryData = array;
						((Event)val).Send();
					}
				}
				catch
				{
				}
			}
		}

		internal static List<TABSCampaignAsset> GetOfficialCampaigns()
		{
			List<TABSCampaignAsset> list = new List<TABSCampaignAsset>();
			try
			{
				ISaveLoaderService service = ServiceLocator.GetService<ISaveLoaderService>();
				foreach (TABSCampaignAsset allCampaign in ContentDatabase.Instance().GetAllCampaigns())
				{
					if (!((Object)(object)allCampaign == (Object)null) && !allCampaign.IsCustomCampaign && !allCampaign.IsModCampaign)
					{
						string text = ((allCampaign.Entity != null) ? allCampaign.Entity.UnlockKey : null);
						if (string.IsNullOrWhiteSpace(text) || service == null || service.HasUnlockedSecret(text))
						{
							list.Add(allCampaign);
						}
					}
				}
			}
			catch
			{
			}
			return list;
		}

		internal static bool ShouldReloadSceneForBoundLevel()
		{
			if (!GameRoomModeState.IsCampaign)
			{
				return false;
			}
			return GetBoundLevelIndex() != _lastSceneLoadedLevelIndex;
		}

		internal static void MarkSceneLoadedForBoundLevel()
		{
			_lastSceneLoadedLevelIndex = GetBoundLevelIndex();
		}

		private static int GetBoundLevelIndex()
		{
			object obj = LevelIndexField?.GetValue(null);
			if (obj is int)
			{
				return (int)obj;
			}
			return 0;
		}

		private static TABSCampaignLevelAsset TryGetBoundLevel()
		{
			try
			{
				return CampaignPlayerDataHolder.GetCurrentLevel();
			}
			catch
			{
				return null;
			}
		}

		private static void UiMapSelectorStartPostfix(UIMapSelector __instance)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Expected O, but got Unknown
			if (!GameRoomModeState.IsCampaign || (Object)(object)__instance == (Object)null)
			{
				return;
			}
			TABSCampaignAsset selectedCampaign = CampaignPlayerDataHolder.SelectedCampaign;
			TABSCampaignLevelAsset[] array = (((Object)(object)selectedCampaign != (Object)null) ? selectedCampaign.LevelsInCampaign : null);
			if (array == null || array.Length == 0)
			{
				return;
			}
			__instance.ClearMaps();
			__instance.ChangeName("Levels");
			TABSCampaignLevelAsset val = TryGetBoundLevel();
			for (int i = 0; i < array.Length; i++)
			{
				TABSCampaignLevelAsset val2 = array[i];
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				bool flag = (Object)(object)val != (Object)null && val.Entity != null && val2.Entity != null && val.Entity.GUID == val2.Entity.GUID;
				int index = i;
				__instance.AddMapButton((val2.Entity != null) ? val2.Entity.Name : ModL10n.F("level_n", i + 1), (UnityAction)delegate
				{
					if (BoltNetwork.IsServer)
					{
						HostLoadLevel(index);
					}
				}, flag, true, false);
			}
			__instance.SetUpExplicitVerticalNavigation();
		}

		private static bool GetGameModeUiPrefix(MapSelectionCanvas __instance)
		{
			if (!GameRoomModeState.IsCampaign)
			{
				return true;
			}
			try
			{
				if ((Object)(object)__instance.SandboxUI != (Object)null)
				{
					__instance.SandboxUI.SetActive(false);
				}
				if ((Object)(object)__instance.CampaignUI != (Object)null)
				{
					__instance.CampaignUI.SetActive(true);
					Paginator component = __instance.CampaignUI.GetComponent<Paginator>();
					if (component != null)
					{
						component.OpenPage();
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private static bool SetLevelGridPrefix(LevelSelection __instance)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			if (!GameRoomModeState.IsCampaign)
			{
				return true;
			}
			try
			{
				((LevelSelector)__instance).levelType = (LevelType)2;
				AccessTools.Field(typeof(LevelSelection), "m_SelectedCampaignLevel")?.SetValue(__instance, CampaignPlayerDataHolder.SelectedCampaign);
				((Paginator)__instance).OpenPage();
			}
			catch
			{
			}
			return false;
		}

		private static void SpawnCampaignLevelCellPrefix(ref bool unlocked, ref bool newLevel)
		{
			if (GameRoomModeState.IsCampaign)
			{
				unlocked = true;
				newLevel = false;
			}
		}

		private static bool StartedPlayingNewCampaignPrefix(TABSCampaignAsset newCampaign, int startIndex)
		{
			if (!GameRoomModeState.IsCampaign || !BoltNetwork.IsRunning)
			{
				return true;
			}
			Bind(newCampaign, startIndex);
			return false;
		}

		private static bool LoadCampaignPrefix()
		{
			if (!GameRoomModeState.IsCampaign || !BoltNetwork.IsRunning)
			{
				return true;
			}
			if (BoltNetwork.IsServer)
			{
				HostLoadCurrentBoundLevel();
			}
			return false;
		}

		private static bool LoadCampaignLevelWithIndexPrefix(int index)
		{
			if (!GameRoomModeState.IsCampaign || !BoltNetwork.IsRunning)
			{
				return true;
			}
			if (BoltNetwork.IsServer)
			{
				HostLoadLevel(index);
			}
			return false;
		}

		private static bool LoadNextCampaignLevelPrefix()
		{
			if (!GameRoomModeState.IsCampaign || !BoltNetwork.IsRunning)
			{
				return true;
			}
			if (BoltNetwork.IsServer)
			{
				int num = GetBoundLevelIndex() + 1;
				TABSCampaignAsset selectedCampaign = CampaignPlayerDataHolder.SelectedCampaign;
				if (((selectedCampaign != null) ? selectedCampaign.LevelsInCampaign : null) != null && num < selectedCampaign.LevelsInCampaign.Length)
				{
					HostLoadLevel(num);
				}
			}
			return false;
		}

		private static void EnterPlacementStatePostfix(PlacementUI __instance)
		{
			if (GameRoomModeState.IsCampaign && !((Object)(object)__instance == (Object)null))
			{
				HideBluePlacementUi(__instance);
			}
		}

		private static void ShowUiPostfix(PlacementUI __instance)
		{
			if (GameRoomModeState.IsCampaign && !((Object)(object)__instance == (Object)null))
			{
				HideBluePlacementUi(__instance);
			}
		}

		private static void HideBluePlacementUi(PlacementUI ui)
		{
			try
			{
				object? obj = AccessTools.Field(typeof(PlacementUI), "blueMoney")?.GetValue(ui);
				Component val = (Component)((obj is Component) ? obj : null);
				if ((Object)(object)val != (Object)null)
				{
					val.gameObject.SetActive(false);
				}
				object? obj2 = AccessTools.Field(typeof(PlacementUI), "m_ClearBlueObject")?.GetValue(ui);
				GameObject val2 = (GameObject)((obj2 is GameObject) ? obj2 : null);
				if ((Object)(object)val2 != (Object)null)
				{
					val2.SetActive(false);
				}
			}
			catch
			{
			}
		}

		private static bool FactionBarSpawnPrefix(PlacementFactionBar __instance)
		{
			if (!GameRoomModeState.IsCampaign)
			{
				return true;
			}
			TABSCampaignLevelAsset val = TryGetBoundLevel();
			Faction[] array = null;
			if ((Object)(object)val != (Object)null && val.AllowedFactions != null && val.AllowedFactions.Length != 0)
			{
				array = val.AllowedFactions.Where((Faction f) => (Object)(object)f != (Object)null && f.Entity != null && (Object)(object)ContentDatabase.Instance().GetFaction(f.Entity.GUID) != (Object)null).ToArray();
			}
			if (array == null || array.Length == 0)
			{
				try
				{
					array = ServiceLocator.GetService<ISaveLoaderService>().GetFactionBar();
				}
				catch
				{
				}
			}
			if (array == null)
			{
				return true;
			}
			try
			{
				List<FactionButton> list = new List<FactionButton>();
				AccessTools.Field(typeof(PlacementFactionBar), "factionButtons")?.SetValue(__instance, list);
				int num = 0;
				Faction[] array2 = array;
				foreach (Faction val2 in array2)
				{
					if (!((Object)(object)val2 == (Object)null))
					{
						FactionButton val3 = __instance.SpawnFaction(val2, num);
						if ((Object)(object)val3 != (Object)null)
						{
							list.Add(val3);
						}
						num++;
					}
				}
				AccessTools.Method(typeof(PlacementFactionBar), "FixExpandButton", (Type[])null, (Type[])null)?.Invoke(__instance, new object[1] { false });
			}
			catch
			{
			}
			return false;
		}

		private static void SpawnFactionPostfix(Faction faction, FactionButton __result)
		{
			if (GameRoomModeState.IsCampaign && !((Object)(object)__result == (Object)null) && !((Object)(object)faction == (Object)null))
			{
				__result.SetUnlocked(IsCampaignFactionUnlocked(faction));
			}
		}

		internal static bool IsUnitAllowedOnBoundLevel(object unit)
		{
			object obj = TryGetBoundLevel();
			if (obj == null || unit == null)
			{
				return true;
			}
			try
			{
				return !(AccessTools.Method(obj.GetType(), "IsAllowed", (Type[])null, (Type[])null)?.Invoke(obj, new object[1] { unit }) is bool flag) || flag;
			}
			catch
			{
				return true;
			}
		}

		private static bool DrawFactionUnitPrefix(PlacementUI __instance, UnitBlueprint unit, bool secretUnlocked)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			if (!GameRoomModeState.IsCampaign || (Object)(object)__instance == (Object)null)
			{
				return true;
			}
			bool flag = secretUnlocked && IsUnitAllowedOnBoundLevel(unit);
			object? obj = AccessTools.Field(typeof(PlacementUI), "unitLayoutGroup")?.GetValue(__instance);
			object? obj2 = ((obj is UILayoutGroup) ? obj : null);
			if (obj2 != null)
			{
				((UILayoutGroup)obj2).AddElement(new UnitButtonData(unit, (IPlacementUI)(object)__instance, flag, !secretUnlocked));
			}
			return false;
		}

		private static bool AssignInitialUnitToBrushPrefix(PlacementUI __instance)
		{
			if (!GameRoomModeState.IsCampaign || (Object)(object)__instance == (Object)null)
			{
				return true;
			}
			try
			{
				object obj = TryGetBoundLevel();
				object obj2 = AccessTools.Field(typeof(PlacementUI), "m_unitDatabase")?.GetValue(__instance);
				object obj3 = AccessTools.Field(typeof(PlacementUI), "m_unitPlacementBrush")?.GetValue(__instance);
				object obj4 = AccessTools.Field(typeof(PlacementUI), "m_RadialMenu")?.GetValue(__instance);
				object obj5 = null;
				Array array = ((obj != null) ? (AccessTools.Field(obj.GetType(), "AllowedUnits")?.GetValue(obj) as Array) : null);
				if (array != null)
				{
					foreach (object item in array)
					{
						if (item != null)
						{
							obj5 = item;
							break;
						}
					}
				}
				if (obj5 == null && obj2 != null)
				{
					obj5 = AccessTools.Method(obj2.GetType(), "GetUserUnitBlueprintByExactName", (Type[])null, (Type[])null)?.Invoke(obj2, new object[1] { "UNIT_TRIBAL_CLUB" });
				}
				if (obj5 != null && obj3 != null)
				{
					object obj6 = AccessTools.Property(obj5.GetType(), "Entity")?.GetValue(obj5, null);
					object obj7 = ((obj6 == null) ? null : AccessTools.Property(obj6.GetType(), "GUID")?.GetValue(obj6, null));
					if (obj7 != null)
					{
						AccessTools.Method(obj3.GetType(), "SetBrushUnit", (Type[])null, (Type[])null)?.Invoke(obj3, new object[1] { obj7 });
					}
					if (obj4 != null)
					{
						AccessTools.Method(obj4.GetType(), "SetSelectedUnit", (Type[])null, (Type[])null)?.Invoke(obj4, new object[1] { obj5 });
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private static void BattleRadialButtonUpdateDataPostfix(object __instance)
		{
			if (!GameRoomModeState.IsCampaign || __instance == null)
			{
				return;
			}
			object obj = AccessTools.Property(__instance.GetType(), "CurrentData")?.GetValue(__instance, null);
			if (obj == null)
			{
				return;
			}
			if (obj != null && obj.GetType().Name == "UnitBlueprint")
			{
				bool flag = IsUnitAllowedOnBoundLevel(obj);
				object obj2 = AccessTools.Property(obj.GetType(), "IsSecret")?.GetValue(obj, null);
				if (obj2 is bool && (bool)obj2)
				{
					try
					{
						object obj3 = AccessTools.Property(obj.GetType(), "Entity")?.GetValue(obj, null);
						string text = ((obj3 != null) ? (AccessTools.Property(obj3.GetType(), "UnlockKey")?.GetValue(obj3, null) as string) : null);
						ISaveLoaderService service = ServiceLocator.GetService<ISaveLoaderService>();
						flag = flag && service != null && !string.IsNullOrEmpty(text) && service.HasUnlockedSecret(text);
					}
					catch
					{
					}
				}
				if (!flag)
				{
					AccessTools.Method(__instance.GetType(), "HideCostUI", (Type[])null, (Type[])null)?.Invoke(__instance, null);
				}
				AccessTools.Method(__instance.GetType(), "SetUnlockedState", (Type[])null, (Type[])null)?.Invoke(__instance, new object[1] { flag });
			}
			else
			{
				Faction val = (Faction)((obj is Faction) ? obj : null);
				if (val != null)
				{
					AccessTools.Method(__instance.GetType(), "SetUnlockedState", (Type[])null, (Type[])null)?.Invoke(__instance, new object[1] { IsCampaignFactionUnlocked(val) });
				}
			}
		}

		private static bool BuildCachesPrefix(object __instance)
		{
			if (!GameRoomModeState.IsCampaign || __instance == null || (Object)(object)TryGetBoundLevel() == (Object)null)
			{
				return true;
			}
			try
			{
				if (AccessTools.Field(typeof(BattleRadialMenu), "factionCache")?.GetValue(__instance) is List<IDatabaseEntity> list)
				{
					list.Clear();
				}
				if (AccessTools.Field(typeof(BattleRadialMenu), "addFactionsFactionCache")?.GetValue(__instance) is List<IDatabaseEntity> list2)
				{
					list2.Clear();
				}
				AccessTools.Method(typeof(BattleRadialMenu), "SetUpFactionsForCampaign", (Type[])null, (Type[])null)?.Invoke(__instance, null);
			}
			catch
			{
			}
			return false;
		}

		private static bool IsCampaignFactionUnlocked(Faction faction)
		{
			if ((Object)(object)faction == (Object)null)
			{
				return true;
			}
			try
			{
				GlobalSettingsHandler service = ServiceLocator.GetService<GlobalSettingsHandler>();
				SettingsInstance val = ((service != null) ? service.GetSettingsInstance("GAMEPLAY_RESTRICT_UNITS") : null);
				if (val != null && val.currentValue == 1)
				{
					return true;
				}
			}
			catch
			{
			}
			Array array = (AccessTools.Field(typeof(Faction), "Units")?.GetValue(faction) as Array) ?? (AccessTools.Property(typeof(Faction), "Units")?.GetValue(faction, null) as Array);
			if (array == null || array.Length == 0)
			{
				return true;
			}
			foreach (object item in array)
			{
				if (item != null && IsUnitAllowedOnBoundLevel(item))
				{
					return true;
				}
			}
			return false;
		}

		private static void OnEnterNewScenePostfix()
		{
			if (GameRoomModeState.IsCampaign)
			{
				TABSCampaignLevelAsset val = TryGetBoundLevel();
				if ((Object)(object)val != (Object)null)
				{
					SetLastLoadedLevel(val);
				}
				MarkSceneLoadedForBoundLevel();
			}
		}
	}
	internal class CampaignSelectionUI : MonoBehaviour
	{
		private class CampaignRow
		{
			public TABSCampaignAsset Asset;

			public Sprite Icon;
		}

		internal static CampaignSelectionUI Instance;

		private bool visible;

		private Vector2 scroll;

		private GUIStyle windowStyle;

		private GUIStyle labelStyle;

		private GUIStyle buttonStyle;

		private readonly List<CampaignRow> rows = new List<CampaignRow>();

		private Action<TABSCampaignAsset> onSelected;

		private Action onCancelled;

		public static void Ensure()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if (!((Object)(object)Instance != (Object)null))
			{
				GameObject val = new GameObject("Multiplayer16_CampaignSelectionUI");
				Object.DontDestroyOnLoad((Object)val);
				Instance = val.AddComponent<CampaignSelectionUI>();
			}
		}

		public void Show(Action<TABSCampaignAsset> selected, Action cancelled)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			onSelected = selected;
			onCancelled = cancelled;
			rows.Clear();
			List<TABSCampaignAsset> officialCampaigns = CampaignModeSystem.GetOfficialCampaigns();
			for (int i = 0; i < officialCampaigns.Count; i++)
			{
				if (!((Object)(object)officialCampaigns[i] == (Object)null))
				{
					rows.Add(new CampaignRow
					{
						Asset = officialCampaigns[i]
					});
				}
			}
			LoadIcons();
			visible = true;
			scroll = Vector2.zero;
		}

		private void LoadIcons()
		{
			for (int i = 0; i < rows.Count; i++)
			{
				int idx = i;
				CampaignRow campaignRow = rows[i];
				TABSCampaignAsset asset = campaignRow.Asset;
				if (((asset != null) ? asset.Entity : null) == null)
				{
					continue;
				}
				try
				{
					Sprite levelCellSpriteIcon = asset.Entity.LevelCellSpriteIcon;
					if ((Object)(object)levelCellSpriteIcon != (Object)null)
					{
						campaignRow.Icon = levelCellSpriteIcon;
					}
				}
				catch
				{
				}
				asset.Entity.GetSpriteIconAsync((Action<Sprite>)delegate(Sprite sprite)
				{
					if ((Object)(object)sprite != (Object)null && idx < rows.Count && (Object)(object)rows[idx].Icon == (Object)null)
					{
						rows[idx].Icon = sprite;
					}
				});
				try
				{
					Sprite campaignSprite = CampaignHandler.GetCampaignSprite(asset);
					if ((Object)(object)campaignSprite != (Object)null && (Object)(object)campaignRow.Icon == (Object)null)
					{
						campaignRow.Icon = campaignSprite;
					}
				}
				catch
				{
				}
				TABSCampaignLevelAsset[] levelsInCampaign = asset.LevelsInCampaign;
				if (!((Object)(object)campaignRow.Icon == (Object)null) || levelsInCampaign == null || levelsInCampaign.Length == 0)
				{
					continue;
				}
				TABSCampaignLevelAsset obj3 = levelsInCampaign[0];
				if (((obj3 != null) ? obj3.Entity : null) == null)
				{
					continue;
				}
				try
				{
					Sprite levelCellSpriteIcon2 = levelsInCampaign[0].Entity.LevelCellSpriteIcon;
					if ((Object)(object)levelCellSpriteIcon2 != (Object)null)
					{
						campaignRow.Icon = levelCellSpriteIcon2;
					}
				}
				catch
				{
				}
				levelsInCampaign[0].Entity.GetSpriteIconAsync((Action<Sprite>)delegate(Sprite sprite)
				{
					if ((Object)(object)sprite != (Object)null && idx < rows.Count && (Object)(object)rows[idx].Icon == (Object)null)
					{
						rows[idx].Icon = sprite;
					}
				});
			}
		}

		private void Update()
		{
			if (visible && Input.GetKeyDown((KeyCode)27))
			{
				visible = false;
				onCancelled?.Invoke();
			}
		}

		private void OnGUI()
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			if (visible)
			{
				EnsureStyles();
				Rect val = default(Rect);
				((Rect)(ref val))..ctor((float)(Screen.width / 2 - 400), (float)(Screen.height / 2 - 300), 800f, 600f);
				val = GUILayout.Window(12351, val, new WindowFunction(DrawWindow), ModL10n.T("select_official_campaign"), windowStyle ?? GUI.skin.window, Array.Empty<GUILayoutOption>());
			}
		}

		private void DrawWindow(int id)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			GUIStyle val = labelStyle ?? GUI.skin.label;
			GUIStyle val2 = buttonStyle ?? GUI.skin.button;
			GUILayout.Label(ModL10n.T("campaign_from_first"), val, Array.Empty<GUILayoutOption>());
			scroll = GUILayout.BeginScrollView(scroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(480f) });
			for (int i = 0; i < rows.Count; i++)
			{
				CampaignRow campaignRow = rows[i];
				TABSCampaignAsset val3 = campaignRow?.Asset;
				if (!((Object)(object)val3 == (Object)null))
				{
					string text = ((val3.Entity != null) ? val3.Entity.Name : ModL10n.T("campaign_fallback"));
					GUILayout.BeginHorizontal(GUIStyle.op_Implicit("box"), Array.Empty<GUILayoutOption>());
					if ((Object)(object)campaignRow.Icon != (Object)null && (Object)(object)campaignRow.Icon.texture != (Object)null)
					{
						GUILayout.Label((Texture)(object)campaignRow.Icon.texture, (GUILayoutOption[])(object)new GUILayoutOption[2]
						{
							GUILayout.Width(64f),
							GUILayout.Height(64f)
						});
					}
					else
					{
						GUILayout.Label("", (GUILayoutOption[])(object)new GUILayoutOption[2]
						{
							GUILayout.Width(64f),
							GUILayout.Height(64f)
						});
					}
					GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
					GUILayout.Label(text, val, Array.Empty<GUILayoutOption>());
					int num = ((val3.LevelsInCampaign != null) ? val3.LevelsInCampaign.Length : 0);
					GUILayout.Label(ModL10n.F("level_count", num), val, Array.Empty<GUILayoutOption>());
					GUILayout.EndVertical();
					GUILayout.FlexibleSpace();
					if (GUILayout.Button(ModL10n.T("select"), val2, (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.Width(80f),
						GUILayout.Height(64f)
					}))
					{
						visible = false;
						onSelected?.Invoke(val3);
						GUILayout.EndHorizontal();
						GUILayout.EndScrollView();
						return;
					}
					GUILayout.EndHorizontal();
					GUILayout.Space(5f);
				}
			}
			if (rows.Count == 0)
			{
				GUILayout.Label(ModL10n.T("no_campaigns"), val, Array.Empty<GUILayoutOption>());
			}
			GUILayout.EndScrollView();
			if (GUILayout.Button(ModL10n.T("cancel"), val2, Array.Empty<GUILayoutOption>()))
			{
				visible = false;
				onCancelled?.Invoke();
			}
			GUI.DragWindow();
		}

		private void EnsureStyles()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			if (windowStyle == null)
			{
				windowStyle = new GUIStyle(GUI.skin.window)
				{
					fontSize = 16
				};
				labelStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 14,
					wordWrap = true
				};
				buttonStyle = new GUIStyle(GUI.skin.button)
				{
					fontSize = 14
				};
			}
		}
	}
	internal static class CavalryPossessionPatches
	{
		internal const int MountLookForceWeapon = 123;

		internal const int MountDismountForceWeapon = 131;

		private const float MountLookSendInterval = 0.05f;

		private static Harmony _harmony;

		private static bool _applyingHostDismount;

		private static readonly HashSet<Mount> TrackedMounts = new HashSet<Mount>();

		private static readonly HashSet<int> LocalControlledMountIds = new HashSet<int>();

		private static readonly Dictionary<int, Unit> LocalRiderMounts = new Dictionary<int, Unit>();

		private static readonly HashSet<int> DismountHandledRiders = new HashSet<int>();

		private static readonly HashSet<int> ReleasedRiders = new HashSet<int>();

		private static readonly HashSet<int> ClientObserverRiders = new HashSet<int>();

		private static readonly Dictionary<int, Vector3> RemoteMountLook = new Dictionary<int, Vector3>();

		private static readonly Dictionary<int, Vector3> RemoteMountInput = new Dictionary<int, Vector3>();

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

		private static readonly HashSet<int> HostClientSteeredRiders = new HashSet<int>();

		private static readonly HashSet<int> SteeredMountIds = new HashSet<int>();

		private static readonly HashSet<int> SoftLinkArmedIds = new HashSet<int>();

		private static readonly Dictionary<int, List<Unit>> LocalRiderCluster = new Dictionary<int, List<Unit>>();

		private static readonly List<Unit> ClusterBuf = new List<Unit>(16);

		private static readonly List<Unit> PossessTargetBuf = new List<Unit>(16);

		private static readonly List<Unit> PossessableBuf = new List<Unit>(8);

		private static readonly List<Unit> UnlinkSnapshot = new List<Unit>(16);

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

		private static readonly HashSet<int> ClusterSeen = new HashSet<int>();

		private const float DismountSendInterval = 0.15f;

		private static readonly FieldInfo F_MountPos = AccessTools.Field(typeof(Mount), "myMountPos");

		private static readonly FieldInfo F_OUnitApi = AccessTools.Field(typeof(Mount), "o_unitApi");

		private static readonly FieldInfo F_InputChanged = AccessTools.Field(typeof(Mount), "inputChanged");

		private static readonly FieldInfo F_MountMove = AccessTools.Field(typeof(Mount), "mountMove");

		private static readonly FieldInfo F_RigHolder = AccessTools.Field(typeof(Mount), "rigHolder");

		private static readonly FieldInfo F_Joints = AccessTools.Field(typeof(Mount), "joints");

		private static readonly MethodInfo M_NetworkUnitSyncTransforms = AccessTools.Method(typeof(NetworkUnit), "SyncTransforms", new Type[1] { typeof(bool) }, (Type[])null);

		private static readonly MethodInfo M_MountFall = AccessTools.Method(typeof(Mount), "Fall", (Type[])null, (Type[])null);

		private static Unit _exitingRider;

		public static void ApplyPatches()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			//IL_00d6: Expected O, but got Unknown
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Expected O, but got Unknown
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Expected O, but got Unknown
			//IL_0172: Expected O, but got Unknown
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Expected O, but got Unknown
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Expected O, but got Unknown
			//IL_0226: Expected O, but got Unknown
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Expected O, but got Unknown
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Expected O, but got Unknown
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Expected O, but got Unknown
			//IL_0373: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Expected O, but got Unknown
			//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c7: Expected O, but got Unknown
			//IL_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_0420: Expected O, but got Unknown
			_harmony = new Harmony("Multiplayer16.CavalryPossession");
			MethodInfo methodInfo = AccessTools.Method(typeof(Mount), "EnterMount", new Type[3]
			{
				typeof(UnitBlueprint),
				typeof(Unit),
				typeof(int)
			}, (Type[])null);
			if (methodInfo != null)
			{
				_harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(CavalryPossessionPatches), "EnterMountPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo2 = AccessTools.Method(typeof(Mount), "Update", (Type[])null, (Type[])null);
			if (methodInfo2 != null)
			{
				_harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(CavalryPossessionPatches), "MountUpdatePrefix", (Type[])null), new HarmonyMethod(typeof(CavalryPossessionPatches), "MountUpdatePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo3 = AccessTools.Method(typeof(MovementHandler), "BatchedFixedUpdate", (Type[])null, (Type[])null);
			if (methodInfo3 != null)
			{
				_harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(typeof(CavalryPossessionPatches), "MovementHandlerFixedPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo4 = AccessTools.Method(typeof(Mount), "Fall", (Type[])null, (Type[])null);
			if (methodInfo4 != null)
			{
				_harmony.Patch((MethodBase)methodInfo4, new HarmonyMethod(typeof(CavalryPossessionPatches), "FallPrefix", (Type[])null), new HarmonyMethod(typeof(CavalryPossessionPatches), "FallPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo5 = AccessTools.Method(typeof(CameraAbilityPossess), "EnterUnit", new Type[1] { typeof(Unit) }, (Type[])null);
			if (methodInfo5 != null)
			{
				_harmony.Patch((MethodBase)methodInfo5, (HarmonyMethod)null, new HarmonyMethod(typeof(CavalryPossessionPatches), "EnterUnitPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo6 = AccessTools.Method(typeof(CameraAbilityPossess), "ExitUnit", (Type[])null, (Type[])null);
			if (methodInfo6 != null)
			{
				_harmony.Patch((MethodBase)methodInfo6, new HarmonyMethod(typeof(CavalryPossessionPatches), "ExitUnitPrefix", (Type[])null), new HarmonyMethod(typeof(CavalryPossessionPatches), "ExitUnitPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo7 = AccessTools.Method(typeof(NetworkUnit), "OnEnterPossession", (Type[])null, (Type[])null);
			if (methodInfo7 != null)
			{
				_harmony.Patch((MethodBase)methodInfo7, (HarmonyMethod)null, new HarmonyMethod(typeof(CavalryPossessionPatches), "NetworkUnitOnEnterPossessionPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo8 = AccessTools.Method(typeof(UnitAPI), "SetLookDirection", new Type[2]
			{
				typeof(Vector3),
				typeof(bool)
			}, (Type[])null);
			if (methodInfo8 != null)
			{
				_harmony.Patch((MethodBase)methodInfo8, new HarmonyMethod(typeof(CavalryPossessionPatches), "SetLookDirectionPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo9 = AccessTools.Method(typeof(UnitAPI), "SetMovementSpeed", new Type[2]
			{
				typeof(float),
				typeof(bool)
			}, (Type[])null);
			if (methodInfo9 != null)
			{
				_harmony.Patch((MethodBase)methodInfo9, new HarmonyMethod(typeof(CavalryPossessionPatches), "SetMovementSpeedPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo10 = AccessTools.Method(typeof(NetworkUnit), "UpdateLookDirection", (Type[])null, (Type[])null);
			if (methodInfo10 != null)
			{
				_harmony.Patch((MethodBase)methodInfo10, new HarmonyMethod(typeof(CavalryPossessionPatches), "UpdateLookDirectionPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo11 = AccessTools.Method(typeof(GeneralInput), "Update", (Type[])null, (Type[])null);
			if (methodInfo11 != null)
			{
				_harmony.Patch((MethodBase)methodInfo11, new HarmonyMethod(typeof(CavalryPossessionPatches), "GeneralInputUpdatePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo12 = AccessTools.Method(typeof(PossessedNetworkUnit), "OnEnterPossession", new Type[1] { typeof(Unit) }, (Type[])null);
			if (methodInfo12 != null)
			{
				_harmony.Patch((MethodBase)methodInfo12, (HarmonyMethod)null, new HarmonyMethod(typeof(CavalryPossessionPatches), "PossessedNetworkUnitEnterPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			Debug.Log((object)"[Multiplayer16] CavalryPossessionPatches: 已 Patch 骑兵坐骑附身朝向");
		}

		private static void PossessedNetworkUnitEnterPostfix(PossessedNetworkUnit __instance, Unit unit)
		{
			if ((Object)(object)__instance == (Object)null || !ShouldSkipPossessorPnuBind(unit))
			{
				return;
			}
			try
			{
				__instance.OnExitPossession(unit);
			}
			catch
			{
			}
		}

		private static void EnterMountPostfix(Mount __instance)
		{
			if ((Object)(object)__instance != (Object)null)
			{
				TrackedMounts.Add(__instance);
			}
			Unit val = (((Object)(object)__instance != (Object)null) ? ((Component)__instance).GetComponent<Unit>() : null);
			if ((Object)(object)val != (Object)null)
			{
				DismountHandledRiders.Remove(val.InstanceId);
				LastDismountSend.Remove(val.InstanceId);
				if ((Object)(object)__instance.OtherData != (Object)null && (Object)(object)__instance.OtherData.unit != (Object)null)
				{
					DismountHandledRiders.Remove(__instance.OtherData.unit.InstanceId);
				}
			}
			if (ShouldSkipPossessorPnuBind(val))
			{
				PossessionSync.UnbindPossessorPnu(val);
			}
		}

		private static void EnterUnitPostfix(Unit unitAPI)
		{
			if ((Object)(object)unitAPI != (Object)null)
			{
				DismountHandledRiders.Remove(unitAPI.InstanceId);
				ReleasedRiders.Remove(unitAPI.InstanceId);
			}
			DisableMountAiForRider(unitAPI);
			if (IsMountedOverrideRider(unitAPI) && IsLocallyPossessed(unitAPI))
			{
				GeneralInput componentInChildren = ((Component)unitAPI).GetComponentInChildren<GeneralInput>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					componentInChildren.AllowRotationChange = true;
					componentInChildren.hasControl = true;
				}
			}
			if (BoltNetwork.IsClient && !BoltNetwork.IsServer)
			{
				TakeLocalMountControl(unitAPI);
				LinkedPossessionSync.BeginClient(unitAPI);
			}
		}

		private static void ExitUnitPrefix(object __instance)
		{
			_exitingRider = null;
			if (__instance != null)
			{
				FieldInfo fieldInfo = AccessTools.Field(__instance.GetType(), "currentUnit");
				_exitingRider = (Unit)((fieldInfo != null) ? /*isinst with value type is only supported in some contexts*/: null);
			}
		}

		private static void ExitUnitPostfix()
		{
			LinkedPossessionSync.EndClient();
			ReleaseLocalMountControl(_exitingRider);
			RestoreAfterPossession(_exitingRider);
			_exitingRider = null;
		}

		private static void NetworkUnitOnEnterPossessionPostfix(NetworkUnit __instance)
		{
			Unit val = (((Object)(object)__instance != (Object)null) ? __instance.Unit : null);
			if ((Object)(object)val != (Object)null)
			{
				ReleasedRiders.Remove(val.InstanceId);
			}
			DisableMountAiForRider(val);
		}

		private static bool SetMovementSpeedPrefix(UnitAPI __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			Unit component = ((Component)__instance).GetComponent<Unit>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			if (IsPlayerSteeredMount(component))
			{
				return false;
			}
			if (IsMountedOverrideRider(component) && ShouldDrivePossessedMountLook(component))
			{
				return false;
			}
			if (IsUnpossessedOverrideMount(component))
			{
				return false;
			}
			return true;
		}

		private static void GeneralInputUpdatePrefix(GeneralInput __instance)
		{
			if ((Object)(object)__instance == (Object)null || !BoltNetwork.IsRunning)
			{
				return;
			}
			Unit val = null;
			try
			{
				DataHandler val2 = ((Component)__instance).GetComponent<DataHandler>();
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = ((Component)__instance).GetComponentInParent<DataHandler>();
				}
				val = (((Object)(object)val2 != (Object)null) ? val2.unit : null);
			}
			catch
			{
			}
			if ((Object)(object)val == (Object)null || IsLocallyPossessed(val))
			{
				return;
			}
			Unit riderFromMountUnit = GetRiderFromMountUnit(val);
			if (!((Object)(object)riderFromMountUnit != (Object)null) || !IsLocallyPossessed(riderFromMountUnit))
			{
				if (IsUnpossessedOverrideMount(val))
				{
					__instance.hasControl = false;
				}
				else if (IsPlayerSteeredMount(val) && !LocalControlledMountIds.Contains(val.InstanceId))
				{
					__instance.hasControl = false;
				}
				else if (IsMountedOverrideRider(val) && ShouldDrivePossessedMountLook(val) && !IsLocallyPossessed(val))
				{
					__instance.hasControl = false;
				}
			}
		}

		private static bool SetLookDirectionPrefix(UnitAPI __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			Unit component = ((Component)__instance).GetComponent<Unit>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			if (ReleasedRiders.Contains(component.InstanceId))
			{
				return true;
			}
			if (IsPlayerSteeredMount(component))
			{
				return false;
			}
			if (IsMountedOverrideRider(component) && ShouldDrivePossessedMountLook(component))
			{
				return false;
			}
			if (IsUnpossessedOverrideMount(component))
			{
				return false;
			}
			return true;
		}

		private static bool UpdateLookDirectionPrefix(NetworkUnit __instance)
		{
			Unit val = (((Object)(object)__instance != (Object)null) ? __instance.Unit : null);
			if ((Object)(object)val == (Object)null)
			{
				return true;
			}
			if (!IsMountOfPossessedRider(val))
			{
				return true;
			}
			return !ShouldDrivePossessedMountLook(GetRiderFromMountUnit(val));
		}

		private static bool ShouldDrivePossessedMountLook(Unit rider)
		{
			if ((Object)(object)rider == (Object)null)
			{
				return false;
			}
			if (ReleasedRiders.Contains(rider.InstanceId))
			{
				return false;
			}
			if (DismountHandledRiders.Contains(rider.InstanceId))
			{
				return false;
			}
			if (IsLocallyPossessed(rider))
			{
				Mount component = ((Component)rider).GetComponent<Mount>();
				if ((Object)(object)component != (Object)null && !component.IsMounted)
				{
					return false;
				}
				return true;
			}
			if (HostClientSteeredRiders.Contains(rider.InstanceId))
			{
				return true;
			}
			if (BoltNetwork.IsRunning && BoltNetwork.IsServer)
			{
				return PossessionSync.IsUnitPossessedByAnyone(rider);
			}
			return false;
		}

		private static bool FallPrefix(Mount __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			if (BoltNetwork.IsServer && __instance.IsMounted)
			{
				SnapshotUnlinkTargets(__instance);
			}
			if (_applyingHostDismount)
			{
				return true;
			}
			if (SoftLinkBroken(__instance))
			{
				return true;
			}
			if (!BoltNetwork.IsRunning || !BoltNetwork.IsClient || BoltNetwork.IsServer)
			{
				return true;
			}
			if (!__instance.IsMounted || !OverridesMountInput(__instance))
			{
				return true;
			}
			Unit component = ((Component)__instance).GetComponent<Unit>();
			if (!IsLocallyPossessed(component) && !IsObservingRemoteCavalry(component))
			{
				return true;
			}
			return false;
		}

		private static void FallPostfix(Mount __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && !__instance.IsMounted)
			{
				Unit component = ((Component)__instance).GetComponent<Unit>();
				if ((Object)(object)component != (Object)null)
				{
					SoftLinkArmedIds.Remove(component.InstanceId);
				}
				Unit mountUnit = (((Object)(object)__instance.OtherData != (Obj