206 lines
6.5 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
2022-05-22 15:55:26 +08:00
using RageCoop.Core;
2021-08-26 17:01:32 +02:00
using Lidgren.Network;
using GTA.Math;
2022-06-19 11:12:20 +08:00
using RageCoop.Core.Scripting;
2022-06-23 09:46:38 +08:00
using System.Security.Cryptography;
2021-08-26 17:01:32 +02:00
2022-05-22 15:55:26 +08:00
namespace RageCoop.Server
2021-08-26 17:01:32 +02:00
{
2022-06-22 14:18:20 +08:00
public class ServerPed
2022-06-21 18:13:30 +08:00
{
2022-06-24 10:33:36 +08:00
public int ID { get;internal set; }
2022-06-21 18:13:30 +08:00
/// <summary>
2022-06-22 14:18:20 +08:00
/// The ID of the ped's last vehicle.
2022-06-21 18:13:30 +08:00
/// </summary>
public int VehicleID { get; internal set; }
public Vector3 Position { get; internal set; }
public int Health { get; internal set; }
}
2022-06-22 14:18:20 +08:00
public class PlayerConfig
{
#region CLIENT
public bool EnableAutoRespawn { get; set; }=true;
#endregion
public bool ShowBlip { get; set; } = true;
public bool ShowNameTag { get; set; } = true;
public GTA.BlipColor BlipColor { get; set; } = GTA.BlipColor.White;
public PlayerConfigFlags GetFlags()
{
var flag=PlayerConfigFlags.None;
if (ShowBlip)
{
flag|= PlayerConfigFlags.ShowBlip;
}
if (ShowNameTag)
{
flag |= PlayerConfigFlags.ShowNameTag;
}
return flag;
}
}
2021-08-26 17:01:32 +02:00
public class Client
{
private readonly Server Server;
internal Client(Server server)
{
Server=server;
}
2022-06-21 18:13:30 +08:00
internal long NetID = 0;
public NetConnection Connection { get;internal set; }
2022-06-22 14:18:20 +08:00
public ServerPed Player { get; internal set; }
2022-06-21 18:13:30 +08:00
public float Latency { get; internal set; }
public int ID { get; internal set; }
2022-06-22 14:18:20 +08:00
private PlayerConfig _config { get; set; }=new PlayerConfig();
public PlayerConfig Config { get { return _config; }set { _config=value;Server.SendPlayerInfos(); } }
2022-06-23 09:46:38 +08:00
internal readonly Dictionary<int, Action<object>> Callbacks = new();
2022-06-24 10:33:36 +08:00
internal byte[] PublicKey { get; set; }
public bool IsReady { get; internal set; }=false;
2022-06-21 18:13:30 +08:00
public string Username { get;internal set; } = "N/A";
#region CUSTOMDATA FUNCTIONS
2022-06-23 09:46:38 +08:00
/*
public void SetData<T>(string name, T data)
{
if (HasData(name))
{
_customData[name] = data;
}
else
{
_customData.Add(name, data);
}
}
public bool HasData(string name)
{
return _customData.ContainsKey(name);
}
public T GetData<T>(string name)
{
return HasData(name) ? (T)_customData[name] : default;
}
public void RemoveData(string name)
{
if (HasData(name))
{
_customData.Remove(name);
}
}
2022-06-23 09:46:38 +08:00
*/
2021-08-26 17:01:32 +02:00
2022-06-23 09:46:38 +08:00
#endregion
#region FUNCTIONS
2022-06-22 14:18:20 +08:00
public void Kick(string reason="You have been kicked!")
2021-12-11 14:00:22 +01:00
{
2022-06-04 18:09:42 +08:00
Connection?.Disconnect(reason);
2021-12-11 14:00:22 +01:00
}
2022-06-04 18:09:42 +08:00
public void Kick(params string[] reasons)
2022-04-08 22:30:34 +02:00
{
2022-06-04 18:09:42 +08:00
Kick(string.Join(" ", reasons));
2022-04-08 22:30:34 +02:00
}
2021-08-26 17:01:32 +02:00
public void SendChatMessage(string message, string from = "Server")
{
try
2021-08-26 17:01:32 +02:00
{
NetConnection userConnection = Server.MainNetServer.Connections.Find(x => x.RemoteUniqueIdentifier == NetID);
if (userConnection == null)
{
return;
}
Server.SendChatMessage(from, message, userConnection);
}
catch (Exception e)
{
Server.Logger?.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
}
2021-08-26 17:01:32 +02:00
}
/// <summary>
2022-06-24 10:33:36 +08:00
/// Send a CleanUpWorld message to this client.
/// </summary>
2022-06-24 10:33:36 +08:00
/// <param name="clients"></param>
public void SendCleanUpWorld(List<Client> clients = null)
2021-08-26 17:01:32 +02:00
{
2022-06-24 10:33:36 +08:00
SendCustomEvent(CustomEvents.CleanUpWorld, null);
2021-08-26 17:01:32 +02:00
}
2021-12-10 13:38:03 +01:00
2022-06-23 09:46:38 +08:00
/// <summary>
/// Send a native call to client and do a callback when the response received.
/// </summary>
/// <typeparam name="T">Type of the response</typeparam>
/// <param name="callBack"></param>
/// <param name="hash"></param>
/// <param name="args"></param>
public void SendNativeCall<T>(Action<object> callBack, GTA.Native.Hash hash, params object[] args)
{
var argsList= new List<object>(args);
argsList.InsertRange(0, new object[] { (byte)Type.GetTypeCode(typeof(T)), RequestNativeCallID<T>(callBack), (ulong)hash });
SendCustomEvent(CustomEvents.NativeCall, argsList);
}
/// <summary>
/// Send a native call to client and ignore it's response.
/// </summary>
/// <param name="hash"></param>
/// <param name="args"></param>
public void SendNativeCall(GTA.Native.Hash hash, params object[] args)
{
var argsList = new List<object>(args);
argsList.InsertRange(0, new object[] { (byte)TypeCode.Empty,(ulong)hash});
// Server.Logger?.Debug(argsList.DumpWithType());
2022-06-23 09:46:38 +08:00
SendCustomEvent(CustomEvents.NativeCall, argsList);
}
private int RequestNativeCallID<T>(Action<object> callback)
{
int ID = 0;
lock (Callbacks)
{
while ((ID==0)
|| Callbacks.ContainsKey(ID))
{
byte[] rngBytes = new byte[4];
RandomNumberGenerator.Create().GetBytes(rngBytes);
// Convert the bytes into an integer
ID = BitConverter.ToInt32(rngBytes, 0);
}
Callbacks.Add(ID, callback);
}
return ID;
}
2022-06-19 11:12:20 +08:00
public void SendCustomEvent(int id,List<object> args)
{
if (!IsReady)
{
Server.Logger?.Warning($"Player \"{Username}\" is not ready!");
}
try
{
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
new Packets.CustomEvent()
{
Hash=id,
2022-06-19 11:12:20 +08:00
Args=args
2022-05-22 15:55:26 +08:00
}.Pack(outgoingMessage);
Server.MainNetServer.SendMessage(outgoingMessage, Connection, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Event);
}
catch (Exception ex)
{
Server.Logger?.Error(ex);
}
}
#endregion
2021-08-26 17:01:32 +02:00
}
}