Browse Source

Update Documentation to be compatible with Beta2

this one took a while
tags/1.0-rc
Christopher F 8 years ago
parent
commit
77342903bb
17 changed files with 206 additions and 147 deletions
  1. +7
    -1
      docs/api/index.md
  2. +107
    -47
      docs/guides/commands.md
  3. +2
    -0
      docs/guides/intro.md
  4. +1
    -5
      docs/guides/samples.md
  5. +10
    -10
      docs/guides/samples/command_handler.cs
  6. +10
    -3
      docs/guides/samples/dependency_map_setup.cs
  7. +1
    -1
      docs/guides/samples/faq/avatar.cs
  8. +0
    -4
      docs/guides/samples/faq/guild_from_message.cs
  9. +1
    -1
      docs/guides/samples/faq/send_message.cs
  10. +5
    -5
      docs/guides/samples/groups.cs
  11. +14
    -15
      docs/guides/samples/module.cs
  12. +3
    -4
      docs/guides/samples/require_context.cs
  13. +9
    -7
      docs/guides/samples/require_owner.cs
  14. +2
    -3
      docs/guides/samples/require_permission.cs
  15. +1
    -1
      docs/guides/samples/typereader.cs
  16. +22
    -9
      docs/guides/terminology.md
  17. +11
    -31
      docs/migrating.md

+ 7
- 1
docs/api/index.md View File

@@ -3,4 +3,10 @@

This is where you will find documentation for all members and objects in Discord.Net

**TODO:** Think of something useful to put on this page.
__Commonly Used Entities__
@Discord.WebSocket
@Discord.WebSocket.DiscordSocketClient
@Discord.WebSocket.SocketGuildChannel
@Discord.WebSocket.SocketGuildUser
@Discord.WebSocket.SocketMessage
@Discord.WebSocket.SocketRole

+ 107
- 47
docs/guides/commands.md View File

@@ -1,37 +1,60 @@
# The Command Service

[Discord.Commands](xref:Discord.Commands) provides an Attribute-based Command Parser.
[Discord.Commands](xref:Discord.Commands) provides an Attribute-based
Command Parser.

### Setup

To use Commands, you must create a [Commands Service](xref:Discord.Commands.CommandService) and a Command Handler.
To use Commands, you must create a
[Commands Service](xref:Discord.Commands.CommandService)
and a Command Handler.

Included below is a very bare-bones Command Handler. You can extend your Command Handler as much as you like, however the below is the bare minimum.
Included below is a very bare-bones Command Handler. You can extend
your Command Handler as much as you like, however the below is the
bare minimum.

[!code-csharp[Barebones Command Handler](samples/command_handler.cs)]

## Commands

In 1.0, Commands are no longer implemented at runtime with a builder pattern.
While a builder pattern may be provided later, commands are created primarily with
attributes.
In 1.0, Commands are no longer implemented at runtime with a builder
pattern. While a builder pattern may be provided later, commands are
created primarily with attributes.

### Basic Structure

All commands belong to a Module. (See the below section for creating modules.)
All commands belong to a Module. (See the below section for creating
modules).

All commands in a module must be defined as an `Task`, with at least one argument,
being the @Discord.IUserMessage representing the context of the command.
All commands in a module must be defined as a `Task`.

To add parameters to your command, add additional arguments to the `Task` of the command.
You are _not_ required to accept all arguments as `String`, they will be automatically parsed
into the type you specify for the arument. See the Example Module for an example of command parameters.
To add parameters to your command, you simply need to add parameters
to the Task that represents the command. You are _not_ required to
accept all arguments as `String`, they will be automatically parsed
into the type you specify for the arument. See the Example Module
for an example of command parameters.

## Modules

Modules serve as a host for commands you create.
Modules are an organizational pattern that allow you to write your
commands in different classes, and have them automatically loaded.

To create a module, create a class that you will place commands in. Flag this class with the `[Module]` attribute. You may optionally pass in a string to the `Module` attribute to set a prefix for all of the commands inside the module.
Discord.Net's implementation of Modules is influenced heavily from
ASP.Net Core's Controller pattern. This means that the lifetime of a
module instance is only as long as the command being ran in it.

**Avoid using long-running code** in your modules whereever possible.
You should **not** be implementing very much logic into your modules;
outsource to a service for that.

If you are unfamiliar with Inversion of Control, it is recommended to
read the MSDN article on [IoC] and [Dependency Injection].

To create a module, create a class that inherits from
@Discord.Commands.ModuleBase.

[IoC]: https://msdn.microsoft.com/en-us/library/ff921087.aspx
[Dependency Injection]: https://msdn.microsoft.com/en-us/library/ff921152.aspx

### Example Module

@@ -39,68 +62,95 @@ To create a module, create a class that you will place commands in. Flag this cl

#### Loading Modules Automatically

The Command Service can automatically discover all classes in an Assembly that are flagged with the `Module` attribute, and load them.
The Command Service can automatically discover all classes in an
Assembly that inherit @Discord.Commands.ModuleBase, and load them.

To have a module opt-out of auto-loading, pass `autoload: false` in the Module attribute.
To have a module opt-out of auto-loading, pass `autoload: false` in
the Module attribute.

Invoke [CommandService.LoadAssembly](xref:Discord.Commands.CommandService#Discord_Commands_CommandService_LoadAssembly) to discover modules and install them.
Invoke [CommandService.AddModules] to discover modules and install them.

[CommandService.AddModules]: xref:Discord.Commands.CommandService#Discord_Commands_CommandService_AddModules

#### Loading Modules Manually

To manually load a module, invoke [CommandService.Load](xref:Discord.Commands.CommandService#Discord_Commands_CommandService_Load), and pass in an instance of your module.
To manually load a module, invoke [CommandService.AddModule],
by passing in the generic type of your module, and optionally
a dependency map.

### Module Constructors
[CommandService.AddModule]: xref:Discord.Commands.CommandService#Discord_Commands_CommandService_AddModule__1_Discord_Commands_IDependencyMap_

When automatically loading modules, you are limited in your constructor. Using a constructor that accepts _no arguments_, or a constructor that accepts a @Discord.Commands.CommandService will always work.
### Module Constructors

Alternatively, you can use an @Discord.Commands.IDependencyMap, as shown below.
Modules are constructed using Dependency Injection. Any parameters
that are placed in the constructor must be injected into an
@Discord.Commands.IDependencyMap. Alternatively, you may accept an
IDependencyMap as an argument and extract services yourself.

### Command Groups

Command groups function similarly to Modules, but they must be contained inside a module. Simply create a **public** class inside a module, and flag it with the @Discord.Commands.GroupAttribute
Command Groups allow you to create a module where commands are prefixed.
To create a group, create a new module and flag it with the
@Discord.Commands.GroupAttribute.

>![NOTE]
>Groups do not _need_ to be modules. Only classes with commands should
>inherit from ModuleBase. If you plan on using a group for strictly
>organizational purposes, there is no reason to make it a module.

[!code-csharp[Groups Sample](samples/groups.cs)]

## Dependency Injection

The Commands Service includes a very basic implementation of Dependency Injection that allows you to have completely custom constructors, within certain limitations.
The commands service is bundled with a very barebones Dependency
Injection service for your convienence. It is recommended that
you use DI when writing your modules.

### Setup

First, you need to create an @Discord.Commands.IDependencyMap . The library includes @Discord.Commands.DependencyMap to help with this, however you may create your own IDependencyMap if you wish.
First, you need to create an @Discord.Commands.IDependencyMap.
The library includes @Discord.Commands.DependencyMap to help with
this, however you may create your own IDependencyMap if you wish.

Next, add the dependencies your modules will use to the map.

Finally, pass the map into the `LoadAssembly` method. Your modules will automatically be loaded with this dependency map.
Finally, pass the map into the `LoadAssembly` method.
Your modules will automatically be loaded with this dependency map.

[!code-csharp[DependencyMap Setup](samples/dependency_map_setup.cs)]

### Usage in Modules

In the constructor of your module, any parameters will be filled in by the @Discord.Commands.IDependencyMap you pass into `LoadAssembly`.
In the constructor of your module, any parameters will be filled in by
the @Discord.Commands.IDependencyMap you pass into `LoadAssembly`.

>[!NOTE]
>If you accept `CommandService` or `IDependencyMap` as a parameter in your constructor, these parameters will be filled by the CommandService the module was loaded from, and the DependencyMap passed into it, respectively.
>If you accept `CommandService` or `IDependencyMap` as a parameter in
your constructor, these parameters will be filled by the
CommandService the module was loaded from, and the DependencyMap passed
into it, respectively.

[!code-csharp[DependencyMap in Modules](samples/dependency_module.cs)]

# Preconditions

Preconditions serve as a permissions system for your commands. Keep in mind, however, that they are
not limited to _just_ permissions, and can be as complex as you want them to be.
Preconditions serve as a permissions system for your commands. Keep in
mind, however, that they are not limited to _just_ permissions, and
can be as complex as you want them to be.

>[!NOTE]
>Preconditions can be applied to Modules, Groups, or Commands.

## Bundled Preconditions

@Discord.Commands ships with two built-in preconditions, @Discord.Commands.RequireContextAttribute
and @Discord.Commands.RequirePermissionAttribute.
@Discord.Commands ships with two built-in preconditions,
@Discord.Commands.RequireContextAttribute and
@Discord.Commands.RequirePermissionAttribute.

### RequireContext

@Discord.Commands.RequireContextAttribute is a precondition that requires your command to be
executed in the specified context.
@Discord.Commands.RequireContextAttribute is a precondition that
requires your command to be executed in the specified context.

You may require three different types of context:
* Guild
@@ -113,29 +163,34 @@ Since these are `Flags`, you may OR them together.

### RequirePermission

@Discord.Commands.RequirePermissionAttribute is a precondition that allows you to quickly
specfiy that a user must poesess a permission to execute a command.
@Discord.Commands.RequirePermissionAttribute is a precondition that
allows you to quickly specfiy that a user must poesess a permission
to execute a command.

You may require either a @Discord.GuildPermission or @Discord.ChannelPermission
You may require either a @Discord.GuildPermission or
@Discord.ChannelPermission

[!code-csharp[RequireContext](samples/require_permission.cs)]

## Custom Preconditions

To write your own preconditions, create a new class that inherits from @Discord.Commands.PreconditionAttribute
To write your own preconditions, create a new class that inherits from
@Discord.Commands.PreconditionAttribute

In order for your precondition to function, you will need to override `CheckPermissions`,
which is a `Task<PreconditionResult>`.
In order for your precondition to function, you will need to override
`CheckPermissions`, which is a `Task<PreconditionResult>`.
Your IDE should provide an option to fill this in for you.

Return `PreconditionResult.FromSuccess()` if the context met the required parameters, otherwise
return `PreconditionResult.FromError()`, optionally including an error message.
Return `PreconditionResult.FromSuccess()` if the context met the
required parameters, otherwise return `PreconditionResult.FromError()`,
optionally including an error message.

[!code-csharp[Custom Precondition](samples/require_owner.cs)]

# Type Readers

Type Readers allow you to parse different types of arguments in your commands.
Type Readers allow you to parse different types of arguments in
your commands.

By default, the following Types are supported arguments:

@@ -153,16 +208,20 @@ By default, the following Types are supported arguments:

### Creating a Type Readers

To create a TypeReader, create a new class that imports @Discord and @Discord.Commands . Ensure your class inherits from @Discord.Commands.TypeReader
To create a TypeReader, create a new class that imports @Discord and
@Discord.Commands. Ensure your class inherits from @Discord.Commands.TypeReader

Next, satisfy the `TypeReader` class by overriding `Task<TypeReaderResult> Read(IUserMessage context, string input)`.
Next, satisfy the `TypeReader` class by overriding `Task<TypeReaderResult> Read(CommandContext context, string input)`.

>[!NOTE]
>In many cases, Visual Studio can fill this in for you, using the "Implement Abstract Class" IntelliSense hint.
>In many cases, Visual Studio can fill this in for you, using the
>"Implement Abstract Class" IntelliSense hint.

Inside this task, add whatever logic you need to parse the input string.

Finally, return a `TypeReaderResult`. If you were able to successfully parse the input, return `TypeReaderResult.FromSuccess(parsedInput)`. Otherwise, return `TypeReaderResult.FromError`.
Finally, return a `TypeReaderResult`. If you were able to successfully
parse the input, return `TypeReaderResult.FromSuccess(parsedInput)`.
Otherwise, return `TypeReaderResult.FromError`.

#### Sample

@@ -170,4 +229,5 @@ Finally, return a `TypeReaderResult`. If you were able to successfully parse the

### Installing TypeReaders

TypeReaders are not automatically discovered by the Command Service, and must be explicitly added. To install a TypeReader, invoke [CommandService.AddTypeReader](xref:Discord.Commands.CommandService#Discord_Commands_CommandService_AddTypeReader__1_Discord_Commands_TypeReader_).
TypeReaders are not automatically discovered by the Command Service,
and must be explicitly added. To install a TypeReader, invoke [CommandService.AddTypeReader](xref:Discord.Commands.CommandService#Discord_Commands_CommandService_AddTypeReader__1_Discord_Commands_TypeReader_).

+ 2
- 0
docs/guides/intro.md View File

@@ -16,6 +16,8 @@ Bot accounts must be added to a server, you must use the [OAuth 2 Flow](https://

You can install Discord.Net 1.0 from our [MyGet Feed](https://www.myget.org/feed/Packages/discord-net).

**For most users writing bots, install only `Discord.Net.WebSocket`.**

You may add the MyGet feed to Visual Studio directly from `https://www.myget.org/F/discord-net/api/v3/index.json`.

You can also pull the latest source from [GitHub](https://github.com/RogueException/Discord.Net).


+ 1
- 5
docs/guides/samples.md View File

@@ -17,8 +17,4 @@ title: Samples

#### Sending a message to a channel

[!code-csharp[Message to Channel](samples/faq/send_message.cs)]

#### Retrieving an IGuild from an IUserMessage

[!code-csharp[Message to Guild](samples/faq/guild_from_message.cs)]
[!code-csharp[Message to Channel](samples/faq/send_message.cs)]

+ 10
- 10
docs/guides/samples/command_handler.cs View File

@@ -33,21 +33,21 @@ public class Program
// Discover all of the commands in this assembly and load them.
await commands.LoadAssembly(Assembly.GetEntryAssembly());
}
public async Task HandleCommand(IMessage paramMessage)
public async Task HandleCommand(SocketMessage messageParam)
{
// Cast paramMessage to an IUserMessage, return if the message was a System message.
var msg = paramMessage as IUserMessage;
if (msg == null) return;
// Internal integer, marks where the command begins
// Don't process the command if it was a System Message
var message = messageParam as SocketUserMessage;
if (message == null) return;
// Create a number to track where the prefix ends and the command begins
int argPos = 0;
// Get the current user (used for Mention parsing)
var currentUser = await client.GetCurrentUserAsync();
// Determine if the message is a command, based on if it starts with '!' or a mention prefix
if (msg.HasCharPrefix('!', ref argPos) || msg.HasMentionPrefix(currentUser, ref argPos))
if (message.HasCharPrefix('!', ref argPos) || message.HasMentionPrefix(client.CurrentUser, ref argPos))
{
// Execute the command. (result does not indicate a return value,
// Create a Command Context
var context = new CommandContext(client, message);
// Execute the command. (result does not indicate a return value,
// rather an object stating if the command executed succesfully)
var result = await _commands.Execute(msg, argPos);
var result = await _commands.Execute(context, argPos);
if (!result.IsSuccess)
await msg.Channel.SendMessageAsync(result.ErrorReason);
}


+ 10
- 3
docs/guides/samples/dependency_map_setup.cs View File

@@ -1,6 +1,7 @@
using Discord;
using Discord.Commands;
using Discord.WebSocket;
using foxboat.Services;

public class Commands
{
@@ -8,10 +9,16 @@ public class Commands
{
var commands = new CommandService();
var map = new DependencyMap();
map.Add<IDiscordClient>(client);
var self = await client.GetCurrentUserAsync();
map.Add<ISelfUser>(self);
map.Add(client);
map.Add(commands);
await commands.LoadAssembly(Assembly.GetCurrentAssembly(), map);
}
// In ConfigureServices, we will inject the Dependency Map with
// all of the services our client will use.
public Task ConfigureServices(IDependencyMap map)
{
map.Add(new NotificationService(map));
map.Add(new DatabaseService(map));
}
// ...
}

+ 1
- 1
docs/guides/samples/faq/avatar.cs View File

@@ -1,5 +1,5 @@
public async Task ChangeAvatar()
{
var fileStream = new FileStream("./newAvatar.png", FileMode.Open);
await (await _client.GetCurrentUserAsync()).ModifyAsync(x => x.Avatar = fileStream);
await _client.CurrentUser.ModifyAsync(x => x.Avatar = fileStream);
}

+ 0
- 4
docs/guides/samples/faq/guild_from_message.cs View File

@@ -1,4 +0,0 @@
public async Task MessageReceived(IMessage msg)
{
var guild = (msg.Channel as IGuildChannel)?.Guild;
}

+ 1
- 1
docs/guides/samples/faq/send_message.cs View File

@@ -1,6 +1,6 @@
public async Task SendMessageToChannel(ulong ChannelId)
{
var channel = await _client.GetChannelAsync(ChannelId) as IMessageChannel;
var channel = _client.GetChannel(ChannelId) as ISocketMessageChannel;
await channel?.SendMessageAsync("aaaaaaaaahhh!!!")
/* ^ This question mark is used to indicate that 'channel' may sometimes be null, and in cases that it is null, we will do nothing here. */
}

+ 5
- 5
docs/guides/samples/groups.cs View File

@@ -1,15 +1,15 @@
[Module("admin")]
public class AdminModule
[Group("admin")]
public class AdminModule : ModuleBase
{
[Group("mod")]
public class ModerationGroup
public class ModerationGroup : ModuleBase
{
// ~admin mod ban foxbot#0282
[Command("ban")]
public async Task Ban(IUserMessage msg, IGuildUser user) { }
public async Task Ban(IGuildUser user) { }
}

// ~admin clean 100
[Command("clean")]
public async Task Clean(IUserMessage msg, int count = 100) { }
public async Task Clean(int count = 100) { }
}

+ 14
- 15
docs/guides/samples/module.cs View File

@@ -1,29 +1,29 @@
using Discord;
using Discord.Commands;
using Discord.WebSocket;

// Create a module with no prefix
[Module]
public class Info
public class Info : ModuleBase
{
// ~say hello -> hello
[Command("say"), Summary("Echos a message.")]
public async Task Say(IUserMessage msg,
[Unparsed, Summary("The text to echo")] string echo)
public async Task Say([Unparsed, Summary("The text to echo")] string echo)
{
await msg.Channel.SendMessageAsync(echo);
// ReplyAsync is a method on ModuleBase
await ReplyAsync(echo);
}
}

// Create a module with the 'sample' prefix
[Module("sample")]
public class Sample
[Group("sample")]
public class Sample : ModuleBase
{
// ~sample square 20 ->
// ~sample square 20 -> 400
[Command("square"), Summary("Squares a number.")]
public async Task Square(IUserMessage msg,
[Summary("The number to square.")] int num)
public async Task Square([Summary("The number to square.")] int num)
{
await msg.Channel.SendMessageAsync($"{num}^2 = {Math.Pow(num, 2)}");
// We can also access the channel from the Command Context.
await Context.Channel.SendMessageAsync($"{num}^2 = {Math.Pow(num, 2)}");
}

// ~sample userinfo --> foxbot#0282
@@ -34,10 +34,9 @@ public class Sample
// ~sample whois 96642168176807936 --> Khionu#8708
[Command("userinfo"), Summary("Returns info about the current user, or the user parameter, if one passed.")]
[Alias("user", "whois")]
public async Task UserInfo(IUserMessage msg,
[Summary("The (optional) user to get info for")] IUser user = null)
public async Task UserInfo([Summary("The (optional) user to get info for")] IUser user = null)
{
var userInfo = user ?? await Program.Client.GetCurrentUserAsync();
await msg.Channel.SendMessageAsync($"{userInfo.Username}#{userInfo.Discriminator}");
var userInfo = user ?? Context.Client.CurrentUser;
await ReplyAsync($"{userInfo.Username}#{userInfo.Discriminator}");
}
}

+ 3
- 4
docs/guides/samples/require_context.cs View File

@@ -1,11 +1,10 @@
[Module]
public class InfoModule
public class InfoModule : ModuleBase
{
// Constrain this command to Guilds
[RequireContext(ContextType.Guild)]
public async Task Whois(IUserMessage msg, IGuildUser user) { }
public async Task Whois(IGuildUser user) { }

// Constrain this command to either Guilds or DMs
[RequireContext(ContextType.Guild | ContextType.DM)]
public async Task Info(IUserMessage msg) { }
public async Task Info() { }
}

+ 9
- 7
docs/guides/samples/require_owner.cs View File

@@ -1,16 +1,18 @@
// Defining the Precondition

// Specify that this precondition can target a Class (Module/Group) or Method (Command)
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
// Inherit from PreconditionAttribute
public class RequireOwnerAttribute : PreconditionAttribute
{
public readonly ulong OwnerId = 66078337084162048;

// Override the CheckPermissions method
public override Task<PreconditionResult> CheckPermissions(IUserMessage context, Command executingCommand, object moduleInstance)
public override Task<PreconditionResult> CheckPermissions(CommandContext context, CommandInfo command, IDependencyMap map)
{
// If the author of the message is '66078337084162048', return success; otherwise fail.
return Task.FromResult(context.Author.Id == OwnerId ? PreconditionResult.FromSuccess() : PreconditionResult.FromError("You must be the owner of the bot."));
// Get the ID of the bot's owner
var ownerId = (await map.Get<DiscordSocketClient>().GetApplicationInfoAsync()).Owner.Id;
// If this command was executed by that user, return a success
if (context.User.Id == ownerId)
return PreconditionResult.FromSuccess();
// Since it wasn't, fail
else
return PreconditionResult.FromError("You must be the owner of the bot to run this command.");
}
}

+ 2
- 3
docs/guides/samples/require_permission.cs View File

@@ -1,7 +1,6 @@
[Module]
public class AdminModule
public class AdminModule : ModuleBase
{
[Command("ban")]
[RequirePermission(GuildPermission.BanMembers)]
public async Task Ban(IUserMessage msg) { }
public async Task Ban(IGuildUser target) { }
}

+ 1
- 1
docs/guides/samples/typereader.cs View File

@@ -3,7 +3,7 @@ using Discord.Commands;

public class BooleanTypeReader : TypeReader
{
public override Task<TypeReaderResult> Read(IUserMessage context, string input)
public override Task<TypeReaderResult> Read(CommandContext context, string input)
{
bool result;
if (bool.TryParse(input, out result))


+ 22
- 9
docs/guides/terminology.md View File

@@ -9,17 +9,30 @@ title: Terminology

Most terms for objects remain the same between 0.9 and 1.0. The major difference is that the ``Server`` is now called ``Guild``, to stay in line with Discord internally

## Introduction to Interfaces
## Implementation Specific Entities

Discord.Net 1.0 is built strictly around Interfaces. There are no methods that return a concrete object, only an interface.
Discord.Net 1.0 is split into a core library, and three different
implementations - Discord.Net.Core, Discord.Net.Rest, Discord.Net.Rpc,
and Discord.Net.WebSockets.

Many of the interfaces in Discord.Net are linked through inheritance. For example, @Discord.IChannel represents any channel in Discord. @Discord.IGuildChannel inherits from IChannel, and represents all channels belonging to a Guild. As a result, @Discord.IChannel can sometimes be cast to @Discord.IGuildChannel, and you may find yourself doing this frequently in order to properly utilize the library.
As a bot developer, you will only need to use Discord.Net.WebSockets,
but you should be aware of the differences between them.

### The Inheritance Tree
`Discord.Net.Core` provides a set of interfaces that model Discord's
API. These interfaces are consistent throughout all implementations of
Discord.Net, and if you are writing an implementation-agnostic library
or addon, you can rely on the core interfaces to ensure that your
addon will run on all platforms.

You may want to familiarize yourself with the inheritance in Discord.Net. An inheritance tree is provided below.
`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`.

![](https://i.lithi.io/kpgd.png)
![](https://i.lithi.io/kNrr.png)
![](https://i.lithi.io/gs8d.png)
![](https://i.lithi.io/LAJr.png)
`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`.

`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`.

+ 11
- 31
docs/migrating.md View File

@@ -5,11 +5,6 @@ changes in the design of the library.**

>A medium to advanced understanding is recommended when working with this library.

One of the biggest major changes from `0.9.x` is the exclusive use of interfaces.
For the most part, your usability will be very similar to the 0.9 approach of concrete
classes. You **will** be required to cast some entities; this is outlined in a later
section.

It is recommended to familiarize yourself with the entities in 1.0 before continuing.
Feel free to look through the library's source directly, look through IntelliSense, or
look through our hosted [API Documentation](xref:Discord).
@@ -19,8 +14,7 @@ look through our hosted [API Documentation](xref:Discord).
Most API models function _similarly_ to 0.9, however their names have been changed.
You should also keep in mind that we now separate different types of Channels and Users.

Take a look at inheritance section of @Terminology for an example of how inheritance and interfaces
work in 1.0
Before proceeding, please read over @Terminology to understand the naming behind some objects.

Below is a table that compares most common 0.9 entities to their 1.0 counterparts.

@@ -29,18 +23,16 @@ Below is a table that compares most common 0.9 entities to their 1.0 counterpart

| 0.9 | 1.0 | Notice |
| --- | --- | ------ |
| Server | @Discord.IGuild |
| Channel | @Discord.IGuildChannel | Applies only to channels that are members of a Guild |
| Channel.IsPrivate | @Discord.IDMChannel
| ChannelType.Text | @Discord.ITextChannel | This applies only to Text Channels in Guilds
| ChannelType.Voice | @Discord.IVoiceChannel | This applies only to Voice Channels in Guilds
| User | @Discord.IGuildUser | This applies only to users belonging to a Guild*
| Profile | @Discord.ISelfUser
| Message | @Discord.IUserMessage

\* To retrieve an @Discord.IGuildUser, you must retrieve the user from an @Discord.IGuild.
[IDiscordClient.GetUserAsync](xref:Discord.IDiscordClient#Discord_IDiscordClient_GetUserAsync_System_UInt64_)
returns a @Discord.IUser, which only contains the information that Discord exposes for public users.
| Server | @Discord.WebSocket.SocketGuild |
| Channel | @Discord.WebSocket.SocketGuildChannel | Applies only to channels that are members of a Guild |
| Channel.IsPrivate | @Discord.WebSocket.SocketDMChannel
| ChannelType.Text | @Discord.WebSocket.SocketTextChannel | This applies only to Text Channels in Guilds
| ChannelType.Voice | @Discord.WebSocket.SocketVoiceChannel | This applies only to Voice Channels in Guilds
| User | @Discord.WebSocket.SocketGuildUser | This applies only to users belonging to a Guild*
| Profile | @Discord.WebSocket.SocketGuildUser
| Message | @Discord.WebSocket.SocketUserMessage

\* To retrieve an @Discord.WebSocket.SocketGuildUser, you must retrieve the user from an @Discord.WebSocket.SocketGuild.

## Event Registration

@@ -67,15 +59,3 @@ API docs before implementing it.
## Async

Nearly everything in 1.0 is an async Task. You should always await any tasks you invoke.

However, when using WebSockets, you may find this both inconvienent, and unnecessary, as many of the
WebSocket implementations of the interfaces keep their own local cache of objects, rendering the use
of async redundant.

**As of right now,** there are extension methods you can use, located in `Discord.WebSocket` that will
provide java-esque, synchronus `GetXXX` methods to replace the asynchronus methods on WebSocket entities.

This functionality may be changed at a later date, we are currently reviewing this implementation and
alternative methods.

For your reference, you may want to look through the extension classes located in @Discord.WebSocket

Loading…
Cancel
Save