Resource system

This commit is contained in:
Sardelka
2022-06-21 18:13:30 +08:00
parent e1606889f7
commit 30f7a281b0
17 changed files with 245 additions and 129 deletions

View File

@ -206,6 +206,13 @@ namespace RageCoop.Client
} }
break; break;
case PacketTypes.CustomEvent:
{
Packets.CustomEvent packet = new Packets.CustomEvent();
packet.Unpack(data);
Scripting.API.Events.InvokeCustomEventReceived(packet.Hash, packet.Args);
}
break;
case PacketTypes.FileTransferChunk: case PacketTypes.FileTransferChunk:
{ {
Packets.FileTransferChunk packet = new Packets.FileTransferChunk(); Packets.FileTransferChunk packet = new Packets.FileTransferChunk();
@ -234,12 +241,6 @@ namespace RageCoop.Client
} }
break; break;
case PacketTypes.CustomEvent:
{
Packets.CustomEvent packet = new Packets.CustomEvent();
packet.Unpack(data);
}
break;
default: default:
if (packetType.IsSyncEvent()) if (packetType.IsSyncEvent())
{ {
@ -293,17 +294,17 @@ namespace RageCoop.Client
c.Velocity = packet.Velocity; c.Velocity = packet.Velocity;
c.Speed = packet.Speed; c.Speed = packet.Speed;
c.CurrentWeaponHash = packet.CurrentWeaponHash; c.CurrentWeaponHash = packet.CurrentWeaponHash;
c.IsAiming = flags.HasFlag(PedDataFlags.IsAiming); c.IsAiming = flags.HasPedFlag(PedDataFlags.IsAiming);
c.IsReloading = flags.HasFlag(PedDataFlags.IsReloading); c.IsReloading = flags.HasPedFlag(PedDataFlags.IsReloading);
c.IsJumping = flags.HasFlag(PedDataFlags.IsJumping); c.IsJumping = flags.HasPedFlag(PedDataFlags.IsJumping);
c.IsRagdoll = flags.HasFlag(PedDataFlags.IsRagdoll); c.IsRagdoll = flags.HasPedFlag(PedDataFlags.IsRagdoll);
c.IsOnFire = flags.HasFlag(PedDataFlags.IsOnFire); c.IsOnFire = flags.HasPedFlag(PedDataFlags.IsOnFire);
c.IsInParachuteFreeFall = flags.HasFlag(PedDataFlags.IsInParachuteFreeFall); c.IsInParachuteFreeFall = flags.HasPedFlag(PedDataFlags.IsInParachuteFreeFall);
c.IsParachuteOpen = flags.HasFlag(PedDataFlags.IsParachuteOpen); c.IsParachuteOpen = flags.HasPedFlag(PedDataFlags.IsParachuteOpen);
c.IsOnLadder = flags.HasFlag(PedDataFlags.IsOnLadder); c.IsOnLadder = flags.HasPedFlag(PedDataFlags.IsOnLadder);
c.IsVaulting = flags.HasFlag(PedDataFlags.IsVaulting); c.IsVaulting = flags.HasPedFlag(PedDataFlags.IsVaulting);
c.IsInCover = flags.HasFlag(PedDataFlags.IsInCover); c.IsInCover = flags.HasPedFlag(PedDataFlags.IsInCover);
c.IsInStealthMode = flags.HasFlag(PedDataFlags.IsInStealthMode); c.IsInStealthMode = flags.HasPedFlag(PedDataFlags.IsInStealthMode);
c.Heading=packet.Heading; c.Heading=packet.Heading;
c.LastSynced = Main.Ticked; c.LastSynced = Main.Ticked;
if (c.IsAiming) if (c.IsAiming)
@ -360,14 +361,14 @@ namespace RageCoop.Client
v.Colors=packet.Colors; v.Colors=packet.Colors;
v.LandingGear=packet.LandingGear; v.LandingGear=packet.LandingGear;
v.RoofState=(VehicleRoofState)packet.RoofState; v.RoofState=(VehicleRoofState)packet.RoofState;
v.EngineRunning = packet.Flag.HasFlag(VehicleDataFlags.IsEngineRunning); v.EngineRunning = packet.Flag.HasVehFlag(VehicleDataFlags.IsEngineRunning);
v.LightsOn = packet.Flag.HasFlag(VehicleDataFlags.AreLightsOn); v.LightsOn = packet.Flag.HasVehFlag(VehicleDataFlags.AreLightsOn);
v.BrakeLightsOn = packet.Flag.HasFlag(VehicleDataFlags.AreBrakeLightsOn); v.BrakeLightsOn = packet.Flag.HasVehFlag(VehicleDataFlags.AreBrakeLightsOn);
v.HighBeamsOn = packet.Flag.HasFlag(VehicleDataFlags.AreHighBeamsOn); v.HighBeamsOn = packet.Flag.HasVehFlag(VehicleDataFlags.AreHighBeamsOn);
v.SireneActive = packet.Flag.HasFlag(VehicleDataFlags.IsSirenActive); v.SireneActive = packet.Flag.HasVehFlag(VehicleDataFlags.IsSirenActive);
v.IsDead = packet.Flag.HasFlag(VehicleDataFlags.IsDead); v.IsDead = packet.Flag.HasVehFlag(VehicleDataFlags.IsDead);
v.HornActive = packet.Flag.HasFlag(VehicleDataFlags.IsHornActive); v.HornActive = packet.Flag.HasVehFlag(VehicleDataFlags.IsHornActive);
v.Transformed = packet.Flag.HasFlag(VehicleDataFlags.IsTransformed); v.Transformed = packet.Flag.HasVehFlag(VehicleDataFlags.IsTransformed);
v.Passengers=new Dictionary<VehicleSeat, SyncedPed>(); v.Passengers=new Dictionary<VehicleSeat, SyncedPed>();
v.LockStatus=packet.LockStatus; v.LockStatus=packet.LockStatus;
v.RadioStation=packet.RadioStation; v.RadioStation=packet.RadioStation;

View File

@ -44,11 +44,11 @@ namespace RageCoop.Client
Flag = p.GetPedFlags(), Flag = p.GetPedFlags(),
Heading=p.Heading, Heading=p.Heading,
}; };
if (packet.Flag.HasFlag(PedDataFlags.IsAiming)) if (packet.Flag.HasPedFlag(PedDataFlags.IsAiming))
{ {
packet.AimCoords = p.GetAimCoord(); packet.AimCoords = p.GetAimCoord();
} }
if (packet.Flag.HasFlag(PedDataFlags.IsRagdoll)) if (packet.Flag.HasPedFlag(PedDataFlags.IsRagdoll))
{ {
packet.RotationVelocity=p.RotationVelocity; packet.RotationVelocity=p.RotationVelocity;
} }

View File

@ -41,11 +41,10 @@ namespace RageCoop.Client.Scripting
/// </summary> /// </summary>
public static class Events public static class Events
{ {
/// <summary> #region DELEGATES
/// Empty delegate
/// </summary>
public delegate void EmptyEvent(); public delegate void EmptyEvent();
public delegate void CustomEvent(int hash, List<object> args);
#endregion
/// <summary> /// <summary>
/// The local player is dead /// The local player is dead
/// </summary> /// </summary>
@ -75,15 +74,38 @@ namespace RageCoop.Client.Scripting
/// This is equivalent of <see cref="GTA.Script.Tick"/>. /// This is equivalent of <see cref="GTA.Script.Tick"/>.
/// </summary> /// </summary>
public static event EmptyEvent OnTick; public static event EmptyEvent OnTick;
/// <summary>
/// This will be invoked when a CustomEvent is received from the server.
/// </summary>
public static event CustomEvent OnCustomEventReceived;
#region INVOKE #region INVOKE
internal static void InvokeVehicleSpawned(SyncedVehicle v) { OnVehicleSpawned?.Invoke(null,v); } internal static void InvokeVehicleSpawned(SyncedVehicle v) { OnVehicleSpawned?.Invoke(null, v); }
internal static void InvokeVehicleDeleted(SyncedVehicle v) { OnVehicleDeleted?.Invoke(null, v); } internal static void InvokeVehicleDeleted(SyncedVehicle v) { OnVehicleDeleted?.Invoke(null, v); }
internal static void InvokePedSpawned(SyncedPed p) { OnPedSpawned?.Invoke(null, p); } internal static void InvokePedSpawned(SyncedPed p) { OnPedSpawned?.Invoke(null, p); }
internal static void InvokePedDeleted(SyncedPed p) { OnPedDeleted?.Invoke(null, p); } internal static void InvokePedDeleted(SyncedPed p) { OnPedDeleted?.Invoke(null, p); }
internal static void InvokePlayerDied() { OnPlayerDied?.Invoke(); } internal static void InvokePlayerDied() { OnPlayerDied?.Invoke(); }
internal static void InvokeTick() { OnTick?.Invoke(); } internal static void InvokeTick() { OnTick?.Invoke(); }
internal static void InvokeCustomEventReceived(int hash, List<object> args)
{
OnCustomEventReceived?.Invoke(hash, args);
}
#endregion #endregion
internal static void ClearHandlers()
{
OnPlayerDied=null;
OnTick=null;
OnPedDeleted=null;
OnPedSpawned=null;
OnVehicleDeleted=null;
OnVehicleSpawned=null;
OnCustomEventReceived=null;
}
} }
#region FUNCTIONS
/// <summary> /// <summary>
/// Send a local chat message to this player /// Send a local chat message to this player
/// </summary> /// </summary>
@ -166,6 +188,22 @@ namespace RageCoop.Client.Scripting
{ {
get { return Main.CurrentVersion; } get { return Main.CurrentVersion; }
} }
/// <summary>
/// Send an event and data to the specified clients.
/// </summary>
/// <param name="eventHash">An unique identifier of the event</param>
/// <param name="args">The objects conataing your data, supported types:
/// byte, short, ushort, int, uint, long, ulong, float, bool, string.</param>
public static void SendCustomEvent(int eventHash, List<object> args)
{
var p = new Packets.CustomEvent()
{
Args=args,
Hash=eventHash
};
Networking.Send(p, ConnectionChannel.Event, Lidgren.Network.NetDeliveryMethod.ReliableOrdered);
}
#endregion
} }
} }

View File

@ -468,8 +468,6 @@ namespace RageCoop.Client
} }
_lastIsJumping = false; _lastIsJumping = false;
Function.Call(Hash.SET_PED_STEALTH_MOVEMENT, MainPed, IsInStealthMode, 0);
if (IsRagdoll || Health==0) if (IsRagdoll || Health==0)
{ {
if (!MainPed.IsRagdoll) if (!MainPed.IsRagdoll)

View File

@ -316,7 +316,7 @@ namespace RageCoop.Client
} }
MainVehicle.LockStatus=LockStatus; MainVehicle.LockStatus=LockStatus;
if (Flags.HasFlag(VehicleDataFlags.IsDeluxoHovering)) if (Flags.HasVehFlag(VehicleDataFlags.IsDeluxoHovering))
{ {
if (!MainVehicle.IsDeluxoHovering()) if (!MainVehicle.IsDeluxoHovering())
{ {

View File

@ -80,15 +80,6 @@ namespace RageCoop.Client
return flags; return flags;
} }
public static bool HasFlag(this PedDataFlags flagToCheck, PedDataFlags flag)
{
return (flagToCheck & flag)!=0;
}
public static bool HasFlag(this VehicleDataFlags flagToCheck, VehicleDataFlags flag)
{
return (flagToCheck & flag)!=0;
}
public static Dictionary<uint, bool> GetWeaponComponents(this Weapon weapon) public static Dictionary<uint, bool> GetWeaponComponents(this Weapon weapon)

View File

@ -107,5 +107,14 @@ namespace RageCoop.Core
} }
public static bool HasPedFlag(this PedDataFlags flagToCheck, PedDataFlags flag)
{
return (flagToCheck & flag)!=0;
}
public static bool HasVehFlag(this VehicleDataFlags flagToCheck, VehicleDataFlags flag)
{
return (flagToCheck & flag)!=0;
}
} }
} }

View File

@ -152,7 +152,7 @@ namespace RageCoop.Core
// Write ped velocity // Write ped velocity
byteArray.AddVector3(Velocity); byteArray.AddVector3(Velocity);
if (Flag.HasFlag(PedDataFlags.IsRagdoll)) if (Flag.HasPedFlag(PedDataFlags.IsRagdoll))
{ {
byteArray.AddVector3(RotationVelocity); byteArray.AddVector3(RotationVelocity);
} }
@ -163,7 +163,7 @@ namespace RageCoop.Core
// Write ped weapon hash // Write ped weapon hash
byteArray.AddRange(BitConverter.GetBytes(CurrentWeaponHash)); byteArray.AddRange(BitConverter.GetBytes(CurrentWeaponHash));
if (Flag.HasFlag(PedDataFlags.IsAiming)) if (Flag.HasPedFlag(PedDataFlags.IsAiming))
{ {
// Write ped aim coords // Write ped aim coords
byteArray.AddVector3(AimCoords); byteArray.AddVector3(AimCoords);
@ -202,7 +202,7 @@ namespace RageCoop.Core
Velocity = reader.ReadVector3(); Velocity = reader.ReadVector3();
// Read rotation velocity if in ragdoll // Read rotation velocity if in ragdoll
if (Flag.HasFlag(PedDataFlags.IsRagdoll)) if (Flag.HasPedFlag(PedDataFlags.IsRagdoll))
{ {
RotationVelocity=reader.ReadVector3(); RotationVelocity=reader.ReadVector3();
} }
@ -214,7 +214,7 @@ namespace RageCoop.Core
CurrentWeaponHash = reader.ReadUInt(); CurrentWeaponHash = reader.ReadUInt();
// Try to read aim coords // Try to read aim coords
if (Flag.HasFlag(PedDataFlags.IsAiming)) if (Flag.HasPedFlag(PedDataFlags.IsAiming))
{ {
// Read player aim coords // Read player aim coords
AimCoords = reader.ReadVector3(); AimCoords = reader.ReadVector3();

View File

@ -66,12 +66,12 @@ namespace RageCoop.Core
byteArray.AddRange(BitConverter.GetBytes(EngineHealth)); byteArray.AddRange(BitConverter.GetBytes(EngineHealth));
// Check // Check
if (Flag.HasFlag(VehicleDataFlags.IsAircraft)) if (Flag.HasVehFlag(VehicleDataFlags.IsAircraft))
{ {
// Write the vehicle landing gear // Write the vehicle landing gear
byteArray.Add(LandingGear); byteArray.Add(LandingGear);
} }
if (Flag.HasFlag(VehicleDataFlags.HasRoof)) if (Flag.HasVehFlag(VehicleDataFlags.HasRoof))
{ {
byteArray.Add(RoofState); byteArray.Add(RoofState);
} }
@ -166,12 +166,12 @@ namespace RageCoop.Core
// Check // Check
if (Flag.HasFlag(VehicleDataFlags.IsAircraft)) if (Flag.HasVehFlag(VehicleDataFlags.IsAircraft))
{ {
// Read vehicle landing gear // Read vehicle landing gear
LandingGear = reader.ReadByte(); LandingGear = reader.ReadByte();
} }
if (Flag.HasFlag(VehicleDataFlags.HasRoof)) if (Flag.HasVehFlag(VehicleDataFlags.HasRoof))
{ {
RoofState=reader.ReadByte(); RoofState=reader.ReadByte();
} }

View File

@ -7,6 +7,7 @@
<FileVersion>0.1</FileVersion> <FileVersion>0.1</FileVersion>
<Version>0.1</Version> <Version>0.1</Version>
<DebugType>embedded</DebugType> <DebugType>embedded</DebugType>
<ProduceReferenceAssembly>True</ProduceReferenceAssembly>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net6.0|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net6.0|AnyCPU'">

View File

@ -7,15 +7,28 @@ using RageCoop.Core.Scripting;
namespace RageCoop.Server namespace RageCoop.Server
{ {
public class Player
{
/// <summary>
/// The ID of player's last vehicle.
/// </summary>
public int VehicleID { get; internal set; }
public Vector3 Position { get; internal set; }
public int Health { get; internal set; }
}
public class Client public class Client
{ {
public long NetID = 0; internal long NetID = 0;
internal NetConnection Connection { get; set; } public NetConnection Connection { get;internal set; }
public PlayerData Player; public Player Player { get; internal set; }
public float Latency { get; internal set; }
public int ID { get; internal set; }
private readonly Dictionary<string, object> _customData = new(); private readonly Dictionary<string, object> _customData = new();
private long _callbacksCount = 0; private long _callbacksCount = 0;
public readonly Dictionary<long, Action<object>> Callbacks = new(); public readonly Dictionary<long, Action<object>> Callbacks = new();
public bool IsReady { get; internal set; }=false; public bool IsReady { get; internal set; }=false;
public string Username { get;internal set; } = "N/A";
#region CUSTOMDATA FUNCTIONS #region CUSTOMDATA FUNCTIONS
public void SetData<T>(string name, T data) public void SetData<T>(string name, T data)
{ {
@ -190,7 +203,7 @@ namespace RageCoop.Server
{ {
if (!IsReady) if (!IsReady)
{ {
Program.Logger.Warning($"Player \"{Player.Username}\" is not ready!"); Program.Logger.Warning($"Player \"{Username}\" is not ready!");
return; return;
} }

View File

@ -46,7 +46,8 @@ namespace RageCoop.Server
} }
catch (Exception e) catch (Exception e)
{ {
Logger.Error($"Fatal error occurred, server shutting down:{e}"); Logger.Error(e);
Logger.Error($"Fatal error occurred, server shutting down.");
} }
} }

View File

@ -12,10 +12,7 @@ namespace RageCoop.Server.Scripting
public static class API public static class API
{ {
#region INTERNAL #region INTERNAL
internal static void InvokeCustomEvent(int hash,List<object> args) internal static Dictionary<int, List<Action<List<object>>>> CustomEventHandlers = new();
{
}
#endregion #endregion
public static class Events public static class Events
{ {
@ -29,30 +26,26 @@ namespace RageCoop.Server.Scripting
public static event EventHandler<HandshakeEventArgs> OnPlayerHandshake; public static event EventHandler<HandshakeEventArgs> OnPlayerHandshake;
public static event PlayerConnect OnPlayerConnected; public static event PlayerConnect OnPlayerConnected;
public static event PlayerDisconnect OnPlayerDisconnected; public static event PlayerDisconnect OnPlayerDisconnected;
public static void ClearHandlers() public static event EventHandler<OnCommandEventArgs> OnCommandReceived;
/// <summary>
/// This will be invoked when a CustomEvent is received from one client.
/// </summary>
public static event EventHandler<CustomEventReceivedArgs> OnCustomEventReceived;
internal static void ClearHandlers()
{ {
foreach (Delegate d in OnChatMessage.GetInvocationList()) OnChatMessage=null;
{ OnPlayerHandshake=null;
OnChatMessage -= (EventHandler<ChatEventArgs>)d; OnPlayerConnected=null;
} OnPlayerDisconnected=null;
foreach (Delegate d in OnPlayerHandshake.GetInvocationList()) OnCustomEventReceived=null;
{ OnCommandReceived=null;
OnPlayerHandshake -= (EventHandler<HandshakeEventArgs>)d;
}
foreach (Delegate d in OnPlayerConnected.GetInvocationList())
{
OnPlayerConnected -= (PlayerConnect)d;
}
foreach (Delegate d in OnPlayerDisconnected.GetInvocationList())
{
OnPlayerDisconnected -= (PlayerDisconnect)d;
}
} }
#region INVOKE #region INVOKE
internal static void InvokeOnChatMessage(Packets.ChatMessage p,NetConnection con) internal static void InvokeOnChatMessage(Packets.ChatMessage p,Client sender)
{ {
OnChatMessage?.Invoke(null,new ChatEventArgs() { OnChatMessage?.Invoke(null,new ChatEventArgs() {
Sender=Util.GetClientByNetID(con.RemoteUniqueIdentifier), Sender=sender,
Message=p.Message Message=p.Message
}); });
} }
@ -62,6 +55,22 @@ namespace RageCoop.Server.Scripting
{ OnPlayerDisconnected?.Invoke(client); } { OnPlayerDisconnected?.Invoke(client); }
internal static void InvokePlayerHandshake(HandshakeEventArgs args) internal static void InvokePlayerHandshake(HandshakeEventArgs args)
{ OnPlayerHandshake?.Invoke(null, args); } { OnPlayerHandshake?.Invoke(null, args); }
internal static void InvokeCustomEventReceived(Packets.CustomEvent p,Client sender)
{
OnCustomEventReceived?.Invoke(null, new CustomEventReceivedArgs() { Hash=p.Hash, Args=p.Args,Sender=sender });
}
internal static bool InvokeOnCommandReceived(string cname,string[] cargs,Client sender)
{
var args = new OnCommandEventArgs()
{
Name=cname,
Args=cargs,
Sender=sender
};
OnCommandReceived?.Invoke(null,args);
return args.Cancel;
}
#endregion #endregion
} }
@ -119,7 +128,7 @@ namespace RageCoop.Server.Scripting
/// <returns>The Client from this user or null</returns> /// <returns>The Client from this user or null</returns>
public static Client GetClientByUsername(string username) public static Client GetClientByUsername(string username)
{ {
return Server.Clients.Values.FirstOrDefault(x => x.Player.Username.ToLower() == username.ToLower()); return Server.Clients.Values.FirstOrDefault(x => x.Username.ToLower() == username.ToLower());
} }
/// <summary> /// <summary>
@ -127,8 +136,7 @@ namespace RageCoop.Server.Scripting
/// </summary> /// </summary>
/// <param name="message">The chat message</param> /// <param name="message">The chat message</param>
/// <param name="username">The username which send this message (default = "Server")</param> /// <param name="username">The username which send this message (default = "Server")</param>
/// <param name="netHandleList">The list of connections (players) who received this chat message</param> public static void SendChatMessage(string message, List<Client> targets = null, string username = "Server")
public static void SendChatMessageToAll(string message, string username = "Server", List<long> netHandleList = null)
{ {
try try
{ {
@ -136,12 +144,22 @@ namespace RageCoop.Server.Scripting
{ {
return; return;
} }
targets ??= new(Server.Clients.Values);
List<NetConnection> connections = netHandleList == null foreach(Client client in targets)
? Server.MainNetServer.Connections {
: Server.MainNetServer.Connections.FindAll(c => netHandleList.Contains(c.RemoteUniqueIdentifier)); Server.SendChatMessage(username, message, client.Connection);
}
Server.SendChatMessage(username, message, connections); }
catch (Exception e)
{
Program.Logger.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
}
}
public static void SendChatMessage(string message, Client target, string username = "Server")
{
try
{
Server.SendChatMessage(username, message, target.Connection);
} }
catch (Exception e) catch (Exception e)
{ {
@ -198,8 +216,13 @@ namespace RageCoop.Server.Scripting
Server.RegisterCommands<T>(); Server.RegisterCommands<T>();
} }
/// <summary>
public static void TriggerCustomEvent(int eventHash,List<object> args,List<Client> targets=null) /// Send an event and data to the specified clients.
/// </summary>
/// <param name="eventHash">An unique identifier of the event</param>
/// <param name="args">The objects conataing your data, supported types: byte, short, ushort, int, uint, long, ulong, float, bool, string.</param>
/// <param name="targets">The target clients to send.</param>
public static void SendCustomEvent(int eventHash,List<object> args,List<Client> targets=null)
{ {
targets ??= new(Server.Clients.Values); targets ??= new(Server.Clients.Values);
var p = new Packets.CustomEvent() var p = new Packets.CustomEvent()
@ -212,6 +235,22 @@ namespace RageCoop.Server.Scripting
Server.Send(p,c,ConnectionChannel.Event,NetDeliveryMethod.ReliableOrdered); Server.Send(p,c,ConnectionChannel.Event,NetDeliveryMethod.ReliableOrdered);
} }
} }
public static void RegisterCustomEventHandler(int hash,Action<List<object>> handler)
{
List<Action<List<object>>> handlers;
lock (CustomEventHandlers)
{
if (!CustomEventHandlers.TryGetValue(hash,out handlers))
{
CustomEventHandlers.Add(hash, handlers = new List<Action<List<object>>>());
}
handlers.Add(handler);
}
}
public static Core.Logging.Logger GetLogger()
{
return Program.Logger;
}
#endregion #endregion
} }
} }

View File

@ -12,6 +12,22 @@ namespace RageCoop.Server.Scripting
public Client Sender { get; set; } public Client Sender { get; set; }
public string Message { get; set; } public string Message { get; set; }
} }
public class CustomEventReceivedArgs : EventArgs
{
public Client Sender { get; set; }
public int Hash { get; set; }
public List<object> Args { get; set; }
}
public class OnCommandEventArgs : EventArgs
{
public Client Sender { get; set; }
public string Name { get; set; }
public string[] Args { get; set; }
/// <summary>
/// If this value was set to true, corresponding handler registered with <see cref="API.RegisterCommand(string, Action{CommandContext})"/> will not be invoked.
/// </summary>
public bool Cancel { get; set; } = false;
}
public class HandshakeEventArgs : EventArgs public class HandshakeEventArgs : EventArgs
{ {
public int ID { get; set; } public int ID { get; set; }

View File

@ -92,9 +92,9 @@ namespace RageCoop.Server.Scripting
{ {
Task.Run(() => Task.Run(() =>
{ {
Logger.Info($"Sending resources to client:{client.Player.Username}"); Logger.Info($"Sending resources to client:{client.Username}");
Server.SendFile(path, "Resources.zip", client); Server.SendFile(path, "Resources.zip", client);
Logger.Info($"Resources sent to:{client.Player.Username}"); Logger.Info($"Resources sent to:{client.Username}");
}); });
} }

View File

@ -178,6 +178,7 @@ namespace RageCoop.Server
Program.Logger.Dispose(); Program.Logger.Dispose();
} }
Client sender;
private void ProcessMessage(NetIncomingMessage message) private void ProcessMessage(NetIncomingMessage message)
{ {
if(message == null) { return; } if(message == null) { return; }
@ -230,16 +231,20 @@ namespace RageCoop.Server
break; break;
} }
case NetIncomingMessageType.Data: case NetIncomingMessageType.Data:
{ {
// Get packet type // Get packet type
byte btype = message.ReadByte(); byte btype = message.ReadByte();
var type = (PacketTypes)btype; var type = (PacketTypes)btype;
int len = message.ReadInt32(); int len = message.ReadInt32();
byte[] data = message.ReadBytes(len); byte[] data = message.ReadBytes(len);
try try
{ {
// Get sender client
if (!Clients.TryGetValue(message.SenderConnection.RemoteUniqueIdentifier, out sender))
{
throw new UnauthorizedAccessException("No client data found:"+message.SenderEndPoint);
}
switch (type) switch (type)
{ {
@ -296,19 +301,19 @@ namespace RageCoop.Server
case PacketTypes.ChatMessage: case PacketTypes.ChatMessage:
{ {
try
{
Packets.ChatMessage packet = new(); Packets.ChatMessage packet = new();
packet.Unpack(data); packet.Unpack(data);
API.Events.InvokeOnChatMessage(packet, message.SenderConnection); API.Events.InvokeOnChatMessage(packet, sender);
SendChatMessage(packet); SendChatMessage(packet,sender);
} }
catch (Exception e) break;
{ case PacketTypes.CustomEvent:
DisconnectAndLog(message.SenderConnection, type, e); {
} Packets.CustomEvent packet = new Packets.CustomEvent();
packet.Unpack(data);
API.Events.InvokeCustomEventReceived(packet, sender);
} }
break; break;
@ -384,7 +389,7 @@ namespace RageCoop.Server
Client client = Util.GetClientByNetID(message.SenderConnection.RemoteUniqueIdentifier); Client client = Util.GetClientByNetID(message.SenderConnection.RemoteUniqueIdentifier);
if (client != null) if (client != null)
{ {
client.Player.Latency = message.ReadFloat(); client.Latency = message.ReadFloat();
} }
} }
break; break;
@ -415,9 +420,9 @@ namespace RageCoop.Server
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage(); NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
new Packets.PlayerInfoUpdate() new Packets.PlayerInfoUpdate()
{ {
PedID=c.Player.PedID, PedID=c.ID,
Username=c.Player.Username, Username=c.Username,
Latency=c.Player.Latency, Latency=c.Latency,
}.Pack(outgoingMessage); }.Pack(outgoingMessage);
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.ReliableSequenced, (byte)ConnectionChannel.Default); MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.ReliableSequenced, (byte)ConnectionChannel.Default);
}); });
@ -454,7 +459,7 @@ namespace RageCoop.Server
connection.Deny("Username contains special chars!"); connection.Deny("Username contains special chars!");
return; return;
} }
if (Clients.Values.Any(x => x.Player.Username.ToLower() == packet.Username.ToLower())) if (Clients.Values.Any(x => x.Username.ToLower() == packet.Username.ToLower()))
{ {
connection.Deny("Username is already taken!"); connection.Deny("Username is already taken!");
return; return;
@ -485,10 +490,9 @@ namespace RageCoop.Server
{ {
NetID = connection.RemoteUniqueIdentifier, NetID = connection.RemoteUniqueIdentifier,
Connection=connection, Connection=connection,
Username=packet.Username,
Player = new() Player = new()
{ {
Username = packet.Username,
PedID=packet.PedID,
} }
} }
);; );;
@ -535,8 +539,8 @@ namespace RageCoop.Server
new Packets.PlayerConnect() new Packets.PlayerConnect()
{ {
// NetHandle = targetNetHandle, // NetHandle = targetNetHandle,
Username = targetClient.Player.Username, Username = targetClient.Username,
PedID=targetClient.Player.PedID, PedID=targetClient.ID,
}.Pack(outgoingMessage); }.Pack(outgoingMessage);
MainNetServer.SendMessage(outgoingMessage, local, NetDeliveryMethod.ReliableOrdered, 0); MainNetServer.SendMessage(outgoingMessage, local, NetDeliveryMethod.ReliableOrdered, 0);
@ -547,8 +551,8 @@ namespace RageCoop.Server
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage(); NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
new Packets.PlayerConnect() new Packets.PlayerConnect()
{ {
PedID=localClient.Player.PedID, PedID=localClient.ID,
Username = localClient.Player.Username Username = localClient.Username
}.Pack(outgoingMessage); }.Pack(outgoingMessage);
if(clients.Count > 0) if(clients.Count > 0)
{ {
@ -557,11 +561,11 @@ namespace RageCoop.Server
} }
API.Events.InvokePlayerConnected(localClient); API.Events.InvokePlayerConnected(localClient);
Program.Logger.Info($"Player {localClient.Player.Username} connected!"); Program.Logger.Info($"Player {localClient.Username} connected!");
if (!string.IsNullOrEmpty(MainSettings.WelcomeMessage)) if (!string.IsNullOrEmpty(MainSettings.WelcomeMessage))
{ {
SendChatMessage(new Packets.ChatMessage() { Username = "Server", Message = MainSettings.WelcomeMessage }, new List<NetConnection>() { local }); SendChatMessage(new Packets.ChatMessage() { Username = "Server", Message = MainSettings.WelcomeMessage }, null,new List<NetConnection>() { local });
} }
} }
@ -569,7 +573,7 @@ namespace RageCoop.Server
private static void SendPlayerDisconnectPacket(long nethandle) private static void SendPlayerDisconnectPacket(long nethandle)
{ {
List<NetConnection> clients = MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != nethandle); List<NetConnection> clients = MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != nethandle);
int playerPedID = Clients[nethandle].Player.PedID; int playerPedID = Clients[nethandle].ID;
if (clients.Count > 0) if (clients.Count > 0)
{ {
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage(); NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
@ -590,7 +594,7 @@ namespace RageCoop.Server
Clients.Remove(localClient.NetID); Clients.Remove(localClient.NetID);
API.Events.InvokePlayerDisconnected(localClient); API.Events.InvokePlayerDisconnected(localClient);
Program.Logger.Info($"Player {localClient.Player.Username} disconnected! ID:{playerPedID}"); Program.Logger.Info($"Player {localClient.Username} disconnected! ID:{playerPedID}");
} }
@ -624,7 +628,7 @@ namespace RageCoop.Server
} }
// Save the new data // Save the new data
if (packet.Passengers.ContainsValue(client.Player.PedID)) if (packet.Passengers.ContainsValue(client.ID))
{ {
client.Player.VehicleID = packet.ID; client.Player.VehicleID = packet.ID;
} }
@ -644,7 +648,7 @@ namespace RageCoop.Server
{ {
return; return;
} }
bool isPlayer = packet.ID==client.Player.PedID; bool isPlayer = packet.ID==client.ID;
if (isPlayer) { client.Player.Position=packet.Position; } if (isPlayer) { client.Player.Position=packet.Position; }
foreach (var c in Clients.Values) foreach (var c in Clients.Values)
@ -719,19 +723,24 @@ namespace RageCoop.Server
#endregion #endregion
// Send a message to targets or all players // Send a message to targets or all players
private static void SendChatMessage(Packets.ChatMessage packet, List<NetConnection> targets = null) private static void SendChatMessage(Packets.ChatMessage packet,Client sender=null, List<NetConnection> targets = null)
{ {
if (packet.Message.StartsWith('/')) if (packet.Message.StartsWith('/'))
{ {
string[] cmdArgs = packet.Message.Split(" "); string[] cmdArgs = packet.Message.Split(" ");
string cmdName = cmdArgs[0].Remove(0, 1); string cmdName = cmdArgs[0].Remove(0, 1);
if (API.Events.InvokeOnCommandReceived(cmdName, cmdArgs, sender))
{
return;
}
if (Commands.Any(x => x.Key.Name == cmdName)) if (Commands.Any(x => x.Key.Name == cmdName))
{ {
string[] argsWithoutCmd = cmdArgs.Skip(1).ToArray(); string[] argsWithoutCmd = cmdArgs.Skip(1).ToArray();
CommandContext ctx = new() CommandContext ctx = new()
{ {
Client = Clients.Values.Where(x => x.Player.Username == packet.Username).FirstOrDefault(), Client = Clients.Values.Where(x => x.Username == packet.Username).FirstOrDefault(),
Args = argsWithoutCmd Args = argsWithoutCmd
}; };

View File

@ -67,7 +67,7 @@ namespace RageCoop.Server
public static NetConnection GetConnectionByUsername(string username) public static NetConnection GetConnectionByUsername(string username)
{ {
Client client = Server.Clients.Values.ToList().Find(x => x.Player.Username.ToLower() == username.ToLower()); Client client = Server.Clients.Values.ToList().Find(x => x.Username.ToLower() == username.ToLower());
if (client == null) if (client == null)
{ {
return null; return null;