diff --git a/Subsurface/Source/Items/Components/ItemComponent.cs b/Subsurface/Source/Items/Components/ItemComponent.cs index d3ba798bf..5564b0809 100644 --- a/Subsurface/Source/Items/Components/ItemComponent.cs +++ b/Subsurface/Source/Items/Components/ItemComponent.cs @@ -73,13 +73,7 @@ namespace Barotrauma.Items.Components public ItemComponent Parent; private string msg; - - protected UInt32 netStateID; - public UInt32 NetStateID - { - get { return netStateID; } - } - + [HasDefaultValue(0.0f, false)] public float PickingTime { diff --git a/Subsurface/Source/Items/Item.cs b/Subsurface/Source/Items/Item.cs index fdd50dfbe..5938b56c1 100644 --- a/Subsurface/Source/Items/Item.cs +++ b/Subsurface/Source/Items/Item.cs @@ -64,13 +64,7 @@ namespace Barotrauma //a dictionary containing lists of the status effects in all the components of the item private Dictionary> statusEffectLists; - - private UInt32 netStateID; - public UInt32 NetStateID - { - get { return netStateID; } - } - + public readonly Dictionary properties; public Dictionary ObjectProperties { diff --git a/Subsurface/Source/Map/Structure.cs b/Subsurface/Source/Map/Structure.cs index 845705ebb..0c9c10b53 100644 --- a/Subsurface/Source/Map/Structure.cs +++ b/Subsurface/Source/Map/Structure.cs @@ -63,12 +63,6 @@ namespace Barotrauma bool isHorizontal; - private UInt32 netStateID; - public UInt32 NetStateID - { - get { return netStateID; } - } - public SpriteEffects SpriteEffects = SpriteEffects.None; public bool resizeHorizontal diff --git a/Subsurface/Source/Map/Submarine.cs b/Subsurface/Source/Map/Submarine.cs index 72db303b5..f7c6a695b 100644 --- a/Subsurface/Source/Map/Submarine.cs +++ b/Subsurface/Source/Map/Submarine.cs @@ -135,16 +135,7 @@ namespace Barotrauma return hash; } } - - private UInt32 netStateID; - public UInt32 NetStateID - { - get - { - return netStateID; - } - } - + public static List Loaded { get { return loaded; } diff --git a/Subsurface/Source/Networking/Client.cs b/Subsurface/Source/Networking/Client.cs index 575cd448a..52bd7d852 100644 --- a/Subsurface/Source/Networking/Client.cs +++ b/Subsurface/Source/Networking/Client.cs @@ -36,10 +36,10 @@ namespace Barotrauma.Networking public UInt16 lastSentChatMsgID = 0; //last msg this client said public UInt16 lastRecvChatMsgID = 0; //last msg this client knows about - public UInt32 lastSentEntityEventID = 0; - public UInt32 lastRecvEntityEventID = 0; + public UInt16 lastSentEntityEventID = 0; + public UInt16 lastRecvEntityEventID = 0; - public UInt32 lastRecvEntitySpawnID = 0; + public UInt16 lastRecvEntitySpawnID = 0; public List chatMsgQueue = new List(); public UInt16 lastChatMsgQueueID; @@ -49,13 +49,13 @@ namespace Barotrauma.Networking public bool NeedsMidRoundSync; //how many unique events the client missed before joining the server - public UInt32 UnreceivedEntityEventCount; + public UInt16 UnreceivedEntityEventCount; private List kickVoters; //when was a specific entity event last sent to the client // key = event id, value = NetTime.Now when sending - public Dictionary entityEventLastSent; + public Dictionary entityEventLastSent; public bool ReadyToStart; @@ -104,7 +104,7 @@ namespace Barotrauma.Networking jobPreferences = new List(JobPrefab.List.GetRange(0, 3)); - entityEventLastSent = new Dictionary(); + entityEventLastSent = new Dictionary(); } public static bool IsValidName(string name) diff --git a/Subsurface/Source/Networking/EntitySpawner.cs b/Subsurface/Source/Networking/EntitySpawner.cs index 5b6ba38fd..9dbf7c115 100644 --- a/Subsurface/Source/Networking/EntitySpawner.cs +++ b/Subsurface/Source/Networking/EntitySpawner.cs @@ -10,7 +10,7 @@ namespace Barotrauma { private enum SpawnableType { Item, Character }; - public UInt32 NetStateID + public UInt16 NetStateID { get; private set; @@ -138,7 +138,7 @@ namespace Barotrauma spawnHistory.Add(new SpawnOrRemove(entity, true)); entity.Remove(); - NetStateID = (UInt32)spawnHistory.Count; + NetStateID = (UInt16)spawnHistory.Count; } } @@ -149,7 +149,7 @@ namespace Barotrauma spawnHistory.Add(new SpawnOrRemove(entity, false)); - NetStateID = (UInt32)spawnHistory.Count; + NetStateID = (UInt16)spawnHistory.Count; } public void AddToSpawnedList(IEnumerable entities) @@ -160,7 +160,7 @@ namespace Barotrauma foreach (Entity entity in entities) { spawnHistory.Add(new SpawnOrRemove(entity, false)); - NetStateID = (UInt32)spawnHistory.Count; + NetStateID = (UInt16)spawnHistory.Count; } } @@ -171,7 +171,7 @@ namespace Barotrauma //skip items that the client already knows about List entities = spawnHistory.Skip((int)client.lastRecvEntitySpawnID).ToList(); - message.Write((UInt32)spawnHistory.Count); + message.Write((UInt16)spawnHistory.Count); message.Write((UInt16)entities.Count); for (int i = 0; i < entities.Count; i++) @@ -202,7 +202,7 @@ namespace Barotrauma { if (GameMain.Server != null) return; - UInt32 ID = message.ReadUInt32(); + UInt16 ID = message.ReadUInt16(); var entityCount = message.ReadUInt16(); for (int i = 0; i < entityCount; i++) @@ -214,7 +214,7 @@ namespace Barotrauma ushort entityId = message.ReadUInt16(); var entity = Entity.FindEntityByID(entityId); - if (entity == null || ID - entityCount + i < NetStateID) continue; //already removed + if (entity == null || NetIdUtils.IdMoreRecent(NetStateID,(UInt16)(ID - entityCount + i))) continue; //already removed entity.Remove(); } @@ -223,10 +223,10 @@ namespace Barotrauma switch (message.ReadByte()) { case (byte)SpawnableType.Item: - Item.ReadSpawnData(message, ID - entityCount + i >= NetStateID); + Item.ReadSpawnData(message, NetIdUtils.IdMoreRecent((UInt16)(ID - entityCount + i),(UInt16)(NetStateID+1))); break; case (byte)SpawnableType.Character: - Character.ReadSpawnData(message, ID - entityCount + i >= NetStateID); + Character.ReadSpawnData(message, NetIdUtils.IdMoreRecent((UInt16)(ID - entityCount + i), (UInt16)(NetStateID + 1))); break; default: DebugConsole.ThrowError("Received invalid entity spawn message (unknown spawnable type)"); diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs index d72ba0ebe..d9163370a 100644 --- a/Subsurface/Source/Networking/GameClient.cs +++ b/Subsurface/Source/Networking/GameClient.cs @@ -39,7 +39,7 @@ namespace Barotrauma.Networking private UInt16 lastQueueChatMsgID = 0; //last message added to the queue private List chatMsgQueue = new List(); - public UInt32 LastSentEntityEventID; + public UInt16 LastSentEntityEventID; private ClientEntityEventManager entityEventManager; @@ -875,7 +875,7 @@ namespace Barotrauma.Networking { case ServerNetObject.SYNC_IDS: lastSentChatMsgID = inc.ReadUInt16(); - LastSentEntityEventID = inc.ReadUInt32(); + LastSentEntityEventID = inc.ReadUInt16(); break; case ServerNetObject.ENTITY_POSITION: UInt16 id = inc.ReadUInt16(); diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index f9b5ac1e7..fd5c6840d 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -634,17 +634,13 @@ namespace Barotrauma.Networking //TODO: might want to use a clever class for this UInt16 lastRecvChatMsgID = inc.ReadUInt16(); - UInt32 lastRecvEntitySpawnID = inc.ReadUInt32(); - UInt32 lastRecvEntityEventID = inc.ReadUInt32(); + UInt16 lastRecvEntitySpawnID = inc.ReadUInt16(); + UInt16 lastRecvEntityEventID = inc.ReadUInt16(); //last msgs we've created/sent, the client IDs should never be higher than these - UInt32 lastEntitySpawnID = Entity.Spawner.NetStateID; - UInt32 lastEntityEventID = entityEventManager.Events.Count == 0 ? 0 : entityEventManager.Events.Last().ID; - - Debug.Assert( - c.lastRecvEntityEventID.GetType() == typeof(UInt32), - "Event ID type changed, you may need to reimplement MidRound syncing logic to handle ID wraparound"); - + UInt16 lastEntitySpawnID = Entity.Spawner.NetStateID; + UInt16 lastEntityEventID = entityEventManager.Events.Count == 0 ? (UInt16)0 : entityEventManager.Events.Last().ID; + if (c.NeedsMidRoundSync) { //received all the old events -> client in sync, we can switch to normal behavior @@ -655,7 +651,7 @@ namespace Barotrauma.Networking } else { - lastEntityEventID = (uint)c.UnreceivedEntityEventCount - 1; + lastEntityEventID = (UInt16)(c.UnreceivedEntityEventCount - 1); } } @@ -672,8 +668,12 @@ namespace Barotrauma.Networking #endif c.lastRecvChatMsgID = NetIdUtils.Clamp(c.lastRecvChatMsgID, lastRecvChatMsgID, c.lastChatMsgQueueID); - c.lastRecvEntitySpawnID = Math.Min(Math.Max(c.lastRecvEntitySpawnID, lastRecvEntitySpawnID), lastEntitySpawnID); - c.lastRecvEntityEventID = Math.Min(Math.Max(c.lastRecvEntityEventID, lastRecvEntityEventID), lastEntityEventID); + + 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(c.lastRecvEntityEventID, lastEntityEventID)) c.lastRecvEntityEventID = lastEntityEventID; break; case ClientNetObject.CHAT_MESSAGE: diff --git a/Subsurface/Source/Networking/NetEntityEvent/ClientEntityEventManager.cs b/Subsurface/Source/Networking/NetEntityEvent/ClientEntityEventManager.cs index f3866e6ca..8d78081b3 100644 --- a/Subsurface/Source/Networking/NetEntityEvent/ClientEntityEventManager.cs +++ b/Subsurface/Source/Networking/NetEntityEvent/ClientEntityEventManager.cs @@ -11,25 +11,25 @@ namespace Barotrauma.Networking { private List events; - private UInt32 ID; + private UInt16 ID; private GameClient thisClient; //when was a specific entity event last sent to the client // key = event id, value = NetTime.Now when sending - public Dictionary eventLastSent; + public Dictionary eventLastSent; - public UInt32 LastReceivedID + public UInt16 LastReceivedID { get { return lastReceivedID; } } - private UInt32 lastReceivedID; + private UInt16 lastReceivedID; public ClientEntityEventManager(GameClient client) { events = new List(); - eventLastSent = new Dictionary(); + eventLastSent = new Dictionary(); thisClient = client; } @@ -61,7 +61,7 @@ namespace Barotrauma.Networking //find the index of the first event the server hasn't received int startIndex = events.Count; while (startIndex > 0 && - events[startIndex-1].ID > thisClient.LastSentEntityEventID) + NetIdUtils.IdMoreRecent(events[startIndex-1].ID,thisClient.LastSentEntityEventID)) { startIndex--; } @@ -103,21 +103,21 @@ namespace Barotrauma.Networking /// public void Read(ServerNetObject type, NetIncomingMessage msg, float sendingTime) { - UInt32 unreceivedEntityEventCount = 0; - UInt32 firstNewID = 0; + UInt16 unreceivedEntityEventCount = 0; + UInt16 firstNewID = 0; if (type == ServerNetObject.ENTITY_EVENT_INITIAL) { - unreceivedEntityEventCount = msg.ReadUInt32(); - firstNewID = msg.ReadUInt32(); + unreceivedEntityEventCount = msg.ReadUInt16(); + firstNewID = msg.ReadUInt16(); } - UInt32 firstEventID = msg.ReadUInt32(); + UInt16 firstEventID = msg.ReadUInt16(); int eventCount = msg.ReadByte(); for (int i = 0; i < eventCount; i++) { - UInt32 thisEventID = firstEventID + (UInt32)i; + UInt16 thisEventID = (UInt16)(firstEventID + (UInt16)i); UInt16 entityID = msg.ReadUInt16(); byte msgLength = msg.ReadByte(); @@ -163,7 +163,7 @@ namespace Barotrauma.Networking if (lastReceivedID == unreceivedEntityEventCount - 1 || unreceivedEntityEventCount == 0) { - lastReceivedID = firstNewID - 1; + lastReceivedID = (UInt16)(firstNewID - 1); } } } diff --git a/Subsurface/Source/Networking/NetEntityEvent/NetEntityEvent.cs b/Subsurface/Source/Networking/NetEntityEvent/NetEntityEvent.cs index c89abf9f0..48dadb30c 100644 --- a/Subsurface/Source/Networking/NetEntityEvent/NetEntityEvent.cs +++ b/Subsurface/Source/Networking/NetEntityEvent/NetEntityEvent.cs @@ -20,13 +20,13 @@ namespace Barotrauma.Networking } public readonly Entity Entity; - public readonly UInt32 ID; + public readonly UInt16 ID; //arbitrary extra data that will be passed to the Write method of the serializable entity //(the index of an itemcomponent for example) protected object[] Data; - protected NetEntityEvent(INetSerializable entity, UInt32 id) + protected NetEntityEvent(INetSerializable entity, UInt16 id) { this.ID = id; this.Entity = entity as Entity; @@ -73,7 +73,7 @@ namespace Barotrauma.Networking get { return createTime; } } - public ServerEntityEvent(IServerSerializable entity, UInt32 id) + public ServerEntityEvent(IServerSerializable entity, UInt16 id) : base(entity, id) { serializable = entity; @@ -93,7 +93,7 @@ namespace Barotrauma.Networking public UInt16 CharacterStateID; - public ClientEntityEvent(IClientSerializable entity, UInt32 id) + public ClientEntityEvent(IClientSerializable entity, UInt16 id) : base(entity, id) { serializable = entity; diff --git a/Subsurface/Source/Networking/NetEntityEvent/NetEntityEventManager.cs b/Subsurface/Source/Networking/NetEntityEvent/NetEntityEventManager.cs index 28d9ffe87..2bb2b91f9 100644 --- a/Subsurface/Source/Networking/NetEntityEvent/NetEntityEventManager.cs +++ b/Subsurface/Source/Networking/NetEntityEvent/NetEntityEventManager.cs @@ -13,7 +13,7 @@ namespace Barotrauma.Networking public const int MaxEventBufferLength = 1024; public const int MaxEventsPerWrite = 64; - //public UInt32 LastReceivedEntityEventID + //public UInt16 LastReceivedEntityEventID //{ // get { return lastReceivedEntityEventID; } //} diff --git a/Subsurface/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs b/Subsurface/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs index e29441edc..7643f9cda 100644 --- a/Subsurface/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs +++ b/Subsurface/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs @@ -15,7 +15,7 @@ namespace Barotrauma.Networking //used for syncing clients who join mid-round private List uniqueEvents; - private UInt32 lastSentToAll; + private UInt16 lastSentToAll; public List Events { @@ -49,7 +49,7 @@ namespace Barotrauma.Networking private List bufferedEvents; - private UInt32 ID; + private UInt16 ID; private GameServer server; @@ -127,14 +127,14 @@ namespace Barotrauma.Networking if (clients.Count > 0) { lastSentToAll = clients[0].lastRecvEntityEventID; - clients.ForEach(c => { if (c.inGame) lastSentToAll = Math.Min(lastSentToAll, c.lastRecvEntityEventID); }); + clients.ForEach(c => { if (c.inGame && NetIdUtils.IdMoreRecent(lastSentToAll,c.lastRecvEntityEventID)) lastSentToAll = c.lastRecvEntityEventID; }); ServerEntityEvent firstEventToResend = events.Find(e => e.ID == (lastSentToAll + 1)); if (firstEventToResend != null && (Timing.TotalTime-firstEventToResend.CreateTime)>10.0f) { //it's been 10 seconds since this event was created //kick everyone that hasn't received it yet, this is way too old - List toKick = clients.FindAll(c => c.inGame && c.lastRecvEntityEventID <= lastSentToAll); + List toKick = clients.FindAll(c => c.inGame && NetIdUtils.IdMoreRecent((UInt16)(lastSentToAll+1),c.lastRecvEntityEventID)); if (toKick!=null) toKick.ForEach(c => GameMain.Server.DisconnectClient(c,"","You have been disconnected because of excessive desync")); } } @@ -247,7 +247,7 @@ namespace Barotrauma.Networking { if (uniqueEvents.Count > 0) { - client.UnreceivedEntityEventCount = (UInt32)uniqueEvents.Count; + client.UnreceivedEntityEventCount = (UInt16)uniqueEvents.Count; client.NeedsMidRoundSync = true; } else @@ -262,12 +262,12 @@ namespace Barotrauma.Networking /// public void Read(NetIncomingMessage msg, Client sender = null) { - UInt32 firstEventID = msg.ReadUInt32(); + UInt16 firstEventID = msg.ReadUInt16(); int eventCount = msg.ReadByte(); for (int i = 0; i < eventCount; i++) { - UInt32 thisEventID = firstEventID + (UInt32)i; + UInt16 thisEventID = (UInt16)(firstEventID + (UInt16)i); UInt16 entityID = msg.ReadUInt16(); byte msgLength = msg.ReadByte();