ItemRemover -> EntityRemover, clients reset spawner & remover when starting a new round

This commit is contained in:
Regalis
2016-10-12 20:46:47 +03:00
parent 60b36e020c
commit 170e1a0da8
12 changed files with 144 additions and 115 deletions
+2 -1
View File
@@ -134,7 +134,8 @@
<Compile Include="Source\Items\Components\ItemLabel.cs" /> <Compile Include="Source\Items\Components\ItemLabel.cs" />
<Compile Include="Source\Items\Components\StatusHUD.cs" /> <Compile Include="Source\Items\Components\StatusHUD.cs" />
<Compile Include="Source\Items\FixRequirement.cs" /> <Compile Include="Source\Items\FixRequirement.cs" />
<Compile Include="Source\Items\ItemSpawner.cs" /> <Compile Include="Source\Networking\EntityRemover.cs" />
<Compile Include="Source\Networking\EntitySpawner.cs" />
<Compile Include="Source\Map\EntityGrid.cs" /> <Compile Include="Source\Map\EntityGrid.cs" />
<Compile Include="Source\Map\FireSource.cs" /> <Compile Include="Source\Map\FireSource.cs" />
<Compile Include="Source\Map\Levels\CaveGenerator.cs" /> <Compile Include="Source\Map\Levels\CaveGenerator.cs" />
+2 -2
View File
@@ -337,12 +337,12 @@ namespace Barotrauma
if (spawnPos != null) if (spawnPos != null)
{ {
Item.Spawner.QueueItem(itemPrefab, (Vector2)spawnPos, false); Item.Spawner.QueueItem(itemPrefab, (Vector2)spawnPos);
} }
else if (spawnInventory != null) else if (spawnInventory != null)
{ {
Item.Spawner.QueueItem(itemPrefab, (Inventory)spawnInventory, false); Item.Spawner.QueueItem(itemPrefab, (Inventory)spawnInventory);
} }
break; break;
@@ -77,6 +77,9 @@ namespace Barotrauma
TaskManager = new TaskManager(this); TaskManager = new TaskManager(this);
Entity.Spawner.Clear();
Entity.Remover.Clear();
this.saveFile = saveFile; this.saveFile = saveFile;
//guiRoot = new GUIFrame(new Rectangle(0,0,GameMain.GraphicsWidth,GameMain.GraphicsWidth), Color.Transparent); //guiRoot = new GUIFrame(new Rectangle(0,0,GameMain.GraphicsWidth,GameMain.GraphicsWidth), Color.Transparent);
-3
View File
@@ -31,9 +31,6 @@ namespace Barotrauma
public static List<Item> ItemList = new List<Item>(); public static List<Item> ItemList = new List<Item>();
private ItemPrefab prefab; private ItemPrefab prefab;
public static ItemRemover Remover = new ItemRemover();
public static bool ShowLinks = true; public static bool ShowLinks = true;
private List<string> tags; private List<string> tags;
+1
View File
@@ -12,6 +12,7 @@ namespace Barotrauma
private static Dictionary<ushort, Entity> dictionary = new Dictionary<ushort, Entity>(); private static Dictionary<ushort, Entity> dictionary = new Dictionary<ushort, Entity>();
public static EntitySpawner Spawner = new EntitySpawner(); public static EntitySpawner Spawner = new EntitySpawner();
public static EntityRemover Remover = new EntityRemover();
private ushort id; private ushort id;
+1 -1
View File
@@ -270,7 +270,7 @@ namespace Barotrauma
} }
Entity.Spawner.Update(); Entity.Spawner.Update();
Item.Remover.Update(); Entity.Remover.Update();
} }
public virtual void Update(Camera cam, float deltaTime) { } public virtual void Update(Camera cam, float deltaTime) { }
+2 -2
View File
@@ -37,7 +37,7 @@ namespace Barotrauma.Networking
public UInt32 lastRecvChatMsgID = 0; //last msg this client knows about public UInt32 lastRecvChatMsgID = 0; //last msg this client knows about
public UInt32 lastRecvEntitySpawnID = 0; public UInt32 lastRecvEntitySpawnID = 0;
public UInt32 lastRecvItemRemoveID = 0; public UInt32 lastRecvEntityRemoveID = 0;
public List<string> ChatMessages = new List<string>(); public List<string> ChatMessages = new List<string>();
@@ -64,7 +64,7 @@ namespace Barotrauma.Networking
lastRecvChatMsgID = ChatMessage.LastID; lastRecvChatMsgID = ChatMessage.LastID;
lastRecvEntitySpawnID = 0; lastRecvEntitySpawnID = 0;
lastRecvItemRemoveID = 0; lastRecvEntityRemoveID = 0;
} }
public int KickVoteCount public int KickVoteCount
@@ -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<Entity> removeQueue;
public List<Entity> removedEntities = new List<Entity>();
public EntityRemover()
{
removeQueue = new Queue<Entity>();
}
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<Entity> 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();
}
}
}
+14 -99
View File
@@ -1,8 +1,8 @@
using Microsoft.Xna.Framework; using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Barotrauma.Networking;
using System;
namespace Barotrauma namespace Barotrauma
{ {
@@ -75,45 +75,40 @@ namespace Barotrauma
spawnQueue = new Queue<IEntitySpawnInfo>(); spawnQueue = new Queue<IEntitySpawnInfo>();
} }
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 (GameMain.Client != null) return;
if (!isNetworkMessage && GameMain.Client != null) return;
spawnQueue.Enqueue(new ItemSpawnInfo(itemPrefab, worldPosition)); 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 (GameMain.Client != null) return;
if (!isNetworkMessage && GameMain.Client != null) return;
spawnQueue.Enqueue(new ItemSpawnInfo(itemPrefab, position, sub)); 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 (GameMain.Client != null) return;
if (!isNetworkMessage && GameMain.Client != null) return;
spawnQueue.Enqueue(new ItemSpawnInfo(itemPrefab, inventory)); spawnQueue.Enqueue(new ItemSpawnInfo(itemPrefab, inventory));
} }
public void Update() public void Update()
{ {
if (GameMain.Client != null) return;
if (!spawnQueue.Any()) return; if (!spawnQueue.Any()) return;
//List<Inventory> inventories = new List<Inventory>();
while (spawnQueue.Count>0) while (spawnQueue.Count>0)
{ {
var entitySpawnInfo = spawnQueue.Dequeue(); var entitySpawnInfo = spawnQueue.Dequeue();
var spawnedEntity = entitySpawnInfo.Spawn(); 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) public void AddToSpawnedList(Entity entity)
@@ -134,7 +129,7 @@ namespace Barotrauma
message.Write((UInt32)spawnedEntities.Count); message.Write((UInt32)spawnedEntities.Count);
message.Write((byte)entities.Count); message.Write((UInt16)entities.Count);
for (int i = 0; i < entities.Count; i++) for (int i = 0; i < entities.Count; i++)
{ {
if (entities[i] is Item) if (entities[i] is Item)
@@ -156,7 +151,7 @@ namespace Barotrauma
UInt32 ID = message.ReadUInt32(); UInt32 ID = message.ReadUInt32();
var entityCount = message.ReadByte(); var entityCount = message.ReadUInt16();
for (int i = 0; i < entityCount; i++) for (int i = 0; i < entityCount; i++)
{ {
switch (message.ReadByte()) switch (message.ReadByte())
@@ -186,84 +181,4 @@ namespace Barotrauma
spawnedEntities.Clear(); spawnedEntities.Clear();
} }
} }
//todo: turn into a generic EntityRemover class + sync
class ItemRemover : IServerSerializable
{
public UInt32 NetStateID
{
get;
private set;
}
private readonly Queue<Item> removeQueue;
public List<Item> removedItems = new List<Item>();
public ItemRemover()
{
removeQueue = new Queue<Item>();
}
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<Item> items = new List<Item>();
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<itemCount; i++)
{
ushort itemId = message.ReadUInt16();
var item = MapEntity.FindEntityByID(itemId) as Item;
if (item == null) continue;
item.Remove();
}
}
public void Clear()
{
NetStateID = 0;
removeQueue.Clear();
removedItems.Clear();
}
}
} }
+14 -1
View File
@@ -559,6 +559,9 @@ namespace Barotrauma.Networking
{ {
if (Character != null) Character.Remove(); if (Character != null) Character.Remove();
Entity.Spawner.Clear();
Entity.Remover.Clear();
endVoteTickBox.Selected = false; endVoteTickBox.Selected = false;
int seed = inc.ReadInt32(); int seed = inc.ReadInt32();
@@ -715,6 +718,14 @@ namespace Barotrauma.Networking
break; break;
case ServerNetObject.ENTITY_SPAWN: case ServerNetObject.ENTITY_SPAWN:
Item.Spawner.ClientRead(inc); Item.Spawner.ClientRead(inc);
inc.ReadPadBits();
break;
case ServerNetObject.ENTITY_REMOVE:
Item.Remover.ClientRead(inc);
inc.ReadPadBits();
break;
default:
DebugConsole.ThrowError("Error while reading update from server (unknown object header \""+objHeader+"\"!)");
break; break;
} }
} }
@@ -750,7 +761,9 @@ namespace Barotrauma.Networking
outmsg.Write((byte)ClientNetObject.SYNC_IDS); outmsg.Write((byte)ClientNetObject.SYNC_IDS);
outmsg.Write(GameMain.NetLobbyScreen.LastUpdateID); outmsg.Write(GameMain.NetLobbyScreen.LastUpdateID);
outmsg.Write(ChatMessage.LastID); outmsg.Write(ChatMessage.LastID);
outmsg.Write(Item.Spawner.NetStateID); outmsg.Write(Entity.Spawner.NetStateID);
outmsg.Write(Entity.Remover.NetStateID);
ChatMessage removeMsg; ChatMessage removeMsg;
while ((removeMsg = chatMsgQueue.Find(cMsg => cMsg.NetStateID <= lastSentChatMsgID)) != null) while ((removeMsg = chatMsgQueue.Find(cMsg => cMsg.NetStateID <= lastSentChatMsgID)) != null)
{ {
+12 -3
View File
@@ -599,9 +599,10 @@ namespace Barotrauma.Networking
case ClientNetObject.SYNC_IDS: case ClientNetObject.SYNC_IDS:
//TODO: might want to use a clever class for this //TODO: might want to use a clever class for this
c.lastRecvGeneralUpdate = Math.Max(c.lastRecvGeneralUpdate, inc.ReadUInt32()); c.lastRecvGeneralUpdate = Math.Max(c.lastRecvGeneralUpdate, inc.ReadUInt32());
c.lastRecvChatMsgID = Math.Max(c.lastRecvChatMsgID, inc.ReadUInt32()); c.lastRecvChatMsgID = Math.Max(c.lastRecvChatMsgID, inc.ReadUInt32());
c.lastRecvEntitySpawnID = Math.Max(c.lastRecvEntitySpawnID, inc.ReadUInt32()); c.lastRecvEntitySpawnID = Math.Max(c.lastRecvEntitySpawnID, inc.ReadUInt32());
c.lastRecvEntityRemoveID = Math.Max(c.lastRecvEntityRemoveID, inc.ReadUInt32());
break; break;
case ClientNetObject.CHAT_MESSAGE: case ClientNetObject.CHAT_MESSAGE:
@@ -663,6 +664,14 @@ namespace Barotrauma.Networking
outmsg.WritePadBits(); 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); outmsg.Write((byte)ServerNetObject.END_OF_MESSAGE);
server.SendMessage(outmsg, c.Connection, NetDeliveryMethod.Unreliable); server.SendMessage(outmsg, c.Connection, NetDeliveryMethod.Unreliable);
} }
@@ -47,7 +47,8 @@ namespace Barotrauma.Networking
CHARACTER_POSITION, CHARACTER_POSITION,
ITEM_STATE, ITEM_STATE,
ENTITY_SPAWN ENTITY_SPAWN,
ENTITY_REMOVE
} }
enum VoteType enum VoteType