From e0287a13afd739e722506fabc2c44fb623196341 Mon Sep 17 00:00:00 2001 From: starfish Date: Wed, 26 Jan 2022 04:22:08 +0800 Subject: [PATCH 1/8] Refactor StationUIManager --- .../Logistics/StationSubscribeUIUpdates.cs | 18 -- .../StationSubscribeUIUpdatesProcessor.cs | 29 --- .../StationUIInitialSyncProcessor.cs | 62 ++--- .../Logistics/StationUIProcessor.cs | 54 +--- .../Patches/Dynamic/UIStationWindow_Patch.cs | 61 ++--- NebulaWorld/Logistics/StationUIManager.cs | 243 ++---------------- 6 files changed, 70 insertions(+), 397 deletions(-) delete mode 100644 NebulaModel/Packets/Logistics/StationSubscribeUIUpdates.cs delete mode 100644 NebulaNetwork/PacketProcessors/Logistics/StationSubscribeUIUpdatesProcessor.cs diff --git a/NebulaModel/Packets/Logistics/StationSubscribeUIUpdates.cs b/NebulaModel/Packets/Logistics/StationSubscribeUIUpdates.cs deleted file mode 100644 index b749187b4..000000000 --- a/NebulaModel/Packets/Logistics/StationSubscribeUIUpdates.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace NebulaModel.Packets.Logistics -{ - public class StationSubscribeUIUpdates - { - public int PlanetId { get; set; } - public int StationId { get; set; } - public int StationGId { get; set; } - public bool Subscribe { get; set; } - public StationSubscribeUIUpdates() { } - public StationSubscribeUIUpdates(bool subscribe, int planetId, int stationId, int stationGId) - { - PlanetId = planetId; - StationId = stationId; - StationGId = stationGId; - Subscribe = subscribe; - } - } -} diff --git a/NebulaNetwork/PacketProcessors/Logistics/StationSubscribeUIUpdatesProcessor.cs b/NebulaNetwork/PacketProcessors/Logistics/StationSubscribeUIUpdatesProcessor.cs deleted file mode 100644 index 76219b944..000000000 --- a/NebulaNetwork/PacketProcessors/Logistics/StationSubscribeUIUpdatesProcessor.cs +++ /dev/null @@ -1,29 +0,0 @@ -using NebulaAPI; -using NebulaModel.Networking; -using NebulaModel.Packets; -using NebulaModel.Packets.Logistics; -using NebulaWorld; - -namespace NebulaNetwork.PacketProcessors.Logistics -{ - [RegisterPacketProcessor] - internal class StationSubscribeUIUpdatesProcessor : PacketProcessor - { - public override void ProcessPacket(StationSubscribeUIUpdates packet, NebulaConnection conn) - { - if (IsClient) - { - return; - } - - if (packet.Subscribe) - { - Multiplayer.Session.StationsUI.AddSubscriber(packet.PlanetId, packet.StationId, packet.StationGId, conn); - } - else - { - Multiplayer.Session.StationsUI.RemoveSubscriber(packet.PlanetId, packet.StationId, packet.StationGId, conn); - } - } - } -} diff --git a/NebulaNetwork/PacketProcessors/Logistics/StationUIInitialSyncProcessor.cs b/NebulaNetwork/PacketProcessors/Logistics/StationUIInitialSyncProcessor.cs index a3665b383..80efc0168 100644 --- a/NebulaNetwork/PacketProcessors/Logistics/StationUIInitialSyncProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Logistics/StationUIInitialSyncProcessor.cs @@ -8,7 +8,6 @@ /* * When the client opens the UI of a station (ILS/PLS/Collector) the contents gets updated and shown to * the player once this packet is received. He will see a loading text before that. - * This will also subscribe to live updates syncing changes made by other players to the station while the UI is opened */ namespace NebulaNetwork.PacketProcessors.Logistics { @@ -29,47 +28,36 @@ public override void ProcessPacket(StationUIInitialSync packet, NebulaConnection return; } - if (Multiplayer.Session.StationsUI.UIIsSyncedStage == 1) - { - UIStationWindow stationWindow = UIRoot.instance.uiGame.stationWindow; - - stationComponent.tripRangeDrones = packet.TripRangeDrones; - stationComponent.tripRangeShips = packet.TripRangeShips; - stationComponent.deliveryDrones = packet.DeliveryDrones; - stationComponent.deliveryShips = packet.DeliveryShips; - stationComponent.warpEnableDist = packet.WarperEnableDistance; - stationComponent.warperNecessary = packet.WarperNecessary; - stationComponent.includeOrbitCollector = packet.IncludeOrbitCollector; - stationComponent.energy = packet.Energy; - stationComponent.energyPerTick = packet.EnergyPerTick; + stationComponent.tripRangeDrones = packet.TripRangeDrones; + stationComponent.tripRangeShips = packet.TripRangeShips; + stationComponent.deliveryDrones = packet.DeliveryDrones; + stationComponent.deliveryShips = packet.DeliveryShips; + stationComponent.warpEnableDist = packet.WarperEnableDistance; + stationComponent.warperNecessary = packet.WarperNecessary; + stationComponent.includeOrbitCollector = packet.IncludeOrbitCollector; + stationComponent.energy = packet.Energy; + stationComponent.energyPerTick = packet.EnergyPerTick; - for (int i = 0; i < packet.ItemId.Length; i++) + for (int i = 0; i < packet.ItemId.Length; i++) + { + if (stationComponent.storage == null) { - if (stationComponent.storage == null) - { - stationComponent.storage = new StationStore[packet.ItemId.Length]; - } - - stationComponent.storage[i].itemId = packet.ItemId[i]; - stationComponent.storage[i].max = packet.ItemCountMax[i]; - stationComponent.storage[i].count = packet.ItemCount[i]; - stationComponent.storage[i].remoteOrder = packet.RemoteOrder[i]; - stationComponent.storage[i].localLogic = (ELogisticStorage)packet.LocalLogic[i]; - stationComponent.storage[i].remoteLogic = (ELogisticStorage)packet.RemoteLogic[i]; + stationComponent.storage = new StationStore[packet.ItemId.Length]; } - if (stationWindow != null && stationWindow.active) - { - conn.SendPacket(new StationSubscribeUIUpdates(true, stationComponent.planetId, stationComponent.id, stationComponent.gid)); - Multiplayer.Session.StationsUI.UIIsSyncedStage++; - stationWindow._Free(); - stationWindow._Init(stationComponent); - stationWindow._stationId = stationComponent.id; - stationWindow._Open(); - stationWindow._Update(); - } + stationComponent.storage[i].itemId = packet.ItemId[i]; + stationComponent.storage[i].max = packet.ItemCountMax[i]; + stationComponent.storage[i].count = packet.ItemCount[i]; + stationComponent.storage[i].remoteOrder = packet.RemoteOrder[i]; + stationComponent.storage[i].localLogic = (ELogisticStorage)packet.LocalLogic[i]; + stationComponent.storage[i].remoteLogic = (ELogisticStorage)packet.RemoteLogic[i]; + } - Multiplayer.Session.StationsUI.UIStationId = stationComponent.id; + UIStationWindow stationWindow = UIRoot.instance.uiGame.stationWindow; + if (stationWindow.active && Multiplayer.Session.StationsUI.UIIsSyncedStage == 1) + { + //Trigger OnStationIdChange() to refresh window + stationWindow.OnStationIdChange(); } } } diff --git a/NebulaNetwork/PacketProcessors/Logistics/StationUIProcessor.cs b/NebulaNetwork/PacketProcessors/Logistics/StationUIProcessor.cs index 337e6f825..0ffc8e360 100644 --- a/NebulaNetwork/PacketProcessors/Logistics/StationUIProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Logistics/StationUIProcessor.cs @@ -20,55 +20,17 @@ public override void ProcessPacket(StationUI packet, NebulaConnection conn) { if (IsHost) { - // if a user adds/removes a ship, drone or warper or changes max power input broadcast to everyone. - if (Multiplayer.Session.StationsUI.UpdateCooldown == 0 && - (packet.SettingIndex == StationUI.EUISettings.MaxChargePower - || packet.SettingIndex == StationUI.EUISettings.SetDroneCount - || packet.SettingIndex == StationUI.EUISettings.SetShipCount - || packet.SettingIndex == StationUI.EUISettings.SetWarperCount) - ) - { - // this is the SendPacketToAllPlayers() logic but we need to set the mimic flag here. - using (playerManager.GetConnectedPlayers(out Dictionary connectedPlayers)) - { - foreach (KeyValuePair kvp in connectedPlayers) - { - INebulaPlayer p = kvp.Value; - packet.ShouldMimic = ((NebulaConnection)p.Connection) == conn; - p.SendPacket(packet); - } - } - } - else if (packet.SettingIndex == StationUI.EUISettings.AddOrRemoveItemFromStorageResponse) - { - // if someone adds or removes items by hand broadcast to every player on that planet - INebulaPlayer player = playerManager.GetPlayer(conn); - if (player != null) - { - playerManager.SendPacketToPlanet(packet, player.Data.LocalPlanetId); - } - } - else if (Multiplayer.Session.StationsUI.UpdateCooldown == 0 || !packet.IsStorageUI) - { - List subscribers = Multiplayer.Session.StationsUI.GetSubscribers(packet.PlanetId, packet.StationId, packet.StationGId); - - for (int i = 0; i < subscribers.Count; i++) - { - if (subscribers[i] != null) - { - /* - * as we block the normal method for the client he must run it once he receives this packet. - * but only the one issued the request should do it, we indicate this here - */ - packet.ShouldMimic = subscribers[i] == conn; - subscribers[i].SendPacket(packet); - } - } - } // always update values for host, but he does not need to rely on the mimic flag (infact its bad for him) packet.ShouldMimic = false; - Multiplayer.Session.StationsUI.UpdateUI(packet); + + // broadcast to every clients that may have the station loaded. + playerManager.SendPacketToStarExcept(packet, packet.PlanetId, conn); + + // as we block the normal method for the client he must run it once he receives this packet. + // but only the one issued the request should do it, we indicate this here + packet.ShouldMimic = true; + conn.SendPacket(packet); } if (IsClient) diff --git a/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs b/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs index 7aed6d18a..03a3befda 100644 --- a/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs @@ -284,45 +284,32 @@ public static bool OnWarperIconClick_Prefix(UIStationWindow __instance) return true; } - [HarmonyPrefix] - [HarmonyPatch(nameof(UIStationWindow.OnStationIdChange))] - public static bool OnStationIdChange_Prefix(UIStationWindow __instance) + [HarmonyPostfix] + [HarmonyPatch(nameof(UIStationWindow._OnOpen))] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Original Function Name")] + public static void _OnOpen_Postfix(UIStationWindow __instance) { - if (!Multiplayer.IsActive || Multiplayer.Session.LocalPlayer.IsHost || Multiplayer.Session.StationsUI.UIIsSyncedStage > 0 || GameMain.localPlanet == null || !__instance.active) + if (!Multiplayer.IsActive || Multiplayer.Session.LocalPlayer.IsHost || Multiplayer.Session.StationsUI.UIIsSyncedStage > 0) { - return true; + return; } + + // Hide UI elements until sync data arrive __instance.titleText.text = "Loading..."; - Multiplayer.Session.StationsUI.LastSelectedGameObj = EventSystem.current.currentSelectedGameObject; - if (__instance.factory == null) - { - __instance.factory = GameMain.localPlanet.factory; - } - if (__instance.transport == null) - { - __instance.transport = __instance.factory.transport; - } - StationComponent stationComponent = null; - if (__instance.stationId == 0) + for (int i = 0; i < __instance.storageUIs.Length; i++) { - UIStationStorage[] stationStorage = __instance.storageUIs; - if (stationStorage != null && stationStorage[0] != null && stationStorage[0].station.id != 0) - { - stationComponent = __instance.transport.stationPool[stationStorage[0].station.id]; - } + __instance.storageUIs[i]._Close(); + __instance.storageUIs[i].ClosePopMenu(); } - else - { - stationComponent = __instance.transport.stationPool[__instance.stationId]; - } - if (stationComponent != null && GameMain.localPlanet != null) + __instance.panelDown.SetActive(false); + + StationComponent stationComponent = __instance.transport?.stationPool[__instance.stationId]; + if (stationComponent != null && __instance.factory != null) { - int id = (stationComponent.isStellar == true) ? stationComponent.gid : stationComponent.id; - // for some reason PLS has planetId set to 0, so we use players localPlanet here (he should be on a planet anyways when opening the UI) - Multiplayer.Session.Network.SendPacket(new StationUIInitialSyncRequest(stationComponent.planetId, stationComponent.id, stationComponent.gid)); + // for some reason advance miner has planetId set to 0, so we use UI's factory planetId + Multiplayer.Session.Network.SendPacket(new StationUIInitialSyncRequest(__instance.factory.planetId, stationComponent.id, stationComponent.gid)); Multiplayer.Session.StationsUI.UIIsSyncedStage++; } - return false; } [HarmonyPrefix] @@ -346,21 +333,9 @@ public static void _OnClose_Postfix(UIStationWindow __instance) { return; } - if (__instance.factory == null) - { - __instance.factory = GameMain.localPlanet.factory; - } - if (__instance.transport == null) - { - __instance.transport = __instance.factory.transport; - } - if (__instance.stationId != 0 || Multiplayer.Session.StationsUI.UIStationId != 0) + if (__instance.stationId != 0) { - // it is actually 0 before we manually set it to the right value in StationUIInitialSyncProcessor.cs and thus its a good check to skip sending the packet on the Free() call - Multiplayer.Session.Network.SendPacket(new StationSubscribeUIUpdates(false, __instance.transport.planet.id, __instance.transport.stationPool[Multiplayer.Session.StationsUI.UIStationId].id, __instance.transport.stationPool[Multiplayer.Session.StationsUI.UIStationId].gid)); - Multiplayer.Session.StationsUI.LastSelectedGameObj = null; Multiplayer.Session.StationsUI.UIIsSyncedStage = 0; - Multiplayer.Session.StationsUI.UIStationId = 0; } } } diff --git a/NebulaWorld/Logistics/StationUIManager.cs b/NebulaWorld/Logistics/StationUIManager.cs index 011880b40..3f8a64a64 100644 --- a/NebulaWorld/Logistics/StationUIManager.cs +++ b/NebulaWorld/Logistics/StationUIManager.cs @@ -8,93 +8,25 @@ namespace NebulaWorld.Logistics { - public class Subscribers - { - public int PlanetId { get; } - public int StationId { get; } - public int StationGId { get; } - public List Connections { get; set; } - public Subscribers(int planetId, int stationId, int stationGId) - { - PlanetId = planetId; - StationId = stationId; - StationGId = stationGId; - Connections = new List(); - } - - public override string ToString() - { - return $"{PlanetId}.{StationId}.{StationGId}"; - } - - public static string GetKey(int planetId, int stationId, int statgionGId) - { - return $"{planetId}.{stationId}.{statgionGId}"; - } - } - public class StationUIManager : IDisposable { - private Dictionary _stationUISubscribers; - - public int UpdateCooldown; // cooldown is used to slow down updates on storage slider + public int UpdateCooldown; // cooldown is reserved for future use public BaseEventData LastMouseEvent; public bool LastMouseEventWasDown; - public GameObject LastSelectedGameObj; public int UIIsSyncedStage; // 0 == not synced, 1 == request sent, 2 == synced | this is only used client side - public int UIStationId; public bool UIRequestedShipDronWarpChange; // when receiving a ship, drone or warp change only take/add items from the one issuing the request public StationUIManager() { - _stationUISubscribers = new Dictionary(); } public void Dispose() { - _stationUISubscribers = null; - } - - // When a client opens a station's UI he requests a subscription for live updates, so add him to the list - public void AddSubscriber(int planetId, int stationId, int stationGId, NebulaConnection connection) - { - // Attempt to find existing subscribers to a specific station, if we couldn't find an existing one - // we must initialize a new Subscribers for this specific station. - if (!_stationUISubscribers.TryGetValue(Subscribers.GetKey(planetId, stationId, stationGId), out Subscribers subscribers)) - { - _stationUISubscribers.Add(Subscribers.GetKey(planetId, stationId, stationGId), new Subscribers(planetId, stationId, stationGId)); - } - - _stationUISubscribers.TryGetValue(Subscribers.GetKey(planetId, stationId, stationGId), out subscribers); - - subscribers?.Connections.Add(connection); - } - public void RemoveSubscriber(int planetId, int stationId, int stationGId, NebulaConnection connection) - { - if (_stationUISubscribers.TryGetValue(Subscribers.GetKey(planetId, stationId, stationGId), out Subscribers subscribers)) - { - subscribers.Connections.Remove(connection); - - if (subscribers.Connections.Count == 0) - { - _stationUISubscribers.Remove(subscribers.ToString()); - } - } - } - - public List GetSubscribers(int planetId, int stationId, int stationGId) - { - if (!_stationUISubscribers.TryGetValue(Subscribers.GetKey(planetId, stationId, stationGId), out Subscribers subscribers)) - { - return new List(); - } - - return subscribers.Connections; } public void DecreaseCooldown() { - // cooldown is for the storage sliders + // cooldown is reserved for future use if (UpdateCooldown > 0) { UpdateCooldown--; @@ -103,27 +35,23 @@ public void DecreaseCooldown() public void UpdateUI(StationUI packet) { - if ((UpdateCooldown == 0 || !packet.IsStorageUI) && Multiplayer.Session.LocalPlayer.IsHost) + if (packet.IsStorageUI) { - UpdateCooldown = 10; - if (packet.IsStorageUI) - { - UpdateStorageUI(packet); - } - else - { - UpdateSettingsUI(packet); - } + UpdateStorageUI(packet); } - else if (!Multiplayer.Session.LocalPlayer.IsHost) + else { - if (packet.IsStorageUI) - { - UpdateStorageUI(packet); - } - else + UpdateSettingsUI(packet); + } + + // If station window is opened and veiwing the updating station, refresh the window. + UIStationWindow stationWindow = UIRoot.instance.uiGame.stationWindow; + if (stationWindow != null && stationWindow.active) + { + if (stationWindow.factory?.planetId == packet.PlanetId && stationWindow.stationId == packet.StationId) { - UpdateSettingsUI(packet); + Log.Info($"Refresh value {packet.StationId}"); + stationWindow.OnStationIdChange(); } } } @@ -269,8 +197,6 @@ private void UpdateSettingsUIBackground(StationUI packet, PlanetData planet, Sta */ private void UpdateSettingsUI(StationUI packet) { - UIStationWindow stationWindow = UIRoot.instance.uiGame.stationWindow; - StationComponent stationComponent = null; PlanetData planet = GameMain.galaxy?.PlanetById(packet.PlanetId); @@ -288,144 +214,12 @@ private void UpdateSettingsUI(StationUI packet) if (stationComponent == null) { - Log.Error($"UpdateStorageUI: Unable to find requested station on planet {packet.PlanetId} with id {packet.StationId} and gid of {packet.StationGId}"); + Log.Warn($"UpdateStorageUI: Unable to find requested station on planet {packet.PlanetId} with id {packet.StationId} and gid of {packet.StationGId}"); return; } - if (stationWindow == null) - { - return; - } - - int _stationId = stationWindow._stationId; - - // Client has no knowledge of the planet, closed the window or - // opened a different station, do all updates in the background. - if (planet?.factory?.transport == null || stationComponent.id != _stationId) - { - UpdateSettingsUIBackground(packet, planet, stationComponent); - return; - } - - // this locks the patches so we can call vanilla functions without triggering our patches to avoid endless loops - using (Multiplayer.Session.Ships.PatchLockILS.On()) - { - if (packet.SettingIndex == StationUI.EUISettings.MaxChargePower) - { - stationWindow.OnMaxChargePowerSliderValueChange(packet.SettingValue); - } - if (packet.SettingIndex == StationUI.EUISettings.MaxTripDrones) - { - stationWindow.OnMaxTripDroneSliderValueChange(packet.SettingValue); - } - if (packet.SettingIndex == StationUI.EUISettings.MaxTripVessel) - { - stationWindow.OnMaxTripVesselSliderValueChange(packet.SettingValue); - } - if (packet.SettingIndex == StationUI.EUISettings.MinDeliverDrone) - { - stationWindow.OnMinDeliverDroneValueChange(packet.SettingValue); - } - if (packet.SettingIndex == StationUI.EUISettings.MinDeliverVessel) - { - stationWindow.OnMinDeliverVesselValueChange(packet.SettingValue); - } - if (packet.SettingIndex == StationUI.EUISettings.WarpDistance) - { - stationWindow.OnWarperDistanceValueChange(packet.SettingValue); - } - if (packet.SettingIndex == StationUI.EUISettings.WarperNeeded) - { - stationWindow.OnWarperNecessaryClick(0); - } - if (packet.SettingIndex == StationUI.EUISettings.IncludeCollectors) - { - stationWindow.OnIncludeOrbitCollectorClick(0); - } - if (packet.SettingIndex >= StationUI.EUISettings.SetDroneCount && packet.SettingIndex <= StationUI.EUISettings.SetWarperCount) - { - if (packet.SettingIndex == StationUI.EUISettings.SetDroneCount) - { - if (UIRequestedShipDronWarpChange) - { - stationWindow.OnDroneIconClick(0); - UIRequestedShipDronWarpChange = false; - } - stationComponent.idleDroneCount = (int)packet.SettingValue; - } - if (packet.SettingIndex == StationUI.EUISettings.SetShipCount) - { - if (UIRequestedShipDronWarpChange) - { - stationWindow.OnShipIconClick(0); - UIRequestedShipDronWarpChange = false; - } - stationComponent.idleShipCount = (int)packet.SettingValue; - } - if (packet.SettingIndex == StationUI.EUISettings.SetWarperCount) - { - if (UIRequestedShipDronWarpChange) - { - stationWindow.OnWarperIconClick(0); - UIRequestedShipDronWarpChange = false; - } - stationComponent.warperCount = (int)packet.SettingValue; - - if (stationComponent.storage != null && packet.WarperShouldTakeFromStorage) - { - for (int i = 0; i < stationComponent.storage.Length; i++) - { - if (stationComponent.storage[i].itemId == 1210 && stationComponent.storage[i].count > 0) - { - stationComponent.storage[i].count--; - break; - } - } - } - } - } - /* - * the idea is that clients request that they want to apply a change and do so once the server responded with an okay. - * the calls to OnItemIconMouseDown() and OnItemIconMouseUp() are blocked for clients and called only from here. - */ - if (packet.SettingIndex == StationUI.EUISettings.AddOrRemoveItemFromStorageRequest) - { - if (stationComponent.storage != null) - { - if (packet.ShouldMimic) - { - BaseEventData mouseEvent = LastMouseEvent; - UIStationStorage[] storageUIs = stationWindow.storageUIs; - - if (LastMouseEvent != null) - { - // TODO: change this such that only server sends the response, else clients with a desynced state could change servers storage to a faulty value - // issue #249 - if (LastMouseEventWasDown) - { - storageUIs[packet.StorageIdx].OnItemIconMouseDown(mouseEvent); - StationUI packet2 = new StationUI(packet.PlanetId, packet.StationId, packet.StationGId, packet.StorageIdx, StationUI.EUISettings.AddOrRemoveItemFromStorageResponse, packet.ItemId, stationComponent.storage[packet.StorageIdx].count); - Multiplayer.Session.Network.SendPacket(packet2); - } - else - { - storageUIs[packet.StorageIdx].OnItemIconMouseUp(mouseEvent); - StationUI packet2 = new StationUI(packet.PlanetId, packet.StationId, packet.StationGId, packet.StorageIdx, StationUI.EUISettings.AddOrRemoveItemFromStorageResponse, packet.ItemId, stationComponent.storage[packet.StorageIdx].count); - Multiplayer.Session.Network.SendPacket(packet2); - } - LastMouseEvent = null; - } - } - } - } - if (packet.SettingIndex == StationUI.EUISettings.AddOrRemoveItemFromStorageResponse) - { - if (stationComponent.storage != null) - { - stationComponent.storage[packet.StorageIdx].count = (int)packet.SettingValue; - } - } - } + // Do all updates in the background. + UpdateSettingsUIBackground(packet, planet, stationComponent); } private void UpdateStorageUI(StationUI packet) @@ -452,6 +246,7 @@ private void UpdateStorageUI(StationUI packet) using (Multiplayer.Session.Ships.PatchLockILS.On()) { + Log.Info($"Refresh storage {stationComponent.id}"); planet.factory.transport.SetStationStorage(stationComponent.id, packet.StorageIdx, packet.ItemId, packet.ItemCountMax, packet.LocalLogic, packet.RemoteLogic, (packet.ShouldMimic == true) ? GameMain.mainPlayer : null); } } From a326498c53eb8f70137b26bd0fc92e5b00a2f9b8 Mon Sep 17 00:00:00 2001 From: starfish Date: Thu, 27 Jan 2022 21:55:26 +0800 Subject: [PATCH 2/8] Change sliders dragging behaviors - Make setting sliders only send packets when mouse button release - Make storage max sliders only apply when dragging stop --- NebulaModel/Packets/Logistics/StationUI.cs | 1 + .../StationUIInitialSyncProcessor.cs | 2 +- .../Patches/Dynamic/UIStationStorage_Patch.cs | 42 +++++ .../Patches/Dynamic/UIStationWindow_Patch.cs | 169 ++++++++---------- NebulaWorld/Logistics/StationUIManager.cs | 10 +- 5 files changed, 128 insertions(+), 96 deletions(-) diff --git a/NebulaModel/Packets/Logistics/StationUI.cs b/NebulaModel/Packets/Logistics/StationUI.cs index 2d186b536..2980f8749 100644 --- a/NebulaModel/Packets/Logistics/StationUI.cs +++ b/NebulaModel/Packets/Logistics/StationUI.cs @@ -4,6 +4,7 @@ public class StationUI { public enum EUISettings { + None, MaxChargePower, MaxTripDrones, MaxTripVessel, diff --git a/NebulaNetwork/PacketProcessors/Logistics/StationUIInitialSyncProcessor.cs b/NebulaNetwork/PacketProcessors/Logistics/StationUIInitialSyncProcessor.cs index 80efc0168..73c0d27e3 100644 --- a/NebulaNetwork/PacketProcessors/Logistics/StationUIInitialSyncProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Logistics/StationUIInitialSyncProcessor.cs @@ -54,7 +54,7 @@ public override void ProcessPacket(StationUIInitialSync packet, NebulaConnection } UIStationWindow stationWindow = UIRoot.instance.uiGame.stationWindow; - if (stationWindow.active && Multiplayer.Session.StationsUI.UIIsSyncedStage == 1) + if (stationWindow.active && stationWindow.factory?.planetId == packet.PlanetId && stationWindow.stationId == packet.StationId) { //Trigger OnStationIdChange() to refresh window stationWindow.OnStationIdChange(); diff --git a/NebulaPatcher/Patches/Dynamic/UIStationStorage_Patch.cs b/NebulaPatcher/Patches/Dynamic/UIStationStorage_Patch.cs index 5fd239d37..1a6cb5326 100644 --- a/NebulaPatcher/Patches/Dynamic/UIStationStorage_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/UIStationStorage_Patch.cs @@ -3,11 +3,53 @@ using NebulaWorld; using UnityEngine.EventSystems; + namespace NebulaPatcher.Patches.Dynamic { [HarmonyPatch(typeof(UIStationStorage))] internal class UIStationStorage_Patch { + private static bool eventLock; + + [HarmonyPrefix] + [HarmonyPatch(nameof(UIStationStorage.OnMaxSliderValueChange))] + public static bool OnMaxSliderValueChangePrefix(UIStationStorage __instance, float val) + { + if (Multiplayer.IsActive && !eventLock) + { + if (val != (float)(__instance.station.storage[__instance.index].max / 100)) + { + // If the silder value doesn't match with storage.max, mark it + Multiplayer.Session.StationsUI.StorageMaxChangeId = __instance.index; + } + } + return !Multiplayer.IsActive; + } + + [HarmonyPrefix] + [HarmonyPatch(nameof(UIStationStorage._OnUpdate))] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Original Function Name")] + public static void _OnUpdate_Prefix(UIStationStorage __instance, ref float __state) + { + // Set up eventLock so value changes in maxSlider.value don't trigger changed check + eventLock = true; + __state = __instance.maxSlider.value; + } + + [HarmonyPostfix] + [HarmonyPatch(nameof(UIStationStorage._OnUpdate))] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Original Function Name")] + public static void _OnUpdate_Postfix(UIStationStorage __instance, float __state) + { + // Restore the silder value so it is not modified by RefreshValues() + if (Multiplayer.IsActive && Multiplayer.Session.StationsUI.StorageMaxChangeId != -1) + { + __instance.maxSlider.value = __state; + __instance.maxValueText.text = ((int)(__instance.maxSlider.value * 100)).ToString(); + } + eventLock = false; + } + /* * host behaves normally and sends update to clients which then apply the changes * clients send a request to the server and only run the original method once they receive the response diff --git a/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs b/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs index 03a3befda..913f0c7d9 100644 --- a/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs @@ -1,7 +1,7 @@ using HarmonyLib; -using NebulaModel.Logger; using NebulaModel.Packets.Logistics; using NebulaWorld; +using UnityEngine; using UnityEngine.EventSystems; namespace NebulaPatcher.Patches.Dynamic @@ -13,136 +13,104 @@ internal class UIStationWindow_Patch [HarmonyPatch(nameof(UIStationWindow.OnMaxChargePowerSliderValueChange))] public static bool OnMaxChargePowerSliderValueChange_Prefix(UIStationWindow __instance, float value) { - if (Multiplayer.IsActive && !Multiplayer.Session.Ships.PatchLockILS) + if (__instance.event_lock || !Multiplayer.IsActive || Multiplayer.Session.Ships.PatchLockILS) { - StationUI packet = new StationUI(__instance.factory.planet.id, __instance.factory.transport.stationPool[__instance.stationId].id, __instance.factory.transport.stationPool[__instance.stationId].gid, StationUI.EUISettings.MaxChargePower, value); - Multiplayer.Session.Network.SendPacket(packet); - if (Multiplayer.Session.LocalPlayer.IsHost) - { - return true; - } - return false; + return true; } - return true; + Multiplayer.Session.StationsUI.SliderBarPacket.SettingIndex = StationUI.EUISettings.MaxChargePower; + Multiplayer.Session.StationsUI.SliderBarPacket.SettingValue = value; + return Multiplayer.Session.LocalPlayer.IsHost; } [HarmonyPrefix] [HarmonyPatch(nameof(UIStationWindow.OnMaxTripDroneSliderValueChange))] public static bool OnMaxTripDroneSliderValueChange_Prefix(UIStationWindow __instance, float value) { - if (Multiplayer.IsActive && !Multiplayer.Session.Ships.PatchLockILS && (Multiplayer.Session.StationsUI.UIIsSyncedStage == 2 || Multiplayer.Session.LocalPlayer.IsHost)) + if (__instance.event_lock || !Multiplayer.IsActive || Multiplayer.Session.Ships.PatchLockILS) { - StationUI packet = new StationUI(__instance.factory.planet.id, __instance.factory.transport.stationPool[__instance.stationId].id, __instance.factory.transport.stationPool[__instance.stationId].gid, StationUI.EUISettings.MaxTripDrones, value); - Multiplayer.Session.Network.SendPacket(packet); - if (Multiplayer.Session.LocalPlayer.IsHost) - { - return true; - } - return false; + return true; } - return true; + Multiplayer.Session.StationsUI.SliderBarPacket.SettingIndex = StationUI.EUISettings.MaxTripDrones; + Multiplayer.Session.StationsUI.SliderBarPacket.SettingValue = value; + return Multiplayer.Session.LocalPlayer.IsHost; } [HarmonyPrefix] [HarmonyPatch(nameof(UIStationWindow.OnMaxTripVesselSliderValueChange))] public static bool OnMaxTripVesselSliderValueChange_Prefix(UIStationWindow __instance, float value) { - if (Multiplayer.IsActive && !Multiplayer.Session.Ships.PatchLockILS && (Multiplayer.Session.StationsUI.UIIsSyncedStage == 2 || Multiplayer.Session.LocalPlayer.IsHost)) + if (__instance.event_lock || !Multiplayer.IsActive || Multiplayer.Session.Ships.PatchLockILS) { - StationUI packet = new StationUI(__instance.factory.planet.id, __instance.factory.transport.stationPool[__instance.stationId].id, __instance.factory.transport.stationPool[__instance.stationId].gid, StationUI.EUISettings.MaxTripVessel, value); - Multiplayer.Session.Network.SendPacket(packet); - if (Multiplayer.Session.LocalPlayer.IsHost) - { - return true; - } - return false; + return true; } - return true; + Multiplayer.Session.StationsUI.SliderBarPacket.SettingIndex = StationUI.EUISettings.MaxTripVessel; + Multiplayer.Session.StationsUI.SliderBarPacket.SettingValue = value; + return Multiplayer.Session.LocalPlayer.IsHost; } [HarmonyPrefix] [HarmonyPatch(nameof(UIStationWindow.OnMinDeliverDroneValueChange))] public static bool OnMinDeliverDroneValueChange_Prefix(UIStationWindow __instance, float value) { - if (Multiplayer.IsActive && !Multiplayer.Session.Ships.PatchLockILS && (Multiplayer.Session.StationsUI.UIIsSyncedStage == 2 || Multiplayer.Session.LocalPlayer.IsHost)) + if (__instance.event_lock || !Multiplayer.IsActive || Multiplayer.Session.Ships.PatchLockILS) { - StationUI packet = new StationUI(__instance.factory.planet.id, __instance.factory.transport.stationPool[__instance.stationId].id, __instance.factory.transport.stationPool[__instance.stationId].gid, StationUI.EUISettings.MinDeliverDrone, value); - Multiplayer.Session.Network.SendPacket(packet); - if (Multiplayer.Session.LocalPlayer.IsHost) - { - return true; - } - return false; + return true; } - return true; + Multiplayer.Session.StationsUI.SliderBarPacket.SettingIndex = StationUI.EUISettings.MinDeliverDrone; + Multiplayer.Session.StationsUI.SliderBarPacket.SettingValue = value; + return Multiplayer.Session.LocalPlayer.IsHost; } [HarmonyPrefix] [HarmonyPatch(nameof(UIStationWindow.OnMinDeliverVesselValueChange))] public static bool OnMinDeliverVesselValueChange_Prefix(UIStationWindow __instance, float value) { - if (Multiplayer.IsActive && !Multiplayer.Session.Ships.PatchLockILS && (Multiplayer.Session.StationsUI.UIIsSyncedStage == 2 || Multiplayer.Session.LocalPlayer.IsHost)) + if (__instance.event_lock || !Multiplayer.IsActive || Multiplayer.Session.Ships.PatchLockILS) { - StationUI packet = new StationUI(__instance.factory.planet.id, __instance.factory.transport.stationPool[__instance.stationId].id, __instance.factory.transport.stationPool[__instance.stationId].gid, StationUI.EUISettings.MinDeliverVessel, value); - Multiplayer.Session.Network.SendPacket(packet); - if (Multiplayer.Session.LocalPlayer.IsHost) - { - return true; - } - return false; + return true; } - return true; + Multiplayer.Session.StationsUI.SliderBarPacket.SettingIndex = StationUI.EUISettings.MinDeliverVessel; + Multiplayer.Session.StationsUI.SliderBarPacket.SettingValue = value; + return Multiplayer.Session.LocalPlayer.IsHost; } [HarmonyPrefix] [HarmonyPatch(nameof(UIStationWindow.OnWarperDistanceValueChange))] public static bool OnWarperDistanceValueChange_Prefix(UIStationWindow __instance, float value) { - if (Multiplayer.IsActive && !Multiplayer.Session.Ships.PatchLockILS && (Multiplayer.Session.StationsUI.UIIsSyncedStage == 2 || Multiplayer.Session.LocalPlayer.IsHost)) + if (__instance.event_lock || !Multiplayer.IsActive || Multiplayer.Session.Ships.PatchLockILS) { - StationUI packet = new StationUI(__instance.factory.planet.id, __instance.factory.transport.stationPool[__instance.stationId].id, __instance.factory.transport.stationPool[__instance.stationId].gid, StationUI.EUISettings.WarpDistance, value); - Multiplayer.Session.Network.SendPacket(packet); - if (Multiplayer.Session.LocalPlayer.IsHost) - { - return true; - } - return false; + return true; } - return true; + Multiplayer.Session.StationsUI.SliderBarPacket.SettingIndex = StationUI.EUISettings.WarpDistance; + Multiplayer.Session.StationsUI.SliderBarPacket.SettingValue = value; + return Multiplayer.Session.LocalPlayer.IsHost; } [HarmonyPrefix] [HarmonyPatch(nameof(UIStationWindow.OnWarperNecessaryClick))] public static bool OnWarperNecessaryClick_Prefix(UIStationWindow __instance) { - if (Multiplayer.IsActive && !Multiplayer.Session.Ships.PatchLockILS && (Multiplayer.Session.StationsUI.UIIsSyncedStage == 2 || Multiplayer.Session.LocalPlayer.IsHost)) + if (__instance.event_lock || !Multiplayer.IsActive || Multiplayer.Session.Ships.PatchLockILS) { - StationUI packet = new StationUI(__instance.factory.planet.id, __instance.factory.transport.stationPool[__instance.stationId].id, __instance.factory.transport.stationPool[__instance.stationId].gid, StationUI.EUISettings.WarperNeeded, 0f); - Multiplayer.Session.Network.SendPacket(packet); - if (Multiplayer.Session.LocalPlayer.IsHost) - { - return true; - } - return false; + return true; } - return true; + StationUI packet = new StationUI(__instance.factory.planet.id, __instance.factory.transport.stationPool[__instance.stationId].id, __instance.factory.transport.stationPool[__instance.stationId].gid, StationUI.EUISettings.WarperNeeded, 0f); + Multiplayer.Session.Network.SendPacket(packet); + return Multiplayer.Session.LocalPlayer.IsHost; } [HarmonyPrefix] [HarmonyPatch(nameof(UIStationWindow.OnIncludeOrbitCollectorClick))] public static bool OnIncludeOrbitCollectorClick_Prefix(UIStationWindow __instance) { - if (Multiplayer.IsActive && !Multiplayer.Session.Ships.PatchLockILS && (Multiplayer.Session.StationsUI.UIIsSyncedStage == 2 || Multiplayer.Session.LocalPlayer.IsHost)) + if (__instance.event_lock || !Multiplayer.IsActive || Multiplayer.Session.Ships.PatchLockILS) { - StationUI packet = new StationUI(__instance.factory.planet.id, __instance.factory.transport.stationPool[__instance.stationId].id, __instance.factory.transport.stationPool[__instance.stationId].gid, StationUI.EUISettings.IncludeCollectors, 0f); - Multiplayer.Session.Network.SendPacket(packet); - if (Multiplayer.Session.LocalPlayer.IsHost) - { - return true; - } - return false; + return true; } - return true; + StationUI packet = new StationUI(__instance.factory.planet.id, __instance.factory.transport.stationPool[__instance.stationId].id, __instance.factory.transport.stationPool[__instance.stationId].gid, StationUI.EUISettings.IncludeCollectors, 0f); + Multiplayer.Session.Network.SendPacket(packet); + return Multiplayer.Session.LocalPlayer.IsHost; } [HarmonyPrefix] @@ -289,12 +257,20 @@ public static bool OnWarperIconClick_Prefix(UIStationWindow __instance) [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Original Function Name")] public static void _OnOpen_Postfix(UIStationWindow __instance) { - if (!Multiplayer.IsActive || Multiplayer.Session.LocalPlayer.IsHost || Multiplayer.Session.StationsUI.UIIsSyncedStage > 0) + if (!Multiplayer.IsActive || __instance.transport == null) + { + return; + } + + StationComponent stationComponent = __instance.transport.stationPool[__instance.stationId]; + Multiplayer.Session.StationsUI.SliderBarPacket = new StationUI(__instance.factory.planet.id, stationComponent.id, stationComponent.gid, StationUI.EUISettings.None, 0); + Multiplayer.Session.StationsUI.StorageMaxChangeId = -1; + if (Multiplayer.Session.LocalPlayer.IsHost) { return; } - // Hide UI elements until sync data arrive + // Stage 0 : Hide UI elements until sync data arrive __instance.titleText.text = "Loading..."; for (int i = 0; i < __instance.storageUIs.Length; i++) { @@ -303,25 +279,42 @@ public static void _OnOpen_Postfix(UIStationWindow __instance) } __instance.panelDown.SetActive(false); - StationComponent stationComponent = __instance.transport?.stationPool[__instance.stationId]; - if (stationComponent != null && __instance.factory != null) - { - // for some reason advance miner has planetId set to 0, so we use UI's factory planetId - Multiplayer.Session.Network.SendPacket(new StationUIInitialSyncRequest(__instance.factory.planetId, stationComponent.id, stationComponent.gid)); - Multiplayer.Session.StationsUI.UIIsSyncedStage++; - } + // for some reason advance miner has planetId set to 0, so we use UI's factory planetId + Multiplayer.Session.Network.SendPacket(new StationUIInitialSyncRequest(__instance.factory.planetId, stationComponent.id, stationComponent.gid)); } [HarmonyPrefix] [HarmonyPatch(nameof(UIStationWindow._OnUpdate))] [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Original Function Name")] - public static bool _OnUpdate_Prefix() + public static bool _OnUpdate_Prefix(UIStationWindow __instance) { - if (!Multiplayer.IsActive || Multiplayer.Session.LocalPlayer.IsHost || Multiplayer.Session.StationsUI.UIIsSyncedStage == 2) + if (!Multiplayer.IsActive) { return true; } - return false; + + // When releasing left mouse button + if (Input.GetMouseButtonUp(0)) + { + if (Multiplayer.Session.StationsUI.SliderBarPacket.SettingIndex != StationUI.EUISettings.None) + { + // Send SliderBarPacket when left mouse button is released + Multiplayer.Session.Network.SendPacket(Multiplayer.Session.StationsUI.SliderBarPacket); + Multiplayer.Session.StationsUI.SliderBarPacket.SettingIndex = StationUI.EUISettings.None; + } + if (Multiplayer.Session.StationsUI.StorageMaxChangeId >= 0) + { + // Do the job in UIStationStorage.OnMaxSliderValueChange() + int index = Multiplayer.Session.StationsUI.StorageMaxChangeId; + float val = __instance.storageUIs[index].maxSlider.value; + StationStore stationStore = __instance.transport.stationPool[__instance.stationId].storage[index]; + __instance.transport.SetStationStorage(__instance.stationId, index, stationStore.itemId, (int)(val * 100f + 0.5f), stationStore.localLogic, stationStore.remoteLogic, GameMain.mainPlayer); + + // In client side, preserve displaying slider value until host response + Multiplayer.Session.StationsUI.StorageMaxChangeId = Multiplayer.Session.LocalPlayer.IsHost ? -1 : -2; + } + } + return true; } [HarmonyPostfix] @@ -329,14 +322,10 @@ public static bool _OnUpdate_Prefix() [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Original Function Name")] public static void _OnClose_Postfix(UIStationWindow __instance) { - if (!Multiplayer.IsActive || Multiplayer.Session.LocalPlayer.IsHost) + if (!Multiplayer.IsActive) { return; } - if (__instance.stationId != 0) - { - Multiplayer.Session.StationsUI.UIIsSyncedStage = 0; - } } } } diff --git a/NebulaWorld/Logistics/StationUIManager.cs b/NebulaWorld/Logistics/StationUIManager.cs index 3f8a64a64..21728b992 100644 --- a/NebulaWorld/Logistics/StationUIManager.cs +++ b/NebulaWorld/Logistics/StationUIManager.cs @@ -13,8 +13,9 @@ public class StationUIManager : IDisposable public int UpdateCooldown; // cooldown is reserved for future use public BaseEventData LastMouseEvent; public bool LastMouseEventWasDown; - public int UIIsSyncedStage; // 0 == not synced, 1 == request sent, 2 == synced | this is only used client side public bool UIRequestedShipDronWarpChange; // when receiving a ship, drone or warp change only take/add items from the one issuing the request + public StationUI SliderBarPacket; // store the change of slider bar temporary, only send it when mouse button is released. + public int StorageMaxChangeId; // index of the storage that its slider value changed by the user. -1: None, -2: Syncing public StationUIManager() { @@ -50,8 +51,7 @@ public void UpdateUI(StationUI packet) { if (stationWindow.factory?.planetId == packet.PlanetId && stationWindow.stationId == packet.StationId) { - Log.Info($"Refresh value {packet.StationId}"); - stationWindow.OnStationIdChange(); + stationWindow.OnStationIdChange(); } } } @@ -66,7 +66,7 @@ private void UpdateSettingsUIBackground(StationUI packet, PlanetData planet, Sta // update drones, ships, warpers and energy consumption for everyone if ((packet.SettingIndex >= StationUI.EUISettings.SetDroneCount && packet.SettingIndex <= StationUI.EUISettings.SetWarperCount) || packet.SettingIndex == StationUI.EUISettings.MaxChargePower) { - if (packet.SettingIndex == (int)StationUI.EUISettings.MaxChargePower && planet.factory?.powerSystem != null) + if (packet.SettingIndex == StationUI.EUISettings.MaxChargePower && planet.factory?.powerSystem != null) { PowerConsumerComponent[] consumerPool = planet.factory.powerSystem.consumerPool; if (consumerPool.Length > stationComponent.pcId) @@ -246,8 +246,8 @@ private void UpdateStorageUI(StationUI packet) using (Multiplayer.Session.Ships.PatchLockILS.On()) { - Log.Info($"Refresh storage {stationComponent.id}"); planet.factory.transport.SetStationStorage(stationComponent.id, packet.StorageIdx, packet.ItemId, packet.ItemCountMax, packet.LocalLogic, packet.RemoteLogic, (packet.ShouldMimic == true) ? GameMain.mainPlayer : null); + StorageMaxChangeId = -1; } } } From 76482378df2ddd48beb8a915a07d038b93fe520e Mon Sep 17 00:00:00 2001 From: starfish Date: Fri, 28 Jan 2022 12:18:01 +0800 Subject: [PATCH 3/8] Change itemIcon clicking behaviors - Change to use original method, and on postfix update the changed itemCount. - Client will revert itemCount changes and wait for host approve. - Drone & Ship count update now try to set the total count of working + idle, if total count exceed limit or not enough idle ships, hot will correct the setting value. - AddOrRemoveItemFromStorage now include ``inc`` --- NebulaModel/Packets/Logistics/StationUI.cs | 9 +- .../Logistics/StationUIProcessor.cs | 4 +- .../Patches/Dynamic/UIStationStorage_Patch.cs | 101 ++++---- .../Patches/Dynamic/UIStationWindow_Patch.cs | 173 +++++-------- NebulaWorld/Logistics/StationUIManager.cs | 238 +++++++++--------- 5 files changed, 233 insertions(+), 292 deletions(-) diff --git a/NebulaModel/Packets/Logistics/StationUI.cs b/NebulaModel/Packets/Logistics/StationUI.cs index 2980f8749..2ea8954d0 100644 --- a/NebulaModel/Packets/Logistics/StationUI.cs +++ b/NebulaModel/Packets/Logistics/StationUI.cs @@ -16,8 +16,7 @@ public enum EUISettings SetDroneCount, SetShipCount, SetWarperCount, - AddOrRemoveItemFromStorageRequest, - AddOrRemoveItemFromStorageResponse + AddOrRemoveItemFromStorage } public int PlanetId { get; set; } @@ -26,6 +25,7 @@ public enum EUISettings public bool IsStorageUI { get; set; } public StationUI.EUISettings SettingIndex { get; set; } public float SettingValue { get; set; } + public float SettingValue2 { get; set; } public int StorageIdx { get; set; } public int ItemId { get; set; } public int ItemCountMax { get; set; } @@ -61,7 +61,7 @@ public StationUI(int planetId, int stationId, int stationGId, StationUI.EUISetti SettingValue = value; WarperShouldTakeFromStorage = warperShouldTakeFromStorage; } - public StationUI(int planetId, int stationId, int stationGId, int storageIdx, StationUI.EUISettings settingIndex, int itemId, int settingValue) + public StationUI(int planetId, int stationId, int stationGId, int storageIdx, StationUI.EUISettings settingIndex, int itemId, int count, int inc) { WarperShouldTakeFromStorage = false; @@ -71,7 +71,8 @@ public StationUI(int planetId, int stationId, int stationGId, int storageIdx, St StorageIdx = storageIdx; SettingIndex = settingIndex; ItemId = itemId; - SettingValue = settingValue; + SettingValue = count; + SettingValue2 = inc; } } } diff --git a/NebulaNetwork/PacketProcessors/Logistics/StationUIProcessor.cs b/NebulaNetwork/PacketProcessors/Logistics/StationUIProcessor.cs index 0ffc8e360..4c66def99 100644 --- a/NebulaNetwork/PacketProcessors/Logistics/StationUIProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Logistics/StationUIProcessor.cs @@ -22,7 +22,7 @@ public override void ProcessPacket(StationUI packet, NebulaConnection conn) { // always update values for host, but he does not need to rely on the mimic flag (infact its bad for him) packet.ShouldMimic = false; - Multiplayer.Session.StationsUI.UpdateUI(packet); + Multiplayer.Session.StationsUI.UpdateUI(ref packet); // broadcast to every clients that may have the station loaded. playerManager.SendPacketToStarExcept(packet, packet.PlanetId, conn); @@ -35,7 +35,7 @@ public override void ProcessPacket(StationUI packet, NebulaConnection conn) if (IsClient) { - Multiplayer.Session.StationsUI.UpdateUI(packet); + Multiplayer.Session.StationsUI.UpdateUI(ref packet); } } } diff --git a/NebulaPatcher/Patches/Dynamic/UIStationStorage_Patch.cs b/NebulaPatcher/Patches/Dynamic/UIStationStorage_Patch.cs index 1a6cb5326..2ccee8759 100644 --- a/NebulaPatcher/Patches/Dynamic/UIStationStorage_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/UIStationStorage_Patch.cs @@ -1,9 +1,8 @@ using HarmonyLib; using NebulaModel.Packets.Logistics; using NebulaWorld; -using UnityEngine.EventSystems; - +#pragma warning disable Harmony003 namespace NebulaPatcher.Patches.Dynamic { [HarmonyPatch(typeof(UIStationStorage))] @@ -56,40 +55,32 @@ public static void _OnUpdate_Postfix(UIStationStorage __instance, float __state) */ [HarmonyPrefix] [HarmonyPatch(nameof(UIStationStorage.OnItemIconMouseDown))] - public static bool OnItemIconMouseDown_Postfix(UIStationStorage __instance, BaseEventData evt) + [HarmonyPriority(Priority.First)] + public static void OnItemIconMouseDown_Prefix(UIStationStorage __instance, ref (int,int) __state) { - if (Multiplayer.IsActive && !Multiplayer.Session.Ships.PatchLockILS) + __state = (__instance.station.storage[__instance.index].count, __instance.station.storage[__instance.index].inc); + } + + [HarmonyPostfix] + [HarmonyPatch(nameof(UIStationStorage.OnItemIconMouseDown))] + [HarmonyPriority(Priority.Last)] + public static void OnItemIconMouseDown_Postfix(UIStationStorage __instance, (int, int) __state) + { + if (!Multiplayer.IsActive || Multiplayer.Session.Ships.PatchLockILS) { - Multiplayer.Session.StationsUI.LastMouseEvent = evt; - Multiplayer.Session.StationsUI.LastMouseEventWasDown = true; - StationUI packet; - if (Multiplayer.Session.LocalPlayer.IsHost) - { - PointerEventData pointEventData = evt as PointerEventData; - if (GameMain.mainPlayer.inhandItemId == __instance.station.storage[__instance.index].itemId && pointEventData.button == PointerEventData.InputButton.Left) - { - int diff = __instance.station.storage[__instance.index].max - __instance.station.storage[__instance.index].count; - int amount = (diff >= GameMain.mainPlayer.inhandItemCount) ? GameMain.mainPlayer.inhandItemCount : diff; - if (amount < 0) - { - amount = 0; - } - packet = new StationUI(__instance.stationWindow.factory.planet.id, __instance.station.id, __instance.station.gid, __instance.index, StationUI.EUISettings.AddOrRemoveItemFromStorageResponse, __instance.station.storage[__instance.index].itemId, __instance.station.storage[__instance.index].count + amount); - Multiplayer.Session.Network.SendPacket(packet); - } - } - else - { - packet = new StationUI(__instance.stationWindow.factory.planet.id, __instance.station.id, __instance.station.gid, __instance.index, StationUI.EUISettings.AddOrRemoveItemFromStorageRequest, __instance.station.storage[__instance.index].itemId, __instance.station.storage[__instance.index].count); - Multiplayer.Session.Network.SendPacket(packet); - } - if (Multiplayer.Session.LocalPlayer.IsHost) + return; + } + StationStore stationStore = __instance.station.storage[__instance.index]; + if (__state.Item1 != stationStore.count || __state.Item2 != stationStore.inc) + { + StationUI packet = new StationUI(__instance.stationWindow.factory.planet.id, __instance.station.id, __instance.station.gid, __instance.index, StationUI.EUISettings.AddOrRemoveItemFromStorage, stationStore.itemId, stationStore.count, stationStore.inc); + Multiplayer.Session.Network.SendPacket(packet); + if (Multiplayer.Session.LocalPlayer.IsClient) { - return true; + __instance.station.storage[__instance.index].count = __state.Item1; + __instance.station.storage[__instance.index].inc = __state.Item2; } - return false; } - return true; } /* @@ -98,35 +89,35 @@ public static bool OnItemIconMouseDown_Postfix(UIStationStorage __instance, Base */ [HarmonyPrefix] [HarmonyPatch(nameof(UIStationStorage.OnItemIconMouseUp))] - public static bool OnItemIconMouseUp_Postfix(UIStationStorage __instance, BaseEventData evt) + [HarmonyPriority(Priority.First)] + public static void OnItemIconMouseUp_Prefix(UIStationStorage __instance, ref (int, int) __state) { - if (Multiplayer.IsActive && !Multiplayer.Session.Ships.PatchLockILS) + __state = (__instance.station.storage[__instance.index].count, __instance.station.storage[__instance.index].inc); + } + + [HarmonyPostfix] + [HarmonyPatch(nameof(UIStationStorage.OnItemIconMouseUp))] + [HarmonyPriority(Priority.Last)] + public static void OnItemIconMouseUp_Postfix(UIStationStorage __instance, (int, int) __state) + { + if (!Multiplayer.IsActive || Multiplayer.Session.Ships.PatchLockILS) { - Multiplayer.Session.StationsUI.LastMouseEvent = evt; - Multiplayer.Session.StationsUI.LastMouseEventWasDown = false; - StationUI packet; - if (Multiplayer.Session.LocalPlayer.IsHost) - { - if (__instance.insplit) - { - int splitVal = UIRoot.instance.uiGame.gridSplit.value; - int diff = (splitVal >= __instance.station.storage[__instance.index].count) ? __instance.station.storage[__instance.index].count : splitVal; - packet = new StationUI(__instance.stationWindow.factory.planet.id, __instance.station.id, __instance.station.gid, __instance.index, StationUI.EUISettings.AddOrRemoveItemFromStorageResponse, __instance.station.storage[__instance.index].itemId, __instance.station.storage[__instance.index].count - diff); - Multiplayer.Session.Network.SendPacket(packet); - } - } - else - { - packet = new StationUI(__instance.stationWindow.factory.planet.id, __instance.station.id, __instance.station.gid, __instance.index, StationUI.EUISettings.AddOrRemoveItemFromStorageRequest, __instance.station.storage[__instance.index].itemId, __instance.station.storage[__instance.index].count); - Multiplayer.Session.Network.SendPacket(packet); - } - if (Multiplayer.Session.LocalPlayer.IsHost) + return; + } + StationStore stationStore = __instance.station.storage[__instance.index]; + + if (__state.Item1 != stationStore.count || __state.Item2 != stationStore.inc) + + { + StationUI packet = new StationUI(__instance.stationWindow.factory.planet.id, __instance.station.id, __instance.station.gid, __instance.index, StationUI.EUISettings.AddOrRemoveItemFromStorage, stationStore.itemId, stationStore.count, stationStore.inc); + Multiplayer.Session.Network.SendPacket(packet); + if (Multiplayer.Session.LocalPlayer.IsClient) { - return true; + __instance.station.storage[__instance.index].count = __state.Item1; + __instance.station.storage[__instance.index].inc = __state.Item2; } - return false; } - return true; } } } +#pragma warning restore Harmony003 diff --git a/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs b/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs index 913f0c7d9..38c66652c 100644 --- a/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs @@ -115,141 +115,100 @@ public static bool OnIncludeOrbitCollectorClick_Prefix(UIStationWindow __instanc [HarmonyPrefix] [HarmonyPatch(nameof(UIStationWindow.OnDroneIconClick))] - public static bool OnDroneIconClick_Prefix(UIStationWindow __instance) + [HarmonyPriority(Priority.First)] + public static void OnDroneIconClick_Prefix(UIStationWindow __instance, ref int __state) { - if (Multiplayer.IsActive && !Multiplayer.Session.Ships.PatchLockILS) + StationComponent stationComponent = __instance.transport.stationPool[__instance.stationId]; + __state = stationComponent.idleDroneCount; + } + + [HarmonyPostfix] + [HarmonyPatch(nameof(UIStationWindow.OnDroneIconClick))] + [HarmonyPriority(Priority.Last)] + public static void OnDroneIconClick_Posfix(UIStationWindow __instance, int __state) + { + if (__instance.event_lock || !Multiplayer.IsActive || Multiplayer.Session.Ships.PatchLockILS) { - Player player = GameMain.mainPlayer; - if (player.inhandItemCount > 0 && player.inhandItemId != 5001) - { - ItemProto itemProto = LDB.items.Select(5001); - UIRealtimeTip.Popup("只能放入".Translate() + itemProto.name, true, 0); - return false; - } - StationComponent stationComponent = __instance.transport.stationPool[__instance.stationId]; - ItemProto stationItem = LDB.items.Select(__instance.factory.entityPool[stationComponent.entityId].protoId); - - int toAdd; - if (player.inhandItemCount > 0) - { - int droneAmount = stationComponent.idleDroneCount + stationComponent.workDroneCount; - int spaceLeft = stationItem.prefabDesc.stationMaxDroneCount - droneAmount; - if (spaceLeft < 0) - { - spaceLeft = 0; - } - toAdd = (__instance.player.inhandItemCount >= spaceLeft) ? spaceLeft : __instance.player.inhandItemCount; - } - else - { - toAdd = stationComponent.idleDroneCount * -1; - } - if (!Multiplayer.Session.LocalPlayer.IsHost) - { - Multiplayer.Session.StationsUI.UIRequestedShipDronWarpChange = true; - } + return; + } - StationUI packet = new StationUI(__instance.factory.planet.id, stationComponent.id, stationComponent.gid, StationUI.EUISettings.SetDroneCount, stationComponent.idleDroneCount + toAdd); + StationComponent stationComponent = __instance.transport.stationPool[__instance.stationId]; + if (__state != stationComponent.idleDroneCount) + { + int droneCount = stationComponent.idleDroneCount + stationComponent.workDroneCount; + StationUI packet = new StationUI(__instance.factory.planet.id, stationComponent.id, stationComponent.gid, StationUI.EUISettings.SetDroneCount, droneCount); Multiplayer.Session.Network.SendPacket(packet); - if (Multiplayer.Session.LocalPlayer.IsHost) + if (Multiplayer.Session.LocalPlayer.IsClient) { - return true; + // Revert drone count until host verify + stationComponent.idleDroneCount = __state; } - return false; } - return true; } [HarmonyPrefix] [HarmonyPatch(nameof(UIStationWindow.OnShipIconClick))] - public static bool OnShipIconClick_Prefix(UIStationWindow __instance) + [HarmonyPriority(Priority.First)] + public static void OnShipIconClick_Prefix(UIStationWindow __instance, ref int __state) { - if (Multiplayer.IsActive && !Multiplayer.Session.Ships.PatchLockILS) + StationComponent stationComponent = __instance.transport.stationPool[__instance.stationId]; + __state = stationComponent.idleShipCount; + } + + [HarmonyPostfix] + [HarmonyPatch(nameof(UIStationWindow.OnShipIconClick))] + [HarmonyPriority(Priority.Last)] + public static void OnShipIconClick_Posfix(UIStationWindow __instance, int __state) + { + if (__instance.event_lock || !Multiplayer.IsActive || Multiplayer.Session.Ships.PatchLockILS) { - Player player = GameMain.mainPlayer; - if (player.inhandItemCount > 0 && player.inhandItemId != 5002) - { - ItemProto itemProto = LDB.items.Select(5002); - UIRealtimeTip.Popup("只能放入".Translate() + itemProto.name, true, 0); - return false; - } - StationComponent stationComponent = __instance.transport.stationPool[__instance.stationId]; - ItemProto stationItem = LDB.items.Select(__instance.factory.entityPool[stationComponent.entityId].protoId); - - int toAdd; - if (player.inhandItemCount > 0) - { - int shipAmount = stationComponent.idleShipCount + stationComponent.workShipCount; - int spaceLeft = stationItem.prefabDesc.stationMaxShipCount - shipAmount; - if (spaceLeft < 0) - { - spaceLeft = 0; - } - toAdd = (__instance.player.inhandItemCount >= spaceLeft) ? spaceLeft : __instance.player.inhandItemCount; - } - else - { - toAdd = stationComponent.idleShipCount * -1; - } - if (!Multiplayer.Session.LocalPlayer.IsHost) - { - Multiplayer.Session.StationsUI.UIRequestedShipDronWarpChange = true; - } - StationUI packet = new StationUI(__instance.factory.planet.id, stationComponent.id, stationComponent.gid, StationUI.EUISettings.SetShipCount, stationComponent.idleShipCount + toAdd); - Multiplayer.Session.Network.SendPacket(packet); + return; + } - if (Multiplayer.Session.LocalPlayer.IsHost) + StationComponent stationComponent = __instance.transport.stationPool[__instance.stationId]; + if (__state != stationComponent.idleShipCount) + { + int ShipCount = stationComponent.idleShipCount + stationComponent.workShipCount; + StationUI packet = new StationUI(__instance.factory.planet.id, stationComponent.id, stationComponent.gid, StationUI.EUISettings.SetShipCount, ShipCount); + Multiplayer.Session.Network.SendPacket(packet); + if (Multiplayer.Session.LocalPlayer.IsClient) { - return true; + // Revert ship count until host verify + stationComponent.idleShipCount = __state; } - return false; } - return true; } [HarmonyPrefix] [HarmonyPatch(nameof(UIStationWindow.OnWarperIconClick))] - public static bool OnWarperIconClick_Prefix(UIStationWindow __instance) + [HarmonyPriority(Priority.First)] + public static void OnWarperIconClick_Prefix(UIStationWindow __instance, ref int __state) { - if (Multiplayer.IsActive && !Multiplayer.Session.Ships.PatchLockILS) + StationComponent stationComponent = __instance.transport.stationPool[__instance.stationId]; + __state = stationComponent.warperCount; + } + + [HarmonyPostfix] + [HarmonyPatch(nameof(UIStationWindow.OnWarperIconClick))] + [HarmonyPriority(Priority.Last)] + public static void OnWarperIconClick_Posfix(UIStationWindow __instance, int __state) + { + if (__instance.event_lock || !Multiplayer.IsActive || Multiplayer.Session.Ships.PatchLockILS) { - Player player = GameMain.mainPlayer; - if (player.inhandItemCount > 0 && player.inhandItemId != 1210) - { - ItemProto itemProto = LDB.items.Select(1210); - UIRealtimeTip.Popup("只能放入".Translate() + itemProto.name, true, 0); - return false; - } - StationComponent stationComponent = __instance.transport.stationPool[__instance.stationId]; - - int toAdd; - if (player.inhandItemCount > 0) - { - int spaceLeft = stationComponent.warperMaxCount - stationComponent.warperCount; - if (spaceLeft < 0) - { - spaceLeft = 0; - } - toAdd = (__instance.player.inhandItemCount >= spaceLeft) ? spaceLeft : __instance.player.inhandItemCount; - } - else - { - toAdd = stationComponent.warperCount * -1; - } - if (!Multiplayer.Session.LocalPlayer.IsHost) - { - Multiplayer.Session.StationsUI.UIRequestedShipDronWarpChange = true; - } + return; + } - StationUI packet = new StationUI(__instance.factory.planet.id, stationComponent.id, stationComponent.gid, StationUI.EUISettings.SetWarperCount, stationComponent.warperCount + toAdd); + StationComponent stationComponent = __instance.transport.stationPool[__instance.stationId]; + if (__state != stationComponent.warperCount) + { + StationUI packet = new StationUI(__instance.factory.planet.id, stationComponent.id, stationComponent.gid, StationUI.EUISettings.SetWarperCount, stationComponent.warperCount); Multiplayer.Session.Network.SendPacket(packet); - if (Multiplayer.Session.LocalPlayer.IsHost) + if (Multiplayer.Session.LocalPlayer.IsClient) { - return true; + // Revert warper count until host verify + stationComponent.warperCount = __state; } - return false; } - return true; } [HarmonyPostfix] diff --git a/NebulaWorld/Logistics/StationUIManager.cs b/NebulaWorld/Logistics/StationUIManager.cs index 21728b992..bb4921cdd 100644 --- a/NebulaWorld/Logistics/StationUIManager.cs +++ b/NebulaWorld/Logistics/StationUIManager.cs @@ -1,18 +1,13 @@ using NebulaModel.Logger; -using NebulaModel.Networking; using NebulaModel.Packets.Logistics; using System; -using System.Collections.Generic; using UnityEngine; -using UnityEngine.EventSystems; namespace NebulaWorld.Logistics { public class StationUIManager : IDisposable { public int UpdateCooldown; // cooldown is reserved for future use - public BaseEventData LastMouseEvent; - public bool LastMouseEventWasDown; public bool UIRequestedShipDronWarpChange; // when receiving a ship, drone or warp change only take/add items from the one issuing the request public StationUI SliderBarPacket; // store the change of slider bar temporary, only send it when mouse button is released. public int StorageMaxChangeId; // index of the storage that its slider value changed by the user. -1: None, -2: Syncing @@ -34,15 +29,20 @@ public void DecreaseCooldown() } } - public void UpdateUI(StationUI packet) + public void UpdateUI(ref StationUI packet) { + StationComponent stationComponent = GetStation(packet); + if (stationComponent == null) + { + return; + } if (packet.IsStorageUI) { - UpdateStorageUI(packet); + UpdateStorageUI(stationComponent, packet); } else { - UpdateSettingsUI(packet); + UpdateSettingsUI(stationComponent, ref packet); } // If station window is opened and veiwing the updating station, refresh the window. @@ -59,33 +59,54 @@ public void UpdateUI(StationUI packet) /** * Updates to a given station that should happen in the background. */ - private void UpdateSettingsUIBackground(StationUI packet, PlanetData planet, StationComponent stationComponent) + private void UpdateSettingsUI(StationComponent stationComponent, ref StationUI packet) { - StationComponent[] gStationPool = GameMain.data.galacticTransport.stationPool; - - // update drones, ships, warpers and energy consumption for everyone - if ((packet.SettingIndex >= StationUI.EUISettings.SetDroneCount && packet.SettingIndex <= StationUI.EUISettings.SetWarperCount) || packet.SettingIndex == StationUI.EUISettings.MaxChargePower) + Debug.Log(packet.SettingIndex); + // SetDroneCount, SetShipCount may change packet.SettingValue + switch (packet.SettingIndex) { - if (packet.SettingIndex == StationUI.EUISettings.MaxChargePower && planet.factory?.powerSystem != null) + case StationUI.EUISettings.MaxChargePower: { - PowerConsumerComponent[] consumerPool = planet.factory.powerSystem.consumerPool; - if (consumerPool.Length > stationComponent.pcId) + PlanetData planet = GameMain.galaxy.PlanetById(packet.PlanetId); + if (planet.factory?.powerSystem != null) { - consumerPool[stationComponent.pcId].workEnergyPerTick = (long)(50000.0 * packet.SettingValue + 0.5); + PowerConsumerComponent[] consumerPool = planet.factory.powerSystem.consumerPool; + if (consumerPool.Length > stationComponent.pcId) + { + consumerPool[stationComponent.pcId].workEnergyPerTick = (long)(50000.0 * packet.SettingValue + 0.5); + } } + break; } - - if (packet.SettingIndex == StationUI.EUISettings.SetDroneCount) + case StationUI.EUISettings.SetDroneCount: { - stationComponent.idleDroneCount = (int)packet.SettingValue; + // Check if new setting is acceptable + int totalCount = Math.Min((int)packet.SettingValue, stationComponent.workDroneDatas.Length); + stationComponent.idleDroneCount = Math.Max(totalCount - stationComponent.workDroneCount, 0); + if (totalCount < (int)packet.SettingValue && packet.ShouldMimic) + { + // The result is less than original setting, refund extra drones to author + int refund = (int)packet.SettingValue - totalCount; + GameMain.mainPlayer.TryAddItemToPackage(5001, refund, 0, true); + } + packet.SettingValue = totalCount; + break; } - - if (packet.SettingIndex == StationUI.EUISettings.SetShipCount) + case StationUI.EUISettings.SetShipCount: { - stationComponent.idleShipCount = (int)packet.SettingValue; + // Check if new setting is acceptable + int totalCount = Math.Min((int)packet.SettingValue, stationComponent.workShipDatas.Length); + stationComponent.idleShipCount = Math.Max(totalCount - stationComponent.workShipCount, 0); + if (totalCount < (int)packet.SettingValue && packet.ShouldMimic) + { + // The result is less than original setting, refund extra ships to author + int refund = (int)packet.SettingValue - totalCount; + GameMain.mainPlayer.TryAddItemToPackage(5002, refund, 0, true); + } + packet.SettingValue = totalCount; + break; } - - if (packet.SettingIndex == StationUI.EUISettings.SetWarperCount) + case StationUI.EUISettings.SetWarperCount: { stationComponent.warperCount = (int)packet.SettingValue; if (stationComponent.storage != null && packet.WarperShouldTakeFromStorage) @@ -99,93 +120,83 @@ private void UpdateSettingsUIBackground(StationUI packet, PlanetData planet, Sta } } } + break; } - } - - if (packet.SettingIndex == StationUI.EUISettings.MaxTripDrones) - { - stationComponent.tripRangeDrones = Math.Cos(packet.SettingValue / 180.0 * 3.141592653589793); - } - - if (packet.SettingIndex == StationUI.EUISettings.MaxTripVessel) - { - double value = packet.SettingValue; - if (value > 40.5) + case StationUI.EUISettings.MaxTripDrones: { - value = 10000.0; + stationComponent.tripRangeDrones = Math.Cos(packet.SettingValue / 180.0 * 3.141592653589793); + break; } - else if (value > 20.5) + case StationUI.EUISettings.MaxTripVessel: { - value = value * 2f - 20f; - } - - stationComponent.tripRangeShips = 2400000.0 * value; - } - - if (packet.SettingIndex == StationUI.EUISettings.MinDeliverDrone) - { - int value = (int)(packet.SettingValue * 10f + 0.5f); - if (value < 1) - { - value = 1; - } - - stationComponent.deliveryDrones = value; - } - - if (packet.SettingIndex == StationUI.EUISettings.MinDeliverVessel) - { - int value = (int)(packet.SettingValue * 10f + 0.5f); - if (value < 1) - { - value = 1; + double value = packet.SettingValue; + if (value > 40.5) + { + value = 10000.0; + } + else if (value > 20.5) + { + value = value * 2f - 20f; + } + stationComponent.tripRangeShips = 2400000.0 * value; + break; } - - stationComponent.deliveryShips = value; - } - - if (packet.SettingIndex == StationUI.EUISettings.WarpDistance) - { - double value = packet.SettingValue; - if (value < 1.5) + case StationUI.EUISettings.MinDeliverDrone: { - value = 0.2; + int value = (int)(packet.SettingValue * 10f + 0.5f); + stationComponent.deliveryDrones = value < 1 ? 1 : value; + break; } - else if (value < 7.5) + case StationUI.EUISettings.MinDeliverVessel: { - value = value * 0.5 - 0.5; + int value = (int)(packet.SettingValue * 10f + 0.5f); + stationComponent.deliveryShips = value < 1 ? 1 : value; + break; } - else if (value < 16.5) + case StationUI.EUISettings.WarpDistance: { - value -= 4f; + double value = packet.SettingValue; + if (value < 1.5) + { + value = 0.2; + } + else if (value < 7.5) + { + value = value * 0.5 - 0.5; + } + else if (value < 16.5) + { + value -= 4f; + } + else if (value < 20.5) + { + value = value * 2f - 20f; + } + else + { + value = 60; + } + stationComponent.warpEnableDist = 40000.0 * value; + break; } - else if (value < 20.5) + case StationUI.EUISettings.WarperNeeded: { - value = value * 2f - 20f; + stationComponent.warperNecessary = !stationComponent.warperNecessary; + break; } - else + case StationUI.EUISettings.IncludeCollectors: { - value = 60; + stationComponent.includeOrbitCollector = !stationComponent.includeOrbitCollector; + break; } - - stationComponent.warpEnableDist = 40000.0 * value; - } - - if (packet.SettingIndex == StationUI.EUISettings.WarperNeeded) - { - stationComponent.warperNecessary = !stationComponent.warperNecessary; - } - - if (packet.SettingIndex == StationUI.EUISettings.IncludeCollectors) - { - stationComponent.includeOrbitCollector = !stationComponent.includeOrbitCollector; - } - - if (packet.SettingIndex == StationUI.EUISettings.AddOrRemoveItemFromStorageResponse) - { - if (stationComponent.storage != null) + case StationUI.EUISettings.AddOrRemoveItemFromStorage: { - stationComponent.storage[packet.StorageIdx].count = (int)packet.SettingValue; + if (stationComponent.storage != null) + { + stationComponent.storage[packet.StorageIdx].count = (int)packet.SettingValue; + stationComponent.storage[packet.StorageIdx].inc = (int)packet.SettingValue2; + } + break; } } } @@ -195,7 +206,7 @@ private void UpdateSettingsUIBackground(StationUI packet, PlanetData planet, Sta * * First determine if the local player has the station window opened and handle that accordingly. */ - private void UpdateSettingsUI(StationUI packet) + private StationComponent GetStation(StationUI packet) { StationComponent stationComponent = null; PlanetData planet = GameMain.galaxy?.PlanetById(packet.PlanetId); @@ -203,7 +214,7 @@ private void UpdateSettingsUI(StationUI packet) // If we can't find planet or the factory for said planet, we can just skip this if (planet?.factory?.transport == null) { - return; + return null; } StationComponent[] gStationPool = GameMain.data.galacticTransport.stationPool; @@ -214,38 +225,17 @@ private void UpdateSettingsUI(StationUI packet) if (stationComponent == null) { - Log.Warn($"UpdateStorageUI: Unable to find requested station on planet {packet.PlanetId} with id {packet.StationId} and gid of {packet.StationGId}"); - return; + Log.Warn($"StationUI: Unable to find requested station on planet {packet.PlanetId} with id {packet.StationId} and gid of {packet.StationGId}"); + return null; } - - // Do all updates in the background. - UpdateSettingsUIBackground(packet, planet, stationComponent); + return stationComponent; } - private void UpdateStorageUI(StationUI packet) + private void UpdateStorageUI(StationComponent stationComponent, StationUI packet) { - StationComponent stationComponent = null; - PlanetData planet = GameMain.galaxy?.PlanetById(packet.PlanetId); - - // If we can't find planet or the factory for said planet, we can just skip this - if (planet?.factory?.transport == null) - { - return; - } - - StationComponent[] gStationPool = GameMain.data.galacticTransport.stationPool; - StationComponent[] stationPool = planet?.factory?.transport?.stationPool; - - stationComponent = packet.StationGId > 0 ? gStationPool[packet.StationGId] : stationPool?[packet.StationId]; - - if (stationComponent == null) - { - Log.Error($"UpdateStorageUI: Unable to find requested station on planet {packet.PlanetId} with id {packet.StationId} and gid of {packet.StationGId}"); - return; - } - using (Multiplayer.Session.Ships.PatchLockILS.On()) { + PlanetData planet = GameMain.galaxy.PlanetById(packet.PlanetId); planet.factory.transport.SetStationStorage(stationComponent.id, packet.StorageIdx, packet.ItemId, packet.ItemCountMax, packet.LocalLogic, packet.RemoteLogic, (packet.ShouldMimic == true) ? GameMain.mainPlayer : null); StorageMaxChangeId = -1; } From 95ff93a1ae38b53886f5c1c76562287ba2cf2025 Mon Sep 17 00:00:00 2001 From: starfish Date: Fri, 28 Jan 2022 21:26:48 +0800 Subject: [PATCH 4/8] Add new station setting in 0.9.24 - Add plierCount, MaxMiningSpeed(Advance miner) --- NebulaModel/Packets/Logistics/StationUI.cs | 4 +- .../Packets/Logistics/StationUIInitialSync.cs | 3 ++ .../StationUIInitialSyncProcessor.cs | 1 + .../StationUIInitialSyncRequestProcessor.cs | 1 + .../Patches/Dynamic/UIStationWindow_Patch.cs | 39 +++++++++++++------ NebulaWorld/Logistics/StationUIManager.cs | 18 ++++++++- 6 files changed, 53 insertions(+), 13 deletions(-) diff --git a/NebulaModel/Packets/Logistics/StationUI.cs b/NebulaModel/Packets/Logistics/StationUI.cs index 2ea8954d0..9066d4398 100644 --- a/NebulaModel/Packets/Logistics/StationUI.cs +++ b/NebulaModel/Packets/Logistics/StationUI.cs @@ -16,7 +16,9 @@ public enum EUISettings SetDroneCount, SetShipCount, SetWarperCount, - AddOrRemoveItemFromStorage + AddOrRemoveItemFromStorage, + PilerCount, + MaxMiningSpeed } public int PlanetId { get; set; } diff --git a/NebulaModel/Packets/Logistics/StationUIInitialSync.cs b/NebulaModel/Packets/Logistics/StationUIInitialSync.cs index 459d18be3..714a9fd9f 100644 --- a/NebulaModel/Packets/Logistics/StationUIInitialSync.cs +++ b/NebulaModel/Packets/Logistics/StationUIInitialSync.cs @@ -14,6 +14,7 @@ public class StationUIInitialSync public bool IncludeOrbitCollector { get; set; } public long Energy { get; set; } public long EnergyPerTick { get; set; } + public int PilerCount { get; set; } public int[] ItemId { get; set; } public int[] ItemCountMax { get; set; } public int[] ItemCount { get; set; } @@ -35,6 +36,7 @@ public StationUIInitialSync( bool includeOrbitCollector, long energy, long energyPerTick, + int pilerCount, int[] itemId, int[] itemCountMax, int[] itemCount, @@ -55,6 +57,7 @@ int[] remoteOrder IncludeOrbitCollector = includeOrbitCollector; Energy = energy; EnergyPerTick = energyPerTick; + PilerCount = pilerCount; ItemId = itemId; ItemCountMax = itemCountMax; diff --git a/NebulaNetwork/PacketProcessors/Logistics/StationUIInitialSyncProcessor.cs b/NebulaNetwork/PacketProcessors/Logistics/StationUIInitialSyncProcessor.cs index 73c0d27e3..3155e47fb 100644 --- a/NebulaNetwork/PacketProcessors/Logistics/StationUIInitialSyncProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Logistics/StationUIInitialSyncProcessor.cs @@ -37,6 +37,7 @@ public override void ProcessPacket(StationUIInitialSync packet, NebulaConnection stationComponent.includeOrbitCollector = packet.IncludeOrbitCollector; stationComponent.energy = packet.Energy; stationComponent.energyPerTick = packet.EnergyPerTick; + stationComponent.pilerCount = packet.PilerCount; for (int i = 0; i < packet.ItemId.Length; i++) { diff --git a/NebulaNetwork/PacketProcessors/Logistics/StationUIInitialSyncRequestProcessor.cs b/NebulaNetwork/PacketProcessors/Logistics/StationUIInitialSyncRequestProcessor.cs index 145922ad5..1f6790ead 100644 --- a/NebulaNetwork/PacketProcessors/Logistics/StationUIInitialSyncRequestProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Logistics/StationUIInitialSyncRequestProcessor.cs @@ -64,6 +64,7 @@ public override void ProcessPacket(StationUIInitialSyncRequest packet, NebulaCon stationComponent.includeOrbitCollector, stationComponent.energy, stationComponent.energyPerTick, + stationComponent.pilerCount, itemId, itemCountMax, itemCount, diff --git a/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs b/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs index 38c66652c..8d14cd85c 100644 --- a/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs @@ -74,6 +74,19 @@ public static bool OnMinDeliverVesselValueChange_Prefix(UIStationWindow __instan return Multiplayer.Session.LocalPlayer.IsHost; } + [HarmonyPrefix] + [HarmonyPatch(nameof(UIStationWindow.OnMaxMiningSpeedChange))] + public static bool OnMaxMiningSpeedChangee_Prefix(UIStationWindow __instance, float value) + { + if (__instance.event_lock || !Multiplayer.IsActive || Multiplayer.Session.Ships.PatchLockILS) + { + return true; + } + Multiplayer.Session.StationsUI.SliderBarPacket.SettingIndex = StationUI.EUISettings.MaxMiningSpeed; + Multiplayer.Session.StationsUI.SliderBarPacket.SettingValue = value; + return Multiplayer.Session.LocalPlayer.IsHost; + } + [HarmonyPrefix] [HarmonyPatch(nameof(UIStationWindow.OnWarperDistanceValueChange))] public static bool OnWarperDistanceValueChange_Prefix(UIStationWindow __instance, float value) @@ -87,6 +100,21 @@ public static bool OnWarperDistanceValueChange_Prefix(UIStationWindow __instance return Multiplayer.Session.LocalPlayer.IsHost; } + [HarmonyPostfix] + [HarmonyPatch(nameof(UIStationWindow.OnMinPilerValueChange))] + [HarmonyPatch(nameof(UIStationWindow.OnTechPilerClick))] + public static void OnPilerCountChange(UIStationWindow __instance) + { + if (__instance.event_lock || !Multiplayer.IsActive || Multiplayer.Session.Ships.PatchLockILS) + { + return; + } + + StationComponent stationComponent = __instance.transport.stationPool[__instance.stationId]; + StationUI packet = new StationUI(__instance.factory.planet.id, stationComponent.id, stationComponent.gid, StationUI.EUISettings.PilerCount, stationComponent.pilerCount); + Multiplayer.Session.Network.SendPacket(packet); + } + [HarmonyPrefix] [HarmonyPatch(nameof(UIStationWindow.OnWarperNecessaryClick))] public static bool OnWarperNecessaryClick_Prefix(UIStationWindow __instance) @@ -275,16 +303,5 @@ public static bool _OnUpdate_Prefix(UIStationWindow __instance) } return true; } - - [HarmonyPostfix] - [HarmonyPatch(nameof(UIStationWindow._OnClose))] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Original Function Name")] - public static void _OnClose_Postfix(UIStationWindow __instance) - { - if (!Multiplayer.IsActive) - { - return; - } - } } } diff --git a/NebulaWorld/Logistics/StationUIManager.cs b/NebulaWorld/Logistics/StationUIManager.cs index bb4921cdd..35b9e568d 100644 --- a/NebulaWorld/Logistics/StationUIManager.cs +++ b/NebulaWorld/Logistics/StationUIManager.cs @@ -61,7 +61,6 @@ public void UpdateUI(ref StationUI packet) */ private void UpdateSettingsUI(StationComponent stationComponent, ref StationUI packet) { - Debug.Log(packet.SettingIndex); // SetDroneCount, SetShipCount may change packet.SettingValue switch (packet.SettingIndex) { @@ -198,6 +197,23 @@ private void UpdateSettingsUI(StationComponent stationComponent, ref StationUI p } break; } + case StationUI.EUISettings.PilerCount: + { + stationComponent.pilerCount = (int)packet.SettingValue; + break; + } + case StationUI.EUISettings.MaxMiningSpeed: + { + 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)); + } + break; + } } } From b1773bfa8e181954fc47e652d645d9ed9e4abfa4 Mon Sep 17 00:00:00 2001 From: starfish Date: Sat, 29 Jan 2022 03:32:00 +0800 Subject: [PATCH 5/8] Fix starId in StationUIProcessor --- NebulaNetwork/PacketProcessors/Logistics/StationUIProcessor.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NebulaNetwork/PacketProcessors/Logistics/StationUIProcessor.cs b/NebulaNetwork/PacketProcessors/Logistics/StationUIProcessor.cs index 4c66def99..24251fbcb 100644 --- a/NebulaNetwork/PacketProcessors/Logistics/StationUIProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Logistics/StationUIProcessor.cs @@ -25,7 +25,8 @@ public override void ProcessPacket(StationUI packet, NebulaConnection conn) Multiplayer.Session.StationsUI.UpdateUI(ref packet); // broadcast to every clients that may have the station loaded. - playerManager.SendPacketToStarExcept(packet, packet.PlanetId, conn); + int starId = GameMain.galaxy.PlanetById(packet.PlanetId)?.star.id ?? -1; + playerManager.SendPacketToStarExcept(packet, starId, conn); // as we block the normal method for the client he must run it once he receives this packet. // but only the one issued the request should do it, we indicate this here From 1bdd56fc810d8ae2ce97c58ab0f77a40e83832d9 Mon Sep 17 00:00:00 2001 From: starfish Date: Sat, 29 Jan 2022 07:19:49 +0800 Subject: [PATCH 6/8] Disable buttons interaction until host response - Disable drone/ship/warper icon buttons when client sends out the request. - Let item count changes in storage reflect immediately because they don't need to be verified by host --- .../Patches/Dynamic/UIStationStorage_Patch.cs | 10 ---------- .../Patches/Dynamic/UIStationWindow_Patch.cs | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/NebulaPatcher/Patches/Dynamic/UIStationStorage_Patch.cs b/NebulaPatcher/Patches/Dynamic/UIStationStorage_Patch.cs index 2ccee8759..0cf381b71 100644 --- a/NebulaPatcher/Patches/Dynamic/UIStationStorage_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/UIStationStorage_Patch.cs @@ -75,11 +75,6 @@ public static void OnItemIconMouseDown_Postfix(UIStationStorage __instance, (int { StationUI packet = new StationUI(__instance.stationWindow.factory.planet.id, __instance.station.id, __instance.station.gid, __instance.index, StationUI.EUISettings.AddOrRemoveItemFromStorage, stationStore.itemId, stationStore.count, stationStore.inc); Multiplayer.Session.Network.SendPacket(packet); - if (Multiplayer.Session.LocalPlayer.IsClient) - { - __instance.station.storage[__instance.index].count = __state.Item1; - __instance.station.storage[__instance.index].inc = __state.Item2; - } } } @@ -111,11 +106,6 @@ public static void OnItemIconMouseUp_Postfix(UIStationStorage __instance, (int, { StationUI packet = new StationUI(__instance.stationWindow.factory.planet.id, __instance.station.id, __instance.station.gid, __instance.index, StationUI.EUISettings.AddOrRemoveItemFromStorage, stationStore.itemId, stationStore.count, stationStore.inc); Multiplayer.Session.Network.SendPacket(packet); - if (Multiplayer.Session.LocalPlayer.IsClient) - { - __instance.station.storage[__instance.index].count = __state.Item1; - __instance.station.storage[__instance.index].inc = __state.Item2; - } } } } diff --git a/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs b/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs index 8d14cd85c..0b5baa1ba 100644 --- a/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs @@ -170,6 +170,7 @@ public static void OnDroneIconClick_Posfix(UIStationWindow __instance, int __sta { // Revert drone count until host verify stationComponent.idleDroneCount = __state; + __instance.droneIconButton.button.interactable = false; } } } @@ -203,6 +204,7 @@ public static void OnShipIconClick_Posfix(UIStationWindow __instance, int __stat { // Revert ship count until host verify stationComponent.idleShipCount = __state; + __instance.shipIconButton.button.interactable = false; } } } @@ -235,6 +237,7 @@ public static void OnWarperIconClick_Posfix(UIStationWindow __instance, int __st { // Revert warper count until host verify stationComponent.warperCount = __state; + __instance.warperIconButton.button.interactable = false; } } } @@ -303,5 +306,19 @@ public static bool _OnUpdate_Prefix(UIStationWindow __instance) } return true; } + + [HarmonyPostfix] + [HarmonyPatch(nameof(UIStationWindow.OnStationIdChange))] + public static void OnStationIdChange_Postfix(UIStationWindow __instance) + { + if (!Multiplayer.IsActive || Multiplayer.Session.LocalPlayer.IsHost) + { + return; + } + + __instance.warperIconButton.button.interactable = true; + __instance.shipIconButton.button.interactable = true; + __instance.droneIconButton.button.interactable = true; + } } } From ba4b6fef6977f17882531a628584bbe9c6d02104 Mon Sep 17 00:00:00 2001 From: starfish Date: Mon, 31 Jan 2022 06:55:08 +0800 Subject: [PATCH 7/8] Add ItemInc in initial station sync packet --- NebulaModel/Packets/Logistics/StationUIInitialSync.cs | 3 +++ .../Logistics/StationUIInitialSyncProcessor.cs | 1 + .../Logistics/StationUIInitialSyncRequestProcessor.cs | 5 ++++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/NebulaModel/Packets/Logistics/StationUIInitialSync.cs b/NebulaModel/Packets/Logistics/StationUIInitialSync.cs index 714a9fd9f..03ad8da54 100644 --- a/NebulaModel/Packets/Logistics/StationUIInitialSync.cs +++ b/NebulaModel/Packets/Logistics/StationUIInitialSync.cs @@ -18,6 +18,7 @@ public class StationUIInitialSync public int[] ItemId { get; set; } public int[] ItemCountMax { get; set; } public int[] ItemCount { get; set; } + public int[] ItemInc { get; set; } public int[] LocalLogic { get; set; } public int[] RemoteLogic { get; set; } public int[] RemoteOrder { get; set; } @@ -40,6 +41,7 @@ public StationUIInitialSync( int[] itemId, int[] itemCountMax, int[] itemCount, + int[] itemInc, int[] localLogic, int[] remoteLogic, int[] remoteOrder @@ -62,6 +64,7 @@ int[] remoteOrder ItemId = itemId; ItemCountMax = itemCountMax; ItemCount = itemCount; + ItemInc = itemInc; LocalLogic = localLogic; RemoteLogic = remoteLogic; RemoteOrder = remoteOrder; diff --git a/NebulaNetwork/PacketProcessors/Logistics/StationUIInitialSyncProcessor.cs b/NebulaNetwork/PacketProcessors/Logistics/StationUIInitialSyncProcessor.cs index 3155e47fb..873613765 100644 --- a/NebulaNetwork/PacketProcessors/Logistics/StationUIInitialSyncProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Logistics/StationUIInitialSyncProcessor.cs @@ -49,6 +49,7 @@ public override void ProcessPacket(StationUIInitialSync packet, NebulaConnection stationComponent.storage[i].itemId = packet.ItemId[i]; stationComponent.storage[i].max = packet.ItemCountMax[i]; stationComponent.storage[i].count = packet.ItemCount[i]; + stationComponent.storage[i].inc = packet.ItemInc[i]; stationComponent.storage[i].remoteOrder = packet.RemoteOrder[i]; stationComponent.storage[i].localLogic = (ELogisticStorage)packet.LocalLogic[i]; stationComponent.storage[i].remoteLogic = (ELogisticStorage)packet.RemoteLogic[i]; diff --git a/NebulaNetwork/PacketProcessors/Logistics/StationUIInitialSyncRequestProcessor.cs b/NebulaNetwork/PacketProcessors/Logistics/StationUIInitialSyncRequestProcessor.cs index 1f6790ead..168fcf2ea 100644 --- a/NebulaNetwork/PacketProcessors/Logistics/StationUIInitialSyncRequestProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Logistics/StationUIInitialSyncRequestProcessor.cs @@ -20,7 +20,7 @@ public override void ProcessPacket(StationUIInitialSyncRequest packet, NebulaCon return; } - StationComponent stationComponent = null; + StationComponent stationComponent; StationComponent[] gStationPool = GameMain.data.galacticTransport.stationPool; StationComponent[] stationPool = GameMain.data.galaxy?.PlanetById(packet.PlanetId)?.factory?.transport?.stationPool; @@ -37,6 +37,7 @@ public override void ProcessPacket(StationUIInitialSyncRequest packet, NebulaCon int[] itemId = new int[storage.Length]; int[] itemCountMax = new int[storage.Length]; int[] itemCount = new int[storage.Length]; + int[] itemInc = new int[storage.Length]; int[] localLogic = new int[storage.Length]; int[] remoteLogic = new int[storage.Length]; int[] remoteOrder = new int[storage.Length]; @@ -46,6 +47,7 @@ public override void ProcessPacket(StationUIInitialSyncRequest packet, NebulaCon itemId[i] = storage[i].itemId; itemCountMax[i] = storage[i].max; itemCount[i] = storage[i].count; + itemInc[i] = storage[i].inc; localLogic[i] = (int)storage[i].localLogic; remoteLogic[i] = (int)storage[i].remoteLogic; remoteOrder[i] = storage[i].remoteOrder; @@ -68,6 +70,7 @@ public override void ProcessPacket(StationUIInitialSyncRequest packet, NebulaCon itemId, itemCountMax, itemCount, + itemInc, localLogic, remoteLogic, remoteOrder From 779e15fd31f12e9fafc7ec3e04f6b50a8c7858ce Mon Sep 17 00:00:00 2001 From: starfish Date: Mon, 31 Jan 2022 23:40:54 +0800 Subject: [PATCH 8/8] Add remoteOrderUpdate - Let client request for remoteOrder update every 180 ticks. --- .../Packets/Logistics/RemoteOrderUpdate.cs | 15 ++++ NebulaModel/Packets/Logistics/StationUI.cs | 40 +--------- NebulaModel/Packets/Logistics/StorageUI.cs | 43 +++++++++++ .../Logistics/RemoteOrderUpdateProcessor.cs | 45 +++++++++++ .../Logistics/StationUIProcessor.cs | 13 ++-- .../Logistics/StorageUIProcessor.cs | 42 ++++++++++ .../Patches/Dynamic/PlanetTransport_Patch.cs | 2 +- .../Patches/Dynamic/UIStationStorage_Patch.cs | 4 +- .../Patches/Dynamic/UIStationWindow_Patch.cs | 15 ++++ NebulaWorld/Logistics/StationUIManager.cs | 76 ++++++++++--------- 10 files changed, 209 insertions(+), 86 deletions(-) create mode 100644 NebulaModel/Packets/Logistics/RemoteOrderUpdate.cs create mode 100644 NebulaModel/Packets/Logistics/StorageUI.cs create mode 100644 NebulaNetwork/PacketProcessors/Logistics/RemoteOrderUpdateProcessor.cs create mode 100644 NebulaNetwork/PacketProcessors/Logistics/StorageUIProcessor.cs diff --git a/NebulaModel/Packets/Logistics/RemoteOrderUpdate.cs b/NebulaModel/Packets/Logistics/RemoteOrderUpdate.cs new file mode 100644 index 000000000..a9c726f14 --- /dev/null +++ b/NebulaModel/Packets/Logistics/RemoteOrderUpdate.cs @@ -0,0 +1,15 @@ +namespace NebulaModel.Packets.Logistics +{ + public class RemoteOrderUpdate + { + public int StationGId { get; set; } + public int[] RemoteOrder { get; set; } + + public RemoteOrderUpdate() { } + public RemoteOrderUpdate(int stationGid, int[] remoteOrder) + { + StationGId = stationGid; + RemoteOrder = remoteOrder; + } + } +} diff --git a/NebulaModel/Packets/Logistics/StationUI.cs b/NebulaModel/Packets/Logistics/StationUI.cs index 9066d4398..39604783e 100644 --- a/NebulaModel/Packets/Logistics/StationUI.cs +++ b/NebulaModel/Packets/Logistics/StationUI.cs @@ -16,7 +16,6 @@ public enum EUISettings SetDroneCount, SetShipCount, SetWarperCount, - AddOrRemoveItemFromStorage, PilerCount, MaxMiningSpeed } @@ -24,38 +23,14 @@ public enum EUISettings public int PlanetId { get; set; } public int StationId { get; set; } public int StationGId { get; set; } - public bool IsStorageUI { get; set; } public StationUI.EUISettings SettingIndex { get; set; } public float SettingValue { get; set; } - public float SettingValue2 { get; set; } - public int StorageIdx { get; set; } - public int ItemId { get; set; } - public int ItemCountMax { get; set; } - public ELogisticStorage LocalLogic { get; set; } - public ELogisticStorage RemoteLogic { get; set; } - public bool ShouldMimic { get; set; } public bool WarperShouldTakeFromStorage { get; set; } + public bool ShouldRefund { get; set; } public StationUI() { } - public StationUI(int planetId, int stationId, int stationGId, int storageIdx, int itemId, int itemCountMax, ELogisticStorage localLogic, ELogisticStorage remoteLogic) - { - IsStorageUI = true; - ShouldMimic = false; - WarperShouldTakeFromStorage = false; - - PlanetId = planetId; - StationId = stationId; - StationGId = stationGId; - StorageIdx = storageIdx; - ItemId = itemId; - ItemCountMax = itemCountMax; - LocalLogic = localLogic; - RemoteLogic = remoteLogic; - } public StationUI(int planetId, int stationId, int stationGId, StationUI.EUISettings settingIndex, float value, bool warperShouldTakeFromStorage = false) { - IsStorageUI = false; - PlanetId = planetId; StationId = stationId; StationGId = stationGId; @@ -63,18 +38,5 @@ public StationUI(int planetId, int stationId, int stationGId, StationUI.EUISetti SettingValue = value; WarperShouldTakeFromStorage = warperShouldTakeFromStorage; } - public StationUI(int planetId, int stationId, int stationGId, int storageIdx, StationUI.EUISettings settingIndex, int itemId, int count, int inc) - { - WarperShouldTakeFromStorage = false; - - PlanetId = planetId; - StationId = stationId; - StationGId = stationGId; - StorageIdx = storageIdx; - SettingIndex = settingIndex; - ItemId = itemId; - SettingValue = count; - SettingValue2 = inc; - } } } diff --git a/NebulaModel/Packets/Logistics/StorageUI.cs b/NebulaModel/Packets/Logistics/StorageUI.cs new file mode 100644 index 000000000..47b56acb9 --- /dev/null +++ b/NebulaModel/Packets/Logistics/StorageUI.cs @@ -0,0 +1,43 @@ +namespace NebulaModel.Packets.Logistics +{ + public class StorageUI + { + public int PlanetId { get; set; } + public int StationId { get; set; } + public int StationGId { get; set; } + public int StorageIdx { get; set; } + public int ItemId { get; set; } + public int ItemCountMax { get; set; } + public ELogisticStorage LocalLogic { get; set; } + public ELogisticStorage RemoteLogic { get; set; } + public int ItemCount { get; set; } + public int ItemInc { get; set; } + public bool ShouldRefund { get; set; } + + public StorageUI() { } + public StorageUI(int planetId, int stationId, int stationGId, int storageIdx, int itemId, int itemCountMax, ELogisticStorage localLogic, ELogisticStorage remoteLogic) + { + ItemCount = -1; //Indicate it is SetStationStorage() + + PlanetId = planetId; + StationId = stationId; + StationGId = stationGId; + StorageIdx = storageIdx; + ItemId = itemId; + ItemCountMax = itemCountMax; + LocalLogic = localLogic; + RemoteLogic = remoteLogic; + } + public StorageUI(int planetId, int stationId, int stationGId, int storageIdx, int itemCount, int itemInc) + { + ShouldRefund = false; + + PlanetId = planetId; + StationId = stationId; + StationGId = stationGId; + StorageIdx = storageIdx; + ItemCount = itemCount; + ItemInc = itemInc; + } + } +} diff --git a/NebulaNetwork/PacketProcessors/Logistics/RemoteOrderUpdateProcessor.cs b/NebulaNetwork/PacketProcessors/Logistics/RemoteOrderUpdateProcessor.cs new file mode 100644 index 000000000..f82213fbd --- /dev/null +++ b/NebulaNetwork/PacketProcessors/Logistics/RemoteOrderUpdateProcessor.cs @@ -0,0 +1,45 @@ +using NebulaAPI; +using NebulaModel.Networking; +using NebulaModel.Packets; +using NebulaModel.Packets.Logistics; +using NebulaWorld; + +namespace NebulaNetwork.PacketProcessors.Logistics +{ + [RegisterPacketProcessor] + public class RemoteOrderUpdateProcessor : PacketProcessor + { + public override void ProcessPacket(RemoteOrderUpdate packet, NebulaConnection conn) + { + if (IsHost) + { + StationComponent stationComponent = GameMain.data.galacticTransport.stationPool[packet.StationGId]; + StationStore[] storage = stationComponent?.storage; + if (stationComponent == null || storage == null) + { + return; + } + int[] remoteOrder = new int[storage.Length]; + for (int i = 0; i < stationComponent.storage.Length; i++) + { + remoteOrder[i] = storage[i].remoteOrder; + } + packet.RemoteOrder = remoteOrder; + conn.SendPacket(packet); + } + if (IsClient) + { + StationComponent stationComponent = GameMain.data.galacticTransport.stationPool[packet.StationGId]; + StationStore[] storage = stationComponent?.storage; + if (stationComponent == null || storage == null) + { + return; + } + for (int i = 0; i < storage.Length; i++) + { + storage[i].remoteOrder = packet.RemoteOrder[i]; + } + } + } + } +} \ No newline at end of file diff --git a/NebulaNetwork/PacketProcessors/Logistics/StationUIProcessor.cs b/NebulaNetwork/PacketProcessors/Logistics/StationUIProcessor.cs index 24251fbcb..7a8ec1931 100644 --- a/NebulaNetwork/PacketProcessors/Logistics/StationUIProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Logistics/StationUIProcessor.cs @@ -3,7 +3,6 @@ using NebulaModel.Packets; using NebulaModel.Packets.Logistics; using NebulaWorld; -using System.Collections.Generic; namespace NebulaNetwork.PacketProcessors.Logistics { @@ -20,23 +19,23 @@ public override void ProcessPacket(StationUI packet, NebulaConnection conn) { if (IsHost) { - // always update values for host, but he does not need to rely on the mimic flag (infact its bad for him) - packet.ShouldMimic = false; - Multiplayer.Session.StationsUI.UpdateUI(ref packet); + // always update values for host + packet.ShouldRefund = false; + Multiplayer.Session.StationsUI.UpdateStation(ref packet); // broadcast to every clients that may have the station loaded. int starId = GameMain.galaxy.PlanetById(packet.PlanetId)?.star.id ?? -1; playerManager.SendPacketToStarExcept(packet, starId, conn); // as we block the normal method for the client he must run it once he receives this packet. - // but only the one issued the request should do it, we indicate this here - packet.ShouldMimic = true; + // but only the one issued the request should get items refund + packet.ShouldRefund = true; conn.SendPacket(packet); } if (IsClient) { - Multiplayer.Session.StationsUI.UpdateUI(ref packet); + Multiplayer.Session.StationsUI.UpdateStation(ref packet); } } } diff --git a/NebulaNetwork/PacketProcessors/Logistics/StorageUIProcessor.cs b/NebulaNetwork/PacketProcessors/Logistics/StorageUIProcessor.cs new file mode 100644 index 000000000..4b850bbec --- /dev/null +++ b/NebulaNetwork/PacketProcessors/Logistics/StorageUIProcessor.cs @@ -0,0 +1,42 @@ +using NebulaAPI; +using NebulaModel.Networking; +using NebulaModel.Packets; +using NebulaModel.Packets.Logistics; +using NebulaWorld; + +namespace NebulaNetwork.PacketProcessors.Logistics +{ + [RegisterPacketProcessor] + internal class StorageUIProcessor : PacketProcessor + { + private readonly IPlayerManager playerManager; + public StorageUIProcessor() + { + playerManager = Multiplayer.Session.Network.PlayerManager; + } + + public override void ProcessPacket(StorageUI packet, NebulaConnection conn) + { + if (IsHost) + { + // always update values for host + packet.ShouldRefund = false; + Multiplayer.Session.StationsUI.UpdateStorage(packet); + + // broadcast to every clients that may have the station loaded. + int starId = GameMain.galaxy.PlanetById(packet.PlanetId)?.star.id ?? -1; + playerManager.SendPacketToStarExcept(packet, starId, conn); + + // as we block some methods for the client he must run it once he receives this packet. + // but only the one issued the request should get items refund + packet.ShouldRefund = true; + conn.SendPacket(packet); + } + + if (IsClient) + { + Multiplayer.Session.StationsUI.UpdateStorage(packet); + } + } + } +} diff --git a/NebulaPatcher/Patches/Dynamic/PlanetTransport_Patch.cs b/NebulaPatcher/Patches/Dynamic/PlanetTransport_Patch.cs index 264a6d8a3..54562b2e4 100644 --- a/NebulaPatcher/Patches/Dynamic/PlanetTransport_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/PlanetTransport_Patch.cs @@ -18,7 +18,7 @@ public static bool SetStationStorage_Postfix(PlanetTransport __instance, int sta if (stationComponent != null) { - StationUI packet = new StationUI(__instance.planet.id, stationComponent.id, stationComponent.gid, storageIdx, itemId, itemCountMax, localLogic, remoteLogic); + StorageUI packet = new StorageUI(__instance.planet.id, stationComponent.id, stationComponent.gid, storageIdx, itemId, itemCountMax, localLogic, remoteLogic); Multiplayer.Session.Network.SendPacket(packet); } diff --git a/NebulaPatcher/Patches/Dynamic/UIStationStorage_Patch.cs b/NebulaPatcher/Patches/Dynamic/UIStationStorage_Patch.cs index 0cf381b71..b90afdd2c 100644 --- a/NebulaPatcher/Patches/Dynamic/UIStationStorage_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/UIStationStorage_Patch.cs @@ -73,7 +73,7 @@ public static void OnItemIconMouseDown_Postfix(UIStationStorage __instance, (int StationStore stationStore = __instance.station.storage[__instance.index]; if (__state.Item1 != stationStore.count || __state.Item2 != stationStore.inc) { - StationUI packet = new StationUI(__instance.stationWindow.factory.planet.id, __instance.station.id, __instance.station.gid, __instance.index, StationUI.EUISettings.AddOrRemoveItemFromStorage, stationStore.itemId, stationStore.count, stationStore.inc); + StorageUI packet = new StorageUI(__instance.stationWindow.factory.planet.id, __instance.station.id, __instance.station.gid, __instance.index, stationStore.count, stationStore.inc); Multiplayer.Session.Network.SendPacket(packet); } } @@ -104,7 +104,7 @@ public static void OnItemIconMouseUp_Postfix(UIStationStorage __instance, (int, if (__state.Item1 != stationStore.count || __state.Item2 != stationStore.inc) { - StationUI packet = new StationUI(__instance.stationWindow.factory.planet.id, __instance.station.id, __instance.station.gid, __instance.index, StationUI.EUISettings.AddOrRemoveItemFromStorage, stationStore.itemId, stationStore.count, stationStore.inc); + StorageUI packet = new StorageUI(__instance.stationWindow.factory.planet.id, __instance.station.id, __instance.station.gid, __instance.index, stationStore.count, stationStore.inc); Multiplayer.Session.Network.SendPacket(packet); } } diff --git a/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs b/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs index 0b5baa1ba..e4e6b4e58 100644 --- a/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/UIStationWindow_Patch.cs @@ -9,6 +9,8 @@ namespace NebulaPatcher.Patches.Dynamic [HarmonyPatch(typeof(UIStationWindow))] internal class UIStationWindow_Patch { + private static long lastUpdateGametick; + [HarmonyPrefix] [HarmonyPatch(nameof(UIStationWindow.OnMaxChargePowerSliderValueChange))] public static bool OnMaxChargePowerSliderValueChange_Prefix(UIStationWindow __instance, float value) @@ -259,6 +261,7 @@ public static void _OnOpen_Postfix(UIStationWindow __instance) { return; } + lastUpdateGametick = GameMain.gameTick; // Stage 0 : Hide UI elements until sync data arrive __instance.titleText.text = "Loading..."; @@ -304,6 +307,18 @@ public static bool _OnUpdate_Prefix(UIStationWindow __instance) Multiplayer.Session.StationsUI.StorageMaxChangeId = Multiplayer.Session.LocalPlayer.IsHost ? -1 : -2; } } + + // Request for remoteOrder update every 180tick + if (Multiplayer.Session.LocalPlayer.IsClient && GameMain.gameTick - lastUpdateGametick > 180) + { + int gid = __instance.transport?.stationPool?[__instance.stationId].gid ?? 0; + if (gid > 0) + { + Multiplayer.Session.Network.SendPacket(new RemoteOrderUpdate(gid, System.Array.Empty())); + } + lastUpdateGametick = GameMain.gameTick; + } + return true; } diff --git a/NebulaWorld/Logistics/StationUIManager.cs b/NebulaWorld/Logistics/StationUIManager.cs index 35b9e568d..8dd1510c9 100644 --- a/NebulaWorld/Logistics/StationUIManager.cs +++ b/NebulaWorld/Logistics/StationUIManager.cs @@ -8,9 +8,9 @@ namespace NebulaWorld.Logistics public class StationUIManager : IDisposable { public int UpdateCooldown; // cooldown is reserved for future use - public bool UIRequestedShipDronWarpChange; // when receiving a ship, drone or warp change only take/add items from the one issuing the request - public StationUI SliderBarPacket; // store the change of slider bar temporary, only send it when mouse button is released. - public int StorageMaxChangeId; // index of the storage that its slider value changed by the user. -1: None, -2: Syncing + public bool UIRequestedShipDronWarpChange { get; set; } // when receiving a ship, drone or warp change only take/add items from the one issuing the request + public StationUI SliderBarPacket { get; set; } // store the change of slider bar temporary, only send it when mouse button is released. + public int StorageMaxChangeId { get; set; } // index of the storage that its slider value changed by the user. -1: None, -2: Syncing public StationUIManager() { @@ -29,29 +29,39 @@ public void DecreaseCooldown() } } - public void UpdateUI(ref StationUI packet) + public void UpdateStation(ref StationUI packet) { - StationComponent stationComponent = GetStation(packet); + StationComponent stationComponent = GetStation(packet.PlanetId, packet.StationId, packet.StationGId); if (stationComponent == null) { + Log.Warn($"StationUI: Unable to find requested station on planet {packet.PlanetId} with id {packet.StationId} and gid of {packet.StationGId}"); return; } - if (packet.IsStorageUI) - { - UpdateStorageUI(stationComponent, packet); - } - else + UpdateSettingsUI(stationComponent, ref packet); + RefreshWindow(packet.PlanetId, packet.StationId); + } + + public void UpdateStorage(StorageUI packet) + { + StationComponent stationComponent = GetStation(packet.PlanetId, packet.StationId, packet.StationGId); + if (stationComponent == null) { - UpdateSettingsUI(stationComponent, ref packet); + Log.Warn($"StorageUI: Unable to find requested station on planet {packet.PlanetId} with id {packet.StationId} and gid of {packet.StationGId}"); + return; } + UpdateStorageUI(stationComponent, packet); + RefreshWindow(packet.PlanetId, packet.StationId); + } + private void RefreshWindow(int planetId, int stationId) + { // If station window is opened and veiwing the updating station, refresh the window. UIStationWindow stationWindow = UIRoot.instance.uiGame.stationWindow; if (stationWindow != null && stationWindow.active) { - if (stationWindow.factory?.planetId == packet.PlanetId && stationWindow.stationId == packet.StationId) + if (stationWindow.factory?.planetId == planetId && stationWindow.stationId == stationId) { - stationWindow.OnStationIdChange(); + stationWindow.OnStationIdChange(); } } } @@ -82,7 +92,7 @@ private void UpdateSettingsUI(StationComponent stationComponent, ref StationUI p // Check if new setting is acceptable int totalCount = Math.Min((int)packet.SettingValue, stationComponent.workDroneDatas.Length); stationComponent.idleDroneCount = Math.Max(totalCount - stationComponent.workDroneCount, 0); - if (totalCount < (int)packet.SettingValue && packet.ShouldMimic) + if (totalCount < (int)packet.SettingValue && packet.ShouldRefund) { // The result is less than original setting, refund extra drones to author int refund = (int)packet.SettingValue - totalCount; @@ -96,7 +106,7 @@ private void UpdateSettingsUI(StationComponent stationComponent, ref StationUI p // Check if new setting is acceptable int totalCount = Math.Min((int)packet.SettingValue, stationComponent.workShipDatas.Length); stationComponent.idleShipCount = Math.Max(totalCount - stationComponent.workShipCount, 0); - if (totalCount < (int)packet.SettingValue && packet.ShouldMimic) + if (totalCount < (int)packet.SettingValue && packet.ShouldRefund) { // The result is less than original setting, refund extra ships to author int refund = (int)packet.SettingValue - totalCount; @@ -188,15 +198,6 @@ private void UpdateSettingsUI(StationComponent stationComponent, ref StationUI p stationComponent.includeOrbitCollector = !stationComponent.includeOrbitCollector; break; } - case StationUI.EUISettings.AddOrRemoveItemFromStorage: - { - if (stationComponent.storage != null) - { - stationComponent.storage[packet.StorageIdx].count = (int)packet.SettingValue; - stationComponent.storage[packet.StorageIdx].inc = (int)packet.SettingValue2; - } - break; - } case StationUI.EUISettings.PilerCount: { stationComponent.pilerCount = (int)packet.SettingValue; @@ -222,10 +223,9 @@ private void UpdateSettingsUI(StationComponent stationComponent, ref StationUI p * * First determine if the local player has the station window opened and handle that accordingly. */ - private StationComponent GetStation(StationUI packet) + private StationComponent GetStation(int planetId, int stationId, int stationGid) { - StationComponent stationComponent = null; - PlanetData planet = GameMain.galaxy?.PlanetById(packet.PlanetId); + PlanetData planet = GameMain.galaxy?.PlanetById(planetId); // If we can't find planet or the factory for said planet, we can just skip this if (planet?.factory?.transport == null) @@ -237,23 +237,25 @@ private StationComponent GetStation(StationUI packet) StationComponent[] stationPool = planet?.factory?.transport?.stationPool; // Figure out if we're dealing with a PLS or a ILS station - stationComponent = packet.StationGId > 0 ? gStationPool[packet.StationGId] : stationPool?[packet.StationId]; - - if (stationComponent == null) - { - Log.Warn($"StationUI: Unable to find requested station on planet {packet.PlanetId} with id {packet.StationId} and gid of {packet.StationGId}"); - return null; - } + StationComponent stationComponent = stationGid > 0 ? gStationPool[stationGid] : stationPool?[stationId]; return stationComponent; } - private void UpdateStorageUI(StationComponent stationComponent, StationUI packet) + private void UpdateStorageUI(StationComponent stationComponent, StorageUI packet) { using (Multiplayer.Session.Ships.PatchLockILS.On()) { PlanetData planet = GameMain.galaxy.PlanetById(packet.PlanetId); - planet.factory.transport.SetStationStorage(stationComponent.id, packet.StorageIdx, packet.ItemId, packet.ItemCountMax, packet.LocalLogic, packet.RemoteLogic, (packet.ShouldMimic == true) ? GameMain.mainPlayer : null); - StorageMaxChangeId = -1; + if (packet.ItemCount == -1) + { + planet.factory.transport.SetStationStorage(stationComponent.id, packet.StorageIdx, packet.ItemId, packet.ItemCountMax, packet.LocalLogic, packet.RemoteLogic, (packet.ShouldRefund == true) ? GameMain.mainPlayer : null); + StorageMaxChangeId = -1; + } + else + { + stationComponent.storage[packet.StorageIdx].count = packet.ItemCount; + stationComponent.storage[packet.StorageIdx].inc = packet.ItemInc; + } } } }