diff --git a/NebulaModel/DataStructures/MechaData.cs b/NebulaModel/DataStructures/MechaData.cs index 64e162491..3826786b8 100644 --- a/NebulaModel/DataStructures/MechaData.cs +++ b/NebulaModel/DataStructures/MechaData.cs @@ -4,7 +4,6 @@ using NebulaAPI.DataStructures; using NebulaAPI.Interfaces; using NebulaAPI.Packets; -using NebulaModel.Packets.Players; using static NebulaModel.Networking.BinaryUtils; #endregion diff --git a/NebulaModel/Packets/Players/PlayerTechBonuses.cs b/NebulaModel/DataStructures/PlayerTechBonuses.cs similarity index 99% rename from NebulaModel/Packets/Players/PlayerTechBonuses.cs rename to NebulaModel/DataStructures/PlayerTechBonuses.cs index d0061bf20..e2fe201ea 100644 --- a/NebulaModel/Packets/Players/PlayerTechBonuses.cs +++ b/NebulaModel/DataStructures/PlayerTechBonuses.cs @@ -2,11 +2,10 @@ using NebulaAPI.DataStructures; using NebulaAPI.Interfaces; -using static NebulaModel.Networking.BinaryUtils; #endregion -namespace NebulaModel.Packets.Players; +namespace NebulaModel.DataStructures; public class PlayerTechBonuses : IPlayerTechBonuses { diff --git a/NebulaModel/Packets/GameHistory/GameHistoryResearchUpdatePacket.cs b/NebulaModel/Packets/GameHistory/GameHistoryResearchUpdatePacket.cs index be517afde..a207a9e9f 100644 --- a/NebulaModel/Packets/GameHistory/GameHistoryResearchUpdatePacket.cs +++ b/NebulaModel/Packets/GameHistory/GameHistoryResearchUpdatePacket.cs @@ -4,16 +4,18 @@ public class GameHistoryResearchUpdatePacket { public GameHistoryResearchUpdatePacket() { } - public GameHistoryResearchUpdatePacket(int techId, long hashUploaded, long hashNeeded, int techHashedFor10Frames) + public GameHistoryResearchUpdatePacket(int techId, long hashUploaded, long hashNeeded, int techHashedFor10Frames, int techQueueLength) { TechId = techId; HashUploaded = hashUploaded; HashNeeded = hashNeeded; TechHashedFor10Frames = techHashedFor10Frames; + TechQueueLength = (ushort)techQueueLength; } public int TechId { get; set; } public long HashUploaded { get; set; } public long HashNeeded { get; set; } public int TechHashedFor10Frames { get; set; } + public ushort TechQueueLength { get; set; } } diff --git a/NebulaModel/Packets/GameHistory/GameHistoryTechQueueSyncRequest.cs b/NebulaModel/Packets/GameHistory/GameHistoryTechQueueSyncRequest.cs new file mode 100644 index 000000000..f6208aee7 --- /dev/null +++ b/NebulaModel/Packets/GameHistory/GameHistoryTechQueueSyncRequest.cs @@ -0,0 +1,13 @@ +namespace NebulaModel.Packets.GameHistory; + +public class GameHistoryTechQueueSyncRequest +{ + public GameHistoryTechQueueSyncRequest() { } + + public GameHistoryTechQueueSyncRequest(int[] techQueue) + { + TechQueue = techQueue; + } + + public int[] TechQueue { get; set; } +} diff --git a/NebulaModel/Packets/Session/GlobalGameDataResponse.cs b/NebulaModel/Packets/Session/GlobalGameDataResponse.cs index b69f44dc9..d46621a08 100644 --- a/NebulaModel/Packets/Session/GlobalGameDataResponse.cs +++ b/NebulaModel/Packets/Session/GlobalGameDataResponse.cs @@ -4,20 +4,21 @@ public class GlobalGameDataResponse { public GlobalGameDataResponse() { } - public GlobalGameDataResponse(bool sandboxToolsEnabled, - byte[] historyBinaryData, byte[] spaceSectorBinaryData, - byte[] milestoneSystemBinaryData, byte[] trashSystemBinaryData) + public GlobalGameDataResponse(EDataType dataType, byte[] binaryData) { - SandboxToolsEnabled = sandboxToolsEnabled; - HistoryBinaryData = historyBinaryData; - SpaceSectorBinaryData = spaceSectorBinaryData; - MilestoneSystemBinaryData = milestoneSystemBinaryData; - TrashSystemBinaryData = trashSystemBinaryData; + DataType = dataType; + BinaryData = binaryData; } - public bool SandboxToolsEnabled { get; set; } - public byte[] HistoryBinaryData { get; set; } - public byte[] SpaceSectorBinaryData { get; set; } - public byte[] MilestoneSystemBinaryData { get; set; } - public byte[] TrashSystemBinaryData { get; set; } + public enum EDataType : byte + { + History = 1, + SpaceSector, + MilestoneSystem, + TrashSystem, + Ready + } + + public EDataType DataType { get; set; } + public byte[] BinaryData { get; set; } } diff --git a/NebulaNetwork/PacketProcessors/Factory/Entity/BuildEntityRequestProcessor.cs b/NebulaNetwork/PacketProcessors/Factory/BuildEntityRequestProcessor.cs similarity index 97% rename from NebulaNetwork/PacketProcessors/Factory/Entity/BuildEntityRequestProcessor.cs rename to NebulaNetwork/PacketProcessors/Factory/BuildEntityRequestProcessor.cs index f4d48a355..8017eae7f 100644 --- a/NebulaNetwork/PacketProcessors/Factory/Entity/BuildEntityRequestProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Factory/BuildEntityRequestProcessor.cs @@ -13,7 +13,7 @@ #endregion -namespace NebulaNetwork.PacketProcessors.Factory.Entity; +namespace NebulaNetwork.PacketProcessors.Factory; [RegisterPacketProcessor] public class BuildEntityRequestProcessor : PacketProcessor diff --git a/NebulaNetwork/PacketProcessors/Factory/Entity/CreatePrebuildsRequestProcessor.cs b/NebulaNetwork/PacketProcessors/Factory/CreatePrebuildsRequestProcessor.cs similarity index 93% rename from NebulaNetwork/PacketProcessors/Factory/Entity/CreatePrebuildsRequestProcessor.cs rename to NebulaNetwork/PacketProcessors/Factory/CreatePrebuildsRequestProcessor.cs index 7f67d5e5c..c8fe070c1 100644 --- a/NebulaNetwork/PacketProcessors/Factory/Entity/CreatePrebuildsRequestProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Factory/CreatePrebuildsRequestProcessor.cs @@ -8,7 +8,7 @@ #endregion -namespace NebulaNetwork.PacketProcessors.Factory.Entity; +namespace NebulaNetwork.PacketProcessors.Factory; [RegisterPacketProcessor] internal class CreatePrebuildsRequestProcessor : PacketProcessor diff --git a/NebulaNetwork/PacketProcessors/Factory/Entity/DestructEntityRequestProcessor.cs b/NebulaNetwork/PacketProcessors/Factory/DestructEntityRequestProcessor.cs similarity index 97% rename from NebulaNetwork/PacketProcessors/Factory/Entity/DestructEntityRequestProcessor.cs rename to NebulaNetwork/PacketProcessors/Factory/DestructEntityRequestProcessor.cs index 120defdc7..9f3813b9b 100644 --- a/NebulaNetwork/PacketProcessors/Factory/Entity/DestructEntityRequestProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Factory/DestructEntityRequestProcessor.cs @@ -9,7 +9,7 @@ #endregion -namespace NebulaNetwork.PacketProcessors.Factory.Entity; +namespace NebulaNetwork.PacketProcessors.Factory; [RegisterPacketProcessor] public class DestructEntityRequestProcessor : PacketProcessor diff --git a/NebulaNetwork/PacketProcessors/Factory/Entity/EntityBoostSwitchProcessor.cs b/NebulaNetwork/PacketProcessors/Factory/EntityBoostSwitchProcessor.cs similarity index 97% rename from NebulaNetwork/PacketProcessors/Factory/Entity/EntityBoostSwitchProcessor.cs rename to NebulaNetwork/PacketProcessors/Factory/EntityBoostSwitchProcessor.cs index 618d6c262..20bea5db4 100644 --- a/NebulaNetwork/PacketProcessors/Factory/Entity/EntityBoostSwitchProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Factory/EntityBoostSwitchProcessor.cs @@ -8,7 +8,7 @@ #endregion -namespace NebulaNetwork.PacketProcessors.Factory.Entity; +namespace NebulaNetwork.PacketProcessors.Factory; [RegisterPacketProcessor] internal class EntityBoostSwitchProcessor : PacketProcessor diff --git a/NebulaNetwork/PacketProcessors/Factory/Entity/EntityWarningSwitchProcessor.cs b/NebulaNetwork/PacketProcessors/Factory/EntityWarningSwitchProcessor.cs similarity index 95% rename from NebulaNetwork/PacketProcessors/Factory/Entity/EntityWarningSwitchProcessor.cs rename to NebulaNetwork/PacketProcessors/Factory/EntityWarningSwitchProcessor.cs index 3506258c3..b33e8cb61 100644 --- a/NebulaNetwork/PacketProcessors/Factory/Entity/EntityWarningSwitchProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Factory/EntityWarningSwitchProcessor.cs @@ -7,7 +7,7 @@ #endregion -namespace NebulaNetwork.PacketProcessors.Factory.Entity; +namespace NebulaNetwork.PacketProcessors.Factory; [RegisterPacketProcessor] internal class EntityWarningSwitchProcessor : PacketProcessor diff --git a/NebulaNetwork/PacketProcessors/Factory/Entity/ExtraInfoUpdateProcessor.cs b/NebulaNetwork/PacketProcessors/Factory/ExtraInfoUpdateProcessor.cs similarity index 95% rename from NebulaNetwork/PacketProcessors/Factory/Entity/ExtraInfoUpdateProcessor.cs rename to NebulaNetwork/PacketProcessors/Factory/ExtraInfoUpdateProcessor.cs index d77910928..19e6b04b2 100644 --- a/NebulaNetwork/PacketProcessors/Factory/Entity/ExtraInfoUpdateProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Factory/ExtraInfoUpdateProcessor.cs @@ -8,7 +8,7 @@ #endregion -namespace NebulaNetwork.PacketProcessors.Factory.Entity; +namespace NebulaNetwork.PacketProcessors.Factory; [RegisterPacketProcessor] internal class ExtraInfoUpdateProcessor : PacketProcessor diff --git a/NebulaNetwork/PacketProcessors/Factory/Inserter/InserterItemUpdatePacket.cs b/NebulaNetwork/PacketProcessors/Factory/Inserter/InserterItemUpdateProcessor.cs similarity index 100% rename from NebulaNetwork/PacketProcessors/Factory/Inserter/InserterItemUpdatePacket.cs rename to NebulaNetwork/PacketProcessors/Factory/Inserter/InserterItemUpdateProcessor.cs diff --git a/NebulaNetwork/PacketProcessors/Factory/Entity/KillEntityRequestProcessor.cs b/NebulaNetwork/PacketProcessors/Factory/KillEntityRequestProcessor.cs similarity index 89% rename from NebulaNetwork/PacketProcessors/Factory/Entity/KillEntityRequestProcessor.cs rename to NebulaNetwork/PacketProcessors/Factory/KillEntityRequestProcessor.cs index 197b5d5a0..96ff2eb96 100644 --- a/NebulaNetwork/PacketProcessors/Factory/Entity/KillEntityRequestProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Factory/KillEntityRequestProcessor.cs @@ -10,7 +10,7 @@ #endregion -namespace NebulaNetwork.PacketProcessors.Factory.Entity; +namespace NebulaNetwork.PacketProcessors.Factory; [RegisterPacketProcessor] public class KillEntityRequestProcessor : PacketProcessor @@ -23,6 +23,7 @@ protected override void ProcessPacket(KillEntityRequest packet, NebulaConnection using (Multiplayer.Session.Factories.IsIncomingRequest.On()) { Multiplayer.Session.Factories.TargetPlanet = packet.PlanetId; + Multiplayer.Session.Factories.EventFactory = factory; if (!factory.planet.factoryLoaded) { @@ -41,6 +42,7 @@ protected override void ProcessPacket(KillEntityRequest packet, NebulaConnection } Multiplayer.Session.Factories.TargetPlanet = NebulaModAPI.PLANET_NONE; + Multiplayer.Session.Factories.EventFactory = null; } } } diff --git a/NebulaNetwork/PacketProcessors/Factory/Entity/PasteBuildingSettingUpdateProcessor.cs b/NebulaNetwork/PacketProcessors/Factory/PasteBuildingSettingUpdateProcessor.cs similarity index 94% rename from NebulaNetwork/PacketProcessors/Factory/Entity/PasteBuildingSettingUpdateProcessor.cs rename to NebulaNetwork/PacketProcessors/Factory/PasteBuildingSettingUpdateProcessor.cs index 6ea0b2950..49776859f 100644 --- a/NebulaNetwork/PacketProcessors/Factory/Entity/PasteBuildingSettingUpdateProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Factory/PasteBuildingSettingUpdateProcessor.cs @@ -8,7 +8,7 @@ #endregion -namespace NebulaNetwork.PacketProcessors.Factory.Entity; +namespace NebulaNetwork.PacketProcessors.Factory; // Processes pasting settings (e.g. item to make in an assembler) onto buildings events [RegisterPacketProcessor] diff --git a/NebulaNetwork/PacketProcessors/Factory/Entity/PrebuildItemRequiredUpdateProcessor.cs b/NebulaNetwork/PacketProcessors/Factory/PrebuildItemRequiredUpdateProcessor.cs similarity index 96% rename from NebulaNetwork/PacketProcessors/Factory/Entity/PrebuildItemRequiredUpdateProcessor.cs rename to NebulaNetwork/PacketProcessors/Factory/PrebuildItemRequiredUpdateProcessor.cs index 49e4fa120..f5d7ff941 100644 --- a/NebulaNetwork/PacketProcessors/Factory/Entity/PrebuildItemRequiredUpdateProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Factory/PrebuildItemRequiredUpdateProcessor.cs @@ -9,7 +9,7 @@ #endregion -namespace NebulaNetwork.PacketProcessors.Factory.Entity; +namespace NebulaNetwork.PacketProcessors.Factory; [RegisterPacketProcessor] public class PrebuildItemRequiredUpdateProcessor : PacketProcessor diff --git a/NebulaNetwork/PacketProcessors/Factory/Entity/PrebuildReconstructProcessor.cs b/NebulaNetwork/PacketProcessors/Factory/PrebuildReconstructProcessor.cs similarity index 94% rename from NebulaNetwork/PacketProcessors/Factory/Entity/PrebuildReconstructProcessor.cs rename to NebulaNetwork/PacketProcessors/Factory/PrebuildReconstructProcessor.cs index 3f515584d..ec9ab662c 100644 --- a/NebulaNetwork/PacketProcessors/Factory/Entity/PrebuildReconstructProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Factory/PrebuildReconstructProcessor.cs @@ -8,7 +8,7 @@ #endregion -namespace NebulaNetwork.PacketProcessors.Factory.Entity; +namespace NebulaNetwork.PacketProcessors.Factory; [RegisterPacketProcessor] public class PrebuildReconstructProcessor : PacketProcessor diff --git a/NebulaNetwork/PacketProcessors/Factory/Entity/UpgradeEntityRequestProcessor.cs b/NebulaNetwork/PacketProcessors/Factory/UpgradeEntityRequestProcessor.cs similarity index 96% rename from NebulaNetwork/PacketProcessors/Factory/Entity/UpgradeEntityRequestProcessor.cs rename to NebulaNetwork/PacketProcessors/Factory/UpgradeEntityRequestProcessor.cs index 5a7920d0f..658715889 100644 --- a/NebulaNetwork/PacketProcessors/Factory/Entity/UpgradeEntityRequestProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Factory/UpgradeEntityRequestProcessor.cs @@ -9,7 +9,7 @@ #endregion -namespace NebulaNetwork.PacketProcessors.Factory.Entity; +namespace NebulaNetwork.PacketProcessors.Factory; [RegisterPacketProcessor] public class UpgradeEntityRequestProcessor : PacketProcessor diff --git a/NebulaNetwork/PacketProcessors/GameHistory/GameHistoryResearchUpdateProcessor.cs b/NebulaNetwork/PacketProcessors/GameHistory/GameHistoryResearchUpdateProcessor.cs index 5ebac0789..85cd5b08d 100644 --- a/NebulaNetwork/PacketProcessors/GameHistory/GameHistoryResearchUpdateProcessor.cs +++ b/NebulaNetwork/PacketProcessors/GameHistory/GameHistoryResearchUpdateProcessor.cs @@ -1,5 +1,6 @@ #region +using System; using NebulaAPI.Packets; using NebulaModel.Logger; using NebulaModel.Networking; @@ -29,5 +30,11 @@ protected override void ProcessPacket(GameHistoryResearchUpdatePacket packet, Ne state.hashNeeded = packet.HashNeeded; data.techStates[data.currentTech] = state; Multiplayer.Session.Statistics.TechHashedFor10Frames = packet.TechHashedFor10Frames; + + if (packet.TechQueueLength != GameMain.history.techQueueLength) + { + // TechQueue length mismatch. Ask from server to get a full queue to stay in sync + conn.SendPacket(new GameHistoryTechQueueSyncRequest([])); + } } } diff --git a/NebulaNetwork/PacketProcessors/GameHistory/GameHistoryTechQueueSyncProcessor.cs b/NebulaNetwork/PacketProcessors/GameHistory/GameHistoryTechQueueSyncProcessor.cs new file mode 100644 index 000000000..b3f83f562 --- /dev/null +++ b/NebulaNetwork/PacketProcessors/GameHistory/GameHistoryTechQueueSyncProcessor.cs @@ -0,0 +1,42 @@ +#region + +using NebulaAPI.GameState; +using NebulaAPI.Packets; +using NebulaModel.Networking; +using NebulaModel.Packets; +using NebulaModel.Packets.GameHistory; +using NebulaWorld; + +#endregion + +namespace NebulaNetwork.PacketProcessors.GameHistory; + +[RegisterPacketProcessor] +internal class GameHistoryTechQueueSyncProcessor : PacketProcessor +{ + protected override void ProcessPacket(GameHistoryTechQueueSyncRequest packet, NebulaConnection conn) + { + if (IsHost) + { + packet.TechQueue = GameMain.history.techQueue; + conn.SendPacket(packet); + } + else + { + using (Multiplayer.Session.History.IsIncomingRequest.On()) + { + var length = GameMain.history.techQueue.Length; + for (var i = 0; i < length; i++) + { + // Clear the original queue by dequeue for compatibility + GameMain.history.DequeueTech(); + } + for (var i = 0; i < packet.TechQueue.Length; i++) + { + if (packet.TechQueue[i] == 0) return; + GameMain.history.EnqueueTech(packet.TechQueue[i]); + } + } + } + } +} diff --git a/NebulaNetwork/PacketProcessors/Players/PlayerMechaDataProcessor.cs b/NebulaNetwork/PacketProcessors/Players/PlayerMechaDataProcessor.cs index cbd9407bc..9bcd92fae 100644 --- a/NebulaNetwork/PacketProcessors/Players/PlayerMechaDataProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Players/PlayerMechaDataProcessor.cs @@ -2,6 +2,7 @@ using NebulaAPI.Packets; using NebulaModel; +using NebulaModel.Logger; using NebulaModel.Networking; using NebulaModel.Packets; using NebulaModel.Packets.Players; @@ -26,6 +27,11 @@ protected override void ProcessPacket(PlayerMechaData packet, NebulaConnection c } var player = Multiplayer.Session.Server.Players.Get(conn); + if (player == null) + { + Log.Warn("Can't find the connected player for PlayerMechaData!"); + return; + } //Find correct player for data to update, preserve sand count if syncing is enabled var sandCount = player.Data.Mecha.SandCount; diff --git a/NebulaNetwork/PacketProcessors/Session/GlobalGameDataRequestProcessor.cs b/NebulaNetwork/PacketProcessors/Session/GlobalGameDataRequestProcessor.cs index 27c4b278d..5f22d460f 100644 --- a/NebulaNetwork/PacketProcessors/Session/GlobalGameDataRequestProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Session/GlobalGameDataRequestProcessor.cs @@ -3,7 +3,6 @@ using NebulaAPI.Packets; using NebulaModel.Networking; using NebulaModel.Packets; -using NebulaModel.Packets.GameStates; using NebulaModel.Packets.Session; #endregion @@ -21,46 +20,51 @@ protected override void ProcessPacket(GlobalGameDataRequest packet, NebulaConnec } //Export GameHistoryData, SpaceSector, TrashSystem, MilestoneSystem - //PlanetFactory, Dysonsphere, GalacticTransport will be handle else where - var responsePacket = new GlobalGameDataResponse(); - var totalSize = 0; + //PlanetFactory, Dysonsphere, GalacticTransport will be handle else where using (var writer = new BinaryUtils.Writer()) { GameMain.history.Export(writer.BinaryWriter); - responsePacket.SandboxToolsEnabled = GameMain.sandboxToolsEnabled; - responsePacket.HistoryBinaryData = writer.CloseAndGetBytes(); - totalSize += responsePacket.HistoryBinaryData.Length; + + conn.SendPacket(new GlobalGameDataResponse( + GlobalGameDataResponse.EDataType.History, writer.CloseAndGetBytes())); } using (var writer = new BinaryUtils.Writer()) { - // Initial syncing from vanilla, to be refined later in future. + // Note: Initial syncing from vanilla. May be refined later in future NebulaWorld.Combat.CombatManager.SerializeOverwrite = true; GameMain.data.spaceSector.BeginSave(); GameMain.data.spaceSector.Export(writer.BinaryWriter); GameMain.data.spaceSector.EndSave(); NebulaWorld.Combat.CombatManager.SerializeOverwrite = false; - responsePacket.SpaceSectorBinaryData = writer.CloseAndGetBytes(); - totalSize += responsePacket.SpaceSectorBinaryData.Length; + conn.SendPacket(new GlobalGameDataResponse( + GlobalGameDataResponse.EDataType.SpaceSector, writer.CloseAndGetBytes())); } using (var writer = new BinaryUtils.Writer()) { GameMain.data.milestoneSystem.Export(writer.BinaryWriter); - responsePacket.MilestoneSystemBinaryData = writer.CloseAndGetBytes(); - totalSize += responsePacket.MilestoneSystemBinaryData.Length; + + conn.SendPacket(new GlobalGameDataResponse( + GlobalGameDataResponse.EDataType.MilestoneSystem, writer.CloseAndGetBytes())); } using (var writer = new BinaryUtils.Writer()) { GameMain.data.trashSystem.Export(writer.BinaryWriter); - responsePacket.TrashSystemBinaryData = writer.CloseAndGetBytes(); - totalSize += responsePacket.TrashSystemBinaryData.Length; + + conn.SendPacket(new GlobalGameDataResponse( + GlobalGameDataResponse.EDataType.TrashSystem, writer.CloseAndGetBytes())); } - conn.SendPacket(new FragmentInfo(totalSize)); - conn.SendPacket(responsePacket); + using (var writer = new BinaryUtils.Writer()) + { + writer.BinaryWriter.Write(GameMain.sandboxToolsEnabled); + + conn.SendPacket(new GlobalGameDataResponse( + GlobalGameDataResponse.EDataType.Ready, writer.CloseAndGetBytes())); + } } } diff --git a/NebulaNetwork/PacketProcessors/Session/GlobalGameDataResponseProcessor.cs b/NebulaNetwork/PacketProcessors/Session/GlobalGameDataResponseProcessor.cs index 9c48981d1..fbb36e4ba 100644 --- a/NebulaNetwork/PacketProcessors/Session/GlobalGameDataResponseProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Session/GlobalGameDataResponseProcessor.cs @@ -17,13 +17,7 @@ protected override void ProcessPacket(GlobalGameDataResponse packet, NebulaConne { if (IsHost) return; - // The whole fragment is received - GameStatesManager.FragmentSize = 0; - // Store the binary data in GameStatesManager then later overwrite those system in GameData.NewGame GameStatesManager.ImportGlobalGameData(packet); - - // We are ready to start the game now - DSPGame.StartGameSkipPrologue(DSPGame.GameDesc); } } diff --git a/NebulaNetwork/PacketProcessors/Session/HandshakeResponseProcessor.cs b/NebulaNetwork/PacketProcessors/Session/HandshakeResponseProcessor.cs index 9045eaadd..690d04792 100644 --- a/NebulaNetwork/PacketProcessors/Session/HandshakeResponseProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Session/HandshakeResponseProcessor.cs @@ -57,6 +57,8 @@ protected override void ProcessPacket(HandshakeResponse packet, NebulaConnection Multiplayer.Session.Network.SendPacket(new GlobalGameDataRequest()); if (DSPGame.Game != null) { + // Client: Close planetDetail before requesting to prevent error + UIRoot.instance.uiGame.SetPlanetDetail(null); DSPGame.EndGame(); } // Prepare gameDesc to later start in GlobalGameDataResponseProcessor diff --git a/NebulaNetwork/Server.cs b/NebulaNetwork/Server.cs index 1768882e1..029864dc5 100644 --- a/NebulaNetwork/Server.cs +++ b/NebulaNetwork/Server.cs @@ -418,7 +418,7 @@ public void Update() { var state = GameMain.data.history.techStates[GameMain.data.history.currentTech]; SendPacket(new GameHistoryResearchUpdatePacket(GameMain.data.history.currentTech, state.hashUploaded, - state.hashNeeded, GameMain.statistics.techHashedFor10Frames)); + state.hashNeeded, GameMain.statistics.techHashedFor10Frames, GameMain.data.history.techQueueLength)); } } diff --git a/NebulaPatcher/Patches/Transpilers/PlanetFactory_Transpiler.cs b/NebulaPatcher/Patches/Transpilers/PlanetFactory_Transpiler.cs index bf9deb52c..edfb6f8c5 100644 --- a/NebulaPatcher/Patches/Transpilers/PlanetFactory_Transpiler.cs +++ b/NebulaPatcher/Patches/Transpilers/PlanetFactory_Transpiler.cs @@ -216,4 +216,45 @@ private delegate bool CatchBeltFastFillIn(bool result, PlanetFactory factory, in byte itemCount, byte itemInc); private delegate bool CatchBeltFastTakeOut(bool result, PlanetFactory factory, int beltId, int itemId, int count); + + + [HarmonyTranspiler] + [HarmonyPatch(nameof(PlanetFactory.AddPrebuildDataWithComponents))] + public static IEnumerable AddPrebuildDataWithComponents_Transpiler(IEnumerable instructions) + { + try + { + /* In server there is PlanetTimer that add dummy physics which will cause error in remote planets + + Replace: if (this.planet.physics == null) return num; + To: if (!this.planet.factoryLoaded) return num; + */ + var matcher = new CodeMatcher(instructions) + .MatchForward(true, + new CodeMatch(OpCodes.Ldarg_0), + new CodeMatch(i => i.opcode == OpCodes.Call && ((MethodInfo)i.operand).Name == "get_planet"), + new CodeMatch(i => i.opcode == OpCodes.Ldfld && ((FieldInfo)i.operand).Name == "physics"), + new CodeMatch(OpCodes.Brtrue) + ); + + var jumpOprand = matcher.Operand; + + matcher.Advance(-3) + .RemoveInstructions(4) + .Insert( + new CodeInstruction(OpCodes.Ldarg_0), + new CodeInstruction(OpCodes.Call, AccessTools.DeclaredPropertyGetter(typeof(PlanetFactory), nameof(PlanetFactory.planet))), + new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(PlanetData), nameof(PlanetData.factoryLoaded))), + new CodeInstruction(OpCodes.Brtrue_S, jumpOprand) + ); + + return matcher.InstructionEnumeration(); + } + catch (Exception e) + { + Log.Error("Transpiler PlanetFactory.AddPrebuildDataWithComponents error!"); + Log.Error(e); + return instructions; + } + } } diff --git a/NebulaWorld/GameStates/GameStatesManager.cs b/NebulaWorld/GameStates/GameStatesManager.cs index cb3da9b67..32ac14c71 100644 --- a/NebulaWorld/GameStates/GameStatesManager.cs +++ b/NebulaWorld/GameStates/GameStatesManager.cs @@ -72,11 +72,39 @@ public static string LoadingMessage() public static void ImportGlobalGameData(GlobalGameDataResponse packet) { - SandboxToolsEnabled = packet.SandboxToolsEnabled; - HistoryBinaryData = packet.HistoryBinaryData; - SpaceSectorBinaryData = packet.SpaceSectorBinaryData; - MilestoneSystemBinaryData = packet.MilestoneSystemBinaryData; - TrashSystemBinaryData = packet.TrashSystemBinaryData; + switch (packet.DataType) + { + case GlobalGameDataResponse.EDataType.History: + HistoryBinaryData = packet.BinaryData; + Log.Info("Waiting for SpaceSector data from the server..."); + break; + + case GlobalGameDataResponse.EDataType.SpaceSector: + SpaceSectorBinaryData = packet.BinaryData; + Log.Info("Waiting for MilestoneSystem data from the server..."); + break; + + case GlobalGameDataResponse.EDataType.MilestoneSystem: + MilestoneSystemBinaryData = packet.BinaryData; + Log.Info("Waiting for TrashSystem data from the server..."); + break; + + case GlobalGameDataResponse.EDataType.TrashSystem: + TrashSystemBinaryData = packet.BinaryData; + Log.Info("Waiting for the remaining data from the server..."); + break; + + case GlobalGameDataResponse.EDataType.Ready: + using (var reader = new BinaryUtils.Reader(packet.BinaryData)) + { + var br = reader.BinaryReader; + SandboxToolsEnabled = br.ReadBoolean(); + } + Log.Info("Loading GlobalGameData complete. Initializing..."); + // We are ready to start the game now + DSPGame.StartGameSkipPrologue(DSPGame.GameDesc); + break; + } } public static void OverwriteGlobalGameData(GameData data)