Adding Entity guides, flowcharts, better sample system. (#2054)
* initial * Interaction glossary entry * Sharded Interaction sample * Renames into solution * Debugging samples * Modify target location for webhookclient * Finalizing docs work, resolving docfx errors. * Adding threaduser to user chart * Add branch info to readme. * Edits to user chart * Resolve format for glossary entries * Patch sln target * Issue with file naming fixed * Patch 1/x for builds * Appending suggestions
This commit is contained in:
@@ -53,7 +53,7 @@ able to message.
|
||||
You may check the message channel type. Visit [Glossary] to see the
|
||||
various types of channels.
|
||||
|
||||
[glossary]: xref:FAQ.Glossary#message-channels
|
||||
[Glossary]: xref:Guides.Entities.Glossary#channels
|
||||
|
||||
## How can I get the guild from a message?
|
||||
|
||||
|
||||
@@ -24,6 +24,6 @@ Visit the repo's [release tag] to see the latest public pre-release.
|
||||
|
||||
The `DependencyMap` has been replaced with Microsoft's
|
||||
[DependencyInjection] Abstractions. An example usage can be seen
|
||||
[here](https://github.com/foxbot/DiscordBotBase/blob/csharp/src/DiscordBot/Program.cs#L36).
|
||||
[here](https://github.com/Discord-Net-Labs/Discord.Net-Labs/blob/release/3.x/samples/InteractionFramework/Program.cs#L66).
|
||||
|
||||
[DependencyInjection]: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection
|
||||
|
||||
@@ -16,7 +16,5 @@
|
||||
topicUid: FAQ.Commands.Interactions
|
||||
- name: Dependency Injection
|
||||
topicUid: FAQ.Commands.DI
|
||||
- name: Glossary
|
||||
topicUid: FAQ.Glossary
|
||||
- name: Legacy or Upgrade
|
||||
topicUid: FAQ.Legacy
|
||||
|
||||
68
docs/guides/entities/casting.md
Normal file
68
docs/guides/entities/casting.md
Normal file
@@ -0,0 +1,68 @@
|
||||
---
|
||||
uid: Guides.Entities.Casting
|
||||
title: Casting & Unboxing
|
||||
---
|
||||
|
||||
# Casting
|
||||
|
||||
Casting can be done in many ways, and is the only method to box and unbox types to/from their base definition.
|
||||
Casting only works for types that inherit the base type that you want to unbox from.
|
||||
`IUser` cannot be cast to `IMessage`.
|
||||
|
||||
> [!NOTE]
|
||||
> Interfaces **can** be cast to other interfaces, as long as they inherit each other.
|
||||
> The same goes for reverse casting. As long as some entity can be simplified into what it inherits, your cast will pass.
|
||||
|
||||
## Boxing
|
||||
|
||||
A boxed object is the definition of an object that was simplified (or trimmed) by incoming traffic,
|
||||
but still owns the data of the originally constructed type. Boxing is an implicit operation.
|
||||
|
||||
Through casting, we can **unbox** this type, and access the properties that were unaccessible before.
|
||||
|
||||
## Unboxing
|
||||
|
||||
Unboxing is the most direct way to access the real definition of an object.
|
||||
If we want to return a type from its interface, we can unbox it directly.
|
||||
|
||||
[!code-csharp[Unboxing](samples/unboxing.cs)]
|
||||
|
||||
## Regular casting
|
||||
|
||||
In 'regular' casting, we use the `as` keyword to assign the given type to the object.
|
||||
If the boxed type can indeed be cast into given type,
|
||||
it will become said type, and its properties can be accessed.
|
||||
[!code-csharp[Casting](samples/casting.cs)]
|
||||
|
||||
> [!WARNING]
|
||||
> If the type you're casting to is null, a `NullReferenceException` will be thrown when it's called.
|
||||
> This makes safety casting much more interesting to use, as it prevents this exception from being thrown.
|
||||
|
||||
## Safety casting
|
||||
|
||||
Safety casting makes sure that the type you're trying to cast to can never be null, as it passes checks upon calling them.
|
||||
|
||||
There are 3 different ways to safety cast an object:
|
||||
|
||||
### Basic safety casting:
|
||||
|
||||
To safety cast an object, all we need to do is check if it is of the member type in a statement.
|
||||
If this check fails, it will continue below, making sure we don't try to access null.
|
||||
[!code-csharp[Base](samples/safety-cast.cs)]
|
||||
|
||||
### Object declaration:
|
||||
|
||||
Here we declare the object we are casting to,
|
||||
making it so that you can immediately work with its properties without reassigning through regular casting.
|
||||
[!code-csharp[Declare](samples/safety-cast-var.cs)]
|
||||
|
||||
### Reverse passage:
|
||||
|
||||
In previous examples, we want to let code continue running after the check, or if the check fails.
|
||||
In this example, the cast will return the entire method (ignoring the latter) upon failure,
|
||||
and declare the variable for further use into the method:
|
||||
[!code-csharp[Pass](samples/safety-cast-pass.cs)]
|
||||
|
||||
> [!NOTE]
|
||||
> Usage of `is`, `not` and `as` is required in cast assignment and/or type checks. `==`, `!=` and `=` are invalid assignment,
|
||||
> as these operators only apply to initialized objects and not their types.
|
||||
@@ -1,29 +1,19 @@
|
||||
---
|
||||
uid: FAQ.Glossary
|
||||
title: Common Terminologies / Glossary
|
||||
uid: Guides.Entities.Glossary
|
||||
title: Glossary & Flowcharts
|
||||
---
|
||||
|
||||
# Glossary
|
||||
# Entity Types
|
||||
|
||||
This is an additional chapter for quick references to various common
|
||||
types that you may see within Discord.Net. To see more information
|
||||
regarding each type of object, click on the object to navigate
|
||||
to our API documentation page where you might find more explanation
|
||||
about it.
|
||||
A list of all Discord.Net entities, what they can be cast to and what their properties are.
|
||||
|
||||
## Common Types
|
||||
> [!NOTE]
|
||||
> All interfaces have the same inheritance tree for both `Socket` and `Rest` entities.
|
||||
> Entities with that have been marked red are exclusive to the project they source from.
|
||||
|
||||
* A **Guild** ([IGuild]) is an isolated collection of users and
|
||||
channels, and are often referred to as "servers".
|
||||
- Example: [Discord API](https://discord.gg/jkrBmQR)
|
||||
* A **Channel** ([IChannel]) represents a generic channel.
|
||||
- Example: #dotnet_discord-net
|
||||
- See [Channel Types](#channel-types)
|
||||
## Channels
|
||||
|
||||
[IGuild]: xref:Discord.IGuild
|
||||
[IChannel]: xref:Discord.IChannel
|
||||
|
||||
## Channel Types
|
||||

|
||||
|
||||
### Message Channels
|
||||
* A **Text Channel** ([ITextChannel]) is a message channel from a Guild.
|
||||
@@ -40,14 +30,11 @@ channels, and are often referred to as "servers".
|
||||
- This can be any channels that may exist in a guild.
|
||||
* A **Voice Channel** ([IVoiceChannel]) is a voice channel in a guild.
|
||||
* A **Stage Channel** ([IStageChannel]) is a stage channel in a guild.
|
||||
* A **Category Channel** ([ICategoryChannel]) (2.0+) is a category that
|
||||
* A **Category Channel** ([ICategoryChannel]) is a category that
|
||||
holds one or more sub-channels.
|
||||
* A **Nested Channel** ([INestedChannel]) (2.0+) is a channel that can
|
||||
* A **Nested Channel** ([INestedChannel]) is a channel that can
|
||||
exist under a category.
|
||||
|
||||
> [!NOTE]
|
||||
> A Channel ([IChannel]) can be all types of channels.
|
||||
|
||||
[INestedChannel]: xref:Discord.INestedChannel
|
||||
[IGuildChannel]: xref:Discord.IGuildChannel
|
||||
[IMessageChannel]: xref:Discord.IMessageChannel
|
||||
@@ -62,17 +49,27 @@ exist under a category.
|
||||
[IStageChannel]: xref:Discord.IStageChannel
|
||||
[INewsChannel]: xref:Discord.INewsChannel
|
||||
|
||||
## Message Types
|
||||
## Messages
|
||||
|
||||

|
||||
|
||||
* A **Rest Followup Message** ([RestFollowupMessage]) is a message returned by followup on on an interaction.
|
||||
* A **Rest Interaction Message** ([RestInteractionMessage]) is a message returned by the interaction's original response.
|
||||
* A **Rest User Message** ([RestUserMessage]) is a message sent over rest; it can be any of the above.
|
||||
* An **User Message** ([IUserMessage]) is a message sent by a user.
|
||||
* A **System Message** ([ISystemMessage]) is a message sent by Discord itself.
|
||||
* A **Message** ([IMessage]) can be any of the above.
|
||||
|
||||
[RestFollowupMessage]: xref:Discord.Rest.RestFollowupMessage
|
||||
[RestInteractionMessage]: xref:Discord.Rest.RestInteractionMessage
|
||||
[RestUserMEssage]: xref:Discord.Rest.RestUserMessage
|
||||
[IUserMessage]: xref:Discord.IUserMessage
|
||||
[ISystemMessage]: xref:Discord.ISystemMessage
|
||||
[IMessage]: xref:Discord.IMessage
|
||||
|
||||
## User Types
|
||||
## Users
|
||||
|
||||

|
||||
|
||||
* A **Guild User** ([IGuildUser]) is a user available inside a guild.
|
||||
* A **Group User** ([IGroupUser]) is a user available inside a group.
|
||||
@@ -85,7 +82,29 @@ exist under a category.
|
||||
[ISelfUser]: xref:Discord.ISelfUser
|
||||
[IUser]: xref:Discord.IUser
|
||||
|
||||
## Emoji Types
|
||||
## Interactions
|
||||
|
||||

|
||||
|
||||
* A **Slash command** ([ISlashCommandInteraction]) is an application command executed in the text box, with provided parameters.
|
||||
* A **Message Command** ([IMessageCommandInteraction]) is an application command targetting a message.
|
||||
* An **User Command** ([IUserCommandInteraction]) is an application command targetting a user.
|
||||
* An **Application Command** ([IApplicationCommandInteraction]) is any of the above.
|
||||
* A **Message component** ([IMessageComponent]) is the interaction of a button being clicked/dropdown option(s) entered.
|
||||
* An **Autocomplete Interaction** ([IAutocompleteinteraction]) is an interaction that has been automatically completed.
|
||||
* An **Interaction** ([IDiscordInteraction]) is any of the above.
|
||||
|
||||
[ISlashCommandInteraction]: xref:Discord.ISlashCommandInteraction
|
||||
[IMessageCommandInteraction]: xref:Discord.IMessageCommandInteraction
|
||||
[IUserCommandInteraction]: xref:Discord.IUserCommandInteraction
|
||||
[IApplicationCommandInteraction]: xref:Discord.IApplicationCommandInteraction
|
||||
[IMessageComponent]: xref:Discord.IMessageComponent
|
||||
[IAutocompleteinteraction]: xref:Discord.IAutocompleteInteraction
|
||||
[IDiscordInteraction]: xref:Discord.IDiscordInteraction
|
||||
|
||||
## Other types:
|
||||
|
||||
### Emoji
|
||||
|
||||
* An **Emote** ([Emote]) is a custom emote from a guild.
|
||||
- Example: `<:dotnet:232902710280716288>`
|
||||
@@ -95,8 +114,7 @@ exist under a category.
|
||||
[Emote]: xref:Discord.Emote
|
||||
[Emoji]: xref:Discord.Emoji
|
||||
|
||||
|
||||
## Sticker Types
|
||||
### Stickers
|
||||
|
||||
* A **Sticker** ([ISticker]) is a standard Discord sticker.
|
||||
* A **Custom Sticker ([ICustomSticker]) is a Guild-unique sticker.
|
||||
@@ -104,7 +122,7 @@ exist under a category.
|
||||
[ISticker]: xref:Discord.ISticker
|
||||
[ICustomSticker]: xref:Discord.ICustomSticker
|
||||
|
||||
## Activity Types
|
||||
### Activity
|
||||
|
||||
* A **Game** ([Game]) refers to a user's game activity.
|
||||
* A **Rich Presence** ([RichGame]) refers to a user's detailed
|
||||
BIN
docs/guides/entities/images/IChannel.png
Normal file
BIN
docs/guides/entities/images/IChannel.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 58 KiB |
BIN
docs/guides/entities/images/IInteraction.png
Normal file
BIN
docs/guides/entities/images/IInteraction.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 37 KiB |
BIN
docs/guides/entities/images/IMessage.png
Normal file
BIN
docs/guides/entities/images/IMessage.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
BIN
docs/guides/entities/images/IUser.png
Normal file
BIN
docs/guides/entities/images/IUser.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 62 KiB |
@@ -1,26 +1,41 @@
|
||||
---
|
||||
uid: Guides.Concepts.Entities
|
||||
title: Entities
|
||||
uid: Guides.Entities.Intro
|
||||
title: Introduction
|
||||
---
|
||||
|
||||
# Entities in Discord.Net
|
||||
|
||||
> [!NOTE]
|
||||
> This article is written with the Socket variants of entities in mind,
|
||||
> not the general interfaces or Rest entities.
|
||||
|
||||
Discord.Net provides a versatile entity system for navigating the
|
||||
Discord API.
|
||||
|
||||
> [!TIP]
|
||||
> It is **vital** that you use the proper IDs for an entity when using
|
||||
> a `GetXXX` method. It is recommended that you enable Discord's
|
||||
> _developer mode_ to allow easy access to entity IDs, found in
|
||||
> Settings > Appearance > Advanced. Read more about it in the
|
||||
> [FAQ](xref:FAQ.Basics.GetStarted) page.
|
||||
|
||||
## Inheritance
|
||||
|
||||
Due to the nature of the Discord API, some entities are designed with
|
||||
multiple variants; for example, `SocketUser` and `SocketGuildUser`.
|
||||
multiple variants; for example, `IUser` and `IGuildUser`.
|
||||
|
||||
All models will contain the most detailed version of an entity
|
||||
possible, even if the type is less detailed.
|
||||
|
||||
For example, in the case of the `MessageReceived` event, a
|
||||
## Socket & REST
|
||||
|
||||
REST entities are retrieved over REST, and will be disposed after use.
|
||||
It is suggested to limit the amount of REST calls as much as possible,
|
||||
as calls over REST interact with the API, and are thus prone to rate-limits.
|
||||
|
||||
- [Learn more about REST](https://restfulapi.net/)
|
||||
|
||||
Socket entities are created through the gateway,
|
||||
most commonly through `DiscordSocketClient` events.
|
||||
These entities will enter the clients' global cache for later use.
|
||||
|
||||
In the case of the `MessageReceived` event, a
|
||||
`SocketMessage` is passed in with a channel property of type
|
||||
`SocketMessageChannel`. All messages come from channels capable of
|
||||
messaging, so this is the only variant of a channel that can cover
|
||||
@@ -31,7 +46,9 @@ But that doesn't mean a message _can't_ come from a
|
||||
retrieve information about a guild from a message entity, you will
|
||||
need to cast its channel object to a `SocketTextChannel`.
|
||||
|
||||
You can find out various types of entities in the [Glossary page.](xref:FAQ.Glossary)
|
||||
> [!NOTE]
|
||||
> You can find out the inheritance tree & definitions of various entities
|
||||
> [here](xref:Guides.Entities.Glossary)
|
||||
|
||||
## Navigation
|
||||
|
||||
@@ -40,26 +57,31 @@ you to easily navigate to an entity's parent or children. As explained
|
||||
above, you will sometimes need to cast to a more detailed version of
|
||||
an entity to navigate to its parent.
|
||||
|
||||
## Accessing Entities
|
||||
## Accessing Socket Entities
|
||||
|
||||
The most basic forms of entities, `SocketGuild`, `SocketUser`, and
|
||||
`SocketChannel` can be pulled from the DiscordSocketClient's global
|
||||
cache, and can be retrieved using the respective `GetXXX` method on
|
||||
DiscordSocketClient.
|
||||
|
||||
> [!TIP]
|
||||
> It is **vital** that you use the proper IDs for an entity when using
|
||||
> a `GetXXX` method. It is recommended that you enable Discord's
|
||||
> _developer mode_ to allow easy access to entity IDs, found in
|
||||
> Settings > Appearance > Advanced. Read more about it in the
|
||||
> [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
|
||||
`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.
|
||||
|
||||
## Sample
|
||||
### Sample
|
||||
|
||||
[!code-csharp[Entity Sample](samples/entities.cs)]
|
||||
[!code-csharp[Socket Sample](samples/socketentities.cs)]
|
||||
|
||||
## Accessing REST Entities
|
||||
|
||||
REST entities work almost the same as Socket entities, but are much less frequently used.
|
||||
To access REST entities, the `DiscordSocketClient`'s `Rest` property is required.
|
||||
Another option here is to create your own [DiscordRestClient], independent of the Socket gateway.
|
||||
|
||||
[DiscordRestClient]: xref:Discord.Rest.DiscordRestClient
|
||||
|
||||
### Sample
|
||||
|
||||
[!code-csharp[Rest Sample](samples/restentities.cs)]
|
||||
7
docs/guides/entities/samples/casting.cs
Normal file
7
docs/guides/entities/samples/casting.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
// Say we have an entity; for the simplicity of this example, it will appear from thin air.
|
||||
IChannel channel;
|
||||
|
||||
// If we want this to be an ITextChannel so we can access the properties of a text channel inside of a guild, an approach would be:
|
||||
ITextChannel textChannel = channel as ITextChannel;
|
||||
|
||||
await textChannel.DoSomethingICantWithIChannelAsync();
|
||||
8
docs/guides/entities/samples/restentities.cs
Normal file
8
docs/guides/entities/samples/restentities.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
// RestUser entities expose the accent color and banner of a user.
|
||||
// This being one of the few use-cases for requesting a RestUser instead of depending on the Socket counterpart.
|
||||
public static EmbedBuilder WithUserColor(this EmbedBuilder builder, IUser user)
|
||||
{
|
||||
var restUser = await _client.Rest.GetUserAsync(user.Id);
|
||||
return builder.WithColor(restUser.AccentColor ?? Color.Blue);
|
||||
// The accent color can still be null, so a check for this needs to be done to prevent an exception to be thrown.
|
||||
}
|
||||
10
docs/guides/entities/samples/safety-cast-pass.cs
Normal file
10
docs/guides/entities/samples/safety-cast-pass.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
private void MyFunction(IMessage message)
|
||||
{
|
||||
// Here we do the reverse as in the previous examples, and let it continue the code below if it IS an IUserMessage
|
||||
if (message is not IUserMessage userMessage)
|
||||
return;
|
||||
|
||||
// Because we do the above check inline (don't give the statement a body),
|
||||
// the code will still declare `userMessage` as available outside of the above statement.
|
||||
Console.WriteLine(userMessage.Author);
|
||||
}
|
||||
9
docs/guides/entities/samples/safety-cast-var.cs
Normal file
9
docs/guides/entities/samples/safety-cast-var.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
IUser user;
|
||||
|
||||
// Here we can pre-define the actual declaration of said IGuildUser object,
|
||||
// so we don't need to cast additionally inside of the statement.
|
||||
if (user is IGuildUser guildUser)
|
||||
{
|
||||
Console.WriteLine(guildUser.JoinedAt);
|
||||
}
|
||||
// Check failed.
|
||||
8
docs/guides/entities/samples/safety-cast.cs
Normal file
8
docs/guides/entities/samples/safety-cast.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
IUser user;
|
||||
|
||||
// Here we check if the user is an IGuildUser, if not, let it pass. This ensures its not null.
|
||||
if (user is IGuildUser)
|
||||
{
|
||||
Console.WriteLine("This user is in a guild!");
|
||||
}
|
||||
// Check failed.
|
||||
9
docs/guides/entities/samples/unboxing.cs
Normal file
9
docs/guides/entities/samples/unboxing.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
IUser user;
|
||||
|
||||
// Here we use inline unboxing to make a call to its member (if available) only once.
|
||||
|
||||
// Note that if the entity we're trying to cast to is null, this will throw a NullReferenceException.
|
||||
Console.WriteLine(((IGuildUser)user).Nickname);
|
||||
|
||||
// In case you are certain the entity IS said member, you can also use unboxing to declare variables.
|
||||
IGuildUser guildUser = (IGuildUser)user;
|
||||
@@ -21,8 +21,14 @@
|
||||
topicUid: Guides.Concepts.Events
|
||||
- name: Managing Connections
|
||||
topicUid: Guides.Concepts.ManageConnections
|
||||
- name: Entities
|
||||
topicUid: Guides.Concepts.Entities
|
||||
- name: Entities
|
||||
items:
|
||||
- name: Introduction
|
||||
topicUid: Guides.Entities.Intro
|
||||
- name: Casting
|
||||
topicUid: Guides.Entities.Casting
|
||||
- name: Glossary & Flowcharts
|
||||
topicUid: Guides.Entities.Glossary
|
||||
- name: Working with Text-based Commands
|
||||
items:
|
||||
- name: Introduction
|
||||
|
||||
Reference in New Issue
Block a user