Rework on SendNativeCall
This commit is contained in:
@ -111,68 +111,7 @@ namespace RageCoop.Client
|
||||
|
||||
|
||||
}
|
||||
private static object DecodeNativeCall(ulong hash, List<object> args, bool returnValue, byte? returnType = null)
|
||||
{
|
||||
List<InputArgument> arguments = new List<InputArgument>();
|
||||
|
||||
if (args == null || args.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
for (ushort i = 0; i < args.Count; i++)
|
||||
{
|
||||
object x = args.ElementAt(i);
|
||||
switch (x)
|
||||
{
|
||||
case int _:
|
||||
arguments.Add((int)x);
|
||||
break;
|
||||
case bool _:
|
||||
arguments.Add((bool)x);
|
||||
break;
|
||||
case float _:
|
||||
arguments.Add((float)x);
|
||||
break;
|
||||
case string _:
|
||||
arguments.Add((string)x);
|
||||
break;
|
||||
case Vector3 _:
|
||||
Vector3 vector = (Vector3)x;
|
||||
arguments.Add((float)vector.X);
|
||||
arguments.Add((float)vector.Y);
|
||||
arguments.Add((float)vector.Z);
|
||||
break;
|
||||
default:
|
||||
GTA.UI.Notification.Show("[DecodeNativeCall][" + hash + "]: Type of argument not found!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (!returnValue)
|
||||
{
|
||||
Function.Call((Hash)hash, arguments.ToArray());
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (returnType.Value)
|
||||
{
|
||||
case 0x00: // int
|
||||
return Function.Call<int>((Hash)hash, arguments.ToArray());
|
||||
case 0x01: // bool
|
||||
return Function.Call<bool>((Hash)hash, arguments.ToArray());
|
||||
case 0x02: // float
|
||||
return Function.Call<float>((Hash)hash, arguments.ToArray());
|
||||
case 0x03: // string
|
||||
return Function.Call<string>((Hash)hash, arguments.ToArray());
|
||||
case 0x04: // vector3
|
||||
return Function.Call<Vector3>((Hash)hash, arguments.ToArray());
|
||||
default:
|
||||
GTA.UI.Notification.Show("[DecodeNativeCall][" + hash + "]: Type of return not found!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
private static void DecodeNativeCallWithResponse(Packets.NativeResponse packet)
|
||||
{
|
||||
object result = DecodeNativeCall(packet.Hash, packet.Args, true, packet.ResultType);
|
||||
@ -202,6 +141,7 @@ namespace RageCoop.Client
|
||||
Client.SendMessage(outgoingMessage, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Native);
|
||||
Client.FlushSendQueue();
|
||||
}
|
||||
*/
|
||||
#endregion // -- PLAYER --
|
||||
|
||||
#endregion
|
||||
|
@ -184,26 +184,6 @@ namespace RageCoop.Client
|
||||
Main.QueueAction(() => { Main.MainChat.AddMessage(packet.Username, packet.Message); return true; });
|
||||
|
||||
|
||||
}
|
||||
break;
|
||||
case PacketTypes.NativeCall:
|
||||
{
|
||||
|
||||
Packets.NativeCall packet = new Packets.NativeCall();
|
||||
packet.Unpack(data);
|
||||
|
||||
Main.QueueAction(() => { DecodeNativeCall(packet.Hash, packet.Args, false); });
|
||||
|
||||
}
|
||||
break;
|
||||
case PacketTypes.NativeResponse:
|
||||
{
|
||||
|
||||
Packets.NativeResponse packet = new Packets.NativeResponse();
|
||||
packet.Unpack(data);
|
||||
|
||||
DecodeNativeCallWithResponse(packet);
|
||||
|
||||
}
|
||||
break;
|
||||
case PacketTypes.CustomEvent:
|
||||
|
@ -95,6 +95,9 @@ namespace RageCoop.Client.Scripting
|
||||
internal static void InvokeCustomEventReceived(Packets.CustomEvent p)
|
||||
{
|
||||
var args = new CustomEventReceivedArgs() { Hash=p.Hash, Args=p.Args};
|
||||
|
||||
// Main.Logger.Debug($"CustomEvent:\n"+args.Args.DumpWithType());
|
||||
|
||||
List<Action<CustomEventReceivedArgs>> handlers;
|
||||
if (CustomEventHandlers.TryGetValue(p.Hash, out handlers))
|
||||
{
|
||||
@ -210,7 +213,6 @@ namespace RageCoop.Client.Scripting
|
||||
Hash=eventHash
|
||||
};
|
||||
Networking.Send(p, ConnectionChannel.Event, Lidgren.Network.NetDeliveryMethod.ReliableOrdered);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -3,6 +3,9 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using GTA.Native;
|
||||
using GTA;
|
||||
using RageCoop.Core;
|
||||
using RageCoop.Core.Scripting;
|
||||
|
||||
namespace RageCoop.Client.Scripting
|
||||
@ -12,6 +15,7 @@ namespace RageCoop.Client.Scripting
|
||||
public override void OnStart()
|
||||
{
|
||||
API.RegisterCustomEventHandler(CustomEvents.SetAutoRespawn,SetAutoRespawn);
|
||||
API.RegisterCustomEventHandler(CustomEvents.NativeCall,NativeCall);
|
||||
}
|
||||
|
||||
public override void OnStop()
|
||||
@ -21,5 +25,125 @@ namespace RageCoop.Client.Scripting
|
||||
{
|
||||
API.Config.EnableAutoRespawn=(bool)args.Args[0];
|
||||
}
|
||||
private void NativeCall(CustomEventReceivedArgs e)
|
||||
{
|
||||
List<InputArgument> arguments = new List<InputArgument>();
|
||||
int i;
|
||||
var ty = (byte)e.Args[0];
|
||||
Main.Logger.Debug($"gettype");
|
||||
Main.Logger.Flush();
|
||||
TypeCode returnType=(TypeCode)ty;
|
||||
Main.Logger.Debug($"typeok");
|
||||
Main.Logger.Flush();
|
||||
i = returnType==TypeCode.Empty ? 1 : 2;
|
||||
var hash = (Hash)e.Args[i++];
|
||||
for(; i<e.Args.Count;i++)
|
||||
{
|
||||
arguments.Add(GetInputArgument(e.Args[i]));
|
||||
}
|
||||
Main.QueueAction(() =>
|
||||
{
|
||||
|
||||
if (returnType==TypeCode.Empty)
|
||||
{
|
||||
Function.Call(hash, arguments.ToArray());
|
||||
return;
|
||||
}
|
||||
var t = returnType;
|
||||
int id = (int)e.Args[1];
|
||||
|
||||
|
||||
switch (returnType)
|
||||
{
|
||||
case TypeCode.Boolean:
|
||||
API.SendCustomEvent(CustomEvents.NativeResponse,
|
||||
new List<object> { id, Function.Call<bool>(hash, arguments.ToArray()) });
|
||||
break;
|
||||
case TypeCode.Byte:
|
||||
API.SendCustomEvent(CustomEvents.NativeResponse,
|
||||
new List<object> { id, Function.Call<byte>(hash, arguments.ToArray()) });
|
||||
break;
|
||||
case TypeCode.Char:
|
||||
API.SendCustomEvent(CustomEvents.NativeResponse,
|
||||
new List<object> { id, Function.Call<char>(hash, arguments.ToArray()) });
|
||||
break;
|
||||
|
||||
case TypeCode.Single:
|
||||
API.SendCustomEvent(CustomEvents.NativeResponse,
|
||||
new List<object> { id, Function.Call<float>(hash, arguments.ToArray()) });
|
||||
break;
|
||||
|
||||
case TypeCode.Double:
|
||||
API.SendCustomEvent(CustomEvents.NativeResponse,
|
||||
new List<object> { id, Function.Call<double>(hash, arguments.ToArray()) });
|
||||
break;
|
||||
|
||||
case TypeCode.Int16:
|
||||
API.SendCustomEvent(CustomEvents.NativeResponse,
|
||||
new List<object> { id, Function.Call<short>(hash, arguments.ToArray()) });
|
||||
break;
|
||||
|
||||
case TypeCode.Int32:
|
||||
API.SendCustomEvent(CustomEvents.NativeResponse,
|
||||
new List<object> { id, Function.Call<int>(hash, arguments.ToArray()) });
|
||||
break;
|
||||
|
||||
case TypeCode.Int64:
|
||||
API.SendCustomEvent(CustomEvents.NativeResponse,
|
||||
new List<object> { id, Function.Call<long>(hash, arguments.ToArray()) });
|
||||
break;
|
||||
|
||||
case TypeCode.String:
|
||||
API.SendCustomEvent(CustomEvents.NativeResponse,
|
||||
new List<object> { id, Function.Call<string>(hash, arguments.ToArray()) });
|
||||
break;
|
||||
|
||||
case TypeCode.UInt16:
|
||||
API.SendCustomEvent(CustomEvents.NativeResponse,
|
||||
new List<object> { id, Function.Call<ushort>(hash, arguments.ToArray()) });
|
||||
break;
|
||||
|
||||
case TypeCode.UInt32:
|
||||
API.SendCustomEvent(CustomEvents.NativeResponse,
|
||||
new List<object> { id, Function.Call<uint>(hash, arguments.ToArray()) });
|
||||
break;
|
||||
|
||||
case TypeCode.UInt64:
|
||||
API.SendCustomEvent(CustomEvents.NativeResponse,
|
||||
new List<object> { id, Function.Call<ulong>(hash, arguments.ToArray()) });
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
private InputArgument GetInputArgument(object obj)
|
||||
{
|
||||
// Implicit conversion
|
||||
switch (obj)
|
||||
{
|
||||
case byte _:
|
||||
return (byte)obj;
|
||||
case short _:
|
||||
return (short)obj;
|
||||
case ushort _:
|
||||
return (ushort)obj;
|
||||
case int _:
|
||||
return (int)obj;
|
||||
case uint _:
|
||||
return (uint)obj;
|
||||
case long _:
|
||||
return (long)obj;
|
||||
case ulong _:
|
||||
return (ulong)obj;
|
||||
case float _:
|
||||
return (float)obj;
|
||||
case bool _:
|
||||
return (bool)obj;
|
||||
case string _:
|
||||
return (obj as string);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ namespace RageCoop.Core
|
||||
switch (obj)
|
||||
{
|
||||
case byte _:
|
||||
return (0x01, BitConverter.GetBytes((byte)obj));
|
||||
return (0x01, new byte[] { (byte)obj });
|
||||
case short _:
|
||||
return (0x02, BitConverter.GetBytes((short)obj));
|
||||
case ushort _:
|
||||
@ -120,5 +120,87 @@ namespace RageCoop.Core
|
||||
{
|
||||
return (flagToCheck & flag)!=0;
|
||||
}
|
||||
public static Type GetActualType(this TypeCode code)
|
||||
{
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case TypeCode.Boolean:
|
||||
return typeof(bool);
|
||||
|
||||
case TypeCode.Byte:
|
||||
return typeof(byte);
|
||||
|
||||
case TypeCode.Char:
|
||||
return typeof(char);
|
||||
|
||||
case TypeCode.DateTime:
|
||||
return typeof(DateTime);
|
||||
|
||||
case TypeCode.DBNull:
|
||||
return typeof(DBNull);
|
||||
|
||||
case TypeCode.Decimal:
|
||||
return typeof(decimal);
|
||||
|
||||
case TypeCode.Double:
|
||||
return typeof(double);
|
||||
|
||||
case TypeCode.Empty:
|
||||
return null;
|
||||
|
||||
case TypeCode.Int16:
|
||||
return typeof(short);
|
||||
|
||||
case TypeCode.Int32:
|
||||
return typeof(int);
|
||||
|
||||
case TypeCode.Int64:
|
||||
return typeof(long);
|
||||
|
||||
case TypeCode.Object:
|
||||
return typeof(object);
|
||||
|
||||
case TypeCode.SByte:
|
||||
return typeof(sbyte);
|
||||
|
||||
case TypeCode.Single:
|
||||
return typeof(Single);
|
||||
|
||||
case TypeCode.String:
|
||||
return typeof(string);
|
||||
|
||||
case TypeCode.UInt16:
|
||||
return typeof(UInt16);
|
||||
|
||||
case TypeCode.UInt32:
|
||||
return typeof(UInt32);
|
||||
|
||||
case TypeCode.UInt64:
|
||||
return typeof(UInt64);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
public static string DumpWithType(this IEnumerable<object> objects)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach(var obj in objects)
|
||||
{
|
||||
sb.Append(obj.GetType()+":"+obj.ToString()+"\n");
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
public static string Dump<T>(this IEnumerable<T> objects)
|
||||
{
|
||||
return "{"+string.Join(",",objects)+"}";
|
||||
}
|
||||
public static void ForEach<T>(this IEnumerable<T> objects,Action<T> action)
|
||||
{
|
||||
foreach(var obj in objects)
|
||||
{
|
||||
action(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ namespace RageCoop.Core
|
||||
public class CustomEvent : Packet
|
||||
{
|
||||
public int Hash { get; set; }
|
||||
public List<object> Args { get; set; }=new List<object>();
|
||||
public List<object> Args { get; set; }
|
||||
|
||||
public override void Pack(NetOutgoingMessage message)
|
||||
{
|
||||
@ -23,7 +23,7 @@ namespace RageCoop.Core
|
||||
foreach (var arg in Args)
|
||||
{
|
||||
tup=CoreUtils.GetBytesFromObject(arg);
|
||||
if (tup.Item2==null)
|
||||
if (tup.Item1==0||tup.Item2==null)
|
||||
{
|
||||
throw new ArgumentException($"Object of type {arg.GetType()} is not supported");
|
||||
}
|
||||
@ -41,10 +41,11 @@ namespace RageCoop.Core
|
||||
|
||||
Hash = reader.ReadInt();
|
||||
var len=reader.ReadInt();
|
||||
Args=new List<object>(len);
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
byte argType = reader.ReadByte();
|
||||
switch (argType)
|
||||
byte type = reader.ReadByte();
|
||||
switch (type)
|
||||
{
|
||||
case 0x01:
|
||||
Args.Add(reader.ReadByte());
|
||||
@ -76,6 +77,9 @@ namespace RageCoop.Core
|
||||
case 0x10:
|
||||
Args.Add(reader.ReadString());
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException($"Unexpected type:{type}\r\n{array.Dump()}");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,8 +15,8 @@ namespace RageCoop.Core
|
||||
PlayerInfoUpdate=3,
|
||||
|
||||
ChatMessage=10,
|
||||
NativeCall=11,
|
||||
NativeResponse=12,
|
||||
// NativeCall=11,
|
||||
// NativeResponse=12,
|
||||
//Mod=13,
|
||||
CleanUpWorld=14,
|
||||
|
||||
@ -191,7 +191,7 @@ namespace RageCoop.Core
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
#region ===== NATIVECALL =====
|
||||
public class NativeCall : Packet
|
||||
{
|
||||
@ -423,6 +423,7 @@ namespace RageCoop.Core
|
||||
}
|
||||
}
|
||||
#endregion // ===== NATIVECALL =====
|
||||
*/
|
||||
}
|
||||
|
||||
public static class CoopSerializer
|
||||
|
@ -1,19 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace RageCoop.Core.Scripting
|
||||
{
|
||||
internal static class CustomEvents
|
||||
{
|
||||
static MD5 Hasher = MD5.Create();
|
||||
public static int SendWeather = Hash("RageCoop.SendWeather");
|
||||
public static int OnPlayerDied = Hash("RageCoop.OnPlayerDied");
|
||||
public static int SetAutoRespawn = Hash("RageCoop.SetAutoRespawn");
|
||||
public static int Hash(string s)
|
||||
{
|
||||
return BitConverter.ToInt32(Hasher.ComputeHash(Encoding.UTF8.GetBytes(s)), 0);
|
||||
}
|
||||
}
|
||||
}
|
52
RageCoop.Core/Scripting/CustomEvents.cs
Normal file
52
RageCoop.Core/Scripting/CustomEvents.cs
Normal file
@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace RageCoop.Core.Scripting
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static class CustomEvents
|
||||
{
|
||||
static MD5 Hasher = MD5.Create();
|
||||
static Dictionary<int,string> Hashed=new Dictionary<int,string>();
|
||||
public static readonly int SetWeather = Hash("RageCoop.SetWeather");
|
||||
public static readonly int OnPlayerDied = Hash("RageCoop.OnPlayerDied");
|
||||
public static readonly int SetAutoRespawn = Hash("RageCoop.SetAutoRespawn");
|
||||
public static readonly int NativeCall = Hash("RageCoop.NativeCall");
|
||||
// public static readonly int NativeCallNoResponse = Hash("RageCoop.NativeCallNoResponse");
|
||||
public static readonly int NativeResponse = Hash("RageCoop.NativeResponse");
|
||||
/// <summary>
|
||||
/// Get a Int32 hash of a string.
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentException">The exception is thrown when the name did not match a previously computed one and the hash was the same.</exception>
|
||||
public static int Hash(string s)
|
||||
{
|
||||
var hash = BitConverter.ToInt32(Hasher.ComputeHash(Encoding.UTF8.GetBytes(s)), 0);
|
||||
string name;
|
||||
lock (Hashed)
|
||||
{
|
||||
if (Hashed.TryGetValue(hash, out name))
|
||||
{
|
||||
if (name!=s)
|
||||
{
|
||||
throw new ArgumentException($"Hashed value has collision with another name:{name}, hashed value:{hash}");
|
||||
}
|
||||
else
|
||||
{
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Hashed.Add(hash, s);
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ using RageCoop.Core;
|
||||
using Lidgren.Network;
|
||||
using GTA.Math;
|
||||
using RageCoop.Core.Scripting;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace RageCoop.Server
|
||||
{
|
||||
@ -49,12 +50,11 @@ namespace RageCoop.Server
|
||||
private PlayerConfig _config { get; set; }=new PlayerConfig();
|
||||
public PlayerConfig Config { get { return _config; }set { _config=value;Server.SendPlayerInfos(); } }
|
||||
|
||||
private readonly Dictionary<string, object> _customData = new();
|
||||
private long _callbacksCount = 0;
|
||||
public readonly Dictionary<long, Action<object>> Callbacks = new();
|
||||
internal readonly Dictionary<int, 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)
|
||||
{
|
||||
if (HasData(name))
|
||||
@ -84,8 +84,9 @@ namespace RageCoop.Server
|
||||
_customData.Remove(name);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
*/
|
||||
|
||||
#endregion
|
||||
#region FUNCTIONS
|
||||
public void Kick(string reason="You have been kicked!")
|
||||
{
|
||||
@ -113,7 +114,7 @@ namespace RageCoop.Server
|
||||
Program.Logger.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/// <summary>
|
||||
/// Send a native call to client and ignore its return value.
|
||||
/// </summary>
|
||||
@ -220,7 +221,53 @@ namespace RageCoop.Server
|
||||
Program.Logger.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Send a native call to client and do a callback when the response received.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the response</typeparam>
|
||||
/// <param name="callBack"></param>
|
||||
/// <param name="hash"></param>
|
||||
/// <param name="args"></param>
|
||||
public void SendNativeCall<T>(Action<object> callBack, GTA.Native.Hash hash, params object[] args)
|
||||
{
|
||||
var argsList= new List<object>(args);
|
||||
argsList.InsertRange(0, new object[] { (byte)Type.GetTypeCode(typeof(T)), RequestNativeCallID<T>(callBack), (ulong)hash });
|
||||
|
||||
SendCustomEvent(CustomEvents.NativeCall, argsList);
|
||||
}
|
||||
/// <summary>
|
||||
/// Send a native call to client and ignore it's response.
|
||||
/// </summary>
|
||||
/// <param name="hash"></param>
|
||||
/// <param name="args"></param>
|
||||
public void SendNativeCall(GTA.Native.Hash hash, params object[] args)
|
||||
{
|
||||
var argsList = new List<object>(args);
|
||||
argsList.InsertRange(0, new object[] { (byte)TypeCode.Empty,(ulong)hash});
|
||||
// Program.Logger.Debug(argsList.DumpWithType());
|
||||
SendCustomEvent(CustomEvents.NativeCall, argsList);
|
||||
}
|
||||
private int RequestNativeCallID<T>(Action<object> callback)
|
||||
{
|
||||
int ID = 0;
|
||||
lock (Callbacks)
|
||||
{
|
||||
while ((ID==0)
|
||||
|| Callbacks.ContainsKey(ID))
|
||||
{
|
||||
byte[] rngBytes = new byte[4];
|
||||
|
||||
RandomNumberGenerator.Create().GetBytes(rngBytes);
|
||||
|
||||
// Convert the bytes into an integer
|
||||
ID = BitConverter.ToInt32(rngBytes, 0);
|
||||
}
|
||||
Callbacks.Add(ID, callback);
|
||||
}
|
||||
return ID;
|
||||
}
|
||||
public void SendCleanUpWorld()
|
||||
{
|
||||
NetConnection userConnection = Server.MainNetServer.Connections.Find(x => x.RemoteUniqueIdentifier == NetID);
|
||||
@ -239,7 +286,6 @@ namespace RageCoop.Server
|
||||
if (!IsReady)
|
||||
{
|
||||
Program.Logger.Warning($"Player \"{Username}\" is not ready!");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
|
@ -5,6 +5,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Lidgren.Network;
|
||||
using RageCoop.Core;
|
||||
using RageCoop.Core.Scripting;
|
||||
using System.Net;
|
||||
|
||||
namespace RageCoop.Server.Scripting
|
||||
@ -93,6 +94,7 @@ namespace RageCoop.Server.Scripting
|
||||
}
|
||||
|
||||
#region FUNCTIONS
|
||||
/*
|
||||
/// <summary>
|
||||
/// Send a native call (Function.Call) to all players.
|
||||
/// Keys = int, float, bool, string and lvector3
|
||||
@ -129,14 +131,14 @@ namespace RageCoop.Server.Scripting
|
||||
Program.Logger.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
/// <summary>
|
||||
/// Get a list of all Clients
|
||||
/// </summary>
|
||||
/// <returns>All clients as a dictionary indexed by NetID</returns>
|
||||
public static Dictionary<long, Client> GetAllClients()
|
||||
{
|
||||
return Server.Clients;
|
||||
return new(Server.Clients);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -270,6 +272,10 @@ namespace RageCoop.Server.Scripting
|
||||
handlers.Add(handler);
|
||||
}
|
||||
}
|
||||
public static void RegisterCustomEventHandler(string name, Action<CustomEventReceivedArgs> handler)
|
||||
{
|
||||
RegisterCustomEventHandler(CustomEvents.Hash(name), handler);
|
||||
}
|
||||
public static Logger GetLogger()
|
||||
{
|
||||
return Program.Logger;
|
||||
|
@ -11,6 +11,7 @@ namespace RageCoop.Server.Scripting
|
||||
{
|
||||
public override void OnStart()
|
||||
{
|
||||
API.RegisterCustomEventHandler(CustomEvents.NativeResponse, NativeResponse);
|
||||
}
|
||||
public override void OnStop()
|
||||
{
|
||||
@ -19,5 +20,26 @@ namespace RageCoop.Server.Scripting
|
||||
{
|
||||
c.SendCustomEvent(CustomEvents.SetAutoRespawn, new() { toggle });
|
||||
}
|
||||
void NativeResponse(CustomEventReceivedArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
int id = (int)e.Args[0];
|
||||
Action<object> callback;
|
||||
lock (e.Sender.Callbacks)
|
||||
{
|
||||
if (e.Sender.Callbacks.TryGetValue(id, out callback))
|
||||
{
|
||||
callback(e.Args[1]);
|
||||
e.Sender.Callbacks.Remove(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
API.GetLogger().Error("Failed to parse NativeResponse");
|
||||
API.GetLogger().Error(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +83,15 @@ namespace RageCoop.Server.Scripting
|
||||
{
|
||||
foreach (var s in d.Scripts)
|
||||
{
|
||||
s.OnStop();
|
||||
try
|
||||
{
|
||||
|
||||
s.OnStop();
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Logger?.Error(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ namespace RageCoop.Server
|
||||
internal class Server
|
||||
{
|
||||
private static readonly string _compatibleVersion = "V0_5";
|
||||
private static BaseScript BaseScript { get; set; }=new BaseScript();
|
||||
public static BaseScript BaseScript { get; set; }=new BaseScript();
|
||||
public static readonly Settings MainSettings = Util.Read<Settings>("Settings.xml");
|
||||
public static NetServer MainNetServer;
|
||||
|
||||
@ -317,22 +317,6 @@ namespace RageCoop.Server
|
||||
}
|
||||
break;
|
||||
|
||||
case PacketTypes.NativeResponse:
|
||||
{
|
||||
Packets.NativeResponse packet = new();
|
||||
packet.Unpack(data);
|
||||
|
||||
Client client = Util.GetClientByNetID(message.SenderConnection.RemoteUniqueIdentifier);
|
||||
if (client != null)
|
||||
{
|
||||
if (client.Callbacks.ContainsKey(packet.ID))
|
||||
{
|
||||
client.Callbacks[packet.ID].Invoke(packet.Args[0]);
|
||||
client.Callbacks.Remove(packet.ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PacketTypes.FileTransferComplete:
|
||||
{
|
||||
Packets.FileTransferComplete packet = new Packets.FileTransferComplete();
|
||||
|
Reference in New Issue
Block a user