Some stuff for the upcoming change

This commit is contained in:
Sardelka
2022-08-06 12:32:04 +08:00
parent ca5ef8cf4c
commit a50be5b869
11 changed files with 90 additions and 73 deletions

View File

@ -10,10 +10,11 @@ namespace RageCoop.Client
{
internal static partial class Networking
{
public static NetClient Client;
public static NetPeer Peer;
public static float Latency = 0;
public static bool ShowNetworkInfo = false;
public static Security Security;
public static Security Security;
public static NetConnection ServerConnection;
private static readonly Dictionary<int, Action<PacketType, byte[]>> PendingResponses = new Dictionary<int, Action<PacketType, byte[]>>();
internal static readonly Dictionary<PacketType, Func<byte[], Packet>> RequestHandlers = new Dictionary<PacketType, Func<byte[], Packet>>();
internal static float SimulatedLatency=0;
@ -29,9 +30,9 @@ namespace RageCoop.Client
{
while (true)
{
if (Client!=null)
if (Peer!=null)
{
ProcessMessage(Client.WaitMessage(200));
ProcessMessage(Peer.WaitMessage(200));
}
else
{
@ -45,7 +46,7 @@ namespace RageCoop.Client
{
if (IsOnServer)
{
Client.Disconnect("Bye!");
Peer.Shutdown("Bye!");
}
else if (IsConnecting) {
_publicKeyReceived.Set();
@ -63,10 +64,11 @@ namespace RageCoop.Client
{
AutoFlushSendQueue = false,
SimulatedMinimumLatency =SimulatedLatency,
AcceptIncomingConnections = true
};
config.EnableMessageType(NetIncomingMessageType.UnconnectedData);
config.EnableMessageType(NetIncomingMessageType.NatIntroductionSuccess);
string[] ip = new string[2];
@ -89,8 +91,8 @@ namespace RageCoop.Client
try
{
DownloadManager.Cleanup();
Client = new NetClient(config);
Client.Start();
Peer = new NetClient(config);
Peer.Start();
Main.QueueAction(() => { GTA.UI.Notification.Show($"~y~Trying to connect..."); });
Menus.CoopMenu._serverConnectItem.Enabled=false;
Security.Regen();
@ -101,18 +103,19 @@ namespace RageCoop.Client
}
// Send HandshakePacket
NetOutgoingMessage outgoingMessage = Client.CreateMessage();
NetOutgoingMessage outgoingMessage = Peer.CreateMessage();
var handshake = new Packets.Handshake()
{
PedID = Main.LocalPlayerID,
Username =username,
ModVersion = Main.CurrentVersion,
PasswordEncrypted=Security.Encrypt(password.GetBytes())
PasswordEncrypted=Security.Encrypt(password.GetBytes()),
InternalEndPoint = (System.Net.IPEndPoint)Peer.Socket.LocalEndPoint
};
Security.GetSymmetricKeysCrypted(out handshake.AesKeyCrypted, out handshake.AesIVCrypted);
handshake.Pack(outgoingMessage);
Client.Connect(ip[0], short.Parse(ip[1]), outgoingMessage);
ServerConnection = Peer.Connect(ip[0], short.Parse(ip[1]), outgoingMessage);
}
catch (Exception ex)
@ -126,7 +129,7 @@ namespace RageCoop.Client
}
public static bool IsOnServer
{
get { return Client?.ConnectionStatus == NetConnectionStatus.Connected; }
get { return ServerConnection?.Status == NetConnectionStatus.Connected; }
}
#region -- PLAYER --
@ -158,10 +161,10 @@ namespace RageCoop.Client
private static bool GetServerPublicKey(string address, int timeout = 10000)
{
Security.ServerRSA=null;
var msg = Client.CreateMessage();
var msg = Peer.CreateMessage();
new Packets.PublicKeyRequest().Pack(msg);
var adds = address.Split(':');
Client.SendUnconnectedMessage(msg, adds[0], int.Parse(adds[1]));
Peer.SendUnconnectedMessage(msg, adds[0], int.Parse(adds[1]));
return _publicKeyReceived.WaitOne(timeout) && Security.ServerRSA!=null;
}
@ -175,11 +178,11 @@ namespace RageCoop.Client
result.Deserialize(p);
callback(result);
});
var msg = Client.CreateMessage();
var msg = Peer.CreateMessage();
msg.Write((byte)PacketType.Request);
msg.Write(id);
request.Pack(msg);
Client.SendMessage(msg, NetDeliveryMethod.ReliableOrdered, (int)channel);
Peer.SendMessage(msg,ServerConnection, NetDeliveryMethod.ReliableOrdered, (int)channel);
}
#endregion

View File

@ -58,23 +58,24 @@ namespace RageCoop.Client
Main.Logger.Info(">> Connected <<");
break;
case NetConnectionStatus.Disconnected:
Memory.RestorePatches();
DownloadManager.Cleanup();
if (Main.MainChat.Focused)
if (message.SenderConnection==ServerConnection)
{
Main.MainChat.Focused = false;
Memory.RestorePatches();
DownloadManager.Cleanup();
if (Main.MainChat.Focused)
{
Main.MainChat.Focused = false;
}
Main.QueueAction(() => Main.CleanUp());
CoopMenu.DisconnectedMenuSetting();
Main.Logger.Info($">> Disconnected << reason: {reason}");
Main.QueueAction(() =>
GTA.UI.Notification.Show("~r~Disconnected: " + reason));
Main.Resources.Unload();
}
Main.QueueAction(() => Main.CleanUp());
#if !NON_INTERACTIVE
CoopMenu.DisconnectedMenuSetting();
#endif
Main.Logger.Info($">> Disconnected << reason: {reason}");
Main.QueueAction(() =>
GTA.UI.Notification.Show("~r~Disconnected: " + reason));
Main.Resources.Unload();
break;
@ -109,12 +110,12 @@ namespace RageCoop.Client
int len = message.ReadInt32();
if (RequestHandlers.TryGetValue(realType, out var handler))
{
var response = Client.CreateMessage();
var response = Peer.CreateMessage();
response.Write((byte)PacketType.Response);
response.Write(id);
handler(message.ReadBytes(len)).Pack(response);
Client.SendMessage(response, NetDeliveryMethod.ReliableOrdered, message.SequenceChannel);
Client.FlushSendQueue();
Peer.SendMessage(response,ServerConnection, NetDeliveryMethod.ReliableOrdered, message.SequenceChannel);
Peer.FlushSendQueue();
}
break;
}
@ -136,7 +137,7 @@ namespace RageCoop.Client
});
Main.Logger.Error($"[{packetType}] {ex.Message}");
Main.Logger.Error(ex);
Client.Disconnect($"Packet Error [{packetType}]");
Peer.Shutdown($"Packet Error [{packetType}]");
}
break;
}
@ -164,7 +165,7 @@ namespace RageCoop.Client
break;
}
Client.Recycle(message);
Peer.Recycle(message);
}
private static void HandlePacket(PacketType packetType, byte[] data)
{

View File

@ -20,9 +20,9 @@ namespace RageCoop.Client
/// <param name="method"></param>
public static void Send(Packet p, ConnectionChannel channel = ConnectionChannel.Default, NetDeliveryMethod method = NetDeliveryMethod.UnreliableSequenced)
{
NetOutgoingMessage outgoingMessage = Client.CreateMessage();
NetOutgoingMessage outgoingMessage = Peer.CreateMessage();
p.Pack(outgoingMessage);
Client.SendMessage(outgoingMessage, method, (int)channel);
Peer.SendMessage(outgoingMessage,ServerConnection, method, (int)channel);
}
public static void SendPed(SyncedPed c, bool full)
@ -176,15 +176,15 @@ namespace RageCoop.Client
#endregion
public static void SendChatMessage(string message)
{
NetOutgoingMessage outgoingMessage = Client.CreateMessage();
NetOutgoingMessage outgoingMessage = Peer.CreateMessage();
new Packets.ChatMessage(new Func<string, byte[]>((s) =>
{
return Security.Encrypt(s.GetBytes());
})) { Username = Main.Settings.Username, Message = message }.Pack(outgoingMessage);
Client.SendMessage(outgoingMessage, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Chat);
Client.FlushSendQueue();
Peer.SendMessage(outgoingMessage,ServerConnection, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Chat);
Peer.FlushSendQueue();
#if DEBUG
#endif

View File

@ -13,11 +13,11 @@ namespace RageCoop.Client
{
while (true)
{
var bu = Networking.Client.Statistics.SentBytes;
var bd = Networking.Client.Statistics.ReceivedBytes;
var bu = Networking.Peer.Statistics.SentBytes;
var bd = Networking.Peer.Statistics.ReceivedBytes;
Thread.Sleep(1000);
BytesUpPerSecond=Networking.Client.Statistics.SentBytes-bu;
BytesDownPerSecond=Networking.Client.Statistics.ReceivedBytes-bd;
BytesUpPerSecond=Networking.Peer.Statistics.SentBytes-bu;
BytesDownPerSecond=Networking.Peer.Statistics.ReceivedBytes-bd;
}
});
}

View File

@ -173,7 +173,7 @@ namespace RageCoop.Client.Scripting
/// <summary>
/// Get an <see cref="System.Net.IPEndPoint"/> that the player is currently connected to, or null if not connected to the server
/// </summary>
public static System.Net.IPEndPoint ServerEndPoint { get { return Networking.IsOnServer ? Networking.Client?.ServerConnection.RemoteEndPoint : null; } }
public static System.Net.IPEndPoint ServerEndPoint { get { return Networking.IsOnServer ? Networking.ServerConnection?.RemoteEndPoint : null; } }
/// <summary>
/// Check if a RAGECOOP menu is visible

View File

@ -561,7 +561,7 @@ namespace RageCoop.Client
#endif
}
ThreadPool.QueueUserWorkItem((o) => { Networking.Client.FlushSendQueue(); });
ThreadPool.QueueUserWorkItem((o) => { Networking.Peer.FlushSendQueue(); });
}

View File

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Net;
namespace RageCoop.Core
{
@ -21,20 +20,17 @@ namespace RageCoop.Core
internal class ConnectionRequest : Packet
{
public int TargetID { get; set; }
public IPEndPoint InternalEndPoint { get; set; }
public override PacketType Type => PacketType.ConnectionRequest;
public override byte[] Serialize()
{
var data=new List<byte>(10);
data.AddInt(TargetID);
data.AddString(InternalEndPoint.ToString());
return data.ToArray();
}
public override void Deserialize(byte[] array)
{
var reader=new BitReader(array);
TargetID = reader.ReadInt32();
InternalEndPoint=CoreUtils.StringToEndPoint(reader.ReadString());
}
}
}

View File

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
using Lidgren.Network;
using System.Net;
namespace RageCoop.Core
{
@ -32,6 +32,7 @@ namespace RageCoop.Core
/// </summary>
public byte[] PasswordEncrypted { get; set; }
public IPEndPoint InternalEndPoint { get; set; }
public override byte[] Serialize()
{
@ -50,6 +51,8 @@ namespace RageCoop.Core
byteArray.AddRange(BitConverter.GetBytes(modVersionBytes.Length));
byteArray.AddRange(modVersionBytes);
byteArray.AddString(InternalEndPoint.ToString());
// Write AesKeyCrypted
byteArray.AddArray(AesKeyCrypted);
@ -78,6 +81,8 @@ namespace RageCoop.Core
// Read ModVersion
ModVersion = reader.ReadString();
InternalEndPoint=CoreUtils.StringToEndPoint(reader.ReadString());
AesKeyCrypted=reader.ReadByteArray();
AesIVCrypted=reader.ReadByteArray();

View File

@ -6,6 +6,7 @@ using System.Diagnostics;
using RageCoop.Core.Scripting;
using System.Security.Cryptography;
using RageCoop.Server.Scripting;
using System.Net;
namespace RageCoop.Server
{
@ -22,8 +23,14 @@ namespace RageCoop.Server
/// <summary>
/// Th client's IP address and port.
/// </summary>
public System.Net.IPEndPoint EndPoint { get { return Connection?.RemoteEndPoint; } }
internal long NetID = 0;
public IPEndPoint EndPoint { get { return Connection?.RemoteEndPoint; } }
/// <summary>
/// Internal(LAN) address of this client, used for NAT hole-punching
/// </summary>
public IPEndPoint InternalEndPoint { get; internal set; }
internal long NetHandle = 0;
internal NetConnection Connection { get;set; }
/// <summary>
/// The <see cref="ServerPed"/> instance representing the client's main character.

View File

@ -179,10 +179,10 @@ namespace RageCoop.Server.Scripting
/// <summary>
/// Get a list of all Clients
/// </summary>
/// <returns>All clients as a dictionary indexed by NetID</returns>
public Dictionary<string, Client> GetAllClients()
/// <returns>All clients as a dictionary indexed by their main character's id</returns>
public Dictionary<int, Client> GetAllClients()
{
return new(Server.ClientsByName);
return new(Server.ClientsByID);
}
/// <summary>

View File

@ -46,6 +46,7 @@ namespace RageCoop.Server
internal readonly Dictionary<Command, Action<CommandContext>> Commands = new();
internal readonly Dictionary<long,Client> ClientsByNetHandle = new();
internal readonly Dictionary<string, Client> ClientsByName = new();
internal readonly Dictionary<int, Client> ClientsByID = new();
internal Client _hostClient;
private Dictionary<int,FileTransfer> InProgressFileTransfers=new();
@ -449,39 +450,31 @@ namespace RageCoop.Server
Packets.PedSync packet = new();
packet.Deserialize(data);
PedSync(packet, sender);
}
break;
case PacketType.VehicleSync:
{
Packets.VehicleSync packet = new();
packet.Deserialize(data);
VehicleSync(packet, sender);
}
break;
case PacketType.ProjectileSync:
{
Packets.ProjectileSync packet = new();
packet.Deserialize(data);
ProjectileSync(packet, sender);
}
break;
case PacketType.ChatMessage:
{
Packets.ChatMessage packet = new((b) =>
{
return Security.Decrypt(b,sender.EndPoint);
});
packet.Deserialize(data);
ChatMessageReceived(packet.Username,packet.Message, sender);
}
break;
@ -492,7 +485,16 @@ namespace RageCoop.Server
_worker.QueueJob(() => API.Events.InvokeCustomEventReceived(packet, sender));
}
break;
case PacketType.ConnectionRequest:
{
var p=new Packets.ConnectionRequest();
p.Deserialize(data);
if (ClientsByID.TryGetValue(p.TargetID,out var target))
{
MainNetServer.Introduce(target.InternalEndPoint,target.EndPoint,sender.InternalEndPoint,sender.EndPoint,Guid.NewGuid().ToString());
}
break;
}
default:
Logger?.Error("Unhandled Data / Packet type");
break;
@ -576,13 +578,15 @@ namespace RageCoop.Server
ClientsByNetHandle.Add(connection.RemoteUniqueIdentifier,
tmpClient = new Client(this)
{
NetID = connection.RemoteUniqueIdentifier,
NetHandle = connection.RemoteUniqueIdentifier,
Connection=connection,
Username=packet.Username,
Player = player
Player = player,
InternalEndPoint=packet.InternalEndPoint,
}
);
ClientsByName.Add(packet.Username.ToLower(), tmpClient);
ClientsByID.Add(player.ID, tmpClient);
if (ClientsByNetHandle.Count==1) {
_hostClient=tmpClient;
}
@ -661,8 +665,9 @@ namespace RageCoop.Server
Entities.CleanUp(localClient);
_worker.QueueJob(() => API.Events.InvokePlayerDisconnected(localClient));
Logger?.Info($"Player {localClient.Username} disconnected! ID:{localClient.Player.ID}");
ClientsByNetHandle.Remove(localClient.NetID);
ClientsByName.Remove(localClient.Username.ToLower());
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)
{
@ -689,7 +694,7 @@ namespace RageCoop.Server
{
// Don't send data back
if (c.NetID==client.NetID) { continue; }
if (c.NetHandle==client.NetHandle) { continue; }
// Check streaming distance
if (isPlayer)
@ -715,7 +720,7 @@ namespace RageCoop.Server
bool isPlayer = packet.ID==client.Player?.LastVehicle?.ID;
foreach (var c in ClientsByNetHandle.Values)
{
if (c.NetID==client.NetID) { continue; }
if (c.NetHandle==client.NetHandle) { continue; }
if (isPlayer)
{
// Player's vehicle
@ -739,7 +744,7 @@ namespace RageCoop.Server
foreach (var c in ClientsByNetHandle.Values)
{
if (c.NetID==client.NetID) { continue; }
if (c.NetHandle==client.NetHandle) { continue; }
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
packet.Pack(outgoingMessage);
MainNetServer.SendMessage(outgoingMessage, c.Connection, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PedSync);