Resource system
This commit is contained in:
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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())
|
||||||
{
|
{
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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'">
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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; }
|
||||||
|
@ -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}");
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
Reference in New Issue
Block a user