You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

general.md 6.3 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. ---
  2. uid: FAQ.Commands.General
  3. title: General Questions about chat Commands
  4. ---
  5. # Chat Command-related Questions
  6. In the following section, you will find commonly asked questions and
  7. answered regarding general command usage when using @Discord.Commands.
  8. ## How can I restrict some of my commands so only specific users can execute them?
  9. Based on how you want to implement the restrictions, you can use the
  10. built-in [RequireUserPermission] precondition, which allows you to
  11. restrict the command based on the user's current permissions in the
  12. guild or channel (*e.g., `GuildPermission.Administrator`,
  13. `ChannelPermission.ManageMessages`*).
  14. If, however, you wish to restrict the commands based on the user's
  15. role, you can either create your custom precondition or use
  16. Joe4evr's [Preconditions Addons] that provides a few custom
  17. preconditions that aren't provided in the stock library.
  18. Its source can also be used as an example for creating your
  19. custom preconditions.
  20. [RequireUserPermission]: xref:Discord.Commands.RequireUserPermissionAttribute
  21. [Preconditions Addons]: https://github.com/Joe4evr/Discord.Addons/tree/master/src/Discord.Addons.Preconditions
  22. ## Why am I getting an error about `Assembly.GetEntryAssembly`?
  23. You may be confusing @Discord.Commands.CommandService.AddModulesAsync*
  24. with @Discord.Commands.CommandService.AddModuleAsync*. The former
  25. is used to add modules via the assembly, while the latter is used to
  26. add a single module.
  27. ## What does [Remainder] do in the command signature?
  28. The [RemainderAttribute] leaves the string unparsed, meaning you
  29. do not have to add quotes around the text for the text to be
  30. recognized as a single object. Please note that if your method has
  31. multiple parameters, the remainder attribute can only be applied to
  32. the last parameter.
  33. [!code-csharp[Remainder](samples/Remainder.cs)]
  34. [RemainderAttribute]: xref:Discord.Commands.RemainderAttribute
  35. ## Discord.Net keeps saying that a `MessageReceived` handler is blocking the gateway, what should I do?
  36. By default, the library warns the user about any long-running event
  37. handler that persists for **more than 3 seconds**. Any event
  38. handlers that are run on the same thread as the gateway task, the task
  39. in charge of keeping the connection alive, may block the processing of
  40. heartbeat, and thus terminating the connection.
  41. In this case, the library detects that a `MessageReceived`
  42. event handler is blocking the gateway thread. This warning is
  43. typically associated with the command handler as it listens for that
  44. particular event. If the command handler is blocking the thread, then
  45. this **might** mean that you have a long-running command.
  46. > [!NOTE]
  47. > In rare cases, runtime errors can also cause blockage, usually
  48. > associated with Mono, which is not supported by this library.
  49. To prevent a long-running command from blocking the gateway
  50. thread, a flag called [RunMode] is explicitly designed to resolve
  51. this issue.
  52. There are 2 main `RunMode`s.
  53. 1. `RunMode.Sync`
  54. 2. `RunMode.Async`
  55. `Sync` is the default behavior and makes the command to be run on the
  56. same thread as the gateway one. `Async` will spin the task off to a
  57. different thread from the gateway one.
  58. > [!IMPORTANT]
  59. > While specifying `RunMode.Async` allows the command to be spun off
  60. > to a different thread, keep in mind that by doing so, there will be
  61. > **potentially unwanted consequences**. Before applying this flag,
  62. > please consider whether it is necessary to do so.
  63. >
  64. > Further details regarding `RunMode.Async` can be found below.
  65. You can set the `RunMode` either by specifying it individually via
  66. the `CommandAttribute` or by setting the global default with
  67. the [DefaultRunMode] flag under `CommandServiceConfig`.
  68. # [CommandAttribute](#tab/cmdattrib)
  69. [!code-csharp[Command Attribute](samples/runmode-cmdattrib.cs)]
  70. # [CommandServiceConfig](#tab/cmdconfig)
  71. [!code-csharp[Command Service Config](samples/runmode-cmdconfig.cs)]
  72. ***
  73. ***
  74. [RunMode]: xref:Discord.Commands.RunMode
  75. [CommandAttribute]: xref:Discord.Commands.CommandAttribute
  76. [DefaultRunMode]: xref:Discord.Commands.CommandServiceConfig.DefaultRunMode
  77. ## How does `RunMode.Async` work, and why is Discord.Net *not* using it by default?
  78. `RunMode.Async` works by spawning a new `Task` with an unawaited
  79. [Task.Run], essentially making the task that is used to invoke the
  80. command task to be finished on a different thread. This design means
  81. that [ExecuteAsync] will be forced to return a successful
  82. [ExecuteResult] regardless of the actual execution result.
  83. The following are the known caveats with `RunMode.Async`,
  84. 1. You can potentially introduce a race condition.
  85. 2. Unnecessary overhead caused by the [async state machine].
  86. 3. [ExecuteAsync] will immediately return [ExecuteResult] instead of
  87. other result types (this is particularly important for those who wish
  88. to utilize [RuntimeResult] in 2.0).
  89. 4. Exceptions are swallowed in the `ExecuteAsync` result.
  90. However, there are ways to remedy some of these.
  91. For #3, in Discord.Net 2.0, the library introduces a new event called
  92. [CommandService.CommandExecuted], which is raised whenever the command is executed.
  93. This event will be raised regardless of
  94. the `RunMode` type and will return the appropriate execution result
  95. and the associated @Discord.Commands.CommandInfo if applicable.
  96. For #4, exceptions are caught in [CommandService.Log] event under
  97. [LogMessage.Exception] as [CommandException] and in the
  98. [CommandService.CommandExecuted] event under the [IResult] as
  99. [ExecuteResult.Exception].
  100. [Task.Run]: https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.run
  101. [async state machine]: https://www.red-gate.com/simple-talk/dotnet/net-tools/c-async-what-is-it-and-how-does-it-work/
  102. [ExecuteAsync]: xref:Discord.Commands.CommandService.ExecuteAsync*
  103. [ExecuteResult]: xref:Discord.Commands.ExecuteResult
  104. [RuntimeResult]: xref:Discord.Commands.RuntimeResult
  105. [CommandService.CommandExecuted]: xref:Discord.Commands.CommandService.CommandExecuted
  106. [CommandService.Log]: xref:Discord.Commands.CommandService.Log
  107. [LogMessage.Exception]: xref:Discord.LogMessage.Exception*
  108. [ExecuteResult.Exception]: xref:Discord.Commands.ExecuteResult.Exception*
  109. [CommandException]: xref:Discord.Commands.CommandException
  110. [IResult]: xref:Discord.Commands.IResult