Ejemplo n.º 1
0
        /// <summary>Try to execute the specified action input as a command.</summary>
        /// <param name="actionInput">The action input to try to execute.</param>
        private void TryExecuteAction(ActionInput actionInput)
        {
            try
            {
                ScriptingCommand command = CommandCreator.Instance.Create(actionInput);
                if (command == null)
                {
                    return;
                }

                // Verify the user has permissions to use this command.
                string guardsErrorMessage = CommandGuardHelpers.VerifyCommandPermission(command);
                if (guardsErrorMessage == null)
                {
                    guardsErrorMessage = (string)command.GuardsDelegate.DynamicInvoke(actionInput);
                }

                // Verify that the other command-specific guards are passed.
                if (guardsErrorMessage == null)
                {
                    // Execute the command if we passed all the guards.
                    command.ExecuteDelegate.DynamicInvoke(actionInput);
                }
                else
                {
                    // Otherwise display what went wrong to the user of the action.
                    IController controller = actionInput.Controller;
                    controller.Write(new OutputBuilder().AppendLine(guardsErrorMessage));
                }
            }
            catch (Exception ex)
            {
                // Most of our exceptions should be TargetInvocationExceptions but we're going to
                // handle them basically the same way as others, except that we only care about the
                // inner exception (what actually went wrong, since we know we're doing invokes here).
                if (ex is TargetInvocationException && ex.InnerException != null)
                {
                    ex = ex.InnerException;
                }

                // In order to isolate command-specific issues, we're going to trap the exception, log
                // the details, and kill that command.  (Other commands and the game itself should be
                // able to continue through such situations.)
                // Start gathering info, but carefully to avoid causing potential further exceptions here.
                IController controller = actionInput.Controller;
#if DEBUG
                Thing  thing     = controller != null ? controller.Thing : null;
                string thingName = thing != null ? thing.Name : "[null]";
                string thingID   = thing != null?thing.Id.ToString() : "[null]";

                string fullCommand = actionInput != null ? actionInput.FullText : "[null]";
                string format      = "Exception encountered for command: {1}{0}From thing: {2} (ID: {3}){0}{4}";
                string message     = string.Format(format, Environment.NewLine, fullCommand, thingName, thingID, ex.ToDeepString());
#endif

                // If the debugger is attached, we probably want to break now in order to better debug
                // the issue closer to where it occurred; if your debugger broke here you may want to
                // look at the stack trace to see where the exception originated.
                if (Debugger.IsAttached)
                {
                    string stackTrace = ex.StackTrace;
                    Debugger.Break();
                }

                // TODO: FIX: this.host..UpdateSubSystemHost(this, message);
                if (controller != null)
                {
#if DEBUG
                    controller.Write(new OutputBuilder().AppendLine(message));
#else
                    controller.Write(new OutputBuilder().AppendLine("An error occured processing your command."));
#endif
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>Try to execute the specified action input as a command.</summary>
        /// <param name="actionInput">The action input to try to execute.</param>
        private void TryExecuteAction(ActionInput actionInput)
        {
            Debug.Assert(actionInput != null, "actionInput must be defined.");
            try
            {
                ScriptingCommand command = CommandCreator.Instance.Create(actionInput);
                if (command == null)
                {
                    return;
                }

                // Verify the user has permissions to use this command.
                string guardsErrorMessage = CommandGuardHelpers.VerifyCommandPermission(command);
                if (guardsErrorMessage == null)
                {
                    guardsErrorMessage = (string)command.GuardsDelegate.DynamicInvoke(actionInput);
                }

                // Verify that the other command-specific guards are passed.
                if (guardsErrorMessage == null)
                {
                    // Execute the command if we passed all the guards.
                    command.ExecuteDelegate.DynamicInvoke(actionInput);
                }
                else
                {
                    // Otherwise display what went wrong to the issuing session of this action input.
                    // (If there is no such session, such as an AI issuing a malformed action, for now this is just ignored. TODO: Send this issue to server log?)
                    actionInput.Session?.WriteLine(guardsErrorMessage);
                }
            }
            catch (Exception ex)
            {
                // Most of our exceptions should be TargetInvocationExceptions but we're going to
                // handle them basically the same way as others, except that we only care about the
                // inner exception (what actually went wrong, since we know we're doing invokes here).
                if (ex is TargetInvocationException && ex.InnerException != null)
                {
                    ex = ex.InnerException;
                }

                // In order to isolate command-specific issues, we're going to trap the exception, log
                // the details, and kill that command.  (Other commands and the game itself should be
                // able to continue through such situations.)
                // Start gathering info, but carefully to avoid causing potential further exceptions here.
#if DEBUG
                // TODO: Improve action error output to always provide full details to server log and admin players.
                //       https://github.com/DavidRieman/WheelMUD/issues/136
                string thingName   = actionInput.Actor?.Name ?? "[null]";
                string thingID     = actionInput.Actor?.Id.ToString() ?? "[null]";
                string fullCommand = actionInput.FullText ?? "[null]";
                string format      = "Exception encountered for command: {1}{0}From thing: {2} (ID: {3}){0}{4}";
                string message     = string.Format(format, Environment.NewLine, fullCommand, thingName, thingID, ex.ToDeepString());
#else
                string message = "An error occurred while processing your command.";
#endif
                actionInput.Session?.WriteLine(message);

                // If the debugger is attached, we probably want to break now in order to better debug
                // the issue closer to where it occurred; if your debugger broke here you may want to
                // look at the stack trace to see where the exception originated.
                if (Debugger.IsAttached)
                {
                    string stackTrace = ex.StackTrace;
                    Debugger.Break();
                }
            }
        }