diff --git a/NebulaModel/DataStructures/PlayerData.cs b/NebulaModel/DataStructures/PlayerData.cs index 647b98152..461eb92c5 100644 --- a/NebulaModel/DataStructures/PlayerData.cs +++ b/NebulaModel/DataStructures/PlayerData.cs @@ -96,6 +96,25 @@ public void Deserialize(INetDataReader reader) } } + // Old import method + public void DeserializeOld(INetDataReader reader, ushort revision) + { + Username = reader.GetString(); + PlayerId = reader.GetUShort(); + LocalPlanetId = reader.GetInt(); + MechaColors = new Float4[reader.GetInt()]; + for (int i = 0; i < MechaColors.Length; i++) + { + MechaColors[i] = reader.GetFloat4(); + } + LocalPlanetPosition = reader.GetFloat3(); + UPosition = reader.GetDouble3(); + Rotation = reader.GetFloat3(); + BodyRotation = reader.GetFloat3(); + Mecha = new MechaData(); + Mecha.Deserialize(reader); + } + public IPlayerData CreateCopyWithoutMechaData() { return new PlayerData(PlayerId, LocalPlanetId, MechaColors, Username, LocalPlanetPosition, UPosition, Rotation, BodyRotation); diff --git a/NebulaModel/Packets/Belt/BeltUpdatePickupItemsPacket.cs b/NebulaModel/Packets/Factory/Belt/BeltUpdatePickupItemsPacket.cs similarity index 96% rename from NebulaModel/Packets/Belt/BeltUpdatePickupItemsPacket.cs rename to NebulaModel/Packets/Factory/Belt/BeltUpdatePickupItemsPacket.cs index ed04de990..af0e8c993 100644 --- a/NebulaModel/Packets/Belt/BeltUpdatePickupItemsPacket.cs +++ b/NebulaModel/Packets/Factory/Belt/BeltUpdatePickupItemsPacket.cs @@ -1,6 +1,6 @@ using NebulaAPI; -namespace NebulaModel.Packets.Belt +namespace NebulaModel.Packets.Factory.Belt { public class BeltUpdatePickupItemsPacket { diff --git a/NebulaModel/Packets/Belt/BeltUpdatePutItemOnPacket.cs b/NebulaModel/Packets/Factory/Belt/BeltUpdatePutItemOnPacket.cs similarity index 91% rename from NebulaModel/Packets/Belt/BeltUpdatePutItemOnPacket.cs rename to NebulaModel/Packets/Factory/Belt/BeltUpdatePutItemOnPacket.cs index b36d0c63d..b393f6726 100644 --- a/NebulaModel/Packets/Belt/BeltUpdatePutItemOnPacket.cs +++ b/NebulaModel/Packets/Factory/Belt/BeltUpdatePutItemOnPacket.cs @@ -1,4 +1,4 @@ -namespace NebulaModel.Packets.Belt +namespace NebulaModel.Packets.Factory.Belt { public class BeltUpdatePutItemOnPacket { diff --git a/NebulaModel/Packets/Factory/Belt/ConnectToMonitorPacket.cs b/NebulaModel/Packets/Factory/Belt/ConnectToMonitorPacket.cs new file mode 100644 index 000000000..ac3e45cef --- /dev/null +++ b/NebulaModel/Packets/Factory/Belt/ConnectToMonitorPacket.cs @@ -0,0 +1,19 @@ +namespace NebulaModel.Packets.Factory.Belt +{ + public class ConnectToMonitorPacket + { + public int MonitorId { get; set; } + public int BeltId { get; set; } + public int Offset { get; set; } + public int PlanetId { get; set; } + + public ConnectToMonitorPacket() { } + public ConnectToMonitorPacket(int monitorId, int beltId, int offset, int planetId) + { + MonitorId = monitorId; + BeltId = beltId; + Offset = offset; + PlanetId = planetId; + } + } +} diff --git a/NebulaModel/Packets/Factory/Belt/ConnectToSpraycoaterPacket.cs b/NebulaModel/Packets/Factory/Belt/ConnectToSpraycoaterPacket.cs new file mode 100644 index 000000000..fe82f1d21 --- /dev/null +++ b/NebulaModel/Packets/Factory/Belt/ConnectToSpraycoaterPacket.cs @@ -0,0 +1,19 @@ +namespace NebulaModel.Packets.Factory.Belt +{ + public class ConnectToSpraycoaterPacket + { + public int SpraycoaterId { get; set; } + public int CargoBeltId { get; set; } + public int IncBeltId { get; set; } + public int PlanetId { get; set; } + + public ConnectToSpraycoaterPacket() { } + public ConnectToSpraycoaterPacket(int spraycoaterId, int cargoBeltId, int incBeltId, int planetId) + { + SpraycoaterId = spraycoaterId; + CargoBeltId = cargoBeltId; + IncBeltId = incBeltId; + PlanetId = planetId; + } + } +} diff --git a/NebulaModel/Packets/Session/SyncComplete.cs b/NebulaModel/Packets/Session/SyncComplete.cs index 7d98f4d81..25301602e 100644 --- a/NebulaModel/Packets/Session/SyncComplete.cs +++ b/NebulaModel/Packets/Session/SyncComplete.cs @@ -9,7 +9,11 @@ public class SyncComplete public PlayerData[] AllPlayers { get; set; } public byte[] ClientCert { get; set; } - public SyncComplete() { AllPlayers = new PlayerData[] { }; } + public SyncComplete() + { + AllPlayers = new PlayerData[] { }; + ClientCert = new byte[] { }; + } public SyncComplete(IPlayerData[] otherPlayers) { AllPlayers = otherPlayers.Select(data => (PlayerData)data).ToArray(); diff --git a/NebulaNetwork/PacketProcessors/Factory/Belt/BeltUpdatePickupItemsProcessor.cs b/NebulaNetwork/PacketProcessors/Factory/Belt/BeltUpdatePickupItemsProcessor.cs index 0455b4c89..5c54176b0 100644 --- a/NebulaNetwork/PacketProcessors/Factory/Belt/BeltUpdatePickupItemsProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Factory/Belt/BeltUpdatePickupItemsProcessor.cs @@ -2,7 +2,7 @@ using NebulaModel.Logger; using NebulaModel.Networking; using NebulaModel.Packets; -using NebulaModel.Packets.Belt; +using NebulaModel.Packets.Factory.Belt; namespace NebulaNetwork.PacketProcessors.Factory.Belt { diff --git a/NebulaNetwork/PacketProcessors/Factory/Belt/BeltUpdatePutItemOnProcessor.cs b/NebulaNetwork/PacketProcessors/Factory/Belt/BeltUpdatePutItemOnProcessor.cs index 7d29aa66b..5b9b6c620 100644 --- a/NebulaNetwork/PacketProcessors/Factory/Belt/BeltUpdatePutItemOnProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Factory/Belt/BeltUpdatePutItemOnProcessor.cs @@ -2,7 +2,7 @@ using NebulaModel.Logger; using NebulaModel.Networking; using NebulaModel.Packets; -using NebulaModel.Packets.Belt; +using NebulaModel.Packets.Factory.Belt; using NebulaWorld; namespace NebulaNetwork.PacketProcessors.Factory.Belt diff --git a/NebulaNetwork/PacketProcessors/Factory/Belt/ConnectToMonitorProcessor.cs b/NebulaNetwork/PacketProcessors/Factory/Belt/ConnectToMonitorProcessor.cs new file mode 100644 index 000000000..aa7e8b351 --- /dev/null +++ b/NebulaNetwork/PacketProcessors/Factory/Belt/ConnectToMonitorProcessor.cs @@ -0,0 +1,25 @@ +using NebulaAPI; +using NebulaModel.Networking; +using NebulaModel.Packets; +using NebulaModel.Packets.Factory.Belt; +using NebulaWorld; + +namespace NebulaNetwork.PacketProcessors.Factory.Belt +{ + [RegisterPacketProcessor] + internal class ConnectToMonitorProcessor : PacketProcessor + { + public override void ProcessPacket(ConnectToMonitorPacket packet, NebulaConnection conn) + { + using (Multiplayer.Session.Factories.IsIncomingRequest.On()) + { + CargoTraffic cargoTraffic = GameMain.galaxy.PlanetById(packet.PlanetId)?.factory?.cargoTraffic; + if (cargoTraffic == null) + { + return; + } + cargoTraffic.ConnectToMonitor(packet.MonitorId, packet.BeltId, packet.Offset); + } + } + } +} diff --git a/NebulaNetwork/PacketProcessors/Factory/Belt/ConnectToSpraycoaterProcessor.cs b/NebulaNetwork/PacketProcessors/Factory/Belt/ConnectToSpraycoaterProcessor.cs new file mode 100644 index 000000000..df2679be5 --- /dev/null +++ b/NebulaNetwork/PacketProcessors/Factory/Belt/ConnectToSpraycoaterProcessor.cs @@ -0,0 +1,25 @@ +using NebulaAPI; +using NebulaModel.Networking; +using NebulaModel.Packets; +using NebulaModel.Packets.Factory.Belt; +using NebulaWorld; + +namespace NebulaNetwork.PacketProcessors.Factory.Belt +{ + [RegisterPacketProcessor] + internal class ConnectToSpraycoaterProcessor : PacketProcessor + { + public override void ProcessPacket(ConnectToSpraycoaterPacket packet, NebulaConnection conn) + { + using (Multiplayer.Session.Factories.IsIncomingRequest.On()) + { + CargoTraffic cargoTraffic = GameMain.galaxy.PlanetById(packet.PlanetId)?.factory?.cargoTraffic; + if (cargoTraffic == null) + { + return; + } + cargoTraffic.ConnectToSpraycoater(packet.SpraycoaterId, packet.CargoBeltId, packet.IncBeltId); + } + } + } +} \ No newline at end of file diff --git a/NebulaNetwork/PacketProcessors/Factory/Laboratory/LaboratoryUpdateEventProcessor.cs b/NebulaNetwork/PacketProcessors/Factory/Laboratory/LaboratoryUpdateEventProcessor.cs index 814a6bcef..152902a53 100644 --- a/NebulaNetwork/PacketProcessors/Factory/Laboratory/LaboratoryUpdateEventProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Factory/Laboratory/LaboratoryUpdateEventProcessor.cs @@ -2,6 +2,7 @@ using NebulaModel.Networking; using NebulaModel.Packets; using NebulaModel.Packets.Factory.Laboratory; +using NebulaWorld; namespace NebulaNetwork.PacketProcessors.Factory.Labratory { @@ -14,34 +15,38 @@ public override void ProcessPacket(LaboratoryUpdateEventPacket packet, NebulaCon LabComponent[] pool = factory?.factorySystem?.labPool; if (pool != null && packet.LabIndex != -1 && packet.LabIndex < pool.Length && pool[packet.LabIndex].id != -1) { - if (packet.ProductId == -4) + using (Multiplayer.Session.Factories.IsIncomingRequest.On()) { - pool[packet.LabIndex].forceAccMode = !pool[packet.LabIndex].forceAccMode; + Multiplayer.Session.Factories.PacketAuthor = NebulaModAPI.AUTHOR_NONE; + if (packet.ProductId == -4) + { + pool[packet.LabIndex].forceAccMode = !pool[packet.LabIndex].forceAccMode; + } + else if (packet.ProductId == -3) + { + //Widthdraw produced cubes + pool[packet.LabIndex].produced[0] = 0; + } + else if (packet.ProductId == -2) + { + //Research recipe reseted + pool[packet.LabIndex].SetFunction(false, 0, 0, factory.entitySignPool); + } + else if (packet.ProductId == -1) + { + //Center chenged to research-mode + pool[packet.LabIndex].SetFunction(true, 0, GameMain.data.history.currentTech, factory.entitySignPool); + } + else + { + //Cube Recipe changed + int[] matrixIds = LabComponent.matrixIds; + RecipeProto recipeProto = LDB.items.Select(matrixIds[packet.ProductId]).maincraft; + pool[packet.LabIndex].SetFunction(false, (recipeProto == null) ? 0 : recipeProto.ID, 0, factory.entitySignPool); + } + factory.factorySystem?.SyncLabFunctions(GameMain.mainPlayer, packet.LabIndex); + factory.factorySystem?.SyncLabForceAccMode(GameMain.mainPlayer, packet.LabIndex); } - else if (packet.ProductId == -3) - { - //Widthdraw produced cubes - pool[packet.LabIndex].produced[0] = 0; - } - else if (packet.ProductId == -2) - { - //Research recipe reseted - pool[packet.LabIndex].SetFunction(false, 0, 0, factory.entitySignPool); - } - else if (packet.ProductId == -1) - { - //Center chenged to research-mode - pool[packet.LabIndex].SetFunction(true, 0, GameMain.data.history.currentTech, factory.entitySignPool); - } - else - { - //Cube Recipe changed - int[] matrixIds = LabComponent.matrixIds; - RecipeProto recipeProto = LDB.items.Select(matrixIds[packet.ProductId]).maincraft; - pool[packet.LabIndex].SetFunction(false, (recipeProto == null) ? 0 : recipeProto.ID, 0, factory.entitySignPool); - } - factory.factorySystem?.SyncLabFunctions(GameMain.mainPlayer, packet.LabIndex); - factory.factorySystem?.SyncLabForceAccMode(GameMain.mainPlayer, packet.LabIndex); } } } diff --git a/NebulaNetwork/PacketProcessors/Logistics/ILSAddStationComponentProcessor.cs b/NebulaNetwork/PacketProcessors/Logistics/ILSAddStationComponentProcessor.cs index 88d0ce6dd..bfa6d5873 100644 --- a/NebulaNetwork/PacketProcessors/Logistics/ILSAddStationComponentProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Logistics/ILSAddStationComponentProcessor.cs @@ -17,17 +17,16 @@ public override void ProcessPacket(ILSAddStationComponent packet, NebulaConnecti using (Multiplayer.Session.Ships.PatchLockILS.On()) { GalacticTransport galacticTransport = GameMain.data.galacticTransport; - - if (packet.PlanetId == GameMain.localPlanet?.id) + StationComponent[] stationPool = GameMain.galaxy.PlanetById(packet.PlanetId).factory?.transport.stationPool; + if (stationPool != null) { - // 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); + // If we have loaded the factory where the new station was created on, should be able to find + // it in our PlanetTransport.stationPool + galacticTransport.AddStationComponent(packet.PlanetId, stationPool[packet.StationId]); } else { - // If we're not on the same planet as the new station was create on, we need to create a + // If we haven't loaded the factory 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 Multiplayer.Session.Ships.CreateFakeStationComponent(packet.StationGId, packet.PlanetId, packet.MaxShipCount); } diff --git a/NebulaNetwork/PacketProcessors/Players/RemoveDroneOrdersProcessor.cs b/NebulaNetwork/PacketProcessors/Players/RemoveDroneOrdersProcessor.cs index ffca839cb..c8cb3cb6b 100644 --- a/NebulaNetwork/PacketProcessors/Players/RemoveDroneOrdersProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Players/RemoveDroneOrdersProcessor.cs @@ -1,8 +1,10 @@ -using NebulaModel.Networking; +using NebulaAPI; +using NebulaModel.Networking; using NebulaModel.Packets; namespace NebulaNetwork.PacketProcessors.Players { + [RegisterPacketProcessor] internal class RemoveDroneOrdersProcessor : PacketProcessor { public override void ProcessPacket(RemoveDroneOrdersPacket packet, NebulaConnection conn) diff --git a/NebulaNetwork/PacketProcessors/Session/LobbyRequestProcessor.cs b/NebulaNetwork/PacketProcessors/Session/LobbyRequestProcessor.cs index a00755ed8..ee72c4a97 100644 --- a/NebulaNetwork/PacketProcessors/Session/LobbyRequestProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Session/LobbyRequestProcessor.cs @@ -128,6 +128,12 @@ public override void ProcessPacket(LobbyRequest packet, NebulaConnection conn) // if user is known and host is ingame dont put him into lobby but let him join the game if (!isNewUser && Multiplayer.Session.IsGameLoaded) { + // Remove the new player from pending list + using (playerManager.GetPendingPlayers(out Dictionary pendingPlayers)) + { + pendingPlayers.Remove(conn); + } + // Add the new player to the list using (playerManager.GetSyncingPlayers(out Dictionary syncingPlayers)) { diff --git a/NebulaNetwork/SaveManager.cs b/NebulaNetwork/SaveManager.cs index 66cf8066b..c110b0949 100644 --- a/NebulaNetwork/SaveManager.cs +++ b/NebulaNetwork/SaveManager.cs @@ -92,6 +92,7 @@ public static void LoadServerData() byte[] source = File.ReadAllBytes(path); NetDataReader netDataReader = new NetDataReader(source); + ushort revision = 0; try { string revString = netDataReader.GetString(); @@ -100,10 +101,15 @@ public static void LoadServerData() throw new System.Exception(); } - ushort revision = netDataReader.GetUShort(); + revision = netDataReader.GetUShort(); + NebulaModel.Logger.Log.Info($"Loading server data, revision {revision}"); if (revision != REVISION) { - throw new System.Exception(); + // Supported revision: 4~5 + if (revision < 4 || revision > REVISION) + { + throw new System.Exception(); + } } } catch (System.Exception) @@ -119,8 +125,16 @@ public static void LoadServerData() for (int i = 0; i < playerNum; i++) { string hash = netDataReader.GetString(); - - PlayerData playerData = netDataReader.Get(); + PlayerData playerData; + if (revision == REVISION) + { + playerData = netDataReader.Get(); + } + else + { + playerData = new PlayerData(); + playerData.DeserializeOld(netDataReader, revision); + } if (!savedPlayerData.ContainsKey(hash)) { savedPlayerData.Add(hash, playerData); diff --git a/NebulaPatcher/Patches/Dynamic/BuildTool_Common_Patch.cs b/NebulaPatcher/Patches/Dynamic/BuildTool_Common_Patch.cs index 373c0f66e..b47330c5c 100644 --- a/NebulaPatcher/Patches/Dynamic/BuildTool_Common_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/BuildTool_Common_Patch.cs @@ -31,6 +31,8 @@ public static bool CreatePrebuilds_Prefix(BuildTool __instance) } if(__instance is BuildTool_PathAddon) { + // traffic monitors & sprayers cannot be drag build atm, so its always only one. + previews = new List(); previews.Add(((BuildTool_PathAddon)__instance).handbp); } diff --git a/NebulaPatcher/Patches/Dynamic/CargoTraffic_Patch.cs b/NebulaPatcher/Patches/Dynamic/CargoTraffic_Patch.cs index cffe1f028..f3801b0a6 100644 --- a/NebulaPatcher/Patches/Dynamic/CargoTraffic_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/CargoTraffic_Patch.cs @@ -1,6 +1,6 @@ using HarmonyLib; using NebulaAPI; -using NebulaModel.Packets.Belt; +using NebulaModel.Packets.Factory.Belt; using NebulaWorld; namespace NebulaPatcher.Patches.Dynamic @@ -78,5 +78,35 @@ public static bool RefreshPathUV_Prefix() //Do not call renderer, if user is not on the planet as the request return !Multiplayer.IsActive || Multiplayer.Session.Factories.TargetPlanet == NebulaModAPI.PLANET_NONE || GameMain.mainPlayer.planetId == Multiplayer.Session.Factories.TargetPlanet; } + + [HarmonyPostfix] + [HarmonyPatch(nameof(CargoTraffic.ConnectToMonitor))] + public static void ConnectToMonitor_Postfix(int monitorId, int targetBeltId, int offset) + { + if (!Multiplayer.IsActive) + { + return; + } + // If host build, or client receive his build request + if((Multiplayer.Session.LocalPlayer.IsHost && !Multiplayer.Session.Factories.IsIncomingRequest.Value)|| Multiplayer.Session.Factories.PacketAuthor == Multiplayer.Session.LocalPlayer.Id) + { + Multiplayer.Session.Network.SendPacketToLocalStar(new ConnectToMonitorPacket(monitorId, targetBeltId, offset, GameMain.data.localPlanet.id)); + } + } + + [HarmonyPostfix] + [HarmonyPatch(nameof(CargoTraffic.ConnectToSpraycoater))] + public static void ConnectToSpraycoater(int spraycoaterId, int cargoBeltId, int incBeltId) + { + if (!Multiplayer.IsActive) + { + return; + } + // If host build, or client receive his build request + if ((Multiplayer.Session.LocalPlayer.IsHost && !Multiplayer.Session.Factories.IsIncomingRequest.Value) || Multiplayer.Session.Factories.PacketAuthor == Multiplayer.Session.LocalPlayer.Id) + { + Multiplayer.Session.Network.SendPacketToLocalStar(new ConnectToSpraycoaterPacket(spraycoaterId, cargoBeltId, incBeltId, GameMain.data.localPlanet.id)); + } + } } } diff --git a/NebulaPatcher/Patches/Dynamic/SpeakerComponent_Patch.cs b/NebulaPatcher/Patches/Dynamic/SpeakerComponent_Patch.cs index 0d0a47d24..3d9ff0fe1 100644 --- a/NebulaPatcher/Patches/Dynamic/SpeakerComponent_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/SpeakerComponent_Patch.cs @@ -51,7 +51,6 @@ public static void SetPitch_Prefix(MonitorComponent __instance, int __0) [HarmonyPatch(nameof(SpeakerComponent.SetLength))] public static void SetLength_Prefix(MonitorComponent __instance, float __0) { - Log.Info($"SetLength {__0} {Multiplayer.Session.Warning.IsIncomingMonitorPacket == true}"); if (Multiplayer.IsActive && !Multiplayer.Session.Warning.IsIncomingMonitorPacket) { int planetId = GameMain.data.localPlanet == null ? -1 : GameMain.data.localPlanet.id; @@ -77,7 +76,6 @@ public static void SetLength_Prefix(MonitorComponent __instance, bool __0) [HarmonyPatch(nameof(SpeakerComponent.SetFalloffRadius))] public static void SetFalloffRadius_Prefix(MonitorComponent __instance, float __0, float __1) { - Log.Info($"SetFalloffRadius {__0} {__1} {Multiplayer.Session.Warning.IsIncomingMonitorPacket == true}"); if (Multiplayer.IsActive && !Multiplayer.Session.Warning.IsIncomingMonitorPacket) { int planetId = GameMain.data.localPlanet == null ? -1 : GameMain.data.localPlanet.id; diff --git a/NebulaWorld/Factory/BeltManager.cs b/NebulaWorld/Factory/BeltManager.cs index ae17138c9..d4e856657 100644 --- a/NebulaWorld/Factory/BeltManager.cs +++ b/NebulaWorld/Factory/BeltManager.cs @@ -1,4 +1,4 @@ -using NebulaModel.Packets.Belt; +using NebulaModel.Packets.Factory.Belt; using System; using System.Collections.Generic; diff --git a/NebulaWorld/Factory/BuildToolManager.cs b/NebulaWorld/Factory/BuildToolManager.cs index 99b52d5e6..b9f5bc0ff 100644 --- a/NebulaWorld/Factory/BuildToolManager.cs +++ b/NebulaWorld/Factory/BuildToolManager.cs @@ -258,6 +258,7 @@ public bool InitialCheck(Vector3 pos) if ((now - LastCheckTime) < WAIT_TIME && LastPosition == pos) { //Stop client from sending prebuilds at the same position + UIRealtimeTip.Popup("Please wait for server respond"); return false; } LastCheckTime = now; diff --git a/NebulaWorld/Logistics/StationUIManager.cs b/NebulaWorld/Logistics/StationUIManager.cs index 8dd1510c9..bd3a20f4e 100644 --- a/NebulaWorld/Logistics/StationUIManager.cs +++ b/NebulaWorld/Logistics/StationUIManager.cs @@ -77,7 +77,7 @@ private void UpdateSettingsUI(StationComponent stationComponent, ref StationUI p case StationUI.EUISettings.MaxChargePower: { PlanetData planet = GameMain.galaxy.PlanetById(packet.PlanetId); - if (planet.factory?.powerSystem != null) + if (planet?.factory?.powerSystem?.consumerPool != null) { PowerConsumerComponent[] consumerPool = planet.factory.powerSystem.consumerPool; if (consumerPool.Length > stationComponent.pcId) @@ -205,13 +205,16 @@ private void UpdateSettingsUI(StationComponent stationComponent, ref StationUI p } case StationUI.EUISettings.MaxMiningSpeed: { - PlanetFactory factory = GameMain.galaxy.PlanetById(packet.PlanetId).factory; + PlanetFactory factory = GameMain.galaxy.PlanetById(packet.PlanetId)?.factory; if (factory != null) { int speed = 10000 + (int)(packet.SettingValue + 0.5f) * 1000; - long workEnergyPrefab = LDB.items.Select(factory.entityPool[stationComponent.entityId].protoId).prefabDesc.workEnergyPerTick; - factory.factorySystem.minerPool[stationComponent.minerId].speed = speed; - factory.powerSystem.consumerPool[stationComponent.pcId].workEnergyPerTick = (long)(workEnergyPrefab * (speed / 10000f) * (speed / 10000f)); + PrefabDesc workEnergyPrefab = LDB.items.Select(factory.entityPool[stationComponent.entityId].protoId)?.prefabDesc; + if (workEnergyPrefab != null && factory.factorySystem?.minerPool != null && factory.powerSystem?.consumerPool != null) + { + factory.factorySystem.minerPool[stationComponent.minerId].speed = speed; + factory.powerSystem.consumerPool[stationComponent.pcId].workEnergyPerTick = (long)(workEnergyPrefab.workEnergyPerTick * (speed / 10000f) * (speed / 10000f)); + } } break; }