211 lines
6.9 KiB
C#
Raw Normal View History

2022-05-22 15:55:26 +08:00
using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using Lidgren.Network;
using RageCoop.Core;
using System.Threading.Tasks;
using System.Threading;
using GTA.Math;
2022-05-22 15:55:26 +08:00
using GTA.Native;
namespace RageCoop.Client
{
internal static partial class Networking
2022-05-22 15:55:26 +08:00
{
public static NetClient Client;
public static float Latency = 0;
public static bool ShowNetworkInfo = false;
static Networking()
{
Task.Run(() =>
{
while (true)
{
if (Client!=null)
{
ProcessMessage(Client.WaitMessage(200));
Client.FlushSendQueue();
}
else
{
Thread.Sleep(20);
}
}
});
}
2022-05-31 23:12:32 -08:00
public static void ToggleConnection(string address)
2022-05-22 15:55:26 +08:00
{
if (IsOnServer)
2022-05-22 15:55:26 +08:00
{
Client.Disconnect("Bye!");
}
else
{
// 623c92c287cc392406e7aaaac1c0f3b0 = RAGECOOP
NetPeerConfiguration config = new NetPeerConfiguration("623c92c287cc392406e7aaaac1c0f3b0")
{
AutoFlushSendQueue = true
2022-05-22 15:55:26 +08:00
};
config.EnableMessageType(NetIncomingMessageType.ConnectionLatencyUpdated);
Client = new NetClient(config);
Client.Start();
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");
}
2022-05-22 15:55:26 +08:00
EntityPool.AddPlayer();
// Send HandshakePacket
2022-05-22 15:55:26 +08:00
NetOutgoingMessage outgoingMessage = Client.CreateMessage();
new Packets.Handshake()
{
PedID = Main.LocalPlayerID,
2022-05-22 15:55:26 +08:00
Username = Main.Settings.Username,
ModVersion = Main.CurrentVersion,
}.Pack(outgoingMessage);
Client.Connect(ip[0], short.Parse(ip[1]), outgoingMessage);
}
}
public static bool IsOnServer
2022-05-22 15:55:26 +08:00
{
get { return Client?.ConnectionStatus == NetConnectionStatus.Connected; }
2022-05-22 15:55:26 +08:00
}
#region -- GET --
#region -- PLAYER --
private static void PlayerConnect(Packets.PlayerConnect packet)
2022-05-22 15:55:26 +08:00
{
var p = new PlayerData
{
PedID = packet.PedID,
Username= packet.Username,
};
GTA.UI.Notification.Show($"{p.Username} connected.");
PlayerList.SetPlayer(packet.PedID, packet.Username);
2022-05-22 15:55:26 +08:00
Main.Logger.Debug($"player connected:{p.Username}");
}
private static void PlayerDisconnect(Packets.PlayerDisconnect packet)
2022-05-22 15:55:26 +08:00
{
var name=PlayerList.GetPlayer(packet.PedID).Username;
2022-05-22 15:55:26 +08:00
GTA.UI.Notification.Show($"{name} left.");
PlayerList.RemovePlayer(packet.PedID);
2022-05-22 15:55:26 +08:00
EntityPool.RemoveAllFromPlayer(packet.PedID);
}
private static object DecodeNativeCall(ulong hash, List<object> args, bool returnValue, byte? returnType = null)
2022-05-22 15:55:26 +08:00
{
List<InputArgument> arguments = new List<InputArgument>();
if (args == null || args.Count == 0)
{
return null;
}
for (ushort i = 0; i < args.Count; i++)
{
object x = args.ElementAt(i);
switch (x)
{
case int _:
arguments.Add((int)x);
break;
case bool _:
arguments.Add((bool)x);
break;
case float _:
arguments.Add((float)x);
break;
case string _:
arguments.Add((string)x);
break;
case Vector3 _:
Vector3 vector = (Vector3)x;
2022-05-22 15:55:26 +08:00
arguments.Add((float)vector.X);
arguments.Add((float)vector.Y);
arguments.Add((float)vector.Z);
break;
default:
GTA.UI.Notification.Show("[DecodeNativeCall][" + hash + "]: Type of argument not found!");
return null;
}
}
if (!returnValue)
{
Function.Call((Hash)hash, arguments.ToArray());
return null;
}
switch (returnType.Value)
{
case 0x00: // int
return Function.Call<int>((Hash)hash, arguments.ToArray());
case 0x01: // bool
return Function.Call<bool>((Hash)hash, arguments.ToArray());
case 0x02: // float
return Function.Call<float>((Hash)hash, arguments.ToArray());
case 0x03: // string
return Function.Call<string>((Hash)hash, arguments.ToArray());
case 0x04: // vector3
return Function.Call<Vector3>((Hash)hash, arguments.ToArray());
2022-05-22 15:55:26 +08:00
default:
GTA.UI.Notification.Show("[DecodeNativeCall][" + hash + "]: Type of return not found!");
return null;
}
}
private static void DecodeNativeCallWithResponse(Packets.NativeResponse packet)
2022-05-22 15:55:26 +08:00
{
object result = DecodeNativeCall(packet.Hash, packet.Args, true, packet.ResultType);
if (Main.CheckNativeHash.ContainsKey(packet.Hash))
{
foreach (KeyValuePair<ulong, byte> hash in Main.CheckNativeHash)
{
if (hash.Key == packet.Hash)
{
lock (Main.ServerItems)
{
Main.ServerItems.Add((int)result, hash.Value);
}
break;
}
}
}
NetOutgoingMessage outgoingMessage = Client.CreateMessage();
new Packets.NativeResponse()
{
Hash = 0,
Args = new List<object>() { result },
ID = packet.ID
}.Pack(outgoingMessage);
Client.SendMessage(outgoingMessage, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Native);
Client.FlushSendQueue();
}
#endregion // -- PLAYER --
#endregion
}
}