From 2d194371b9e00dd98fae56927d4b050d4de08b05 Mon Sep 17 00:00:00 2001 From: starfish <50672801+starfi5h@users.noreply.github.com> Date: Mon, 1 Apr 2024 20:15:36 +0800 Subject: [PATCH 1/7] Lock packetProcessor.Write to prevent thread error --- NebulaModel/Networking/NebulaConnection.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/NebulaModel/Networking/NebulaConnection.cs b/NebulaModel/Networking/NebulaConnection.cs index ccad95b7f..5d0306fbb 100644 --- a/NebulaModel/Networking/NebulaConnection.cs +++ b/NebulaModel/Networking/NebulaConnection.cs @@ -55,8 +55,11 @@ public NebulaConnection(WebSocket peerSocket, EndPoint peerEndpoint, NebulaNetPa { lock (pendingPackets) { - var rawData = packetProcessor.Write(packet); - pendingPackets.Enqueue(rawData); + lock (packetProcessor) + { + var rawData = packetProcessor.Write(packet); //not-threadsafe + pendingPackets.Enqueue(rawData); + } ProcessPacketQueue(); } } From 12b5b59c10726d7fe70c7a2f37ffbbcc0146e4cc Mon Sep 17 00:00:00 2001 From: starfish <50672801+starfi5h@users.noreply.github.com> Date: Mon, 1 Apr 2024 21:20:17 +0800 Subject: [PATCH 2/7] Fix enemy releated errors --- .../Dynamic/EnemyDFGroundSystem_Patch.cs | 30 +++++++++++++++++++ .../Patches/Dynamic/EnemyFormation_Patch.cs | 26 ++++++++++++++++ .../Patches/Dynamic/SpaceSector_Patch.cs | 23 ++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 NebulaPatcher/Patches/Dynamic/EnemyFormation_Patch.cs diff --git a/NebulaPatcher/Patches/Dynamic/EnemyDFGroundSystem_Patch.cs b/NebulaPatcher/Patches/Dynamic/EnemyDFGroundSystem_Patch.cs index f791db5e5..354983b6c 100644 --- a/NebulaPatcher/Patches/Dynamic/EnemyDFGroundSystem_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/EnemyDFGroundSystem_Patch.cs @@ -2,6 +2,7 @@ using System; using HarmonyLib; +using NebulaModel.Logger; using NebulaModel.Packets.Combat.GroundEnemy; using NebulaWorld; @@ -159,4 +160,33 @@ public static void GameTickLogic_Prefix(EnemyDFGroundSystem __instance, long gam Multiplayer.Session.Enemies.BroadcastBaseStatusPackets(__instance, gameTick); } } + + [HarmonyPrefix] + [HarmonyPatch(nameof(EnemyDFGroundSystem.KeyTickLogic))] + public static void KeyTickLogic_Prefix(EnemyDFGroundSystem __instance) + { + if (!Multiplayer.IsActive || Multiplayer.Session.IsServer) return; + + // Fix NRE in EnemyDFGroundSystem.KeyTickLogic (System.Int64 time);(IL_0929) + var cursor = __instance.builders.cursor; + var buffer = __instance.builders.buffer; + var baseBuffer = __instance.bases.buffer; + var enemyPool = __instance.factory.enemyPool; + for (var builderId = 1; builderId < cursor; builderId++) + { + ref var builder = ref buffer[builderId]; + if (builder.id == builderId) + { + if (baseBuffer[enemyPool[builder.enemyId].owner] == null) + { + var msg = $"Remove EnemyDFGroundSystem enemy[{builder.enemyId}]: owner = {enemyPool[builder.enemyId].owner}"; + Log.WarnInform(msg); + + __instance.factory.enemyPool[builder.enemyId].SetEmpty(); + __instance.builders.Remove(builderId); + } + } + } + } + } diff --git a/NebulaPatcher/Patches/Dynamic/EnemyFormation_Patch.cs b/NebulaPatcher/Patches/Dynamic/EnemyFormation_Patch.cs new file mode 100644 index 000000000..50bd07753 --- /dev/null +++ b/NebulaPatcher/Patches/Dynamic/EnemyFormation_Patch.cs @@ -0,0 +1,26 @@ +#region + +using HarmonyLib; + +#endregion + +namespace NebulaPatcher.Patches.Dynamic; + +[HarmonyPatch(typeof(EnemyFormation))] +internal class EnemyFormation_Patch +{ + [HarmonyPrefix] + [HarmonyPatch(typeof(EnemyFormation), nameof(EnemyFormation.RemoveUnit))] + public static bool RemoveUnit_Prefix(EnemyFormation __instance, int port) + { + if (__instance.units[port] != 0) + { + if (__instance.vacancyCursor < __instance.vacancies.Length) // guard + { + __instance.vacancies[__instance.vacancyCursor++] = port; + } + __instance.units[port] = 0; + } + return false; + } +} diff --git a/NebulaPatcher/Patches/Dynamic/SpaceSector_Patch.cs b/NebulaPatcher/Patches/Dynamic/SpaceSector_Patch.cs index f6d990108..4a9c7a5e1 100644 --- a/NebulaPatcher/Patches/Dynamic/SpaceSector_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/SpaceSector_Patch.cs @@ -4,6 +4,7 @@ using NebulaWorld; using NebulaModel.Packets.Combat.DFHive; using NebulaModel.Packets.Combat.SpaceEnemy; +using NebulaModel.Logger; #endregion @@ -65,4 +66,26 @@ public static bool TryCreateNewHive_Prefix(StarData star) } return true; } + + [HarmonyPrefix] + [HarmonyPatch(nameof(SpaceSector.GameTick))] + public static void GameTick_Prefix(SpaceSector __instance) + { + if (!Multiplayer.IsActive || Multiplayer.Session.IsServer) return; + + // Fix NRE in DFSTurretComponent.InternalUpdate (PrefabDesc pdesc);(IL_0017) + for (var enemyId = 1; enemyId < __instance.enemyCursor; enemyId++) + { + ref var enemy = ref __instance.enemyPool[enemyId]; + if (enemy.id != enemyId) continue; + + if (SpaceSector.PrefabDescByModelIndex[enemy.modelIndex] == null) + { + var msg = $"Remove SpeaceSector enemy[{enemyId}]: modelIndex{enemy.modelIndex}"; + Log.WarnInform(msg); + + __instance.enemyPool[enemyId].SetEmpty(); + } + } + } } From 7170440c85695c4da28f96a0cdbb6b32a7ad2b56 Mon Sep 17 00:00:00 2001 From: starfish <50672801+starfi5h@users.noreply.github.com> Date: Mon, 1 Apr 2024 21:37:09 +0800 Subject: [PATCH 3/7] Fix issues when client join --- .../Players/PlayerMechaDIYArmorProcessor.cs | 4 +- NebulaWorld/SimulatedWorld.cs | 40 ++++++++++++------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/NebulaNetwork/PacketProcessors/Players/PlayerMechaDIYArmorProcessor.cs b/NebulaNetwork/PacketProcessors/Players/PlayerMechaDIYArmorProcessor.cs index 9dbd36117..0d7f516ef 100644 --- a/NebulaNetwork/PacketProcessors/Players/PlayerMechaDIYArmorProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Players/PlayerMechaDIYArmorProcessor.cs @@ -1,11 +1,9 @@ #region -using NebulaAPI.GameState; using NebulaAPI.Packets; using NebulaModel.Networking; using NebulaModel.Packets; using NebulaModel.Packets.Players; -using NebulaWorld; #endregion @@ -69,10 +67,12 @@ protected override void ProcessPacket(PlayerMechaDIYArmor packet, NebulaConnecti editor.mecha.diyAppearance = new MechaAppearance(); editor.mecha.diyAppearance.Init(); } + // Modify from UIMechaEditor.ApplyMechaAppearance GameMain.mainPlayer.mecha.diyAppearance.CopyTo(editor.mecha.diyAppearance); editor.mechaArmorModel.RefreshAllPartObjects(); editor.mechaArmorModel.RefreshAllBoneObjects(); editor.mecha.diyAppearance.NotifyAllEvents(); + editor.CalcMechaProperty(); // set mecha.hp and mecha.energyConsumptionCoef editor._left_content_height_max = 0f; editor.SetLeftScrollTop(); editor.saveGroup._Open(); diff --git a/NebulaWorld/SimulatedWorld.cs b/NebulaWorld/SimulatedWorld.cs index 94da7062b..e65ddfc89 100644 --- a/NebulaWorld/SimulatedWorld.cs +++ b/NebulaWorld/SimulatedWorld.cs @@ -110,21 +110,7 @@ public void SetupInitialPlayerState() GameMain.mainPlayer.mecha.groundCombatModule.AfterImport(GameMain.data); // do we need to do something about the spaceSector? GameMain.mainPlayer.mecha.spaceCombatModule.AfterImport(GameMain.data); // do we need to do something about the spaceSector? - // Recycle all fleets - var module = GameMain.mainPlayer.mecha.groundCombatModule; - for (var fleetIndex = 0; fleetIndex < module.fleetCount; fleetIndex++) - { - ref var ptr = ref module.moduleFleets[fleetIndex]; - if (ptr.fleetId == 0) continue; - ptr.OnFleetComponentRemoved(); - } - module = GameMain.mainPlayer.mecha.spaceCombatModule; - for (var fleetIndex = 0; fleetIndex < module.fleetCount; fleetIndex++) - { - ref var ptr = ref module.moduleFleets[fleetIndex]; - if (ptr.fleetId == 0) continue; - ptr.OnFleetComponentRemoved(); - } + FixPlayerAfterImport(); } // Initialization on the host side after game is loaded @@ -206,6 +192,30 @@ public void SetupInitialPlayerState() GameMain.mainPlayer.gameObject.AddComponentIfMissing(); } + public static void FixPlayerAfterImport() + { + var player = GameMain.mainPlayer; + + // Inventory Capacity level 7 will increase package columncount from 10 -> 12 + var packageRowCount = (player.package.size - 1) / player.GetPackageColumnCount() + 1; + // Make sure all slots are available on UI + player.package.SetSize(player.packageColCount * packageRowCount); + player.deliveryPackage.rowCount = packageRowCount; + player.deliveryPackage.NotifySizeChange(); + + // Set fleetId = 0, fleetAstroId = 0 and fighter.craftId = 0 + var moduleFleets = player.mecha.groundCombatModule.moduleFleets; + for (var index = 0; index < moduleFleets.Length; index++) + { + moduleFleets[index].ClearFleetForeignKey(); + } + moduleFleets = player.mecha.spaceCombatModule.moduleFleets; + for (var index = 0; index < moduleFleets.Length; index++) + { + moduleFleets[index].ClearFleetForeignKey(); + } + } + public void OnPlayerJoining(string username) { if (IsPlayerJoining) From dd9a0f7461b9dc344bcb0eb59db62897b0f5a2d6 Mon Sep 17 00:00:00 2001 From: starfish <50672801+starfi5h@users.noreply.github.com> Date: Mon, 1 Apr 2024 23:47:57 +0800 Subject: [PATCH 4/7] Add warning and guard to ILS packets --- .../Logistics/ILSAddStationComponent.cs | 5 +-- .../ILSAddStationComponentProcessor.cs | 15 +++++++-- .../Logistics/ILSRequestShipDockProcessor.cs | 32 ++++++++----------- .../Logistics/StationUIProcessor.cs | 1 - .../Logistics/StorageUIProcessor.cs | 2 -- .../Patches/Dynamic/PlanetTransport_Patch.cs | 13 +++----- NebulaWorld/Logistics/ILSShipManager.cs | 20 +++++------- NebulaWorld/Logistics/StationUIManager.cs | 8 ++--- 8 files changed, 47 insertions(+), 49 deletions(-) diff --git a/NebulaModel/Packets/Logistics/ILSAddStationComponent.cs b/NebulaModel/Packets/Logistics/ILSAddStationComponent.cs index 3e35fb258..0b70aee24 100644 --- a/NebulaModel/Packets/Logistics/ILSAddStationComponent.cs +++ b/NebulaModel/Packets/Logistics/ILSAddStationComponent.cs @@ -4,17 +4,18 @@ public class ILSAddStationComponent { public ILSAddStationComponent() { } - public ILSAddStationComponent(int planetId, int stationId, int stationGId, int maxShipCount) + public ILSAddStationComponent(int planetId, int stationId, int stationGId, int entityId, int maxShipCount) { StationGId = stationGId; PlanetId = planetId; StationId = stationId; + EntityId = entityId; MaxShipCount = maxShipCount; } public int PlanetId { get; set; } public int StationId { get; set; } public int StationGId { get; set; } - + public int EntityId { get; set; } public int MaxShipCount { get; set; } } diff --git a/NebulaNetwork/PacketProcessors/Logistics/ILSAddStationComponentProcessor.cs b/NebulaNetwork/PacketProcessors/Logistics/ILSAddStationComponentProcessor.cs index 1509fed41..835aab785 100644 --- a/NebulaNetwork/PacketProcessors/Logistics/ILSAddStationComponentProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Logistics/ILSAddStationComponentProcessor.cs @@ -1,5 +1,6 @@ #region +using System; using NebulaAPI.Packets; using NebulaModel.Logger; using NebulaModel.Networking; @@ -23,14 +24,24 @@ protected override void ProcessPacket(ILSAddStationComponent packet, NebulaConne using (Multiplayer.Session.Ships.PatchLockILS.On()) { var galacticTransport = GameMain.data.galacticTransport; - var stationPool = GameMain.galaxy.PlanetById(packet.PlanetId).factory?.transport.stationPool; + var stationPool = GameMain.galaxy.PlanetById(packet.PlanetId)?.factory?.transport.stationPool; if (stationPool != null) { // If we have loaded the factory where the new station was created on, should be able to find // it in our PlanetTransport.stationPool // Assgin gid here so this station will go to galacticTransport.stationPool[gid] stationPool[packet.StationId].gid = packet.StationGId; - galacticTransport.AddStationComponent(packet.PlanetId, stationPool[packet.StationId]); + if (galacticTransport.AddStationComponent(packet.PlanetId, stationPool[packet.StationId]) != packet.StationGId) + { + Log.WarnInform($"AddStationComponent gid mismatch: {stationPool[packet.StationId].gid} => packet.StationGId"); + galacticTransport.stationPool[packet.StationGId] = stationPool[packet.StationId]; + } + galacticTransport.stationCursor = Math.Max(galacticTransport.stationCursor, packet.StationGId + 1); + + if (stationPool[packet.StationId].entityId != packet.EntityId) + { + Log.WarnInform($"Station gid {packet.StationGId} entityId mismatch: {stationPool[packet.StationId].entityId} => {packet.EntityId}"); + } } else { diff --git a/NebulaNetwork/PacketProcessors/Logistics/ILSRequestShipDockProcessor.cs b/NebulaNetwork/PacketProcessors/Logistics/ILSRequestShipDockProcessor.cs index 6acfac5a7..1635ca5c0 100644 --- a/NebulaNetwork/PacketProcessors/Logistics/ILSRequestShipDockProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Logistics/ILSRequestShipDockProcessor.cs @@ -2,13 +2,10 @@ using System.Collections.Generic; using NebulaAPI.DataStructures; -using NebulaAPI.GameState; -using NebulaAPI.Networking; using NebulaAPI.Packets; using NebulaModel.Networking; using NebulaModel.Packets; using NebulaModel.Packets.Logistics; -using NebulaWorld; #endregion @@ -30,9 +27,8 @@ protected override void ProcessPacket(ILSRequestShipDock packet, NebulaConnectio return; } - var player = Players.Get(conn, EConnectionStatus.Connected) ?? Players.Get(conn, EConnectionStatus.Syncing); - - if (player == null || GameMain.data.galacticTransport.stationCapacity <= packet.StationGId) + var stationPool = GameMain.data.galacticTransport.stationPool; + if (stationPool.Length <= packet.StationGId || stationPool[packet.StationGId] == null) { return; } @@ -47,12 +43,12 @@ protected override void ProcessPacket(ILSRequestShipDock packet, NebulaConnectio // find ShipData that has otherGId set to packet.stationGId for (var i = 0; i < GameMain.data.galacticTransport.stationCapacity; i++) { - if (GameMain.data.galacticTransport.stationPool[i] == null) + if (stationPool[i] == null) { continue; } - var shipData = GameMain.data.galacticTransport.stationPool[i].workShipDatas; + var shipData = stationPool[i].workShipDatas; for (var j = 0; j < shipData.Length; j++) { @@ -73,7 +69,7 @@ protected override void ProcessPacket(ILSRequestShipDock packet, NebulaConnectio // also add add ships of current station as they use the dock pos too in the pos calculation // NOTE: we need to set this stations gid as otherStationGId so that the client accesses the array in the right way - var shipData2 = GameMain.data.galacticTransport.stationPool[packet.StationGId].workShipDatas; + var shipData2 = stationPool[packet.StationGId].workShipDatas; for (var i = 0; i < shipData2.Length; i++) { @@ -86,14 +82,14 @@ protected override void ProcessPacket(ILSRequestShipDock packet, NebulaConnectio } var packet2 = new ILSShipDock(packet.StationGId, - GameMain.data.galacticTransport.stationPool[packet.StationGId].shipDockPos, - GameMain.data.galacticTransport.stationPool[packet.StationGId].shipDockRot, - shipOtherGId.ToArray(), - shipIndex.ToArray(), - shipPos.ToArray(), - shipRot.ToArray(), - shipPPosTemp.ToArray(), - shipPRotTemp.ToArray()); - player.SendPacket(packet2); + stationPool[packet.StationGId].shipDockPos, + stationPool[packet.StationGId].shipDockRot, + [.. shipOtherGId], + [.. shipIndex], + [.. shipPos], + [.. shipRot], + [.. shipPPosTemp], + [.. shipPRotTemp]); + conn.SendPacket(packet2); } } diff --git a/NebulaNetwork/PacketProcessors/Logistics/StationUIProcessor.cs b/NebulaNetwork/PacketProcessors/Logistics/StationUIProcessor.cs index c823f74c2..b0c8571a4 100644 --- a/NebulaNetwork/PacketProcessors/Logistics/StationUIProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Logistics/StationUIProcessor.cs @@ -23,7 +23,6 @@ protected override void ProcessPacket(StationUI packet, NebulaConnection conn) StationUIManager.UpdateStation(ref packet); // broadcast to other clients - var player = Players.Get(conn); Server.SendPacketExclude(packet, conn); // as we block the normal method for the client he must run it once he receives this packet. diff --git a/NebulaNetwork/PacketProcessors/Logistics/StorageUIProcessor.cs b/NebulaNetwork/PacketProcessors/Logistics/StorageUIProcessor.cs index 6fb9d5caa..69cb095ec 100644 --- a/NebulaNetwork/PacketProcessors/Logistics/StorageUIProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Logistics/StorageUIProcessor.cs @@ -1,6 +1,5 @@ #region -using NebulaAPI.GameState; using NebulaAPI.Packets; using NebulaModel.Networking; using NebulaModel.Packets; @@ -23,7 +22,6 @@ protected override void ProcessPacket(StorageUI packet, NebulaConnection conn) Multiplayer.Session.StationsUI.UpdateStorage(packet); // broadcast to other clients - var player = Players.Get(conn); Server.SendPacketExclude(packet, conn); // as we block some methods for the client he must run it once he receives this packet. diff --git a/NebulaPatcher/Patches/Dynamic/PlanetTransport_Patch.cs b/NebulaPatcher/Patches/Dynamic/PlanetTransport_Patch.cs index 4d08f405b..5992922ea 100644 --- a/NebulaPatcher/Patches/Dynamic/PlanetTransport_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/PlanetTransport_Patch.cs @@ -12,8 +12,6 @@ namespace NebulaPatcher.Patches.Dynamic; [HarmonyPatch(typeof(PlanetTransport))] internal class PlanetTransport_Patch { - private static int RemovingStationGId; - [HarmonyPrefix] [HarmonyPatch(nameof(PlanetTransport.SetStationStorage))] public static bool SetStationStorage_Prefix(PlanetTransport __instance, int stationId, int storageIdx, int itemId, @@ -62,7 +60,7 @@ public static void NewStationComponent_Postfix(PlanetTransport __instance, Stati Log.Info( $"Send AddStationComponen to all clients for planet {__result.planetId}, id {__result.id} with gId of {__result.gid}"); Multiplayer.Session.Network.SendPacket(new ILSAddStationComponent(__result.planetId, __result.id, __result.gid, - _desc.stationMaxShipCount)); + __result.entityId, _desc.stationMaxShipCount)); } [HarmonyPostfix] @@ -89,10 +87,9 @@ public static void Import_Postfix(PlanetTransport __instance) */ [HarmonyPrefix] [HarmonyPatch(nameof(PlanetTransport.RemoveStationComponent))] - public static bool RemoveStationComponent_Prefix(PlanetTransport __instance, int id) + public static bool RemoveStationComponent_Prefix(PlanetTransport __instance, int id, ref int __state) { - RemovingStationGId = - __instance.stationPool[id].gid; // cache this as we need it in the postfix but its gone there already. + __state = __instance.stationPool[id].gid; // cache this as we need it in the postfix but its gone there already. return !Multiplayer.IsActive || Multiplayer.Session.LocalPlayer.IsHost || Multiplayer.Session.Ships.PatchLockILS; } @@ -101,13 +98,13 @@ public static bool RemoveStationComponent_Prefix(PlanetTransport __instance, int */ [HarmonyPostfix] [HarmonyPatch(nameof(PlanetTransport.RemoveStationComponent))] - public static void RemoveStationComponent_Postfix(PlanetTransport __instance, int id) + public static void RemoveStationComponent_Postfix(PlanetTransport __instance, int id, int __state) { if (!Multiplayer.IsActive || !Multiplayer.Session.LocalPlayer.IsHost) { return; } - Multiplayer.Session.Network.SendPacket(new ILSRemoveStationComponent(id, __instance.planet.id, RemovingStationGId)); + Multiplayer.Session.Network.SendPacket(new ILSRemoveStationComponent(id, __instance.planet.id, __state)); } [HarmonyPrefix] diff --git a/NebulaWorld/Logistics/ILSShipManager.cs b/NebulaWorld/Logistics/ILSShipManager.cs index c60ca29b6..5e7583923 100644 --- a/NebulaWorld/Logistics/ILSShipManager.cs +++ b/NebulaWorld/Logistics/ILSShipManager.cs @@ -42,10 +42,6 @@ public static void IdleShipGetToWork(ILSIdleShipBackToWork packet) { CreateFakeStationComponent(packet.ThisGId, packet.PlanetA, packet.StationMaxShipCount); } - else if (stationPool[packet.ThisGId].shipDockPos == Vector3.zero) - { - RequestStationDockPos(packet.ThisGId); - } if (stationPool.Length <= packet.OtherGId) { CreateFakeStationComponent(packet.OtherGId, packet.PlanetB, packet.StationMaxShipCount); @@ -54,12 +50,12 @@ public static void IdleShipGetToWork(ILSIdleShipBackToWork packet) { CreateFakeStationComponent(packet.OtherGId, packet.PlanetB, packet.StationMaxShipCount); } - else if (stationPool[packet.OtherGId].shipDockPos == Vector3.zero) - { - RequestStationDockPos(packet.OtherGId); - } var stationComponent = stationPool[packet.ThisGId]; + if (stationComponent == null) + { + return; // This shouldn't happen, but guard just in case + } stationComponent.workShipDatas[stationComponent.workShipCount].stage = -2; stationComponent.workShipDatas[stationComponent.workShipCount].planetA = packet.PlanetA; @@ -113,12 +109,12 @@ public static void WorkShipBackToIdle(ILSWorkShipBackToIdle packet) { CreateFakeStationComponent(packet.GId, packet.PlanetA, packet.StationMaxShipCount); } - else if (stationPool[packet.GId].shipDockPos == Vector3.zero) - { - RequestStationDockPos(packet.GId); - } var stationComponent = stationPool[packet.GId]; + if (stationComponent == null) + { + return; // This shouldn't happen, but guard just in case + } Array.Copy(stationComponent.workShipDatas, packet.WorkShipIndex + 1, stationComponent.workShipDatas, packet.WorkShipIndex, stationComponent.workShipDatas.Length - packet.WorkShipIndex - 1); diff --git a/NebulaWorld/Logistics/StationUIManager.cs b/NebulaWorld/Logistics/StationUIManager.cs index 183ec7b59..a775e2f52 100644 --- a/NebulaWorld/Logistics/StationUIManager.cs +++ b/NebulaWorld/Logistics/StationUIManager.cs @@ -260,11 +260,11 @@ private static StationComponent GetStation(int planetId, int stationId, int stat return null; } - var gStationPool = GameMain.data.galacticTransport.stationPool; - var stationPool = planet?.factory?.transport?.stationPool; + // Get the station from stationId on the planet + var stationPool = planet.factory.transport.stationPool; + var stationComponent = stationPool[stationId]; + var _ = stationGid; // Should ILS be dealt with differently? - // Figure out if we're dealing with a PLS or a ILS station - var stationComponent = stationGid > 0 ? gStationPool[stationGid] : stationPool?[stationId]; return stationComponent; } From 23647868b833da0c3a8678c0cf7f605bf6d5d1c4 Mon Sep 17 00:00:00 2001 From: starfish <50672801+starfi5h@users.noreply.github.com> Date: Tue, 2 Apr 2024 02:36:30 +0800 Subject: [PATCH 5/7] Fix SectorModel and PlanetATField in headless server --- .../Patches/Dynamic/Dedicated_Server_Patch.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/NebulaPatcher/Patches/Dynamic/Dedicated_Server_Patch.cs b/NebulaPatcher/Patches/Dynamic/Dedicated_Server_Patch.cs index df33b3868..71d34b552 100644 --- a/NebulaPatcher/Patches/Dynamic/Dedicated_Server_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/Dedicated_Server_Patch.cs @@ -49,6 +49,7 @@ public static void GameMainBegin_Postfix() [HarmonyPatch(typeof(GameData), nameof(GameData.OnDraw))] [HarmonyPatch(typeof(GameData), nameof(GameData.OnPostDraw))] [HarmonyPatch(typeof(FactoryModel), nameof(FactoryModel.LateUpdate))] + [HarmonyPatch(typeof(SectorModel), nameof(SectorModel.LateUpdate))] public static bool OnDraw_Prefix() { return false; @@ -159,4 +160,16 @@ public static bool DoMeshGeneration_Prefix() { return false; } + + [HarmonyPostfix] + [HarmonyPatch(typeof(PlanetATField), nameof(PlanetATField.RecalculatePhysicsShape))] + public static void RecalculatePhysicsShape_Postfix(PlanetATField __instance) + { + // vanilla use GPU to calculate the shape of shield that is not fully covered the whole planet + // In this patch it will act as it has been fully covered to make the planet shield effective + if (!__instance.isEmpty) + { + __instance.isSpherical = true; + } + } } From 78d2a24cd5eea6a359f14e3f781800d519066716 Mon Sep 17 00:00:00 2001 From: starfi5h <50672801+starfi5h@users.noreply.github.com> Date: Tue, 2 Apr 2024 12:03:18 +0800 Subject: [PATCH 6/7] Apply suggestions from code review Co-authored-by: Chris Yeninas <844685+PhantomGamers@users.noreply.github.com> --- NebulaPatcher/Patches/Dynamic/SpaceSector_Patch.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NebulaPatcher/Patches/Dynamic/SpaceSector_Patch.cs b/NebulaPatcher/Patches/Dynamic/SpaceSector_Patch.cs index 4a9c7a5e1..54e09ed9a 100644 --- a/NebulaPatcher/Patches/Dynamic/SpaceSector_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/SpaceSector_Patch.cs @@ -81,7 +81,7 @@ public static void GameTick_Prefix(SpaceSector __instance) if (SpaceSector.PrefabDescByModelIndex[enemy.modelIndex] == null) { - var msg = $"Remove SpeaceSector enemy[{enemyId}]: modelIndex{enemy.modelIndex}"; + var msg = $"Remove SpaceSector enemy[{enemyId}]: modelIndex{enemy.modelIndex}"; Log.WarnInform(msg); __instance.enemyPool[enemyId].SetEmpty(); From 66cbb5fa199eebbf3758f462c8b560e2fad2aa06 Mon Sep 17 00:00:00 2001 From: starfish <50672801+starfi5h@users.noreply.github.com> Date: Tue, 2 Apr 2024 17:25:34 +0800 Subject: [PATCH 7/7] try-catch ILSIdleShipBackToWork and ILSWorkShipBackToIdle --- .../ILSIdleShipBackToWorkProcessor.cs | 13 +++++----- .../ILSWorkShipBackToIdleProcessor.cs | 10 ++++++-- NebulaWorld/Logistics/ILSShipManager.cs | 24 ++++++++++--------- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/NebulaNetwork/PacketProcessors/Logistics/ILSIdleShipBackToWorkProcessor.cs b/NebulaNetwork/PacketProcessors/Logistics/ILSIdleShipBackToWorkProcessor.cs index 1ccdd993e..187862c75 100644 --- a/NebulaNetwork/PacketProcessors/Logistics/ILSIdleShipBackToWorkProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Logistics/ILSIdleShipBackToWorkProcessor.cs @@ -1,10 +1,11 @@ #region +using System; using NebulaAPI.Packets; +using NebulaModel.Logger; using NebulaModel.Networking; using NebulaModel.Packets; using NebulaModel.Packets.Logistics; -using NebulaWorld; using NebulaWorld.Logistics; #endregion @@ -16,18 +17,18 @@ public class ILSIdleShipBackToWorkProcessor : PacketProcessor= stationComponent.workShipDatas.Length) + { + return; // Ship count is outside the range + } stationComponent.workShipDatas[stationComponent.workShipCount].stage = -2; stationComponent.workShipDatas[stationComponent.workShipCount].planetA = packet.PlanetA; @@ -71,11 +75,8 @@ public static void IdleShipGetToWork(ILSIdleShipBackToWork packet) stationComponent.workShipDatas[stationComponent.workShipCount].warperCnt = packet.ShipWarperCount; stationComponent.warperCount = packet.StationWarperCount; - if (stationComponent.idleShipCount > 0) - { - stationComponent.workShipCount++; - stationComponent.idleShipCount--; - } + stationComponent.workShipCount++; + stationComponent.idleShipCount--; stationComponent.IdleShipGetToWork(packet.ShipIndex); var shipSailSpeed = GameMain.history.logisticShipSailSpeedModified; @@ -115,14 +116,15 @@ public static void WorkShipBackToIdle(ILSWorkShipBackToIdle packet) { return; // This shouldn't happen, but guard just in case } + if (stationComponent.workShipCount <= 0 || stationComponent.workShipDatas.Length <= packet.WorkShipIndex) + { + return; // Ship count is outside the range + } Array.Copy(stationComponent.workShipDatas, packet.WorkShipIndex + 1, stationComponent.workShipDatas, packet.WorkShipIndex, stationComponent.workShipDatas.Length - packet.WorkShipIndex - 1); - if (stationComponent.workShipCount > 0) - { - stationComponent.workShipCount--; - stationComponent.idleShipCount++; - } + stationComponent.workShipCount--; + stationComponent.idleShipCount++; stationComponent.WorkShipBackToIdle(packet.ShipIndex); Array.Clear(stationComponent.workShipDatas, stationComponent.workShipCount, stationComponent.workShipDatas.Length - stationComponent.workShipCount); @@ -152,7 +154,7 @@ public static void CreateFakeStationComponent(int gId, int planetId, int maxShip stationComponent.shipRenderers = new ShipRenderingData[maxShipCount]; stationComponent.shipUIRenderers = new ShipUIRenderingData[maxShipCount]; stationComponent.workShipCount = 0; - stationComponent.idleShipCount = 0; + stationComponent.idleShipCount = maxShipCount; // add dummy idle ship count to use in ILSShipManager stationComponent.shipDockPos = Vector3.zero; //gets updated later by server packet stationComponent.shipDockRot = Quaternion.identity; // gets updated later by server packet stationComponent.storage = []; // zero-length array for mod compatibility