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

View File

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

View File

@ -41,11 +41,10 @@ namespace RageCoop.Client.Scripting
/// </summary>
public static class Events
{
/// <summary>
/// Empty delegate
/// </summary>
#region DELEGATES
public delegate void EmptyEvent();
public delegate void CustomEvent(int hash, List<object> args);
#endregion
/// <summary>
/// The local player is dead
/// </summary>
@ -75,15 +74,38 @@ namespace RageCoop.Client.Scripting
/// This is equivalent of <see cref="GTA.Script.Tick"/>.
/// </summary>
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
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 InvokePedSpawned(SyncedPed p) { OnPedSpawned?.Invoke(null, p); }
internal static void InvokePedDeleted(SyncedPed p) { OnPedDeleted?.Invoke(null, p); }
internal static void InvokePlayerDied() { OnPlayerDied?.Invoke(); }
internal static void InvokeTick() { OnTick?.Invoke(); }
internal static void InvokeCustomEventReceived(int hash, List<object> args)
{
OnCustomEventReceived?.Invoke(hash, args);
}
#endregion
internal static void ClearHandlers()
{
OnPlayerDied=null;
OnTick=null;
OnPedDeleted=null;
OnPedSpawned=null;
OnVehicleDeleted=null;
OnVehicleSpawned=null;
OnCustomEventReceived=null;
}
}
#region FUNCTIONS
/// <summary>
/// Send a local chat message to this player
/// </summary>
@ -166,6 +188,22 @@ namespace RageCoop.Client.Scripting
{
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;
Function.Call(Hash.SET_PED_STEALTH_MOVEMENT, MainPed, IsInStealthMode, 0);
if (IsRagdoll || Health==0)
{
if (!MainPed.IsRagdoll)

View File

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

View File

@ -80,15 +80,6 @@ namespace RageCoop.Client
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)

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

View File

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

View File

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

View File

@ -7,15 +7,28 @@ using RageCoop.Core.Scripting;
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 long NetID = 0;
internal NetConnection Connection { get; set; }
public PlayerData Player;
internal long NetID = 0;
public NetConnection Connection { get;internal set; }
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 long _callbacksCount = 0;
public readonly Dictionary<long, Action<object>> Callbacks = new();
public bool IsReady { get; internal set; }=false;
public string Username { get;internal set; } = "N/A";
#region CUSTOMDATA FUNCTIONS
public void SetData<T>(string name, T data)
{
@ -190,7 +203,7 @@ namespace RageCoop.Server
{
if (!IsReady)
{
Program.Logger.Warning($"Player \"{Player.Username}\" is not ready!");
Program.Logger.Warning($"Player \"{Username}\" is not ready!");
return;
}

View File

@ -46,7 +46,8 @@ namespace RageCoop.Server
}
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
{
#region INTERNAL
internal static void InvokeCustomEvent(int hash,List<object> args)
{
}
internal static Dictionary<int, List<Action<List<object>>>> CustomEventHandlers = new();
#endregion
public static class Events
{
@ -29,30 +26,26 @@ namespace RageCoop.Server.Scripting
public static event EventHandler<HandshakeEventArgs> OnPlayerHandshake;
public static event PlayerConnect OnPlayerConnected;
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 -= (EventHandler<ChatEventArgs>)d;
}
foreach (Delegate d in OnPlayerHandshake.GetInvocationList())
{
OnPlayerHandshake -= (EventHandler<HandshakeEventArgs>)d;
}
foreach (Delegate d in OnPlayerConnected.GetInvocationList())
{
OnPlayerConnected -= (PlayerConnect)d;
}
foreach (Delegate d in OnPlayerDisconnected.GetInvocationList())
{
OnPlayerDisconnected -= (PlayerDisconnect)d;
}
OnChatMessage=null;
OnPlayerHandshake=null;
OnPlayerConnected=null;
OnPlayerDisconnected=null;
OnCustomEventReceived=null;
OnCommandReceived=null;
}
#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() {
Sender=Util.GetClientByNetID(con.RemoteUniqueIdentifier),
Sender=sender,
Message=p.Message
});
}
@ -62,6 +55,22 @@ namespace RageCoop.Server.Scripting
{ OnPlayerDisconnected?.Invoke(client); }
internal static void InvokePlayerHandshake(HandshakeEventArgs 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
}
@ -119,7 +128,7 @@ namespace RageCoop.Server.Scripting
/// <returns>The Client from this user or null</returns>
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>
@ -127,8 +136,7 @@ namespace RageCoop.Server.Scripting
/// </summary>
/// <param name="message">The chat message</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 SendChatMessageToAll(string message, string username = "Server", List<long> netHandleList = null)
public static void SendChatMessage(string message, List<Client> targets = null, string username = "Server")
{
try
{
@ -136,12 +144,22 @@ namespace RageCoop.Server.Scripting
{
return;
}
List<NetConnection> connections = netHandleList == null
? Server.MainNetServer.Connections
: Server.MainNetServer.Connections.FindAll(c => netHandleList.Contains(c.RemoteUniqueIdentifier));
Server.SendChatMessage(username, message, connections);
targets ??= new(Server.Clients.Values);
foreach(Client client in targets)
{
Server.SendChatMessage(username, message, client.Connection);
}
}
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)
{
@ -198,8 +216,13 @@ namespace RageCoop.Server.Scripting
Server.RegisterCommands<T>();
}
public static void TriggerCustomEvent(int eventHash,List<object> args,List<Client> targets=null)
/// <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>
/// <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);
var p = new Packets.CustomEvent()
@ -212,6 +235,22 @@ namespace RageCoop.Server.Scripting
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
}
}

View File

@ -12,6 +12,22 @@ namespace RageCoop.Server.Scripting
public Client Sender { 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 int ID { get; set; }

View File

@ -92,9 +92,9 @@ namespace RageCoop.Server.Scripting
{
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);
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();
}
Client sender;
private void ProcessMessage(NetIncomingMessage message)
{
if(message == null) { return; }
@ -230,16 +231,20 @@ namespace RageCoop.Server
break;
}
case NetIncomingMessageType.Data:
{
// Get packet type
byte btype = message.ReadByte();
var type = (PacketTypes)btype;
int len = message.ReadInt32();
byte[] data = message.ReadBytes(len);
try
{
// Get sender client
if (!Clients.TryGetValue(message.SenderConnection.RemoteUniqueIdentifier, out sender))
{
throw new UnauthorizedAccessException("No client data found:"+message.SenderEndPoint);
}
switch (type)
{
@ -296,19 +301,19 @@ namespace RageCoop.Server
case PacketTypes.ChatMessage:
{
try
{
Packets.ChatMessage packet = new();
packet.Unpack(data);
Packets.ChatMessage packet = new();
packet.Unpack(data);
API.Events.InvokeOnChatMessage(packet, message.SenderConnection);
SendChatMessage(packet);
}
catch (Exception e)
{
DisconnectAndLog(message.SenderConnection, type, e);
}
API.Events.InvokeOnChatMessage(packet, sender);
SendChatMessage(packet,sender);
}
break;
case PacketTypes.CustomEvent:
{
Packets.CustomEvent packet = new Packets.CustomEvent();
packet.Unpack(data);
API.Events.InvokeCustomEventReceived(packet, sender);
}
break;
@ -384,7 +389,7 @@ namespace RageCoop.Server
Client client = Util.GetClientByNetID(message.SenderConnection.RemoteUniqueIdentifier);
if (client != null)
{
client.Player.Latency = message.ReadFloat();
client.Latency = message.ReadFloat();
}
}
break;
@ -415,9 +420,9 @@ namespace RageCoop.Server
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
new Packets.PlayerInfoUpdate()
{
PedID=c.Player.PedID,
Username=c.Player.Username,
Latency=c.Player.Latency,
PedID=c.ID,
Username=c.Username,
Latency=c.Latency,
}.Pack(outgoingMessage);
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.ReliableSequenced, (byte)ConnectionChannel.Default);
});
@ -454,7 +459,7 @@ namespace RageCoop.Server
connection.Deny("Username contains special chars!");
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!");
return;
@ -485,10 +490,9 @@ namespace RageCoop.Server
{
NetID = connection.RemoteUniqueIdentifier,
Connection=connection,
Username=packet.Username,
Player = new()
{
Username = packet.Username,
PedID=packet.PedID,
}
}
);;
@ -535,8 +539,8 @@ namespace RageCoop.Server
new Packets.PlayerConnect()
{
// NetHandle = targetNetHandle,
Username = targetClient.Player.Username,
PedID=targetClient.Player.PedID,
Username = targetClient.Username,
PedID=targetClient.ID,
}.Pack(outgoingMessage);
MainNetServer.SendMessage(outgoingMessage, local, NetDeliveryMethod.ReliableOrdered, 0);
@ -547,8 +551,8 @@ namespace RageCoop.Server
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
new Packets.PlayerConnect()
{
PedID=localClient.Player.PedID,
Username = localClient.Player.Username
PedID=localClient.ID,
Username = localClient.Username
}.Pack(outgoingMessage);
if(clients.Count > 0)
{
@ -557,11 +561,11 @@ namespace RageCoop.Server
}
API.Events.InvokePlayerConnected(localClient);
Program.Logger.Info($"Player {localClient.Player.Username} connected!");
Program.Logger.Info($"Player {localClient.Username} connected!");
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)
{
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)
{
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
@ -590,7 +594,7 @@ namespace RageCoop.Server
Clients.Remove(localClient.NetID);
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
if (packet.Passengers.ContainsValue(client.Player.PedID))
if (packet.Passengers.ContainsValue(client.ID))
{
client.Player.VehicleID = packet.ID;
}
@ -644,7 +648,7 @@ namespace RageCoop.Server
{
return;
}
bool isPlayer = packet.ID==client.Player.PedID;
bool isPlayer = packet.ID==client.ID;
if (isPlayer) { client.Player.Position=packet.Position; }
foreach (var c in Clients.Values)
@ -719,19 +723,24 @@ namespace RageCoop.Server
#endregion
// 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('/'))
{
string[] cmdArgs = packet.Message.Split(" ");
string cmdName = cmdArgs[0].Remove(0, 1);
if (API.Events.InvokeOnCommandReceived(cmdName, cmdArgs, sender))
{
return;
}
if (Commands.Any(x => x.Key.Name == cmdName))
{
string[] argsWithoutCmd = cmdArgs.Skip(1).ToArray();
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
};

View File

@ -67,7 +67,7 @@ namespace RageCoop.Server
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)
{
return null;