Alright. I am making a script that I want to release. On my event, it requires 3 arguments, 1 being a Player, and the other 2 being String. When I try to trigger my event using a chat message, it sends the error to the chat, that goes something like
Error invoking callback for event ds:newname: System.InvalidCastException: Could not cast event argument from ExpandoObject to Player
at CitizenFX.Core.CallUtilities.<GetPassArguments>g__ChangeType0_0 (System.Object value, System.Type type) [0x00020] in /src/code/client/clrcore/EventHandlerDictionary.cs:121
at CitizenFX.Core.CallUtilities.GetPassArguments (System.Reflection.MethodInfo method, System.Object[] args, System.String sourceString) [0x00085] in /src/code/client/clrcore/EventHandlerDictionary.cs:159
at CitizenFX.Core.EventHandlerEntry+<Invoke>d__5.MoveNext () [0x00047] in /src/code/client/clrcore/EventHandlerDictionary.cs:84
CouldSending heartbeat to live-internal.fivem.net:30110
I don’t know why this is happening because there is nothing to cast, just the player to player in the event. I don’t know if this is happening to anyone else but this only happens to me when I do it to the class Player. It never happens when I put String or Int32 or Boolean. I find this very weird and it is limiting my progress on my script. I have tried to fix it for many days now but it just doesn’t want to work.
EDIT: If you have this issue yourself, don’t look at just the answer, read the rest of the comments below. They will help you too if you are on server side.
If I pass the handle which is a String how am I supposed to convert the handle back to the type of Player. I don’t see a constructor and the method that I am using this event in is not in the BaseScript class.
Sorry that I never confirmed this before. I am on server side. On server side (for some reason) the player.Handle passes a String and not an Int32 and there is no constructor. I just downloaded the newest serverside version of CitizenFX.Core and it is still passing these things. Here is the code from my metadata:
public class Player
{
public System.String Handle { get; }
public System.String Name { get; }
public System.Int32 Ping { get; }
public System.Int32 LastMsg { get; }
public IdentifierCollection Identifiers { get; }
public System.String EndPoint { get; }
public void Drop(System.String reason);
public void TriggerEvent(System.String eventName, params System.Object[] args);
}
I was looking at the source too and thought that it was weird that on there it passes an Int32 instead of a String like server side.
I just thought there would be a better way of doing this than making my own method, I always that that there would be some sort of item in the Core’s code that would allow me to not make my own method. Thanks for the help anyway.
I’ve found a workaround, aka if you wish to pass a class object through an event in C#, what you can do is, convert the class you want to pass to JSON and after you receive, store it in the same class by converting it back.
Example to pass the class
public class Player
{
public string Name {get; set;}
public string Email {get; set;}
public PlayerSkin()
{
Name = "Kenth.";
}
}
Player me = new Player();
// Now if you wanna pass it via triggerevent...
string playerData = JsonConvert.SerializeObject(me);
BaseScript.TriggerClientEvent("eventname", playerData);
// And in the client class library that you share that class with just...
public void eventnamehandler(string playerData)
{
Player me = new Player();
me = JsonConvert.DeserializeObject<Player>(playerData);
}