diff --git a/Content.Client/GameObjects/Components/Storage/ClientStorageComponent.cs b/Content.Client/GameObjects/Components/Storage/ClientStorageComponent.cs index f20cc4d31c..bfe0082186 100644 --- a/Content.Client/GameObjects/Components/Storage/ClientStorageComponent.cs +++ b/Content.Client/GameObjects/Components/Storage/ClientStorageComponent.cs @@ -37,7 +37,6 @@ namespace Content.Client.GameObjects.Components.Storage public override void OnRemove() { Window.Dispose(); - base.OnRemove(); } @@ -53,6 +52,9 @@ namespace Content.Client.GameObjects.Components.Storage case OpenStorageUIMessage msg: OpenUI(); break; + case CloseStorageUIMessage msg: + // todo: close window/grey it out + break; } } diff --git a/Content.Server/GameObjects/Components/Items/Storage/ServerStorageComponent.cs b/Content.Server/GameObjects/Components/Items/Storage/ServerStorageComponent.cs index d0f8982502..617d7d1770 100644 --- a/Content.Server/GameObjects/Components/Items/Storage/ServerStorageComponent.cs +++ b/Content.Server/GameObjects/Components/Items/Storage/ServerStorageComponent.cs @@ -4,6 +4,8 @@ using Content.Shared.GameObjects.Components.Storage; using SS14.Server.GameObjects; using SS14.Server.GameObjects.Components.Container; using SS14.Server.Interfaces.Player; +using SS14.Server.Player; +using SS14.Shared.Enums; using SS14.Shared.GameObjects; using SS14.Shared.GameObjects.Serialization; using SS14.Shared.Interfaces.GameObjects; @@ -23,6 +25,7 @@ namespace Content.Server.GameObjects private int StorageUsed = 0; private int StorageCapacityMax = 10000; + public HashSet SubscribedSessions = new HashSet(); public override void OnAdd() { @@ -47,8 +50,9 @@ namespace Content.Server.GameObjects { if (storage.Remove(toremove)) { + Logger.InfoS("Storage", "Storage (UID {0}) had entity (UID {1}) removed from it.", Owner.Uid, toremove.Uid); StorageUsed -= toremove.GetComponent().ObjectSize; - UpdateClientInventory(); + UpdateClientInventories(); return true; } return false; @@ -63,8 +67,9 @@ namespace Content.Server.GameObjects { if (CanInsert(toinsert) && storage.Insert(toinsert)) { + Logger.InfoS("Storage", "Storage (UID {0}) had entity (UID {1}) inserted into it.", Owner.Uid, toinsert.Uid); StorageUsed += toinsert.GetComponent().ObjectSize; - UpdateClientInventory(); + UpdateClientInventories(); return true; } return false; @@ -93,6 +98,7 @@ namespace Content.Server.GameObjects /// bool IAttackby.Attackby(IEntity user, IEntity attackwith) { + Logger.DebugS("Storage", "Storage (UID {0}) attacked by user (UID {1}) with entity (UID {2}).", Owner.Uid, user.Uid, attackwith.Uid); var hands = user.GetComponent(); //Check that we can drop the item from our hands first otherwise we obviously cant put it inside if (hands.Drop(hands.ActiveIndex)) @@ -118,21 +124,76 @@ namespace Content.Server.GameObjects /// bool IUse.UseEntity(IEntity user) { - SendNetworkMessage(new OpenStorageUIMessage()); + var user_session = user.GetComponent().playerSession; + Logger.DebugS("Storage", "Storage (UID {0}) \"used\" by player session (UID {1}).", Owner.Uid, user_session.AttachedEntityUid); + SubscribeSession(user_session); + SendNetworkMessage(new OpenStorageUIMessage(), user_session.ConnectedClient); + UpdateClientInventory(user_session); return false; } /// - /// Updates the storage UI on all clients telling them of the entities stored in this container + /// Updates the storage UI on all subscribed actors, informing them of the state of the container. /// - private void UpdateClientInventory() + private void UpdateClientInventories() { + foreach (IPlayerSession session in SubscribedSessions) + { + UpdateClientInventory(session); + } + } + + /// + /// Adds actor to the update list. + /// + /// + public void SubscribeSession(IPlayerSession session) + { + if (!SubscribedSessions.Contains(session)) + { + Logger.DebugS("Storage", "Storage (UID {0}) subscribed player session (UID {1}).", Owner.Uid, session.AttachedEntityUid); + session.PlayerStatusChanged += HandlePlayerSessionChangeEvent; + SubscribedSessions.Add(session); + } + } + + /// + /// Removes actor from the update list. + /// + /// + public void UnsubscribeSession(IPlayerSession session) + { + Logger.DebugS("Storage", "Storage (UID {0}) unsubscribed player session (UID {1}).", Owner.Uid, session.AttachedEntityUid); + SubscribedSessions.Remove(session); + SendNetworkMessage(new CloseStorageUIMessage(), session.ConnectedClient); + } + + public void HandlePlayerSessionChangeEvent(object obj, SessionStatusEventArgs SSEA) + { + Logger.DebugS("Storage", "Storage (UID {0}) handled a status change in player session (UID {1}).", Owner.Uid, SSEA.Session.AttachedEntityUid); + if (SSEA.NewStatus != SessionStatus.InGame) + { + UnsubscribeSession(SSEA.Session); + } + } + + /// + /// Updates storage UI on a client, informing them of the state of the container. + /// + private void UpdateClientInventory(IPlayerSession session) + { + if (session.AttachedEntity == null) + { + Logger.DebugS("Storage", "Storage (UID {0}) detected no attached entity in player session (UID {1}).", Owner.Uid, session.AttachedEntityUid); + UnsubscribeSession(session); + return; + } Dictionary storedentities = new Dictionary(); foreach (var entities in storage.ContainedEntities) { storedentities.Add(entities.Uid, entities.GetComponent().ObjectSize); } - SendNetworkMessage(new StorageHeldItemsMessage(storedentities, StorageUsed, StorageCapacityMax)); + SendNetworkMessage(new StorageHeldItemsMessage(storedentities, StorageUsed, StorageCapacityMax), session.ConnectedClient); } /// @@ -148,7 +209,6 @@ namespace Content.Server.GameObjects switch (message) { - case RemoveEntityMessage msg: var playerMan = IoCManager.Resolve(); var session = playerMan.GetSessionByChannel(netChannel); @@ -165,7 +225,6 @@ namespace Content.Server.GameObjects if (entity != null && storage.Contains(entity)) { Remove(entity); - UpdateClientInventory(); var item = entity.GetComponent(); if (item != null && playerentity.TryGetComponent(out HandsComponent hands)) diff --git a/Content.Shared/GameObjects/Components/Storage/SharedStorageComponent.cs b/Content.Shared/GameObjects/Components/Storage/SharedStorageComponent.cs index 385e778825..c0f1749cd2 100644 --- a/Content.Shared/GameObjects/Components/Storage/SharedStorageComponent.cs +++ b/Content.Shared/GameObjects/Components/Storage/SharedStorageComponent.cs @@ -56,4 +56,17 @@ namespace Content.Shared.GameObjects.Components.Storage Directed = true; } } + + /// + /// Component message for closing the storage UI. + /// E.g when the player moves too far away from the container. + /// + [Serializable, NetSerializable] + public class CloseStorageUIMessage : ComponentMessage + { + public CloseStorageUIMessage() + { + Directed = true; + } + } }