News A server update was released on July 20. Server patch notes and downloads are here. Additionally, a client update was released on the same day. Client patch notes are here.

EK.IceFlake

  • Hero Member
  • "We are the champions my fellahs" - Sufyan/VK.SuFy
  • Posts: 1,728
BindFail not getting called
«  »
I have this code
Code: [Select]
SqCmd.Manager().BindFail(this, function (type, msg)
{
    print("!Fail");
    switch (type)
    {
        case ECMDERR.UNKNOWN_COMMAND:
            Cmd.get_invoker().Message(MessageType.Error, "Unknown command.");
            break;
        case ECMDERR.EXECUTION_FAILED:
            Cmd.get_invoker().Message(MessageType.Error, "Internal: Execution failed.");
            break;
        default:
            Cmd.get_invoker().Message(MessageType.Error, "Unknown error.");
            break;
    }
});
However, when I type a command that doesn't exist (and there is no command yet, so no commands exist), it doesn't call the function, and consequently, neither prints '!Fail' nor shows the message (player.Message is overwritten with a custom function, which is the reason for the MessageType argument). What should I do in this case?

KAKAN

  • Wiki Contributor
  • Posts: 3,452
You can contact me at #SLC @ LUNet

EK.IceFlake

  • Hero Member
  • "We are the champions my fellahs" - Sufyan/VK.SuFy
  • Posts: 1,728

.

  • Moderator
  • Posts: 1,785
Re: BindFail not getting called
« Reply #3,  »Last edited
Wasn't necessary to have a signal here. I'll look into it and come back with a report.

EDIT:

First, you need to create a manager instance. This is the old design where you were limited to a global manager. On the new design, I've made it so you can create as many as you like. For example, I can create one for commands coming from IRC and another one for commands coming from the game.

And another one for messages interpreted as commands. I've seen people here sometimes prefixing chat messages with `!` and treating the message as a command.

In your code for example, you create the manager instance, bind an error handler but the manager get's destroyed immediately after that because is not stored anywhere. Which is why you don't receive any call or see any errors to the console. Because the code is correct but logic is not.

There's also a third parameter "payload" which may contain valuable information to the error.

For example:
Code: [Select]
/* ------------------------------------------------------------------------------------------------
 * The main game-related command manager.
*/
g_Cmd <- SqCmd.Manager();

/* ------------------------------------------------------------------------------------------------
 * Bind a function to handle command errors.
*/
g_Cmd.BindFail(getroottable(), function(type, msg, payload) {
    // Retrieve the entity that executed the command
    local invoker = g_Cmd.Invoker;
    // See if the invoker even exists
    if (!invoker || typeof(invoker) != "SqPlayer")
    {
        return; // No one to report!
    }
    // Identify the error type
    // Identify the error type
    switch (type)
    {
        // The command failed for unknown reasons
        case SqCmdErr.Unknown:
        {
            invoker.Message("Unable to execute the command for reasons unknown");
            invoker.Message("=> Please contact the owner: [email protected]");
        } break;
        // The command failed to execute because there was nothing to execute
        case SqCmdErr.EmptyCommand:
        {
            invoker.Message("Cannot execute an empty command");
        } break;
        // The command failed to execute because the command name was invalid after processing
        case SqCmdErr.InvalidCommand:
        {
            invoker.Message("The specified command name is invalid");
        } break;
        // The command failed to execute because there was a syntax error in the arguments
        case SqCmdErr.SyntaxError:
        {
            invoker.Message("There was a syntax error in one of the command arguments");
        } break;
        // The command failed to execute because there was no such command
        case SqCmdErr.UnknownCommand:
        {
            invoker.Message("The specified command does no exist");
        } break;
        // The command failed to execute because the it's currently suspended
        case SqCmdErr.ListenerSuspended:
        {
            invoker.Message("The requested command is currently suspended");
        } break;
        // The command failed to execute because the invoker does not have the proper authority
        case SqCmdErr.InsufficientAuth:
        {
            invoker.Message("You don't have the proper authority to execute this command");
        } break;
        // The command failed to execute because there was no callback to handle the execution
        case SqCmdErr.MissingExecuter:
        {
            invoker.Message("The specified command is not being processed");
        } break;
        // The command was unable to execute because the argument limit was not reached
        case SqCmdErr.IncompleteArgs:
        {
            invoker.Message("The specified command requires at least %d arguments", payload);
        } break;
        // The command was unable to execute because the argument limit was exceeded
        case SqCmdErr.ExtraneousArgs:
        {
            invoker.Message("The specified command can allows up to %d arguments", payload);
        } break;
        // Command was unable to execute due to argument type mismatch
        case SqCmdErr.UnsupportedArg:
        {
            invoker.Message("Argument %d requires a different type than the one you specified", payload);
        } break;
        // The command arguments contained more data than the internal buffer can handle
        case SqCmdErr.BufferOverflow:
        {
            invoker.Message("An internal error occurred and the execution was aborted");
            invoker.Message("=> Please contact the owner: [email protected]");
        } break;
        // The command failed to complete execution due to a runtime exception
        case SqCmdErr.ExecutionFailed:
        {
            invoker.Message("The command failed to complete the execution properly");
            invoker.Message("=> Please contact the owner: [email protected]");
        } break;
        // The command completed the execution but returned a negative result
        case SqCmdErr.ExecutionAborted:
        {
            invoker.Message("The command execution was aborted and therefore had no effect");
        } break;
        // The post execution callback failed to execute due to a runtime exception
        case SqCmdErr.PostProcessingFailed:
        {
            invoker.Message("The command post-processing stage failed to complete properly");
            invoker.Message("=> Please contact the owner: [email protected]");
        } break;
        // The callback that was supposed to deal with the failure also failed due to a runtime exception
        case SqCmdErr.UnresolvedFailure:
        {
            invoker.Message("Unable to resolve the failures during command execution");
            invoker.Message("=> Please contact the owner: [email protected]");
        } break;
        // Something bad happened and no one knows what
        default:
            SqLog.Inf("Command failed to execute because [%s]", msg);
    }
});

Also, you must tell the command manager what commands to run:
Code: [Select]
SqCore.On().PlayerCommand.Connect(function(player, text) {
    g_Cmd.Run(player, text);
});

The first parameter, the invoker, can be anything you want. You'll receive the same thing in the command.

NOTE: The code is from an old snippet of mine. Some error names might be different and some might not exist while new one's might have been added until now. This was just an example.
.