From ea82c2537e64d4b75f85d9369e90cb55cfcadcc7 Mon Sep 17 00:00:00 2001 From: Still Hsu <341464@gmail.com> Date: Tue, 8 May 2018 16:30:48 +0800 Subject: [PATCH] Initial proofread of the articles --- docs/faq/basics/basic-operations.md | 8 +- docs/faq/basics/client-basics.md | 8 +- docs/faq/basics/getting-started.md | 28 +++---- docs/faq/commands/commands.md | 85 ++++++++++++---------- docs/faq/commands/samples/Remainder.cs | 2 +- docs/faq/misc/legacy.md | 4 +- docs/guides/commands/intro.md | 2 +- docs/guides/commands/post-execution.md | 36 ++++----- docs/guides/concepts/connections.md | 14 ++-- docs/guides/concepts/deployment.md | 4 +- docs/guides/concepts/entities.md | 2 +- docs/guides/concepts/events.md | 2 +- docs/guides/concepts/logging.md | 2 +- docs/guides/getting_started/terminology.md | 6 +- 14 files changed, 105 insertions(+), 98 deletions(-) diff --git a/docs/faq/basics/basic-operations.md b/docs/faq/basics/basic-operations.md index 518a7426d..aef28a683 100644 --- a/docs/faq/basics/basic-operations.md +++ b/docs/faq/basics/basic-operations.md @@ -8,7 +8,7 @@ title: Questions about Basic Operations ## How should I safely check a type? > [!WARNING] -> Direct casting (e.g. `(Type)type`) is **the least recommended** +> Direct casting (e.g., `(Type)type`) is **the least recommended** > way of casting, as it *can* throw an [InvalidCastException] > when the object isn't the desired type. > @@ -28,9 +28,9 @@ A good and safe casting example: ## How do I send a message? > [!TIP] -> The [GetChannel] method by default returns an [IChannel]. -> This means channels such as [IVoiceChannel], [ICategoryChannel] -> can be returned. This is why that you cannot send message +> The [GetChannel] method by default returns an [IChannel], allowing +> channel types such as [IVoiceChannel], [ICategoryChannel] +> to be returned; consequently, you cannot send a message > to channels like those. Any implementation of [IMessageChannel] has a [SendMessageAsync] diff --git a/docs/faq/basics/client-basics.md b/docs/faq/basics/client-basics.md index ad55c9722..48386206c 100644 --- a/docs/faq/basics/client-basics.md +++ b/docs/faq/basics/client-basics.md @@ -21,7 +21,7 @@ There are few possible reasons why this may occur. bot account created from the Discord Developer portal, you should be using `TokenType.Bot`. 2. You are not using the correct login credentials. Please keep in - mind that tokens is **different** from a *client secret*. + mind that a token is **different** from a *client secret*. [TokenType]: xref:Discord.TokenType [827]: https://github.com/RogueException/Discord.Net/issues/827 @@ -33,11 +33,11 @@ There are few possible reasons why this may occur. Your bot should **not** attempt to interact in any way with guilds/servers until the [Ready] event fires. When the bot connects, it first has to download guild information from -Discord in order for you to get access to any server +Discord for you to get access to any server information; the client is not ready at this point. Technically, the [GuildAvailable] event fires once the data for a -particular guild has downloaded; however, it's best to wait for all +particular guild has downloaded; however, it is best to wait for all guilds to be downloaded. Once all downloads are complete, the [Ready] event is triggered, then you can proceed to do whatever you like. @@ -46,7 +46,7 @@ event is triggered, then you can proceed to do whatever you like. ## How do I get a message's previous content when that message is edited? -If you need to do anything with messages (e.g. checking Reactions, +If you need to do anything with messages (e.g., checking Reactions, checking the content of edited/deleted messages), you must set the [MessageCacheSize] in your [DiscordSocketConfig] settings in order to use the cached message entity. Read more about it [here](xref:Guides.Concepts.Events#cacheable). diff --git a/docs/faq/basics/getting-started.md b/docs/faq/basics/getting-started.md index 08972ba2e..6e39aeed0 100644 --- a/docs/faq/basics/getting-started.md +++ b/docs/faq/basics/getting-started.md @@ -8,25 +8,27 @@ title: Beginner Questions / How to Get Started ## How do I add my bot to my server/guild? You can do so by using the [permission calculator] provided -by FiniteReality. -This tool allows you to set the permissions that the bot will be -added with, and invite the bot into your guild. With this method, -bots will also be assigned their own special roles that normal users -cannot use; this is what we call a `Managed` role, and this is a much -safer method of permission management than to create a role that any -users can be assigned to. - +by [FiniteReality]. +This tool allows you to set permissions that the bot will be assigned +with, and invite the bot into your guild. With this method, bots will +also be assigned a unique role that a regular user cannot use; this +is what we call a `Managed` role. Because you cannot assign this +role to any other users, it is much safer than creating a single +role which, intentionally or not, can be applied to other users +to escalate their privilege. + +[FiniteReality]: https://github.com/FiniteReality/permissions-calculator [permission calculator]: https://finitereality.github.io/permissions-calculator ## What is a token? A token is a credential used to log into an account. This information should be kept **private** and for your eyes only. Anyone with your -token can log into your account. This applies to both user and bot -accounts. That also means that you should never ever hardcode your -token or add it into source control, as your identity may be stolen -by scrape bots on the internet that scours through constantly to -obtain a token. +token can log into your account. This risk applies to both user +and bot accounts. That also means that you should **never** hardcode +your token or add it into source control, as your identity may be +stolen by scrape bots on the internet that scours through +constantly to obtain a token. ## What is a client/user/object ID? diff --git a/docs/faq/commands/commands.md b/docs/faq/commands/commands.md index 4811b02be..11c28f6ec 100644 --- a/docs/faq/commands/commands.md +++ b/docs/faq/commands/commands.md @@ -5,37 +5,35 @@ title: Questions about Commands # Command-related Questions -## How can I restrict some of my commands so only certain users can execute them? +## How can I restrict some of my commands so only specific users can execute them? Based on how you want to implement the restrictions, you can use the built-in [RequireUserPermission] precondition, which allows you to restrict the command based on the user's current permissions in the -guild or channel (*e.g. `GuildPermission.Administrator`, -`ChannelPermission.ManageMessages` etc.*). +guild or channel (*e.g., `GuildPermission.Administrator`, +`ChannelPermission.ManageMessages`*). If, however, you wish to restrict the commands based on the user's -role, you can either create your own custom precondition or use +role, you can either create your custom precondition or use Joe4evr's [Preconditions Addons] that provides a few custom preconditions that aren't provided in the stock library. -Its source can also be used as an example for creating your own +Its source can also be used as an example for creating your custom preconditions. [RequireUserPermission]: xref:Discord.Commands.RequireUserPermissionAttribute [Preconditions Addons]: https://github.com/Joe4evr/Discord.Addons/tree/master/src/Discord.Addons.Preconditions -## I'm getting an error about `Assembly#GetEntryAssembly`. +## I am getting an error about `Assembly.GetEntryAssembly`. -You may be confusing [CommandService#AddModulesAsync] with -[CommandService#AddModuleAsync]. The former is used to add modules -via the assembly, while the latter is used to add a single module. - -[CommandService#AddModulesAsync]: xref:Discord.Commands.CommandService.AddModulesAsync* -[CommandService#AddModuleAsync]: xref:Discord.Commands.CommandService.AddModuleAsync* +You may be confusing @Discord.Commands.CommandService.AddModulesAsync* +with @Discord.Commands.CommandService.AddModuleAsync*. The former +is used to add modules via the assembly, while the latter is used to +add a single module. ## What does [Remainder] do in the command signature? The [RemainderAttribute] leaves the string unparsed, meaning you -don't have to add quotes around the text for the text to be +do not have to add quotes around the text for the text to be recognized as a single object. Please note that if your method has multiple parameters, the remainder attribute can only be applied to the last parameter. @@ -47,13 +45,14 @@ the last parameter. ## What is a service? Why does my module not hold any data after execution? In Discord.Net, modules are created similarly to ASP.NET, meaning -that they have a transient nature. This means that they are spawned -every time when a request is received, and are killed from memory -when the execution finishes. This is why you cannot store persistent -data inside a module. To workaround this, consider using a service. - -Service is often used to hold data externally, so that they will -persist throughout execution. Think of it like a chest that holds +that they have a transient nature; modules are spawned whenever a +request is received, and are killed from memory when the execution +finishes. In other words, you cannot store persistent +data inside a module. Consider using a service if you wish to +workaround this. + +Service is often used to hold data externally so that they persist +throughout execution. Think of it like a chest that holds whatever you throw at it that won't be affected by anything unless you want it to. Note that you should also learn Microsoft's implementation of [Dependency Injection] \([video]) before proceeding, @@ -68,15 +67,23 @@ A brief example of service and dependency injection can be seen below. ## I have a long-running Task in my command, and Discord.Net keeps saying that a `MessageReceived` handler is blocking the gateway. What gives? -By default, all commands are executed on the same thread as the -gateway task, which is responsible for keeping the connection from -your client to Discord alive. When you execute a command, -this blocks the gateway from communicating for as long as the command -task is being executed. The library will warn you about any long -running event handler (in this case, the command handler) that -persists for **more than 3 seconds**. +By default, the library warns the user about any long-running event +handler that persists for **more than 3 seconds**. Any event +handlers that are run on the same thread as the gateway task, the task +in charge of keeping the connection alive, may block the processing of +heartbeat, and thus terminating the connection. + +In this case, the library detects that a `MessageReceived` +event handler is blocking the gateway thread. This warning is +typically associated with the command handler as it listens for that +particular event. If the command handler is blocking the thread, then +this **might** mean that you have a long-running command (in rare +cases, runtime errors can also cause blockage, usually associated +with Mono, which is not supported by this library). -To resolve this, the library has designed a flag called [RunMode]. +To prevent a long-running command from blocking the gateway +thread, a flag called [RunMode] is explicitly designed to resolve +this issue. There are 2 main `RunMode`s. @@ -84,7 +91,7 @@ There are 2 main `RunMode`s. 2. `RunMode.Async` You can set the `RunMode` either by specifying it individually via -the `CommandAttribute`, or by setting the global default with +the `CommandAttribute` or by setting the global default with the [DefaultRunMode] flag under `CommandServiceConfig`. # [CommandAttribute](#tab/cmdattrib) @@ -101,10 +108,9 @@ the [DefaultRunMode] flag under `CommandServiceConfig`. > [!IMPORTANT] > While specifying `RunMode.Async` allows the command to be spun off -> to a different thread instead of the gateway thread, -> keep in mind that there will be **potential consequences** -> by doing so. Before applying this flag, please -> consider whether it is necessary to do so. +> to a different thread, keep in mind that by doing so, there will be +> **potentially unwanted consequences**. Before applying this flag, +> please consider whether it is necessary to do so. > > Further details regarding `RunMode.Async` can be found below. @@ -115,16 +121,15 @@ the [DefaultRunMode] flag under `CommandServiceConfig`. ## How does `RunMode.Async` work, and why is Discord.Net *not* using it by default? `RunMode.Async` works by spawning a new `Task` with an unawaited -[Task.Run], essentially making `ExecuteAsyncInternalAsync`, the task -that is used to invoke the command task, to be finished on a -different thread. This means that [ExecuteAsync] will be forced to -return a successful [ExecuteResult] regardless of the actual -execution result. +[Task.Run], essentially making the task that is used to invoke the +command task to be finished on a different thread. This design means +that [ExecuteAsync] will be forced to return a successful +[ExecuteResult] regardless of the actual execution result. The following are the known caveats with `RunMode.Async`, -1. You can potentially introduce race condition. -2. Unnecessary overhead caused by [async state machine]. +1. You can potentially introduce a race condition. +2. Unnecessary overhead caused by the [async state machine]. 3. [ExecuteAsync] will immediately return [ExecuteResult] instead of other result types (this is particularly important for those who wish to utilize [RuntimeResult] in 2.0). diff --git a/docs/faq/commands/samples/Remainder.cs b/docs/faq/commands/samples/Remainder.cs index a28c782e0..337fb6e45 100644 --- a/docs/faq/commands/samples/Remainder.cs +++ b/docs/faq/commands/samples/Remainder.cs @@ -16,5 +16,5 @@ public Task EchoAsync(string text) => ReplyAsync(text); // Wrapping the message in quotes solves this. // This way, the system knows the entire message is to be parsed as a // single String. -// e.g. +// e.g., // !echo "Coffee Cake" \ No newline at end of file diff --git a/docs/faq/misc/legacy.md b/docs/faq/misc/legacy.md index ef4caa1cd..fec6ba24d 100644 --- a/docs/faq/misc/legacy.md +++ b/docs/faq/misc/legacy.md @@ -7,8 +7,8 @@ title: Questions about Legacy Versions ## X, Y, Z does not work! It doesn't return a valid value anymore -If you're currently using an older version in stable branch, please -upgrade to the latest pre-release version to ensure maximum +If you are currently using an older version of the stable branch, +please upgrade to the latest pre-release version to ensure maximum compatibility. Several features may be broken in older versions and will likely not be fixed in the version branch due to their breaking nature. diff --git a/docs/guides/commands/intro.md b/docs/guides/commands/intro.md index 8036ed09e..e2fad73e8 100644 --- a/docs/guides/commands/intro.md +++ b/docs/guides/commands/intro.md @@ -107,7 +107,7 @@ be found in @Guides.Commands.TypeReaders. #### Optional Parameters Parameters, by default, are always required. To make a parameter -optional, give it a default value (i.e. `int num = 0`). +optional, give it a default value (i.e., `int num = 0`). #### Parameters with Spaces diff --git a/docs/guides/commands/post-execution.md b/docs/guides/commands/post-execution.md index 5f19147cb..267f84b8f 100644 --- a/docs/guides/commands/post-execution.md +++ b/docs/guides/commands/post-execution.md @@ -6,18 +6,18 @@ title: Post-command Execution Handling # Preface When developing commands, you may want to consider building a -post-execution handling system so you can have a finer control +post-execution handling system so you can have finer control over commands. Discord.Net offers several post-execution workflows for you to work with. -If you recall, in the [Command Guide], we've shown the following +If you recall, in the [Command Guide], we have shown the following example for executing and handling commands, [!code[Command Handler](samples/command_handler.cs)] You may notice that after we perform [ExecuteAsync], we store the -result and print it to the chat. This is essentially the most -basic post-execution handling. +result and print it to the chat, essentially creating the most +fundamental form of a post-execution handler. With this in mind, we could start doing things like the following, @@ -25,8 +25,8 @@ With this in mind, we could start doing things like the following, However, this may not always be preferred, because you are creating your post-execution logic *with* the essential command -handler. This could lead to messy code and could potentially be a -violation of the SRP (Single Responsibility Principle). +handler. This design could lead to messy code and could potentially +be a violation of the SRP (Single Responsibility Principle). Another major issue is if your command is marked with `RunMode.Async`, [ExecuteAsync] will **always** return a successful @@ -37,8 +37,8 @@ about the impact in the [FAQ](xref:FAQ.Commands). Enter [CommandExecuted], an event that was introduced in Discord.Net 2.0. This event is raised whenever a command is -successfully executed **without any run-time exceptions** or **without -any parsing or precondition failure**. This means this event can be +successfully executed **without any run-time exceptions** or **any +parsing or precondition failure**. This means this event can be used to streamline your post-execution design, and the best thing about this event is that it is not prone to `RunMode.Async`'s [ExecuteAsync] drawbacks. @@ -52,7 +52,7 @@ next? We can take this further by using [RuntimeResult]. ### RuntimeResult -`RuntimeResult` was originally introduced in 1.0 to allow +`RuntimeResult` was initially introduced in 1.0 to allow developers to centralize their command result logic. In other words, it is a result type that is designed to be returned when the command has finished its execution. @@ -62,7 +62,7 @@ However, it wasn't widely adopted due to the aforementioned result-handler via the [CommandExecuted] event, we can start making use of this class. -The best way to make use of it is to create your own version of +The best way to make use of it is to create your version of `RuntimeResult`. You can achieve this by inheriting the `RuntimeResult` class. @@ -71,16 +71,16 @@ of `RuntimeResult`, [!code[Base Use](samples/customresult_base.cs)] -The sky's the limit from here. You can add any additional information -you'd like regarding the execution result. +The sky is the limit from here. You can add any additional information +you would like regarding the execution result. -For example, you may want to add your own result type or other +For example, you may want to add your result type or other helpful information regarding the execution, or something simple like static methods to help you create return types easily. [!code[Extended Use](samples/customresult_extended.cs)] -After you're done creating your own [RuntimeResult], you can +After you're done creating your [RuntimeResult], you can implement it in your command by marking the command return type to `Task`. @@ -100,12 +100,12 @@ And now we can check for it in our [CommandExecuted] handler: ## CommandService.Log Event We have so far covered the handling of various result types, but we -haven't talked about what to do if the command enters a catastrophic -failure (i.e. exceptions). To resolve this, we can make use of the +have not talked about what to do if the command enters a catastrophic +failure (i.e., exceptions). To resolve this, we can make use of the [CommandService.Log] event. -All exceptions thrown during a command execution will be caught and -be sent to the Log event under the [LogMessage.Exception] property +All exceptions thrown during a command execution are caught and sent +to the Log event under the [LogMessage.Exception] property as a [CommandException] type. The [CommandException] class allows us to access the exception thrown, as well as the context of the command. diff --git a/docs/guides/concepts/connections.md b/docs/guides/concepts/connections.md index 324b67566..99ea45756 100644 --- a/docs/guides/concepts/connections.md +++ b/docs/guides/concepts/connections.md @@ -11,14 +11,14 @@ stopped. To start a connection, invoke the `StartAsync` method on a client that supports a WebSocket connection; to end a connection, invoke the -`StopAsync` method. This will gracefully close any open WebSocket or +`StopAsync` method, which gracefully closes any open WebSocket or UdpSocket connections. Since the Start/Stop methods only signal to an underlying connection manager that a connection needs to be started, **they return before a -connection is actually made.** +connection is made.** -As a result, you will need to hook into one of the connection-state +As a result, you need to hook into one of the connection-state based events to have an accurate representation of when a client is ready for use. @@ -29,7 +29,7 @@ ready to be used. A separate event, `Ready`, is provided on [DiscordSocketClient], which is raised only when the client has finished guild stream or guild -sync, and has a complete guild cache. +sync and has a completed guild cache. [DiscordSocketClient]: xref:Discord.WebSocket.DiscordSocketClient @@ -41,8 +41,8 @@ sync, and has a complete guild cache. > [!TIP] > Avoid running long-running code on the gateway! If you deadlock the -> gateway (as explained in [events]), the connection manager will be -> unable to recover and reconnect. +> gateway (as explained in [events]), the connection manager will +> **NOT** be able to recover and reconnect. Assuming the client disconnected because of a fault on Discord's end, and not a deadlock on your end, we will always attempt to reconnect @@ -50,6 +50,6 @@ and resume a connection. Don't worry about trying to maintain your own connections, the connection manager is designed to be bulletproof and never fail - if -your client doesn't manage to reconnect, you've found a bug! +your client does not manage to reconnect, you have found a bug! [events]: xref:Guides.Concepts.Events diff --git a/docs/guides/concepts/deployment.md b/docs/guides/concepts/deployment.md index d26abee34..eea747817 100644 --- a/docs/guides/concepts/deployment.md +++ b/docs/guides/concepts/deployment.md @@ -68,7 +68,7 @@ for use on another machine without installing the dependencies first. This can be achieved by using the dotnet CLI too on the development machine: - `dotnet publish -c Release` +* `dotnet publish -c Release` Additionally, you may want to target a specific platform when publishing the application so you may use the application without @@ -80,7 +80,7 @@ For example, when targeting a Windows 10 machine, you may want to use the following to create the application in Windows executable format (.exe): - `dotnet publish -c Release -r win10-x64` +* `dotnet publish -c Release -r win10-x64` [.NET Core application deployment]: https://docs.microsoft.com/en-us/dotnet/core/deploying/ [Runtime ID]: https://docs.microsoft.com/en-us/dotnet/core/rid-catalog \ No newline at end of file diff --git a/docs/guides/concepts/entities.md b/docs/guides/concepts/entities.md index 7c66c7a57..7415f043a 100644 --- a/docs/guides/concepts/entities.md +++ b/docs/guides/concepts/entities.md @@ -56,7 +56,7 @@ DiscordSocketClient. > [FAQ](xref:FAQ.Basics.GetStarted) page. More detailed versions of entities can be pulled from the basic -entities, e.g. `SocketGuild.GetUser`, which returns a +entities, e.g., `SocketGuild.GetUser`, which returns a `SocketGuildUser`, or `SocketGuild.GetChannel`, which returns a `SocketGuildChannel`. Again, you may need to cast these objects to get a variant of the type that you need. diff --git a/docs/guides/concepts/events.md b/docs/guides/concepts/events.md index d8e586681..293b5dc72 100644 --- a/docs/guides/concepts/events.md +++ b/docs/guides/concepts/events.md @@ -74,7 +74,7 @@ object. [Cacheable]: xref:Discord.Cacheable`2 > [!NOTE] -> Many events relating to a Message entity (i.e. `MessageUpdated` and +> Many events relating to a Message entity (i.e., `MessageUpdated` and > `ReactionAdded`) rely on the client's message cache, which is > **not** enabled by default. Set the `MessageCacheSize` flag in > @Discord.WebSocket.DiscordSocketConfig to enable it. diff --git a/docs/guides/concepts/logging.md b/docs/guides/concepts/logging.md index dba78006f..b92d2bd53 100644 --- a/docs/guides/concepts/logging.md +++ b/docs/guides/concepts/logging.md @@ -16,7 +16,7 @@ section. > [!WARNING] > Due to the nature of Discord.Net's event system, all log event > handlers will be executed synchronously on the gateway thread. If your -> log output will be dumped to a Web API (e.g. Sentry), you are advised +> log output will be dumped to a Web API (e.g., Sentry), you are advised > to wrap your output in a `Task.Run` so the gateway thread does not > become blocked while waiting for logging data to be written. diff --git a/docs/guides/getting_started/terminology.md b/docs/guides/getting_started/terminology.md index a03dc8fbf..61a226dcf 100644 --- a/docs/guides/getting_started/terminology.md +++ b/docs/guides/getting_started/terminology.md @@ -28,13 +28,13 @@ addon will run on all platforms. `Discord.Net.Rest` provides a set of concrete classes to be used **strictly** with the REST portion of Discord's API. Entities in this -implementation are prefixed with `Rest` (e.g. `RestChannel`). +implementation are prefixed with `Rest` (e.g., `RestChannel`). `Discord.Net.Rpc` provides a set of concrete classes that are used with Discord's RPC API. Entities in this implementation are prefixed -with `Rpc` (e.g. `RpcChannel`). +with `Rpc` (e.g., `RpcChannel`). `Discord.Net.WebSocket` provides a set of concrete classes that are used primarily with Discord's WebSocket API or entities that are kept in cache. When developing bots, you will be using this implementation. -All entities are prefixed with `Socket` (e.g. `SocketChannel`). \ No newline at end of file +All entities are prefixed with `Socket` (e.g., `SocketChannel`). \ No newline at end of file