EntitySpawner sends spawn/removal messages to clients using EntityEvents.
EntityEvents and EntitySpawner used to work independently of each other, with separate IDs, and there was no guarantee that spawning and events would happen in the correct order. For example, a client could fail to read events during midround syncing because the entity has been removed, or read an event for an incorrect entity because the entity has been removed and the ID taken by some other entity.
This commit is contained in:
@@ -497,17 +497,18 @@ namespace Barotrauma
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Character newCharacter = null;
|
||||||
|
|
||||||
if (file != humanConfigFile)
|
if (file != humanConfigFile)
|
||||||
{
|
{
|
||||||
var enemyCharacter = new AICharacter(file, position, characterInfo, isRemotePlayer);
|
var aiCharacter = new AICharacter(file, position, characterInfo, isRemotePlayer);
|
||||||
var ai = new EnemyAIController(enemyCharacter, file);
|
var ai = new EnemyAIController(aiCharacter, file);
|
||||||
enemyCharacter.SetAI(ai);
|
aiCharacter.SetAI(ai);
|
||||||
|
|
||||||
enemyCharacter.minHealth = 0.0f;
|
aiCharacter.minHealth = 0.0f;
|
||||||
|
|
||||||
return enemyCharacter;
|
newCharacter = aiCharacter;
|
||||||
}
|
}
|
||||||
else if (hasAi)
|
else if (hasAi)
|
||||||
{
|
{
|
||||||
@@ -517,13 +518,18 @@ namespace Barotrauma
|
|||||||
|
|
||||||
aiCharacter.minHealth = -100.0f;
|
aiCharacter.minHealth = -100.0f;
|
||||||
|
|
||||||
return aiCharacter;
|
newCharacter = aiCharacter;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newCharacter = new Character(file, position, characterInfo, isRemotePlayer);
|
||||||
|
newCharacter.minHealth = -100.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
var character = new Character(file, position, characterInfo, isRemotePlayer);
|
if (GameMain.Server != null && Entity.Spawner != null)
|
||||||
character.minHealth = -100.0f;
|
Entity.Spawner.CreateNetworkEvent(newCharacter, false);
|
||||||
|
|
||||||
return character;
|
return newCharacter;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Character(string file, Vector2 position, CharacterInfo characterInfo = null, bool isRemotePlayer = false)
|
protected Character(string file, Vector2 position, CharacterInfo characterInfo = null, bool isRemotePlayer = false)
|
||||||
@@ -1911,6 +1917,21 @@ namespace Barotrauma
|
|||||||
if (AnimController != null) AnimController.Remove();
|
if (AnimController != null) AnimController.Remove();
|
||||||
|
|
||||||
if (Lights.LightManager.ViewTarget == this) Lights.LightManager.ViewTarget = null;
|
if (Lights.LightManager.ViewTarget == this) Lights.LightManager.ViewTarget = null;
|
||||||
|
|
||||||
|
if (selectedItems[0] != null) selectedItems[0].Drop(this);
|
||||||
|
if (selectedItems[1] != null) selectedItems[1].Drop(this);
|
||||||
|
|
||||||
|
if (GameMain.GameSession?.CrewManager != null &&
|
||||||
|
GameMain.GameSession.CrewManager.characters.Contains(this))
|
||||||
|
{
|
||||||
|
GameMain.GameSession.CrewManager.characters.Remove(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (Character c in CharacterList)
|
||||||
|
{
|
||||||
|
if (c.closestCharacter == this) c.closestCharacter = null;
|
||||||
|
if (c.selectedCharacter == this) c.selectedCharacter = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -178,9 +178,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
character.Enabled = false;
|
character.Enabled = false;
|
||||||
|
|
||||||
Entity.Spawner.AddToRemoveQueue(character);
|
Entity.Spawner.AddToRemoveQueue(character);
|
||||||
Entity.Spawner.AddToSpawnedList(husk);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,6 +106,11 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
Item item = new Item(itemPrefab, character.Position, null);
|
Item item = new Item(itemPrefab, character.Position, null);
|
||||||
|
|
||||||
|
if (GameMain.Server != null && Entity.Spawner != null)
|
||||||
|
{
|
||||||
|
Entity.Spawner.CreateNetworkEvent(item, false);
|
||||||
|
}
|
||||||
|
|
||||||
if (ToolBox.GetAttributeBool(itemElement, "equip", false))
|
if (ToolBox.GetAttributeBool(itemElement, "equip", false))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -320,11 +320,6 @@ namespace Barotrauma
|
|||||||
+ "/" + commands[1].ToLower() + ".xml", spawnPosition);
|
+ "/" + commands[1].ToLower() + ".xml", spawnPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spawnedCharacter != null && GameMain.Server != null)
|
|
||||||
{
|
|
||||||
Entity.Spawner.AddToSpawnedList(spawnedCharacter);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "spawnitem":
|
case "spawnitem":
|
||||||
if (commands.Length < 2) return;
|
if (commands.Length < 2) return;
|
||||||
|
|||||||
@@ -109,9 +109,7 @@ namespace Barotrauma
|
|||||||
CrewManager = new CrewManager();
|
CrewManager = new CrewManager();
|
||||||
|
|
||||||
TaskManager = new TaskManager(this);
|
TaskManager = new TaskManager(this);
|
||||||
|
|
||||||
Entity.Spawner.Clear();
|
|
||||||
|
|
||||||
this.saveFile = saveFile;
|
this.saveFile = saveFile;
|
||||||
|
|
||||||
infoButton = new GUIButton(new Rectangle(10, 10, 100, 20), "Info", GUI.Style, null);
|
infoButton = new GUIButton(new Rectangle(10, 10, 100, 20), "Info", GUI.Style, null);
|
||||||
@@ -179,7 +177,7 @@ namespace Barotrauma
|
|||||||
DebugConsole.ThrowError("Couldn't start game session, submarine not selected");
|
DebugConsole.ThrowError("Couldn't start game session, submarine not selected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reloadSub || Submarine.MainSub != submarine) submarine.Load(true);
|
if (reloadSub || Submarine.MainSub != submarine) submarine.Load(true);
|
||||||
Submarine.MainSub = submarine;
|
Submarine.MainSub = submarine;
|
||||||
if (loadSecondSub)
|
if (loadSecondSub)
|
||||||
@@ -194,18 +192,13 @@ namespace Barotrauma
|
|||||||
Submarine.MainSubs[1].Load(false);
|
Submarine.MainSubs[1].Load(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//var secondSub = new Submarine(submarine.FilePath, submarine.MD5Hash.Hash);
|
|
||||||
//secondSub.Load(false);
|
|
||||||
|
|
||||||
if (level != null)
|
if (level != null)
|
||||||
{
|
{
|
||||||
level.Generate();
|
level.Generate();
|
||||||
|
|
||||||
submarine.SetPosition(submarine.FindSpawnPos(level.StartPosition - new Vector2(0.0f, 2000.0f)));
|
submarine.SetPosition(submarine.FindSpawnPos(level.StartPosition - new Vector2(0.0f, 2000.0f)));
|
||||||
|
|
||||||
//secondSub.SetPosition(level.EndPosition - new Vector2(0.0f, 2000.0f));
|
|
||||||
|
|
||||||
GameMain.GameScreen.BackgroundCreatureManager.SpawnSprites(80);
|
GameMain.GameScreen.BackgroundCreatureManager.SpawnSprites(80);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,6 +217,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (gameMode != null) gameMode.MsgBox();
|
if (gameMode != null) gameMode.MsgBox();
|
||||||
|
|
||||||
|
Entity.Spawner = new EntitySpawner();
|
||||||
|
|
||||||
GameMain.GameScreen.ColorFade(Color.Black, Color.TransparentBlack, 5.0f);
|
GameMain.GameScreen.ColorFade(Color.Black, Color.TransparentBlack, 5.0f);
|
||||||
SoundPlayer.SwitchMusic();
|
SoundPlayer.SwitchMusic();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -944,9 +944,9 @@ namespace Barotrauma
|
|||||||
else if (body.Enabled)
|
else if (body.Enabled)
|
||||||
{
|
{
|
||||||
var holdable = GetComponent<Holdable>();
|
var holdable = GetComponent<Holdable>();
|
||||||
if (holdable!=null && holdable.Picker !=null)
|
if (holdable != null && holdable.Picker?.AnimController != null)
|
||||||
{
|
{
|
||||||
if (holdable.Picker.SelectedItems[0]==this)
|
if (holdable.Picker.SelectedItems[0] == this)
|
||||||
{
|
{
|
||||||
depth = holdable.Picker.AnimController.GetLimb(LimbType.RightHand).sprite.Depth + 0.000001f;
|
depth = holdable.Picker.AnimController.GetLimb(LimbType.RightHand).sprite.Depth + 0.000001f;
|
||||||
}
|
}
|
||||||
@@ -960,7 +960,7 @@ namespace Barotrauma
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
body.Draw(spriteBatch, prefab.sprite, color, depth);
|
body.Draw(spriteBatch, prefab.sprite, color, depth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,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;
|
||||||
|
|
||||||
private ushort id;
|
private ushort id;
|
||||||
|
|
||||||
|
|||||||
@@ -38,9 +38,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public UInt16 lastSentEntityEventID = 0;
|
public UInt16 lastSentEntityEventID = 0;
|
||||||
public UInt16 lastRecvEntityEventID = 0;
|
public UInt16 lastRecvEntityEventID = 0;
|
||||||
|
|
||||||
public UInt16 lastRecvEntitySpawnID = 0;
|
|
||||||
|
|
||||||
public List<ChatMessage> chatMsgQueue = new List<ChatMessage>();
|
public List<ChatMessage> chatMsgQueue = new List<ChatMessage>();
|
||||||
public UInt16 lastChatMsgQueueID;
|
public UInt16 lastChatMsgQueueID;
|
||||||
public float ChatSpamSpeed;
|
public float ChatSpamSpeed;
|
||||||
@@ -76,8 +74,7 @@ namespace Barotrauma.Networking
|
|||||||
lastRecvChatMsgID = ChatMessage.LastID;
|
lastRecvChatMsgID = ChatMessage.LastID;
|
||||||
|
|
||||||
lastRecvGeneralUpdate = 0;
|
lastRecvGeneralUpdate = 0;
|
||||||
|
|
||||||
lastRecvEntitySpawnID = 0;
|
|
||||||
lastRecvEntityEventID = 0;
|
lastRecvEntityEventID = 0;
|
||||||
|
|
||||||
UnreceivedEntityEventCount = 0;
|
UnreceivedEntityEventCount = 0;
|
||||||
|
|||||||
@@ -6,18 +6,12 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
class EntitySpawner : IServerSerializable
|
class EntitySpawner : Entity, IServerSerializable
|
||||||
{
|
{
|
||||||
const int MaxEntitiesPerWrite = 10;
|
const int MaxEntitiesPerWrite = 10;
|
||||||
|
|
||||||
private enum SpawnableType { Item, Character };
|
private enum SpawnableType { Item, Character };
|
||||||
|
|
||||||
public UInt16 NetStateID
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IEntitySpawnInfo
|
interface IEntitySpawnInfo
|
||||||
{
|
{
|
||||||
Entity Spawn();
|
Entity Spawn();
|
||||||
@@ -84,9 +78,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<SpawnOrRemove> spawnHistory = new List<SpawnOrRemove>();
|
|
||||||
|
|
||||||
public EntitySpawner()
|
public EntitySpawner()
|
||||||
|
: base(null)
|
||||||
{
|
{
|
||||||
spawnQueue = new Queue<IEntitySpawnInfo>();
|
spawnQueue = new Queue<IEntitySpawnInfo>();
|
||||||
removeQueue = new Queue<Entity>();
|
removeQueue = new Queue<Entity>();
|
||||||
@@ -132,6 +125,13 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void CreateNetworkEvent(Entity entity, bool remove)
|
||||||
|
{
|
||||||
|
if (GameMain.Server != null && entity != null)
|
||||||
|
{
|
||||||
|
GameMain.Server.CreateEntityEvent(this, new object[] { new SpawnOrRemove(entity, remove) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
{
|
{
|
||||||
@@ -142,38 +142,22 @@ namespace Barotrauma
|
|||||||
var entitySpawnInfo = spawnQueue.Dequeue();
|
var entitySpawnInfo = spawnQueue.Dequeue();
|
||||||
|
|
||||||
var spawnedEntity = entitySpawnInfo.Spawn();
|
var spawnedEntity = entitySpawnInfo.Spawn();
|
||||||
if (spawnedEntity != null) AddToSpawnedList(spawnedEntity);
|
if (spawnedEntity != null)
|
||||||
|
{
|
||||||
|
CreateNetworkEvent(spawnedEntity, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (removeQueue.Count > 0)
|
while (removeQueue.Count > 0)
|
||||||
{
|
{
|
||||||
var entity = removeQueue.Dequeue();
|
var removedEntity = removeQueue.Dequeue();
|
||||||
spawnHistory.Add(new SpawnOrRemove(entity, true));
|
|
||||||
|
|
||||||
entity.Remove();
|
if (GameMain.Server != null)
|
||||||
NetStateID = (UInt16)spawnHistory.Count;
|
{
|
||||||
}
|
CreateNetworkEvent(removedEntity, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddToSpawnedList(Entity entity)
|
removedEntity.Remove();
|
||||||
{
|
|
||||||
if (GameMain.Server == null) return;
|
|
||||||
if (entity == null) return;
|
|
||||||
|
|
||||||
spawnHistory.Add(new SpawnOrRemove(entity, false));
|
|
||||||
|
|
||||||
NetStateID = (UInt16)spawnHistory.Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddToSpawnedList(IEnumerable<Entity> entities)
|
|
||||||
{
|
|
||||||
if (GameMain.Server == null) return;
|
|
||||||
if (entities == null) return;
|
|
||||||
|
|
||||||
foreach (Entity entity in entities)
|
|
||||||
{
|
|
||||||
spawnHistory.Add(new SpawnOrRemove(entity, false));
|
|
||||||
NetStateID = (UInt16)spawnHistory.Count;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,89 +165,60 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (GameMain.Server == null) return;
|
if (GameMain.Server == null) return;
|
||||||
|
|
||||||
//skip items that the client already knows about
|
SpawnOrRemove entities = (SpawnOrRemove)extraData[0];
|
||||||
List<SpawnOrRemove> entities = spawnHistory.Skip((int)client.lastRecvEntitySpawnID).ToList();
|
|
||||||
|
message.Write(entities.Remove);
|
||||||
|
|
||||||
if (entities.Count > MaxEntitiesPerWrite)
|
if (entities.Remove)
|
||||||
{
|
{
|
||||||
entities = entities.GetRange(0, MaxEntitiesPerWrite);
|
message.Write(entities.Entity.ID);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
message.Write((UInt16)(spawnHistory.IndexOf(entities[0])+1));
|
|
||||||
message.WriteRangedInteger(0, MaxEntitiesPerWrite, entities.Count);
|
|
||||||
|
|
||||||
for (int i = 0; i < entities.Count; i++)
|
|
||||||
{
|
{
|
||||||
message.Write(entities[i].Remove);
|
if (entities.Entity is Item)
|
||||||
|
|
||||||
if (entities[i].Remove)
|
|
||||||
{
|
{
|
||||||
message.Write(entities[i].Entity.ID);
|
message.Write((byte)SpawnableType.Item);
|
||||||
|
((Item)entities.Entity).WriteSpawnData(message);
|
||||||
}
|
}
|
||||||
else
|
else if (entities.Entity is Character)
|
||||||
{
|
{
|
||||||
if (entities[i].Entity is Item)
|
message.Write((byte)SpawnableType.Character);
|
||||||
{
|
((Character)entities.Entity).WriteSpawnData(message);
|
||||||
message.Write((byte)SpawnableType.Item);
|
|
||||||
((Item)entities[i].Entity).WriteSpawnData(message);
|
|
||||||
}
|
|
||||||
else if (entities[i].Entity is Character)
|
|
||||||
{
|
|
||||||
message.Write((byte)SpawnableType.Character);
|
|
||||||
((Character)entities[i].Entity).WriteSpawnData(message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClientRead(ServerNetObject type, Lidgren.Network.NetBuffer message, float sendingTime)
|
public void ClientRead(ServerNetObject type, Lidgren.Network.NetBuffer message, float sendingTime)
|
||||||
{
|
{
|
||||||
if (GameMain.Server != null) return;
|
if (GameMain.Server != null) return;
|
||||||
|
|
||||||
UInt16 ID = message.ReadUInt16();
|
bool remove = message.ReadBoolean();
|
||||||
var entityCount = message.ReadRangedInteger(0, MaxEntitiesPerWrite);
|
|
||||||
for (int i = 0; i < entityCount; i++)
|
if (remove)
|
||||||
{
|
{
|
||||||
bool remove = message.ReadBoolean();
|
ushort entityId = message.ReadUInt16();
|
||||||
|
|
||||||
if (remove)
|
var entity = FindEntityByID(entityId);
|
||||||
|
if (entity != null)
|
||||||
{
|
{
|
||||||
ushort entityId = message.ReadUInt16();
|
entity.Remove();
|
||||||
|
}
|
||||||
var entity = Entity.FindEntityByID(entityId);
|
}
|
||||||
if (entity != null && NetIdUtils.IdMoreRecent((UInt16)(ID + i), NetStateID))
|
else
|
||||||
{
|
{
|
||||||
entity.Remove();
|
switch (message.ReadByte())
|
||||||
}
|
{
|
||||||
}
|
case (byte)SpawnableType.Item:
|
||||||
else
|
Item.ReadSpawnData(message, true);
|
||||||
{
|
break;
|
||||||
switch (message.ReadByte())
|
case (byte)SpawnableType.Character:
|
||||||
{
|
Character.ReadSpawnData(message, true);
|
||||||
case (byte)SpawnableType.Item:
|
break;
|
||||||
Item.ReadSpawnData(message, NetIdUtils.IdMoreRecent((UInt16)(ID + i), NetStateID));
|
default:
|
||||||
break;
|
DebugConsole.ThrowError("Received invalid entity spawn message (unknown spawnable type)");
|
||||||
case (byte)SpawnableType.Character:
|
break;
|
||||||
Character.ReadSpawnData(message, NetIdUtils.IdMoreRecent((UInt16)(ID + i), NetStateID));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
DebugConsole.ThrowError("Received invalid entity spawn message (unknown spawnable type)");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NetStateID = Math.Max((UInt16)(ID + entityCount - 1), NetStateID);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void Clear()
|
|
||||||
{
|
|
||||||
NetStateID = 0;
|
|
||||||
|
|
||||||
spawnQueue.Clear();
|
|
||||||
removeQueue.Clear();
|
|
||||||
spawnHistory.Clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,8 @@
|
|||||||
using Lidgren.Network;
|
using Lidgren.Network;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using FarseerPhysics;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Barotrauma.Items.Components;
|
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
|
||||||
namespace Barotrauma.Networking
|
namespace Barotrauma.Networking
|
||||||
@@ -635,8 +632,7 @@ namespace Barotrauma.Networking
|
|||||||
//enable spectate button in case we fail to start the round now
|
//enable spectate button in case we fail to start the round now
|
||||||
//(for example, due to a missing sub file or an error)
|
//(for example, due to a missing sub file or an error)
|
||||||
GameMain.NetLobbyScreen.ShowSpectateButton();
|
GameMain.NetLobbyScreen.ShowSpectateButton();
|
||||||
|
|
||||||
Entity.Spawner.Clear();
|
|
||||||
entityEventManager.Clear();
|
entityEventManager.Clear();
|
||||||
LastSentEntityEventID = 0;
|
LastSentEntityEventID = 0;
|
||||||
|
|
||||||
@@ -921,10 +917,6 @@ namespace Barotrauma.Networking
|
|||||||
case ServerNetObject.CHAT_MESSAGE:
|
case ServerNetObject.CHAT_MESSAGE:
|
||||||
ChatMessage.ClientRead(inc);
|
ChatMessage.ClientRead(inc);
|
||||||
break;
|
break;
|
||||||
case ServerNetObject.ENTITY_SPAWN:
|
|
||||||
Item.Spawner.ClientRead(objHeader, inc, sendingTime);
|
|
||||||
inc.ReadPadBits();
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
DebugConsole.ThrowError("Error while reading update from server (unknown object header \""+objHeader+"\"!)");
|
DebugConsole.ThrowError("Error while reading update from server (unknown object header \""+objHeader+"\"!)");
|
||||||
break;
|
break;
|
||||||
@@ -959,7 +951,6 @@ 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(Entity.Spawner.NetStateID);
|
|
||||||
outmsg.Write(entityEventManager.LastReceivedID);
|
outmsg.Write(entityEventManager.LastReceivedID);
|
||||||
|
|
||||||
chatMsgQueue.RemoveAll(cMsg => !NetIdUtils.IdMoreRecent(cMsg.NetStateID, lastSentChatMsgID));
|
chatMsgQueue.RemoveAll(cMsg => !NetIdUtils.IdMoreRecent(cMsg.NetStateID, lastSentChatMsgID));
|
||||||
|
|||||||
@@ -680,11 +680,9 @@ namespace Barotrauma.Networking
|
|||||||
//TODO: might want to use a clever class for this
|
//TODO: might want to use a clever class for this
|
||||||
|
|
||||||
UInt16 lastRecvChatMsgID = inc.ReadUInt16();
|
UInt16 lastRecvChatMsgID = inc.ReadUInt16();
|
||||||
UInt16 lastRecvEntitySpawnID = inc.ReadUInt16();
|
|
||||||
UInt16 lastRecvEntityEventID = inc.ReadUInt16();
|
UInt16 lastRecvEntityEventID = inc.ReadUInt16();
|
||||||
|
|
||||||
//last msgs we've created/sent, the client IDs should never be higher than these
|
//last msgs we've created/sent, the client IDs should never be higher than these
|
||||||
UInt16 lastEntitySpawnID = Entity.Spawner.NetStateID;
|
|
||||||
UInt16 lastEntityEventID = entityEventManager.Events.Count == 0 ? (UInt16)0 : entityEventManager.Events.Last().ID;
|
UInt16 lastEntityEventID = entityEventManager.Events.Count == 0 ? (UInt16)0 : entityEventManager.Events.Last().ID;
|
||||||
|
|
||||||
if (c.NeedsMidRoundSync)
|
if (c.NeedsMidRoundSync)
|
||||||
@@ -705,20 +703,14 @@ namespace Barotrauma.Networking
|
|||||||
//client thinks they've received a msg we haven't sent yet (corrupted packet, msg read/written incorrectly?)
|
//client thinks they've received a msg we haven't sent yet (corrupted packet, msg read/written incorrectly?)
|
||||||
if (NetIdUtils.IdMoreRecent(lastRecvChatMsgID, c.lastChatMsgQueueID))
|
if (NetIdUtils.IdMoreRecent(lastRecvChatMsgID, c.lastChatMsgQueueID))
|
||||||
DebugConsole.ThrowError("client.lastRecvChatMsgID > lastChatMsgQueueID");
|
DebugConsole.ThrowError("client.lastRecvChatMsgID > lastChatMsgQueueID");
|
||||||
|
|
||||||
if (lastRecvEntitySpawnID > lastEntitySpawnID)
|
|
||||||
DebugConsole.ThrowError("client.lastRecvEntitySpawnID > lastEntitySpawnID");
|
|
||||||
|
|
||||||
if (lastRecvEntityEventID > lastEntityEventID)
|
if (lastRecvEntityEventID > lastEntityEventID)
|
||||||
DebugConsole.ThrowError("client.lastRecvEntityEventID > lastEntityEventID");
|
DebugConsole.ThrowError("client.lastRecvEntityEventID > lastEntityEventID");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (NetIdUtils.IdMoreRecent(lastRecvChatMsgID, c.lastRecvChatMsgID)) c.lastRecvChatMsgID = lastRecvChatMsgID;
|
if (NetIdUtils.IdMoreRecent(lastRecvChatMsgID, c.lastRecvChatMsgID)) c.lastRecvChatMsgID = lastRecvChatMsgID;
|
||||||
if (NetIdUtils.IdMoreRecent(c.lastRecvChatMsgID, c.lastChatMsgQueueID)) c.lastRecvChatMsgID = c.lastChatMsgQueueID;
|
if (NetIdUtils.IdMoreRecent(c.lastRecvChatMsgID, c.lastChatMsgQueueID)) c.lastRecvChatMsgID = c.lastChatMsgQueueID;
|
||||||
|
|
||||||
if (NetIdUtils.IdMoreRecent(lastRecvEntitySpawnID, c.lastRecvEntitySpawnID)) c.lastRecvEntitySpawnID = lastRecvEntitySpawnID;
|
|
||||||
if (NetIdUtils.IdMoreRecent(c.lastRecvEntitySpawnID, lastEntitySpawnID)) c.lastRecvEntitySpawnID = lastEntitySpawnID;
|
|
||||||
|
|
||||||
if (NetIdUtils.IdMoreRecent(lastRecvEntityEventID, c.lastRecvEntityEventID)) c.lastRecvEntityEventID = lastRecvEntityEventID;
|
if (NetIdUtils.IdMoreRecent(lastRecvEntityEventID, c.lastRecvEntityEventID)) c.lastRecvEntityEventID = lastRecvEntityEventID;
|
||||||
if (NetIdUtils.IdMoreRecent(c.lastRecvEntityEventID, lastEntityEventID)) c.lastRecvEntityEventID = lastEntityEventID;
|
if (NetIdUtils.IdMoreRecent(c.lastRecvEntityEventID, lastEntityEventID)) c.lastRecvEntityEventID = lastEntityEventID;
|
||||||
|
|
||||||
@@ -839,14 +831,7 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
cMsg.ServerWrite(outmsg, c);
|
cMsg.ServerWrite(outmsg, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Item.Spawner.NetStateID > c.lastRecvEntitySpawnID)
|
|
||||||
{
|
|
||||||
outmsg.Write((byte)ServerNetObject.ENTITY_SPAWN);
|
|
||||||
Item.Spawner.ServerWrite(outmsg, c);
|
|
||||||
outmsg.WritePadBits();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (Character character in Character.CharacterList)
|
foreach (Character character in Character.CharacterList)
|
||||||
{
|
{
|
||||||
if (!character.Enabled) continue;
|
if (!character.Enabled) continue;
|
||||||
@@ -1054,8 +1039,7 @@ namespace Barotrauma.Networking
|
|||||||
private IEnumerable<object> StartGame(Submarine selectedSub, Submarine selectedShuttle, GameModePreset selectedMode)
|
private IEnumerable<object> StartGame(Submarine selectedSub, Submarine selectedShuttle, GameModePreset selectedMode)
|
||||||
{
|
{
|
||||||
initiatedStartGame = true;
|
initiatedStartGame = true;
|
||||||
|
|
||||||
Item.Spawner.Clear();
|
|
||||||
entityEventManager.Clear();
|
entityEventManager.Clear();
|
||||||
|
|
||||||
GameMain.NetLobbyScreen.StartButton.Enabled = false;
|
GameMain.NetLobbyScreen.StartButton.Enabled = false;
|
||||||
@@ -1103,9 +1087,7 @@ namespace Barotrauma.Networking
|
|||||||
foreach (Client client in teamClients)
|
foreach (Client client in teamClients)
|
||||||
{
|
{
|
||||||
client.NeedsMidRoundSync = false;
|
client.NeedsMidRoundSync = false;
|
||||||
|
|
||||||
client.lastRecvEntitySpawnID = 0;
|
|
||||||
|
|
||||||
client.entityEventLastSent.Clear();
|
client.entityEventLastSent.Clear();
|
||||||
client.lastSentEntityEventID = 0;
|
client.lastSentEntityEventID = 0;
|
||||||
client.lastRecvEntityEventID = 0;
|
client.lastRecvEntityEventID = 0;
|
||||||
@@ -1149,13 +1131,7 @@ namespace Barotrauma.Networking
|
|||||||
GameMain.GameSession.CrewManager.characters.Add(myCharacter);
|
GameMain.GameSession.CrewManager.characters.Add(myCharacter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Character c in GameMain.GameSession.CrewManager.characters)
|
|
||||||
{
|
|
||||||
Entity.Spawner.AddToSpawnedList(c);
|
|
||||||
Entity.Spawner.AddToSpawnedList(c.SpawnItems);
|
|
||||||
}
|
|
||||||
|
|
||||||
TraitorManager = null;
|
TraitorManager = null;
|
||||||
if (TraitorsEnabled == YesNoMaybe.Yes ||
|
if (TraitorsEnabled == YesNoMaybe.Yes ||
|
||||||
(TraitorsEnabled == YesNoMaybe.Maybe && Rand.Range(0.0f, 1.0f) < 0.5f))
|
(TraitorsEnabled == YesNoMaybe.Maybe && Rand.Range(0.0f, 1.0f) < 0.5f))
|
||||||
@@ -1268,8 +1244,7 @@ namespace Barotrauma.Networking
|
|||||||
myCharacter = null;
|
myCharacter = null;
|
||||||
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
|
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
|
||||||
GameMain.LightManager.LosEnabled = false;
|
GameMain.LightManager.LosEnabled = false;
|
||||||
|
|
||||||
Item.Spawner.Clear();
|
|
||||||
entityEventManager.Clear();
|
entityEventManager.Clear();
|
||||||
foreach (Client c in connectedClients)
|
foreach (Client c in connectedClients)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -54,9 +54,7 @@ namespace Barotrauma.Networking
|
|||||||
VOTE,
|
VOTE,
|
||||||
ENTITY_POSITION,
|
ENTITY_POSITION,
|
||||||
ENTITY_EVENT,
|
ENTITY_EVENT,
|
||||||
ENTITY_EVENT_INITIAL,
|
ENTITY_EVENT_INITIAL
|
||||||
|
|
||||||
ENTITY_SPAWN
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum VoteType
|
enum VoteType
|
||||||
|
|||||||
@@ -428,7 +428,6 @@ namespace Barotrauma.Networking
|
|||||||
bool myCharacter = i >= clients.Count;
|
bool myCharacter = i >= clients.Count;
|
||||||
|
|
||||||
var character = Character.Create(characterInfos[i], shuttleSpawnPoints[i].WorldPosition, !myCharacter, false);
|
var character = Character.Create(characterInfos[i], shuttleSpawnPoints[i].WorldPosition, !myCharacter, false);
|
||||||
Entity.Spawner.AddToSpawnedList(character);
|
|
||||||
|
|
||||||
character.TeamID = 1;
|
character.TeamID = 1;
|
||||||
|
|
||||||
@@ -448,29 +447,25 @@ namespace Barotrauma.Networking
|
|||||||
if (divingSuitPrefab != null && oxyPrefab != null)
|
if (divingSuitPrefab != null && oxyPrefab != null)
|
||||||
{
|
{
|
||||||
var divingSuit = new Item(divingSuitPrefab, pos, respawnShuttle);
|
var divingSuit = new Item(divingSuitPrefab, pos, respawnShuttle);
|
||||||
|
Entity.Spawner.CreateNetworkEvent(divingSuit, false);
|
||||||
|
|
||||||
var oxyTank = new Item(oxyPrefab, pos, respawnShuttle);
|
var oxyTank = new Item(oxyPrefab, pos, respawnShuttle);
|
||||||
|
Entity.Spawner.CreateNetworkEvent(oxyTank, false);
|
||||||
divingSuit.Combine(oxyTank);
|
divingSuit.Combine(oxyTank);
|
||||||
|
|
||||||
spawnedItems.Add(divingSuit);
|
|
||||||
spawnedItems.Add(oxyTank);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scooterPrefab != null && batteryPrefab != null)
|
if (scooterPrefab != null && batteryPrefab != null)
|
||||||
{
|
{
|
||||||
var scooter = new Item(scooterPrefab, pos, respawnShuttle);
|
var scooter = new Item(scooterPrefab, pos, respawnShuttle);
|
||||||
|
Entity.Spawner.CreateNetworkEvent(scooter, false);
|
||||||
|
|
||||||
var battery = new Item(batteryPrefab, pos, respawnShuttle);
|
var battery = new Item(batteryPrefab, pos, respawnShuttle);
|
||||||
|
Entity.Spawner.CreateNetworkEvent(battery, false);
|
||||||
|
|
||||||
scooter.Combine(battery);
|
scooter.Combine(battery);
|
||||||
|
|
||||||
spawnedItems.Add(scooter);
|
|
||||||
spawnedItems.Add(battery);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
character.GiveJobItems(mainSubSpawnPoints[i]);
|
character.GiveJobItems(mainSubSpawnPoints[i]);
|
||||||
Entity.Spawner.AddToSpawnedList(character.SpawnItems);
|
|
||||||
Entity.Spawner.AddToSpawnedList(spawnedItems);
|
|
||||||
|
|
||||||
GameMain.GameSession.CrewManager.characters.Add(character);
|
GameMain.GameSession.CrewManager.characters.Add(character);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user