Files
RAGECOOP-V/Server/Networking/Server.Connections.cs

187 lines
6.9 KiB
C#
Raw Normal View History

2022-10-23 19:02:39 +08:00
using System;
using System.Linq;
using Lidgren.Network;
2022-08-10 20:42:47 +08:00
using RageCoop.Core;
using RageCoop.Core.Scripting;
using RageCoop.Server.Scripting;
2022-10-23 19:02:39 +08:00
namespace RageCoop.Server;
public partial class Server
2022-08-10 20:42:47 +08:00
{
2022-10-23 19:02:39 +08:00
private void DisconnectAndLog(NetConnection senderConnection, PacketType type, Exception e)
2022-08-10 20:42:47 +08:00
{
2022-10-23 19:02:39 +08:00
Logger?.Error($"Error receiving a packet of type {type}");
Logger?.Error(e.Message);
Logger?.Error(e.StackTrace);
senderConnection.Disconnect(e.Message);
}
private void GetHandshake(NetConnection connection, Packets.Handshake packet)
{
Logger?.Debug("New handshake from: [Name: " + packet.Username + " | Address: " +
connection.RemoteEndPoint.Address + "]");
if (!packet.ModVersion.StartsWith(Version.ToString(3)))
2022-08-10 20:42:47 +08:00
{
2022-10-23 19:02:39 +08:00
connection.Deny($"RAGECOOP version {Version.ToString(3)} required!");
return;
2022-08-10 20:42:47 +08:00
}
2022-10-23 19:02:39 +08:00
if (string.IsNullOrWhiteSpace(packet.Username))
2022-08-10 20:42:47 +08:00
{
2022-10-23 19:02:39 +08:00
connection.Deny("Username is empty or contains spaces!");
return;
}
2022-09-05 13:02:09 +02:00
2022-10-23 19:02:39 +08:00
if (packet.Username.Any(p => !_allowedCharacterSet.Contains(p)))
{
connection.Deny("Username contains special chars!");
return;
}
2022-08-10 20:42:47 +08:00
2022-10-23 19:02:39 +08:00
if (ClientsByNetHandle.Values.Any(x => x.Username.ToLower() == packet.Username.ToLower()))
{
connection.Deny("Username is already taken!");
return;
}
try
{
Security.AddConnection(connection.RemoteEndPoint, packet.AesKeyCrypted, packet.AesIVCrypted);
var args = new HandshakeEventArgs
{
EndPoint = connection.RemoteEndPoint,
ID = packet.PedID,
Username = packet.Username,
PasswordHash = Security.Decrypt(packet.PasswordEncrypted, connection.RemoteEndPoint).GetString()
.GetSHA256Hash().ToHexString()
};
API.Events.InvokePlayerHandshake(args);
if (args.Cancel)
2022-08-10 20:42:47 +08:00
{
2022-10-23 19:02:39 +08:00
connection.Deny(args.DenyReason);
2022-08-10 20:42:47 +08:00
return;
}
2022-10-23 19:02:39 +08:00
}
catch (Exception ex)
{
Logger?.Error($"Cannot process handshake packet from {connection.RemoteEndPoint}");
Logger?.Error(ex);
connection.Deny("Malformed handshak packet!");
return;
}
2022-09-05 13:02:09 +02:00
2022-10-23 19:02:39 +08:00
var handshakeSuccess = MainNetServer.CreateMessage();
var currentClients = ClientsByID.Values.ToArray();
var players = new Packets.PlayerData[currentClients.Length];
for (var i = 0; i < players.Length; i++)
players[i] = new Packets.PlayerData
2022-08-10 20:42:47 +08:00
{
2022-10-23 19:02:39 +08:00
ID = currentClients[i].Player.ID,
Username = currentClients[i].Username
};
2022-09-05 13:02:09 +02:00
2022-10-23 19:02:39 +08:00
new Packets.HandshakeSuccess
{
Players = players
}.Pack(handshakeSuccess);
connection.Approve(handshakeSuccess);
Client tmpClient;
2022-08-10 20:42:47 +08:00
2022-10-23 19:02:39 +08:00
// Add the player to Players
lock (ClientsByNetHandle)
{
var player = new ServerPed(this)
2022-08-10 20:42:47 +08:00
{
2022-10-23 19:02:39 +08:00
ID = packet.PedID
};
Entities.Add(player);
ClientsByNetHandle.Add(connection.RemoteUniqueIdentifier,
tmpClient = new Client(this)
2022-08-10 20:42:47 +08:00
{
2022-10-23 19:02:39 +08:00
NetHandle = connection.RemoteUniqueIdentifier,
Connection = connection,
Username = packet.Username,
Player = player,
InternalEndPoint = packet.InternalEndPoint
2022-08-10 20:42:47 +08:00
}
2022-10-23 19:02:39 +08:00
);
player.Owner = tmpClient;
ClientsByName.Add(packet.Username.ToLower(), tmpClient);
ClientsByID.Add(player.ID, tmpClient);
if (ClientsByNetHandle.Count == 1) _hostClient = tmpClient;
}
2022-08-10 20:42:47 +08:00
2022-10-23 19:02:39 +08:00
Logger?.Debug($"Handshake sucess, Player:{packet.Username} PedID:{packet.PedID}");
}
2022-08-10 20:42:47 +08:00
2022-10-23 19:02:39 +08:00
// The connection has been approved, now we need to send all other players to the new player and the new player to all players
private void PlayerConnected(Client newClient)
{
if (newClient == _hostClient) API.SendCustomEvent(new List<Client> { newClient }, CustomEvents.IsHost, true);
2022-08-10 20:42:47 +08:00
2022-10-23 19:02:39 +08:00
// Send new client to all players
var cons = MainNetServer.Connections.Exclude(newClient.Connection);
if (cons.Count != 0)
2022-08-10 20:42:47 +08:00
{
2022-10-23 19:02:39 +08:00
var outgoingMessage = MainNetServer.CreateMessage();
new Packets.PlayerConnect
2022-08-10 20:42:47 +08:00
{
2022-10-23 19:02:39 +08:00
PedID = newClient.Player.ID,
Username = newClient.Username
}.Pack(outgoingMessage);
2022-08-10 20:42:47 +08:00
2022-10-23 19:02:39 +08:00
MainNetServer.SendMessage(outgoingMessage, cons, NetDeliveryMethod.ReliableOrdered, 0);
}
2022-08-10 20:42:47 +08:00
2022-10-23 19:02:39 +08:00
// Send all props to this player
BaseScript.SendServerPropsTo(new List<ServerProp>(Entities.ServerProps.Values), new List<Client> { newClient });
2022-08-10 20:42:47 +08:00
2022-10-23 19:02:39 +08:00
// Send all blips to this player
BaseScript.SendServerBlipsTo(new List<ServerBlip>(Entities.Blips.Values), new List<Client> { newClient });
2022-08-10 20:42:47 +08:00
2022-10-23 19:02:39 +08:00
// Create P2P connection
if (Settings.UseP2P)
ClientsByNetHandle.Values.ForEach(target =>
2022-08-10 20:42:47 +08:00
{
2022-10-23 19:02:39 +08:00
if (target == newClient) return;
HolePunch(target, newClient);
});
2022-08-10 20:42:47 +08:00
2022-10-23 19:02:39 +08:00
Logger?.Info($"Player {newClient.Username} connected!");
2022-08-10 20:42:47 +08:00
2022-10-23 19:02:39 +08:00
if (!string.IsNullOrEmpty(Settings.WelcomeMessage))
SendChatMessage("Server", Settings.WelcomeMessage, newClient);
}
2022-08-10 20:42:47 +08:00
2022-10-23 19:02:39 +08:00
// Send all players a message that someone has left the server
private void PlayerDisconnected(Client localClient)
{
var cons = MainNetServer.Connections.Exclude(localClient.Connection);
if (cons.Count != 0)
2022-08-10 20:42:47 +08:00
{
2022-10-23 19:02:39 +08:00
var outgoingMessage = MainNetServer.CreateMessage();
new Packets.PlayerDisconnect
2022-08-10 20:42:47 +08:00
{
2022-10-23 19:02:39 +08:00
PedID = localClient.Player.ID
}.Pack(outgoingMessage);
MainNetServer.SendMessage(outgoingMessage, cons, NetDeliveryMethod.ReliableOrdered, 0);
}
2022-08-10 20:42:47 +08:00
2022-10-23 19:02:39 +08:00
Entities.CleanUp(localClient);
QueueJob(() => API.Events.InvokePlayerDisconnected(localClient));
Logger?.Info($"Player {localClient.Username} disconnected! ID:{localClient.Player.ID}");
if (ClientsByNetHandle.ContainsKey(localClient.NetHandle)) ClientsByNetHandle.Remove(localClient.NetHandle);
if (ClientsByName.ContainsKey(localClient.Username.ToLower()))
ClientsByName.Remove(localClient.Username.ToLower());
if (ClientsByID.ContainsKey(localClient.Player.ID)) ClientsByID.Remove(localClient.Player.ID);
if (localClient == _hostClient)
{
_hostClient = ClientsByNetHandle.Values.FirstOrDefault();
_hostClient?.SendCustomEvent(CustomEvents.IsHost, true);
2022-08-10 20:42:47 +08:00
}
2022-10-23 19:02:39 +08:00
Security.RemoveConnection(localClient.Connection.RemoteEndPoint);
2022-08-10 20:42:47 +08:00
}
2022-10-23 19:02:39 +08:00
}