Changed lobby & chatMsg IDs to from uint to ushort, added a utility class that handles the wrap around of IDs
This commit is contained in:
@@ -163,6 +163,7 @@
|
||||
<Compile Include="Source\Networking\NetEntityEvent\NetEntityEventManager.cs" />
|
||||
<Compile Include="Source\Networking\NetEntityEvent\ServerEntityEventManager.cs" />
|
||||
<Compile Include="Source\Networking\NetStats.cs" />
|
||||
<Compile Include="Source\Networking\NetIdUtils.cs" />
|
||||
<Compile Include="Source\Networking\RespawnManager.cs" />
|
||||
<Compile Include="Source\Networking\ServerLog.cs" />
|
||||
<Compile Include="Source\Networking\WhiteList.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;
|
||||
|
||||
@@ -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<ChatMessage> chatMsgQueue = new List<ChatMessage>();
|
||||
public UInt32 lastChatMsgQueueID;
|
||||
public UInt16 lastChatMsgQueueID;
|
||||
public float ChatSpamSpeed;
|
||||
public float ChatSpamTimer;
|
||||
public int ChatSpamCount;
|
||||
|
||||
@@ -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<ChatMessage> chatMsgQueue = new List<ChatMessage>();
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -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<GameMain.NetLobbyScreen.LastUpdateID)
|
||||
|
||||
if (NetIdUtils.IdMoreRecent(GameMain.NetLobbyScreen.LastUpdateID, c.lastRecvGeneralUpdate))
|
||||
{
|
||||
outmsg.Write(true);
|
||||
outmsg.WritePadBits();
|
||||
@@ -849,7 +851,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
outmsg.Write(c.lastSentChatMsgID); //send this to client so they know which chat messages weren't received by the server
|
||||
|
||||
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);
|
||||
@@ -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;
|
||||
|
||||
57
Subsurface/Source/Networking/NetIdUtils.cs
Normal file
57
Subsurface/Source/Networking/NetIdUtils.cs
Normal file
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Is newID more recent than oldID
|
||||
/// </summary>
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
|
||||
Reference in New Issue
Block a user