2022-07-01 14:39:43 +08:00

140 lines
4.6 KiB
C#

using System;
using Lidgren.Network;
using RageCoop.Core;
using System.Threading.Tasks;
using System.Threading;
namespace RageCoop.Client
{
internal static partial class Networking
{
public static NetClient Client;
public static float Latency = 0;
public static bool ShowNetworkInfo = false;
public static Security Security;
static Networking()
{
Security=new Security(Main.Logger);
Task.Run(() =>
{
while (true)
{
if (Client!=null)
{
ProcessMessage(Client.WaitMessage(200));
Client.FlushSendQueue();
}
else
{
Thread.Sleep(20);
}
}
});
}
public static void ToggleConnection(string address,string username=null,string password=null)
{
if (IsOnServer)
{
Client.Disconnect("Bye!");
}
else
{
password = password ?? Main.Settings.Password;
username=username ?? Main.Settings.Username;
// 623c92c287cc392406e7aaaac1c0f3b0 = RAGECOOP
NetPeerConfiguration config = new NetPeerConfiguration("623c92c287cc392406e7aaaac1c0f3b0")
{
AutoFlushSendQueue = true
};
config.EnableMessageType(NetIncomingMessageType.ConnectionLatencyUpdated);
config.EnableMessageType(NetIncomingMessageType.UnconnectedData);
string[] ip = new string[2];
int idx = address.LastIndexOf(':');
if (idx != -1)
{
ip[0] = address.Substring(0, idx);
ip[1] = address.Substring(idx + 1);
}
if (ip.Length != 2)
{
throw new Exception("Malformed URL");
}
EntityPool.AddPlayer();
Task.Run(() =>
{
Client = new NetClient(config);
Client.Start();
Main.QueueAction(() => { GTA.UI.Notification.Show($"~y~Trying to connect..."); });
DownloadManager.Cleanup();
Security.Regen();
GetServerPublicKey(address);
// Send HandshakePacket
NetOutgoingMessage outgoingMessage = Client.CreateMessage();
var handshake=new Packets.Handshake()
{
PedID = Main.LocalPlayerID,
Username =username,
ModVersion = Main.CurrentVersion,
PassHashEncrypted=Security.Encrypt(password.GetHash())
};
Security.GetSymmetricKeysCrypted(out handshake.AesKeyCrypted,out handshake.AesIVCrypted);
handshake.Pack(outgoingMessage);
Client.Connect(ip[0], short.Parse(ip[1]), outgoingMessage);
});
}
}
public static bool IsOnServer
{
get { return Client?.ConnectionStatus == NetConnectionStatus.Connected; }
}
#region -- GET --
#region -- PLAYER --
private static void PlayerConnect(Packets.PlayerConnect packet)
{
var p = new PlayerData
{
PedID = packet.PedID,
Username= packet.Username,
};
GTA.UI.Notification.Show($"{p.Username} connected.");
PlayerList.SetPlayer(packet.PedID, packet.Username);
Main.Logger.Debug($"player connected:{p.Username}");
}
private static void PlayerDisconnect(Packets.PlayerDisconnect packet)
{
var name=PlayerList.GetPlayer(packet.PedID).Username;
GTA.UI.Notification.Show($"{name} left.");
PlayerList.RemovePlayer(packet.PedID);
EntityPool.RemoveAllFromPlayer(packet.PedID);
}
#endregion // -- PLAYER --
private static void GetServerPublicKey(string address,int timeout=10000)
{
var msg=Client.CreateMessage();
new Packets.PublicKeyRequest().Pack(msg);
var adds =address.Split(':');
Client.SendUnconnectedMessage(msg,adds[0],int.Parse(adds[1]));
PublicKeyReceived.WaitOne(timeout);
}
#endregion
}
}