diff --git a/Subsurface/Barotrauma.csproj b/Subsurface/Barotrauma.csproj
index 149dcc032..aa61a1833 100644
--- a/Subsurface/Barotrauma.csproj
+++ b/Subsurface/Barotrauma.csproj
@@ -163,6 +163,7 @@
+
diff --git a/Subsurface/Source/Networking/ChatMessage.cs b/Subsurface/Source/Networking/ChatMessage.cs
index a04de33b4..545ed21c9 100644
--- a/Subsurface/Source/Networking/ChatMessage.cs
+++ b/Subsurface/Source/Networking/ChatMessage.cs
@@ -47,9 +47,9 @@ namespace Barotrauma.Networking
private set;
}
- public static UInt32 LastID = 0;
+ public static UInt16 LastID = 0;
- public UInt32 NetStateID
+ public UInt16 NetStateID
{
get;
set;
@@ -138,9 +138,9 @@ namespace Barotrauma.Networking
static public void ServerRead(NetIncomingMessage msg, Client c)
{
- UInt32 ID = msg.ReadUInt32();
+ UInt16 ID = msg.ReadUInt16();
string txt = msg.ReadString();
- if (c.lastSentChatMsgID < ID)
+ if (NetIdUtils.IdMoreRecent(ID, c.lastSentChatMsgID))
{
//this chat message is new to the server
GameMain.Server.SendChatMessage(txt, null, c);
@@ -169,7 +169,7 @@ namespace Barotrauma.Networking
static public void ClientRead(NetIncomingMessage msg)
{
- UInt32 ID = msg.ReadUInt32();
+ UInt16 ID = msg.ReadUInt16();
ChatMessageType type = (ChatMessageType)msg.ReadByte();
string txt = msg.ReadString();
@@ -189,7 +189,7 @@ namespace Barotrauma.Networking
senderName = msg.ReadString();
}
- if (ID > LastID)
+ if (NetIdUtils.IdMoreRecent(ID, LastID))
{
GameMain.Client.AddChatMessage(txt, type, senderName, senderCharacter);
LastID = ID;
diff --git a/Subsurface/Source/Networking/Client.cs b/Subsurface/Source/Networking/Client.cs
index ea148d322..7725d8b9f 100644
--- a/Subsurface/Source/Networking/Client.cs
+++ b/Subsurface/Source/Networking/Client.cs
@@ -30,11 +30,11 @@ namespace Barotrauma.Networking
public NetConnection Connection { get; set; }
public string version;
public bool inGame;
- public UInt32 lastRecvGeneralUpdate = 0;
+ public UInt16 lastRecvGeneralUpdate = 0;
public bool hasLobbyData = false;
- public UInt32 lastSentChatMsgID = 0; //last msg this client said
- public UInt32 lastRecvChatMsgID = 0; //last msg this client knows about
+ 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;
@@ -42,7 +42,7 @@ namespace Barotrauma.Networking
public UInt32 lastRecvEntitySpawnID = 0;
public List chatMsgQueue = new List();
- public UInt32 lastChatMsgQueueID;
+ public UInt16 lastChatMsgQueueID;
public float ChatSpamSpeed;
public float ChatSpamTimer;
public int ChatSpamCount;
diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs
index 4aafe6211..1c98d5221 100644
--- a/Subsurface/Source/Networking/GameClient.cs
+++ b/Subsurface/Source/Networking/GameClient.cs
@@ -35,8 +35,8 @@ namespace Barotrauma.Networking
private int nonce;
private string saltedPw;
- private UInt32 lastSentChatMsgID = 0; //last message this client has successfully sent
- private UInt32 lastQueueChatMsgID = 0; //last message added to the queue
+ private UInt16 lastSentChatMsgID = 0; //last message this client has successfully sent
+ private UInt16 lastQueueChatMsgID = 0; //last message added to the queue
private List chatMsgQueue = new List();
public UInt32 LastSentEntityEventID;
@@ -729,13 +729,13 @@ namespace Barotrauma.Networking
if (lobbyUpdated)
{
- UInt32 updateID = inc.ReadUInt32();
+ UInt16 updateID = inc.ReadUInt16();
string serverName = inc.ReadString();
string serverText = inc.ReadString();
if (inc.ReadBoolean())
{
- ReadInitialUpdate(inc, updateID <= GameMain.NetLobbyScreen.LastUpdateID);
+ ReadInitialUpdate(inc, !NetIdUtils.IdMoreRecent(updateID,GameMain.NetLobbyScreen.LastUpdateID));
}
string selectSubName = inc.ReadString();
@@ -768,7 +768,7 @@ namespace Barotrauma.Networking
}
//ignore the message if we already a more up-to-date one
- if (updateID > GameMain.NetLobbyScreen.LastUpdateID)
+ if (NetIdUtils.IdMoreRecent(updateID, GameMain.NetLobbyScreen.LastUpdateID))
{
GameMain.NetLobbyScreen.LastUpdateID = updateID;
@@ -811,7 +811,7 @@ namespace Barotrauma.Networking
Voting.AllowModeVoting = allowModeVoting;
}
}
- lastSentChatMsgID = inc.ReadUInt32();
+ lastSentChatMsgID = inc.ReadUInt16();
break;
case ServerNetObject.CHAT_MESSAGE:
ChatMessage.ClientRead(inc);
@@ -833,7 +833,7 @@ namespace Barotrauma.Networking
switch (objHeader)
{
case ServerNetObject.SYNC_IDS:
- lastSentChatMsgID = inc.ReadUInt32();
+ lastSentChatMsgID = inc.ReadUInt16();
LastSentEntityEventID = inc.ReadUInt32();
break;
case ServerNetObject.ENTITY_POSITION:
@@ -878,11 +878,8 @@ namespace Barotrauma.Networking
outmsg.Write((byte)ClientNetObject.SYNC_IDS);
outmsg.Write(GameMain.NetLobbyScreen.LastUpdateID);
outmsg.Write(ChatMessage.LastID);
- ChatMessage removeMsg;
- while ((removeMsg=chatMsgQueue.Find(cMsg => cMsg.NetStateID <= lastSentChatMsgID)) != null)
- {
- chatMsgQueue.Remove(removeMsg);
- }
+
+ chatMsgQueue.RemoveAll(cMsg => !NetIdUtils.IdMoreRecent(cMsg.NetStateID, lastSentChatMsgID));
foreach (ChatMessage cMsg in chatMsgQueue)
{
@@ -903,11 +900,7 @@ namespace Barotrauma.Networking
outmsg.Write(Entity.Spawner.NetStateID);
outmsg.Write(entityEventManager.LastReceivedID);
- ChatMessage removeMsg;
- while ((removeMsg = chatMsgQueue.Find(cMsg => cMsg.NetStateID <= lastSentChatMsgID)) != null)
- {
- chatMsgQueue.Remove(removeMsg);
- }
+ chatMsgQueue.RemoveAll(cMsg => !NetIdUtils.IdMoreRecent(cMsg.NetStateID, lastSentChatMsgID));
foreach (ChatMessage cMsg in chatMsgQueue)
{
diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs
index 289d8b3be..0f7409c42 100644
--- a/Subsurface/Source/Networking/GameServer.cs
+++ b/Subsurface/Source/Networking/GameServer.cs
@@ -66,7 +66,7 @@ namespace Barotrauma.Networking
{
this.password = Encoding.UTF8.GetString(NetUtility.ComputeSHAHash(Encoding.UTF8.GetBytes(password)));
}
-
+
config = new NetPeerConfiguration("barotrauma");
netStats = new NetStats();
@@ -78,6 +78,8 @@ namespace Barotrauma.Networking
config.SimulatedMinimumLatency = 0.1f;
config.ConnectionTimeout = 60.0f;
+
+ NetIdUtils.Test();
#endif
config.Port = port;
Port = port;
@@ -622,8 +624,8 @@ namespace Barotrauma.Networking
{
case ClientNetObject.SYNC_IDS:
//TODO: might want to use a clever class for this
- c.lastRecvGeneralUpdate = Math.Min(Math.Max(c.lastRecvGeneralUpdate, inc.ReadUInt32()), GameMain.NetLobbyScreen.LastUpdateID);
- c.lastRecvChatMsgID = Math.Min(Math.Max(c.lastRecvChatMsgID, inc.ReadUInt32()), c.lastChatMsgQueueID);
+ c.lastRecvGeneralUpdate = NetIdUtils.Clamp(inc.ReadUInt16(), c.lastRecvGeneralUpdate, GameMain.NetLobbyScreen.LastUpdateID);
+ c.lastRecvChatMsgID = NetIdUtils.Clamp(inc.ReadUInt16(), c.lastRecvChatMsgID, c.lastChatMsgQueueID);
break;
case ClientNetObject.CHAT_MESSAGE:
ChatMessage.ServerRead(inc, c);
@@ -657,7 +659,7 @@ namespace Barotrauma.Networking
case ClientNetObject.SYNC_IDS:
//TODO: might want to use a clever class for this
- UInt32 lastRecvChatMsgID = inc.ReadUInt32();
+ UInt16 lastRecvChatMsgID = inc.ReadUInt16();
UInt32 lastRecvEntitySpawnID = inc.ReadUInt32();
UInt32 lastRecvEntityEventID = inc.ReadUInt32();
@@ -734,7 +736,7 @@ namespace Barotrauma.Networking
outmsg.Write(c.lastSentChatMsgID); //send this to client so they know which chat messages weren't received by the server
outmsg.Write(c.lastSentEntityEventID);
- c.chatMsgQueue.RemoveAll(cMsg => cMsg.NetStateID <= c.lastRecvChatMsgID);
+ c.chatMsgQueue.RemoveAll(cMsg => !NetIdUtils.IdMoreRecent(cMsg.NetStateID, c.lastRecvChatMsgID));
foreach (ChatMessage cMsg in c.chatMsgQueue)
{
cMsg.ServerWrite(outmsg, c);
@@ -797,8 +799,8 @@ namespace Barotrauma.Networking
outmsg.Write((byte)ServerPacketHeader.UPDATE_LOBBY);
outmsg.Write((byte)ServerNetObject.SYNC_IDS);
-
- if (c.lastRecvGeneralUpdate cMsg.NetStateID <= c.lastRecvChatMsgID);
+ c.chatMsgQueue.RemoveAll(cMsg => !NetIdUtils.IdMoreRecent(cMsg.NetStateID, c.lastRecvChatMsgID));
foreach (ChatMessage cMsg in c.chatMsgQueue)
{
cMsg.ServerWrite(outmsg, c);
@@ -1480,10 +1482,10 @@ namespace Barotrauma.Networking
modifiedMessage,
(ChatMessageType)type,
senderCharacter);
-
- chatMsg.NetStateID = client.chatMsgQueue.Count > 0 ?
- client.chatMsgQueue.Last().NetStateID + 1 :
- client.lastRecvChatMsgID+1;
+
+ chatMsg.NetStateID = client.chatMsgQueue.Count > 0 ?
+ (ushort)(client.chatMsgQueue.Last().NetStateID + 1) :
+ (ushort)(client.lastRecvChatMsgID + 1);
client.chatMsgQueue.Add(chatMsg);
client.lastChatMsgQueueID = chatMsg.NetStateID;
diff --git a/Subsurface/Source/Networking/NetIdUtils.cs b/Subsurface/Source/Networking/NetIdUtils.cs
new file mode 100644
index 000000000..7702e3006
--- /dev/null
+++ b/Subsurface/Source/Networking/NetIdUtils.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Barotrauma.Networking
+{
+ static class NetIdUtils
+ {
+ ///
+ /// Is newID more recent than oldID
+ ///
+ public static bool IdMoreRecent(ushort newID, ushort oldID)
+ {
+ uint id1 = newID;
+ uint id2 = oldID;
+
+ return
+ (id1 > id2) && (id1 - id2 <= ushort.MaxValue / 2)
+ ||
+ (id2 > id1) && (id2 - id1 > ushort.MaxValue / 2);
+ }
+
+ public static ushort Clamp(ushort id, ushort min, ushort max)
+ {
+ if (IdMoreRecent(min, max))
+ {
+ throw new ArgumentException("Min cannot be larger than max");
+ }
+
+ if (!IdMoreRecent(id, min))
+ {
+ return min;
+ }
+ else if (IdMoreRecent(id, max))
+ {
+ return max;
+ }
+
+ return id;
+ }
+
+#if DEBUG
+ public static void Test()
+ {
+ Debug.Assert(NetIdUtils.IdMoreRecent((ushort)2, (ushort)1));
+ Debug.Assert(NetIdUtils.IdMoreRecent((ushort)2, (ushort)(ushort.MaxValue - 5)));
+ Debug.Assert(!NetIdUtils.IdMoreRecent((ushort)ushort.MaxValue, (ushort)5));
+
+ Debug.Assert(Clamp((ushort)5, (ushort)1, (ushort)10) == 5);
+ Debug.Assert(Clamp((ushort)(ushort.MaxValue - 5), (ushort)(ushort.MaxValue - 2), (ushort)3) == (ushort)(ushort.MaxValue - 2));
+ }
+#endif
+ }
+}
diff --git a/Subsurface/Source/Screens/NetLobbyScreen.cs b/Subsurface/Source/Screens/NetLobbyScreen.cs
index 39d22fe11..67887f04b 100644
--- a/Subsurface/Source/Screens/NetLobbyScreen.cs
+++ b/Subsurface/Source/Screens/NetLobbyScreen.cs
@@ -52,9 +52,8 @@ namespace Barotrauma
public bool IsServer;
public string ServerName;
- const float NetworkUpdateInterval = 1.0f;
- private UInt32 lastUpdateID;
- public UInt32 LastUpdateID
+ private UInt16 lastUpdateID;
+ public UInt16 LastUpdateID
{
get { if (GameMain.Server != null && lastUpdateID < 1) lastUpdateID++; return lastUpdateID; }
set { if (GameMain.Server != null) return; lastUpdateID = value; }