From c272fbfb9728b957b33df26f407d62779cd50613 Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Fri, 10 May 2024 16:12:11 +0200 Subject: [PATCH] Improve patch and allow metabolism disable - Host can now disable metabolism if they wish --- .../OfflineRaidSettingsMenuPatchOverride.cs | 7 +++- Fika.Core/Coop/GameMode/CoopGame.cs | 18 ++++++++- ...arkovApplication_LocalGameCreator_Patch.cs | 37 +++++++++++++------ .../MatchmakerAcceptScreenShowPatch.cs | 6 +-- .../Coop/PacketHandlers/ClientPacketSender.cs | 9 +++++ Fika.Core/Networking/FikaClient.cs | 13 +++++++ Fika.Core/Networking/FikaServer.cs | 18 +++++++++ .../Packets/Backend/SessionSettingsPacket.cs | 28 ++++++++++++++ 8 files changed, 118 insertions(+), 18 deletions(-) create mode 100644 Fika.Core/Networking/Packets/Backend/SessionSettingsPacket.cs diff --git a/Fika.Core/AkiSupport/Overrides/OfflineRaidSettingsMenuPatchOverride.cs b/Fika.Core/AkiSupport/Overrides/OfflineRaidSettingsMenuPatchOverride.cs index 94e82dc7..45bb41d5 100644 --- a/Fika.Core/AkiSupport/Overrides/OfflineRaidSettingsMenuPatchOverride.cs +++ b/Fika.Core/AkiSupport/Overrides/OfflineRaidSettingsMenuPatchOverride.cs @@ -21,7 +21,7 @@ protected override MethodBase GetTargetMethod() [PatchPostfix] private static void PatchPostfix(RaidSettingsWindow __instance, UiElementBlocker ____coopModeBlocker, List ____weatherCanvasGroups, - UpdatableToggle ____randomTimeToggle, UpdatableToggle ____randomWeatherToggle) + UpdatableToggle ____randomTimeToggle, UpdatableToggle ____randomWeatherToggle, List ____waterAndFoodCanvasGroups) { // Always disable the Coop Mode checkbox ____coopModeBlocker.SetBlock(true, "Co-op is always enabled in Fika"); @@ -31,6 +31,11 @@ private static void PatchPostfix(RaidSettingsWindow __instance, UiElementBlocker weatherCanvasGroups = ____weatherCanvasGroups; } + foreach (CanvasGroup canvasGroup in ____waterAndFoodCanvasGroups) + { + canvasGroup.SetUnlockStatus(true, true); + } + instance = __instance; ____randomWeatherToggle.Bind(new Action(ToggleWeather)); diff --git a/Fika.Core/Coop/GameMode/CoopGame.cs b/Fika.Core/Coop/GameMode/CoopGame.cs index 45e49632..36640187 100644 --- a/Fika.Core/Coop/GameMode/CoopGame.cs +++ b/Fika.Core/Coop/GameMode/CoopGame.cs @@ -56,6 +56,8 @@ internal sealed class CoopGame : BaseLocalGame, IBotGame, IFika private CoopExfilManager exfilManager; private GameObject fikaStartButton; + public RaidSettings RaidSettings { get; private set; } + //WildSpawnType for sptUsec and sptBear const int sptUsecValue = 47; const int sptBearValue = 48; @@ -91,7 +93,8 @@ public IWeatherCurve WeatherCurve internal static CoopGame Create(InputTree inputTree, Profile profile, GameDateTime backendDateTime, InsuranceCompanyClass insurance, MenuUI menuUI, CommonUI commonUI, PreloaderUI preloaderUI, GameUI gameUI, LocationSettingsClass.Location location, TimeAndWeatherSettings timeAndWeather, - WavesSettings wavesSettings, EDateTime dateTime, Callback callback, float fixedDeltaTime, EUpdateQueue updateQueue, ISession backEndSession, TimeSpan sessionTime) + WavesSettings wavesSettings, EDateTime dateTime, Callback callback, float fixedDeltaTime, EUpdateQueue updateQueue, + ISession backEndSession, TimeSpan sessionTime, RaidSettings raidSettings) { Logger = BepInEx.Logging.Logger.CreateLogSource("Coop Game Mode"); Logger.LogInfo("CoopGame::Create"); @@ -113,7 +116,7 @@ internal static CoopGame Create(InputTree inputTree, Profile profile, GameDateTi BossLocationSpawn[] bossSpawns = EFT.LocalGame.smethod_8(wavesSettings, location.BossLocationSpawn); coopGame.GClass579 = GClass579.smethod_0(bossSpawns, new Action(coopGame.botsController_0.ActivateBotsByWave)); - if (useCustomWeather) + if (useCustomWeather && MatchmakerAcceptPatches.IsServer) { Logger.LogInfo("Custom weather enabled, initializing curves"); coopGame.SetupCustomWeather(timeAndWeather); @@ -124,6 +127,8 @@ internal static CoopGame Create(InputTree inputTree, Profile profile, GameDateTi Singleton.Create(coopGame); FikaEventDispatcher.DispatchEvent(new FikaGameCreatedEvent(coopGame)); + coopGame.RaidSettings = raidSettings; + return coopGame; } @@ -666,6 +671,15 @@ public override async Task vmethod_2(int playerId, Vector3 position await Task.Delay(5000); } + if (MatchmakerAcceptPatches.IsServer) + { + if (RaidSettings.MetabolismDisabled) + { + myPlayer.HealthController.DisableMetabolism(); + NotificationManagerClass.DisplayMessageNotification("Metabolism disabled", iconType: EFT.Communications.ENotificationIconType.Alert); + } + } + CoopPlayer coopPlayer = (CoopPlayer)myPlayer; coopHandler.Players.Add(coopPlayer.NetId, coopPlayer); diff --git a/Fika.Core/Coop/LocalGame/TarkovApplication_LocalGameCreator_Patch.cs b/Fika.Core/Coop/LocalGame/TarkovApplication_LocalGameCreator_Patch.cs index d7aa1dd7..e3880d80 100644 --- a/Fika.Core/Coop/LocalGame/TarkovApplication_LocalGameCreator_Patch.cs +++ b/Fika.Core/Coop/LocalGame/TarkovApplication_LocalGameCreator_Patch.cs @@ -103,16 +103,14 @@ public static async Task Postfix(Task __result, TarkovApplication __instance, Ti await Task.Delay(1000); + StartHandler startHandler = new(__instance, session.Profile, session.ProfileOfPet, ____raidSettings.SelectedLocation, timeHasComeScreenController); + CoopGame localGame = CoopGame.Create(____inputTree, profile, ____localGameDateTime, session.InsuranceCompany, MonoBehaviourSingleton.Instance, MonoBehaviourSingleton.Instance, MonoBehaviourSingleton.Instance, MonoBehaviourSingleton.Instance, ____raidSettings.SelectedLocation, timeAndWeather, - ____raidSettings.WavesSettings, ____raidSettings.SelectedDateTime, new Callback((r) => - { - typeof(TarkovApplication).GetMethod(nameof(TarkovApplication.method_46)) - .Invoke(__instance, [session.Profile.Id, session.ProfileOfPet, ____raidSettings.SelectedLocation, r, timeHasComeScreenController]); - - }), ____fixedDeltaTime, EUpdateQueue.Update, session, TimeSpan.FromSeconds(60 * ____raidSettings.SelectedLocation.EscapeTimeLimit) + ____raidSettings.WavesSettings, ____raidSettings.SelectedDateTime, new Callback(startHandler.HandleStart), + ____fixedDeltaTime, EUpdateQueue.Update, session, TimeSpan.FromSeconds(60 * ____raidSettings.SelectedLocation.EscapeTimeLimit), ____raidSettings ); Singleton.Create(localGame); FikaEventDispatcher.DispatchEvent(new AbstractGameCreatedEvent(localGame)); @@ -126,20 +124,35 @@ public static async Task Postfix(Task __result, TarkovApplication __instance, Ti timeHasComeScreenController.ChangeStatus("Created Coop Game"); } - Task initTask = localGame.method_4(____raidSettings.BotSettings, ____backendUrl, null, new Callback((r) => + Task finishTask = localGame.method_4(____raidSettings.BotSettings, ____backendUrl, null, new Callback(startHandler.HandleLoadComplete)); + __result = Task.WhenAll(finishTask); + } + + private class StartHandler(TarkovApplication tarkovApplication, Profile pmcProfile, Profile scavProfile, LocationSettingsClass.Location location, MatchmakerTimeHasCome.GClass3163 timeHasComeScreenController) + { + private readonly TarkovApplication tarkovApplication = tarkovApplication; + private readonly Profile pmcProfile = pmcProfile; + private readonly Profile scavProfile = scavProfile; + private readonly LocationSettingsClass.Location location = location; + private readonly MatchmakerTimeHasCome.GClass3163 timeHasComeScreenController = timeHasComeScreenController; + + public void HandleStart(Result result) + { + tarkovApplication.method_46(pmcProfile.Id, scavProfile, location, result, timeHasComeScreenController); + } + + public void HandleLoadComplete(IResult error) { using (GClass21.StartWithToken("LoadingScreen.LoadComplete")) { UnityEngine.Object.DestroyImmediate(MonoBehaviourSingleton.Instance.gameObject); - MainMenuController mmc = (MainMenuController)typeof(TarkovApplication).GetFields(BindingFlags.Instance | BindingFlags.NonPublic).Where(x => x.FieldType == typeof(MainMenuController)).FirstOrDefault().GetValue(__instance); - mmc.Unsubscribe(); + MainMenuController mmc = (MainMenuController)typeof(TarkovApplication).GetFields(BindingFlags.Instance | BindingFlags.NonPublic).Where(x => x.FieldType == typeof(MainMenuController)).FirstOrDefault().GetValue(tarkovApplication); + mmc?.Unsubscribe(); GameWorld gameWorld = Singleton.Instance; gameWorld.OnGameStarted(); FikaEventDispatcher.DispatchEvent(new GameWorldStartedEvent(gameWorld)); } - })); - - __result = Task.WhenAll(initTask); + } } } } diff --git a/Fika.Core/Coop/Matchmaker/MatchmakerAccept/MatchmakerAcceptScreenShowPatch.cs b/Fika.Core/Coop/Matchmaker/MatchmakerAccept/MatchmakerAcceptScreenShowPatch.cs index 87f3f316..2f316dfc 100644 --- a/Fika.Core/Coop/Matchmaker/MatchmakerAccept/MatchmakerAcceptScreenShowPatch.cs +++ b/Fika.Core/Coop/Matchmaker/MatchmakerAccept/MatchmakerAcceptScreenShowPatch.cs @@ -16,7 +16,7 @@ public class MatchmakerAcceptScreenShowPatch : ModulePatch private static GameObject MatchmakerObject { get; set; } [PatchPrefix] - private static void Pre(ref ISession session, ref RaidSettings raidSettings, Profile ___profile_0, MatchMakerAcceptScreen __instance, + private static void PreFix(ref ISession session, ref RaidSettings raidSettings, Profile ___profile_0, MatchMakerAcceptScreen __instance, DefaultUIButton ____acceptButton, DefaultUIButton ____backButton, MatchMakerPlayerPreview ____playerModelView) { if (MatchmakerObject == null) @@ -29,14 +29,14 @@ private static void Pre(ref ISession session, ref RaidSettings raidSettings, Pro raidSettings.RaidMode = ERaidMode.Local; } - var newMatchMaker = MatchmakerObject.GetOrAddComponent(); + MatchMakerUIScript newMatchMaker = MatchmakerObject.GetOrAddComponent(); newMatchMaker.RaidSettings = raidSettings; newMatchMaker.AcceptButton = ____acceptButton; newMatchMaker.BackButton = ____backButton; } [PatchPostfix] - private static void Post(ref ISession session, Profile ___profile_0, MatchMakerAcceptScreen __instance) + private static void PostFix(ref ISession session, Profile ___profile_0, MatchMakerAcceptScreen __instance) { MatchmakerAcceptPatches.MatchMakerAcceptScreenInstance = __instance; MatchmakerAcceptPatches.Profile = ___profile_0; diff --git a/Fika.Core/Coop/PacketHandlers/ClientPacketSender.cs b/Fika.Core/Coop/PacketHandlers/ClientPacketSender.cs index 40538e83..3421c752 100644 --- a/Fika.Core/Coop/PacketHandlers/ClientPacketSender.cs +++ b/Fika.Core/Coop/PacketHandlers/ClientPacketSender.cs @@ -134,6 +134,15 @@ private void Update() private IEnumerator SyncWorld() { + while (Client.NetClient.FirstPeer == null) + { + yield return null; + } + + Writer?.Reset(); + SessionSettingsPacket settingsPacket = new(true); + Client?.SendData(Writer, ref settingsPacket, DeliveryMethod.ReliableOrdered); + CoopGame coopGame = (CoopGame)Singleton.Instance; if (coopGame == null) diff --git a/Fika.Core/Networking/FikaClient.cs b/Fika.Core/Networking/FikaClient.cs index 6a735f6f..962378a2 100644 --- a/Fika.Core/Networking/FikaClient.cs +++ b/Fika.Core/Networking/FikaClient.cs @@ -82,6 +82,7 @@ protected void Start() packetProcessor.SubscribeNetSerializable(OnAssignNetIdPacketReceived); packetProcessor.SubscribeNetSerializable(OnSyncNetIdPacketReceived); packetProcessor.SubscribeNetSerializable(OnOperationCallbackPacketReceived); + packetProcessor.SubscribeNetSerializable(OnSessionSettingsPacketReceived); _netClient = new NetManager(this) { @@ -116,6 +117,18 @@ protected void Start() ClientReady = true; } + private void OnSessionSettingsPacketReceived(SessionSettingsPacket packet, NetPeer peer) + { + if (!packet.IsRequest) + { + if (packet.MetabolismDisabled) + { + Singleton.Instance.MainPlayer.HealthController.DisableMetabolism(); + NotificationManagerClass.DisplayMessageNotification("Metabolism disabled", iconType: EFT.Communications.ENotificationIconType.Alert); + } + } + } + private void OnOperationCallbackPacketReceived(OperationCallbackPacket packet, NetPeer peer) { if (Players.TryGetValue(packet.NetId, out CoopPlayer player) && player.IsYourPlayer) diff --git a/Fika.Core/Networking/FikaServer.cs b/Fika.Core/Networking/FikaServer.cs index 1b2b15cb..3c49f205 100644 --- a/Fika.Core/Networking/FikaServer.cs +++ b/Fika.Core/Networking/FikaServer.cs @@ -80,6 +80,7 @@ public async void Start() packetProcessor.SubscribeNetSerializable(OnMinePacketReceived); packetProcessor.SubscribeNetSerializable(OnBorderZonePacketReceived); packetProcessor.SubscribeNetSerializable(OnSendCharacterPacketReceived); + packetProcessor.SubscribeNetSerializable(OnSessionSettingsPacketReceived); _netServer = new NetManager(this) { @@ -161,6 +162,23 @@ await Task.Run(async () => ServerReady = true; } + private void OnSessionSettingsPacketReceived(SessionSettingsPacket packet, NetPeer peer) + { + if (packet.IsRequest) + { + CoopGame coopGame = (CoopGame)Singleton.Instance; + if (coopGame != null) + { + SessionSettingsPacket returnPacket = new(false) + { + MetabolismDisabled = coopGame.RaidSettings.MetabolismDisabled + }; + + SendDataToPeer(peer, new(), ref returnPacket, DeliveryMethod.ReliableUnordered); + } + } + } + public int PopNetId() { int netId = _currentNetId; diff --git a/Fika.Core/Networking/Packets/Backend/SessionSettingsPacket.cs b/Fika.Core/Networking/Packets/Backend/SessionSettingsPacket.cs new file mode 100644 index 00000000..cc01818f --- /dev/null +++ b/Fika.Core/Networking/Packets/Backend/SessionSettingsPacket.cs @@ -0,0 +1,28 @@ +using LiteNetLib.Utils; + +namespace Fika.Core.Networking +{ + public struct SessionSettingsPacket(bool isRequest) : INetSerializable + { + public bool IsRequest = isRequest; + public bool MetabolismDisabled; + + public void Deserialize(NetDataReader reader) + { + IsRequest = reader.GetBool(); + if (!IsRequest) + { + MetabolismDisabled = reader.GetBool(); + } + } + + public void Serialize(NetDataWriter writer) + { + writer.Put(IsRequest); + if (!IsRequest) + { + writer.Put(MetabolismDisabled); + } + } + } +}