Decompiled source of Online Mod Plus TABS v1.1.0
plugins\Online_Mod_Plus.dll
Decompiled 4 days ago
The result has been truncated due to the large size, download it to view full contents!
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 BepInEx.Bootstrap; using BitCode.UI; using DM; using GamepadUI.StateManager.Core; using HarmonyLib; using InControl; using Landfall.TABC; 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.TeamEdge; using Landfall.TABS.UnitPlacement; using Landfall.TABS.WinConditions; using Landfall.TABS.Workshop; using Landfall.TABS_Input; using Lilzalupa.FourTeams; using Microsoft.CodeAnalysis; using Mod_Name; using Photon.Bolt; using Photon.Bolt.Channel; using Photon.Bolt.Internal; using Photon.Bolt.Matchmaking; using Photon.Bolt.SceneManagement; using Photon.Bolt.Utils; using Photon.Realtime; using Steamworks; using TFBG; using TFBGames; using TMPro; using UIStateManager; using UdpKit; using UdpKit.Platform; using UdpKit.Platform.Photon; using Unity.Entities; 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: InternalsVisibleTo("MP16TestHarness")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("bolt")] [assembly: IgnoresAccessChecksTo("bolt.user")] [assembly: IgnoresAccessChecksTo("Foreign_forces")] [assembly: IgnoresAccessChecksTo("FourTeams")] [assembly: IgnoresAccessChecksTo("Photon3Unity3D")] [assembly: IgnoresAccessChecksTo("PhotonBolt")] [assembly: IgnoresAccessChecksTo("PhotonRealtime")] [assembly: IgnoresAccessChecksTo("udpkit.common")] [assembly: IgnoresAccessChecksTo("udpkit")] [assembly: IgnoresAccessChecksTo("udpkit.platform.photon")] [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 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; 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Expected O, but got Unknown //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Expected O, but got Unknown //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Expected O, but got Unknown //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Expected O, but got Unknown //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Expected O, but got Unknown _harmony = new Harmony("Multiplayer16.BattleRestart"); _harmony.Patch((MethodBase)AccessTools.Method(typeof(OnlineMultiplayerGameMode), "RequestEndBattle", (Type[])null, (Type[])null), new HarmonyMethod(typeof(BattleRestartPatches), "RequestEndBattlePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.Patch((MethodBase)AccessTools.Method(typeof(OnlineMultiplayerGameMode), "BeginEndingMatch", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(BattleRestartPatches), "BeginEndingMatchPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.Patch((MethodBase)AccessTools.Method(typeof(OnlineMultiplayerGameMode), "OnCountDownTimerEnded", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(BattleRestartPatches), "OnCountDownTimerEndedPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.Patch((MethodBase)AccessTools.Method(typeof(NetworkBattleController), "SetReadyForPlacement", (Type[])null, (Type[])null), new HarmonyMethod(typeof(BattleRestartPatches), "SetReadyForPlacementPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.Patch((MethodBase)AccessTools.Method(typeof(NetworkBattleController), "ServerStartPlacement", (Type[])null, (Type[])null), new HarmonyMethod(typeof(BattleRestartPatches), "ServerStartPlacementPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.Patch((MethodBase)AccessTools.Method(typeof(OnlineMultiplayerGameMode), "OnEnterPlacementState", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(BattleRestartPatches), "OnlineOnEnterPlacementStatePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.Patch((MethodBase)AccessTools.Method(typeof(NetworkBattleController), "OnEvent", new Type[1] { typeof(StartPlacementEvent) }, (Type[])null), new HarmonyMethod(typeof(BattleRestartPatches), "OnEventStartPlacementPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.Patch((MethodBase)AccessTools.Method(typeof(BaseGameMode), "OnEnterPlacementState", (Type[])null, (Type[])null), new HarmonyMethod(typeof(BattleRestartPatches), "OnEnterPlacementStatePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Debug.Log((object)"[Multiplayer16] BattleRestartPatches: 主机控制战斗结束与返回放置"); } private static bool RequestEndBattlePrefix(OnlineMultiplayerGameMode __instance) { if (BoltNetwork.IsClient && !BoltNetwork.IsServer) { return false; } if (!BoltNetwork.IsServer) { return true; } if (IsBattleInProgress(__instance)) { if (!_restartConfirmOpen) { ShowRestartConfirm(__instance); } return false; } ContinueAfterMatch(__instance); return false; } private static void ContinueAfterMatch(OnlineMultiplayerGameMode gameMode) { if (!CampaignModeSystem.TryHostContinueAfterWin(gameMode)) { HostReturnToPlacement(gameMode); } } private static bool IsBattleInProgress(OnlineMultiplayerGameMode gameMode) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 if (gameMode != null && !((BaseGameMode)gameMode).MatchOver) { GameStateManager service = ServiceLocator.GetService<GameStateManager>(); if (service == null) { return false; } return (int)service.GameState == 1; } return false; } private static void ShowRestartConfirm(OnlineMultiplayerGameMode gameMode) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //IL_005e: 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) //IL_0069: 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; string text = ModL10n.T("restart_battle_confirm"); 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, text, val, (UnityAction)obj, new string[2] { ModL10n.T("yes"), ModL10n.T("no") }); } catch (Exception ex) { _restartConfirmOpen = false; Debug.LogWarning((object)("[Multiplayer16] 重启确认弹窗失败: " + ex.Message)); HostReturnToPlacement(gameMode); } } private static void CloseRestartConfirmIfOpen() { if (_restartConfirmOpen) { _restartConfirmOpen = false; ModalPanel service = ServiceLocator.GetService<ModalPanel>(); if (service != null) { service.ForcePopUpClose(); } } } private static void BeginEndingMatchPostfix(Team winningTeam) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) CampaignModeSystem.NotifyWinner(winningTeam); } private static void OnCountDownTimerEndedPostfix(OnlineMultiplayerGameMode __instance) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 if (BoltNetwork.IsRunning && BoltNetwork.IsServer && __instance != null && ((BaseGameMode)__instance).MatchOver) { GameStateManager service = ServiceLocator.GetService<GameStateManager>(); if (service != null && (int)service.GameState == 1) { ContinueAfterMatch(__instance); } } } private static bool SetReadyForPlacementPrefix() { return !BoltNetwork.IsRunning; } private static bool ServerStartPlacementPrefix() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 if (!BoltNetwork.IsRunning) { return true; } GameStateManager service = ServiceLocator.GetService<GameStateManager>(); if (service == null) { return true; } return (int)service.GameState > 0; } private static void OnlineOnEnterPlacementStatePostfix() { if (ShouldFastReturnFromBattle()) { RestoreTimeImmediate(); } } private static bool ShouldFastReturnFromBattle() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 if (IsOnlineClient()) { GameStateManager service = ServiceLocator.GetService<GameStateManager>(); if (service == null) { return false; } return (int)service.PreviousGameState == 1; } return false; } private static void RestoreTimeImmediate() { ITimeService service = ServiceLocator.GetService<ITimeService>(); if (service != null) { service.Unlock(); service.UnPause(); service.SetState(1f, 0f, true); } BoltRuntimeSettings.instance.overrideTimeScale = true; } private static void ResetCountdown() { CountdownTimerService service = ServiceLocator.GetService<CountdownTimerService>(); if ((Object)(object)service != (Object)null) { service.countingDown = false; service.canCountDown = true; service.elapsedTime = 0f; service.timeLeft = 0f; } } 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) { CleanupBattleEndForReturnToPlacement(gameMode); if (service != null) { service.EnterPlacementState(); } ((Event)StartPlacementEvent.Create((GlobalTargets)4, (ReliabilityModes)2)).Send(); } } internal static void CleanupBattleEndForReturnToPlacement(OnlineMultiplayerGameMode gameMode) { //IL_004a: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Invalid comparison between Unknown and I4 //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Invalid comparison between Unknown and I4 if (gameMode == null) { return; } gameMode.Unsubscribe(); ResetCountdown(); ((BaseGameMode)gameMode).MatchOver = false; VerticalCurtainController curtainController = ((BaseGameMode)gameMode).CurtainController; if (curtainController != null) { curtainController.OpenCurtains(); } gameMode.SetTimeToPaused(false); RestoreTimeImmediate(); NetworkBattleController service = ServiceLocator.GetService<NetworkBattleController>(); if ((Object)(object)service != (Object)null) { service.m_battleStarted = false; NetworkGamePhase phase = service.Phase; if ((int)phase == 4 || (int)phase == 5) { service.SetPhase((NetworkGamePhase)1); } } } private static void OnEventStartPlacementPrefix() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Invalid comparison between Unknown and I4 if (!IsOnlineClient()) { return; } 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(); } } } private static bool OnEnterPlacementStatePrefix(BaseGameMode __instance) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (!ShouldFastReturnFromBattle() || !(__instance is OnlineMultiplayerGameMode)) { return true; } Debug.Log((object)"[Multiplayer16] 客机自战斗返回放置: 跳过 TaskSequencer"); TeamLayouts teamLayouts = __instance.TeamLayouts; if (teamLayouts != null) { foreach (Team item in teamLayouts.m_layouts.Keys.ToList()) { teamLayouts.ClearTeamLayout(item, true); } } __instance.ResetMatchVariables(); BattleBudget battleBudget = __instance.BattleBudget; if (battleBudget != null) { battleBudget.ResetBudgetAll(); } UnitPlacementBrush brush = __instance.Brush; if (brush != null) { brush.OnEnterPlacementState(); } return false; } private static bool IsOnlineClient() { if (BoltNetwork.IsRunning && BoltNetwork.IsClient) { return !BoltNetwork.IsServer; } return false; } private static void ForceSnapPlacementCamera() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) SandboxPlacementCamera val = Object.FindObjectOfType<SandboxPlacementCamera>(); if (!((Object)(object)val == (Object)null)) { ((MonoBehaviour)val).StopAllCoroutines(); val.m_isGoingToPos = false; val.IsResettingRotation = false; if (val.IsInFreeLook()) { val.ExitFreeLook(); val.m_isGoingToPos = false; ((Component)val).transform.position = val.cameraPlacementStartPosition; } } } } 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_0053: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_012c: 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, (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, (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, (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, (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_004b: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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, (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, (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; } Unit[] array2 = array; foreach (Unit val in array2) { 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: 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, (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, (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, (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); } PlayerTeamMapping.RegisterPlayer(connection); RoomPasswordSystem.SendMapStartToConnectionIfNeeded(connection); PossessionSync.OnClientConnected(connection); } private static bool VerifyAndAcceptConnection(BoltConnection connection) { try { UdpSession currentSession = BoltMatchmaking.CurrentSession; if (currentSession == null || !(currentSession is 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); NetworkBattleControllerPatches.OnPlayerDisconnected(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_004b: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Expected O, but got Unknown //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0141: 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, (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, (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, (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, (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 { __instance.ShowCenterMessage(false, (string)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 int _lastSceneLoadedLevelIndex = int.MinValue; public static bool HasBoundCampaign { get { if ((Object)(object)CampaignPlayerDataHolder.SelectedCampaign != (Object)null) { return GameRoomModeState.IsCampaign; } return false; } } private static HarmonyMethod Hook(string name) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown return new HarmonyMethod(typeof(CampaignModeSystem), name, (Type[])null); } 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 _harmony = new Harmony("Multiplayer16.CampaignMode"); _harmony.Patch((MethodBase)AccessTools.Method(typeof(UIMapSelector), "Start", (Type[])null, (Type[])null), (HarmonyMethod)null, Hook("UiMapSelectorStartPostfix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.Patch((MethodBase)AccessTools.Method(typeof(MapSelectionCanvas), "GetGameModeUI", (Type[])null, (Type[])null), Hook("GetGameModeUiPrefix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.Patch((MethodBase)AccessTools.Method(typeof(LevelSelection), "SetLevelGridForCurrentGameType", (Type[])null, (Type[])null), Hook("SetLevelGridPrefix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.Patch((MethodBase)AccessTools.Method(typeof(LevelSelection), "SpawnCampaignLevelCell", (Type[])null, (Type[])null), Hook("SpawnCampaignLevelCellPrefix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.Patch((MethodBase)AccessTools.Method(typeof(CampaignPlayerDataHolder), "StartedPlayingNewCampaign", (Type[])null, (Type[])null), Hook("StartedPlayingNewCampaignPrefix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.Patch((MethodBase)AccessTools.Method(typeof(TABSSceneManager), "LoadCampaign", (Type[])null, (Type[])null), Hook("LoadCampaignPrefix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.Patch((MethodBase)AccessTools.Method(typeof(CampaignPlayerDataHolder), "LoadCampaignLevelWithIndex", (Type[])null, (Type[])null), Hook("LoadCampaignLevelWithIndexPrefix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.Patch((MethodBase)AccessTools.Method(typeof(CampaignPlayerDataHolder), "LoadNextCampaignLevel", (Type[])null, (Type[])null), Hook("LoadNextCampaignLevelPrefix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.Patch((MethodBase)AccessTools.Method(typeof(PlacementUI), "EnterPlacementState", (Type[])null, (Type[])null), (HarmonyMethod)null, Hook("EnterPlacementStatePostfix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.Patch((MethodBase)AccessTools.Method(typeof(PlacementUI), "ShowUI", (Type[])null, (Type[])null), (HarmonyMethod)null, Hook("ShowUiPostfix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.Patch((MethodBase)AccessTools.Method(typeof(PlacementFactionBar), "Spawn", Type.EmptyTypes, (Type[])null), Hook("FactionBarSpawnPrefix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.Patch((MethodBase)AccessTools.Method(typeof(PlacementFactionBar), "SpawnFaction", (Type[])null, (Type[])null), (HarmonyMethod)null, Hook("SpawnFactionPostfix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.Patch((MethodBase)AccessTools.Method(typeof(PlacementUI), "DrawFactionUnit", new Type[2] { typeof(UnitBlueprint), typeof(bool) }, (Type[])null), Hook("DrawFactionUnitPrefix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.Patch((MethodBase)AccessTools.Method(typeof(PlacementUI), "AssignInitialUnitToBrush", (Type[])null, (Type[])null), Hook("AssignInitialUnitToBrushPrefix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.Patch((MethodBase)AccessTools.Method(typeof(BattleRadialButton), "UpdateData", (Type[])null, (Type[])null), (HarmonyMethod)null, Hook("BattleRadialButtonUpdateDataPostfix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.Patch((MethodBase)AccessTools.Method(typeof(BattleRadialMenu), "BuildCaches", (Type[])null, (Type[])null), Hook("BuildCachesPrefix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.Patch((MethodBase)AccessTools.Method(typeof(OnlineMultiplayerGameMode), "OnEnterNewScene", (Type[])null, (Type[])null), (HarmonyMethod)null, Hook("OnEnterNewScenePostfix"), (HarmonyMethod)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; } CampaignPlayerDataHolder.SelectedCampaign = campaign; CampaignPlayerDataHolder._LevelIndex = levelIndex; CampaignPlayerDataHolder.AutoLoadNextLevel = true; SetLastLoadedLevel(levelsInCampaign[levelIndex]); } } public static void SetLastLoadedLevel(TABSCampaignLevelAsset level) { CampaignHandler.LastLoadedLevel = 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_0038: 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() { return CampaignPlayerDataHolder._LevelIndex; } 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; __instance.m_SelectedCampaignLevel = 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 { if ((Object)(object)ui.blueMoney != (Object)null) { ((Component)ui.blueMoney).gameObject.SetActive(false); } if ((Object)(object)ui.m_ClearBlueObject != (Object)null) { ui.m_ClearBlueObject.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 = (__instance.factionButtons = new List<FactionButton>()); 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++; } } __instance.FixExpandButton(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(UnitBlueprint unit) { TABSCampaignLevelAsset val = TryGetBoundLevel(); if ((Object)(object)val == (Object)null || (Object)(object)unit == (Object)null) { return true; } try { return val.IsAllowed(unit); } catch { return true; } } private static bool DrawFactionUnitPrefix(PlacementUI __instance, UnitBlueprint unit, bool secretUnlocked) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown if (!GameRoomModeState.IsCampaign || (Object)(object)__instance == (Object)null) { return true; } bool flag = secretUnlocked && IsUnitAllowedOnBoundLevel(unit); UILayoutGroup unitLayoutGroup = __instance.unitLayoutGroup; if (unitLayoutGroup != null) { unitLayoutGroup.AddElement(new UnitButtonData(unit, (IPlacementUI)(object)__instance, flag, !secretUnlocked)); } return false; } private static bool AssignInitialUnitToBrushPrefix(PlacementUI __instance) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) if (!GameRoomModeState.IsCampaign || (Object)(object)__instance == (Object)null) { return true; } try { object obj = TryGetBoundLevel()?.AllowedUnits?.FirstOrDefault((Func<UnitBlueprint, bool>)((UnitBlueprint u) => (Object)(object)u != (Object)null)); if (obj == null) { ContentDatabase unitDatabase = __instance.m_unitDatabase; obj = ((unitDatabase != null) ? unitDatabase.GetUserUnitBlueprintByExactName("UNIT_TRIBAL_CLUB") : null); } UnitBlueprint val = (UnitBlueprint)obj; if ((Object)(object)val != (Object)null && __instance.m_unitPlacementBrush != null) { if (val.Entity != null) { __instance.m_unitPlacementBrush.SetBrushUnit(val.Entity.GUID); } BattleRadialMenu radialMenu = __instance.m_RadialMenu; if (radialMenu != null) { radialMenu.SetSelectedUnit(val); } } } catch { } return false; } private static void BattleRadialButtonUpdateDataPostfix(BattleRadialButton __instance) { if (!GameRoomModeState.IsCampaign || (Object)(object)__instance == (Object)null) { return; } IDatabaseEntity currentData = __instance.CurrentData; UnitBlueprint val = (UnitBlueprint)(object)((currentData is UnitBlueprint) ? currentData : null); if (val != null) { bool flag = IsUnitAllowedOnBoundLevel(val); if (val.IsSecret) { try { DatabaseEntity entity = val.Entity; string text = ((entity != null) ? entity.UnlockKey : null); ISaveLoaderService service = ServiceLocator.GetService<ISaveLoaderService>(); flag = flag && service != null && !string.IsNullOrEmpty(text) && service.HasUnlockedSecret(text); } catch { } } if (!flag) { __instance.HideCostUI(); } __instance.SetUnlockedState(flag); } else { IDatabaseEntity currentData2 = __instance.CurrentData; Faction val2 = (Faction)(object)((currentData2 is Faction) ? currentData2 : null); if (val2 != null) { __instance.SetUnlockedState(IsCampaignFactionUnlocked(val2)); } } } private static bool BuildCachesPrefix(BattleRadialMenu __instance) { if (!GameRoomModeState.IsCampaign || (Object)(object)__instance == (Object)null || (Object)(object)TryGetBoundLevel() == (Object)null) { return true; } try { __instance.factionCache?.Clear(); __instance.addFactionsFactionCache?.Clear(); __instance.SetUpFactionsForCampaign(); } 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 { } UnitBlueprint[] units = faction.Units; if (units == null || units.Length == 0) { return true; } return units.Any((UnitBlueprint u) => (Object)(object)u != (Object)null && IsUnitAllowedOnBoundLevel(u)); } 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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) 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_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_0025: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_0054: 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_0066: 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 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_007f: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown //IL_00d8: Expected O, but got Unknown //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Expected O, but got Unknown //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Expected O, but got Unknown //IL_0176: Expected O, but got Unknown //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Expected O, but got Unknown //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Expected O, but got Unknown //IL_022c: Expected O, but got Unknown //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Expected O, but got Unknown //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Expected O, but got Unknown //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Expected O, but got Unknown //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Expected O, but got Unknown //IL_03c4: Unknown result type (might be due to invalid IL or missing references) //IL_03d2: Expected O, but got Unknown //IL_041f: Unknown result type (might be due to invalid IL or missing references) //IL_042c: 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, (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, (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, (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, (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, (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, (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, (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, (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, (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, (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, (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, (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(CameraAbilityPossess __instance) { _exitingRider = __instance?.currentUnit; } 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 != (Object)null) ? __instance.OtherData.unit : null); HandlePossessedDismount(component, mountUnit); if (BoltNetwork.IsServer) { SendHostDismountToClients(component, mountUnit); } else if (BoltNetwork.IsClient && !_applyingHostDismount) { SendDismountToHost(component, mountUnit); } } } private static bool IsPlayerControlledCavalry(Unit rider) { if ((Object)(object)rider == (Object)null) { return false; } if (ReleasedRiders.Contains(rider.InstanceId)) { return false; } if (ShouldDrivePossessedMountLook(rider)) { return true; } if (IsObservingRemoteCavalry(rider)) { return true; } if (BoltNetwork.IsRunning) { return PossessionSync.IsUnitPossessedByAnyone(rider); } return false; } private static bool IsUnpossessedOverrideMount(Unit mountUnit) { if ((Object)(object)mountUnit == (Object)null) { return false; } Mount mountForUnit = GetMountForUnit(mountUnit); if ((Object)(object)mountForUnit == (Object)null || !mountForUnit.IsMounted || !OverridesMountInput(mountForUnit)) { return false; } return !IsPlayerControlledCavalry(((Component)mountForUnit).GetComponent<Unit>()); } private static bool IsPlayerPossessedUnit(Unit unit) { if ((Object)(object)unit == (Object)null) { return false; } try { if ((Object)(object)unit.api != (Object)null && unit.api.IsPossessed) { return true; } } catch { } if (!PossessionSync.IsUnitPossessedByLocalPlayer(unit)) { return PossessionSync.IsUnitPossessedByAnyone(unit); } return true; } private static bool IsOtherPossessedUnit(Unit unit, Unit subject) { if (!IsPlayerPossessedUnit(unit)) { return false; } if ((Object)(object)subject == (Object)null) { return true; } if (unit.InstanceId == subject.InstanceId) { return false; } if (unit.RemoteInstanceId != 0 && unit.RemoteInstanceId == subject.InstanceId) { return false; } if (subject.RemoteInstanceId != 0 && subject.RemoteInstanceId == unit.InstanceId) { return false; } return true; } private static void RestoreMountMovementAi(Mount mount) { //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)mount == (Object)null || !mount.IsMounted || IsOtherPossessedUnit(((Object)(object)mount.OtherData != (Object)null) ? mount.OtherData.unit : null, null)) { return; } UnitAPI mountApi = GetMountApi(mount); if ((Object)(object)mountApi != (Object)null) { if (IsOtherPossessedUnit(((Component)mountApi).GetComponent<Unit>(), null)) { return; } if (!mountApi.IsPossessed) { mountApi.SetIsRemotelyControlled(false); mountApi.SetActive(true, (bool?)false); } } if ((Object)(object)mount.OtherData != (Object)null && (Object)(object)mount.OtherData.input != (Object)null) { mount.OtherData.input.hasControl = false; if (OverridesMountInput(mount)) { mount.OtherData.input.inputDirection = Vector3.forward; } } } private static void MountUpdatePrefix(Mount __instance) { if ((Object)(object)__instance == (Object)null || !__instance.IsMounted) { return; } ArmSoftLinkIfNeeded(__instance); if (SoftLinkBroken(__instance)) { TryFallFromSoftLink(__instance); return; } Unit component = ((Component)__instance).GetComponent<Unit>(); if (!IsPlayerControlledCavalry(component)) { Unit val = (((Object)(object)__instance.OtherData != (Object)null) ? __instance.OtherData.unit : null); if (!IsPlayerSteeredMount(val) && !IsOtherPossessedUnit(val, component) && OverridesMountInput(__instance)) { RestoreMountMovementAi(__instance); } } } private static void MountUpdatePostfix(Mount __instance) { //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Invalid comparison between Unknown and I4 //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return; } if (!__instance.IsMounted) { Unit component = ((Component)__instance).GetComponent<Unit>(); if ((Object)(object)component != (Object)null) { HandlePossessedDismount(component, ((Object)(object)__instance.OtherData != (Object)null) ? __instance.OtherData.unit : null); } } else { if (!OverridesMountInput(__instance)) { return; } Unit component2 = ((Component)__instance).GetComponent<Unit>(); DataHandler otherData = __instance.OtherData; if ((Object)(object)component2 == (Object)null || (Object)(object)otherData == (Object)null || (Object)(object)otherData.input == (Object)null) { return; } if (!IsPlayerControlledCavalry(component2)) { Unit unit = otherData.unit; if (IsOtherPossessedUnit(unit, component2)) { return; } if (IsPlayerSteeredMount(unit)) { Unit val = ResolvePossessedRider(unit); if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)component2) { Vector3 desired = Vector3.zero; if (!TryGetRemoteMountLook(val, out desired) && IsLocallyPossessed(val) && TryGetLocalLookRotation(out var look)) { desired = look * Vector3.forward; } SteerCavalryCluster(val, desired, ((Component)val).GetComponentInChildren<GeneralInput>()); } } else { RestoreMountMovementAi(__instance); } return; } if (IsObservingRemoteCavalry(component2)) { ApplyObservedPossessionAiOff(component2); return; } if (!ShouldDrivePossessedMountLook(component2)) { if (BoltNetwork.IsServer && PossessionSync.IsUnitPossessedByAnyone(component2)) { DisableMountAi(__instance); } return; } GameStateManager service = ServiceLocator.GetService<GameStateManager>(); if (service != null && (int)service.GameState != 1) { return; } DisableMountAi(__instance); if (IsLocallyPossessed(component2)) { LockPossessedMountJoints(__instance); } if (BoltNetwork.IsServer) { if ((Object)(object)component2.data?.mainRig != (Object)null) { component2.data.mainRig.isKinematic = false; } if ((Object)(object)otherData.mainRig != (Object)null) { otherData.mainRig.isKinematic = false; } } GeneralInput componentInChildren = ((Component)component2).GetComponentInChildren<GeneralInput>(); if ((Object)(object)componentInChildren != (Object)null && IsLocallyPossessed(component2)) { componentInChildren.AllowRotationChange = true; } bool flag = false; Vector3 desired2; if (IsLocallyPossessed(component2) && TryGetLocalLookRotation(out var look2)) { desired2 = look2 * Vector3.forward; SendMountControlToHost(component2, desired2, ((Object)(object)componentInChildren != (Object)null) ? componentInChildren.inputDirection : Vector3.zero); flag = true; } else { flag = TryGetRemoteMountLook(component2, out desired2); } if (flag) { desired2.y = 0f; if (((Vector3)(ref desired2)).sqrMagnitude > 0.0001f) { ((Vector3)(ref desired2)).Normalize(); Quaternion rotation = Quaternion.LookRotation(desired2); if ((Object)(object)otherData.input.Direction != (Object)null) { otherData.input.Direction.rotation = rotation; } if ((Object)(object)otherData.characterForwardObject != (Object)null) { otherData.characterForwardObject.rotation = rotation; } otherData.lookDirectionIntent = desired2; if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.Direction != (Object)null) { componentInChildren.Direction.rotation = rotation; } if ((Object)(object)component2.data != (Object)null) { component2.data.lookDirectionIntent = desired2; if ((Object)(object)component2.data.characterForwardObject != (Object)null) { component2.data.characterForwardObject.rotation = rotation; } } } } KeepMountInput(otherData, component2); ApplyPossessedMountMove(otherData, component2, componentInChildren, GetMountPos(__instance)); SteerCavalryCluster(component2, flag ? desired2 : Vector3.zero, componentInChildren); } } private static bool MovementHandlerFixedPrefix(MovementHandler __instance) { if (!BoltNetwork.IsRunning || (Object)(object)__instance == (Object)null) { return true; } DataHandler val = null; try { val = ((Component)__instance).GetComponent<DataHandler>(); } catch { } if ((Object)(object)val?.unit == (Object)null || (Object)(object)val.input == (Object)null) { return true; } if (!IsChargeMountBody(val.unit) && !IsPlayerSteeredMount(val.unit)) { return true; } if (!IsPossessedChargeMount(val.unit) && !IsPlayerSteeredMount(val.unit)) { return true; } Unit val2 = GetRiderFromMountUnit(val.unit) ?? ResolvePossessedRider(val.unit); if ((Object)(object)val2 != (Object)null && IsObservingRemoteCavalry(val2)) { return true; } if (!ShouldDrivePossessedMountLook(val2) && !IsLocallyControlledMount(val.unit) && !IsPlayerSteeredMount(val.unit)) { return true; } KeepMountInput(val, val2); return true; } internal static Unit GetMountUnitFromRider(Unit rider) { if ((Object)(object)rider == (Object)null) { return null; } if (LocalRiderMounts.TryGetValue(rider.InstanceId, out var value) && (Object)(object)value != (Object)null) { return value; } Mount component = ((Component)rider).GetComponent<Mount>(); if ((Object)(object)component != (Object)null && (Object)(object)component.OtherData != (Object)null && (Object)(object)component.OtherData.unit != (Object)null) { return component.OtherData.