C# registercommand with arguments

Im trying to make a simple command that accepts arguments but im not doing it right.

So far i have managed to get to this stage:

 RegisterCommand(“testargs”, new Action<int, dynamic, string>((source, args, raw) =>
{
if (args.Count > 0)
{
dynamic target = args[0];
if (target == null || GetPlayerName(target) == null)
{
TriggerClientEvent(“madmin:message”, “MAdmin: ~y~No player id detected!”);
}
else
{
TriggerClientEvent(“madmin:message”, "MAdmin: ~y~Player: " + GetPlayerName(target) + “”);
}
}
}), false);

The problem is that when i try to run the command without a argument, it breaks the resource.

Here is the error i get in the console when it crashes:

[   1795562] System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
[   1795562] Parameter name: index
[   1795562]   at System.ThrowHelper.ThrowArgumentOutOfRange_IndexException () [0x0000c] in <49fde7938a9b47b480042d844e818c7e>:0 
[   1795562]   at (wrapper dynamic-method) System.Object.CallSite.Target(System.Runtime.CompilerServices.Closure,System.Runtime.CompilerServices.CallSite,object,int)
[   1795562]   at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet] (System.Runtime.CompilerServices.CallSite site, T0 arg0, T1 arg1) [0x0010f] in :0 
[   1795562]   at MAdminServer.Server.<.ctor>b__0_1 (System.Int32 source, System.Object args, System.String raw) [0x000da] in :0 
[   1795562]   at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke(System.Reflection.MonoMethod,object,object[],System.Exception&)
[   1795562]   at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00032] in <49fde7938a9b47b480042d844e818c7e>:0 
[   1795562]    --- End of inner exception stack trace ---
[   1795562] 
[   1795562] 
[   1795562] Server stack trace: 
[   1795562]   at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00048] in <49fde7938a9b47b480042d844e818c7e>:0 
[   1795562]   at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <49fde7938a9b47b480042d844e818c7e>:0 
[   1795562]   at System.Delegate.DynamicInvokeImpl (System.Object[] args) [0x000e7] in <49fde7938a9b47b480042d844e818c7e>:0 
[   1795562]   at System.MulticastDelegate.DynamicInvokeImpl (System.Object[] args) [0x00008] in <49fde7938a9b47b480042d844e818c7e>:0 
[   1795562]   at System.Delegate.DynamicInvoke (System.Object[] args) [0x00000] in <49fde7938a9b47b480042d844e818c7e>:0 
[   1795562]   at CitizenFX.Core.FunctionReference.Invoke (System.Int32 reference, System.Byte[] arguments) [0x00061] in /src/code/client/clrcore/FunctionReference.cs:62 
[   1795562]   at CitizenFX.Core.InternalManager.CallRef (System.Int32 refIndex, System.Byte[] argsSerialized, System.IntPtr& retvalSerialized, System.Int32& retvalSize) [0x00000] in /src/code/client/clrcore/InternalManager.cs:247 
[   1795562]   at (wrapper remoting-invoke-with-check) CitizenFX.Core.InternalManager.CallRef(int,byte[],intptr&,int&)
[   1795562]   at (wrapper xdomain-dispatch) CitizenFX.Core.InternalManager.CallRef(object,byte[]&,byte[]&,int,byte[],int&)
[   1795562] 
[   1795562] Exception rethrown at [0]: 
[   1795562]   at (wrapper xdomain-invoke) CitizenFX.Core.InternalManager.CallRef(int,byte[],intptr&,int&)
[   1795562]   at (wrapper remoting-invoke-with-check) CitizenFX.Core.InternalManager.CallRef(int,byte[],intptr&,int&)
[   1795578]   at CitizenFX.Core.MonoScriptRuntime.CallRef (System.Int32 refIndex, System.Byte[] argsSerialized, System.Int32 argsSize, System.IntPtr& retvalSerialized, System.Int32& retvalSize) [0x00013] in /src/code/client/clrcore/MonoScriptRuntime.cs:151 

Try this, it converts the handle passed to server into Player where you can work with it as ‘source’ of your target. Also changing this to args.ToList().Count() will prevent the error you are getting when no arguments are passed.

            API.RegisterCommand("testargs", new Action<int, List<object>, string>((source, args, raw) =>
            {
                if (args.ToList().Count() > 0)
                {
                    string targetHandle = args[0].ToString();
                    Player player = Players.AsEnumerable().ToList().FirstOrDefault(k => k.Handle == targetHandle);

                    if (player == null)
                    {
                        Debug.WriteLine($"No player id detected");
                    }
                    else
                    {
                        Debug.WriteLine($"Targeting: {player.Name} with id {player.Handle}");
                    }
                }
                else
                {
                    Debug.WriteLine($"No id was provided");
                }
            }), false);

Alternatively you could use error catching around the code

            try
            {
                //Code
            }
            catch (Exception ex)
            {
                //Message or alternate code that wont throw an error
            }
1 Like

Thanks so much! hopefully i will be able to make this code work properly now.