Server name, message and submarine list syncing

This commit is contained in:
juanjp600
2016-09-02 22:24:14 -03:00
parent e0b6642767
commit e3433c725e
6 changed files with 294 additions and 210 deletions
+8
View File
@@ -28,7 +28,9 @@ namespace Barotrauma.Networking
public NetConnection Connection { get; set; }
public string version;
public bool inGame;
public UInt32 lastRecvLobbyUpdate = 0;
public bool hasLobbyData = false;
public UInt32 lastSentChatMsgID = 0; //last msg this client said
public UInt32 lastRecvChatMsgID = 0; //last msg this client knows about
@@ -50,6 +52,12 @@ namespace Barotrauma.Networking
public ClientPermissions Permissions;
public void InitClientSync()
{
lastSentChatMsgID = 0;
lastRecvChatMsgID = ChatMessage.LastID;
}
public int KickVoteCount
{
get { return kickVoters.Count; }
+37 -2
View File
@@ -300,6 +300,7 @@ namespace Barotrauma.Networking
break;
case ServerPacketHeader.UPDATE_LOBBY:
//server accepted client
ReadLobbyUpdate(inc);
CanStart = true;
break;
}
@@ -520,13 +521,45 @@ namespace Barotrauma.Networking
private void ReadLobbyUpdate(NetIncomingMessage inc)
{
lastRecvChatMsgID = inc.ReadUInt32();
ServerNetObject objHeader;
while ((objHeader = (ServerNetObject)inc.ReadByte()) != ServerNetObject.END_OF_MESSAGE)
{
switch (objHeader)
{
case ServerNetObject.SYNC_IDS:
bool lobbyUpdated = inc.ReadBoolean();
inc.ReadPadBits();
if (lobbyUpdated)
{
GameMain.NetLobbyScreen.LastUpdateID = inc.ReadUInt32();
GameMain.NetLobbyScreen.ServerName = inc.ReadString();
GameMain.NetLobbyScreen.ServerMessage = inc.ReadString();
UInt16 subListCount = inc.ReadUInt16();
if (subListCount > 0)
{
List<Submarine> submarines = new List<Submarine>();
for (int i = 0; i < subListCount; i++)
{
string subName = inc.ReadString();
string subHash = inc.ReadString();
var matchingSub = Submarine.SavedSubmarines.Find(s => s.Name == subName);
if (matchingSub != null)
{
submarines.Add(matchingSub);
}
else
{
submarines.Add(new Submarine(Path.Combine(Submarine.SavePath, subName), subHash, false));
}
}
GameMain.NetLobbyScreen.UpdateSubList(GameMain.NetLobbyScreen.SubList, submarines);
GameMain.NetLobbyScreen.UpdateSubList(GameMain.NetLobbyScreen.ShuttleList.ListBox, submarines);
}
}
lastRecvChatMsgID = inc.ReadUInt32();
break;
case ServerNetObject.CHAT_MESSAGE:
UInt32 ID = inc.ReadUInt32();
ChatMessageType type = (ChatMessageType)inc.ReadByte();
@@ -547,6 +580,8 @@ namespace Barotrauma.Networking
NetOutgoingMessage outmsg = client.CreateMessage();
outmsg.Write((byte)ClientPacketHeader.UPDATE_LOBBY);
outmsg.Write((byte)ClientNetObject.SYNC_IDS);
outmsg.Write(GameMain.NetLobbyScreen.LastUpdateID);
outmsg.Write(lastSentChatMsgID);
ChatMessage removeMsg;
while ((removeMsg=chatMsgQueue.Find(cMsg => cMsg.ID <= lastRecvChatMsgID)) != null)
+48 -9
View File
@@ -81,7 +81,7 @@ namespace Barotrauma.Networking
config.EnableUPnP = true;
}
config.MaximumConnections = maxPlayers;
config.MaximumConnections = maxPlayers*2; //double the lidgren connections for unauthenticated players
MaxPlayers = maxPlayers;
config.DisableMessageType(NetIncomingMessageType.DebugMessage |
@@ -546,19 +546,26 @@ namespace Barotrauma.Networking
return;
}
UInt32 ID = inc.ReadUInt32();
if (ID > c.lastRecvChatMsgID)
{
c.lastRecvChatMsgID = ID;
}
ClientNetObject objHeader;
while ((objHeader=(ClientNetObject)inc.ReadByte()) != ClientNetObject.END_OF_MESSAGE)
{
switch (objHeader)
{
case ClientNetObject.SYNC_IDS:
//TODO: might want to use a clever class for this
UInt32 lastLobbyUpdID = inc.ReadUInt32();
if (lastLobbyUpdID > c.lastRecvLobbyUpdate)
{
c.lastRecvLobbyUpdate = lastLobbyUpdID;
}
UInt32 lastChatID = inc.ReadUInt32();
if (lastChatID > c.lastRecvChatMsgID)
{
c.lastRecvChatMsgID = lastChatID;
}
break;
case ClientNetObject.CHAT_MESSAGE:
ID = inc.ReadUInt32();
UInt32 ID = inc.ReadUInt32();
string msg = inc.ReadString();
if (c.lastSentChatMsgID<ID)
{
@@ -598,7 +605,39 @@ namespace Barotrauma.Networking
{
NetOutgoingMessage outmsg = server.CreateMessage();
outmsg.Write((byte)ServerPacketHeader.UPDATE_LOBBY);
outmsg.Write(c.lastSentChatMsgID); //send this to client so they know which messages weren't received by the server
outmsg.Write((byte)ServerNetObject.SYNC_IDS);
if (c.lastRecvLobbyUpdate<GameMain.NetLobbyScreen.LastUpdateID)
{
outmsg.Write(true);
outmsg.WritePadBits();
outmsg.Write(GameMain.NetLobbyScreen.LastUpdateID);
outmsg.Write(GameMain.NetLobbyScreen.GetServerName());
outmsg.Write(GameMain.NetLobbyScreen.ServerMessage);
if (c.lastRecvLobbyUpdate < 1)
{
var subList = GameMain.NetLobbyScreen.GetSubList();
outmsg.Write((UInt16)subList.Count);
for (int i = 0; i < subList.Count; i++)
{
outmsg.Write(subList[i].Name);
outmsg.Write(subList[i].MD5Hash.ToString());
}
}
else
{
outmsg.Write((UInt16)0);
}
}
else
{
outmsg.Write(false);
outmsg.WritePadBits();
}
outmsg.Write(c.lastSentChatMsgID); //send this to client so they know which chat messages weren't received by the server
foreach (GUIComponent gc in GameMain.NetLobbyScreen.ChatBox.children)
{
if (gc is GUITextBlock)
@@ -101,9 +101,10 @@ namespace Barotrauma.Networking
unauthClient.failedAttempts++;
if (unauthClient.failedAttempts > 3)
{
//disconnect after too many failed attempts
unauthClient.Connection.Disconnect("Too many failed login attempts.");
//disconnect and ban after too many failed attempts
unauthClient.Connection.Disconnect("Too many failed login attempts. You have been automatically banned from the server.");
unauthenticatedClients.Remove(unauthClient);
banList.BanPlayer("Unnamed", unauthClient.Connection.RemoteEndPoint.Address.ToString());
unauthClient = null;
return;
}
@@ -112,7 +113,7 @@ namespace Barotrauma.Networking
//not disconnecting the player here, because they'll still use the same connection and nonce if they try logging in again
NetOutgoingMessage reject = server.CreateMessage();
reject.Write((byte)ServerPacketHeader.AUTH_FAILURE);
reject.Write("Wrong password!");
reject.Write("Wrong password! You have "+Convert.ToString(4-unauthClient.failedAttempts)+" more attempts before you're banned from the server.");
server.SendMessage(reject, unauthClient.Connection, NetDeliveryMethod.Unreliable);
unauthClient.AuthTimer = 10.0f;
return;
@@ -171,6 +172,7 @@ namespace Barotrauma.Networking
//both name and IP address match, replace this player's connection
nameTaken.Connection.Disconnect("Your session was taken by a new connection on the same IP address.");
nameTaken.Connection = unauthClient.Connection;
nameTaken.InitClientSync(); //reinitialize sync ids because this is a new connection
unauthenticatedClients.Remove(unauthClient);
unauthClient = null;
return;
@@ -187,7 +189,7 @@ namespace Barotrauma.Networking
//new client
Client newClient = new Client(clName, GetNewClientID());
newClient.lastRecvChatMsgID = ChatMessage.LastID;
newClient.InitClientSync();
newClient.Connection = unauthClient.Connection;
unauthenticatedClients.Remove(unauthClient);
unauthClient = null;
@@ -19,6 +19,7 @@ namespace Barotrauma.Networking
enum ClientNetObject
{
END_OF_MESSAGE, //self-explanatory
SYNC_IDS, //ids of the last changes the client knows about
CHAT_MESSAGE, //also self-explanatory
VOTE, //you get the idea
CHARACTER_INPUT,
@@ -35,6 +36,7 @@ namespace Barotrauma.Networking
enum ServerNetObject
{
END_OF_MESSAGE,
SYNC_IDS,
CHAT_MESSAGE,
VOTE,
CHARACTER_POSITION,
+21 -23
View File
@@ -54,11 +54,21 @@ namespace Barotrauma
const float NetworkUpdateInterval = 1.0f;
private float networkUpdateTimer;
private bool valueChanged;
private UInt32 lastUpdateID;
public UInt32 LastUpdateID
{
get { if (GameMain.Server != null && lastUpdateID < 1) lastUpdateID++; return lastUpdateID; }
set { if (GameMain.Server != null) return; lastUpdateID = value; }
}
private Sprite backgroundSprite;
private GUITextBox serverMessage;
public string ServerMessage
{
get { return serverMessage.Text; }
set { if (GameMain.Server != null) return; serverMessage.Text = value; }
}
public GUIListBox SubList
{
@@ -561,7 +571,7 @@ namespace Barotrauma
GameMain.Server.AutoRestart = tickBox.Selected;
valueChanged = true;
lastUpdateID++;
return true;
}
@@ -573,7 +583,7 @@ namespace Barotrauma
missionTypeBlock.GetChild<GUITextBlock>().Text = Mission.MissionTypes[missionTypeIndex];
missionTypeBlock.UserData = missionTypeIndex;
valueChanged = true;
lastUpdateID++;
}
public bool ToggleMissionType(GUIButton button, object userData)
@@ -586,7 +596,7 @@ namespace Barotrauma
SetMissionType(missionTypeIndex);
valueChanged = true;
lastUpdateID++;
return true;
}
@@ -603,7 +613,7 @@ namespace Barotrauma
SetTraitorsEnabled((YesNoMaybe)index);
valueChanged = true;
lastUpdateID++;
return true;
}
@@ -628,7 +638,7 @@ namespace Barotrauma
private bool SelectSub(GUIComponent component, object obj)
{
valueChanged = true;
lastUpdateID++;
var hash = obj is Submarine ? ((Submarine)obj).MD5Hash.Hash : "";
@@ -654,7 +664,7 @@ namespace Barotrauma
subList.ClearChildren();
if (submarines.Count == 0)
if (submarines.Count == 0 && GameMain.Server != null)
{
DebugConsole.ThrowError("No submarines found!");
}
@@ -734,7 +744,7 @@ namespace Barotrauma
{
if (GameMain.Server == null) return false;
ServerName = text;
valueChanged = true;
lastUpdateID++;
return true;
}
@@ -742,7 +752,7 @@ namespace Barotrauma
public bool UpdateServerMessage(GUITextBox textBox, string text)
{
if (GameMain.Server == null) return false;
valueChanged = true;
lastUpdateID++;
return true;
}
@@ -941,18 +951,6 @@ namespace Barotrauma
autoRestartTimer = Math.Max(autoRestartTimer - (float)deltaTime, 0.0f);
}
if (valueChanged && GameMain.Server != null)
{
networkUpdateTimer -= (float)deltaTime;
if (networkUpdateTimer <= 0.0f)
{
GameMain.Server.UpdateNetLobby(null);
valueChanged = false;
networkUpdateTimer = NetworkUpdateInterval;
}
}
//durationBar.BarScroll = Math.Max(durationBar.BarScroll, 1.0f / 60.0f);
}
@@ -1050,7 +1048,7 @@ namespace Barotrauma
if (modePreset == null) return false;
valueChanged = true;
lastUpdateID++;
return true;
}
@@ -1066,7 +1064,7 @@ namespace Barotrauma
//textBox.Text = LevelSeed;
//textBox.Selected = false;
valueChanged = true;
lastUpdateID++;
return true;
}