Add SendCustomEventQueued()

This commit is contained in:
Sardelka
2022-07-05 11:18:26 +08:00
parent fff5ec4534
commit 05304f9461
9 changed files with 173 additions and 136 deletions

View File

@ -267,10 +267,19 @@ namespace RageCoop.Client
{
Packets.CustomEvent packet = new Packets.CustomEvent(_resolveHandle);
packet.Unpack(data);
Main.Logger.Debug(packet.Args.DumpWithType());
Scripting.API.Events.InvokeCustomEventReceived(packet);
}
break;
case PacketType.CustomEventQueued:
{
Packets.CustomEvent packet = new Packets.CustomEvent(_resolveHandle);
Main.QueueAction(() =>
{
packet.Unpack(data);
Scripting.API.Events.InvokeCustomEventReceived(packet);
});
}
break;
case PacketType.FileTransferChunk:
{
Packets.FileTransferChunk packet = new Packets.FileTransferChunk();

View File

@ -19,7 +19,6 @@ namespace RageCoop.Client.Scripting
API.RegisterCustomEventHandler(CustomEvents.DeleteServerProp, DeleteServerProp);
API.RegisterCustomEventHandler(CustomEvents.DeleteEntity, DeleteEntity);
API.RegisterCustomEventHandler(CustomEvents.SetDisplayNameTag, SetNameTag);
API.RegisterCustomEventHandler(CustomEvents.SetEntity, SetEntity);
API.RegisterCustomEventHandler(CustomEvents.ServerBlipSync, ServerBlipSync);
API.RegisterCustomEventHandler(CustomEvents.DeleteServerBlip, DeleteServerBlip);
API.RegisterCustomEventHandler(CustomEvents.CreateVehicle, CreateVehicle);
@ -30,41 +29,35 @@ namespace RageCoop.Client.Scripting
private void UpdatePedBlip(CustomEventReceivedArgs e)
{
API.QueueAction(() =>
var p = Ped.FromHandle((int)e.Args[0]);
if (p == null) { return; }
if (p.Handle==Game.Player.Character.Handle)
{
var p = Ped.FromHandle((int)e.Args[0]);
if(p == null) { return; }
if (p.Handle==Game.Player.Character.Handle)
{
API.Config.BlipColor=(BlipColor)(byte)e.Args[1];
API.Config.BlipSprite=(BlipSprite)(ushort)e.Args[2];
API.Config.BlipScale=(float)e.Args[3];
}
else
{
var b = p.AttachedBlip;
if(b == null) { b=p.AddBlip(); }
b.Color=(BlipColor)(byte)e.Args[1];
b.Sprite=(BlipSprite)(ushort)e.Args[2];
b.Scale=(float)e.Args[3];
}
});
API.Config.BlipColor=(BlipColor)(byte)e.Args[1];
API.Config.BlipSprite=(BlipSprite)(ushort)e.Args[2];
API.Config.BlipScale=(float)e.Args[3];
}
else
{
var b = p.AttachedBlip;
if (b == null) { b=p.AddBlip(); }
b.Color=(BlipColor)(byte)e.Args[1];
b.Sprite=(BlipSprite)(ushort)e.Args[2];
b.Scale=(float)e.Args[3];
}
}
private void CreateVehicle(CustomEventReceivedArgs e)
{
API.QueueAction(() =>
var veh = World.CreateVehicle((Model)e.Args[1], (Vector3)e.Args[2], (float)e.Args[3]);
veh.CanPretendOccupants=false;
var v = new SyncedVehicle()
{
var veh = World.CreateVehicle((Model)e.Args[1],(Vector3)e.Args[2],(float)e.Args[3]);
veh.CanPretendOccupants=false;
var v = new SyncedVehicle()
{
ID=(int)e.Args[0],
MainVehicle=veh,
OwnerID=Main.LocalPlayerID,
};
EntityPool.Add(v);
});
ID=(int)e.Args[0],
MainVehicle=veh,
OwnerID=Main.LocalPlayerID,
};
EntityPool.Add(v);
}
private void DeleteServerBlip(CustomEventReceivedArgs e)
@ -72,9 +65,7 @@ namespace RageCoop.Client.Scripting
if (EntityPool.ServerBlips.TryGetValue((int)e.Args[0], out var blip))
{
EntityPool.ServerBlips.Remove((int)e.Args[0]);
API.QueueAction(()=>{
blip?.Delete();
});
blip?.Delete();
}
}
@ -88,35 +79,22 @@ namespace RageCoop.Client.Scripting
int rot= (int)obj.Args[5];
var name=(string)obj.Args[6];
Blip blip;
API.QueueAction(() =>
if (!EntityPool.ServerBlips.TryGetValue(id, out blip))
{
// Main.Logger.Debug($"{sprite},{color},{scale},{pos},{rot}");
if (!EntityPool.ServerBlips.TryGetValue(id, out blip))
{
EntityPool.ServerBlips.Add(id, blip=World.CreateBlip(pos));
}
blip.Sprite = sprite;
blip.Color = color;
blip.Scale = scale;
blip.Position = pos;
blip.Rotation = rot;
blip.Name = name;
});
EntityPool.ServerBlips.Add(id, blip=World.CreateBlip(pos));
}
blip.Sprite = sprite;
blip.Color = color;
blip.Scale = scale;
blip.Position = pos;
blip.Rotation = rot;
blip.Name = name;
}
private void SetEntity(CustomEventReceivedArgs obj)
{
API.QueueAction(() =>
{
var e=Entity.FromHandle((int)obj.Args[0]);
e.Position = (Vector3)obj.Args[1];
e.Rotation = (Vector3)obj.Args[2];
});
}
private void DeleteEntity(CustomEventReceivedArgs e)
{
API.QueueAction(() => Entity.FromHandle((int)e.Args[0])?.Delete());
Entity.FromHandle((int)e.Args[0])?.Delete();
}
public override void OnStop()
@ -140,8 +118,9 @@ namespace RageCoop.Client.Scripting
if (EntityPool.ServerProps.TryGetValue(id, out var prop))
{
EntityPool.ServerProps.Remove(id);
API.QueueAction(() => { prop?.MainProp?.Delete(); });
prop?.MainProp?.Delete();
}
}
private void ServerObjectSync(CustomEventReceivedArgs e)
{
@ -158,7 +137,7 @@ namespace RageCoop.Client.Scripting
prop.ModelHash= (Model)e.Args[1];
prop.Position=(Vector3)e.Args[2];
prop.Rotation=(Vector3)e.Args[3];
Main.QueueAction(() => { prop.Update(); });
prop.Update();
}
private void NativeCall(CustomEventReceivedArgs e)
{
@ -172,79 +151,76 @@ namespace RageCoop.Client.Scripting
{
arguments.Add(GetInputArgument(e.Args[i]));
}
Main.QueueAction(() =>
if (returnType==TypeCode.Empty)
{
if (returnType==TypeCode.Empty)
{
Function.Call(hash, arguments.ToArray());
return;
}
var t = returnType;
int id = (int)e.Args[1];
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;
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.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.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.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.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.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.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.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.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;
}
});
case TypeCode.UInt64:
API.SendCustomEvent(CustomEvents.NativeResponse,
new List<object> { id, Function.Call<ulong>(hash, arguments.ToArray()) });
break;
}
}
private InputArgument GetInputArgument(object obj)

View File

@ -9,10 +9,12 @@ namespace RageCoop.Core
internal class CustomEvent : Packet
{
public CustomEvent(Func<byte,BitReader,object> onResolve = null)
public CustomEvent(Func<byte,BitReader,object> onResolve = null,bool queued=false)
{
_resolve= onResolve;
_queued= queued;
}
private bool _queued;
private Func<byte, BitReader, object> _resolve { get; set; }
public int Hash { get; set; }
public bool IsStaged { get; set; }=false;
@ -21,7 +23,7 @@ namespace RageCoop.Core
public override void Pack(NetOutgoingMessage message)
{
Args= Args ?? new object[] { };
message.Write((byte)PacketType.CustomEvent);
message.Write(_queued ? (byte)PacketType.CustomEventQueued: (byte)PacketType.CustomEvent);
List<byte> result = new List<byte>();
result.AddInt(Hash);

View File

@ -31,6 +31,7 @@ namespace RageCoop.Core
AllResourcesSent=15,
CustomEvent = 16,
CustomEventQueued = 17,
#region Sync
#region INTERVAL

View File

@ -159,7 +159,7 @@ namespace RageCoop.Server
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.ToArray());
SendCustomEventQueued(CustomEvents.NativeCall, argsList.ToArray());
}
/// <summary>
/// Send a native call to client and ignore it's response.
@ -171,7 +171,7 @@ namespace RageCoop.Server
var argsList = new List<object>(args);
argsList.InsertRange(0, new object[] { (byte)TypeCode.Empty,(ulong)hash });
// Server.Logger?.Debug(argsList.DumpWithType());
SendCustomEvent(CustomEvents.NativeCall, argsList.ToArray());
SendCustomEventQueued(CustomEvents.NativeCall, argsList.ToArray());
}
private int RequestNativeCallID<T>(Action<object> callback)
{
@ -222,6 +222,36 @@ namespace RageCoop.Server
}
}
/// <summary>
/// Send a CustomEvent that'll be queued at client side and invoked from script thread
/// </summary>
/// <param name="hash"></param>
/// <param name="args"></param>
public void SendCustomEventQueued(int hash, params object[] args)
{
if (!IsReady)
{
Server.Logger?.Warning($"Player \"{Username}\" is not ready!");
}
try
{
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
new Packets.CustomEvent(null,true)
{
Hash=hash,
Args=args
}.Pack(outgoingMessage);
Server.MainNetServer.SendMessage(outgoingMessage, Connection, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Event);
}
catch (Exception ex)
{
Server.Logger?.Error(ex);
}
}
#endregion
}
}

View File

@ -256,7 +256,7 @@ namespace RageCoop.Server.Scripting
{
var argsList = new List<object>(args);
argsList.InsertRange(0, new object[] { (byte)TypeCode.Empty, (ulong)hash });
SendCustomEvent(clients, CustomEvents.NativeCall, argsList.ToArray());
SendCustomEventQueued(clients, CustomEvents.NativeCall, argsList.ToArray());
}
@ -280,6 +280,27 @@ namespace RageCoop.Server.Scripting
Server.Send(p, c, ConnectionChannel.Event, NetDeliveryMethod.ReliableOrdered);
}
}
/// <summary>
/// Send a CustomEvent that'll be queued at client side and invoked from script thread
/// </summary>
/// <param name="targets"></param>
/// <param name="eventHash"></param>
/// <param name="args"></param>
public void SendCustomEventQueued(List<Client> targets, int eventHash, params object[] args)
{
targets ??= new(Server.Clients.Values);
var p = new Packets.CustomEvent(null,true)
{
Args=args,
Hash=eventHash
};
foreach (var c in targets)
{
Server.Send(p, c, ConnectionChannel.Event, NetDeliveryMethod.ReliableOrdered);
}
}
/// <summary>
/// Register an handler to the specifed event hash, one event can have multiple handlers.
/// </summary>

View File

@ -41,14 +41,14 @@ namespace RageCoop.Server.Scripting
{
foreach(var obj in objects)
{
API.SendCustomEvent(clients, CustomEvents.ServerPropSync,obj.ID, obj.Model ,obj.Position,obj.Rotation );
API.SendCustomEventQueued(clients, CustomEvents.ServerPropSync,obj.ID, obj.Model ,obj.Position,obj.Rotation );
}
}
public void SendServerBlipsTo(List<ServerBlip> objects, List<Client> clients = null)
{
foreach (var obj in objects)
{
API.SendCustomEvent(clients, CustomEvents.ServerBlipSync, obj.ID, (ushort)obj.Sprite, (byte)obj.Color, obj.Scale,obj.Position,obj.Rotation,obj.Name );
API.SendCustomEventQueued(clients, CustomEvents.ServerBlipSync, obj.ID, (ushort)obj.Sprite, (byte)obj.Color, obj.Scale,obj.Position,obj.Rotation,obj.Name );
}
}
void NativeResponse(CustomEventReceivedArgs e)

View File

@ -135,7 +135,7 @@ namespace RageCoop.Server
Model=model,
_pos= pos,
};
owner.SendCustomEvent(CustomEvents.CreateVehicle,veh.ID, model, pos, heading);
owner.SendCustomEventQueued(CustomEvents.CreateVehicle,veh.ID, model, pos, heading);
Vehicles.Add(veh.ID, veh);
return veh;
}

View File

@ -89,16 +89,14 @@ namespace RageCoop.Server
/// <summary>
/// Send updated information to clients, would be called automatically.
/// </summary>
internal virtual void Update() {
Owner?.SendCustomEvent(CustomEvents.SetEntity, Handle, Position, Rotation);
}
/// <summary>
/// Delete this object
/// </summary>
public virtual void Delete()
{
Owner?.SendCustomEvent(CustomEvents.DeleteEntity, Handle);
Owner?.SendCustomEventQueued(CustomEvents.DeleteEntity, Handle);
}
/// <summary>
@ -131,7 +129,7 @@ namespace RageCoop.Server
/// </summary>
public override void Delete()
{
Server.API.SendCustomEvent(null,CustomEvents.DeleteServerProp,ID);
Server.API.SendCustomEventQueued(null,CustomEvents.DeleteServerProp,ID);
Server.API.Entities.RemoveProp(ID);
}
@ -157,7 +155,7 @@ namespace RageCoop.Server
/// <summary>
/// Send updated information to clients, would be called automatically.
/// </summary>
internal override void Update()
internal void Update()
{
Server.API.Server.BaseScript.SendServerPropsTo(new() { this });
}
@ -315,7 +313,7 @@ namespace RageCoop.Server
/// </summary>
public void Delete()
{
Server.API.SendCustomEvent(null, CustomEvents.DeleteServerBlip,ID);
Server.API.SendCustomEventQueued(null, CustomEvents.DeleteServerBlip,ID);
Server.Entities.RemoveServerBlip(ID);
}
@ -406,7 +404,7 @@ namespace RageCoop.Server
}
private void DoUpdate()
{
Ped.Owner.SendCustomEvent(CustomEvents.UpdatePedBlip,Ped.Handle,(byte)Color,(ushort)Sprite,Scale);
Ped.Owner.SendCustomEventQueued(CustomEvents.UpdatePedBlip,Ped.Handle,(byte)Color,(ushort)Sprite,Scale);
}
}