diff --git a/NebulaClient/NebulaClient.csproj b/NebulaClient/NebulaClient.csproj index 7de658d4c..d8480cabc 100644 --- a/NebulaClient/NebulaClient.csproj +++ b/NebulaClient/NebulaClient.csproj @@ -42,6 +42,8 @@ + + diff --git a/NebulaClient/PacketProcessors/Factory/Belt/BeltUpdatePickupItemsProcessor.cs b/NebulaClient/PacketProcessors/Factory/Belt/BeltUpdatePickupItemsProcessor.cs new file mode 100644 index 000000000..49193306d --- /dev/null +++ b/NebulaClient/PacketProcessors/Factory/Belt/BeltUpdatePickupItemsProcessor.cs @@ -0,0 +1,25 @@ +using NebulaModel.Attributes; +using NebulaModel.Networking; +using NebulaModel.Packets.Belt; +using NebulaModel.Packets.Processors; + +namespace NebulaClient.PacketProcessors.Factory.Belt +{ + [RegisterPacketProcessor] + class BeltUpdatePickupItemsProcessor : IPacketProcessor + { + public void ProcessPacket(BeltUpdatePickupItemsPacket packet, NebulaConnection conn) + { + if (GameMain.data.factories[packet.FactoryIndex]?.cargoTraffic != null) + { + //Iterate though belt updates and remove target items + for (int i = 0; i < packet.BeltUpdates.Length; i++) + { + CargoTraffic traffic = GameMain.data.factories[packet.FactoryIndex].cargoTraffic; + CargoPath cargoPath = traffic.GetCargoPath(traffic.beltPool[packet.BeltUpdates[i].BeltId].segPathId); + cargoPath.TryPickItem(packet.BeltUpdates[i].SegId - 4 - 1, 12); + } + } + } + } +} \ No newline at end of file diff --git a/NebulaClient/PacketProcessors/Factory/Belt/BeltUpdatePutItemOnProcessor.cs b/NebulaClient/PacketProcessors/Factory/Belt/BeltUpdatePutItemOnProcessor.cs new file mode 100644 index 000000000..dae5f606e --- /dev/null +++ b/NebulaClient/PacketProcessors/Factory/Belt/BeltUpdatePutItemOnProcessor.cs @@ -0,0 +1,22 @@ +using NebulaModel.Attributes; +using NebulaModel.Networking; +using NebulaModel.Packets.Belt; +using NebulaModel.Packets.Processors; +using NebulaWorld.Factory; + +namespace NebulaClient.PacketProcessors.Factory.Belt +{ + [RegisterPacketProcessor] + class BeltUpdatePutItemOnProcessor : IPacketProcessor + { + public void ProcessPacket(BeltUpdatePutItemOnPacket packet, NebulaConnection conn) + { + if (GameMain.data.factories[packet.FactoryIndex]?.cargoTraffic != null) + { + FactoryManager.EventFromServer = true; + GameMain.data.factories[packet.FactoryIndex].cargoTraffic.PutItemOnBelt(packet.BeltId, packet.ItemId); + FactoryManager.EventFromServer = false; + } + } + } +} \ No newline at end of file diff --git a/NebulaHost/NebulaHost.csproj b/NebulaHost/NebulaHost.csproj index 99591a1c9..5a761a883 100644 --- a/NebulaHost/NebulaHost.csproj +++ b/NebulaHost/NebulaHost.csproj @@ -43,6 +43,8 @@ + + diff --git a/NebulaHost/PacketProcessors/Factory/Belt/BeltUpdatePickupItemsProcessor.cs b/NebulaHost/PacketProcessors/Factory/Belt/BeltUpdatePickupItemsProcessor.cs new file mode 100644 index 000000000..07ee77d89 --- /dev/null +++ b/NebulaHost/PacketProcessors/Factory/Belt/BeltUpdatePickupItemsProcessor.cs @@ -0,0 +1,22 @@ +using NebulaModel.Attributes; +using NebulaModel.Networking; +using NebulaModel.Packets.Belt; +using NebulaModel.Packets.Processors; + +namespace NebulaHost.PacketProcessors.Factory.Belt +{ + [RegisterPacketProcessor] + class BeltUpdatePickupItemsProcessor : IPacketProcessor + { + public void ProcessPacket(BeltUpdatePickupItemsPacket packet, NebulaConnection conn) + { + //Iterate though belt updates and remove target items + for (int i = 0; i < packet.BeltUpdates.Length; i++) + { + CargoTraffic traffic = GameMain.data.factories[packet.FactoryIndex].cargoTraffic; + CargoPath cargoPath = traffic.GetCargoPath(traffic.beltPool[packet.BeltUpdates[i].BeltId].segPathId); + cargoPath.TryPickItem(packet.BeltUpdates[i].SegId - 4 - 1, 12); + } + } + } +} \ No newline at end of file diff --git a/NebulaHost/PacketProcessors/Factory/Belt/BeltUpdatePutItemOnProcessor.cs b/NebulaHost/PacketProcessors/Factory/Belt/BeltUpdatePutItemOnProcessor.cs new file mode 100644 index 000000000..d31e7b9a7 --- /dev/null +++ b/NebulaHost/PacketProcessors/Factory/Belt/BeltUpdatePutItemOnProcessor.cs @@ -0,0 +1,19 @@ +using NebulaModel.Attributes; +using NebulaModel.Networking; +using NebulaModel.Packets.Belt; +using NebulaModel.Packets.Processors; +using NebulaWorld.Factory; + +namespace NebulaHost.PacketProcessors.Factory.Belt +{ + [RegisterPacketProcessor] + class BeltUpdatePutItemOnProcessor : IPacketProcessor + { + public void ProcessPacket(BeltUpdatePutItemOnPacket packet, NebulaConnection conn) + { + FactoryManager.EventFromClient = true; + GameMain.data.factories[packet.FactoryIndex].cargoTraffic.PutItemOnBelt(packet.BeltId, packet.ItemId); + FactoryManager.EventFromClient = true; + } + } +} \ No newline at end of file diff --git a/NebulaModel/NebulaModel.csproj b/NebulaModel/NebulaModel.csproj index f329331e8..68dbaf3bb 100644 --- a/NebulaModel/NebulaModel.csproj +++ b/NebulaModel/NebulaModel.csproj @@ -59,6 +59,8 @@ + + diff --git a/NebulaModel/Packets/Belt/BeltUpdatePickupItemsPacket.cs b/NebulaModel/Packets/Belt/BeltUpdatePickupItemsPacket.cs new file mode 100644 index 000000000..2d8874f94 --- /dev/null +++ b/NebulaModel/Packets/Belt/BeltUpdatePickupItemsPacket.cs @@ -0,0 +1,51 @@ +using NebulaModel.Attributes; +using NebulaModel.Networking.Serialization; + +namespace NebulaModel.Packets.Belt +{ + public class BeltUpdatePickupItemsPacket + { + public int FactoryIndex { get; set; } + public BeltUpdate[] BeltUpdates { get; set; } + + public BeltUpdatePickupItemsPacket() { } + + public BeltUpdatePickupItemsPacket(BeltUpdate[] beltUpdates, int factoryIndex) + { + BeltUpdates = beltUpdates; + FactoryIndex = factoryIndex; + } + } + + [RegisterNestedType] + public struct BeltUpdate : INetSerializable + { + public int ItemId { get; set; } + public int Count { get; set; } + public int BeltId { get; set; } + public int SegId { get; set; } + public BeltUpdate(int itemId, int count, int beltId, int segId) + { + SegId = segId; + ItemId = itemId; + Count = count; + BeltId = beltId; + } + + public void Serialize(NetDataWriter writer) + { + writer.Put(ItemId); + writer.Put(Count); + writer.Put(BeltId); + writer.Put(SegId); + } + + public void Deserialize(NetDataReader reader) + { + ItemId = reader.GetInt(); + Count = reader.GetInt(); + BeltId = reader.GetInt(); + SegId = reader.GetInt(); + } + } +} diff --git a/NebulaModel/Packets/Belt/BeltUpdatePutItemOnPacket.cs b/NebulaModel/Packets/Belt/BeltUpdatePutItemOnPacket.cs new file mode 100644 index 000000000..e53e31abf --- /dev/null +++ b/NebulaModel/Packets/Belt/BeltUpdatePutItemOnPacket.cs @@ -0,0 +1,16 @@ +namespace NebulaModel.Packets.Belt +{ + public class BeltUpdatePutItemOnPacket + { + public int BeltId { get; set; } + public int ItemId { get; set; } + public int FactoryIndex { get; set; } + public BeltUpdatePutItemOnPacket() { } + public BeltUpdatePutItemOnPacket(int beltId, int itemId, int factoryIndex) + { + BeltId = beltId; + ItemId = itemId; + FactoryIndex = factoryIndex; + } + } +} diff --git a/NebulaPatcher/NebulaPatcher.csproj b/NebulaPatcher/NebulaPatcher.csproj index 96a40c5a2..5292edeb3 100644 --- a/NebulaPatcher/NebulaPatcher.csproj +++ b/NebulaPatcher/NebulaPatcher.csproj @@ -40,6 +40,7 @@ + @@ -81,6 +82,7 @@ + diff --git a/NebulaPatcher/Patches/Dynamic/CargoTraffic_Patch.cs b/NebulaPatcher/Patches/Dynamic/CargoTraffic_Patch.cs new file mode 100644 index 000000000..569c2b7e6 --- /dev/null +++ b/NebulaPatcher/Patches/Dynamic/CargoTraffic_Patch.cs @@ -0,0 +1,41 @@ +using HarmonyLib; +using NebulaModel.Packets.Belt; +using NebulaWorld; +using NebulaWorld.Factory; + +namespace NebulaPatcher.Patches.Dynamic +{ + [HarmonyPatch(typeof(CargoTraffic))] + class CargoTraffic_Patch + { + [HarmonyPrefix] + [HarmonyPatch("PickupBeltItems")] + public static void PickupBeltItems_Prefix() + { + if (SimulatedWorld.Initialized) + { + BeltManager.BeltPickupStarted(); + } + } + + [HarmonyPostfix] + [HarmonyPatch("PickupBeltItems")] + public static void PickupBeltItems_Postfix() + { + if (SimulatedWorld.Initialized) + { + BeltManager.BeltPickupEnded(); + } + } + + [HarmonyPrefix] + [HarmonyPatch("PutItemOnBelt")] + public static void PutItemOnBelt_Prefix(int beltId, int itemId) + { + if (SimulatedWorld.Initialized && !FactoryManager.EventFromServer && !FactoryManager.EventFromClient) + { + LocalPlayer.SendPacketToLocalStar(new BeltUpdatePutItemOnPacket(beltId, itemId, GameMain.data.localPlanet.factoryIndex)); + } + } + } +} diff --git a/NebulaPatcher/Patches/Transpilers/CargoTraffic_Patch.cs b/NebulaPatcher/Patches/Transpilers/CargoTraffic_Patch.cs new file mode 100644 index 000000000..dce7379c1 --- /dev/null +++ b/NebulaPatcher/Patches/Transpilers/CargoTraffic_Patch.cs @@ -0,0 +1,51 @@ +using HarmonyLib; +using NebulaWorld.Factory; +using System.Collections.Generic; +using System.Reflection.Emit; + +namespace NebulaPatcher.Patches.Transpiler +{ + /* Change this: + if (num3 > 0) + { + UIItemup.Up(itemId, num3); + } + + * To this: + if (num3 > 0) + { + BeltManager.RegisterBeltPickupUpdate(itemId, count, beltId, segId); + UIItemup.Up(itemId, num3); + } + */ + [HarmonyPatch(typeof(CargoTraffic))] + class CargoTraffic_Patch + { + [HarmonyTranspiler] + [HarmonyPatch("PickupBeltItems")] + static IEnumerable PickupBeltItems_Transpiler(ILGenerator gen, IEnumerable instructions) + { + var codes = new List(instructions); + for (int i = 0; i < codes.Count; i++) + { + if (codes[i].opcode == OpCodes.Ble && + codes[i - 1].opcode == OpCodes.Ldc_I4_0 && + codes[i - 2].opcode == OpCodes.Ldloc_S && + codes[i - 3].opcode == OpCodes.Stloc_S && + codes[i - 4].opcode == OpCodes.Callvirt && + codes[i - 5].opcode == OpCodes.Ldfld) + { + codes.InsertRange(i + 1, new CodeInstruction[] { + new CodeInstruction(OpCodes.Ldloc_S, 4), + new CodeInstruction(OpCodes.Ldloc_S, 5), + new CodeInstruction(OpCodes.Ldarg_2), + new CodeInstruction(OpCodes.Ldloc_3), + new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(BeltManager), "RegisterBeltPickupUpdate", new System.Type[] { typeof(int), typeof(int), typeof(int), typeof(int)})), + }); + break; + } + } + return codes; + } + } +} diff --git a/NebulaWorld/Factory/BeltManager.cs b/NebulaWorld/Factory/BeltManager.cs new file mode 100644 index 000000000..c4a13bf9c --- /dev/null +++ b/NebulaWorld/Factory/BeltManager.cs @@ -0,0 +1,26 @@ +using NebulaModel.Packets.Belt; +using System.Collections.Generic; + +namespace NebulaWorld.Factory +{ + public static class BeltManager + { + public static List BeltUpdates = new List(); + public static void BeltPickupStarted() + { + BeltUpdates.Clear(); + } + public static void RegisterBeltPickupUpdate(int itemId, int count, int beltId, int segId) + { + if (SimulatedWorld.Initialized) + { + BeltUpdates.Add(new BeltUpdate(itemId, count, beltId, segId)); + } + } + public static void BeltPickupEnded() + { + LocalPlayer.SendPacketToLocalStar(new BeltUpdatePickupItemsPacket(BeltUpdates.ToArray(), GameMain.data.localPlanet.factoryIndex)); + BeltUpdates.Clear(); + } + } +} diff --git a/NebulaWorld/NebulaWorld.csproj b/NebulaWorld/NebulaWorld.csproj index 2d11596d0..8a8755e24 100644 --- a/NebulaWorld/NebulaWorld.csproj +++ b/NebulaWorld/NebulaWorld.csproj @@ -39,6 +39,7 @@ +