This commit is contained in:
sardelka9515
2022-10-23 19:02:39 +08:00
parent 6b34ab6e36
commit 2828b9b74f
114 changed files with 7374 additions and 7205 deletions

View File

@ -1,37 +1,47 @@
using GTA.UI;
using Lidgren.Network;
using RageCoop.Client.Scripting;
using RageCoop.Core;
using System;
using System;
using System.Collections.Generic;
using System.Net;
using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;
using GTA.UI;
using Lidgren.Network;
using RageCoop.Client.Menus;
using RageCoop.Client.Scripting;
using RageCoop.Core;
namespace RageCoop.Client
{
internal static partial class Networking
{
public static CoopPeer Peer;
public static float Latency => ServerConnection.AverageRoundtripTime / 2;
public static bool ShowNetworkInfo = false;
public static Security Security;
public static NetConnection ServerConnection;
private static readonly Dictionary<int, Action<PacketType, NetIncomingMessage>> PendingResponses = new Dictionary<int, Action<PacketType, NetIncomingMessage>>();
internal static readonly Dictionary<PacketType, Func<NetIncomingMessage, Packet>> RequestHandlers = new Dictionary<PacketType, Func<NetIncomingMessage, Packet>>();
private static readonly Dictionary<int, Action<PacketType, NetIncomingMessage>> PendingResponses =
new Dictionary<int, Action<PacketType, NetIncomingMessage>>();
internal static readonly Dictionary<PacketType, Func<NetIncomingMessage, Packet>> RequestHandlers =
new Dictionary<PacketType, Func<NetIncomingMessage, Packet>>();
internal static float SimulatedLatency = 0;
public static bool IsConnecting { get; private set; }
public static IPEndPoint _targetServerEP;
static Networking()
{
Security = new Security(Main.Logger);
Packets.CustomEvent.ResolveHandle = _resolveHandle;
}
public static void ToggleConnection(string address, string username = null, string password = null, PublicKey publicKey = null)
public static float Latency => ServerConnection.AverageRoundtripTime / 2;
public static bool IsConnecting { get; private set; }
public static bool IsOnServer => ServerConnection?.Status == NetConnectionStatus.Connected;
public static void ToggleConnection(string address, string username = null, string password = null,
PublicKey publicKey = null)
{
Menus.CoopMenu.Menu.Visible = false;
CoopMenu.Menu.Visible = false;
Peer?.Shutdown("Bye");
if (IsOnServer)
{
@ -52,7 +62,7 @@ namespace RageCoop.Client
username = username ?? Main.Settings.Username;
// 623c92c287cc392406e7aaaac1c0f3b0 = RAGECOOP
NetPeerConfiguration config = new NetPeerConfiguration("623c92c287cc392406e7aaaac1c0f3b0")
var config = new NetPeerConfiguration("623c92c287cc392406e7aaaac1c0f3b0")
{
AutoFlushSendQueue = false,
SimulatedMinimumLatency = SimulatedLatency,
@ -65,27 +75,26 @@ namespace RageCoop.Client
config.EnableMessageType(NetIncomingMessageType.UnconnectedData);
config.EnableMessageType(NetIncomingMessageType.NatIntroductionSuccess);
string[] ip = new string[2];
var ip = new string[2];
int idx = address.LastIndexOf(':');
var 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");
}
if (ip.Length != 2) throw new Exception("Malformed URL");
PlayerList.Cleanup();
EntityPool.AddPlayer();
if (publicKey == null && !string.IsNullOrEmpty(password) && !Menus.CoopMenu.ShowPopUp("", "WARNING", "Server's IP can be spoofed when using direct connection, do you wish to continue?", "", true))
if (publicKey == null && !string.IsNullOrEmpty(password) && !CoopMenu.ShowPopUp("", "WARNING",
"Server's IP can be spoofed when using direct connection, do you wish to continue?", "", true))
{
IsConnecting = false;
return;
}
Task.Run(() =>
{
try
@ -97,17 +106,23 @@ namespace RageCoop.Client
Peer = new CoopPeer(config);
Peer.OnMessageReceived += (s, m) =>
{
try { ProcessMessage(m); }
catch (Exception ex) { Main.Logger.Error(ex); }
try
{
ProcessMessage(m);
}
catch (Exception ex)
{
Main.Logger.Error(ex);
}
};
API.QueueAction(() => { Notification.Show($"~y~Trying to connect..."); });
Menus.CoopMenu._serverConnectItem.Enabled = false;
API.QueueAction(() => { Notification.Show("~y~Trying to connect..."); });
CoopMenu._serverConnectItem.Enabled = false;
Security.Regen();
if (publicKey == null)
{
if (!GetServerPublicKey(ip[0], int.Parse(ip[1])))
{
Menus.CoopMenu._serverConnectItem.Enabled = true;
CoopMenu._serverConnectItem.Enabled = true;
throw new TimeoutException("Failed to retrive server's public key");
}
}
@ -117,60 +132,79 @@ namespace RageCoop.Client
}
// Send handshake packet
NetOutgoingMessage outgoingMessage = Peer.CreateMessage();
var handshake = new Packets.Handshake()
var outgoingMessage = Peer.CreateMessage();
var handshake = new Packets.Handshake
{
PedID = Main.LocalPlayerID,
Username = username,
ModVersion = Main.Version.ToString(),
PasswordEncrypted = Security.Encrypt(password.GetBytes()),
InternalEndPoint = new System.Net.IPEndPoint(CoreUtils.GetLocalAddress(ip[0]), Peer.Port)
InternalEndPoint = new IPEndPoint(CoreUtils.GetLocalAddress(ip[0]), Peer.Port)
};
Security.GetSymmetricKeysCrypted(out handshake.AesKeyCrypted, out handshake.AesIVCrypted);
handshake.Pack(outgoingMessage);
ServerConnection = Peer.Connect(ip[0], short.Parse(ip[1]), outgoingMessage);
}
catch (Exception ex)
{
Main.Logger.Error("Cannot connect to server: ", ex);
API.QueueAction(() => Notification.Show("Cannot connect to server: " + ex.Message));
}
IsConnecting = false;
});
}
}
public static bool IsOnServer => ServerConnection?.Status == NetConnectionStatus.Connected;
private static int NewRequestID()
{
var ID = 0;
while (ID == 0 || PendingResponses.ContainsKey(ID))
{
var rngBytes = new byte[4];
RandomNumberGenerator.Create().GetBytes(rngBytes);
// Convert the bytes into an integer
ID = BitConverter.ToInt32(rngBytes, 0);
}
return ID;
}
#region -- PLAYER --
private static void PlayerConnect(Packets.PlayerConnect packet)
{
var p = new Player
{
ID = packet.PedID,
Username = packet.Username,
Username = packet.Username
};
PlayerList.SetPlayer(packet.PedID, packet.Username);
Main.Logger.Debug($"player connected:{p.Username}");
API.QueueAction(() =>
GTA.UI.Notification.Show($"~h~{p.Username}~h~ connected."));
Notification.Show($"~h~{p.Username}~h~ connected."));
}
private static void PlayerDisconnect(Packets.PlayerDisconnect packet)
{
var player = PlayerList.GetPlayer(packet.PedID);
if (player == null) { return; }
if (player == null) return;
PlayerList.RemovePlayer(packet.PedID);
API.QueueAction(() =>
{
EntityPool.RemoveAllFromPlayer(packet.PedID);
GTA.UI.Notification.Show($"~h~{player.Username}~h~ left.");
Notification.Show($"~h~{player.Username}~h~ left.");
});
}
#endregion // -- PLAYER --
#region -- GET --
private static bool GetServerPublicKey(string host, int port, int timeout = 10000)
{
Security.ServerRSA = null;
@ -180,7 +214,8 @@ namespace RageCoop.Client
return _publicKeyReceived.WaitOne(timeout) && Security.ServerRSA != null;
}
public static void GetResponse<T>(Packet request, Action<T> callback, ConnectionChannel channel = ConnectionChannel.RequestResponse) where T : Packet, new()
public static void GetResponse<T>(Packet request, Action<T> callback,
ConnectionChannel channel = ConnectionChannel.RequestResponse) where T : Packet, new()
{
var received = new AutoResetEvent(false);
var id = NewRequestID();
@ -198,20 +233,5 @@ namespace RageCoop.Client
}
#endregion
private static int NewRequestID()
{
int ID = 0;
while ((ID == 0) || PendingResponses.ContainsKey(ID))
{
byte[] rngBytes = new byte[4];
RandomNumberGenerator.Create().GetBytes(rngBytes);
// Convert the bytes into an integer
ID = BitConverter.ToInt32(rngBytes, 0);
}
return ID;
}
}
}
}