From 170e1a0da8e6dc76a376b3894c4758521bfc22be Mon Sep 17 00:00:00 2001 From: Regalis Date: Wed, 12 Oct 2016 20:46:47 +0300 Subject: [PATCH] ItemRemover -> EntityRemover, clients reset spawner & remover when starting a new round --- Subsurface/Barotrauma.csproj | 3 +- Subsurface/Source/DebugConsole.cs | 4 +- Subsurface/Source/GameSession/GameSession.cs | 5 +- Subsurface/Source/Items/Item.cs | 3 - Subsurface/Source/Map/Entity.cs | 1 + Subsurface/Source/Map/MapEntity.cs | 2 +- Subsurface/Source/Networking/Client.cs | 4 +- Subsurface/Source/Networking/EntityRemover.cs | 89 ++++++++++++++ Subsurface/Source/Networking/EntitySpawner.cs | 113 +++--------------- Subsurface/Source/Networking/GameClient.cs | 15 ++- Subsurface/Source/Networking/GameServer.cs | 17 ++- Subsurface/Source/Networking/NetworkMember.cs | 3 +- 12 files changed, 144 insertions(+), 115 deletions(-) create mode 100644 Subsurface/Source/Networking/EntityRemover.cs diff --git a/Subsurface/Barotrauma.csproj b/Subsurface/Barotrauma.csproj index df36c2dce..58e062cef 100644 --- a/Subsurface/Barotrauma.csproj +++ b/Subsurface/Barotrauma.csproj @@ -134,7 +134,8 @@ - + + diff --git a/Subsurface/Source/DebugConsole.cs b/Subsurface/Source/DebugConsole.cs index 5518f79f4..38250136e 100644 --- a/Subsurface/Source/DebugConsole.cs +++ b/Subsurface/Source/DebugConsole.cs @@ -337,12 +337,12 @@ namespace Barotrauma if (spawnPos != null) { - Item.Spawner.QueueItem(itemPrefab, (Vector2)spawnPos, false); + Item.Spawner.QueueItem(itemPrefab, (Vector2)spawnPos); } else if (spawnInventory != null) { - Item.Spawner.QueueItem(itemPrefab, (Inventory)spawnInventory, false); + Item.Spawner.QueueItem(itemPrefab, (Inventory)spawnInventory); } break; diff --git a/Subsurface/Source/GameSession/GameSession.cs b/Subsurface/Source/GameSession/GameSession.cs index ecc1c89bb..a78fe3d3b 100644 --- a/Subsurface/Source/GameSession/GameSession.cs +++ b/Subsurface/Source/GameSession/GameSession.cs @@ -72,11 +72,14 @@ namespace Barotrauma Submarine.MainSub = submarine; GameMain.GameSession = this; - + CrewManager = new CrewManager(); TaskManager = new TaskManager(this); + Entity.Spawner.Clear(); + Entity.Remover.Clear(); + this.saveFile = saveFile; //guiRoot = new GUIFrame(new Rectangle(0,0,GameMain.GraphicsWidth,GameMain.GraphicsWidth), Color.Transparent); diff --git a/Subsurface/Source/Items/Item.cs b/Subsurface/Source/Items/Item.cs index 13a040815..c4dc90d53 100644 --- a/Subsurface/Source/Items/Item.cs +++ b/Subsurface/Source/Items/Item.cs @@ -31,9 +31,6 @@ namespace Barotrauma public static List ItemList = new List(); private ItemPrefab prefab; - - public static ItemRemover Remover = new ItemRemover(); - public static bool ShowLinks = true; private List tags; diff --git a/Subsurface/Source/Map/Entity.cs b/Subsurface/Source/Map/Entity.cs index 021a1e73e..994b43280 100644 --- a/Subsurface/Source/Map/Entity.cs +++ b/Subsurface/Source/Map/Entity.cs @@ -12,6 +12,7 @@ namespace Barotrauma private static Dictionary dictionary = new Dictionary(); public static EntitySpawner Spawner = new EntitySpawner(); + public static EntityRemover Remover = new EntityRemover(); private ushort id; diff --git a/Subsurface/Source/Map/MapEntity.cs b/Subsurface/Source/Map/MapEntity.cs index fe509626c..7a5e73d50 100644 --- a/Subsurface/Source/Map/MapEntity.cs +++ b/Subsurface/Source/Map/MapEntity.cs @@ -270,7 +270,7 @@ namespace Barotrauma } Entity.Spawner.Update(); - Item.Remover.Update(); + Entity.Remover.Update(); } public virtual void Update(Camera cam, float deltaTime) { } diff --git a/Subsurface/Source/Networking/Client.cs b/Subsurface/Source/Networking/Client.cs index c82a92961..352f31d7f 100644 --- a/Subsurface/Source/Networking/Client.cs +++ b/Subsurface/Source/Networking/Client.cs @@ -37,7 +37,7 @@ namespace Barotrauma.Networking public UInt32 lastRecvChatMsgID = 0; //last msg this client knows about public UInt32 lastRecvEntitySpawnID = 0; - public UInt32 lastRecvItemRemoveID = 0; + public UInt32 lastRecvEntityRemoveID = 0; public List ChatMessages = new List(); @@ -64,7 +64,7 @@ namespace Barotrauma.Networking lastRecvChatMsgID = ChatMessage.LastID; lastRecvEntitySpawnID = 0; - lastRecvItemRemoveID = 0; + lastRecvEntityRemoveID = 0; } public int KickVoteCount diff --git a/Subsurface/Source/Networking/EntityRemover.cs b/Subsurface/Source/Networking/EntityRemover.cs new file mode 100644 index 000000000..08a3f081f --- /dev/null +++ b/Subsurface/Source/Networking/EntityRemover.cs @@ -0,0 +1,89 @@ +using Barotrauma.Networking; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Barotrauma +{ + class EntityRemover : IServerSerializable + { + public UInt32 NetStateID + { + get; + private set; + } + + private readonly Queue removeQueue; + + public List removedEntities = new List(); + + public EntityRemover() + { + removeQueue = new Queue(); + } + + public void QueueItem(Item item) + { + if (GameMain.Client != null) return; + + removeQueue.Enqueue(item); + } + + public void Update() + { + if (GameMain.Client != null) return; + + while (removeQueue.Count > 0) + { + var entity = removeQueue.Dequeue(); + removedEntities.Add(entity); + + entity.Remove(); + NetStateID = (UInt32)removedEntities.Count; + } + } + + public void ServerWrite(Lidgren.Network.NetOutgoingMessage message, Client client) + { + if (GameMain.Server == null) return; + + List entities = removedEntities.Skip((int)client.lastRecvEntityRemoveID).ToList(); + + message.Write((UInt32)removedEntities.Count); + + message.Write((UInt16)entities.Count); + foreach (Entity entity in entities) + { + message.Write(entity.ID); + } + } + + public void ClientRead(Lidgren.Network.NetIncomingMessage message) + { + if (GameMain.Server != null) return; + + UInt32 ID = message.ReadUInt32(); + + var entityCount = message.ReadUInt16(); + for (int i = 0; i < entityCount; i++) + { + ushort entityId = message.ReadUInt16(); + + var entity = Entity.FindEntityByID(entityId); + if (entity == null || ID - entityCount + i < NetStateID) continue; //already removed + + entity.Remove(); + } + + NetStateID = Math.Max(ID, NetStateID); + } + + public void Clear() + { + NetStateID = 0; + + removeQueue.Clear(); + removedEntities.Clear(); + } + } +} diff --git a/Subsurface/Source/Networking/EntitySpawner.cs b/Subsurface/Source/Networking/EntitySpawner.cs index bc898d7d3..b4365a056 100644 --- a/Subsurface/Source/Networking/EntitySpawner.cs +++ b/Subsurface/Source/Networking/EntitySpawner.cs @@ -1,8 +1,8 @@ -using Microsoft.Xna.Framework; +using Barotrauma.Networking; +using Microsoft.Xna.Framework; +using System; using System.Collections.Generic; using System.Linq; -using Barotrauma.Networking; -using System; namespace Barotrauma { @@ -75,45 +75,40 @@ namespace Barotrauma spawnQueue = new Queue(); } - public void QueueItem(ItemPrefab itemPrefab, Vector2 worldPosition, bool isNetworkMessage = false) + public void QueueItem(ItemPrefab itemPrefab, Vector2 worldPosition) { - //clients aren't allowed to spawn new items unless the server says so - if (!isNetworkMessage && GameMain.Client != null) return; + if (GameMain.Client != null) return; spawnQueue.Enqueue(new ItemSpawnInfo(itemPrefab, worldPosition)); } - public void QueueItem(ItemPrefab itemPrefab, Vector2 position, Submarine sub, bool isNetworkMessage = false) + public void QueueItem(ItemPrefab itemPrefab, Vector2 position, Submarine sub) { - //clients aren't allowed to spawn new items unless the server says so - if (!isNetworkMessage && GameMain.Client != null) return; + if (GameMain.Client != null) return; spawnQueue.Enqueue(new ItemSpawnInfo(itemPrefab, position, sub)); } - public void QueueItem(ItemPrefab itemPrefab, Inventory inventory, bool isNetworkMessage = false) + public void QueueItem(ItemPrefab itemPrefab, Inventory inventory) { - //clients aren't allowed to spawn new items unless the server says so - if (!isNetworkMessage && GameMain.Client != null) return; + if (GameMain.Client != null) return; spawnQueue.Enqueue(new ItemSpawnInfo(itemPrefab, inventory)); } public void Update() { + if (GameMain.Client != null) return; + if (!spawnQueue.Any()) return; - //List inventories = new List(); while (spawnQueue.Count>0) { var entitySpawnInfo = spawnQueue.Dequeue(); var spawnedEntity = entitySpawnInfo.Spawn(); - - if (spawnedEntity!= null) AddToSpawnedList(spawnedEntity); + if (spawnedEntity != null) AddToSpawnedList(spawnedEntity); } - - //if (GameMain.Server != null) GameMain.Server.SendItemSpawnMessage(items); } public void AddToSpawnedList(Entity entity) @@ -134,7 +129,7 @@ namespace Barotrauma message.Write((UInt32)spawnedEntities.Count); - message.Write((byte)entities.Count); + message.Write((UInt16)entities.Count); for (int i = 0; i < entities.Count; i++) { if (entities[i] is Item) @@ -156,7 +151,7 @@ namespace Barotrauma UInt32 ID = message.ReadUInt32(); - var entityCount = message.ReadByte(); + var entityCount = message.ReadUInt16(); for (int i = 0; i < entityCount; i++) { switch (message.ReadByte()) @@ -186,84 +181,4 @@ namespace Barotrauma spawnedEntities.Clear(); } } - - //todo: turn into a generic EntityRemover class + sync - class ItemRemover : IServerSerializable - { - public UInt32 NetStateID - { - get; - private set; - } - - private readonly Queue removeQueue; - - public List removedItems = new List(); - - public ItemRemover() - { - removeQueue = new Queue(); - } - - public void QueueItem(Item item, bool isNetworkMessage = false) - { - if (!isNetworkMessage && GameMain.Client != null) - { - //clients aren't allowed to remove items unless the server says so - return; - } - - removeQueue.Enqueue(item); - } - - public void Update() - { - if (!removeQueue.Any()) return; - - List items = new List(); - - while (removeQueue.Count > 0) - { - var item = removeQueue.Dequeue(); - removedItems.Add(item); - - item.Remove(); - - items.Add(item); - } - - //if (GameMain.Server != null) GameMain.Server.SendItemRemoveMessage(items); - } - - public void ServerWrite(Lidgren.Network.NetOutgoingMessage message, Client client) - { - //message.Write((byte)items.Count); - //foreach (Item item in items) - //{ - // message.Write(item.ID); - //} - } - - public void ClientRead(Lidgren.Network.NetIncomingMessage message) - { - var itemCount = message.ReadByte(); - for (int i = 0; i cMsg.NetStateID <= lastSentChatMsgID)) != null) { diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index ddfae63bf..19e17c968 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -599,10 +599,11 @@ namespace Barotrauma.Networking case ClientNetObject.SYNC_IDS: //TODO: might want to use a clever class for this - c.lastRecvGeneralUpdate = Math.Max(c.lastRecvGeneralUpdate, inc.ReadUInt32()); - c.lastRecvChatMsgID = Math.Max(c.lastRecvChatMsgID, inc.ReadUInt32()); - c.lastRecvEntitySpawnID = Math.Max(c.lastRecvEntitySpawnID, inc.ReadUInt32()); - + c.lastRecvGeneralUpdate = Math.Max(c.lastRecvGeneralUpdate, inc.ReadUInt32()); + c.lastRecvChatMsgID = Math.Max(c.lastRecvChatMsgID, inc.ReadUInt32()); + c.lastRecvEntitySpawnID = Math.Max(c.lastRecvEntitySpawnID, inc.ReadUInt32()); + c.lastRecvEntityRemoveID = Math.Max(c.lastRecvEntityRemoveID, inc.ReadUInt32()); + break; case ClientNetObject.CHAT_MESSAGE: ChatMessage.ServerRead(inc, c); @@ -663,6 +664,14 @@ namespace Barotrauma.Networking outmsg.WritePadBits(); } + if (Item.Remover.NetStateID > c.lastRecvEntityRemoveID) + { + outmsg.Write((byte)ServerNetObject.ENTITY_REMOVE); + Item.Remover.ServerWrite(outmsg, c); + outmsg.WritePadBits(); + } + + outmsg.Write((byte)ServerNetObject.END_OF_MESSAGE); server.SendMessage(outmsg, c.Connection, NetDeliveryMethod.Unreliable); } diff --git a/Subsurface/Source/Networking/NetworkMember.cs b/Subsurface/Source/Networking/NetworkMember.cs index 2a3623289..9285927d0 100644 --- a/Subsurface/Source/Networking/NetworkMember.cs +++ b/Subsurface/Source/Networking/NetworkMember.cs @@ -47,7 +47,8 @@ namespace Barotrauma.Networking CHARACTER_POSITION, ITEM_STATE, - ENTITY_SPAWN + ENTITY_SPAWN, + ENTITY_REMOVE } enum VoteType