diff --git a/NebulaClient/PacketProcessors/Logistics/ILSAddStationComponentProcessor.cs b/NebulaClient/PacketProcessors/Logistics/ILSAddStationComponentProcessor.cs new file mode 100644 index 000000000..11c745b38 --- /dev/null +++ b/NebulaClient/PacketProcessors/Logistics/ILSAddStationComponentProcessor.cs @@ -0,0 +1,37 @@ +using NebulaModel.Attributes; +using NebulaModel.Networking; +using NebulaModel.Packets.Logistics; +using NebulaModel.Packets.Processors; +using NebulaModel.Logger; +using NebulaWorld.Logistics; + +namespace NebulaClient.PacketProcessors.Logistics +{ + [RegisterPacketProcessor] + public class ILSAddStationComponentProcessor: IPacketProcessor + { + public void ProcessPacket(ILSAddStationComponent packet, NebulaConnection conn) + { + Log.Info($"ILSAddStationComponentProcessor processing packet for planet {packet.PlanetId}, station {packet.StationId} with gId of {packet.StationGId}"); + + using (ILSShipManager.PatchLockILS.On()) + { + GalacticTransport galacticTransport = GameMain.data.galacticTransport; + + if (packet.PlanetId == GameMain.localPlanet?.id) + { + // If we're on the same planet as the new station was created on, should be able to find + // it in our local PlanetTransport.stationPool + StationComponent stationComponent = GameMain.localPlanet.factory.transport.stationPool[packet.StationId]; + galacticTransport.AddStationComponent(packet.PlanetId, stationComponent); + } + else + { + // If we're not on the same planet as the new station was create on, we need to create a + // "fake" station that we can put into the GalacticTransport.stationPool instead of a real on + ILSShipManager.CreateFakeStationComponent(packet.StationGId, packet.PlanetId, true); + } + } + } + } +} diff --git a/NebulaClient/PacketProcessors/Logistics/ILSAddStationComponentResponseProcessor.cs b/NebulaClient/PacketProcessors/Logistics/ILSAddStationComponentResponseProcessor.cs deleted file mode 100644 index cf1539c8a..000000000 --- a/NebulaClient/PacketProcessors/Logistics/ILSAddStationComponentResponseProcessor.cs +++ /dev/null @@ -1,38 +0,0 @@ -using NebulaModel.Attributes; -using NebulaModel.Networking; -using NebulaModel.Packets.Logistics; -using NebulaModel.Packets.Processors; -using NebulaModel.DataStructures; -using NebulaWorld.Logistics; -using UnityEngine; - -/* - * Clients do not directly call AddStationComponent() instead they request the stations GId - * and then call it. This way we ensure that the GId is synced across all players. - * shipDockPos and planetId is only used to identify the right station as there cant be two at the exact same spot - * NOTE: there is issue #245 - */ -namespace NebulaClient.PacketProcessors.Logistics -{ - [RegisterPacketProcessor] - public class ILSAddStationComponentResponseProcessor: IPacketProcessor - { - public void ProcessPacket(ILSAddStationComponentResponse packet, NebulaConnection conn) - { - Vector3 shipDockPos = DataStructureExtensions.ToVector3(packet.shipDockPos); - for(int i = 0; i < ILSShipManager.AddStationComponentQueue[packet.planetId].Count; i++) - { - if(ILSShipManager.AddStationComponentQueue[packet.planetId][i].shipDockPos == shipDockPos) - { - using (ILSShipManager.PatchLockILS.On()) - { - ILSShipManager.AddStationComponentQueue[packet.planetId][i].gid = packet.stationGId; - GameMain.data.galacticTransport.AddStationComponent(packet.planetId, ILSShipManager.AddStationComponentQueue[packet.planetId][i]); - ILSShipManager.AddStationComponentQueue[packet.planetId].RemoveAt(i); - } - return; - } - } - } - } -} diff --git a/NebulaHost/PacketProcessors/Logistics/ILSAddStationComponentRequestProcessor.cs b/NebulaHost/PacketProcessors/Logistics/ILSAddStationComponentRequestProcessor.cs deleted file mode 100644 index 50ddbcd6a..000000000 --- a/NebulaHost/PacketProcessors/Logistics/ILSAddStationComponentRequestProcessor.cs +++ /dev/null @@ -1,31 +0,0 @@ -using NebulaModel.Attributes; -using NebulaModel.Networking; -using NebulaModel.Packets.Logistics; -using NebulaModel.Packets.Processors; -using NebulaModel.DataStructures; - -/* - * if clients build an ILS they request the GId of it, so we need to look it up in the hosts gStationPool - */ -namespace NebulaHost.PacketProcessors.Logistics -{ - [RegisterPacketProcessor] - public class ILSAddStationComponentRequestProcessor: IPacketProcessor - { - public void ProcessPacket(ILSAddStationComponentRequest packet, NebulaConnection conn) - { - StationComponent[] gStationPool = GameMain.data.galacticTransport.stationPool; - foreach(StationComponent stationComponent in gStationPool) - { - if(stationComponent != null && stationComponent.planetId == packet.planetId) - { - if(stationComponent.shipDockPos == DataStructureExtensions.ToVector3(packet.shipDockPos)) - { - conn.SendPacket(new ILSAddStationComponentResponse(stationComponent.gid, packet.planetId, stationComponent.shipDockPos)); - return; - } - } - } - } - } -} diff --git a/NebulaHost/PacketProcessors/Logistics/ILSRequestShipDockProcessor.cs b/NebulaHost/PacketProcessors/Logistics/ILSRequestShipDockProcessor.cs index 982078ba5..1c82b199b 100644 --- a/NebulaHost/PacketProcessors/Logistics/ILSRequestShipDockProcessor.cs +++ b/NebulaHost/PacketProcessors/Logistics/ILSRequestShipDockProcessor.cs @@ -3,6 +3,7 @@ using NebulaModel.Packets.Logistics; using NebulaModel.Packets.Processors; using NebulaModel.DataStructures; +using NebulaModel.Logger; using System.Collections.Generic; /* @@ -23,12 +24,15 @@ public ILSRequestShipDockProcessor() } public void ProcessPacket(ILSRequestShipDock packet, NebulaConnection conn) { + Log.Info($"Parsing ILSRequestShipDock for gId {packet.StationGId}"); + Player player = playerManager.GetPlayer(conn); + if(player == null) { player = playerManager.GetSyncingPlayer(conn); } - if (player != null && GameMain.data.galacticTransport.stationCapacity > packet.stationGId) + if (player != null && GameMain.data.galacticTransport.stationCapacity > packet.StationGId) { List shipOtherGId = new List(); List shipIndex = new List(); @@ -46,7 +50,7 @@ public void ProcessPacket(ILSRequestShipDock packet, NebulaConnection conn) for (int j = 0; j < shipData.Length; j++) { - if (shipData[j].otherGId == packet.stationGId) + if (shipData[j].otherGId == packet.StationGId) { shipOtherGId.Add(shipData[i].otherGId); shipIndex.Add(j); @@ -60,11 +64,11 @@ public void ProcessPacket(ILSRequestShipDock packet, NebulaConnection conn) } // 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 - ShipData[] shipData2 = GameMain.data.galacticTransport.stationPool[packet.stationGId].workShipDatas; + ShipData[] shipData2 = GameMain.data.galacticTransport.stationPool[packet.StationGId].workShipDatas; for(int i = 0; i < shipData2.Length; i++) { - shipOtherGId.Add(packet.stationGId); + shipOtherGId.Add(packet.StationGId); shipIndex.Add(i); shipPos.Add(new Double3(shipData2[i].uPos.x, shipData2[i].uPos.y, shipData2[i].uPos.z)); shipRot.Add(new Float4(shipData2[i].uRot)); @@ -72,9 +76,9 @@ public void ProcessPacket(ILSRequestShipDock packet, NebulaConnection conn) shipPRotTemp.Add(new Float4(shipData2[i].pRotTemp)); } - ILSShipDock packet2 = new ILSShipDock(packet.stationGId, - GameMain.data.galacticTransport.stationPool[packet.stationGId].shipDockPos, - GameMain.data.galacticTransport.stationPool[packet.stationGId].shipDockRot, + ILSShipDock 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(), diff --git a/NebulaModel/Packets/Logistics/ILSAddStationComponent.cs b/NebulaModel/Packets/Logistics/ILSAddStationComponent.cs new file mode 100644 index 000000000..025560457 --- /dev/null +++ b/NebulaModel/Packets/Logistics/ILSAddStationComponent.cs @@ -0,0 +1,19 @@ +using UnityEngine; +using NebulaModel.DataStructures; + +namespace NebulaModel.Packets.Logistics +{ + public class ILSAddStationComponent + { + public int PlanetId { get; set; } + public int StationId { get; set; } + public int StationGId { get; set; } + public ILSAddStationComponent() { } + public ILSAddStationComponent(int planetId, int stationId, int stationGId) + { + StationGId = stationGId; + PlanetId = planetId; + StationId = stationId; + } + } +} diff --git a/NebulaModel/Packets/Logistics/ILSAddStationComponentRequest.cs b/NebulaModel/Packets/Logistics/ILSAddStationComponentRequest.cs deleted file mode 100644 index 76448e51d..000000000 --- a/NebulaModel/Packets/Logistics/ILSAddStationComponentRequest.cs +++ /dev/null @@ -1,17 +0,0 @@ -using UnityEngine; -using NebulaModel.DataStructures; - -namespace NebulaModel.Packets.Logistics -{ - public class ILSAddStationComponentRequest - { - public Float3 shipDockPos { get; set; } - public int planetId { get; set; } - public ILSAddStationComponentRequest() { } - public ILSAddStationComponentRequest(int planetId, Vector3 shipDockPos) - { - this.planetId = planetId; - this.shipDockPos = new Float3(shipDockPos); - } - } -} diff --git a/NebulaModel/Packets/Logistics/ILSAddStationComponentResponse.cs b/NebulaModel/Packets/Logistics/ILSAddStationComponentResponse.cs deleted file mode 100644 index c54ce64b5..000000000 --- a/NebulaModel/Packets/Logistics/ILSAddStationComponentResponse.cs +++ /dev/null @@ -1,19 +0,0 @@ -using UnityEngine; -using NebulaModel.DataStructures; - -namespace NebulaModel.Packets.Logistics -{ - public class ILSAddStationComponentResponse - { - public int stationGId { get; set; } - public int planetId { get; set; } - public Float3 shipDockPos { get; set; } - public ILSAddStationComponentResponse() { } - public ILSAddStationComponentResponse(int stationGId, int planetId, Vector3 shipDockPos) - { - this.stationGId = stationGId; - this.planetId = planetId; - this.shipDockPos = new Float3(shipDockPos); - } - } -} diff --git a/NebulaModel/Packets/Logistics/ILSRequestShipDock.cs b/NebulaModel/Packets/Logistics/ILSRequestShipDock.cs index b4e5d6e67..cf75a376f 100644 --- a/NebulaModel/Packets/Logistics/ILSRequestShipDock.cs +++ b/NebulaModel/Packets/Logistics/ILSRequestShipDock.cs @@ -2,11 +2,11 @@ { public class ILSRequestShipDock { - public int stationGId { get; set; } + public int StationGId { get; set; } public ILSRequestShipDock() { } public ILSRequestShipDock(int stationGId) { - this.stationGId = stationGId; + StationGId = stationGId; } } } diff --git a/NebulaPatcher/Patches/Dynamic/GalacticTransport_Patch.cs b/NebulaPatcher/Patches/Dynamic/GalacticTransport_Patch.cs index cebc81548..c82103720 100644 --- a/NebulaPatcher/Patches/Dynamic/GalacticTransport_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/GalacticTransport_Patch.cs @@ -1,4 +1,5 @@ using HarmonyLib; +using NebulaModel.Logger; using NebulaWorld; using NebulaModel.Packets.Logistics; using NebulaWorld.Logistics; @@ -19,32 +20,6 @@ public static void SetForNewGame_Postfix() } } - [HarmonyPrefix] - [HarmonyPatch("AddStationComponent")] - public static bool AddStationComponent_Prefix(GalacticTransport __instance, int planetId, StationComponent station) - { - if (!SimulatedWorld.Initialized || LocalPlayer.IsMasterClient || ILSShipManager.PatchLockILS) - { - return true; - } - if (!ILSShipManager.AddStationComponentQueue.ContainsKey(planetId)) - { - ILSShipManager.AddStationComponentQueue.Add(planetId, new List()); - } - // use a queue here as we need to wait for the GId sent by server - ILSShipManager.AddStationComponentQueue[planetId].Add(station); - LocalPlayer.SendPacket(new ILSAddStationComponentRequest(planetId, station.shipDockPos)); - - // if we are a client and have no fake station then just add the new one normally - // this should happen when a player places an ILS on a FactoryData known to this client - // or when this client arrives at a planet for the first time which contains ILS - - //TODO: i think this should be false and only added via ILSAddStationComponentResponseProcessor - // but when client builds a ILS on a remote planet the shipDockPos is 0 and thus the checks fail. - // all in all there is some investigation needed here - return true; - } - [HarmonyPrefix] [HarmonyPatch("RemoveStationComponent")] public static bool RemoveStationComponent_Prefix(GalacticTransport __instance, int gid) diff --git a/NebulaPatcher/Patches/Dynamic/PlanetTransport_Patch.cs b/NebulaPatcher/Patches/Dynamic/PlanetTransport_Patch.cs index 20859ccd1..462b5c235 100644 --- a/NebulaPatcher/Patches/Dynamic/PlanetTransport_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/PlanetTransport_Patch.cs @@ -1,4 +1,5 @@ using HarmonyLib; +using NebulaModel.Logger; using NebulaModel.Packets.Logistics; using NebulaWorld; using NebulaWorld.Logistics; @@ -35,18 +36,36 @@ public static bool SetStationStorage_Postfix(PlanetTransport __instance, int sta // as the game does not do that for some reason, we need to do it here [HarmonyPostfix] [HarmonyPatch("NewStationComponent")] - public static void NewStationComponent_Postfix(PlanetTransport __instance, StationComponent __result, int _entityId, int _pcId, PrefabDesc _desc) + public static void NewStationComponent_AddPlanetId_Postfix(PlanetTransport __instance, StationComponent __result, int _entityId, int _pcId, PrefabDesc _desc) { if (!SimulatedWorld.Initialized) { return; } + if (!__result.isStellar && __result.planetId == 0) { __result.planetId = __instance.planet.id; } } + [HarmonyPostfix] + [HarmonyPatch("NewStationComponent")] + public static void NewStationComponent_BroadcastNewILS_Postfix(PlanetTransport __instance, StationComponent __result, int _entityId, int _pcId, PrefabDesc _desc) + { + if (!SimulatedWorld.Initialized || !LocalPlayer.IsMasterClient) return; + + // We don't need to do this for PLS + if (__result.gid == 0) return; + + // After host has added the StationComponent it has planetId, id and gId, now we can inform all clients about this station + // so they can add it to their GalacticTransport as they don't do that. Note that we're doing this in + // PlanetTransport.NewStationComponent and not GalacticTransport.AddStationComponent because stationId will be set at this point. + Log.Info($"Sending packet about new station component to all clients for planet {__result.planetId}, id {__result.id} with gId of {__result.gid}"); + LocalPlayer.SendPacket(new ILSAddStationComponent(__result.planetId, __result.id, __result.gid)); + } + + [HarmonyPostfix] [HarmonyPatch("Import")] public static void Import_Postfix(PlanetTransport __instance) diff --git a/NebulaWorld/Logistics/ILSShipManager.cs b/NebulaWorld/Logistics/ILSShipManager.cs index 41620ecbc..537f61f80 100644 --- a/NebulaWorld/Logistics/ILSShipManager.cs +++ b/NebulaWorld/Logistics/ILSShipManager.cs @@ -1,17 +1,15 @@ using NebulaModel.Packets.Logistics; using HarmonyLib; using UnityEngine; -using System.Collections.Generic; using System; using System.Reflection; using NebulaModel.DataStructures; +using NebulaModel.Logger; namespace NebulaWorld.Logistics { public static class ILSShipManager { - public static Dictionary> AddStationComponentQueue = new Dictionary>(); - private static AccessTools.FieldRef FR_stationId; private static AccessTools.FieldRef FR_storageUIs; private static MethodInfo MI_RefreshValues = null; @@ -162,6 +160,7 @@ public static void CreateFakeStationComponent(int GId, int planetId, bool comput AccessTools.Method(typeof(GalacticTransport), "SetStationCapacity").Invoke(GameMain.data.galacticTransport, args); } + GameMain.data.galacticTransport.stationPool[GId] = new StationComponent(); StationComponent stationComponent = GameMain.data.galacticTransport.stationPool[GId]; stationComponent.isStellar = true; @@ -283,28 +282,18 @@ private static void RefreshValuesUI(StationComponent stationComponent, int stora public static void UpdateSlotData(ILSUpdateSlotData packet) { - // PLS - if (packet.StationGId == 0) + Log.Info($"Updating slot data for planet {packet.PlanetId}, station {packet.StationId} gid {packet.StationGId}. Index {packet.Index}, storageIdx {packet.StorageIdx}"); + + // Clients only care about what happens on their planet, hosts always need to apply this. + // Using PlanetFactory to prevent getting the "fakes" that are creates on clients. + if (LocalPlayer.IsMasterClient || (!LocalPlayer.IsMasterClient && packet.PlanetId == GameMain.localPlanet?.id)) { PlanetData pData = GameMain.galaxy.PlanetById(packet.PlanetId); - if (pData?.factory?.transport != null && packet.StationId < pData.factory.transport.stationPool.Length) + StationComponent stationComponent = pData?.factory?.transport?.stationPool[packet.StationId]; + + if (stationComponent?.slots != null) { - StationComponent stationComponent = pData.factory.transport.stationPool[packet.StationId]; - if (stationComponent?.slots != null) - { - stationComponent.slots[packet.Index].storageIdx = packet.StorageIdx; - } - } - } - else // ILS - { - if (packet.StationGId < GameMain.data.galacticTransport.stationPool.Length) - { - StationComponent stationComponent = GameMain.data.galacticTransport.stationPool[packet.StationGId]; - if (stationComponent?.slots != null) - { - stationComponent.slots[packet.Index].storageIdx = packet.StorageIdx; - } + stationComponent.slots[packet.Index].storageIdx = packet.StorageIdx; } } }