Item spawn syncing

This commit is contained in:
Regalis
2016-10-12 18:29:44 +03:00
parent a235b90aee
commit ac3539da63
5 changed files with 101 additions and 48 deletions
+58 -15
View File
@@ -1,11 +1,19 @@
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Barotrauma.Networking;
using System;
namespace Barotrauma namespace Barotrauma
{ {
class ItemSpawner class ItemSpawner : IServerSerializable
{ {
public UInt32 NetStateID
{
get;
private set;
}
class ItemSpawnInfo class ItemSpawnInfo
{ {
public readonly ItemPrefab Prefab; public readonly ItemPrefab Prefab;
@@ -99,15 +107,30 @@ namespace Barotrauma
//if (GameMain.Server != null) GameMain.Server.SendItemSpawnMessage(items); //if (GameMain.Server != null) GameMain.Server.SendItemSpawnMessage(items);
} }
public void AddToSpawnedList(List<Item> items)
{
foreach (Item item in items)
{
AddToSpawnedList(item);
}
}
public void AddToSpawnedList(Item item) public void AddToSpawnedList(Item item)
{ {
spawnItems.Add(item); spawnItems.Add(item);
NetStateID = (UInt32)spawnItems.Count;
} }
public void FillNetworkData(Lidgren.Network.NetBuffer message, List<Item> items) public void ServerWrite(Lidgren.Network.NetOutgoingMessage message, Client client)
{ {
message.Write((byte)items.Count); if (GameMain.Server == null) return;
//skip items that the client already knows about
List<Item> items = spawnItems.Skip((int)client.lastRecvItemSpawnID).ToList();
message.Write((UInt32)spawnItems.Count);
message.Write((byte)items.Count);
for (int i = 0; i < items.Count; i++) for (int i = 0; i < items.Count; i++)
{ {
message.Write(items[i].Prefab.Name); message.Write(items[i].Prefab.Name);
@@ -136,18 +159,22 @@ namespace Barotrauma
} }
} }
public void ReadNetworkData(Lidgren.Network.NetBuffer message) public void ClientRead(Lidgren.Network.NetIncomingMessage message)
{ {
if (GameMain.Server != null) return;
UInt32 ID = message.ReadUInt32();
var itemCount = message.ReadByte(); var itemCount = message.ReadByte();
for (int i = 0; i < itemCount; i++) for (int i = 0; i < itemCount; i++)
{ {
string itemName = message.ReadString(); string itemName = message.ReadString();
ushort itemId = message.ReadUInt16(); ushort itemId = message.ReadUInt16();
Vector2 pos = Vector2.Zero;
Submarine sub = null;
ushort inventoryId = message.ReadUInt16(); ushort inventoryId = message.ReadUInt16();
Vector2 pos = Vector2.Zero;
Submarine sub = null;
int inventorySlotIndex = -1; int inventorySlotIndex = -1;
if (inventoryId > 0) if (inventoryId > 0)
@@ -157,6 +184,7 @@ namespace Barotrauma
else else
{ {
pos = new Vector2(message.ReadSingle(), message.ReadSingle()); pos = new Vector2(message.ReadSingle(), message.ReadSingle());
ushort subID = message.ReadUInt16(); ushort subID = message.ReadUInt16();
if (subID > 0) if (subID > 0)
{ {
@@ -170,6 +198,10 @@ namespace Barotrauma
tags = message.ReadString(); tags = message.ReadString();
} }
if (ID - itemCount + i < NetStateID) continue;
//----------------------------------------
var prefab = MapEntityPrefab.list.Find(me => me.Name == itemName); var prefab = MapEntityPrefab.list.Find(me => me.Name == itemName);
if (prefab == null) continue; if (prefab == null) continue;
@@ -215,19 +247,28 @@ namespace Barotrauma
} }
inventory.TryPutItem(item, item.AllowedSlots); inventory.TryPutItem(item, item.AllowedSlots);
} }
} }
NetStateID = Math.Max(ID, NetStateID);
} }
public void Clear() public void Clear()
{ {
NetStateID = 0;
spawnQueue.Clear(); spawnQueue.Clear();
spawnItems.Clear(); spawnItems.Clear();
} }
} }
class ItemRemover class ItemRemover : IServerSerializable
{ {
public UInt32 NetStateID
{
get;
private set;
}
private readonly Queue<Item> removeQueue; private readonly Queue<Item> removeQueue;
public List<Item> removedItems = new List<Item>(); public List<Item> removedItems = new List<Item>();
@@ -267,16 +308,16 @@ namespace Barotrauma
//if (GameMain.Server != null) GameMain.Server.SendItemRemoveMessage(items); //if (GameMain.Server != null) GameMain.Server.SendItemRemoveMessage(items);
} }
public void FillNetworkData(Lidgren.Network.NetBuffer message, List<Item> items) public void ServerWrite(Lidgren.Network.NetOutgoingMessage message, Client client)
{ {
message.Write((byte)items.Count); //message.Write((byte)items.Count);
foreach (Item item in items) //foreach (Item item in items)
{ //{
message.Write(item.ID); // message.Write(item.ID);
} //}
} }
public void ReadNetworkData(Lidgren.Network.NetBuffer message) public void ClientRead(Lidgren.Network.NetIncomingMessage message)
{ {
var itemCount = message.ReadByte(); var itemCount = message.ReadByte();
for (int i = 0; i<itemCount; i++) for (int i = 0; i<itemCount; i++)
@@ -292,6 +333,8 @@ namespace Barotrauma
public void Clear() public void Clear()
{ {
NetStateID = 0;
removeQueue.Clear(); removeQueue.Clear();
removedItems.Clear(); removedItems.Clear();
} }
+7
View File
@@ -36,6 +36,10 @@ namespace Barotrauma.Networking
public UInt32 lastSentChatMsgID = 0; //last msg this client said public UInt32 lastSentChatMsgID = 0; //last msg this client said
public UInt32 lastRecvChatMsgID = 0; //last msg this client knows about public UInt32 lastRecvChatMsgID = 0; //last msg this client knows about
public UInt32 lastRecvItemSpawnID = 0;
public UInt32 lastRecvItemRemoveID = 0;
public List<string> ChatMessages = new List<string>(); public List<string> ChatMessages = new List<string>();
public float ChatSpamSpeed; public float ChatSpamSpeed;
public float ChatSpamTimer; public float ChatSpamTimer;
@@ -58,6 +62,9 @@ namespace Barotrauma.Networking
{ {
lastSentChatMsgID = 0; lastSentChatMsgID = 0;
lastRecvChatMsgID = ChatMessage.LastID; lastRecvChatMsgID = ChatMessage.LastID;
lastRecvItemSpawnID = 0;
lastRecvItemRemoveID = 0;
} }
public int KickVoteCount public int KickVoteCount
@@ -704,6 +704,9 @@ namespace Barotrauma.Networking
case ServerNetObject.CHAT_MESSAGE: case ServerNetObject.CHAT_MESSAGE:
ChatMessage.ClientRead(inc); ChatMessage.ClientRead(inc);
break; break;
case ServerNetObject.ITEM_SPAWN:
Item.Spawner.ClientRead(inc);
break;
} }
} }
} }
@@ -738,6 +741,7 @@ 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);
ChatMessage removeMsg; ChatMessage removeMsg;
while ((removeMsg = chatMsgQueue.Find(cMsg => cMsg.NetStateID <= lastSentChatMsgID)) != null) while ((removeMsg = chatMsgQueue.Find(cMsg => cMsg.NetStateID <= lastSentChatMsgID)) != null)
{ {
+26 -29
View File
@@ -568,16 +568,8 @@ 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
UInt32 lastGeneralUpdID = inc.ReadUInt32(); c.lastRecvGeneralUpdate = Math.Max(c.lastRecvGeneralUpdate, inc.ReadUInt32());
if (lastGeneralUpdID > c.lastRecvGeneralUpdate) c.lastRecvChatMsgID = Math.Max(c.lastRecvChatMsgID, inc.ReadUInt32());
{
c.lastRecvGeneralUpdate = lastGeneralUpdID;
}
UInt32 lastChatID = inc.ReadUInt32();
if (lastChatID > c.lastRecvChatMsgID)
{
c.lastRecvChatMsgID = lastChatID;
}
break; break;
case ClientNetObject.CHAT_MESSAGE: case ClientNetObject.CHAT_MESSAGE:
ChatMessage.ServerRead(inc, c); ChatMessage.ServerRead(inc, c);
@@ -606,16 +598,11 @@ 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
UInt32 lastGeneralUpdID = inc.ReadUInt32();
if (lastGeneralUpdID > c.lastRecvGeneralUpdate) c.lastRecvGeneralUpdate = Math.Max(c.lastRecvGeneralUpdate, inc.ReadUInt32());
{ c.lastRecvChatMsgID = Math.Max(c.lastRecvChatMsgID, inc.ReadUInt32());
c.lastRecvGeneralUpdate = lastGeneralUpdID; c.lastRecvItemSpawnID = Math.Max(c.lastRecvItemSpawnID, inc.ReadUInt32());
}
UInt32 lastChatID = inc.ReadUInt32();
if (lastChatID > c.lastRecvChatMsgID)
{
c.lastRecvChatMsgID = lastChatID;
}
break; break;
case ClientNetObject.CHAT_MESSAGE: case ClientNetObject.CHAT_MESSAGE:
ChatMessage.ServerRead(inc, c); ChatMessage.ServerRead(inc, c);
@@ -656,6 +643,7 @@ namespace Barotrauma.Networking
} }
} }
outmsg.Write((byte)ServerNetObject.CHARACTER_POSITION); outmsg.Write((byte)ServerNetObject.CHARACTER_POSITION);
if (c.Character != null && !c.Character.IsDead) if (c.Character != null && !c.Character.IsDead)
{ {
@@ -668,6 +656,13 @@ namespace Barotrauma.Networking
outmsg.WritePadBits(); outmsg.WritePadBits();
} }
if (Item.Spawner.NetStateID > c.lastRecvItemSpawnID)
{
outmsg.Write((byte)ServerNetObject.ITEM_SPAWN);
Item.Spawner.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);
} }
@@ -876,16 +871,12 @@ namespace Barotrauma.Networking
WayPoint[] assignedWayPoints = WayPoint.SelectCrewSpawnPoints(characterInfos, Submarine.MainSub); WayPoint[] assignedWayPoints = WayPoint.SelectCrewSpawnPoints(characterInfos, Submarine.MainSub);
for (int i = 0; i < connectedClients.Count; i++) for (int i = 0; i < connectedClients.Count; i++)
{ {
WayPoint spawnPoint = WayPoint.GetRandom(SpawnType.Human, null, selectedSub);
Vector2 spawnPosition = spawnPoint.WorldPosition;
DebugConsole.NewMessage(spawnPosition.ToString(), Color.Lime);
Character spawnedCharacter = Character.Create(connectedClients[i].characterInfo, assignedWayPoints[i].WorldPosition, true, false); Character spawnedCharacter = Character.Create(connectedClients[i].characterInfo, assignedWayPoints[i].WorldPosition, true, false);
spawnedCharacter.AnimController.Frozen = true; spawnedCharacter.AnimController.Frozen = true;
spawnedCharacter.GiveJobItems(assignedWayPoints[i]);
connectedClients[i].Character = spawnedCharacter; connectedClients[i].Character = spawnedCharacter;
GameMain.GameSession.CrewManager.characters.Add(spawnedCharacter); GameMain.GameSession.CrewManager.characters.Add(spawnedCharacter);
@@ -894,11 +885,17 @@ namespace Barotrauma.Networking
if (characterInfo != null) if (characterInfo != null)
{ {
myCharacter = Character.Create(characterInfo, assignedWayPoints[assignedWayPoints.Length - 1].WorldPosition, false, false); myCharacter = Character.Create(characterInfo, assignedWayPoints[assignedWayPoints.Length - 1].WorldPosition, false, false);
myCharacter.GiveJobItems(assignedWayPoints.Last());
Character.Controlled = myCharacter; Character.Controlled = myCharacter;
GameMain.GameSession.CrewManager.characters.Add(myCharacter); GameMain.GameSession.CrewManager.characters.Add(myCharacter);
} }
foreach (Character c in GameMain.GameSession.CrewManager.characters)
{
Item.Spawner.AddToSpawnedList(c.SpawnItems);
}
SendStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.gameMode.Preset, connectedClients); SendStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.gameMode.Preset, connectedClients);
//var startMessage = CreateStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.gameMode.Preset); //var startMessage = CreateStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.gameMode.Preset);
//server.SendMessage(startMessage, connectedClients.Select(c => c.Connection).ToList(), NetDeliveryMethod.ReliableUnordered, 0); //server.SendMessage(startMessage, connectedClients.Select(c => c.Connection).ToList(), NetDeliveryMethod.ReliableUnordered, 0);
@@ -947,8 +944,8 @@ namespace Barotrauma.Networking
msg.Write(selectedMode.Name); msg.Write(selectedMode.Name);
msg.Write(AllowRespawn); msg.Write(AllowRespawn);
msg.Write(Submarine.MainSubs[1] != null); //loadSecondSub msg.Write(Submarine.MainSubs[1] != null); //loadSecondSub
var clientsWithCharacter = clients.FindAll(c => c.Character != null); var clientsWithCharacter = clients.FindAll(c => c.Character != null);
@@ -1321,7 +1318,7 @@ namespace Barotrauma.Networking
if (jobPrefab != null) jobPreferences.Add(jobPrefab); if (jobPrefab != null) jobPreferences.Add(jobPrefab);
} }
sender.characterInfo = new CharacterInfo(Character.HumanConfigFile, name, gender); sender.characterInfo = new CharacterInfo(Character.HumanConfigFile, sender.name, gender);
sender.characterInfo.HeadSpriteId = headSpriteId; sender.characterInfo.HeadSpriteId = headSpriteId;
sender.jobPreferences = jobPreferences; sender.jobPreferences = jobPreferences;
} }
@@ -45,7 +45,9 @@ namespace Barotrauma.Networking
CHAT_MESSAGE, CHAT_MESSAGE,
VOTE, VOTE,
CHARACTER_POSITION, CHARACTER_POSITION,
ITEM_STATE ITEM_STATE,
ITEM_SPAWN
} }
enum VoteType enum VoteType