using System;
using System.Collections.Generic;
using RageCoop.Core;
using Lidgren.Network;
using System.Diagnostics;
using RageCoop.Core.Scripting;
using System.Security.Cryptography;
using RageCoop.Server.Scripting;
namespace RageCoop.Server
{
///
/// Represent a player connected to this server.
///
public class Client
{
private readonly Server Server;
internal Client(Server server)
{
Server=server;
}
///
/// Th client's IP address and port.
///
public System.Net.IPEndPoint EndPoint { get { return Connection?.RemoteEndPoint; } }
internal long NetID = 0;
internal NetConnection Connection { get;set; }
///
/// The instance representing the client's main character.
///
public ServerPed Player { get; internal set; }
///
/// The client's latency in seconds.
///
public float Latency { get; internal set; }
internal readonly Dictionary> Callbacks = new();
internal byte[] PublicKey { get; set; }
///
/// Indicates whether the client has succefully loaded all resources.
///
public bool IsReady { get; internal set; }=false;
///
/// The client's username.
///
public string Username { get;internal set; } = "N/A";
private bool _autoRespawn=true;
///
/// Gets or sets whether to enable automatic respawn for this client's main ped.
///
public bool EnableAutoRespawn {
get { return _autoRespawn; }
set {
BaseScript.SetAutoRespawn(this,value);
_autoRespawn=value;
}
}
private bool _displayNameTag=true;
private Stopwatch _latencyWatch = new Stopwatch();
///
/// Gets or sets whether to enable automatic respawn for this client's main ped.
///
public bool DisplayNameTag
{
get { return _displayNameTag; }
set
{
Server.BaseScript.SetNameTag(this,value);
_displayNameTag=value;
}
}
internal void UpdateLatency()
{
_latencyWatch.Restart();
Server.GetResponse(this, new Packets.PingPong(), ConnectionChannel.PingPong);
_latencyWatch.Stop();
Latency = (float)_latencyWatch.ElapsedMilliseconds/2000;
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
new Packets.PlayerInfoUpdate()
{
PedID=Player.ID,
Username=Username,
Latency=Latency,
}.Pack(outgoingMessage);
Server.MainNetServer.SendToAll(outgoingMessage, NetDeliveryMethod.ReliableSequenced, (byte)ConnectionChannel.Default);
}
#region FUNCTIONS
///
/// Kick this client
///
///
public void Kick(string reason="You have been kicked!")
{
Connection?.Disconnect(reason);
}
///
/// Kick this client
///
/// Reasons to kick
public void Kick(params string[] reasons)
{
Kick(string.Join(" ", reasons));
}
///
/// Send a chat messsage to this client, not visible to others.
///
///
///
public void SendChatMessage(string message, string from = "Server")
{
try
{
Server.SendChatMessage(from, message, this);
}
catch (Exception e)
{
Server.Logger?.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
}
}
///
/// Send a native call to client and do a callback when the response received.
///
/// Type of the response
///
///
///
public void SendNativeCall(Action