From 4698592fe07fc53bcfcea95034e0f520ff6cf9fa Mon Sep 17 00:00:00 2001 From: starfish <50672801+starfi5h@users.noreply.github.com> Date: Fri, 31 May 2024 18:52:50 +0800 Subject: [PATCH 1/9] Update StationComponent_Transpiler.ILSUpdateShipPos --- .../StationComponent_Transpiler.cs | 166 ++++++++---------- NebulaWorld/Logistics/ILSShipManager.cs | 1 + 2 files changed, 74 insertions(+), 93 deletions(-) diff --git a/NebulaPatcher/Patches/Transpilers/StationComponent_Transpiler.cs b/NebulaPatcher/Patches/Transpilers/StationComponent_Transpiler.cs index 3896bae29..b6d4490b4 100644 --- a/NebulaPatcher/Patches/Transpilers/StationComponent_Transpiler.cs +++ b/NebulaPatcher/Patches/Transpilers/StationComponent_Transpiler.cs @@ -293,7 +293,7 @@ public static IEnumerable InternalTickRemote_Transpiler(IEnumer return matcher.InstructionEnumeration(); } - [HarmonyReversePatch] + [HarmonyReversePatch(HarmonyReversePatchType.Original)] [HarmonyPatch(nameof(StationComponent.InternalTickRemote))] [SuppressMessage("Style", "IDE0060:Remove unused parameter")] public static void ILSUpdateShipPos(StationComponent stationComponent, PlanetFactory factory, int timeGene, @@ -305,30 +305,15 @@ public static void ILSUpdateShipPos(StationComponent stationComponent, PlanetFac static IEnumerable Transpiler(IEnumerable instructions, ILGenerator il) { - // find begin of ship movement computation, remove all content in if (timeGene == this.gene) {...} - // remove c# 10 - 473 var matcher = new CodeMatcher(instructions, il); - var indexStart = matcher - .MatchForward(false, - new CodeMatch(i => i.IsLdarg()), // float num47 = shipSailSpeed / 600f; - new CodeMatch(OpCodes.Ldc_R4), - new CodeMatch(OpCodes.Div), - new CodeMatch(OpCodes.Stloc_S), - new CodeMatch(OpCodes.Ldloc_S), // float num48 = Mathf.Pow(num47, 0.4f); - new CodeMatch(OpCodes.Ldc_R4), - new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(Mathf), "Pow"))) - .Pos; - // cut out only that part of original function, but keep the first 5 IL lines (they create the 'bool flag' which is needed) - for (matcher.Start().Advance(6); matcher.Pos < indexStart;) - { - matcher.SetAndAdvance(OpCodes.Nop, null); - } + int indexStart, indexEnd; - // c# 502: add null check at the beginning of the while(){} for gStationPool[shipData.otherGId] and if it is null skip this shipData until all data received from server + // Part1: Add null check for gStationPool[shipData.otherGId] at the beginning of the major while loop (c# 62) + // If it is null, skip this shipData until all data is received from server // // while (j < this.workShipCount) // { - // ref ShipData ptr3 = ref this.workShipDatas[j]; + // ref ShipData ptr2 = ref this.workShipDatas[j]; // >> insert if (gStationPool[shipData.otherGId] == null) { j++; continue; } matcher .MatchForward(true, @@ -345,19 +330,21 @@ static IEnumerable Transpiler(IEnumerable inst matcher.CreateLabelAt(matcher.Pos + 1, out var jmpNormalFlow); matcher .Advance(1) - .InsertAndAdvance(new CodeInstruction(OpCodes.Ldarg_S, 6)) // gStationPool - .InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, shipDataRef)) // shipData - .InsertAndAdvance(new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(ShipData), "otherGId"))) - .InsertAndAdvance(new CodeInstruction(OpCodes.Ldelem, typeof(StationComponent))) - .InsertAndAdvance(new CodeInstruction(OpCodes.Brtrue, jmpNormalFlow)) - .InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, loopIndex)) // j - .InsertAndAdvance(new CodeInstruction(OpCodes.Ldc_I4_1)) - .InsertAndAdvance(new CodeInstruction(OpCodes.Add)) - .InsertAndAdvance(new CodeInstruction(OpCodes.Stloc_S, loopIndex)) - .InsertAndAdvance(new CodeInstruction(OpCodes.Br, jmpNextLoopIter)); - - // remove c# 537-561 (adding item from landing ship to station and modify remote order and shifitng those arrays AND j-- (as we end up in an endless loop if not)) - // start: this.AddItem(ptr3.itemId, ptr3.itemCount, ptr3.inc); + .InsertAndAdvance( + new CodeInstruction(OpCodes.Ldarg_S, 6), // gStationPool + new CodeInstruction(OpCodes.Ldloc_S, shipDataRef), // shipData + new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(ShipData), "otherGId")), + new CodeInstruction(OpCodes.Ldelem, typeof(StationComponent)), + new CodeInstruction(OpCodes.Brtrue, jmpNormalFlow), + new CodeInstruction(OpCodes.Ldloc_S, loopIndex), + new CodeInstruction(OpCodes.Ldc_I4_1), + new CodeInstruction(OpCodes.Add), + new CodeInstruction(OpCodes.Stloc_S, loopIndex), + new CodeInstruction(OpCodes.Br, jmpNextLoopIter) + ); + + // Part2: Remove c# 97-121 (adding item from landing ship to station and modify remote order and shifitng those arrays AND j-- (as we end up in an endless loop if not)) + // start: this.AddItem(ptr2.itemId, ptr2.itemCount, ptr2.inc); // end: j--; indexStart = matcher .MatchForward(false, @@ -370,7 +357,8 @@ static IEnumerable Transpiler(IEnumerable inst new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(ShipData), "inc")), new CodeMatch(i => i.opcode == OpCodes.Call && ((MethodInfo)i.operand).Name == "AddItem")) .Pos; - var indexEnd = matcher + + indexEnd = matcher .MatchForward(true, new CodeMatch(OpCodes.Sub), new CodeMatch(i => i.opcode == OpCodes.Call && ((MethodInfo)i.operand).Name == "Clear"), @@ -385,85 +373,77 @@ static IEnumerable Transpiler(IEnumerable inst matcher.SetAndAdvance(OpCodes.Nop, null); } - // remove c# 1103 - 1201 (adding item from landing ship to station and modify remote order) - // start: StationComponent stationComponent3 = gStationPool[ptr3.otherGId]; StationStore[] array21 = stationComponent3.storage; - // end: if (this.remotePairCount > 0) {...} + // Part3: Remove c# 252 (ptr2.warperCnt--), assume warperCnt is either 0 or 2(allow round-trip) indexStart = matcher .MatchForward(false, - new CodeMatch(OpCodes.Ldarg_S), new CodeMatch(OpCodes.Ldloc_S), - new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(ShipData), "otherGId")), - new CodeMatch(OpCodes.Ldelem_Ref), - new CodeMatch(OpCodes.Stloc_S), - new CodeMatch(OpCodes.Ldloc_S), - new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(StationComponent), "storage"))) - .Pos; - indexEnd = matcher - .MatchForward(true, - new CodeMatch(OpCodes.Ldarg_0), - new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(StationComponent), "remotePairCount")), - new CodeMatch(OpCodes.Rem), - new CodeMatch(OpCodes.Stloc_S), - new CodeMatch(OpCodes.Ldloc_S), - new CodeMatch(OpCodes.Ldloc_S), - new CodeMatch(OpCodes.Bne_Un)) + new CodeMatch(OpCodes.Ldflda, AccessTools.Field(typeof(ShipData), "warperCnt")), + new CodeMatch(OpCodes.Dup), + new CodeMatch(OpCodes.Ldind_I4), + new CodeMatch(OpCodes.Ldc_I4_1), + new CodeMatch(OpCodes.Sub), + new CodeMatch(OpCodes.Stind_I4)) .Pos; - for (matcher.Start().Advance(indexStart); matcher.Pos <= indexEnd;) + indexEnd = indexStart + 7; + for (matcher.Start().Advance(indexStart); matcher.Pos < indexEnd;) { matcher.SetAndAdvance(OpCodes.Nop, null); } - // remove c# 1208 - 1093 (taking item from station and modify remote order) - // start: stationComponent3.TakeItem(ref itemId3, ref num120, out inc); - // end: lock (obj) {...} - indexStart = matcher - .MatchForward(false, - new CodeMatch(OpCodes.Ldloc_S), - new CodeMatch(OpCodes.Ldloca_S), - new CodeMatch(OpCodes.Ldloca_S), - new CodeMatch(OpCodes.Ldloca_S), - new CodeMatch(i => i.opcode == OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "TakeItem")) - .Pos; - indexEnd = matcher + // Part4: Switch itemCount in ShipData when ship arrive destination to display correct color + // Currently the render only test if itemCount > 0 so we can give it a dummy positive value + // + // c# 668-880 + // if (ptr2.direction > 0) + // { + // ptr2.t -= 0.0334f; + // if (ptr2.t < 0f) + // { + // >> Change the content to following and skip the rest of the calculation + // ptr2.t = 0f; + // ptr2.direction = -1; + // ptr2.itemCount = ptr2.itemCount > 0 ? 0 : 1; + // } >> labelEnd + // + matcher .MatchForward(true, - new CodeMatch(OpCodes.Stind_I4), - new CodeMatch(OpCodes.Leave), - new CodeMatch(OpCodes.Ldloc_S), - new CodeMatch(OpCodes.Brfalse), - new CodeMatch(OpCodes.Ldloc_S), - new CodeMatch(OpCodes.Call), - new CodeMatch(OpCodes.Endfinally)) - .Pos; - for (matcher.Start().Advance(indexStart); matcher.Pos <= indexEnd;) - { - matcher.SetAndAdvance(OpCodes.Nop, null); - } + new CodeMatch(OpCodes.Ldc_R4, 0.0334f), + new CodeMatch(OpCodes.Sub), + new CodeMatch(OpCodes.Stind_R4), + new CodeMatch(OpCodes.Ldloc_S, shipDataRef), + new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(ShipData), "t")), + new CodeMatch(OpCodes.Ldc_R4, 0.0f), + new CodeMatch(OpCodes.Bge_Un)); + var labelEnd = matcher.Operand; - // Switch itemCount in ShipData when ship arrive destination to display correct color - // Currently the render only test if itemCount > 0 so we can give it a dummy positive value - // c# 1241: - // ptr3.direction = -1; - // >> Insert ptr3.itemCount = ptr3.itemCount > 0 ? 0 : 1; matcher - .MatchForward(true, - new CodeMatch(OpCodes.Ldloc_S), - new CodeMatch(OpCodes.Ldc_I4_M1), - new CodeMatch(OpCodes.Stfld)) .Advance(1) .Insert( - new CodeInstruction(OpCodes.Ldloc_S, matcher.InstructionAt(-3).operand), - new CodeInstruction(OpCodes.Ldloc_S, matcher.InstructionAt(-3).operand), + // ptr2.t = 0.0f; + new CodeInstruction(OpCodes.Ldloc_S, shipDataRef), + new CodeInstruction(OpCodes.Ldc_R4, 0.0f), + new CodeInstruction(OpCodes.Stfld, AccessTools.Field(typeof(ShipData), "t")), + + // ptr2.direction = -1; + new CodeInstruction(OpCodes.Ldloc_S, shipDataRef), + new CodeInstruction(OpCodes.Ldc_I4_M1), + new CodeInstruction(OpCodes.Stfld, AccessTools.Field(typeof(ShipData), "direction")), + + // ptr2.itemCount = ptr2.itemCount > 0 ? 0 : 1; + new CodeInstruction(OpCodes.Ldloc_S, shipDataRef), + new CodeInstruction(OpCodes.Ldloc_S, shipDataRef), new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(ShipData), "itemCount")), - new CodeInstruction(OpCodes.Ldc_I4_0), - new CodeInstruction(OpCodes.Stfld, AccessTools.Field(typeof(ShipData), "itemCount")) + new CodeInstruction(OpCodes.Ldc_I4_0), //CreateLabel labelTo0 + new CodeInstruction(OpCodes.Stfld, AccessTools.Field(typeof(ShipData), "itemCount")), + new CodeInstruction(OpCodes.Br_S, labelEnd) ) - .Advance(3) //OpCodes.Ldc_I4_0 + .Advance(9) //OpCodes.Ldc_I4_0 .CreateLabel(out var labelTo0) - .CreateLabelAt(matcher.Pos + 1, out var labelEnd) .Insert( new CodeInstruction(OpCodes.Ldc_I4_0), new CodeInstruction(OpCodes.Bgt_S, labelTo0), new CodeInstruction(OpCodes.Ldc_I4_1), + new CodeInstruction(OpCodes.Stfld, AccessTools.Field(typeof(ShipData), "itemCount")), new CodeInstruction(OpCodes.Br_S, labelEnd) ); diff --git a/NebulaWorld/Logistics/ILSShipManager.cs b/NebulaWorld/Logistics/ILSShipManager.cs index b53ad6867..12f6ae056 100644 --- a/NebulaWorld/Logistics/ILSShipManager.cs +++ b/NebulaWorld/Logistics/ILSShipManager.cs @@ -153,6 +153,7 @@ public static void CreateFakeStationComponent(int gId, int planetId, int maxShip stationComponent.workShipOrders = new RemoteLogisticOrder[maxShipCount]; stationComponent.shipRenderers = new ShipRenderingData[maxShipCount]; stationComponent.shipUIRenderers = new ShipUIRenderingData[maxShipCount]; + stationComponent.priorityLocks = new StationPriorityLock[6]; // dummy placeholder. the real length should be stationMaxItemKinds stationComponent.workShipCount = 0; stationComponent.idleShipCount = maxShipCount; // add dummy idle ship count to use in ILSShipManager stationComponent.shipDockPos = Vector3.zero; //gets updated later by server packet From b82b6e5b19121e097689a43c625a9823f9a17f6c Mon Sep 17 00:00:00 2001 From: starfish <50672801+starfi5h@users.noreply.github.com> Date: Wed, 5 Jun 2024 01:58:33 +0800 Subject: [PATCH 2/9] Optimize ILS ship packets --- .../Logistics/ILSIdleShipBackToWork.cs | 22 ++++++------- .../Packets/Logistics/ILSShipEnterWarp.cs | 15 --------- .../Logistics/ILSWorkShipBackToIdle.cs | 2 +- .../Logistics/ILSShipEnterWarpProcessor.cs | 31 ------------------- .../Patches/Dynamic/StationComponent_Patch.cs | 2 +- NebulaWorld/Logistics/ILSShipManager.cs | 1 - 6 files changed, 12 insertions(+), 61 deletions(-) delete mode 100644 NebulaModel/Packets/Logistics/ILSShipEnterWarp.cs delete mode 100644 NebulaNetwork/PacketProcessors/Logistics/ILSShipEnterWarpProcessor.cs diff --git a/NebulaModel/Packets/Logistics/ILSIdleShipBackToWork.cs b/NebulaModel/Packets/Logistics/ILSIdleShipBackToWork.cs index 55467a598..fa6be002f 100644 --- a/NebulaModel/Packets/Logistics/ILSIdleShipBackToWork.cs +++ b/NebulaModel/Packets/Logistics/ILSIdleShipBackToWork.cs @@ -4,18 +4,17 @@ public class ILSIdleShipBackToWork { public ILSIdleShipBackToWork() { } - public ILSIdleShipBackToWork(ShipData ShipData, int thisGId, int stationMaxShipCount, int stationWarperCount) + public ILSIdleShipBackToWork(in ShipData shipData, int thisGId, int stationMaxShipCount, int stationWarperCount) { ThisGId = thisGId; - PlanetA = ShipData.planetA; - PlanetB = ShipData.planetB; - OtherGId = ShipData.otherGId; - ItemId = ShipData.itemId; - ItemCount = ShipData.itemCount; - Inc = ShipData.inc; - Gene = ShipData.gene; - ShipIndex = ShipData.shipIndex; - ShipWarperCount = ShipData.warperCnt; + PlanetA = shipData.planetA; + PlanetB = shipData.planetB; + OtherGId = shipData.otherGId; + ItemId = shipData.itemId; + ItemCount = shipData.itemCount; + Inc = shipData.inc; + ShipIndex = shipData.shipIndex; + ShipWarperCount = (byte)shipData.warperCnt; StationMaxShipCount = stationMaxShipCount; StationWarperCount = stationWarperCount; } @@ -27,9 +26,8 @@ public ILSIdleShipBackToWork(ShipData ShipData, int thisGId, int stationMaxShipC public int ItemId { get; set; } public int ItemCount { get; set; } public int Inc { get; set; } - public int Gene { get; set; } public int ShipIndex { get; set; } - public int ShipWarperCount { get; set; } + public byte ShipWarperCount { get; set; } // Max count for round-trip: 2 public int StationMaxShipCount { get; set; } public int StationWarperCount { get; set; } } diff --git a/NebulaModel/Packets/Logistics/ILSShipEnterWarp.cs b/NebulaModel/Packets/Logistics/ILSShipEnterWarp.cs deleted file mode 100644 index f86abd216..000000000 --- a/NebulaModel/Packets/Logistics/ILSShipEnterWarp.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace NebulaModel.Packets.Logistics; - -public class ILSShipEnterWarp -{ - public ILSShipEnterWarp() { } - - public ILSShipEnterWarp(int thisGId, int workShipIndex) - { - ThisGId = thisGId; - WorkShipIndex = workShipIndex; - } - - public int ThisGId { get; set; } - public int WorkShipIndex { get; set; } -} diff --git a/NebulaModel/Packets/Logistics/ILSWorkShipBackToIdle.cs b/NebulaModel/Packets/Logistics/ILSWorkShipBackToIdle.cs index c63af820f..0d389f3f1 100644 --- a/NebulaModel/Packets/Logistics/ILSWorkShipBackToIdle.cs +++ b/NebulaModel/Packets/Logistics/ILSWorkShipBackToIdle.cs @@ -4,7 +4,7 @@ public class ILSWorkShipBackToIdle { public ILSWorkShipBackToIdle() { } - public ILSWorkShipBackToIdle(StationComponent stationComponent, ShipData shipData, int workShipIndex) + public ILSWorkShipBackToIdle(StationComponent stationComponent, in ShipData shipData, int workShipIndex) { GId = stationComponent.gid; PlanetA = shipData.planetA; diff --git a/NebulaNetwork/PacketProcessors/Logistics/ILSShipEnterWarpProcessor.cs b/NebulaNetwork/PacketProcessors/Logistics/ILSShipEnterWarpProcessor.cs deleted file mode 100644 index 87a87c0f8..000000000 --- a/NebulaNetwork/PacketProcessors/Logistics/ILSShipEnterWarpProcessor.cs +++ /dev/null @@ -1,31 +0,0 @@ -#region - -using NebulaAPI.Packets; -using NebulaModel.Networking; -using NebulaModel.Packets; -using NebulaModel.Packets.Logistics; - -#endregion - -namespace NebulaNetwork.PacketProcessors.Logistics; - -[RegisterPacketProcessor] -public class ILSShipEnterWarpProcessor : PacketProcessor -{ - protected override void ProcessPacket(ILSShipEnterWarp packet, NebulaConnection conn) - { - if (!IsClient) - { - return; - } - if (packet.ThisGId > GameMain.data.galacticTransport.stationCursor) - { - return; - } - var stationComponent = GameMain.data.galacticTransport.stationPool[packet.ThisGId]; - if (stationComponent != null && packet.WorkShipIndex < stationComponent.workShipCount) - { - stationComponent.workShipDatas[packet.WorkShipIndex].warpState += 0.016666668f; - } - } -} diff --git a/NebulaPatcher/Patches/Dynamic/StationComponent_Patch.cs b/NebulaPatcher/Patches/Dynamic/StationComponent_Patch.cs index f9c5cdf3d..216e27018 100644 --- a/NebulaPatcher/Patches/Dynamic/StationComponent_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/StationComponent_Patch.cs @@ -66,7 +66,7 @@ public static void IdleShipGetToWork_Postfix(StationComponent __instance) { return; } - var packet = new ILSIdleShipBackToWork(__instance.workShipDatas[__instance.workShipCount - 1], __instance.gid, + var packet = new ILSIdleShipBackToWork(in __instance.workShipDatas[__instance.workShipCount - 1], __instance.gid, __instance.workShipDatas.Length, __instance.warperCount); Multiplayer.Session.Network.SendPacket(packet); } diff --git a/NebulaWorld/Logistics/ILSShipManager.cs b/NebulaWorld/Logistics/ILSShipManager.cs index 12f6ae056..ae7e9adbc 100644 --- a/NebulaWorld/Logistics/ILSShipManager.cs +++ b/NebulaWorld/Logistics/ILSShipManager.cs @@ -70,7 +70,6 @@ public static void IdleShipGetToWork(ILSIdleShipBackToWork packet) stationComponent.workShipDatas[stationComponent.workShipCount].itemId = packet.ItemId; stationComponent.workShipDatas[stationComponent.workShipCount].itemCount = packet.ItemCount; stationComponent.workShipDatas[stationComponent.workShipCount].inc = packet.Inc; - stationComponent.workShipDatas[stationComponent.workShipCount].gene = packet.Gene; stationComponent.workShipDatas[stationComponent.workShipCount].shipIndex = packet.ShipIndex; stationComponent.workShipDatas[stationComponent.workShipCount].warperCnt = packet.ShipWarperCount; stationComponent.warperCount = packet.StationWarperCount; From 599b437bd3e75c221881137d67e26be699b5d2af Mon Sep 17 00:00:00 2001 From: starfish <50672801+starfi5h@users.noreply.github.com> Date: Sat, 1 Jun 2024 04:18:35 +0800 Subject: [PATCH 3/9] Export galacticTransport in GlobalGameDataResponse --- .../Packets/Session/GlobalGameDataResponse.cs | 1 + .../Logistics/ILSgStationPoolSyncProcessor.cs | 1 + .../Session/GlobalGameDataRequestProcessor.cs | 8 ++++++++ NebulaWorld/GameStates/GameStatesManager.cs | 17 +++++++++++++++++ 4 files changed, 27 insertions(+) diff --git a/NebulaModel/Packets/Session/GlobalGameDataResponse.cs b/NebulaModel/Packets/Session/GlobalGameDataResponse.cs index d46621a08..32d81a795 100644 --- a/NebulaModel/Packets/Session/GlobalGameDataResponse.cs +++ b/NebulaModel/Packets/Session/GlobalGameDataResponse.cs @@ -13,6 +13,7 @@ public GlobalGameDataResponse(EDataType dataType, byte[] binaryData) public enum EDataType : byte { History = 1, + GalacticTransport, SpaceSector, MilestoneSystem, TrashSystem, diff --git a/NebulaNetwork/PacketProcessors/Logistics/ILSgStationPoolSyncProcessor.cs b/NebulaNetwork/PacketProcessors/Logistics/ILSgStationPoolSyncProcessor.cs index 39457c514..3bfbc772e 100644 --- a/NebulaNetwork/PacketProcessors/Logistics/ILSgStationPoolSyncProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Logistics/ILSgStationPoolSyncProcessor.cs @@ -98,5 +98,6 @@ protected override void ProcessPacket(ILSgStationPoolSync packet, NebulaConnecti } gTransport.Arragement(); + gTransport.RefreshTraffic(0); } } diff --git a/NebulaNetwork/PacketProcessors/Session/GlobalGameDataRequestProcessor.cs b/NebulaNetwork/PacketProcessors/Session/GlobalGameDataRequestProcessor.cs index 5f22d460f..29a0b5daa 100644 --- a/NebulaNetwork/PacketProcessors/Session/GlobalGameDataRequestProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Session/GlobalGameDataRequestProcessor.cs @@ -30,6 +30,14 @@ protected override void ProcessPacket(GlobalGameDataRequest packet, NebulaConnec GlobalGameDataResponse.EDataType.History, writer.CloseAndGetBytes())); } + using (var writer = new BinaryUtils.Writer()) + { + GameMain.data.galacticTransport.Export(writer.BinaryWriter); + + conn.SendPacket(new GlobalGameDataResponse( + GlobalGameDataResponse.EDataType.GalacticTransport, writer.CloseAndGetBytes())); + } + using (var writer = new BinaryUtils.Writer()) { // Note: Initial syncing from vanilla. May be refined later in future diff --git a/NebulaWorld/GameStates/GameStatesManager.cs b/NebulaWorld/GameStates/GameStatesManager.cs index 32ac14c71..f630b6b23 100644 --- a/NebulaWorld/GameStates/GameStatesManager.cs +++ b/NebulaWorld/GameStates/GameStatesManager.cs @@ -25,6 +25,7 @@ public class GameStatesManager : IDisposable // Store data get from GlobalGameDataResponse static bool SandboxToolsEnabled { get; set; } static byte[] HistoryBinaryData { get; set; } + static byte[] GalacticTransportBinaryData { get; set; } static byte[] SpaceSectorBinaryData { get; set; } static byte[] MilestoneSystemBinaryData { get; set; } static byte[] TrashSystemBinaryData { get; set; } @@ -35,6 +36,7 @@ public void Dispose() FragmentSize = 0; SandboxToolsEnabled = false; HistoryBinaryData = null; + GalacticTransportBinaryData = null; SpaceSectorBinaryData = null; MilestoneSystemBinaryData = null; TrashSystemBinaryData = null; @@ -76,6 +78,11 @@ public static void ImportGlobalGameData(GlobalGameDataResponse packet) { case GlobalGameDataResponse.EDataType.History: HistoryBinaryData = packet.BinaryData; + Log.Info("Waiting for GalacticTransport data from the server..."); + break; + + case GlobalGameDataResponse.EDataType.GalacticTransport: + GalacticTransportBinaryData = packet.BinaryData; Log.Info("Waiting for SpaceSector data from the server..."); break; @@ -120,6 +127,16 @@ public static void OverwriteGlobalGameData(GameData data) } HistoryBinaryData = null; } + if (GalacticTransportBinaryData != null) + { + Log.Info("Parsing GalacticTransport data from the server..."); + data.galacticTransport.Init(data); + using (var reader = new BinaryUtils.Reader(GalacticTransportBinaryData)) + { + data.galacticTransport.Import(reader.BinaryReader); + } + GalacticTransportBinaryData = null; + } if (SpaceSectorBinaryData != null) { Log.Info("Parsing SpaceSector data from the server..."); From a98e4c34e4194f1e189cea422f576fd4df3b45d1 Mon Sep 17 00:00:00 2001 From: starfish <50672801+starfi5h@users.noreply.github.com> Date: Sun, 2 Jun 2024 02:22:58 +0800 Subject: [PATCH 4/9] Add ILSUpdateRoute packet --- .../Packets/Logistics/ILSUpdateRoute.cs | 34 ++++++++ .../Logistics/ILSUpdateRouteProcessor.cs | 55 +++++++++++++ .../Dynamic/GalacticTransport_Patch.cs | 80 +++++++++++++++++++ 3 files changed, 169 insertions(+) create mode 100644 NebulaModel/Packets/Logistics/ILSUpdateRoute.cs create mode 100644 NebulaNetwork/PacketProcessors/Logistics/ILSUpdateRouteProcessor.cs diff --git a/NebulaModel/Packets/Logistics/ILSUpdateRoute.cs b/NebulaModel/Packets/Logistics/ILSUpdateRoute.cs new file mode 100644 index 000000000..1a6b134c3 --- /dev/null +++ b/NebulaModel/Packets/Logistics/ILSUpdateRoute.cs @@ -0,0 +1,34 @@ +namespace NebulaModel.Packets.Logistics; + +// Sync route update events in GalacticTransport +public class ILSUpdateRoute +{ + public ILSUpdateRoute() { } + + public ILSUpdateRoute(ERouteEvent type, int id0, int id1 = 0, int itemId = 0) + { + Type = type; + Id0 = id0; + Id1 = id1; + ItemId = itemId; + } + + public ERouteEvent Type { get; set; } + public int Id0 { get; set; } + public int Id1 { get; set; } + public int ItemId { get; set; } + public bool Enable { get; set; } + public string Comment { get; set; } + + public enum ERouteEvent + { + None = 0, + AddStation2StationRoute, + RemoveStation2StationRoute_Single, + RemoveStation2StationRoute_Pair, + AddAstro2AstroRoute, + RemoveAstro2AstroRoute, + SetAstro2AstroRouteEnable, + SetAstro2AstroRouteComment + } +} diff --git a/NebulaNetwork/PacketProcessors/Logistics/ILSUpdateRouteProcessor.cs b/NebulaNetwork/PacketProcessors/Logistics/ILSUpdateRouteProcessor.cs new file mode 100644 index 000000000..d6c6d238d --- /dev/null +++ b/NebulaNetwork/PacketProcessors/Logistics/ILSUpdateRouteProcessor.cs @@ -0,0 +1,55 @@ +#region + +using NebulaAPI.Packets; +using NebulaModel.Logger; +using NebulaModel.Networking; +using NebulaModel.Packets; +using NebulaModel.Packets.Logistics; +using NebulaWorld; + +#endregion + +namespace NebulaNetwork.PacketProcessors.Logistics; + +[RegisterPacketProcessor] +public class ILSUpdateRouteProcessor : PacketProcessor +{ + protected override void ProcessPacket(ILSUpdateRoute packet, NebulaConnection conn) + { + Log.Debug($"{packet.Type} id0:{packet.Id0} id1:{packet.Id1}"); + using (Multiplayer.Session.Ships.PatchLockILS.On()) + { + var galacticTransport = GameMain.data.galacticTransport; + switch (packet.Type) + { + case ILSUpdateRoute.ERouteEvent.AddStation2StationRoute: + galacticTransport.AddStation2StationRoute(packet.Id0, packet.Id1); + break; + + case ILSUpdateRoute.ERouteEvent.RemoveStation2StationRoute_Single: + galacticTransport.RemoveStation2StationRoute(packet.Id0); + break; + + case ILSUpdateRoute.ERouteEvent.RemoveStation2StationRoute_Pair: + galacticTransport.RemoveStation2StationRoute(packet.Id0, packet.Id1); + break; + + case ILSUpdateRoute.ERouteEvent.AddAstro2AstroRoute: + galacticTransport.AddAstro2AstroRoute(packet.Id0, packet.Id1, packet.ItemId); + break; + + case ILSUpdateRoute.ERouteEvent.RemoveAstro2AstroRoute: + galacticTransport.RemoveAstro2AstroRoute(packet.Id0, packet.Id1, packet.ItemId); + break; + + case ILSUpdateRoute.ERouteEvent.SetAstro2AstroRouteEnable: + galacticTransport.SetAstro2AstroRouteEnable(packet.Id0, packet.Id1, packet.ItemId, packet.Enable); + break; + + case ILSUpdateRoute.ERouteEvent.SetAstro2AstroRouteComment: + galacticTransport.SetAstro2AstroRouteComment(packet.Id0, packet.Id1, packet.ItemId, packet.Comment); + break; + } + } + } +} diff --git a/NebulaPatcher/Patches/Dynamic/GalacticTransport_Patch.cs b/NebulaPatcher/Patches/Dynamic/GalacticTransport_Patch.cs index 51a379f0c..a0a32c3a4 100644 --- a/NebulaPatcher/Patches/Dynamic/GalacticTransport_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/GalacticTransport_Patch.cs @@ -1,5 +1,6 @@ #region +using System; using HarmonyLib; using NebulaModel.Packets.Logistics; using NebulaWorld; @@ -36,4 +37,83 @@ public static bool RemoveStationComponent_Prefix() { return !Multiplayer.IsActive || Multiplayer.Session.LocalPlayer.IsHost || Multiplayer.Session.Ships.PatchLockILS; } + + [HarmonyPrefix] + [HarmonyPatch(nameof(GalacticTransport.GameTick))] + public static bool GameTick_Prefix() + { + return !Multiplayer.IsActive || Multiplayer.Session.LocalPlayer.IsHost; + // Let host determine when ships will dispatch. Client will send out ships once receiving ILSIdleShipBackToWork packet + } + + [HarmonyPrefix] + [HarmonyPatch(nameof(GalacticTransport.AddStation2StationRoute))] + public static void AddStation2StationRoute_Prefix(int gid0, int gid1) + { + if (!Multiplayer.IsActive || Multiplayer.Session.Ships.PatchLockILS) return; + + Multiplayer.Session.Network.SendPacket(new ILSUpdateRoute(ILSUpdateRoute.ERouteEvent.AddStation2StationRoute, gid0, gid1)); + } + + [HarmonyPrefix] + [HarmonyPatch(nameof(GalacticTransport.RemoveStation2StationRoute), new Type[] { typeof(int) })] + public static void RemoveStation2StationRoute_Single_Prefix(int gid) + { + if (!Multiplayer.IsActive || Multiplayer.Session.Ships.PatchLockILS) return; + + Multiplayer.Session.Network.SendPacket(new ILSUpdateRoute(ILSUpdateRoute.ERouteEvent.RemoveStation2StationRoute_Single, gid)); + } + + [HarmonyPrefix] + [HarmonyPatch(nameof(GalacticTransport.RemoveStation2StationRoute), new Type[] { typeof(int), typeof(int) })] + public static void RemoveStation2StationRoute_Pair_Prefix(int gid0, int gid1) + { + if (!Multiplayer.IsActive || Multiplayer.Session.Ships.PatchLockILS) return; + + Multiplayer.Session.Network.SendPacket(new ILSUpdateRoute(ILSUpdateRoute.ERouteEvent.RemoveStation2StationRoute_Pair, gid0, gid1)); + } + + [HarmonyPrefix] + [HarmonyPatch(nameof(GalacticTransport.AddAstro2AstroRoute))] + public static void AddAstro2AstroRoute_Prefix(int astroId0, int astroId1, int itemId) + { + if (!Multiplayer.IsActive || Multiplayer.Session.Ships.PatchLockILS) return; + + Multiplayer.Session.Network.SendPacket(new ILSUpdateRoute(ILSUpdateRoute.ERouteEvent.AddAstro2AstroRoute, astroId0, astroId1, itemId)); + } + + [HarmonyPrefix] + [HarmonyPatch(nameof(GalacticTransport.RemoveAstro2AstroRoute))] + public static void RemoveAstro2AstroRoute_Prefix(int astroId0, int astroId1, int itemId) + { + if (!Multiplayer.IsActive || Multiplayer.Session.Ships.PatchLockILS) return; + + Multiplayer.Session.Network.SendPacket(new ILSUpdateRoute(ILSUpdateRoute.ERouteEvent.RemoveAstro2AstroRoute, astroId0, astroId1, itemId)); + } + + [HarmonyPrefix] + [HarmonyPatch(nameof(GalacticTransport.SetAstro2AstroRouteEnable))] + public static void SetAstro2AstroRouteEnable_Prefix(int astroId0, int astroId1, int itemId, bool enable) + { + if (!Multiplayer.IsActive || Multiplayer.Session.Ships.PatchLockILS) return; + + var packet = new ILSUpdateRoute(ILSUpdateRoute.ERouteEvent.SetAstro2AstroRouteEnable, astroId0, astroId1, itemId) + { + Enable = enable + }; + Multiplayer.Session.Network.SendPacket(packet); + } + + [HarmonyPrefix] + [HarmonyPatch(nameof(GalacticTransport.SetAstro2AstroRouteComment))] + public static void SetAstro2AstroRouteComment_Prefix(int astroId0, int astroId1, int itemId, string comment) + { + if (!Multiplayer.IsActive || Multiplayer.Session.Ships.PatchLockILS) return; + + var packet = new ILSUpdateRoute(ILSUpdateRoute.ERouteEvent.SetAstro2AstroRouteComment, astroId0, astroId1, itemId) + { + Comment = comment + }; + Multiplayer.Session.Network.SendPacket(packet); + } } From b5c2e37a221ddb695766c88aa7f5e68ed57cefb0 Mon Sep 17 00:00:00 2001 From: starfish <50672801+starfi5h@users.noreply.github.com> Date: Sun, 2 Jun 2024 03:38:35 +0800 Subject: [PATCH 5/9] Sync RemoteGroupMask and RoutePriority in StationUI --- NebulaModel/Packets/Logistics/StationUI.cs | 18 +++------ .../Patches/Dynamic/UIStationWindow_Patch.cs | 38 +++++++++++++++++++ NebulaWorld/Logistics/StationUIManager.cs | 10 +++++ 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/NebulaModel/Packets/Logistics/StationUI.cs b/NebulaModel/Packets/Logistics/StationUI.cs index 36a2c6789..2090e9bc1 100644 --- a/NebulaModel/Packets/Logistics/StationUI.cs +++ b/NebulaModel/Packets/Logistics/StationUI.cs @@ -19,12 +19,14 @@ public enum EUISettings PilerCount, MaxMiningSpeed, DroneAutoReplenish, - ShipAutoReplenish + ShipAutoReplenish, + RemoteGroupMask, + RoutePriority } public StationUI() { } - public StationUI(int planetId, int stationId, int stationGId, EUISettings settingIndex, float value, + public StationUI(int planetId, int stationId, int stationGId, EUISettings settingIndex, double value, bool warperShouldTakeFromStorage = false) { PlanetId = planetId; @@ -35,21 +37,11 @@ public StationUI(int planetId, int stationId, int stationGId, EUISettings settin WarperShouldTakeFromStorage = warperShouldTakeFromStorage; } - public StationUI(int planetId, int stationId, int stationGId, EUISettings settingIndex, string settingString) - { - PlanetId = planetId; - StationId = stationId; - StationGId = stationGId; - SettingIndex = settingIndex; - SettingString = settingString; - } - public int PlanetId { get; set; } public int StationId { get; set; } public int StationGId { get; set; } public EUISettings SettingIndex { get; set; } - public float SettingValue { get; set; } - public string SettingString { get; set; } + public double SettingValue { get; set; } public bool WarperShouldTakeFromStorage { get; set; } public bool ShouldRefund { get; set; } } diff --git a/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs b/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs index 4b792c27f..fba488558 100644 --- a/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs @@ -372,6 +372,44 @@ public static void OnWarperIconClick_Postfix(UIStationWindow __instance, int __s __instance.warperIconButton.button.interactable = false; } + [HarmonyPostfix] + [HarmonyPatch(nameof(UIStationWindow.OnGroupButtonClick))] + public static void OnGroupButtonClick_Postfix(UIStationWindow __instance) + { + if (__instance.event_lock || !Multiplayer.IsActive || Multiplayer.Session.Ships.PatchLockILS) + { + return; + } + + if (__instance.stationId == 0 || __instance.factory == null) + { + return; + } + var stationComponent = __instance.transport.stationPool[__instance.stationId]; + var packet = new StationUI(__instance.factory.planet.id, stationComponent.id, stationComponent.gid, + StationUI.EUISettings.RemoteGroupMask, BitConverter.Int64BitsToDouble(stationComponent.remoteGroupMask)); + Multiplayer.Session.Network.SendPacket(packet); + } + + [HarmonyPostfix] + [HarmonyPatch(nameof(UIStationWindow.OnBehaviorBomboBoxItemIndexChange))] + public static void OnBehaviorBomboBoxItemIndexChange_Postfix(UIStationWindow __instance) + { + if (__instance.event_lock || !Multiplayer.IsActive || Multiplayer.Session.Ships.PatchLockILS) + { + return; + } + + if (__instance.stationId == 0 || __instance.factory == null) + { + return; + } + var stationComponent = __instance.transport.stationPool[__instance.stationId]; + var packet = new StationUI(__instance.factory.planet.id, stationComponent.id, stationComponent.gid, + StationUI.EUISettings.RoutePriority, (int)stationComponent.routePriority); + Multiplayer.Session.Network.SendPacket(packet); + } + [HarmonyPostfix] [HarmonyPatch(nameof(UIStationWindow._OnOpen))] [SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Original Function Name")] diff --git a/NebulaWorld/Logistics/StationUIManager.cs b/NebulaWorld/Logistics/StationUIManager.cs index a775e2f52..2e39a104a 100644 --- a/NebulaWorld/Logistics/StationUIManager.cs +++ b/NebulaWorld/Logistics/StationUIManager.cs @@ -243,6 +243,16 @@ private static void UpdateSettingsUI(StationComponent stationComponent, ref Stat stationComponent.shipAutoReplenish = packet.SettingValue != 0; break; } + case StationUI.EUISettings.RemoteGroupMask: + { + stationComponent.remoteGroupMask = BitConverter.DoubleToInt64Bits(packet.SettingValue); + break; + } + case StationUI.EUISettings.RoutePriority: + { + stationComponent.routePriority = (ERemoteRoutePriority)packet.SettingValue; + break; + } case StationUI.EUISettings.None: break; default: From 1834f07d8c574df2c74332d0435fbbd7a197907e Mon Sep 17 00:00:00 2001 From: starfish <50672801+starfi5h@users.noreply.github.com> Date: Wed, 5 Jun 2024 00:51:36 +0800 Subject: [PATCH 6/9] Fix UIPlanetDetail in lobby --- NebulaPatcher/Patches/Dynamic/UIPlanetDetail_Patch.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/NebulaPatcher/Patches/Dynamic/UIPlanetDetail_Patch.cs b/NebulaPatcher/Patches/Dynamic/UIPlanetDetail_Patch.cs index b963a6757..427202c09 100644 --- a/NebulaPatcher/Patches/Dynamic/UIPlanetDetail_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/UIPlanetDetail_Patch.cs @@ -41,13 +41,15 @@ public static bool _OnUpdate_Prefix(UIPlanetDetail __instance) return true; } - if (Time.frameCount % 30 == 0) + if (Time.frameCount % 30 == 0 && __instance.tabIndex == 0) { __instance.RefreshDynamicProperties(); + __instance.OnTabButtonClick(0); // baseInfoGroupGo.SetActive(true) } __instance.trslBg.SetActive(true); __instance.imgBg.SetActive(true); - + __instance.displayComboColorCard.color = ((__instance.uiGame.veinAmountDisplayFilter > 0) ? __instance.displayComboFilterColor : __instance.displayComboNormalColor); + __instance.RefreshTabPanel(); return false; } From bedda93320cc1a47f5eeafe282031c63840fa6f2 Mon Sep 17 00:00:00 2001 From: starfish <50672801+starfi5h@users.noreply.github.com> Date: Wed, 5 Jun 2024 05:36:39 +0800 Subject: [PATCH 7/9] Sync buildPreview.tilt --- NebulaModel/Packets/Factory/CreatePrebuildsRequest.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NebulaModel/Packets/Factory/CreatePrebuildsRequest.cs b/NebulaModel/Packets/Factory/CreatePrebuildsRequest.cs index 325590fb4..0f3f80e7e 100644 --- a/NebulaModel/Packets/Factory/CreatePrebuildsRequest.cs +++ b/NebulaModel/Packets/Factory/CreatePrebuildsRequest.cs @@ -127,6 +127,7 @@ public static void DeserializeBuildPreview(BuildPreview buildPreview, IReadOnlyL buildPreview.lpos2 = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); buildPreview.lrot = new Quaternion(br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); buildPreview.lrot2 = new Quaternion(br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); + buildPreview.tilt = br.ReadSingle(); buildPreview.condition = (EBuildCondition)br.ReadInt32(); } @@ -184,6 +185,7 @@ public static void SerializeBuildPreview(BuildPreview buildPreview, IList Date: Wed, 5 Jun 2024 20:26:55 +0800 Subject: [PATCH 8/9] Bump version and changelog to v0.9.4 --- .github/scripts/thunderstore_bundle.js | 2 +- CHANGELOG.md | 7 +++++++ version.json | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/scripts/thunderstore_bundle.js b/.github/scripts/thunderstore_bundle.js index 07ee83c80..8082af80e 100644 --- a/.github/scripts/thunderstore_bundle.js +++ b/.github/scripts/thunderstore_bundle.js @@ -117,7 +117,7 @@ function generateManifest() { const manifest = { name: pluginInfo.name, description: - "With this mod you will be able to play with your friends in the same game! Now supports combat mode in game version 0.10.29", + "With this mod you will be able to play with your friends in the same game! Now supports combat mode in game version 0.10.30", version_number: pluginInfo.version, dependencies: [ BEPINEX_DEPENDENCY, diff --git a/CHANGELOG.md b/CHANGELOG.md index 39bd503ec..226303f21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ ## Changelog +0.9.4: +- Compatible to Steam or Game Pass version 0.10.30.22292 +- @PhantomGamers: Prevent errors with Ngrok from crashing the game +- @PhantomGamers: Added error descriptions to Ngrok errors +- @starfi5h: Sync interstellar routes +- @starfi5h: Sync tilted conveyor belts + 0.9.3: - @starfi5h: Change chat message format. Player's name now has an underlined link to navigate - @starfi5h: Add new config option Chat - Show Timestamp to enable/disable timestamp before the chat message diff --git a/version.json b/version.json index 91ec6a987..110c586bf 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "0.9.3", + "version": "0.9.4", "assemblyVersion": { "precision": "build" }, From 247cad02dbd8d8f8a8d3adcad69c48457301d7e1 Mon Sep 17 00:00:00 2001 From: starfish <50672801+starfi5h@users.noreply.github.com> Date: Wed, 5 Jun 2024 20:46:30 +0800 Subject: [PATCH 9/9] Fix grammar --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 226303f21..acd59ef2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ ## Changelog 0.9.4: -- Compatible to Steam or Game Pass version 0.10.30.22292 +- Compatible with Steam or Game Pass version 0.10.30.22292 - @PhantomGamers: Prevent errors with Ngrok from crashing the game - @PhantomGamers: Added error descriptions to Ngrok errors - @starfi5h: Sync interstellar routes @@ -17,7 +17,7 @@ - @starfi5h: Fix enemies and ILS related errors 0.9.2: -- Compatible to Steam version 0.10.29.22015 or Game Pass version 0.10.29.21943 +- Compatible with Steam version 0.10.29.22015 or Game Pass version 0.10.29.21943 - @sk7725: Added Korean font and TextMeshPro fallback - @starfi5h: Add new chat command `/playerdata` - @starfi5h: Launch construction drones if local player is closer or within 15m