docs: Main docs update (#1304)

* Remove template in favor of official samples

* Fixed a variable name copy pasta mistake

line 35 was _database.GetData() instead of DBService.GetData()

* Experimental theme change

* Change paragraph, code, heading fonts
* Widen viewport

* Update DocFX.Plugins.LastModified v1.2.3

* Exclude Discord.API in docs

* Add remarks for SocketReaction properties

* Add examples for BaseSocketClient.Events

* Add additional clarification for some methods

* Move IUser and IGuildChannel examples

* Clarify several guides samples with notes

- Reword TypeReader comment to avoid giving the idea that the sample itself is "obsolete"
- Remove CommandException logging comment regarding C#7.0 as the version is now the standard across VS2017 and up
- Remove suggestion about handling result in command handler since it is now advised to use CommandExecuted instead
+ Add additional comment to clarify ctor for DI setup

* Add/migrate code examples

* Incorporate material design theme

License @ https://github.com/ovasquez

* Update installation and nightly guide

* Fix improper indentations made obvious by the widen viewport
* Fix minor grammar issues
+ Add installation for nightly build using dotnet CLI

* Fix nav level indentation

* Revise "Your First Bot" article

* Merge some paragraphs to avoid clutter while keeping readability
* Reword the use of command framework
+ Add additional warning/note about environment variable

* Add additional indent level

* Fix indentation text warping

* Remove connections sample

* Update logging sample

Remove redundant part of the sample

* Remove mention of RPC

* Remove misleading section about commands

- Remove command sample from complete snippet
* Revise "Your First Bot" command paragraphs
* Change wording to hint devs that additional command parser packages may be available, as more and more begin to crop up

* Update themes

* Add XML docs contribution guidelines


Update guidelines

* Update CommandExecuted remarks

* Fix precondition remarks typo
no one saw that ok

* Fix permission sample in docfx

* Fix IMessageChannel samples

* Update docs/_template/light-dark-theme/styles/docfx.vendor.minify.css

Co-Authored-By: Still34 <341464@gmail.com>

* Update docs/_template/light-dark-theme/styles/material.css

Co-Authored-By: Still34 <341464@gmail.com>

* Update docs/_template/light-dark-theme/styles/material.css

Co-Authored-By: Still34 <341464@gmail.com>
This commit is contained in:
Still Hsu
2019-05-14 06:29:47 +08:00
committed by Christopher F
parent 5ea3e113b8
commit 4309550ca0
64 changed files with 986 additions and 345 deletions

View File

@@ -1,23 +1,46 @@
# Contributing to Docs
First of all, thank you for your interest in contributing to our
documentation work. We really appreciate it! That being said,
there are several guidelines you should attempt to follow when adding
to/changing the documentation.
## General Guidelines
We do not have any strict conditions for writing documentation,
but keep these guidelines in mind:
* Keep code samples in the `guides/samples` folder
* Keep code samples in each section's `samples` folder
* When referencing an object in the API, link to its page in the
API documentation
* Documentation should be written in an FAQ/Wiki-style format
* Documentation should be written in clear and proper English*
\* If anyone is interested in translating documentation into other
languages, please open an issue or contact me on
Discord (`foxbot#0282`).
languages, please open an issue or contact `foxbot#0282` on
Discord.
## Style Consistencies
## XML Docstrings Guidelines
* Use a ruler set at 70 characters
* When using the `<summary>` tag, use concise verbs. For example:
```cs
/// <summary> Gets or sets the guild user in this object. </summary>
public IGuildUser GuildUser { get; set; }
```
* The `<summary>` tag should not be more than 3 lines long. Consider
simplifying the terms or using the `<remarks>` tag instead.
* When using the `<code>` tag, put the code sample within the
`src/Discord.Net.Examples` project under the corresponding path of
the object and surround the code with a `#region` tag.
* If the remarks you are looking to write are too long, consider
writing a shorter version in the XML docs while keeping the longer
version in the `overwrites` folder using the DocFX overwrites syntax.
* You may find an example of this in the samples provided within
the folder.
## Docs Guide Guidelines
* Use a ruler set at 70 characters (use the docs workspace provided
if you are using Visual Studio Code)
* Links should use long syntax
* Pages should be short and concise, not broad and long
@@ -31,5 +54,7 @@ Please consult the [API Documentation] for more information.
## Recommended Reads
* http://docs.microsoft.com
* http://flask.pocoo.org/docs/0.12/
* [Microsoft Docs](https://docs.microsoft.com)
* [Flask Docs](https://flask.pocoo.org/docs/1.0/)
* [DocFX Manual](https://dotnet.github.io/docfx/)
* [Sandcastle XML Guide](http://ewsoftware.github.io/XMLCommentsGuide)

View File

@@ -1,6 +1,6 @@
A "precondidtion" in the command system is used to determine if a
A "precondition" in the command system is used to determine if a
condition is met before entering the command task. Using a
precondidtion may aid in keeping a well-organized command logic.
precondition may aid in keeping a well-organized command logic.
The most common use case being whether a user has sufficient
permission to execute the command.

View File

@@ -1,4 +1,4 @@
<configuration>
<dllmap os="linux" cpu="x86-64" wordsize="64" dll="git2-8e0b172" target="lib/linux-x64/libgit2-8e0b172.so" />
<dllmap os="osx" cpu="x86,x86-64" dll="git2-8e0b172" target="lib/osx/libgit2-8e0b172.dylib" />
<dllmap os="linux" cpu="x86-64" wordsize="64" dll="git2-a904fc6" target="lib/linux-x64/libgit2-a904fc6.so" />
<dllmap os="osx" cpu="x86,x86-64" dll="git2-a904fc6" target="lib/osx/libgit2-a904fc6.dylib" />
</configuration>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 Oscar Vásquez
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -15,6 +15,7 @@
<link rel="stylesheet" href="{{_rel}}styles/docfx.css">
<link rel="stylesheet" href="{{_rel}}styles/master.css">
<link rel="stylesheet" href="{{_rel}}styles/main.css">
<link rel="stylesheet" href="{{_rel}}styles/material.css">
<link rel="stylesheet" href="{{_rel}}styles/theme-switcher.css">
<link href="https://cdn.rawgit.com/noelboss/featherlight/1.7.6/release/featherlight.min.css" type="text/css" rel="stylesheet" />
<meta name="theme-color" content="#99AAB5"/>

View File

@@ -7,6 +7,15 @@ body {
color: #C0C0C0;
}
h1,
h2,
h3,
h4,
h5,
h6 {
color: #E0E0E0;
}
button,
a {
color: #64B5F6;
@@ -258,6 +267,11 @@ tbody>tr {
border-top: 2px solid rgb(173, 173, 173)
}
/* top navbar */
.navbar-inverse[role="navigation"] {
background-color: #2C2F33;
}
/* select */
select {

View File

@@ -361,7 +361,6 @@ pre {
word-break: break-all;
word-wrap: break-word;
color: #333;
border: 1px solid #ccc;
border-radius: 4px;
}

View File

@@ -7,6 +7,15 @@ body {
color: #dddddd;
}
h1,
h2,
h3,
h4,
h5,
h6 {
color: #EEEEEE;
}
button,
a {
color: #64B5F6;
@@ -39,13 +48,13 @@ hr {
}
/* top navbar */
.navbar-inverse[role="navigation"] {
/*.navbar-inverse[role="navigation"] {
background-color: #2C2F33;
}
}*/
/* sub navbar (below top) */
.subnav {
background: #282B2F
background: rgb(69, 75, 82)
}

View File

@@ -1,14 +1,37 @@
@import url('https://fonts.googleapis.com/css?family=Titillium+Web|Noto+Sans');
@import url('https://fonts.googleapis.com/css?family=Roboto|Muli|Fira+Mono');
html,
body {
font-family: 'Titillium Web', 'Segoe UI', Tahoma, Helvetica, sans-serif;
font-family: 'Roboto', 'Segoe UI', Tahoma, Helvetica, sans-serif;
font-display: optional;
height: 100%;
font-size: 15px;
scroll-behavior: smooth;
}
code{
font-family: 'Fira Mono', 'Courier New', Courier, monospace
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Muli', Verdana, Geneva, Tahoma, sans-serif;
line-height: 130%;
}
h1,
.h1,
h2,
.h2,
h3,
.h3 {
font-weight: 600;
}
#logo
{
max-width: 100px;
@@ -25,6 +48,14 @@ li,
line-height: 160%;
}
.toc-filter{
background: inherit !important;
}
.affix ul>li.active>ul, .affix ul>li.active>a:before, .affix ul>li>a:hover:before{
white-space: normal;
}
img {
box-shadow: 0px 0px 3px 0px rgb(66, 66, 66);
max-width: 95% !important;
@@ -57,16 +88,6 @@ article.content h6{
transition: all .25s ease-in-out;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Noto Sans', Verdana, Geneva, Tahoma, sans-serif;
line-height: 130%;
}
.sideaffix {
line-height: 140%;
}
@@ -173,3 +194,38 @@ span.arrow-d{
span.arrow-r{
top: 6px; position: relative;
}
/* widen viewport */
@media (min-width: 1085px) {
.container {
width: calc(100% - 15vw);
max-width: calc(100% - 15vw);
}
}
/* fix level indentation */
.level2 {
padding: 0 5px;
}
.level3 {
padding: 0 5px;
font-size: 90%;
}
.level4 {
padding: 0 5px;
font-size: 85%;
}
.level5 {
padding: 0 5px;
font-size: 80%;
}
.level6 {
padding: 0 5px;
font-size: 75%;
}

View File

@@ -0,0 +1,199 @@
body {
color: #34393e;
line-height: 1.5;
/*font-size: 16px;*/
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
word-wrap: break-word
}
/* HEADINGS */
h1 {
font-weight: 600;
font-size: 32px;
}
h2 {
font-weight: 600;
font-size: 24px;
line-height: 1.8;
}
h3 {
font-weight: 600;
font-size: 20px;
line-height: 1.8;
}
h5 {
font-size: 14px;
padding: 10px 0px;
}
article h1,
article h2,
article h3,
article h4 {
margin-top: 35px;
margin-bottom: 15px;
}
article h4 {
padding-bottom: 8px;
border-bottom: 2px solid #ddd;
}
/* NAVBAR */
.navbar-brand>img {
color: #fff;
}
.navbar {
border: none;
/* Both navbars use box-shadow */
-webkit-box-shadow: 0px 1px 3px 0px rgba(100, 100, 100, 0.5);
-moz-box-shadow: 0px 1px 3px 0px rgba(100, 100, 100, 0.5);
box-shadow: 0px 1px 3px 0px rgba(100, 100, 100, 0.5);
}
.subnav {
border-top: 1px solid #ddd;
background-color: #fff;
}
.navbar-inverse {
background-color: #0d47a1;
z-index: 100;
}
.navbar-inverse .navbar-nav>li>a,
.navbar-inverse .navbar-text {
color: #fff;
/*background-color: #0d47a1;*/
border-bottom: 3px solid transparent;
padding-bottom: 12px;
}
.navbar-inverse .navbar-nav>li>a:focus,
.navbar-inverse .navbar-nav>li>a:hover {
color: #fff;
background-color: #1157c0;
border-bottom: 3px solid white;
}
.navbar-inverse .navbar-nav>.active>a,
.navbar-inverse .navbar-nav>.active>a:focus,
.navbar-inverse .navbar-nav>.active>a:hover {
color: #fff;
background-color: #1157c0;
border-bottom: 3px solid white;
}
.navbar-form .form-control {
border: none;
border-radius: 20px;
}
/* SIDEBAR */
/*.toc .level1>li {
font-weight: 400;
}*/
.toc .nav>li>a {
color: #34393e;
}
.sidefilter {
background-color: #fff;
border-left: none;
border-right: none;
}
.sidefilter {
background-color: #fff;
border-left: none;
border-right: none;
}
.toc-filter {
padding: 10px;
margin: 0;
}
.toc-filter>input {
border: 2px solid #ddd;
border-radius: 20px;
}
.toc-filter>.filter-icon {
display: none;
}
.sidetoc>.toc {
overflow-x: hidden;
}
.sidetoc {
border: none;
}
/* ALERTS */
.alert {
padding: 0px 0px 5px 0px;
color: inherit;
background-color: inherit;
border: none;
box-shadow: 0px 2px 2px 0px rgba(100, 100, 100, 0.4);
}
.alert>p {
margin-bottom: 0;
padding: 5px 10px;
}
.alert>ul {
margin-bottom: 0;
padding: 5px 40px;
}
.alert>h5 {
padding: 10px 15px;
margin-top: 0;
text-transform: uppercase;
font-weight: bold;
border-radius: 4px 4px 0 0;
}
.alert-info>h5 {
color: #1976d2;
border-bottom: 4px solid #1976d2;
background-color: #e3f2fd;
}
.alert-warning>h5 {
color: #f57f17;
border-bottom: 4px solid #f57f17;
background-color: #fff3e0;
}
.alert-danger>h5 {
color: #d32f2f;
border-bottom: 4px solid #d32f2f;
background-color: #ffebee;
}
/* CODE HIGHLIGHT */
pre {
padding: 9.5px;
margin: 10px 10px 10px;
font-size: 13px;
word-break: break-all;
word-wrap: break-word;
/*background-color: #fffaef;*/
border-radius: 4px;
box-shadow: 0px 1px 4px 1px rgba(100, 100, 100, 0.4);
}

View File

@@ -4,4 +4,7 @@ apiRules:
type: Namespace
- exclude:
uidRegex: ^Discord\.Analyzers$
type: Namespace
- exclude:
uidRegex: ^Discord\.API$
type: Namespace

View File

@@ -3,6 +3,9 @@ public class Initialize
private readonly CommandService _commands;
private readonly DiscordSocketClient _client;
// Ask if there are existing CommandService and DiscordSocketClient
// instance. If there are, we retrieve them and add them to the
// DI container; if not, we create our own.
public Initialize(CommandService commands = null, DiscordSocketClient client = null)
{
_commands = commands ?? new CommandService();

View File

@@ -32,6 +32,6 @@ public class DatabaseModule : ModuleBase<SocketCommandContext>
[Command("read")]
public async Task ReadFromDbAsync()
{
await ReplyAsync(_database.GetData());
await ReplyAsync(DbService.GetData());
}
}
}

View File

@@ -3,6 +3,7 @@ public class CommandHandler
private readonly DiscordSocketClient _client;
private readonly CommandService _commands;
// Retrieve client and CommandService instance via ctor
public CommandHandler(DiscordSocketClient client, CommandService commands)
{
_commands = commands;
@@ -46,19 +47,9 @@ public class CommandHandler
// Execute the command with the command context we just
// created, along with the service provider for precondition checks.
// Keep in mind that result does not indicate a return value
// rather an object stating if the command executed successfully.
var result = await _commands.ExecuteAsync(
await _commands.ExecuteAsync(
context: context,
argPos: argPos,
services: null);
// Optionally, we may inform the user if the command fails
// to be executed; however, this may not always be desired,
// as it may clog up the request queue should a user spam a
// command.
// if (!result.IsSuccess)
// await context.Channel.SendMessageAsync(result.ErrorReason);
}
}

View File

@@ -1,6 +1,5 @@
public async Task LogAsync(LogMessage logMessage)
{
// This casting type requries C#7
if (logMessage.Exception is CommandException cmdException)
{
// We can tell the user that something unexpected has happened

View File

@@ -1,5 +1,6 @@
// Note: This example is obsolete, a boolean type reader is bundled
// with Discord.Commands
// Please note that the library already supports type reading
// primitive types such as bool. This example is merely used
// to demonstrate how one could write a simple TypeReader.
using Discord;
using Discord.Commands;

View File

@@ -35,10 +35,6 @@ sync and has a completed guild cache.
[DiscordSocketClient]: xref:Discord.WebSocket.DiscordSocketClient
### Samples
[!code-csharp[Connection Sample](samples/events.cs)]
## Reconnection
> [!TIP]

View File

@@ -7,7 +7,7 @@ title: Entities
> [!NOTE]
> This article is written with the Socket variants of entities in mind,
> not the general interfaces or Rest/Rpc entities.
> not the general interfaces or Rest entities.
Discord.Net provides a versatile entity system for navigating the
Discord API.

View File

@@ -1,23 +0,0 @@
using Discord;
using Discord.WebSocket;
public class Program
{
private DiscordSocketClient _client;
static void Main(string[] args) => new Program().MainAsync().GetAwaiter().GetResult();
public async Task MainAsync()
{
_client = new DiscordSocketClient();
await _client.LoginAsync(TokenType.Bot, Environment.GetEnvironmentVariable("DiscordToken"));
await _client.StartAsync();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
await _client.StopAsync();
// Wait a little for the client to finish disconnecting before allowing the program to return
await Task.Delay(500);
}
}

View File

@@ -1,29 +1,24 @@
using Discord;
using Discord.WebSocket;
public class Program
public class LoggingService
{
private DiscordSocketClient _client;
static void Main(string[] args) => new Program().MainAsync().GetAwaiter().GetResult();
public async Task MainAsync()
public LoggingService(DiscordSocketClient client, CommandService command)
{
_client = new DiscordSocketClient(new DiscordSocketConfig
{
LogLevel = LogSeverity.Info
});
_client.Log += Log;
await _client.LoginAsync(TokenType.Bot, Environment.GetEnvironmentVariable("DiscordToken"));
await _client.StartAsync();
await Task.Delay(-1);
client.Log += LogAsync;
command.Log += LogAsync;
}
private Task Log(LogMessage message)
private Task LogAsync(LogMessage message)
{
Console.WriteLine(message.ToString());
if (message.Exception is CommandException cmdException)
{
Console.WriteLine($"[Command/{message.Severity}] {cmdException.Command.Aliases.First()}"
+ $" failed to execute in {cmdException.Context.Channel}.");
Console.WriteLine(cmdException);
}
else
Console.WriteLine($"[General/{message.Severity}] {message}");
return Task.CompletedTask;
}
}

View File

@@ -128,12 +128,10 @@ Finally, we can create a new connection to Discord.
Since we are writing a bot, we will be using a [DiscordSocketClient]
along with socket entities. See @Guides.GettingStarted.Terminology
if you are unsure of the differences.
To establish a new connection, we will create an instance of
[DiscordSocketClient] in the new async main. You may pass in an
optional @Discord.WebSocket.DiscordSocketConfig if necessary. For most
users, the default will work fine.
if you are unsure of the differences. To establish a new connection,
we will create an instance of [DiscordSocketClient] in the new async
main. You may pass in an optional @Discord.WebSocket.DiscordSocketConfig
if necessary. For most users, the default will work fine.
Before connecting, we should hook the client's `Log` event to the
log handler that we had just created. Events in Discord.Net work
@@ -142,22 +140,33 @@ similarly to any other events in C#.
Next, you will need to "log in to Discord" with the [LoginAsync]
method with the application's "token."
![Token](images/intro-token.png)
> [!NOTE]
> Pay attention to what you are copying from the developer portal!
> A token is not the same as the application's "client secret."
![Token](images/intro-token.png)
> [!IMPORTANT]
> Your bot's token can be used to gain total access to your bot, so
> **do __NOT__ share this token with anyone else!** It may behoove you
> to store this token in an external source if you plan on distributing
> **do not** share this token with anyone else! You should store this
> token in an external source if you plan on distributing
> the source code for your bot.
>
> In the following example, we retrieve the token from the environment
> variable `DiscordToken`. Please note that this is *not* designed to
> be used in a production environment, as the secrets are stored in
> plain-text.
>
> For information on how to set an environment variable, please see
> instructions below,
>
> * Windows: [How to Create Environment Variables Shortcut in Windows](https://www.tenforums.com/tutorials/121742-create-environment-variables-shortcut-windows.html)
> * Linux: [How To Read and Set Environmental and Shell Variables on a Linux VPS](https://www.digitalocean.com/community/tutorials/how-to-read-and-set-environmental-and-shell-variables-on-a-linux-vps)
> * macOS: [How do I set environment variables on OS X?](https://apple.stackexchange.com/questions/106778/how-do-i-set-environment-variables-on-os-x)
We may now invoke the client's [StartAsync] method, which will
start connection/reconnection logic. It is important to note that
**this method will return as soon as connection logic has been started!**
Any methods that rely on the client's state should go in an event
handler. This means that you should **not** directly be interacting with
the client before it is fully ready.
@@ -173,81 +182,34 @@ The following lines can now be added:
At this point, feel free to start your program and see your bot come
online in Discord.
> [!TIP]
> [!WARNING]
> Getting a warning about `A supplied token was invalid.` and/or
> having trouble logging in? Double-check whether you have put in
> the correct credentials and make sure that it is _not_ a client
> secret, which is different from a token.
> [!TIP]
> [!WARNING]
> Encountering a `PlatformNotSupportedException` when starting your bot?
> This means that you are targeting a platform where .NET's default
> WebSocket client is not supported. Refer to the [installation guide]
> for how to fix this.
> [!NOTE]
> For your reference, you may view the [completed program].
[DiscordSocketClient]: xref:Discord.WebSocket.DiscordSocketClient
[LoginAsync]: xref:Discord.Rest.BaseDiscordClient.LoginAsync*
[StartAsync]: xref:Discord.WebSocket.DiscordSocketClient.StartAsync*
[installation guide]: xref:Guides.GettingStarted.Installation
### Handling a 'ping'
> [!WARNING]
> Please note that this is *not* a proper way to create a command.
> Use the `CommandService` provided by the library instead, as explained
> in the [Command Guide](xref:Guides.Commands.Intro) section.
Now that we have learned to open a connection to Discord, we can
begin handling messages that the users are sending. To start out, our
bot will listen for any message whose content is equal to `!ping` and
will respond back with "Pong!".
Since we want to listen for new messages, the event to hook into
is [MessageReceived].
In your program, add a method that matches the signature of the
`MessageReceived` event - it must be a method (`Func`) that returns
the type `Task` and takes a single parameter, a [SocketMessage]. Also,
since we will be sending data to Discord in this method, we will flag
it as `async`.
In this method, we will add an `if` block to determine if the message
content fits the rules of our scenario - recall that it must be equal
to `!ping`.
Inside the branch of this condition, we will want to send a message,
`Pong!`, back to the channel from which the message comes from. To
find the channel, look for the `Channel` property on the message
parameter.
Next, we will want to send a message to this channel. Since the
channel object is of type [ISocketMessageChannel], we can invoke the
[SendMessageAsync] instance method. For the message content, send back
a string, "Pong!".
You should have now added the following lines,
[!code-csharp[Message](samples/first-bot/message.cs)]
Now that your first bot is complete. You may continue to add on to this
if you desire, but for any bots that will be carrying out multiple
commands, it is strongly recommended to use the command framework as
shown below.
> [!NOTE]
> For your reference, you may view the [completed program].
[MessageReceived]: xref:Discord.WebSocket.BaseSocketClient.MessageReceived
[SocketMessage]: xref:Discord.WebSocket.SocketMessage
[ISocketMessageChannel]: xref:Discord.WebSocket.ISocketMessageChannel
[SendMessageAsync]: xref:Discord.WebSocket.ISocketMessageChannel.SendMessageAsync*
[completed program]: samples/first-bot/complete.cs
# Building a bot with commands
@Guides.Commands.Intro will guide you through how to setup a program
that is ready for [CommandService], a service that is ready for
advanced command usage.
To create commands for your bot, you may choose from a variety of
command processors available. Throughout the guides, we will be using
the one that Discord.Net ships with. @Guides.Commands.Intro will
guide you through how to setup a program that is ready for
[CommandService].
For reference, view an [annotated example] of this structure.

View File

@@ -42,37 +42,45 @@ published to our [MyGet feed]. See
### [Using Visual Studio](#tab/vs-install)
1. Create a new solution for your bot.
1. Create a new solution for your bot
2. In the Solution Explorer, find the "Dependencies" element under your
bot's project.
3. Right click on "Dependencies", and select "Manage NuGet packages."
![Step 3](images/install-vs-deps.png)
4. In the "Browse" tab, search for `Discord.Net`.
5. Install the `Discord.Net` package.
![Step 5](images/install-vs-nuget.png)
bot's project
3. Right click on "Dependencies", and select "Manage NuGet packages"
![Step 3](images/install-vs-deps.png)
4. In the "Browse" tab, search for `Discord.Net`
5. Install the `Discord.Net` package
![Step 5](images/install-vs-nuget.png)
### [Using JetBrains Rider](#tab/rider-install)
1. Create a new solution for your bot.
2. Open the NuGet window (Tools > NuGet > Manage NuGet packages for
Solution).
![Step 2](images/install-rider-nuget-manager.png)
3. In the "Packages" tab, search for `Discord.Net`.
![Step 3](images/install-rider-search.png)
4. Install by adding the package to your project.
![Step 4](images/install-rider-add.png)
1. Create a new solution for your bot
2. Open the NuGet window (Tools > NuGet > Manage NuGet packages for Solution)
![Step 2](images/install-rider-nuget-manager.png)
3. In the "Packages" tab, search for `Discord.Net`
![Step 3](images/install-rider-search.png)
4. Install by adding the package to your project
![Step 4](images/install-rider-add.png)
### [Using Visual Studio Code](#tab/vs-code)
1. Create a new project for your bot.
2. Add `Discord.Net` to your .csproj.
1. Create a new project for your bot
2. Add `Discord.Net` to your `*.csproj`
[!code[Sample .csproj](samples/project.xml)]
### [Using dotnet CLI](#tab/dotnet-cli)
1. Open command-line and navigate to where your .csproj is located.
2. Enter `dotnet add package Discord.Net`.
1. Launch your terminal
2. Navigate to where your `*.csproj` is located
3. Enter `dotnet add package Discord.Net`
***
@@ -115,16 +123,16 @@ by installing one or more custom packages as listed below.
1. Install or compile the following packages:
* `Discord.Net.Providers.WS4Net`
* `Discord.Net.Providers.UDPClient` (Optional)
* This is _only_ required if your bot will be utilizing voice chat.
* `Discord.Net.Providers.WS4Net`
* `Discord.Net.Providers.UDPClient` (Optional)
* This is _only_ required if your bot will be utilizing voice chat.
2. Configure your [DiscordSocketClient] to use these custom providers
over the default ones.
* To do this, set the `WebSocketProvider` and the optional
`UdpSocketProvider` properties on the [DiscordSocketConfig] that you
are passing into your client.
* To do this, set the `WebSocketProvider` and the optional
`UdpSocketProvider` properties on the [DiscordSocketConfig] that you
are passing into your client.
[!code-csharp[Example](samples/netstd11.cs)]

View File

@@ -31,22 +31,33 @@ The following is the feed link of Discord.Net,
Depending on which IDE you use, there are many different ways of
adding the feed to your package source.
### [Visual Studio](#tab/vs)
### [Using Visual Studio](#tab/vs)
1. Go to `Tools` > `NuGet Package Manager` > `Package Manager Settings`
![VS](images/nightlies-vs-step1.png)
2. Go to `Package Sources`
![Package Sources](images/nightlies-vs-step2.png)
3. Click on the add icon
4. Fill in the desired name and source as shown below and hit `Update`
![Add Source](images/nightlies-vs-step4.png)
> [!NOTE]
> Remember to tick the `Include prerelease` checkbox to see the
> Remember to tick the `Include pre-release` checkbox to see the
> nightly builds!
> ![Checkbox](images/nightlies-vs-note.png)
### [Local NuGet.Config](#tab/local-nuget-config)
### [Using dotnet CLI](#tab/cli)
1. Launch your terminal
2. Navigate to where your `*.csproj` is located
3. Type `dotnet add package Discord.Net --source https://www.myget.org/F/discord-net/api/v3/index.json`
### [Using Local NuGet.Config](#tab/local-nuget-config)
If you plan on deploying your bot or developing outside of Visual
Studio, you will need to create a local NuGet configuration file for

View File

@@ -9,7 +9,6 @@ public class Program
{
_client = new DiscordSocketClient();
_client.Log += Log;
_client.MessageReceived += MessageReceivedAsync;
await _client.LoginAsync(TokenType.Bot,
Environment.GetEnvironmentVariable("DiscordToken"));
await _client.StartAsync();
@@ -17,15 +16,6 @@ public class Program
// Block this task until the program is closed.
await Task.Delay(-1);
}
private async Task MessageReceivedAsync(SocketMessage message)
{
if (message.Content == "!ping")
{
await message.Channel.SendMessageAsync("Pong!");
}
}
private Task Log(LogMessage msg)
{
Console.WriteLine(msg.ToString());

View File

@@ -16,17 +16,14 @@ understand these topics to some extent before proceeding. With all
that being said, feel free to visit us on Discord at the link below
if you have any questions!
Here are some examples:
1. [Official samples]
2. [Official template]
An official collection of samples can be found
in [our GitHub repository].
> [!NOTE]
> Please note that you should *not* try to blindly copy paste
> the code. The examples are meant to be a template or a guide.
[Official template]: https://github.com/foxbot/DiscordBotBase/tree/csharp/src/DiscordBot
[Official samples]: https://github.com/RogueException/Discord.Net/tree/dev/samples
[our GitHub repository]: https://github.com/RogueException/Discord.Net/tree/dev/samples
[Task-based Asynchronous Pattern]: https://docs.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap
[polymorphism]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/polymorphism
[interface]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/interfaces/