Anti-gamerfood measures:
- clients don't send server passwords as plaintext: the server sends a nonce which the client encrypt using the password as the key - IPs are visible in netstats - amount of client jobpreferences limited to 3 at the servers side - sanitizing client names
This commit is contained in:
@@ -150,6 +150,7 @@
|
|||||||
<Compile Include="Source\Networking\ChatMessage.cs" />
|
<Compile Include="Source\Networking\ChatMessage.cs" />
|
||||||
<Compile Include="Source\Networking\FileStreamReceiver.cs" />
|
<Compile Include="Source\Networking\FileStreamReceiver.cs" />
|
||||||
<Compile Include="Source\Networking\FileStreamSender.cs" />
|
<Compile Include="Source\Networking\FileStreamSender.cs" />
|
||||||
|
<Compile Include="Source\Networking\GameServerLogin.cs" />
|
||||||
<Compile Include="Source\Networking\NetBufferExtensions.cs" />
|
<Compile Include="Source\Networking\NetBufferExtensions.cs" />
|
||||||
<Compile Include="Source\Networking\NetConfig.cs" />
|
<Compile Include="Source\Networking\NetConfig.cs" />
|
||||||
<Compile Include="Source\Networking\NetStats.cs" />
|
<Compile Include="Source\Networking\NetStats.cs" />
|
||||||
|
|||||||
@@ -191,7 +191,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
|
|
||||||
NewMessage("kick [name]: kick a player out from the server", Color.Cyan);
|
NewMessage("kick [name]: kick a player out from the server", Color.Cyan);
|
||||||
NewMessage("ban [name]: kick and ban the player", Color.Cyan);
|
NewMessage("ban [name]: kick and ban the player from the server", Color.Cyan);
|
||||||
|
NewMessage("banip [IP address]: ban the IP address from the server", Color.Cyan);
|
||||||
NewMessage("debugdraw: toggles the ''debug draw mode''", Color.Cyan);
|
NewMessage("debugdraw: toggles the ''debug draw mode''", Color.Cyan);
|
||||||
NewMessage("netstats: toggles the visibility of the network statistics panel", Color.Cyan);
|
NewMessage("netstats: toggles the visibility of the network statistics panel", Color.Cyan);
|
||||||
|
|
||||||
@@ -289,6 +290,19 @@ namespace Barotrauma
|
|||||||
if (GameMain.Server == null || commands.Length < 2) break;
|
if (GameMain.Server == null || commands.Length < 2) break;
|
||||||
GameMain.Server.KickPlayer(string.Join(" ", commands.Skip(1)), true);
|
GameMain.Server.KickPlayer(string.Join(" ", commands.Skip(1)), true);
|
||||||
break;
|
break;
|
||||||
|
case "banip":
|
||||||
|
if (GameMain.Server == null || commands.Length < 2) break;
|
||||||
|
|
||||||
|
var client = GameMain.Server.ConnectedClients.Find(c => c.Connection.RemoteEndPoint.Address.ToString() == commands[1]);
|
||||||
|
if (client == null)
|
||||||
|
{
|
||||||
|
GameMain.Server.BanList.BanPlayer("Unnamed", commands[1]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GameMain.Server.KickClient(client, true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case "startclient":
|
case "startclient":
|
||||||
if (commands.Length == 1) return;
|
if (commands.Length == 1) return;
|
||||||
if (GameMain.Client == null)
|
if (GameMain.Client == null)
|
||||||
|
|||||||
@@ -66,7 +66,10 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
if (bannedPlayers.Any(bp => bp.IP == ip)) return;
|
if (bannedPlayers.Any(bp => bp.IP == ip)) return;
|
||||||
|
|
||||||
|
DebugConsole.Log("Banned " + name);
|
||||||
|
|
||||||
bannedPlayers.Add(new BannedPlayer(name, ip));
|
bannedPlayers.Add(new BannedPlayer(name, ip));
|
||||||
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsBanned(string IP)
|
public bool IsBanned(string IP)
|
||||||
@@ -108,10 +111,13 @@ namespace Barotrauma.Networking
|
|||||||
BannedPlayer banned = obj as BannedPlayer;
|
BannedPlayer banned = obj as BannedPlayer;
|
||||||
if (banned == null) return false;
|
if (banned == null) return false;
|
||||||
|
|
||||||
|
DebugConsole.Log("Removing ban from " + banned.Name);
|
||||||
GameServer.Log("Removing ban from " + banned.Name, null);
|
GameServer.Log("Removing ban from " + banned.Name, null);
|
||||||
|
|
||||||
bannedPlayers.Remove(banned);
|
bannedPlayers.Remove(banned);
|
||||||
|
|
||||||
|
Save();
|
||||||
|
|
||||||
if (banFrame != null)
|
if (banFrame != null)
|
||||||
{
|
{
|
||||||
banFrame.Parent.RemoveChild(banFrame);
|
banFrame.Parent.RemoveChild(banFrame);
|
||||||
@@ -130,7 +136,6 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public void Save()
|
public void Save()
|
||||||
{
|
{
|
||||||
|
|
||||||
GameServer.Log("Saving banlist", null);
|
GameServer.Log("Saving banlist", null);
|
||||||
|
|
||||||
List<string> lines = new List<string>();
|
List<string> lines = new List<string>();
|
||||||
|
|||||||
@@ -108,21 +108,13 @@ namespace Barotrauma.Networking
|
|||||||
config.DisableMessageType(NetIncomingMessageType.DebugMessage | NetIncomingMessageType.WarningMessage | NetIncomingMessageType.Receipt
|
config.DisableMessageType(NetIncomingMessageType.DebugMessage | NetIncomingMessageType.WarningMessage | NetIncomingMessageType.Receipt
|
||||||
| NetIncomingMessageType.ErrorMessage | NetIncomingMessageType.Error);
|
| NetIncomingMessageType.ErrorMessage | NetIncomingMessageType.Error);
|
||||||
|
|
||||||
// Create new client, with previously created configs
|
|
||||||
client = new NetClient(config);
|
client = new NetClient(config);
|
||||||
netPeer = client;
|
netPeer = client;
|
||||||
reliableChannel = new ReliableChannel(client);
|
reliableChannel = new ReliableChannel(client);
|
||||||
|
|
||||||
NetOutgoingMessage outmsg = client.CreateMessage();
|
|
||||||
client.Start();
|
client.Start();
|
||||||
|
|
||||||
|
NetOutgoingMessage outmsg = client.CreateMessage();
|
||||||
outmsg.Write((byte)PacketTypes.Login);
|
outmsg.Write((byte)PacketTypes.Login);
|
||||||
outmsg.Write(myID);
|
|
||||||
outmsg.Write(password);
|
|
||||||
outmsg.Write(GameMain.Version.ToString());
|
|
||||||
outmsg.Write(GameMain.SelectedPackage.Name);
|
|
||||||
outmsg.Write(GameMain.SelectedPackage.MD5hash.Hash);
|
|
||||||
outmsg.Write(name);
|
|
||||||
|
|
||||||
|
|
||||||
System.Net.IPEndPoint IPEndPoint = null;
|
System.Net.IPEndPoint IPEndPoint = null;
|
||||||
@@ -141,6 +133,7 @@ namespace Barotrauma.Networking
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
client.Connect(IPEndPoint, outmsg);
|
client.Connect(IPEndPoint, outmsg);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -150,17 +143,9 @@ namespace Barotrauma.Networking
|
|||||||
GameMain.ServerListScreen.Select();
|
GameMain.ServerListScreen.Select();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
updateInterval = new TimeSpan(0, 0, 0, 0, 150);
|
updateInterval = new TimeSpan(0, 0, 0, 0, 150);
|
||||||
|
|
||||||
// Set timer to tick every 50ms
|
|
||||||
//update = new System.Timers.startTimer(50);
|
|
||||||
|
|
||||||
// When time has elapsed ( 50ms in this case ), call "update_Elapsed" funtion
|
|
||||||
//update.Elapsed += new System.Timers.ElapsedEventHandler(Update);
|
|
||||||
|
|
||||||
// Funtion that waits for connection approval info from server
|
|
||||||
if (reconnectBox==null)
|
if (reconnectBox==null)
|
||||||
{
|
{
|
||||||
reconnectBox = new GUIMessageBox("CONNECTING", "Connecting to " + serverIP, new string[] { "Cancel" });
|
reconnectBox = new GUIMessageBox("CONNECTING", "Connecting to " + serverIP, new string[] { "Cancel" });
|
||||||
@@ -169,7 +154,7 @@ namespace Barotrauma.Networking
|
|||||||
reconnectBox.Buttons[0].OnClicked += reconnectBox.Close;
|
reconnectBox.Buttons[0].OnClicked += reconnectBox.Close;
|
||||||
}
|
}
|
||||||
|
|
||||||
CoroutineManager.StartCoroutine(WaitForStartingInfo());
|
CoroutineManager.StartCoroutine(WaitForStartingInfo(password));
|
||||||
|
|
||||||
// Start the timer
|
// Start the timer
|
||||||
//update.Start();
|
//update.Start();
|
||||||
@@ -203,7 +188,7 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Before main looping starts, we loop here and wait for approval message
|
// Before main looping starts, we loop here and wait for approval message
|
||||||
private IEnumerable<object> WaitForStartingInfo()
|
private IEnumerable<object> WaitForStartingInfo(string password)
|
||||||
{
|
{
|
||||||
connectCanceled = false;
|
connectCanceled = false;
|
||||||
// When this is set to true, we are approved and ready to go
|
// When this is set to true, we are approved and ready to go
|
||||||
@@ -303,18 +288,12 @@ namespace Barotrauma.Networking
|
|||||||
lobbyUpdateRequest.Write((byte)PacketTypes.RequestNetLobbyUpdate);
|
lobbyUpdateRequest.Write((byte)PacketTypes.RequestNetLobbyUpdate);
|
||||||
client.SendMessage(lobbyUpdateRequest, NetDeliveryMethod.ReliableUnordered);
|
client.SendMessage(lobbyUpdateRequest, NetDeliveryMethod.ReliableUnordered);
|
||||||
}
|
}
|
||||||
else if (packetType == (byte)PacketTypes.KickedOut)
|
|
||||||
{
|
|
||||||
string msg = inc.ReadString();
|
|
||||||
DebugConsole.ThrowError(msg);
|
|
||||||
|
|
||||||
GameMain.MainMenuScreen.Select();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case NetIncomingMessageType.StatusChanged:
|
case NetIncomingMessageType.StatusChanged:
|
||||||
DebugConsole.NewMessage("Connection status changed: " + client.ConnectionStatus.ToString(), Color.Orange);
|
|
||||||
|
|
||||||
NetConnectionStatus connectionStatus = (NetConnectionStatus)inc.ReadByte();
|
NetConnectionStatus connectionStatus = (NetConnectionStatus)inc.ReadByte();
|
||||||
|
DebugConsole.NewMessage("Connection status changed: " + connectionStatus.ToString(), Color.Orange);
|
||||||
|
|
||||||
if (connectionStatus == NetConnectionStatus.Disconnected)
|
if (connectionStatus == NetConnectionStatus.Disconnected)
|
||||||
{
|
{
|
||||||
string denyMessage = inc.ReadString();
|
string denyMessage = inc.ReadString();
|
||||||
@@ -330,6 +309,25 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
connectCanceled = true;
|
connectCanceled = true;
|
||||||
}
|
}
|
||||||
|
else if (connectionStatus == NetConnectionStatus.Connected)
|
||||||
|
{
|
||||||
|
int nonce = inc.SenderConnection.RemoteHailMessage.ReadInt32();
|
||||||
|
|
||||||
|
var outmsg = client.CreateMessage();
|
||||||
|
|
||||||
|
NetEncryption algo = new NetXtea(client, password);
|
||||||
|
outmsg.Write((byte)PacketTypes.Login);
|
||||||
|
outmsg.Write(nonce);
|
||||||
|
outmsg.Write(myID);
|
||||||
|
outmsg.Write(GameMain.Version.ToString());
|
||||||
|
outmsg.Write(GameMain.SelectedPackage.Name);
|
||||||
|
outmsg.Write(GameMain.SelectedPackage.MD5hash.Hash);
|
||||||
|
outmsg.Write(name);
|
||||||
|
|
||||||
|
outmsg.Encrypt(algo);
|
||||||
|
|
||||||
|
client.SendMessage(outmsg, NetDeliveryMethod.ReliableUnordered);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -394,19 +392,6 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
if (!connected) return;
|
if (!connected) return;
|
||||||
|
|
||||||
if (client.ConnectionStatus == NetConnectionStatus.Disconnected)
|
|
||||||
{
|
|
||||||
//GameMain.NetLobbyScreen.RemovePlayer(myID);
|
|
||||||
if (reconnectBox==null)
|
|
||||||
{
|
|
||||||
reconnectBox = new GUIMessageBox("CONNECTION LOST", "You have been disconnected from the server. Reconnecting...", new string[0]);
|
|
||||||
connected = false;
|
|
||||||
ConnectToServer(serverIP);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reconnectBox!=null)
|
if (reconnectBox!=null)
|
||||||
{
|
{
|
||||||
reconnectBox.Close(null,null);
|
reconnectBox.Close(null,null);
|
||||||
@@ -488,6 +473,33 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
while ((inc = client.ReadMessage()) != null)
|
while ((inc = client.ReadMessage()) != null)
|
||||||
{
|
{
|
||||||
|
if (inc.MessageType == NetIncomingMessageType.StatusChanged)
|
||||||
|
{
|
||||||
|
NetConnectionStatus connectionStatus = (NetConnectionStatus)inc.ReadByte();
|
||||||
|
DebugConsole.NewMessage("Connection status changed: " + connectionStatus.ToString(), Color.Orange);
|
||||||
|
|
||||||
|
if (connectionStatus == NetConnectionStatus.Disconnected)
|
||||||
|
{
|
||||||
|
string disconnectMessage = inc.ReadString();
|
||||||
|
if (string.IsNullOrEmpty(disconnectMessage) || disconnectMessage == "Connection timed out")
|
||||||
|
{
|
||||||
|
if (reconnectBox == null)
|
||||||
|
{
|
||||||
|
reconnectBox = new GUIMessageBox("CONNECTION LOST", "You have been disconnected from the server. Reconnecting...", new string[0]);
|
||||||
|
connected = false;
|
||||||
|
ConnectToServer(serverIP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new GUIMessageBox("Disconnected", disconnectMessage);
|
||||||
|
|
||||||
|
Disconnect();
|
||||||
|
GameMain.ServerListScreen.Select();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (inc.MessageType != NetIncomingMessageType.Data) continue;
|
if (inc.MessageType != NetIncomingMessageType.Data) continue;
|
||||||
|
|
||||||
byte packetType = inc.ReadByte();
|
byte packetType = inc.ReadByte();
|
||||||
@@ -590,16 +602,6 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
//GameMain.GameSession.CrewManager.CreateCrewFrame(crew);
|
//GameMain.GameSession.CrewManager.CreateCrewFrame(crew);
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (byte)PacketTypes.KickedOut:
|
|
||||||
string msg = inc.ReadString();
|
|
||||||
|
|
||||||
new GUIMessageBox("Disconnected from server", msg);
|
|
||||||
|
|
||||||
Disconnect();
|
|
||||||
GameMain.MainMenuScreen.Select();
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case (byte)PacketTypes.Chatmessage:
|
case (byte)PacketTypes.Chatmessage:
|
||||||
//ChatMessageType messageType = (ChatMessageType)inc.ReadByte();
|
//ChatMessageType messageType = (ChatMessageType)inc.ReadByte();
|
||||||
@@ -784,16 +786,6 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
secondsLeft -= CoroutineManager.UnscaledDeltaTime;
|
secondsLeft -= CoroutineManager.UnscaledDeltaTime;
|
||||||
|
|
||||||
//float camAngle = (float)((DateTime.Now - endTime).TotalSeconds / endPreviewLength) * MathHelper.TwoPi;
|
|
||||||
//Vector2 offset = (new Vector2(
|
|
||||||
// (float)Math.Cos(camAngle) * (Submarine.Borders.Width / 2.0f),
|
|
||||||
// (float)Math.Sin(camAngle) * (Submarine.Borders.Height / 2.0f)));
|
|
||||||
|
|
||||||
//GameMain.GameScreen.Cam.TargetPos = Submarine.Loaded.Position + offset * 0.8f;
|
|
||||||
//Game1.GameScreen.Cam.MoveCamera((float)deltaTime);
|
|
||||||
|
|
||||||
//messageBox.Text = endMessage + "\nReturning to lobby in " + (int)secondsLeft + " s";
|
|
||||||
|
|
||||||
yield return CoroutineStatus.Running;
|
yield return CoroutineStatus.Running;
|
||||||
} while (secondsLeft > 0.0f);
|
} while (secondsLeft > 0.0f);
|
||||||
}
|
}
|
||||||
@@ -802,8 +794,6 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
GameMain.NetLobbyScreen.Select();
|
GameMain.NetLobbyScreen.Select();
|
||||||
|
|
||||||
//if (GameMain.GameSession!=null) GameMain.GameSession.EndShift("");
|
|
||||||
|
|
||||||
myCharacter = null;
|
myCharacter = null;
|
||||||
foreach (Client c in otherClients)
|
foreach (Client c in otherClients)
|
||||||
{
|
{
|
||||||
@@ -948,16 +938,23 @@ namespace Barotrauma.Networking
|
|||||||
switch (receiver.FileType)
|
switch (receiver.FileType)
|
||||||
{
|
{
|
||||||
case FileTransferMessageType.Submarine:
|
case FileTransferMessageType.Submarine:
|
||||||
var textBlock = GameMain.NetLobbyScreen.SubList.children.Find(c => (c.UserData as Submarine).Name+".sub" == receiver.FileName);
|
|
||||||
if (textBlock != null)
|
|
||||||
{
|
|
||||||
Submarine.SavedSubmarines.RemoveAll(s => s.Name + ".sub" == receiver.FileName);
|
Submarine.SavedSubmarines.RemoveAll(s => s.Name + ".sub" == receiver.FileName);
|
||||||
|
|
||||||
|
for (int i = 0; i<2; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
var textBlock = (i == 0) ?
|
||||||
|
GameMain.NetLobbyScreen.ShuttleList.ListBox.children.Find(c => (c.UserData as Submarine).Name+".sub" == receiver.FileName) :
|
||||||
|
GameMain.NetLobbyScreen.SubList.children.Find(c => (c.UserData as Submarine).Name+".sub" == receiver.FileName);
|
||||||
|
if (textBlock == null) continue;
|
||||||
|
|
||||||
(textBlock as GUITextBlock).TextColor = Color.White;
|
(textBlock as GUITextBlock).TextColor = Color.White;
|
||||||
|
|
||||||
var newSub = new Submarine(receiver.FilePath);
|
var newSub = new Submarine(receiver.FilePath);
|
||||||
Submarine.SavedSubmarines.Add(newSub);
|
Submarine.SavedSubmarines.Add(newSub);
|
||||||
textBlock.UserData = newSub;
|
textBlock.UserData = newSub;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1063,7 +1060,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
var jobPreferences = GameMain.NetLobbyScreen.JobPreferences;
|
var jobPreferences = GameMain.NetLobbyScreen.JobPreferences;
|
||||||
int count = Math.Min(jobPreferences.Count, 3);
|
int count = Math.Min(jobPreferences.Count, 3);
|
||||||
msg.Write(count);
|
msg.Write((byte)count);
|
||||||
for (int i = 0; i < count; i++ )
|
for (int i = 0; i < count; i++ )
|
||||||
{
|
{
|
||||||
msg.Write(jobPreferences[i].Name);
|
msg.Write(jobPreferences[i].Name);
|
||||||
@@ -1094,8 +1091,7 @@ namespace Barotrauma.Networking
|
|||||||
GameMain.GameSession.CrewManager.characters.Add(character);
|
GameMain.GameSession.CrewManager.characters.Add(character);
|
||||||
|
|
||||||
character.ID = ID;
|
character.ID = ID;
|
||||||
|
|
||||||
|
|
||||||
Item.Spawner.ReadNetworkData(inc);
|
Item.Spawner.ReadNetworkData(inc);
|
||||||
|
|
||||||
if (isMyCharacter)
|
if (isMyCharacter)
|
||||||
@@ -1112,8 +1108,6 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public override void SendChatMessage(string message, ChatMessageType? type = null)
|
public override void SendChatMessage(string message, ChatMessageType? type = null)
|
||||||
{
|
{
|
||||||
//AddChatMessage(message);
|
|
||||||
|
|
||||||
if (client.ServerConnection == null) return;
|
if (client.ServerConnection == null) return;
|
||||||
|
|
||||||
type = ChatMessageType.Default;
|
type = ChatMessageType.Default;
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ namespace Barotrauma.Networking
|
|||||||
banList = new BanList();
|
banList = new BanList();
|
||||||
|
|
||||||
LoadSettings();
|
LoadSettings();
|
||||||
|
|
||||||
//----------------------------------------
|
//----------------------------------------
|
||||||
|
|
||||||
|
|
||||||
@@ -277,6 +277,17 @@ namespace Barotrauma.Networking
|
|||||||
if (!started) return;
|
if (!started) return;
|
||||||
|
|
||||||
base.Update(deltaTime);
|
base.Update(deltaTime);
|
||||||
|
|
||||||
|
foreach (UnauthenticatedClient unauthClient in unauthenticatedClients)
|
||||||
|
{
|
||||||
|
unauthClient.AuthTimer -= deltaTime;
|
||||||
|
if (unauthClient.AuthTimer <= 0.0f)
|
||||||
|
{
|
||||||
|
unauthClient.Connection.Disconnect("Connection timed out");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unauthenticatedClients.RemoveAll(uc => uc.AuthTimer <= 0.0f);
|
||||||
|
|
||||||
if (gameStarted)
|
if (gameStarted)
|
||||||
{
|
{
|
||||||
@@ -430,6 +441,8 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
private void ReadMessage(NetIncomingMessage inc)
|
private void ReadMessage(NetIncomingMessage inc)
|
||||||
{
|
{
|
||||||
|
Client sender = connectedClients.Find(x => x.Connection == inc.SenderConnection);
|
||||||
|
|
||||||
switch (inc.MessageType)
|
switch (inc.MessageType)
|
||||||
{
|
{
|
||||||
case NetIncomingMessageType.ConnectionApproval:
|
case NetIncomingMessageType.ConnectionApproval:
|
||||||
@@ -437,76 +450,7 @@ namespace Barotrauma.Networking
|
|||||||
break;
|
break;
|
||||||
case NetIncomingMessageType.StatusChanged:
|
case NetIncomingMessageType.StatusChanged:
|
||||||
Debug.WriteLine(inc.SenderConnection + " status changed. " + (NetConnectionStatus)inc.SenderConnection.Status);
|
Debug.WriteLine(inc.SenderConnection + " status changed. " + (NetConnectionStatus)inc.SenderConnection.Status);
|
||||||
if (inc.SenderConnection.Status == NetConnectionStatus.Connected)
|
if (inc.SenderConnection.Status == NetConnectionStatus.Disconnected)
|
||||||
{
|
|
||||||
Client sender = connectedClients.Find(x => x.Connection == inc.SenderConnection);
|
|
||||||
|
|
||||||
if (sender == null) break;
|
|
||||||
|
|
||||||
if (sender.version != GameMain.Version.ToString())
|
|
||||||
{
|
|
||||||
DisconnectClient(sender, sender.name+" was unable to connect to the server (nonmatching game version)",
|
|
||||||
"Version " + GameMain.Version + " required to connect to the server (Your version: " + sender.version + ")");
|
|
||||||
}
|
|
||||||
else if (connectedClients.Find(x => x.name == sender.name && x != sender)!=null)
|
|
||||||
{
|
|
||||||
DisconnectClient(sender, sender.name + " was unable to connect to the server (name already in use)",
|
|
||||||
"The name ''"+sender.name+"'' is already in use. Please choose another name.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//AssignJobs();
|
|
||||||
|
|
||||||
GameMain.NetLobbyScreen.RemovePlayer(sender.name);
|
|
||||||
GameMain.NetLobbyScreen.AddPlayer(sender.name);
|
|
||||||
|
|
||||||
// Notify the client that they have logged in
|
|
||||||
var outmsg = server.CreateMessage();
|
|
||||||
|
|
||||||
outmsg.Write((byte)PacketTypes.LoggedIn);
|
|
||||||
outmsg.Write(sender.ID);
|
|
||||||
outmsg.Write(gameStarted);
|
|
||||||
outmsg.Write(gameStarted && sender.Character != null && !sender.Character.IsDead);
|
|
||||||
outmsg.Write(AllowSpectating);
|
|
||||||
|
|
||||||
//notify the client about other clients already logged in
|
|
||||||
outmsg.Write((byte)((characterInfo == null) ? connectedClients.Count - 1 : connectedClients.Count));
|
|
||||||
foreach (Client c in connectedClients)
|
|
||||||
{
|
|
||||||
if (c.Connection == inc.SenderConnection) continue;
|
|
||||||
outmsg.Write(c.name);
|
|
||||||
outmsg.Write(c.ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (characterInfo != null)
|
|
||||||
{
|
|
||||||
outmsg.Write(characterInfo.Name);
|
|
||||||
outmsg.Write((byte)0);
|
|
||||||
}
|
|
||||||
|
|
||||||
var subs = GameMain.NetLobbyScreen.GetSubList();
|
|
||||||
outmsg.Write((byte)subs.Count);
|
|
||||||
foreach (Submarine sub in subs)
|
|
||||||
{
|
|
||||||
outmsg.Write(sub.Name);
|
|
||||||
outmsg.Write(sub.MD5Hash.Hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
server.SendMessage(outmsg, inc.SenderConnection, NetDeliveryMethod.ReliableUnordered, 0);
|
|
||||||
|
|
||||||
//notify other clients about the new client
|
|
||||||
outmsg = server.CreateMessage();
|
|
||||||
outmsg.Write((byte)PacketTypes.PlayerJoined);
|
|
||||||
outmsg.Write(sender.name);
|
|
||||||
outmsg.Write(sender.ID);
|
|
||||||
|
|
||||||
//send the message to everyone except the client who just logged in
|
|
||||||
SendMessage(outmsg, NetDeliveryMethod.ReliableUnordered, inc.SenderConnection);
|
|
||||||
|
|
||||||
AddChatMessage(sender.name + " has joined the server", ChatMessageType.Server);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (inc.SenderConnection.Status == NetConnectionStatus.Disconnected)
|
|
||||||
{
|
{
|
||||||
var connectedClient = connectedClients.Find(c => c.Connection == inc.SenderConnection);
|
var connectedClient = connectedClients.Find(c => c.Connection == inc.SenderConnection);
|
||||||
if (connectedClient != null && !disconnectedClients.Contains(connectedClient))
|
if (connectedClient != null && !disconnectedClients.Contains(connectedClient))
|
||||||
@@ -515,21 +459,32 @@ namespace Barotrauma.Networking
|
|||||||
disconnectedClients.Add(connectedClient);
|
disconnectedClients.Add(connectedClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
DisconnectClient(inc.SenderConnection,
|
DisconnectClient(inc.SenderConnection,
|
||||||
connectedClient != null ? connectedClient.name+" has disconnected" : "");
|
connectedClient != null ? connectedClient.name + " has disconnected" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case NetIncomingMessageType.Data:
|
case NetIncomingMessageType.Data:
|
||||||
|
|
||||||
Client dataSender = connectedClients.Find(c => c.Connection == inc.SenderConnection);
|
|
||||||
if (dataSender == null) return;
|
|
||||||
|
|
||||||
byte packetType = inc.ReadByte();
|
byte packetType = inc.ReadByte();
|
||||||
|
|
||||||
|
if (sender == null)
|
||||||
|
{
|
||||||
|
var authUser = unauthenticatedClients.Find(c => c.Connection == inc.SenderConnection);
|
||||||
|
if (authUser == null)
|
||||||
|
{
|
||||||
|
unauthenticatedClients.Remove(authUser);
|
||||||
|
inc.SenderConnection.Disconnect("Disconnected");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CheckAuthentication(inc);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (packetType == (byte)PacketTypes.ReliableMessage)
|
if (packetType == (byte)PacketTypes.ReliableMessage)
|
||||||
{
|
{
|
||||||
if (!dataSender.ReliableChannel.CheckMessage(inc)) return;
|
if (!sender.ReliableChannel.CheckMessage(inc)) return;
|
||||||
packetType = inc.ReadByte();
|
packetType = inc.ReadByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -551,7 +506,7 @@ namespace Barotrauma.Networking
|
|||||||
DisconnectClient(inc.SenderConnection);
|
DisconnectClient(inc.SenderConnection);
|
||||||
break;
|
break;
|
||||||
case (byte)PacketTypes.StartGame:
|
case (byte)PacketTypes.StartGame:
|
||||||
dataSender.ReadyToStart = true;
|
sender.ReadyToStart = true;
|
||||||
break;
|
break;
|
||||||
case (byte)PacketTypes.CharacterInfo:
|
case (byte)PacketTypes.CharacterInfo:
|
||||||
ReadCharacterData(inc);
|
ReadCharacterData(inc);
|
||||||
@@ -560,7 +515,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
if (!AllowFileTransfers)
|
if (!AllowFileTransfers)
|
||||||
{
|
{
|
||||||
SendCancelTransferMessage(dataSender, "File transfers have been disabled by the server.");
|
SendCancelTransferMessage(sender, "File transfers have been disabled by the server.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -579,16 +534,16 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (dataSender.FileStreamSender != null) dataSender.FileStreamSender.CancelTransfer();
|
if (sender.FileStreamSender != null) sender.FileStreamSender.CancelTransfer();
|
||||||
|
|
||||||
var fileStreamSender = FileStreamSender.Create(dataSender.Connection, requestedSubmarine.FilePath, FileTransferMessageType.Submarine);
|
var fileStreamSender = FileStreamSender.Create(sender.Connection, requestedSubmarine.FilePath, FileTransferMessageType.Submarine);
|
||||||
if (fileStreamSender != null) dataSender.FileStreamSender = fileStreamSender;
|
if (fileStreamSender != null) sender.FileStreamSender = fileStreamSender;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case (byte)FileTransferMessageType.Cancel:
|
case (byte)FileTransferMessageType.Cancel:
|
||||||
if (dataSender.FileStreamSender != null)
|
if (sender.FileStreamSender != null)
|
||||||
{
|
{
|
||||||
dataSender.FileStreamSender.CancelTransfer();
|
sender.FileStreamSender.CancelTransfer();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -596,14 +551,12 @@ namespace Barotrauma.Networking
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case (byte)PacketTypes.ResendRequest:
|
case (byte)PacketTypes.ResendRequest:
|
||||||
|
sender.ReliableChannel.HandleResendRequest(inc);
|
||||||
dataSender.ReliableChannel.HandleResendRequest(inc);
|
|
||||||
break;
|
break;
|
||||||
case (byte)PacketTypes.LatestMessageID:
|
case (byte)PacketTypes.LatestMessageID:
|
||||||
dataSender.ReliableChannel.HandleLatestMessageID(inc);
|
sender.ReliableChannel.HandleLatestMessageID(inc);
|
||||||
break;
|
break;
|
||||||
case (byte)PacketTypes.Vote:
|
case (byte)PacketTypes.Vote:
|
||||||
Voting.RegisterVote(inc, connectedClients);
|
Voting.RegisterVote(inc, connectedClients);
|
||||||
@@ -625,8 +578,8 @@ namespace Barotrauma.Networking
|
|||||||
var startMessage = CreateStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.gameMode.Preset);
|
var startMessage = CreateStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.gameMode.Preset);
|
||||||
server.SendMessage(startMessage, inc.SenderConnection, NetDeliveryMethod.ReliableOrdered);
|
server.SendMessage(startMessage, inc.SenderConnection, NetDeliveryMethod.ReliableOrdered);
|
||||||
|
|
||||||
dataSender.Spectating = true;
|
sender.Spectating = true;
|
||||||
CoroutineManager.StartCoroutine(SyncSpectator(dataSender));
|
CoroutineManager.StartCoroutine(SyncSpectator(sender));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -637,127 +590,6 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleConnectionApproval(NetIncomingMessage inc)
|
|
||||||
{
|
|
||||||
if ((PacketTypes)inc.ReadByte() != PacketTypes.Login) return;
|
|
||||||
|
|
||||||
DebugConsole.NewMessage("New player has joined the server", Color.White);
|
|
||||||
|
|
||||||
if (banList.IsBanned(inc.SenderEndPoint.Address.ToString()))
|
|
||||||
{
|
|
||||||
inc.SenderConnection.Deny("You have been banned from the server");
|
|
||||||
DebugConsole.NewMessage("Banned player tried to join the server", Color.Red);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connectedClients.Find(c => c.Connection == inc.SenderConnection)!=null)
|
|
||||||
{
|
|
||||||
inc.SenderConnection.Deny("Connection error - already joined");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte userID;
|
|
||||||
string userPassword = "", version = "", packageName = "", packageHash = "", name = "";
|
|
||||||
try
|
|
||||||
{
|
|
||||||
userID = inc.ReadByte();
|
|
||||||
userPassword = inc.ReadString();
|
|
||||||
version = inc.ReadString();
|
|
||||||
packageName = inc.ReadString();
|
|
||||||
packageHash = inc.ReadString();
|
|
||||||
name = inc.ReadString();
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
inc.SenderConnection.Deny("Connection error - server failed to read your ConnectionApproval message");
|
|
||||||
DebugConsole.NewMessage("Connection error - server failed to read the ConnectionApproval message", Color.Red);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !DEBUG
|
|
||||||
if (!string.IsNullOrWhiteSpace(password) && string.IsNullOrWhiteSpace(userPassword))
|
|
||||||
{
|
|
||||||
inc.SenderConnection.Deny("Password required!");
|
|
||||||
DebugConsole.NewMessage(name + " couldn't join the server (no password)", Color.Red);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (userPassword != password)
|
|
||||||
{
|
|
||||||
inc.SenderConnection.Deny("Wrong password!");
|
|
||||||
DebugConsole.NewMessage(name + " couldn't join the server (wrong password)", Color.Red);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (version != GameMain.Version.ToString())
|
|
||||||
{
|
|
||||||
inc.SenderConnection.Deny("Version " + GameMain.Version + " required to connect to the server (Your version: " + version + ")");
|
|
||||||
DebugConsole.NewMessage(name + " couldn't join the server (wrong game version)", Color.Red);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (packageName != GameMain.SelectedPackage.Name)
|
|
||||||
{
|
|
||||||
inc.SenderConnection.Deny("Your content package (" + packageName + ") doesn't match the server's version (" + GameMain.SelectedPackage.Name + ")");
|
|
||||||
DebugConsole.NewMessage(name + " couldn't join the server (wrong content package name)", Color.Red);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (packageHash != GameMain.SelectedPackage.MD5hash.Hash)
|
|
||||||
{
|
|
||||||
inc.SenderConnection.Deny("Your content package (MD5: " + packageHash + ") doesn't match the server's version (MD5: " + GameMain.SelectedPackage.MD5hash.Hash + ")");
|
|
||||||
DebugConsole.NewMessage(name + " couldn't join the server (wrong content package hash)", Color.Red);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (connectedClients.Find(c => c.name.ToLower() == name.ToLower() && c.ID != userID) != null)
|
|
||||||
{
|
|
||||||
inc.SenderConnection.Deny("The name ''" + name + "'' is already in use. Please choose another name.");
|
|
||||||
DebugConsole.NewMessage(name + " couldn't join the server (name already in use)", Color.Red);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//existing user re-joining
|
|
||||||
if (userID > 0)
|
|
||||||
{
|
|
||||||
Client existingClient = connectedClients.Find(c => c.ID == userID);
|
|
||||||
if (existingClient == null)
|
|
||||||
{
|
|
||||||
existingClient = disconnectedClients.Find(c => c.ID == userID);
|
|
||||||
if (existingClient != null)
|
|
||||||
{
|
|
||||||
disconnectedClients.Remove(existingClient);
|
|
||||||
connectedClients.Add(existingClient);
|
|
||||||
|
|
||||||
UpdateCrewFrame();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (existingClient != null)
|
|
||||||
{
|
|
||||||
existingClient.Connection = inc.SenderConnection;
|
|
||||||
existingClient.ReliableChannel = new ReliableChannel(server);
|
|
||||||
inc.SenderConnection.Approve();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
userID = 1;
|
|
||||||
while (connectedClients.Any(c => c.ID == userID))
|
|
||||||
{
|
|
||||||
userID++;
|
|
||||||
}
|
|
||||||
|
|
||||||
Client newClient = new Client(server, name, userID);
|
|
||||||
newClient.Connection = inc.SenderConnection;
|
|
||||||
newClient.version = version;
|
|
||||||
|
|
||||||
connectedClients.Add(newClient);
|
|
||||||
|
|
||||||
UpdateCrewFrame();
|
|
||||||
|
|
||||||
inc.SenderConnection.Approve();
|
|
||||||
|
|
||||||
refreshMasterTimer = DateTime.Now;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void SendMessage(NetOutgoingMessage msg, NetDeliveryMethod deliveryMethod, NetConnection excludedConnection = null)
|
private void SendMessage(NetOutgoingMessage msg, NetDeliveryMethod deliveryMethod, NetConnection excludedConnection = null)
|
||||||
{
|
{
|
||||||
List<NetConnection> recipients = new List<NetConnection>();
|
List<NetConnection> recipients = new List<NetConnection>();
|
||||||
@@ -1159,38 +991,14 @@ namespace Barotrauma.Networking
|
|||||||
msg.Write(true);
|
msg.Write(true);
|
||||||
msg.Write((byte)0);
|
msg.Write((byte)0);
|
||||||
}
|
}
|
||||||
else{
|
else
|
||||||
|
{
|
||||||
msg.Write(false);
|
msg.Write(false);
|
||||||
}
|
}
|
||||||
WriteCharacterData(msg, c.Name, c);
|
WriteCharacterData(msg, c.Name, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// message.Write((byte)PacketTypes.NewCharacter);
|
|
||||||
|
|
||||||
//message.Write(character.ConfigPath);
|
|
||||||
|
|
||||||
//message.Write(character.ID);
|
|
||||||
|
|
||||||
//message.Write(character.Position.X);
|
|
||||||
//message.Write(character.Position.Y);
|
|
||||||
|
|
||||||
|
|
||||||
//List<Client> playingClients = connectedClients.FindAll(c => c.Character != null);
|
|
||||||
|
|
||||||
//msg.Write((myCharacter == null) ? (byte)playingClients.Count : (byte)(playingClients.Count + 1));
|
|
||||||
//foreach (Client client in playingClients)
|
|
||||||
//{
|
|
||||||
// msg.Write(client.ID);
|
|
||||||
// WriteCharacterData(msg, client.Character.Name, client.Character);
|
|
||||||
//}
|
|
||||||
|
|
||||||
//if (myCharacter != null)
|
|
||||||
//{
|
|
||||||
// msg.Write((byte)0);
|
|
||||||
// WriteCharacterData(msg, myCharacter.Info.Name, myCharacter);
|
|
||||||
//}
|
|
||||||
|
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1310,14 +1118,10 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
Log(msg, ChatMessage.MessageColor[(int)ChatMessageType.Server]);
|
Log(msg, ChatMessage.MessageColor[(int)ChatMessageType.Server]);
|
||||||
|
|
||||||
|
client.Connection.Disconnect(targetmsg);
|
||||||
|
|
||||||
|
//notify other players about the disconnected client
|
||||||
NetOutgoingMessage outmsg = server.CreateMessage();
|
NetOutgoingMessage outmsg = server.CreateMessage();
|
||||||
outmsg.Write((byte)PacketTypes.KickedOut);
|
|
||||||
outmsg.Write(targetmsg);
|
|
||||||
server.SendMessage(outmsg, client.Connection, NetDeliveryMethod.ReliableUnordered, 0);
|
|
||||||
|
|
||||||
connectedClients.Remove(client);
|
|
||||||
|
|
||||||
outmsg = server.CreateMessage();
|
|
||||||
outmsg.Write((byte)PacketTypes.PlayerLeft);
|
outmsg.Write((byte)PacketTypes.PlayerLeft);
|
||||||
outmsg.Write(client.ID);
|
outmsg.Write(client.ID);
|
||||||
outmsg.Write(msg);
|
outmsg.Write(msg);
|
||||||
@@ -1329,6 +1133,7 @@ namespace Barotrauma.Networking
|
|||||||
server.SendMessage(outmsg, server.Connections, NetDeliveryMethod.ReliableUnordered, 0);
|
server.SendMessage(outmsg, server.Connections, NetDeliveryMethod.ReliableUnordered, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connectedClients.Remove(client);
|
||||||
if (client.FileStreamSender != null)
|
if (client.FileStreamSender != null)
|
||||||
{
|
{
|
||||||
client.FileStreamSender.Dispose();
|
client.FileStreamSender.Dispose();
|
||||||
@@ -1362,15 +1167,14 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
playerName = playerName.ToLowerInvariant();
|
playerName = playerName.ToLowerInvariant();
|
||||||
|
|
||||||
Client client = connectedClients.Find(c => c.name.ToLowerInvariant() == playerName ||
|
Client client = connectedClients.Find(c =>
|
||||||
(c.Character != null && c.Character.Name.ToLowerInvariant() == playerName));
|
c.name.ToLowerInvariant() == playerName ||
|
||||||
|
(c.Character != null && c.Character.Name.ToLowerInvariant() == playerName));
|
||||||
if (client == null) return;
|
|
||||||
|
|
||||||
KickClient(client, ban);
|
KickClient(client, ban);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void KickClient(Client client, bool ban = false)
|
public void KickClient(Client client, bool ban = false)
|
||||||
{
|
{
|
||||||
if (client == null) return;
|
if (client == null) return;
|
||||||
|
|
||||||
@@ -1519,10 +1323,10 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
if (y >= startY && y < startY + height - 120)
|
if (y >= startY && y < startY + height - 120)
|
||||||
{
|
{
|
||||||
spriteBatch.DrawString(GUI.SmallFont, c.name + ":", new Vector2(x + 10, y), clientColor);
|
spriteBatch.DrawString(GUI.SmallFont, c.name + " ("+c.Connection.RemoteEndPoint.Address.ToString()+")", new Vector2(x + 10, y), clientColor);
|
||||||
spriteBatch.DrawString(GUI.SmallFont, "Ping: " + (int)(c.Connection.AverageRoundtripTime * 1000.0f) + " ms", new Vector2(x + width - 100, y), clientColor);
|
spriteBatch.DrawString(GUI.SmallFont, "Ping: " + (int)(c.Connection.AverageRoundtripTime * 1000.0f) + " ms", new Vector2(x+20, y+10), clientColor);
|
||||||
}
|
}
|
||||||
if (y + 10 >= startY && y < startY + height - 130) spriteBatch.DrawString(GUI.SmallFont, "Resent messages: " + c.Connection.Statistics.ResentMessages, new Vector2(x + 10, y + 10), clientColor);
|
if (y + 25 >= startY && y < startY + height - 130) spriteBatch.DrawString(GUI.SmallFont, "Resent messages: " + c.Connection.Statistics.ResentMessages, new Vector2(x + 20, y + 20), clientColor);
|
||||||
|
|
||||||
resentMessages += (int)c.Connection.Statistics.ResentMessages;
|
resentMessages += (int)c.Connection.Statistics.ResentMessages;
|
||||||
|
|
||||||
@@ -1741,8 +1545,8 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
|
|
||||||
List<JobPrefab> jobPreferences = new List<JobPrefab>();
|
List<JobPrefab> jobPreferences = new List<JobPrefab>();
|
||||||
int count = message.ReadInt32();
|
int count = message.ReadByte();
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < Math.Min(count, 3); i++)
|
||||||
{
|
{
|
||||||
string jobName = message.ReadString();
|
string jobName = message.ReadString();
|
||||||
JobPrefab jobPrefab = JobPrefab.List.Find(jp => jp.Name == jobName);
|
JobPrefab jobPrefab = JobPrefab.List.Find(jp => jp.Name == jobName);
|
||||||
@@ -1960,7 +1764,6 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
banList.Save();
|
banList.Save();
|
||||||
|
|
||||||
|
|
||||||
if (registeredToMaster && restClient != null)
|
if (registeredToMaster && restClient != null)
|
||||||
{
|
{
|
||||||
var request = new RestRequest("masterserver2.php", Method.GET);
|
var request = new RestRequest("masterserver2.php", Method.GET);
|
||||||
@@ -1996,8 +1799,6 @@ namespace Barotrauma.Networking
|
|||||||
public string version;
|
public string version;
|
||||||
public bool inGame;
|
public bool inGame;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private List<Client> kickVoters;
|
private List<Client> kickVoters;
|
||||||
|
|
||||||
public bool ReadyToStart;
|
public bool ReadyToStart;
|
||||||
@@ -2039,6 +1840,27 @@ namespace Barotrauma.Networking
|
|||||||
jobPreferences = new List<JobPrefab>(JobPrefab.List.GetRange(0,3));
|
jobPreferences = new List<JobPrefab>(JobPrefab.List.GetRange(0,3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool IsValidName(string name)
|
||||||
|
{
|
||||||
|
if (name.Contains("\n") || name.Contains("\r\n")) return false;
|
||||||
|
|
||||||
|
return (name.All(c =>
|
||||||
|
c != ';' &&
|
||||||
|
c != ',' &&
|
||||||
|
c != '<' &&
|
||||||
|
c != '/'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string SanitizeName(string name)
|
||||||
|
{
|
||||||
|
if (name.Length > 20)
|
||||||
|
{
|
||||||
|
name = name.Substring(0, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
public T GetVote<T>(VoteType voteType)
|
public T GetVote<T>(VoteType voteType)
|
||||||
{
|
{
|
||||||
return (votes[(int)voteType] is T) ? (T)votes[(int)voteType] : default(T);
|
return (votes[(int)voteType] is T) ? (T)votes[(int)voteType] : default(T);
|
||||||
|
|||||||
@@ -0,0 +1,261 @@
|
|||||||
|
using Barotrauma.Networking.ReliableMessages;
|
||||||
|
using Lidgren.Network;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Barotrauma.Networking
|
||||||
|
{
|
||||||
|
class UnauthenticatedClient
|
||||||
|
{
|
||||||
|
public NetConnection Connection;
|
||||||
|
public int Nonce;
|
||||||
|
|
||||||
|
public float AuthTimer;
|
||||||
|
|
||||||
|
public UnauthenticatedClient(NetConnection connection, int nonce)
|
||||||
|
{
|
||||||
|
Connection = connection;
|
||||||
|
Nonce = nonce;
|
||||||
|
|
||||||
|
AuthTimer = 5.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
partial class GameServer : NetworkMember, IPropertyObject
|
||||||
|
{
|
||||||
|
List<UnauthenticatedClient> unauthenticatedClients = new List<UnauthenticatedClient>();
|
||||||
|
|
||||||
|
private void HandleConnectionApproval(NetIncomingMessage inc)
|
||||||
|
{
|
||||||
|
if ((PacketTypes)inc.ReadByte() != PacketTypes.Login) return;
|
||||||
|
|
||||||
|
if (banList.IsBanned(inc.SenderEndPoint.Address.ToString()))
|
||||||
|
{
|
||||||
|
inc.SenderConnection.Deny("You have been banned from the server");
|
||||||
|
DebugConsole.NewMessage("Banned player tried to join the server", Color.Red);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connectedClients.Any(c => c.Connection == inc.SenderConnection))
|
||||||
|
{
|
||||||
|
inc.SenderConnection.Deny("Connection error - already joined");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nonce = CryptoRandom.Instance.Next();
|
||||||
|
var msg = server.CreateMessage();
|
||||||
|
msg.Write(nonce);
|
||||||
|
|
||||||
|
unauthenticatedClients.Add(new UnauthenticatedClient(inc.SenderConnection, nonce));
|
||||||
|
|
||||||
|
inc.SenderConnection.Approve(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CheckAuthentication(NetIncomingMessage inc)
|
||||||
|
{
|
||||||
|
var unauthenticatedClient = unauthenticatedClients.Find(uc => uc.Connection == inc.SenderConnection);
|
||||||
|
if (unauthenticatedClient != null)
|
||||||
|
{
|
||||||
|
unauthenticatedClients.Remove(unauthenticatedClient);
|
||||||
|
|
||||||
|
NetEncryption algo = new NetXtea(server, password);
|
||||||
|
inc.Decrypt(algo);
|
||||||
|
|
||||||
|
int nonce = inc.ReadInt32();
|
||||||
|
if (nonce != unauthenticatedClient.Nonce)
|
||||||
|
{
|
||||||
|
inc.SenderConnection.Disconnect("Wrong password!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inc.SenderConnection.Disconnect("Authentication failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugConsole.NewMessage("New player has joined the server", Color.White);
|
||||||
|
|
||||||
|
byte userID;
|
||||||
|
string version = "", packageName = "", packageHash = "", name = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
userID = inc.ReadByte();
|
||||||
|
version = inc.ReadString();
|
||||||
|
packageName = inc.ReadString();
|
||||||
|
packageHash = inc.ReadString();
|
||||||
|
name = Client.SanitizeName(inc.ReadString());
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
inc.SenderConnection.Disconnect("Connection error - server failed to read your ConnectionApproval message");
|
||||||
|
DebugConsole.NewMessage("Connection error - server failed to read the ConnectionApproval message", Color.Red);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !DEBUG
|
||||||
|
if (string.IsNullOrWhiteSpace(name))
|
||||||
|
{
|
||||||
|
inc.SenderConnection.Disconnect("Invalid username");
|
||||||
|
DebugConsole.NewMessage(name + " couldn't join the server (name empty)", Color.Red);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (!Client.IsValidName(name))
|
||||||
|
{
|
||||||
|
inc.SenderConnection.Disconnect("Username contains illegal symbols");
|
||||||
|
DebugConsole.NewMessage(name + " couldn't join the server (username contains illegal symbols)", Color.Red);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (version != GameMain.Version.ToString())
|
||||||
|
{
|
||||||
|
inc.SenderConnection.Disconnect("Version " + GameMain.Version + " required to connect to the server (Your version: " + version + ")");
|
||||||
|
DebugConsole.NewMessage(name + " couldn't join the server (wrong game version)", Color.Red);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (packageName != GameMain.SelectedPackage.Name)
|
||||||
|
{
|
||||||
|
inc.SenderConnection.Disconnect("Your content package (" + packageName + ") doesn't match the server's version (" + GameMain.SelectedPackage.Name + ")");
|
||||||
|
DebugConsole.NewMessage(name + " couldn't join the server (wrong content package name)", Color.Red);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (packageHash != GameMain.SelectedPackage.MD5hash.Hash)
|
||||||
|
{
|
||||||
|
inc.SenderConnection.Disconnect("Your content package (MD5: " + packageHash + ") doesn't match the server's version (MD5: " + GameMain.SelectedPackage.MD5hash.Hash + ")");
|
||||||
|
DebugConsole.NewMessage(name + " couldn't join the server (wrong content package hash)", Color.Red);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (connectedClients.Any(c => c.name.ToLower() == name.ToLower() && c.Connection != inc.SenderConnection))
|
||||||
|
{
|
||||||
|
inc.SenderConnection.Disconnect("The name ''" + name + "'' is already in use. Please choose another name.");
|
||||||
|
DebugConsole.NewMessage(name + " couldn't join the server (name already in use)", Color.Red);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//existing user re-joining
|
||||||
|
if (userID > 0)
|
||||||
|
{
|
||||||
|
Client existingClient = connectedClients.Find(c =>
|
||||||
|
c.ID == userID &&
|
||||||
|
c.Connection == inc.SenderConnection);
|
||||||
|
|
||||||
|
if (existingClient == null)
|
||||||
|
{
|
||||||
|
existingClient = disconnectedClients.Find(c =>
|
||||||
|
c.ID == userID &&
|
||||||
|
c.Connection == inc.SenderConnection);
|
||||||
|
|
||||||
|
if (existingClient != null)
|
||||||
|
{
|
||||||
|
disconnectedClients.Remove(existingClient);
|
||||||
|
connectedClients.Add(existingClient);
|
||||||
|
|
||||||
|
UpdateCrewFrame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (existingClient != null)
|
||||||
|
{
|
||||||
|
existingClient.Connection = inc.SenderConnection;
|
||||||
|
existingClient.ReliableChannel = new ReliableChannel(server);
|
||||||
|
LogClientIn(inc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
userID = 1;
|
||||||
|
while (connectedClients.Any(c => c.ID == userID))
|
||||||
|
{
|
||||||
|
userID++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Client newClient = new Client(server, name, userID);
|
||||||
|
newClient.Connection = inc.SenderConnection;
|
||||||
|
newClient.version = version;
|
||||||
|
|
||||||
|
connectedClients.Add(newClient);
|
||||||
|
|
||||||
|
UpdateCrewFrame();
|
||||||
|
|
||||||
|
LogClientIn(inc);
|
||||||
|
|
||||||
|
refreshMasterTimer = DateTime.Now;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LogClientIn(NetIncomingMessage inc)
|
||||||
|
{
|
||||||
|
Client sender = connectedClients.Find(x => x.Connection == inc.SenderConnection);
|
||||||
|
|
||||||
|
if (sender == null) return;
|
||||||
|
|
||||||
|
if (sender.version != GameMain.Version.ToString())
|
||||||
|
{
|
||||||
|
DisconnectClient(sender, sender.name + " was unable to connect to the server (nonmatching game version)",
|
||||||
|
"Version " + GameMain.Version + " required to connect to the server (Your version: " + sender.version + ")");
|
||||||
|
}
|
||||||
|
else if (connectedClients.Find(x => x.name == sender.name && x != sender) != null)
|
||||||
|
{
|
||||||
|
DisconnectClient(sender, sender.name + " was unable to connect to the server (name already in use)",
|
||||||
|
"The name ''" + sender.name + "'' is already in use. Please choose another name.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//AssignJobs();
|
||||||
|
|
||||||
|
GameMain.NetLobbyScreen.RemovePlayer(sender.name);
|
||||||
|
GameMain.NetLobbyScreen.AddPlayer(sender.name);
|
||||||
|
|
||||||
|
// Notify the client that they have logged in
|
||||||
|
var outmsg = server.CreateMessage();
|
||||||
|
|
||||||
|
outmsg.Write((byte)PacketTypes.LoggedIn);
|
||||||
|
outmsg.Write(sender.ID);
|
||||||
|
outmsg.Write(gameStarted);
|
||||||
|
outmsg.Write(gameStarted && sender.Character != null && !sender.Character.IsDead);
|
||||||
|
outmsg.Write(AllowSpectating);
|
||||||
|
|
||||||
|
//notify the client about other clients already logged in
|
||||||
|
outmsg.Write((byte)((characterInfo == null) ? connectedClients.Count - 1 : connectedClients.Count));
|
||||||
|
foreach (Client c in connectedClients)
|
||||||
|
{
|
||||||
|
if (c.Connection == inc.SenderConnection) continue;
|
||||||
|
outmsg.Write(c.name);
|
||||||
|
outmsg.Write(c.ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (characterInfo != null)
|
||||||
|
{
|
||||||
|
outmsg.Write(characterInfo.Name);
|
||||||
|
outmsg.Write((byte)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
var subs = GameMain.NetLobbyScreen.GetSubList();
|
||||||
|
outmsg.Write((byte)subs.Count);
|
||||||
|
foreach (Submarine sub in subs)
|
||||||
|
{
|
||||||
|
outmsg.Write(sub.Name);
|
||||||
|
outmsg.Write(sub.MD5Hash.Hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
server.SendMessage(outmsg, inc.SenderConnection, NetDeliveryMethod.ReliableUnordered, 0);
|
||||||
|
|
||||||
|
//notify other clients about the new client
|
||||||
|
outmsg = server.CreateMessage();
|
||||||
|
outmsg.Write((byte)PacketTypes.PlayerJoined);
|
||||||
|
outmsg.Write(sender.name);
|
||||||
|
outmsg.Write(sender.ID);
|
||||||
|
|
||||||
|
//send the message to everyone except the client who just logged in
|
||||||
|
SendMessage(outmsg, NetDeliveryMethod.ReliableUnordered, inc.SenderConnection);
|
||||||
|
|
||||||
|
AddChatMessage(sender.name + " has joined the server", ChatMessageType.Server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,9 +13,9 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
Unknown,
|
Unknown,
|
||||||
|
|
||||||
Login, LoggedIn, LogOut,
|
Login, LoggedIn,
|
||||||
|
|
||||||
PlayerJoined, PlayerLeft, KickedOut,
|
PlayerJoined, PlayerLeft,
|
||||||
|
|
||||||
RequestNetLobbyUpdate,
|
RequestNetLobbyUpdate,
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user