Browse Source

Merge branch 'dev' into feature/link-sanitize

pull/1152/head
Quin Lynch GitHub 3 years ago
parent
commit
6fe35c7e9b
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
100 changed files with 4944 additions and 198 deletions
  1. +17
    -0
      .github/PULL_REQUEST_TEMPLATE.md
  2. +4
    -4
      .gitignore
  3. +441
    -0
      CHANGELOG.md
  4. +19
    -1
      CONTRIBUTING.md
  5. +23
    -0
      Discord.Net.code-workspace
  6. +95
    -17
      Discord.Net.sln
  7. +16
    -0
      Discord.Net.sln.DotSettings
  8. +9
    -7
      Discord.Net.targets
  9. +1
    -1
      LICENSE
  10. +33
    -6
      README.md
  11. +9
    -0
      StyleAnalyzer.targets
  12. +0
    -61
      appveyor.yml
  13. +41
    -0
      azure-pipelines.yml
  14. +27
    -0
      azure/build.yml
  15. +35
    -0
      azure/deploy.yml
  16. +15
    -0
      azure/docs.bat
  17. +16
    -0
      azure/docs.yml
  18. +40
    -26
      docs/CONTRIBUTING.md
  19. +21
    -0
      docs/Discord.Net.Docs.code-workspace
  20. +9
    -10
      docs/README.md
  21. +31
    -0
      docs/_overwrites/Commands/CommandException.Overwrite.md
  22. +22
    -0
      docs/_overwrites/Commands/DontAutoLoadAttribute.Overwrite.md
  23. +27
    -0
      docs/_overwrites/Commands/DontInjectAttribute.Overwrite.md
  24. +5
    -0
      docs/_overwrites/Commands/ICommandContext.Inclusion.md
  25. +27
    -0
      docs/_overwrites/Commands/ICommandContext.Overwrite.md
  26. +103
    -0
      docs/_overwrites/Commands/PreconditionAttribute.Overwrites.md
  27. +6
    -0
      docs/_overwrites/Commands/PreconditionAttribute.Remarks.Inclusion.md
  28. +29
    -0
      docs/_overwrites/Common/DiscordComparers.Overwrites.md
  29. +69
    -0
      docs/_overwrites/Common/EmbedBuilder.Overwrites.md
  30. +25
    -0
      docs/_overwrites/Common/EmbedObjectBuilder.Inclusion.md
  31. +20
    -0
      docs/_overwrites/Common/EmbedObjectBuilder.Overwrites.md
  32. +26
    -0
      docs/_overwrites/Common/IEmote.Inclusion.md
  33. +81
    -0
      docs/_overwrites/Common/IEmote.Overwrites.md
  34. +174
    -0
      docs/_overwrites/Common/ObjectProperties.Overwrites.md
  35. +24
    -0
      docs/_overwrites/Common/OverrideTypeReaderAttribute.Overwrites.md
  36. BIN
      docs/_overwrites/Common/images/embed-example.png
  37. BIN
      docs/_overwrites/Common/images/react-example.png
  38. BIN
      docs/_template/description-generator/plugins/DocFX.Plugin.DescriptionGenerator.dll
  39. +21
    -0
      docs/_template/description-generator/plugins/LICENSE
  40. +29
    -0
      docs/_template/last-modified/plugins/LICENSE
  41. BIN
      docs/_template/last-modified/plugins/LastModifiedPostProcessor.dll
  42. BIN
      docs/_template/last-modified/plugins/LibGit2Sharp.dll
  43. +4
    -0
      docs/_template/last-modified/plugins/LibGit2Sharp.dll.config
  44. BIN
      docs/_template/last-modified/plugins/lib/alpine-x64/libgit2-a904fc6.so
  45. BIN
      docs/_template/last-modified/plugins/lib/alpine-x64/libgit2-ef5a385.so
  46. BIN
      docs/_template/last-modified/plugins/lib/alpine.3.9-x64/libgit2-ef5a385.so
  47. BIN
      docs/_template/last-modified/plugins/lib/debian-arm64/libgit2-ef5a385.so
  48. BIN
      docs/_template/last-modified/plugins/lib/debian.9-x64/libgit2-a904fc6.so
  49. BIN
      docs/_template/last-modified/plugins/lib/debian.9-x64/libgit2-ef5a385.so
  50. BIN
      docs/_template/last-modified/plugins/lib/fedora-x64/libgit2-a904fc6.so
  51. BIN
      docs/_template/last-modified/plugins/lib/fedora-x64/libgit2-ef5a385.so
  52. BIN
      docs/_template/last-modified/plugins/lib/linux-x64/libgit2-a904fc6.so
  53. BIN
      docs/_template/last-modified/plugins/lib/linux-x64/libgit2-ef5a385.so
  54. BIN
      docs/_template/last-modified/plugins/lib/osx/libgit2-a904fc6.dylib
  55. BIN
      docs/_template/last-modified/plugins/lib/osx/libgit2-ef5a385.dylib
  56. BIN
      docs/_template/last-modified/plugins/lib/rhel-x64/libgit2-a904fc6.so
  57. BIN
      docs/_template/last-modified/plugins/lib/rhel-x64/libgit2-ef5a385.so
  58. BIN
      docs/_template/last-modified/plugins/lib/ubuntu.16.04-arm64/libgit2-ef5a385.so
  59. BIN
      docs/_template/last-modified/plugins/lib/ubuntu.18.04-x64/libgit2-a904fc6.so
  60. BIN
      docs/_template/last-modified/plugins/lib/ubuntu.18.04-x64/libgit2-ef5a385.so
  61. BIN
      docs/_template/last-modified/plugins/lib/win32/x64/git2-a904fc6.dll
  62. BIN
      docs/_template/last-modified/plugins/lib/win32/x64/git2-ef5a385.dll
  63. BIN
      docs/_template/last-modified/plugins/lib/win32/x86/git2-a904fc6.dll
  64. BIN
      docs/_template/last-modified/plugins/lib/win32/x86/git2-ef5a385.dll
  65. +21
    -0
      docs/_template/light-dark-theme/docfx-material-license.md
  66. +34
    -0
      docs/_template/light-dark-theme/partials/affix.tmpl.partial
  67. +33
    -0
      docs/_template/light-dark-theme/partials/head.tmpl.partial
  68. +8
    -0
      docs/_template/light-dark-theme/partials/scripts.tmpl.partial
  69. +3
    -0
      docs/_template/light-dark-theme/styles/cornerify.js
  70. +322
    -0
      docs/_template/light-dark-theme/styles/dark.css
  71. +1021
    -0
      docs/_template/light-dark-theme/styles/docfx.vendor.minify.css
  72. +324
    -0
      docs/_template/light-dark-theme/styles/gray.css
  73. +117
    -0
      docs/_template/light-dark-theme/styles/light.css
  74. +234
    -0
      docs/_template/light-dark-theme/styles/master.css
  75. +199
    -0
      docs/_template/light-dark-theme/styles/material.css
  76. +26
    -0
      docs/_template/light-dark-theme/styles/styleswitcher.js
  77. +9
    -0
      docs/_template/light-dark-theme/styles/theme-switcher.css
  78. +72
    -0
      docs/_template/light-dark-theme/styles/tomorrow.css
  79. +115
    -0
      docs/_template/light-dark-theme/styles/vs2015.css
  80. +11
    -8
      docs/api/index.md
  81. +46
    -57
      docs/docfx.json
  82. +123
    -0
      docs/faq/basics/basic-operations.md
  83. +94
    -0
      docs/faq/basics/client-basics.md
  84. +82
    -0
      docs/faq/basics/getting-started.md
  85. BIN
      docs/faq/basics/images/dev-mode.png
  86. BIN
      docs/faq/basics/images/mention-escape.png
  87. BIN
      docs/faq/basics/images/role-copy.png
  88. BIN
      docs/faq/basics/images/snowflake.png
  89. +15
    -0
      docs/faq/basics/samples/cast.cs
  90. +18
    -0
      docs/faq/basics/samples/emoji-others.cs
  91. +17
    -0
      docs/faq/basics/samples/emoji-self.cs
  92. +54
    -0
      docs/faq/commands/dependency-injection.md
  93. +147
    -0
      docs/faq/commands/general.md
  94. +28
    -0
      docs/faq/commands/samples/DI.cs
  95. +20
    -0
      docs/faq/commands/samples/Remainder.cs
  96. +29
    -0
      docs/faq/commands/samples/missing-dep.cs
  97. +7
    -0
      docs/faq/commands/samples/runmode-cmdattrib.cs
  98. +10
    -0
      docs/faq/commands/samples/runmode-cmdconfig.cs
  99. +82
    -0
      docs/faq/misc/glossary.md
  100. +29
    -0
      docs/faq/misc/legacy.md

+ 17
- 0
.github/PULL_REQUEST_TEMPLATE.md View File

@@ -0,0 +1,17 @@
Thanks in advance for your contribution to Discord.Net!

Before opening a pull request, please consider the following:

Does your changeset adhere to the Contributing Guidelines?

Does your changeset address a specific issue or idea? If not, please
break your changes up into multiple requests.

Have your changes been previously discussed with other members
of the community? We prefer new features to be vetted through
an issue or a discussion in our Discord channel first; bug-fixes
and other small changes are generally fine without prior vetting.

Please remove this section, and include a summary of your changes
below.
---

+ 4
- 4
.gitignore View File

@@ -15,8 +15,6 @@
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
build/
bld/
[Bb]in/
@@ -129,7 +127,7 @@ publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
@@ -153,7 +151,6 @@ AppPackages/
# Others
*.[Cc]ache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
@@ -206,3 +203,6 @@ project.lock.json
docs/api/\.manifest

\.idea/

# Codealike UID
codealike.json

+ 441
- 0
CHANGELOG.md View File

@@ -0,0 +1,441 @@
# Changelog

## [2.4.0] - 2021-05-22
### Added
- #1726 Add stickers (91a9063)
- #1753 Webhook message edit & delete functionality (f67cd8e)
- #1757 Add ability to add/remove roles by id (4c9910c)
- #1781 Add GetEmotesAsync to IGuild (df23d57)
- #1801 Add missing property to MESSAGE_REACTION_ADD event (0715d7d)
- #1828 Add methods to interact with reactions without a message object (5b244f2)
- #1830 Add ModifyMessageAsync to IMessageChannel (365a848)
- #1844 Add Discord Certified Moderator user flag (4b8d444)

### Fixed
- #1486 Add type reader when entity type reader exists (c46daaa)
- #1835 Cached message emoji cleanup at MESSAGE_REACTION_REMOVE_EMOJI (8afef82)

### Misc
- #1778 Remove URI check from EmbedBuilder (25b04c4)
- #1800 Fix spelling in SnowflakeUtils.FromSnowflake (6aff419)

## [2.3.1] - 2021-03-10
### Fixed
- #1761 Deadlock in DiscordShardedClient when Ready is never received (73e5cc2)
- #1773 Private methods aren't added as commands (0fc713a)
- #1780 NullReferenceException in pin/unpin audit logs (f794163)
- #1786 Add ChannelType property to ChannelInfo audit log (6ac5ea1)
- #1791 Update Webhook ChannelId from model change (d2518db)
- #1794 Audit log UserId can be null (d41aeee)

### Misc
- #1774 Add remark regarding CustomStatus as the activity (51b7afe)

## [2.3.0] - 2021-01-28
### Added
- #1491 Add INVITE_CREATE and INVITE_DELETE events (1ab670b)
- #1520 Support reading multiple activities (421a0c1)
- #1521 Allow for inherited commands in modules (a51cdf6)
- #1526 Add Direction.Around to GetMessagesAsync (f2130f8)
- #1537 Implement gateway ratelimit (ec673e1)
- #1544 Add MESSAGE_REACTION_REMOVE_EMOJI and RemoveAllReactionsForEmoteAsync (a89f076)
- #1549 Add GetUsersAsync to SocketGuild (30b5a83)
- #1566 Support Gateway Intents (d5d10d3)
- #1573 Add missing properties to Guild and deprecate GuildEmbed (ec212b1)
- #1581 Add includeRoleIds to PruneUsersAsync (a80e5ff)
- #1588 Add GetStreams to AudioClient (1e012ac)
- #1596 Add missing channel properties (2d80037)
- #1604 Add missing application properties (including Teams) (10fcde0)
- #1619 Add "View Guild Insights" to GuildPermission (2592264)
- #1637 Added CultureInvariant RegexOption to WebhookUrlRegex (e3925a7)
- #1659 Add inline replies (e3850e1)
- #1688 Send presence on Identify payload (25d5d36)
- #1721 Add role tags (6a62c47)
- #1722 Add user public flags (c683b29)
- #1724 Add MessageFlags and AllowedMentions to message modify (225550d)
- #1731 Add GuildUser IsPending property (8b25c9b)
- #1690 Add max bitrate value to SocketGuild (aacfea0)

### Fixed
- #1244 Missing AddReactions permission for DM channels. (e40ca4a)
- #1469 unsupported property causes an exception (468f826)
- #1525 AllowedMentions and AllowedMentionTypes (3325031)
- #1531 Add AllowedMentions to SendFileAsync (ab32607)
- #1532 GuildEmbed.ChannelId as nullable per API documentation (971d519)
- #1546 Different ratelimits for the same route (implement discord buckets) (2f6c017)
- #1548 Incomplete Ready, DownloadUsersAsync, and optimize AlwaysDownloadUsers (dc8c959)
- #1555 InvalidOperationException at MESSAGE_CREATE (bd4672a)
- #1557 Sending 2 requests instead of 1 to create a Guild role. (5430cc8)
- #1571 Not using the new domain name. (df8a0f7)
- #1578 Trim token before passing it to the authorization header (42ba372)
- #1580 Stop TaskCanceledException from bubbling up (b8fa464)
- #1599 Invite audit log without inviter (b95b95b)
- #1602 Add AllowedMentions to webhooks (bd4516b)
- #1603 Cancel reconnection when 4014 (f396cd9)
- #1608 Voice overwrites and CategoryId remarks (43c8fc0)
- #1614 Check error 404 and return null for GetBanAsync (ae9fff6)
- #1621 Parse mentions from message payload (366ca9a)
- #1622 Do not update overwrite cache locally (3860da0)
- #1623 Invoke UserUpdated from GuildMemberUpdated if needed (3085e88)
- #1624 Handle null PreferredLocale in rare cases (c1d04b4)
- #1639 Invite and InviteMetadata properties (dd2e524)
- #1642 Add missing permissions (4b389f3)
- #1647 handicap member downloading for verified bots (fa5ef5e)
- #1652 Update README.MD to reflect new discord domain (03b831e)
- #1667 Audio stream dispose (a2af985)
- #1671 Crosspost throwing InvalidOperationException (9134443)
- #1672 Team is nullable, not optional (be60d81)
- #1681 Emoji url encode (04389a4)
- #1683 SocketGuild.HasAllMembers is false if a user left a guild (47f571e)
- #1686 Revert PremiumSubscriptionCount type (97e71cd)
- #1695 Possible NullReferenceException when receiving InvalidSession (5213916)
- #1702 Rollback Activities to Game (9d7cb39)
- #1727 Move and fix internal AllowedMentions object (4a7f8fe)
- limit request members batch size (084db25)
- UserMentions throwing NullRef (5ed01a3)
- Wrong author for SocketUserMessage.ReferencedMessage (1e9b252)
- Discord sends null when there's no team (05a1f0a)
- IMessage.Embeds docs remarks (a4d32d3)
- Missing MessageReference when sending files (2095701)

### Misc
- #1545 MutualGuilds optimization (323a677)
- #1551 Update webhook regex to support discord.com (7585789)
- #1556 Add SearchUsersAsync (57880de)
- #1561 Minor refactor to switch expression (42826df)
- #1576 Updating comments for privileged intents (c42bfa6)
- #1678 Change ratelimit messages (47ed806)
- #1714 Update summary of SocketVoiceChannel.Users (e385c40)
- #1720 VoiceRegions and related changes (5934c79)
- Add updated libraries for LastModified (d761846)
- Add alternative documentation link (accd351)
- Temporarily disable StyleCops until all the fixes are impl'd (36de7b2)
- Remove redundant CreateGuildRoleParams (3df0539)
- Add minor tweaks to DiscordSocketConfig docs strings (2cd1880)
- Fix MaxWaitBetweenGuildAvailablesBeforeReady docs string (e31cdc7)
- Missing summary tag for GatewayIntents (3a10018)
- Add new method of role ID copy (857ef77)
- Resolve inheritdocs for IAttachment (9ea3291)
- Mark null as a specific langword in summary (13a41f8)
- Cleanup GatewayReconnectException docs (833ee42)
- Update Docfx.Plugins.LastModified to v1.2.4 (28a6f97)
- Update framework version for tests to Core 3.1 to comply with LTS (4988a07)
- Move bulk deletes remarks from <summary> to <remarks> (62539f0)

## [2.2.0] - 2020-04-16
### Added
- #1247 Implement Client Status Support (9da11b4)
- #1310 id overload for RemoveReactionAsync (c88b1da)
- #1319 BOOST (faf23de)
- #1326 Added a Rest property to DiscordShardedClient (9fede34)
- #1348 Add Quote Formatting (265da99)
- #1354 Add support for setting X-RateLimit-Precision (9482204)
- #1355 Provide ParameterInfo with error ParseResult (3755a02)
- #1357 add the "Stream" permission. (b00da3d)
- #1358 Add ChannelFollowAdd MessageType (794eba5)
- #1369 Add SelfStream voice state property (9bb08c9)
- #1372 support X-RateLimit-Reset-After (7b9029d)
- #1373 update audit log models (c54867f)
- #1377 Support filtering audit log entries on user, action type, and before entry id (68eb71c)
- #1386 support guild subscription opt-out (0d54207)
- #1387 #1381 Guild PreferredLocale support (a61adb0)
- #1406 CustomStatusGame Activity (79a0ea9)
- #1413 Implemented Message Reference Property (f86c39d)
- #1414 add StartedAt, EndsAt, Elapsed and Remaining to SpotifyGame. (2bba324)
- #1432 Add ability to modify the banner for guilds (d734ce0)
- suppress messages (cd28892)

### Fixed
- #1318 #1314 Don't parse tags within code blocks (c977f2e)
- #1333 Remove null coalescing on ToEmbedBuilder Color (120c0f7)
- #1337 Fixed attempting to access a non-present optional value (4edda5b)
- #1346 CommandExecuted event will fire when a parameter precondition fails like what happens when standard precondition fails. (e8cb031)
- #1371 Fix keys of guild update audit (b0a595b)
- #1375 Use double precision for X-Reset-After, set CultureInfo when parsing numeric types (606dac3)
- #1392 patch todo in NamedTypeReader (0bda8a4)
- #1405 add .NET Standard 2.1 support for Color (7f0c0c9)
- #1412 GetUsersAsync to use MaxUsersPerBatch const as limit instead of MaxMessagesPerBatch. (5439cba)
- #1416 false-positive detection of CustomStatusGame based on Id property (a484651)
- #1418 #1335 Add isMentionable parameter to CreateRoleAsync in non-breaking manner (1c63fd4)
- #1421 (3ff4e3d)
- include MessageFlags and SuppressEmbedParams (d6d4429)

### Changed
- #1368 Update ISystemMessage interface to allow reactions (07f4d5f)
- #1417 fix #1415 Re-add support for overwrite permissions for news channels (e627f07)
- use millisecond precision by default (bcb3534)

### Misc
- #1290 Split Unit and Integration tests into separate projects (a797be9)
- #1328 Fix #1327 Color.ToString returns wrong value (1e8aa08)
- #1329 Fix invalid cref values in docs (363d1c6)
- #1330 Fix spelling mistake in ExclusiveBulkDelete warning (c864f48)
- #1331 Change token explanation (0484fe8)
- #1349 Fixed a spelling error. (af79ed5)
- #1353 [ci skip] Removed duplicate "any" from the readme (15b2a36)
- #1359 Fixing GatewayEncoding comment (52565ed)
- #1379 September 2019 Documentation Update (fd3810e)
- #1382 Fix .NET Core 3.0 compatibility + Drop NS1.3 (d199d93)
- #1388 fix coercion error with DateTime/Offset (3d39704)
- #1393 Utilize ValueTuples (99d7135)
- #1400 Fix #1394 Misworded doc for command params args (1c6ee72)
- #1401 Fix package publishing in azure pipelines (a08d529)
- #1402 Fix packaging (65223a6)
- #1403 Cache regex instances in MessageHelper (007b011)
- #1424 Fix the Comparer descriptions not linking the type (911523d)
- #1426 Fix incorrect and missing colour values for Color fields (9ede6b9)
- #1470 Added System.Linq reference (adf823c)
- temporary sanity checking in SocketGuild (c870e67)
- build and deploy docs automatically (2981d6b)
- 2.2.0 (4b602b4)
- target the Process env-var scope (3c6b376)
- fix metapackage build (1794f95)
- copy only _site to docs-static (a8cdadc)
- do not exit on failed robocopy (fd204ee)
- add idn debugger (91aec9f)
- rename IsStream to IsStreaming (dcd9cdd)
- feature (40844b9)

## [2.1.1] - 2019-06-08
### Fixed
- #994: Remainder parameters now ignore character escaping, as there is no reason to escape characters here (2e95c49)
- #1316: `Emote.Equals` now pays no respect to the Name property, since Discord's API does not care about an emote's name (abf3e90)
- #1317: `Emote.GetHashCode` now pays no respect to the Name property, see above (1b54883)
- #1323: Optionals will no longer claim to be specified when a reaction message was not cached (1cc5d73)
- Log messages sourcing from REST events will no longer be raised twice (c78a679)
- News embeds will be processed as `EmbedType.Unknown`, rather than throwing an error and dropping the message (d287ed1)

### Changed
- #1311: Members may now be disconnected from voice channels by passing `null` as `GuildUserProperties.Channel` (fc48c66)
- #1313: `IMessage.Tags` now includes the EveryoneRole on @everyone and @here mentions (1f55f01)
- #1320: The maximum value for setting slow-mode has been updated to 6 hours, per the new API limit (4433ca7)

### Misc
- This library's compatibility with Semantic Versioning has been clarified. Please see the README (4d7de17)
- The depency on System.Interactive.Async has been bumped to `3.2.0` (3e65e03)

## [2.1.0] - 2019-05-18
### Added
- #1236: Bulk deletes (for messages) may now be accessed via the `MessagesBulkDeleted` event (dec353e)
- #1240: OAuth applications utilizing the `guilds.join` scope may now add users to guilds through any client (1356ea9)
- #1255: Message and attachment spoilers may now be set or detected (f3b20b2)
- #1260: DiscordWebhookClient may be created from a Webhook URL (f2113c7)
- #1261: A `GetCategoryChannel` helper may now be used to retrieve category channels directly from socket guilds (e03c527)
- #1263: "user joined the guild" messages are now supported (00d3f5a)
- #1271: AuthorID may now be retrieved from message delete audit log entries (1ae4220)
- #1293: News Channels are now supported 📰 (9084c42)
- `ExclusiveBulkDelete` configuration setting can be used to control bulk delete event behavior (03e6401)

### Removed
- #1294: The `IGuildUser` overload of `EmbedBuilder.WithAuthor` no longer exists (b52b54d)

### Fixed
- #1256: Fetching audit logs no longer raises null reference exceptions when a webhook has been deleted (049b014)
- #1268: Null reference exceptions on `MESSAGE_CREATE` concerning partial member objects no longer occur (377622b)
- #1278: The token validator now internally pads tokens to the proper length (48b327b)
- #1292: Messages now properly initialize empty collections (b2ebc03)
- The `DiscordSocketRestClient` is now properly initialized (a44c13a)
- Exceptions in event handlers are now always logged (f6e3200)

### Changed
- #1305: Token validation will fail when tokens contain whitespace (bb61efa)

### Misc
- #1241: Added documentation samples for Webhooks (655a006)
- #1243: Happy new year 🎉 (0275f7d)
- #1257: Improved clarity in comments in the command samples (2473619)
- #1276: Documentation uses a relative path for the logo asset (b80f0e8)
- #1303: EmbedBuilder documentation now builds in the correct spot (51618e6)
- #1304: Updated documentation (4309550)
- CI for this project is now powered by Azure DevOps (this is not a sponsored message 🚀) (9b2bc18)
- IDisposableAnalyzers should now be a development dependency (8003ac8)

## [2.0.1] - 2019-01-04
### Fixed
- #1226: Only escape the closing quotation mark of non-remainder strings (65b8c09)
- Commands with async RunModes will now propagate exceptions up to CommandExecuted (497918e)

### Misc
- #1225: Commands sample no longer hooks the log event twice (552f34c)
- #1227: The logo on the docs index page should scale responsively (d39bf6e)
- #1230: Replaced precondition sample on docs (feed4fd)

## [2.0.0] - 2018-12-28
### Added

- #747: `CommandService` now has a `CommandExecuted` event (e991715)
- #765: Parameters may have a name specified via `NameAttribute` (9c81ab9)
- #773: Both socket clients inherit from `BaseSocketClient` (9b7afec)
- #785: Primitives now automatically load a NullableTypeReader (cb0ff78)
- #819: Support for Welcome Message channels (30e867a)
- #835: Emoji may now be managed from a bot (b4bf046)
- #843: Webhooks may now be managed from a bot (7b2ddd0)
- #863: An embed may be converted to an `EmbedBuilder` using the `.ToEmbedBuilder()` method (5218e6b)
- #877: Support for reading rich presences (34b4e5a)
- #888: Users may now opt-in to using a proxy (678a723)
- #906: API Analyzers to assist users when writing their bot (f69ef2a)
- #907: Full support for channel categories (030422f)
- #913: Animated emoji may be read and written (a19ff18)
- #915: Unused parameters may be discarded, rather than failing the command (5f46aef)
- #929: Standard EqualityComparers for use in LINQ operations with the library's entities (b5e7548)
- #934: Modules now contain an `OnModuleBuilding` method, which is invoked when the module is built (bb8ebc1)
- #952: Added 'All' permission set for categories (6d58796)
- #957: Ratelimit related objects now include request information (500f5f4)
- #962: Add `GetRecommendedShardCountAsync` (fc5e70c)
- #970: Add Spotify track support to user Activities (64b9cc7)
- #973: Added `GetDefaultAvatarUrl` to user (109f663)
- #978: Embeds can be attached alongside a file upload (e9f9b48)
- #984, #1089: `VoiceServerUpdate` events are now publically accessible (e775853, 48fed06)
- #996: Added `DeleteMessageAsync` to `IMessageChannel` (bc6009e)
- #1005: Added dedicated `TimeSpan` TypeReader which "doesn't suck" (b52af7a)
- #1009: Users can now specify the replacement behavior or default typereaders (6b7c6e9)
- #1020: Users can now specify parameters when creating channels (bf5275e)
- #1030: Added `IsDeprecated`, `IsCustom` properties to `VoiceRegion` (510f474)
- #1037: Added `SocketUser.MutualGuilds`, various extension methods to commands (637d9fc)
- #1043: `Discord.Color` is now compatible with `System.Drawing.Color` (c275e57)
- #1055: Added audit logs (39dffe8)
- #1056: Added `GetBanAsync` (97c8931)
- #1102: Added `GetJumpUrl()` to messages (afc3a9d)
- #1123: Commands can now accept named parameters (419c0a5)
- #1124: Preconditions can now set custom error messages (5677f23)
- #1126: `Color` now has equality (a2d8800)
- #1159: Guild channels can now by synced with their parent category (5ea1fb3)
- #1165: Bring Guild and Message models up to date with the API (d30d122)
- #1166: Added `GetVoiceRegionsAsync` to `IGuild` (00717cf)
- #1183: Added Add Guild Member endpoint for OAuth clients (8ef5f81)
- #1196: Channel position can now be specified when creating a channel (a64ab60)
- #1198: The Socket client can now access its underlying REST client (65afd37)
- #1213: Added `GuildEmote#CreatorId` (92bf836)
- 'html' variant added to the `EmbedType` enum (42c879c)
- Modules can now be nested in non-module classes (4edbd8d)
- Added `BanAsync` to guild members (1905fde)
- Added the permisison bit for priority speaker (c1d7818)
- All result types can use `FromError` (748e92b)
- Added support for reading/writing slow mode (97d17cf)
- Added markdown format for URLs (f005af3)
- Reactions can now be added to messages in bulk (5421df1)

### Fixed
- #742: `DiscordShardedClient#GetGuildFor` will now direct null guilds to Shard 0 (d5e9d6f)
- #743: Various issues with permissions and inheritance of permissions (f996338)
- #755: `IRole.Mention` will correctly tag the @everyone role (6b5a6e7)
- #768: `CreateGuildAsync` will include the icon stream (865080a)
- #866: Revised permissions constants and behavior (dec7cb2)
- #872: Bulk message deletion should no longer fail for incomplete batch sizes (804d918)
- #923: A null value should properly reset a user's nickname (227f61a)
- #938: The reconnect handler should no longer deadlock during Discord outages (73ac9d7)
- #941: Fix behavior of OverrideTypeReader (170a2e0)
- #945: Fix properties on SocketCategoryChannel (810f6d6)
- #959: Webhooks now use the correct parameter when assigning to the Avatar URL (8876597)
- #966: Correct the implementation of HasFlag and ResolveChannel in permissions (32ebdd5)
- #968: Add missing parameter in WebSocket4Net constructor (8537924)
- #981: Enforce a maximum value when parsing timestamps from Discord (bfaa6fc)
- #993: Null content will no longer null-ref on message sends/edits (55299ff)
- #1003: Fixed ordering of parameters in permissions classes (a06e212)
- #1010: EmbedBuilder no longer produces mutable embeds (2988b38)
- #1012: `Embed.Length` should now yield the correct results (a3ce80c)
- #1017: GetReactionUsersAsync includes query parameters (9b29c00)
- #1022: GetReactionUsersAsync is now correctly paginated (79811d0)
- #1023: Fix/update invite-related behaviors (7022149)
- #1031: Messages with no guild-specific data should no longer be lost (3631886)
- #1036: Fixed cases where `RetryMode.RetryRatelimit` were ignored (c618cb3)
- #1044: Populate the guild in `SocketWebhookUser` (6a7810b)
- #1048: The REST client will now create a full GuildUser object (033d312)
- #1049: Fixed null-ref in `GetShardIdFor` (7cfed7f)
- #1059: Include 'view channel' in voice channel's All permissions set (e764daf)
- #1083: Default type readers will now be properly replaced (4bc06a0)
- #1093: Fixed race condition in audio client authentication (322d46e)
- #1139: Fixed consistency in exceptions (9e9a11d)
- #1151: `GetReactionUsersAsync` now uses the correct pagination constant (c898325)
- #1163: Reaction ratelimits are now placed in the same bucket, treated correctly (5ea1fb3)
- #1186: Webhooks can now send files with embeds correctly (c1d5152)
- #1192: CommandExecuted no longer fires twice for RuntimeResults (10233f3)
- #1195: Channel Create audit log events properly deserialize (dca6c33)
- #1202: The UDP client should no longer be used after disposed (ccb16e4)
- #1203: The Audio client should no longer lock up on disconnect (2c93363)
- #1209: MessageUpdated should no longer pass a null after object (91e0f03)
- Ignore messages with no ID in bulk delete (676be40)
- No longer attempt to load generic types as modules (b1eaa44)
- No longer complain when a `PRESENCES_REPLACE` update is received (beb3d46)
- CommandExecuted will be raised on async exception failures (6260749)
- ExecuteResult now contains the entire exception, not an abridged message (f549da5)
- CommandExecuted will no longer be raised twice for exceptions (aec7105)
- The default WebSocket will now close correctly (ac389f5)

### Changed
- #731: `IUserMessage#GetReactionUsersAsync` now takes an `IEmote` instead of a `string` (5d7f2fc)
- #744: IAsyncEnumerable has been redesigned (5bbd9bb)
- #777: `IGuild#DefaultChannel` will now resolve the first accessible channel, per changes to Discord (1ffcd4b)
- #781: Attempting to add or remove a member's EveryoneRole will throw (506a6c9)
- #801: `EmbedBuilder` will no longer implicitly convert to `Embed`, you must build manually (94f7dd2)
- #804: Command-related tasks will have the 'async' suffix (14fbe40)
- #812: The WebSocket4Net provider has been bumped to version 0.15, allowing support for .NET Standard apps (e25054b)
- #829: DeleteMessagesAsync moved from IMessageChannel to ITextChannel (e00f17f)
- #853: WebSocket will now use `zlib-stream` compression (759db34)
- #874: The `ReadMessages` permission is moving to `ViewChannel` (edfbd05)
- #877: Refactored Games into Activities (34b4e5a)
- #943: Multiple types of quotation marks can now be parsed (thanks 🍎) (cee71ef)
- #955: The `GameParty` model will now use long values (178ea8d)
- #986: Expose the internal entity TypeReaders (660fec0)
- #992: Throw an exception when trying to modify someone else's message (d50fc3b)
- #998: Commands can specify their own `IgnoreExtraArgs` behavior (6d30100)
- #1033: The `ReadMessages` permission bit is now named `ViewChannel` (5f084ad)
- #1042: Content parameter of `SendMessageAsync` is now optional (0ba8b06)
- #1057: An audio channel's `ConnectAsync` now allows users to handle the voice connection elsewhere, such as in Lavalink (890904f)
- #1094: Overhauled invites, added vanity invite support (ffe994a)
- #1108: Reactions now use the undocumented 1/.25 ratelimit, making them 4x faster (6b21b11)
- #1128: Bot tokens will now be validated for common mishaps before use (2de6cef)
- #1140: Check the invite `maxAge` parameter before making the request (649a779)
- #1164: All command results will now be raised in `CommandExecuted` (10f67a8)
- #1171: Clients have been changed to properly make use of `IDisposable` (7366cd4)
- #1172: Invite related methods were moved from `IGuildChannel` to `INestedChannel` (a3f5e0b)
- #1200: HasPrefix extensions now check for null values first (46e2674)
- `IGuildChannel#Nsfw` moved to `ITextChannel`, now maps to the API property (608bc35)
- Preemptive ratelimits are now logged under verbose, rather than warning. (3c1e766)
- The default InviteAge when creating Invites is now 24 hours (9979a02)
- All parameters to `ReplyAsync` have been made optional (b38dca7)
- The socket client will now use additional fields to fill in member/guild information on messages (8fb2c71)
- The Audio Client now uses Voice WS v3 (9ba38d7)


### Removed
- #790: Redundant overloads for `AddField` removed from EmbedBuilder (479361b)
- #925: RPC is no longer being maintained nor packaged (b30af57)
- #958: Remove support for user tokens (2fd4f56)
- User logins (including selfbots) are no longer supported (fc5adca)

### Misc
- #786: Unit tests for the Color structure (22b969c)
- #828: We now include a contributing guide (cd82a0f)
- #876: We now include a standard editorconfig (5c8c784)
- #963: Docs now include a release version, build instructions (88e6244)
- #964: Fix documentation spelling of 'echoes' (fda19b5)
- #967: Unit test permissions (63e6704)
- #968: Bumped version of WebSocket4Net to 0.15.2 (8537924)
- #972: Include sample bots in the source repository (217ec34)
- #1046: We now support .NET Standard 2.0 (bbbac85)
- #1114: Various performance optimizations (82cfdff)
- #1149: The CI will now test on Ubuntu as well as Windows (674a0fc)
- #1161: The entire documentation has been rewritten, all core entities were docstringed (ff0fea9)
- #1175: Documentation changes in command samples (fb8dbca)
- #1177: Added documentation for sharded bots (00097d3)
- #1219: The project now has a logo! 🎉 (5750c3e)
- This project is now licensed to the Discord.Net contributors (710e182)
- Added templates for pull requests (f2ddf51)
- Fixed documentation layout for the logo (bafdce4)

## [1.0.2] - 2017-09-09
### Fixed

- Guilds utilizing Channel Categories will no longer crash bots on the `READY` event.

## [1.0.1] - 2017-07-05
### Fixed

- #732: Fixed parameter preconditions not being loaded from class-based modules (b6dcc9e)
- #726: Fixed CalculateScore throwing an ArgumentException for missing parameters (7597cf5)
- EmbedBuilder URI validation should no longer throw NullReferenceExceptions in certain edge cases (d89804d)
- Fixed module auto-detection for nested modules (d2afb06)

### Changed
- ShardedCommandContext now inherits from SocketCommandContext (8cd99be)

+ 19
- 1
CONTRIBUTING.md View File

@@ -41,4 +41,22 @@ We attempt to conform to the .NET Foundation's [Coding Style](https://github.com
where possible.

As a general rule, follow the coding style already set in the file you
are editing, or look at a similar file if you are adding a new one.
are editing, or look at a similar file if you are adding a new one.

### Documentation Style for Members

When creating a new public member, the member must be annotated with sufficient documentation. This should include the
following, but not limited to:

* `<summary>` summarizing the purpose of the method.
* `<param>` or `<typeparam>` explaining the parameter.
* `<return>` explaining the type of the returned member and what it is.
* `<exception>` if the method directly throws an exception.

The length of the documentation should also follow the ruler as suggested by our
[Visual Studio Code workspace](Discord.Net.code-workspace).

#### Recommended Reads

* [Official Microsoft Documentation](https://docs.microsoft.com)
* [Sandcastle User Manual](https://ewsoftware.github.io/XMLCommentsGuide/html/4268757F-CE8D-4E6D-8502-4F7F2E22DDA3.htm)

+ 23
- 0
Discord.Net.code-workspace View File

@@ -0,0 +1,23 @@
{
"folders": [
{
"path": "."
}
],
"settings": {
"editor.rulers": [
120
],
"files.exclude": {
"**/.git": true,
"**/.svn": true,
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true,
"docs/": true,
"**/obj": true,
"**/bin": true,
"samples/": true,
}
}
}

+ 95
- 17
Discord.Net.sln View File

@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27004.2009
# Visual Studio Version 16
VisualStudioVersion = 16.0.28407.52
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Core", "src\Discord.Net.Core\Discord.Net.Core.csproj", "{91E9E7BD-75C9-4E98-84AA-2C271922E5C2}"
EndProject
@@ -18,18 +18,30 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Providers.WS4Ne
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{CC3D4B1C-9DE0-448B-8AE7-F3F1F3EC5C3A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Tests", "test\Discord.Net.Tests\Discord.Net.Tests.csproj", "{C38E5BC1-11CB-4101-8A38-5B40A1BC6433}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Webhook", "src\Discord.Net.Webhook\Discord.Net.Webhook.csproj", "{9AFAB80E-D2D3-4EDB-B58C-BACA78D1EA30}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Analyzers", "src\Discord.Net.Analyzers\Discord.Net.Analyzers.csproj", "{BBA8E7FB-C834-40DC-822F-B112CB7F0140}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{BB59D5B5-E7B0-4BF4-8F82-D14431B2799B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "01_basic_ping_bot", "samples\01_basic_ping_bot\01_basic_ping_bot.csproj", "{F2FF84FB-F6AD-47E5-9EE5-18206CAE136E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "01_basic_ping_bot", "samples\01_basic_ping_bot\01_basic_ping_bot.csproj", "{F2FF84FB-F6AD-47E5-9EE5-18206CAE136E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "02_commands_framework", "samples\02_commands_framework\02_commands_framework.csproj", "{4E1F1F40-B1DD-40C9-A4B1-A2046A4C9C76}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "03_sharded_client", "samples\03_sharded_client\03_sharded_client.csproj", "{9B4C4AFB-3D15-44C6-9E36-12ED625AAA26}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Tests.Unit", "test\Discord.Net.Tests.Unit\Discord.Net.Tests.Unit.csproj", "{DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Tests.Integration", "test\Discord.Net.Tests.Integration\Discord.Net.Tests.Integration.csproj", "{E169E15A-E82C-45BF-8C24-C2CADB7093AA}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{C7CF5621-7D36-433B-B337-5A2E3C101A71}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Analyzers.Tests", "test\Discord.Net.Analyzers.Tests\Discord.Net.Analyzers.Tests.csproj", "{FC67057C-E92F-4E1C-98BE-46F839C8AD71}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Examples", "src\Discord.Net.Examples\Discord.Net.Examples.csproj", "{47820065-3CFB-401C-ACEA-862BD564A404}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "idn", "samples\idn\idn.csproj", "{4A03840B-9EBE-47E3-89AB-E0914DF21AFB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -100,18 +112,6 @@ Global
{6BDEEC08-417B-459F-9CA3-FF8BAB18CAC7}.Release|x64.Build.0 = Release|Any CPU
{6BDEEC08-417B-459F-9CA3-FF8BAB18CAC7}.Release|x86.ActiveCfg = Release|Any CPU
{6BDEEC08-417B-459F-9CA3-FF8BAB18CAC7}.Release|x86.Build.0 = Release|Any CPU
{C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Debug|x64.ActiveCfg = Debug|Any CPU
{C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Debug|x64.Build.0 = Debug|Any CPU
{C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Debug|x86.ActiveCfg = Debug|Any CPU
{C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Debug|x86.Build.0 = Debug|Any CPU
{C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Release|Any CPU.Build.0 = Release|Any CPU
{C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Release|x64.ActiveCfg = Release|Any CPU
{C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Release|x64.Build.0 = Release|Any CPU
{C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Release|x86.ActiveCfg = Release|Any CPU
{C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Release|x86.Build.0 = Release|Any CPU
{9AFAB80E-D2D3-4EDB-B58C-BACA78D1EA30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9AFAB80E-D2D3-4EDB-B58C-BACA78D1EA30}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9AFAB80E-D2D3-4EDB-B58C-BACA78D1EA30}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -160,6 +160,78 @@ Global
{4E1F1F40-B1DD-40C9-A4B1-A2046A4C9C76}.Release|x64.Build.0 = Release|Any CPU
{4E1F1F40-B1DD-40C9-A4B1-A2046A4C9C76}.Release|x86.ActiveCfg = Release|Any CPU
{4E1F1F40-B1DD-40C9-A4B1-A2046A4C9C76}.Release|x86.Build.0 = Release|Any CPU
{9B4C4AFB-3D15-44C6-9E36-12ED625AAA26}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9B4C4AFB-3D15-44C6-9E36-12ED625AAA26}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9B4C4AFB-3D15-44C6-9E36-12ED625AAA26}.Debug|x64.ActiveCfg = Debug|Any CPU
{9B4C4AFB-3D15-44C6-9E36-12ED625AAA26}.Debug|x64.Build.0 = Debug|Any CPU
{9B4C4AFB-3D15-44C6-9E36-12ED625AAA26}.Debug|x86.ActiveCfg = Debug|Any CPU
{9B4C4AFB-3D15-44C6-9E36-12ED625AAA26}.Debug|x86.Build.0 = Debug|Any CPU
{9B4C4AFB-3D15-44C6-9E36-12ED625AAA26}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9B4C4AFB-3D15-44C6-9E36-12ED625AAA26}.Release|Any CPU.Build.0 = Release|Any CPU
{9B4C4AFB-3D15-44C6-9E36-12ED625AAA26}.Release|x64.ActiveCfg = Release|Any CPU
{9B4C4AFB-3D15-44C6-9E36-12ED625AAA26}.Release|x64.Build.0 = Release|Any CPU
{9B4C4AFB-3D15-44C6-9E36-12ED625AAA26}.Release|x86.ActiveCfg = Release|Any CPU
{9B4C4AFB-3D15-44C6-9E36-12ED625AAA26}.Release|x86.Build.0 = Release|Any CPU
{DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}.Debug|x64.ActiveCfg = Debug|Any CPU
{DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}.Debug|x64.Build.0 = Debug|Any CPU
{DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}.Debug|x86.ActiveCfg = Debug|Any CPU
{DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}.Debug|x86.Build.0 = Debug|Any CPU
{DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}.Release|Any CPU.Build.0 = Release|Any CPU
{DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}.Release|x64.ActiveCfg = Release|Any CPU
{DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}.Release|x64.Build.0 = Release|Any CPU
{DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}.Release|x86.ActiveCfg = Release|Any CPU
{DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}.Release|x86.Build.0 = Release|Any CPU
{E169E15A-E82C-45BF-8C24-C2CADB7093AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E169E15A-E82C-45BF-8C24-C2CADB7093AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E169E15A-E82C-45BF-8C24-C2CADB7093AA}.Debug|x64.ActiveCfg = Debug|Any CPU
{E169E15A-E82C-45BF-8C24-C2CADB7093AA}.Debug|x64.Build.0 = Debug|Any CPU
{E169E15A-E82C-45BF-8C24-C2CADB7093AA}.Debug|x86.ActiveCfg = Debug|Any CPU
{E169E15A-E82C-45BF-8C24-C2CADB7093AA}.Debug|x86.Build.0 = Debug|Any CPU
{E169E15A-E82C-45BF-8C24-C2CADB7093AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E169E15A-E82C-45BF-8C24-C2CADB7093AA}.Release|Any CPU.Build.0 = Release|Any CPU
{E169E15A-E82C-45BF-8C24-C2CADB7093AA}.Release|x64.ActiveCfg = Release|Any CPU
{E169E15A-E82C-45BF-8C24-C2CADB7093AA}.Release|x64.Build.0 = Release|Any CPU
{E169E15A-E82C-45BF-8C24-C2CADB7093AA}.Release|x86.ActiveCfg = Release|Any CPU
{E169E15A-E82C-45BF-8C24-C2CADB7093AA}.Release|x86.Build.0 = Release|Any CPU
{FC67057C-E92F-4E1C-98BE-46F839C8AD71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FC67057C-E92F-4E1C-98BE-46F839C8AD71}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FC67057C-E92F-4E1C-98BE-46F839C8AD71}.Debug|x64.ActiveCfg = Debug|Any CPU
{FC67057C-E92F-4E1C-98BE-46F839C8AD71}.Debug|x64.Build.0 = Debug|Any CPU
{FC67057C-E92F-4E1C-98BE-46F839C8AD71}.Debug|x86.ActiveCfg = Debug|Any CPU
{FC67057C-E92F-4E1C-98BE-46F839C8AD71}.Debug|x86.Build.0 = Debug|Any CPU
{FC67057C-E92F-4E1C-98BE-46F839C8AD71}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FC67057C-E92F-4E1C-98BE-46F839C8AD71}.Release|Any CPU.Build.0 = Release|Any CPU
{FC67057C-E92F-4E1C-98BE-46F839C8AD71}.Release|x64.ActiveCfg = Release|Any CPU
{FC67057C-E92F-4E1C-98BE-46F839C8AD71}.Release|x64.Build.0 = Release|Any CPU
{FC67057C-E92F-4E1C-98BE-46F839C8AD71}.Release|x86.ActiveCfg = Release|Any CPU
{FC67057C-E92F-4E1C-98BE-46F839C8AD71}.Release|x86.Build.0 = Release|Any CPU
{47820065-3CFB-401C-ACEA-862BD564A404}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{47820065-3CFB-401C-ACEA-862BD564A404}.Debug|Any CPU.Build.0 = Debug|Any CPU
{47820065-3CFB-401C-ACEA-862BD564A404}.Debug|x64.ActiveCfg = Debug|Any CPU
{47820065-3CFB-401C-ACEA-862BD564A404}.Debug|x64.Build.0 = Debug|Any CPU
{47820065-3CFB-401C-ACEA-862BD564A404}.Debug|x86.ActiveCfg = Debug|Any CPU
{47820065-3CFB-401C-ACEA-862BD564A404}.Debug|x86.Build.0 = Debug|Any CPU
{47820065-3CFB-401C-ACEA-862BD564A404}.Release|Any CPU.ActiveCfg = Release|Any CPU
{47820065-3CFB-401C-ACEA-862BD564A404}.Release|Any CPU.Build.0 = Release|Any CPU
{47820065-3CFB-401C-ACEA-862BD564A404}.Release|x64.ActiveCfg = Release|Any CPU
{47820065-3CFB-401C-ACEA-862BD564A404}.Release|x64.Build.0 = Release|Any CPU
{47820065-3CFB-401C-ACEA-862BD564A404}.Release|x86.ActiveCfg = Release|Any CPU
{47820065-3CFB-401C-ACEA-862BD564A404}.Release|x86.Build.0 = Release|Any CPU
{4A03840B-9EBE-47E3-89AB-E0914DF21AFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4A03840B-9EBE-47E3-89AB-E0914DF21AFB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4A03840B-9EBE-47E3-89AB-E0914DF21AFB}.Debug|x64.ActiveCfg = Debug|Any CPU
{4A03840B-9EBE-47E3-89AB-E0914DF21AFB}.Debug|x64.Build.0 = Debug|Any CPU
{4A03840B-9EBE-47E3-89AB-E0914DF21AFB}.Debug|x86.ActiveCfg = Debug|Any CPU
{4A03840B-9EBE-47E3-89AB-E0914DF21AFB}.Debug|x86.Build.0 = Debug|Any CPU
{4A03840B-9EBE-47E3-89AB-E0914DF21AFB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4A03840B-9EBE-47E3-89AB-E0914DF21AFB}.Release|Any CPU.Build.0 = Release|Any CPU
{4A03840B-9EBE-47E3-89AB-E0914DF21AFB}.Release|x64.ActiveCfg = Release|Any CPU
{4A03840B-9EBE-47E3-89AB-E0914DF21AFB}.Release|x64.Build.0 = Release|Any CPU
{4A03840B-9EBE-47E3-89AB-E0914DF21AFB}.Release|x86.ActiveCfg = Release|Any CPU
{4A03840B-9EBE-47E3-89AB-E0914DF21AFB}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -173,6 +245,12 @@ Global
{BBA8E7FB-C834-40DC-822F-B112CB7F0140} = {CC3D4B1C-9DE0-448B-8AE7-F3F1F3EC5C3A}
{F2FF84FB-F6AD-47E5-9EE5-18206CAE136E} = {BB59D5B5-E7B0-4BF4-8F82-D14431B2799B}
{4E1F1F40-B1DD-40C9-A4B1-A2046A4C9C76} = {BB59D5B5-E7B0-4BF4-8F82-D14431B2799B}
{9B4C4AFB-3D15-44C6-9E36-12ED625AAA26} = {BB59D5B5-E7B0-4BF4-8F82-D14431B2799B}
{DBF8B16E-5967-4480-8EDE-15D98A0DF0C4} = {C7CF5621-7D36-433B-B337-5A2E3C101A71}
{E169E15A-E82C-45BF-8C24-C2CADB7093AA} = {C7CF5621-7D36-433B-B337-5A2E3C101A71}
{FC67057C-E92F-4E1C-98BE-46F839C8AD71} = {C7CF5621-7D36-433B-B337-5A2E3C101A71}
{47820065-3CFB-401C-ACEA-862BD564A404} = {BB59D5B5-E7B0-4BF4-8F82-D14431B2799B}
{4A03840B-9EBE-47E3-89AB-E0914DF21AFB} = {BB59D5B5-E7B0-4BF4-8F82-D14431B2799B}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D2404771-EEC8-45F2-9D71-F3373F6C1495}


+ 16
- 0
Discord.Net.sln.DotSettings View File

@@ -0,0 +1,16 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/UserDictionary/Words/=Cacheable/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Downloader/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Emoji/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=libsodium/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=NSFW/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Ratelimit/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=seeked/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=sharded/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Spotify/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=unban/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Uncache/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=webhook/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=webhooks/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=webhook_0027s/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=ZWSP/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

+ 9
- 7
Discord.Net.targets View File

@@ -1,13 +1,15 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VersionPrefix>2.0.0</VersionPrefix>
<VersionSuffix>beta2</VersionSuffix>
<Authors>RogueException</Authors>
<VersionPrefix>3.0.0</VersionPrefix>
<VersionSuffix>dev</VersionSuffix>
<LangVersion>latest</LangVersion>
<Authors>Discord.Net Contributors</Authors>
<PackageTags>discord;discordapp</PackageTags>
<PackageProjectUrl>https://github.com/RogueException/Discord.Net</PackageProjectUrl>
<PackageProjectUrl>https://github.com/Discord-Net/Discord.Net</PackageProjectUrl>
<PackageLicenseUrl>http://opensource.org/licenses/MIT</PackageLicenseUrl>
<PackageIconUrl>https://github.com/Discord-Net/Discord.Net/raw/dev/docs/marketing/logo/PackageLogo.png</PackageIconUrl>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>git://github.com/RogueException/Discord.Net</RepositoryUrl>
<RepositoryUrl>git://github.com/Discord-Net/Discord.Net</RepositoryUrl>
</PropertyGroup>
<PropertyGroup Condition=" '$(BuildNumber)' == '' ">
<VersionSuffix Condition=" '$(VersionSuffix)' != ''">$(VersionSuffix)-dev</VersionSuffix>
@@ -16,10 +18,10 @@
<PropertyGroup Condition=" '$(BuildNumber)' != '' And $(IsTagBuild) != 'true' ">
<VersionSuffix Condition=" '$(VersionSuffix)' != '' ">$(VersionSuffix)-$(BuildNumber)</VersionSuffix>
<VersionSuffix Condition=" '$(VersionSuffix)' == '' ">build-$(BuildNumber)</VersionSuffix>
</PropertyGroup>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<NoWarn>$(NoWarn);CS1573;CS1591</NoWarn>
<WarningsAsErrors>true</WarningsAsErrors>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
</Project>
</Project>

+ 1
- 1
LICENSE View File

@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2015-2017 Discord.Net Contributors
Copyright (c) 2015-2021 Discord.Net Contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal


+ 33
- 6
README.md View File

@@ -1,40 +1,67 @@
# Discord.Net

[![NuGet](https://img.shields.io/nuget/vpre/Discord.Net.svg?maxAge=2592000?style=plastic)](https://www.nuget.org/packages/Discord.Net)
[![MyGet](https://img.shields.io/myget/discord-net/vpre/Discord.Net.svg)](https://www.myget.org/feed/Packages/discord-net)
[![Build status](https://ci.appveyor.com/api/projects/status/5sb7n8a09w9clute/branch/dev?svg=true)](https://ci.appveyor.com/project/RogueException/discord-net/branch/dev)
[![Discord](https://discordapp.com/api/guilds/81384788765712384/widget.png)](https://discord.gg/jkrBmQR)
[![MyGet](https://img.shields.io/myget/discord-net/vpre/Discord.Net.svg)](https://www.myget.org/feed/Packages/discord-net)
[![Build Status](https://dev.azure.com/discord-net/Discord.Net/_apis/build/status/discord-net.Discord.Net?branchName=dev)](https://dev.azure.com/discord-net/Discord.Net/_build/latest?definitionId=1&branchName=dev)
[![Discord](https://discord.com/api/guilds/81384788765712384/widget.png)](https://discord.gg/jkrBmQR)

An unofficial .NET API Wrapper for the Discord client (https://discord.com).

## Documentation

An unofficial .NET API Wrapper for the Discord client (http://discordapp.com).
- [Nightly](https://docs.stillu.cc/)
- [Latest CI repo](https://github.com/discord-net/docs-static)

Check out the [documentation](https://discord.foxbot.me/docs/) or join the [Discord API Chat](https://discord.gg/jkrBmQR).
## Installation

## Installation
### Stable (NuGet)

Our stable builds available from NuGet through the Discord.Net metapackage:

- [Discord.Net](https://www.nuget.org/packages/Discord.Net/)

The individual components may also be installed from NuGet:

- [Discord.Net.Commands](https://www.nuget.org/packages/Discord.Net.Commands/)
- [Discord.Net.Rest](https://www.nuget.org/packages/Discord.Net.Rest/)
- [Discord.Net.WebSocket](https://www.nuget.org/packages/Discord.Net.WebSocket/)
- [Discord.Net.Webhook](https://www.nuget.org/packages/Discord.Net.Webhook/)

### Unstable (MyGet)

Nightly builds are available through our MyGet feed (`https://www.myget.org/F/discord-net/api/v3/index.json`).

## Compiling

In order to compile Discord.Net, you require the following:

### Using Visual Studio

- [Visual Studio 2017](https://www.microsoft.com/net/core#windowsvs2017)
- [.NET Core SDK](https://www.microsoft.com/net/download/core)

The .NET Core workload must be selected during Visual Studio installation.

### Using Command Line

- [.NET Core SDK](https://www.microsoft.com/net/download/core)

## Known Issues

### WebSockets (Win7 and earlier)

.NET Core 1.1 does not support WebSockets on Win7 and earlier. This issue has been fixed since the release of .NET Core 2.1. It is recommended to target .NET Core 2.1 or above for your project if you wish to run your bot on legacy platforms; alternatively, you may choose to install the [Discord.Net.Providers.WS4Net](https://www.nuget.org/packages/Discord.Net.Providers.WS4Net/) package.

## Versioning Guarantees

This library generally abides by [Semantic Versioning](https://semver.org). Packages are published in MAJOR.MINOR.PATCH version format.

An increment of the PATCH component always indicates that an internal-only change was made, generally a bugfix. These changes will not affect the public-facing API in any way, and are always guaranteed to be forward- and backwards-compatible with your codebase, any pre-compiled dependencies of your codebase.

An increment of the MINOR component indicates that some addition was made to the library, and this addition is not backwards-compatible with prior versions. However, Discord.Net **does not guarantee forward-compatibility** on minor additions. In other words, we permit a limited set of breaking changes on a minor version bump.

Due to the nature of the Discord API, we will oftentimes need to add a property to an entity to support the latest API changes. Discord.Net provides interfaces as a method of consuming entities; and as such, introducing a new field to an entity is technically a breaking change. Major version bumps generally indicate some major change to the library, and as such we are hesitant to bump the major version for every minor addition to the library. To compromise, we have decided that interfaces should be treated as **consumable only**, and your applications should typically not be implementing interfaces. (For applications where interfaces are implemented, such as in test mocks, we apologize for this inconsistency with SemVer).

Furthermore, while we will never break the API (outside of interface changes) on minor builds, we will occasionally need to break the ABI, by introducing parameters to a method to match changes upstream with Discord. As such, a minor version increment may require you to recompile your code, and dependencies, such as addons, may also need to be recompiled and republished on the newer version. When a binary breaking change is made, the change will be noted in the release notes.

An increment of the MAJOR component indicates that breaking changes have been made to the library; consumers should check the release notes to determine what changes need to be made.

+ 9
- 0
StyleAnalyzer.targets View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- <ItemGroup>
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.205" PrivateAssets="all" />
</ItemGroup>
<PropertyGroup>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
</PropertyGroup> -->
</Project>

+ 0
- 61
appveyor.yml View File

@@ -1,61 +0,0 @@
version: build-{build}
branches:
only:
- dev
image: Visual Studio 2017

nuget:
disable_publish_on_pr: true
pull_requests:
do_not_increment_build_number: true
clone_folder: C:\Projects\Discord.Net
cache: test/Discord.Net.Tests/cache.db

environment:
DOTNET_CLI_TELEMETRY_OPTOUT: 1
DNET_TEST_TOKEN:
secure: l7h5e7UE7yRd70hAB97kjPiQpPOShwqoBbOzEAYQ+XBd/Pre5OA33IXa3uisdUeQJP/nPFhcOsI+yn7WpuFaoQ==
DNET_TEST_GUILDID: 273160668180381696
init:
- ps: $Env:BUILD = "$($Env:APPVEYOR_BUILD_NUMBER.PadLeft(5, "0"))"

build_script:
- ps: appveyor-retry dotnet restore Discord.Net.sln -v Minimal /p:BuildNumber="$Env:BUILD" /p:IsTagBuild="$Env:APPVEYOR_REPO_TAG"
- ps: dotnet build Discord.Net.sln -c "Release" /p:BuildNumber="$Env:BUILD" /p:IsTagBuild="$Env:APPVEYOR_REPO_TAG"
after_build:
- ps: dotnet pack "src\Discord.Net.Core\Discord.Net.Core.csproj" -c "Release" -o "../../artifacts" --no-build /p:BuildNumber="$Env:BUILD" /p:IsTagBuild="$Env:APPVEYOR_REPO_TAG"
- ps: dotnet pack "src\Discord.Net.Rest\Discord.Net.Rest.csproj" -c "Release" -o "../../artifacts" --no-build /p:BuildNumber="$Env:BUILD" /p:IsTagBuild="$Env:APPVEYOR_REPO_TAG"
- ps: dotnet pack "src\Discord.Net.WebSocket\Discord.Net.WebSocket.csproj" -c "Release" -o "../../artifacts" --no-build /p:BuildNumber="$Env:BUILD" /p:IsTagBuild="$Env:APPVEYOR_REPO_TAG"
- ps: dotnet pack "src\Discord.Net.Commands\Discord.Net.Commands.csproj" -c "Release" -o "../../artifacts" --no-build /p:BuildNumber="$Env:BUILD" /p:IsTagBuild="$Env:APPVEYOR_REPO_TAG"
- ps: dotnet pack "src\Discord.Net.Webhook\Discord.Net.Webhook.csproj" -c "Release" -o "../../artifacts" --no-build /p:BuildNumber="$Env:BUILD" /p:IsTagBuild="$Env:APPVEYOR_REPO_TAG"
- ps: dotnet pack "src\Discord.Net.Providers.WS4Net\Discord.Net.Providers.WS4Net.csproj" -c "Release" -o "../../artifacts" --no-build /p:BuildNumber="$Env:BUILD" /p:IsTagBuild="$Env:APPVEYOR_REPO_TAG"
- ps: dotnet pack "src\Discord.Net.Analyzers\Discord.Net.Analyzers.csproj" -c "Release" -o "../../artifacts" --no-build /p:BuildNumber="$Env:BUILD" /p:IsTagBuild="$Env:APPVEYOR_REPO_TAG"
- ps: >-
if ($Env:APPVEYOR_REPO_TAG -eq "true") {
nuget pack src\Discord.Net\Discord.Net.nuspec -OutputDirectory "artifacts" -properties suffix=""
} else {
nuget pack src\Discord.Net\Discord.Net.nuspec -OutputDirectory "artifacts" -properties suffix="-$Env:BUILD"
}
- ps: Get-ChildItem artifacts\*.nupkg | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }

test_script:
- ps: >-
if ($APPVEYOR_PULL_REQUEST_NUMBER -eq "") {
dotnet test test/Discord.Net.Tests/Discord.Net.Tests.csproj -c "Release" --no-build /p:BuildNumber="$Env:BUILD" /p:IsTagBuild="$Env:APPVEYOR_REPO_TAG"
}

deploy:
- provider: NuGet
server: https://www.myget.org/F/discord-net/api/v2/package
api_key:
secure: Jl7BXeUjRnkVHDMBuUWSXcEOkrli1PBleW2IiLyUs5j63UNUNp1hcjaUJRujx9lz
symbol_server: https://www.myget.org/F/discord-net/symbols/api/v2/package
on:
branch: dev
- provider: NuGet
server: https://www.myget.org/F/rogueexception/api/v2/package
api_key:
secure: D+vW2O2LBf/iJb4f+q8fkyIW2VdIYIGxSYLWNrOD4BHlDBZQlJipDbNarWjUr2Kn
symbol_server: https://www.myget.org/F/rogueexception/symbols/api/v2/package
on:
branch: dev

+ 41
- 0
azure-pipelines.yml View File

@@ -0,0 +1,41 @@
variables:
buildConfiguration: Release
buildTag: $[ startsWith(variables['Build.SourceBranch'], 'refs/tags') ]
buildNumber: $[ variables['Build.BuildNumber'] ]

trigger:
tags:
include:
- '*'
branches:
include:
- '*'

jobs:
- job: Linux
pool:
vmImage: 'ubuntu-latest'
steps:
- template: azure/build.yml

- job: Windows_build
pool:
vmImage: 'windows-latest'
condition: ne(variables['Build.SourceBranch'], 'refs/heads/dev')
steps:
- template: azure/build.yml

- job: Windows_deploy
pool:
vmImage: 'windows-latest'
condition: |
and (
succeeded(),
or (
eq(variables['Build.SourceBranch'], 'refs/heads/dev'),
eq(variables['buildTag'], True)
)
)
steps:
- template: azure/build.yml
- template: azure/deploy.yml

+ 27
- 0
azure/build.yml View File

@@ -0,0 +1,27 @@
steps:
- task: DotNetCoreCLI@2
inputs:
command: 'restore'
projects: 'Discord.Net.sln'
feedsToUse: 'select'
verbosityRestore: 'Minimal'
displayName: Restore packages

- script: dotnet build "Discord.Net.sln" --no-restore -v minimal -c $(buildConfiguration) /p:BuildNumber=$(buildNumber) /p:IsTagBuild=$(buildTag)
displayName: Build projects

- script: dotnet test "test/Discord.Net.Tests.Unit/Discord.Net.Tests.Unit.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) --logger trx
displayName: Unit Tests

- script: dotnet test "test/Discord.Net.Analyzers.Tests/Discord.Net.Analyzers.Tests.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) --logger trx
displayName: Analyzer Tests

# - script: dotnet test "test/Discord.Net.Tests.Integration/Discord.Net.Tests.Integration.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) --logger trx
# condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/dev'))

- task: PublishTestResults@2
displayName: Publish test results
condition: succeededOrFailed()
inputs:
testRunner: VSTest
testResultsFiles: '**/*.trx'

+ 35
- 0
azure/deploy.yml View File

@@ -0,0 +1,35 @@
steps:
- script: |
dotnet pack "src\Discord.Net.Core\Discord.Net.Core.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) -o "$(Build.ArtifactStagingDirectory)" /p:BuildNumber=$(buildNumber) /p:IsTagBuild=$(buildTag)
dotnet pack "src\Discord.Net.Rest\Discord.Net.Rest.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) -o "$(Build.ArtifactStagingDirectory)" /p:BuildNumber=$(buildNumber) /p:IsTagBuild=$(buildTag)
dotnet pack "src\Discord.Net.WebSocket\Discord.Net.WebSocket.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) -o "$(Build.ArtifactStagingDirectory)" /p:BuildNumber=$(buildNumber) /p:IsTagBuild=$(buildTag)
dotnet pack "src\Discord.Net.Commands\Discord.Net.Commands.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) -o "$(Build.ArtifactStagingDirectory)" /p:BuildNumber=$(buildNumber) /p:IsTagBuild=$(buildTag)
dotnet pack "src\Discord.Net.Webhook\Discord.Net.Webhook.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) -o "$(Build.ArtifactStagingDirectory)" /p:BuildNumber=$(buildNumber) /p:IsTagBuild=$(buildTag)
dotnet pack "src\Discord.Net.Providers.WS4Net\Discord.Net.Providers.WS4Net.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) -o "$(Build.ArtifactStagingDirectory)" /p:BuildNumber=$(buildNumber) /p:IsTagBuild=$(buildTag)
dotnet pack "src\Discord.Net.Analyzers\Discord.Net.Analyzers.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) -o "$(Build.ArtifactStagingDirectory)" /p:BuildNumber=$(buildNumber) /p:IsTagBuild=$(buildTag)
displayName: Pack projects

- task: NuGetCommand@2
displayName: Pack metapackage (release mode)
condition: eq(variables['buildTag'], True)
inputs:
command: 'pack'
packagesToPack: 'src/Discord.Net/Discord.Net.nuspec'
versioningScheme: 'off'

- task: NuGetCommand@2
displayName: Pack metapackage
condition: eq(variables['buildTag'], False)
inputs:
command: 'pack'
packagesToPack: 'src/Discord.Net/Discord.Net.nuspec'
versioningScheme: 'off'
buildProperties: 'suffix=-$(buildNumber)'

- task: NuGetCommand@2
displayName: Push to NuGet
inputs:
command: push
nuGetFeedType: external
packagesToPush: '$(Build.ArtifactStagingDirectory)/*.nupkg'
publishFeedCredentials: myget-discord

+ 15
- 0
azure/docs.bat View File

@@ -0,0 +1,15 @@
ECHO clone docs-static
git clone git@github.com:discord-net/docs-static.git || EXIT /B 1

ECHO remove old 'latest'
ECHO Y | RMDIR /S docs-static\latest || EXIT /B 1

ECHO build docs
docfx.console\tools\docfx.exe docs/docfx.json -o docs-staging || EXIT /B 1
ROBOCOPY docs-staging\_site docs-static\latest /MIR

ECHO commit and deploy
git config --global user.name "Discord.Net CI Robot" && git config --global user.email "robot@foxbot.me"
git -C docs-static add -A || EXIT /B 1
git -C docs-static commit -m "[ci deploy] %date% %time%: %Build.BuildId%" || EXIT /B 1
git -C docs-static push --force || EXIT /B 1

+ 16
- 0
azure/docs.yml View File

@@ -0,0 +1,16 @@
steps:
- task: InstallSSHKey@0
displayName: Install deploy key for docs
inputs:
knownHostsEntry: '|1|gFD+Dvd+09xvjlKReWSg3wE7q1A=|WJnD0RZ5H4HX5U0nA4Kt+R5yf+w= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ=='
sshPublicKey: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDN1oXiGqKblqfO+vr3cMLSiV6paD5BT+2RXfeCpVkRWSFCB7dfP2m1osJSBqqoCHvJGfbX1brGa+3fnmBgbqQ9vl1NkAmdjHYz4yfTKAt6KShYKXmPpTWBfbAqO2DUzTfTJ18XxNutK931vbWRtOjAMt7Aohw0FYm541QPr2IHIabTvVTPujVExHnMTB9cyKa8xzMD9W3zRLXJbhwOi0LtpgxX6OC/HpwdWod6TfxKdnkPMmVCOo7GTJITyd1GEFg+eNShBIaAZ557nAr8rm2ybEqYvhqFQI0cYMXbfr934yPoNN5yONE1PxDarr1T3GE3ZCWQw2Rc9CAKxrMTez7h
sshKeySecureFile: docs-static_rsa

- task: NuGetCommand@2
displayName: Install DocFx
inputs:
command: custom
arguments: install docfx.console -ExcludeVersion

- script: azure/docs.bat
displayName: Build and deploy docs

+ 40
- 26
docs/CONTRIBUTING.md View File

@@ -1,46 +1,60 @@
# Contributing to Docs

I don't really have any strict conditions for writing documentation,
but just keep these few guidelines in mind:
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.

* Keep code samples in the `guides/samples` folder
* When referencing an object in the API, link to it's page in the
API documentation.
* 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`).
## General Guidelines

### Layout
* 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*

Documentation should be written in a FAQ/Wiki style format.
\* If anyone is interested in translating documentation into other
languages, please open an issue or contact `foxbot#0282` on
Discord.

Recommended reads:
## XML Docstrings Guidelines

* http://docs.microsoft.com
* http://flask.pocoo.org/docs/0.12/
* When using the `<summary>` tag, use concise verbs. For example:

Style consistencies:
```cs
/// <summary> Gets or sets the guild user in this object. </summary>
public IGuildUser GuildUser { get; set; }
```

* Use a ruler set at 70 characters
* 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

Example of long link syntax:

```
```md
Please consult the [API Documentation] for more information.

[API Documentation]: xref:System.String
```

### Compiling

Documentation is compiled into a static site using [DocFx].
We currently use the most recent build off the dev branch.

After making changes, compile your changes into the static site with
`docfx`. You can also view your changes live with `docfx --serve`.
## Recommended Reads

[DocFx]: https://dotnet.github.io/docfx/
* [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)

+ 21
- 0
docs/Discord.Net.Docs.code-workspace View File

@@ -0,0 +1,21 @@
{
"folders": [
{
"path": "."
}
],
"settings": {
"editor.rulers": [
70
],
"files.exclude": {
"**/.git": true,
"**/.svn": true,
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true,
"obj/": true,
"_site/": true,
}
}
}

+ 9
- 10
docs/README.md View File

@@ -1,16 +1,15 @@
# Instructions for Building Documentation

The documentation for the Discord.NET library uses [DocFX][docfx-main]. [Instructions for installing this tool can be found here.][docfx-installing]
The documentation for the Discord.Net library uses [DocFX][docfx-main].
Instructions for installing this tool can be found [here][docfx-installing].

1. Navigate to the root of the repository.
2. (Optional) If you intend to target a specific version, ensure that you
have the correct version checked out.
3. Build the library. Run `dotnet build` in the root of this repository.
Ensure that the build passes without errors.
4. Build the docs using `docfx .\docs\docfx.json`. Add the `--serve` parameter
to preview the site locally. Some elements of the page may appear incorrect
when not hosted by a server.
- Remarks: According to the docfx website, this tool does work on Linux under mono.
2. Build the docs using `docfx docs/docfx.json`. Add the `--serve`
parameter to preview the site locally. Some elements of the page
may appear incorrectly when hosted offline.

Please note that if you intend to target a specific version, ensure
that you have the correct version checked out.

[docfx-main]: https://dotnet.github.io/docfx/
[docfx-installing]: https://dotnet.github.io/docfx/tutorial/docfx_getting_started.html
[docfx-installing]: https://dotnet.github.io/docfx/tutorial/docfx_getting_started.html

+ 31
- 0
docs/_overwrites/Commands/CommandException.Overwrite.md View File

@@ -0,0 +1,31 @@
---
uid: Discord.Commands.CommandException
remarks: *content
---

This @System.Exception class is typically used when diagnosing
an error thrown during the execution of a command. You will find the
thrown exception passed into
[LogMessage.Exception](xref:Discord.LogMessage.Exception), which is
sent to your [CommandService.Log](xref:Discord.Commands.CommandService.Log)
event handler.

---
uid: Discord.Commands.CommandException
example: [*content]
---

You may use this information to handle runtime exceptions after
execution. Below is an example of how you may use this:

```cs
public Task LogHandlerAsync(LogMessage logMessage)
{
// Note that this casting method requires C#7 and up.
if (logMessage?.Exception is CommandException cmdEx)
{
Console.WriteLine($"{cmdEx.GetBaseException().GetType()} was thrown while executing {cmdEx.Command.Aliases.First()} in {cmdEx.Context.Channel} by {cmdEx.Context.User}.");
}
return Task.CompletedTask;
}
```

+ 22
- 0
docs/_overwrites/Commands/DontAutoLoadAttribute.Overwrite.md View File

@@ -0,0 +1,22 @@
---
uid: Discord.Commands.DontAutoLoadAttribute
remarks: *content
---

The attribute can be applied to a public class that inherits
@Discord.Commands.ModuleBase. By applying this attribute,
@Discord.Commands.CommandService.AddModulesAsync* will not discover and
add the marked module to the CommandService.

---
uid: Discord.Commands.DontAutoLoadAttribute
example: [*content]
---

```cs
[DontAutoLoad]
public class MyModule : ModuleBase<SocketCommandContext>
{
// ...
}
```

+ 27
- 0
docs/_overwrites/Commands/DontInjectAttribute.Overwrite.md View File

@@ -0,0 +1,27 @@
---
uid: Discord.Commands.DontInjectAttribute
remarks: *content
---

The attribute can be applied to a public settable property inside a
@Discord.Commands.ModuleBase based class. By applying this attribute,
the marked property will not be automatically injected of the
dependency. See @Guides.Commands.DI to learn more.

---
uid: Discord.Commands.DontInjectAttribute
example: [*content]
---

```cs
public class MyModule : ModuleBase<SocketCommandContext>
{
[DontInject]
public MyService MyService { get; set; }

public MyModule()
{
MyService = new MyService();
}
}
```

+ 5
- 0
docs/_overwrites/Commands/ICommandContext.Inclusion.md View File

@@ -0,0 +1,5 @@
An example of how this class is used the command system can be seen
below:

[!code[Sample module](../../guides/commands/samples/intro/empty-module.cs)]
[!code[Command handler](../../guides/commands/samples/intro/command_handler.cs)]

+ 27
- 0
docs/_overwrites/Commands/ICommandContext.Overwrite.md View File

@@ -0,0 +1,27 @@
---
uid: Discord.Commands.ICommandContext
example: [*content]
---

[!include[Example Section](ICommandContext.Inclusion.md)]

---
uid: Discord.Commands.CommandContext
example: [*content]
---

[!include[Example Section](ICommandContext.Inclusion.md)]

---
uid: Discord.Commands.SocketCommandContext
example: [*content]
---

[!include[Example Section](ICommandContext.Inclusion.md)]

---
uid: Discord.Commands.ShardCommandContext
example: [*content]
---

[!include[Example Section](ICommandContext.Inclusion.md)]

+ 103
- 0
docs/_overwrites/Commands/PreconditionAttribute.Overwrites.md View File

@@ -0,0 +1,103 @@
---
uid: Discord.Commands.PreconditionAttribute
remarks: *content
---

This precondition attribute can be applied on module-level or
method-level for a command.

[!include[Additional Remarks](PreconditionAttribute.Remarks.Inclusion.md)]

---
uid: Discord.Commands.ParameterPreconditionAttribute
remarks: *content
---

This precondition attribute can be applied on parameter-level for a
command.

[!include[Additional Remarks](PreconditionAttribute.Remarks.Inclusion.md)]

---
uid: Discord.Commands.PreconditionAttribute
example: [*content]
---

The following example creates a precondition to see if the user has
sufficient role required to access the command.

```cs
public class RequireRoleAttribute : PreconditionAttribute
{
private readonly ulong _roleId;

public RequireRoleAttribute(ulong roleId)
{
_roleId = roleId;
}

public override async Task<PreconditionResult> CheckPermissionsAsync(ICommandContext context,
CommandInfo command, IServiceProvider services)
{
var guildUser = context.User as IGuildUser;
if (guildUser == null)
return PreconditionResult.FromError("This command cannot be executed outside of a guild.");

var guild = guildUser.Guild;
if (guild.Roles.All(r => r.Id != _roleId))
return PreconditionResult.FromError(
$"The guild does not have the role ({_roleId}) required to access this command.");

return guildUser.RoleIds.Any(rId => rId == _roleId)
? PreconditionResult.FromSuccess()
: PreconditionResult.FromError("You do not have the sufficient role required to access this command.");
}
}
```

---
uid: Discord.Commands.ParameterPreconditionAttribute
example: [*content]
---

The following example creates a precondition on a parameter-level to
see if the targeted user has a lower hierarchy than the user who
executed the command.

```cs
public class RequireHierarchyAttribute : ParameterPreconditionAttribute
{
public override async Task<PreconditionResult> CheckPermissionsAsync(ICommandContext context,
ParameterInfo parameter, object value, IServiceProvider services)
{
// Hierarchy is only available under the socket variant of the user.
if (!(context.User is SocketGuildUser guildUser))
return PreconditionResult.FromError("This command cannot be used outside of a guild.");

SocketGuildUser targetUser;
switch (value)
{
case SocketGuildUser targetGuildUser:
targetUser = targetGuildUser;
break;
case ulong userId:
targetUser = await context.Guild.GetUserAsync(userId).ConfigureAwait(false) as SocketGuildUser;
break;
default:
throw new ArgumentOutOfRangeException();
}

if (targetUser == null)
return PreconditionResult.FromError("Target user not found.");

if (guildUser.Hierarchy < targetUser.Hierarchy)
return PreconditionResult.FromError("You cannot target anyone else whose roles are higher than yours.");

var currentUser = await context.Guild.GetCurrentUserAsync().ConfigureAwait(false) as SocketGuildUser;
if (currentUser?.Hierarchy < targetUser.Hierarchy)
return PreconditionResult.FromError("The bot's role is lower than the targeted user.");

return PreconditionResult.FromSuccess();
}
}
```

+ 6
- 0
docs/_overwrites/Commands/PreconditionAttribute.Remarks.Inclusion.md View File

@@ -0,0 +1,6 @@
A "precondition" in the command system is used to determine if a
condition is met before entering the command task. Using a
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.

+ 29
- 0
docs/_overwrites/Common/DiscordComparers.Overwrites.md View File

@@ -0,0 +1,29 @@
---
uid: Discord.DiscordComparers.ChannelComparer
summary: *content
---
Gets an [IEqualityComparer](xref:System.Collections.Generic.IEqualityComparer`1)<<xref:Discord.IChannel>> to be used to compare channels.

---
uid: Discord.DiscordComparers.GuildComparer
summary: *content
---
Gets an [IEqualityComparer](xref:System.Collections.Generic.IEqualityComparer`1)<<xref:Discord.IGuild>> to be used to compare guilds.

---
uid: Discord.DiscordComparers.MessageComparer
summary: *content
---
Gets an [IEqualityComparer](xref:System.Collections.Generic.IEqualityComparer`1)<<xref:Discord.IMessage>> to be used to compare messages.

---
uid: Discord.DiscordComparers.RoleComparer
summary: *content
---
Gets an [IEqualityComparer](xref:System.Collections.Generic.IEqualityComparer`1)<<xref:Discord.IRole>> to be used to compare roles.

---
uid: Discord.DiscordComparers.UserComparer
summary: *content
---
Gets an [IEqualityComparer](xref:System.Collections.Generic.IEqualityComparer`1)<<xref:Discord.IUser>> to be used to compare users.

+ 69
- 0
docs/_overwrites/Common/EmbedBuilder.Overwrites.md View File

@@ -0,0 +1,69 @@
---
uid: Discord.EmbedBuilder
seealso:
- linkId: Discord.EmbedFooterBuilder
- linkId: Discord.EmbedAuthorBuilder
- linkId: Discord.EmbedFieldBuilder
remarks: *content
---

This builder class is used to build an @Discord.Embed (rich embed)
object that will be ready to be sent via @Discord.IMessageChannel.SendMessageAsync*
after @Discord.EmbedBuilder.Build* is called.

---
uid: Discord.EmbedBuilder
example: [*content]
---

#### Basic Usage

The example below builds an embed and sends it to the chat using the
command system.

```cs
[Command("embed")]
public async Task SendRichEmbedAsync()
{
var embed = new EmbedBuilder
{
// Embed property can be set within object initializer
Title = "Hello world!",
Description = "I am a description set by initializer."
};
// Or with methods
embed.AddField("Field title",
"Field value. I also support [hyperlink markdown](https://example.com)!")
.WithAuthor(Context.Client.CurrentUser)
.WithFooter(footer => footer.Text = "I am a footer.")
.WithColor(Color.Blue)
.WithTitle("I overwrote \"Hello world!\"")
.WithDescription("I am a description.")
.WithUrl("https://example.com")
.WithCurrentTimestamp();
//Your embed needs to be built before it is able to be sent
await ReplyAsync(embed: embed.Build());
}
```

![Embed Example](images/embed-example.png)

#### Usage with Local Images

The example below sends an image and has the image embedded in the rich
embed. See @Discord.IMessageChannel.SendFileAsync* for more information
about uploading a file or image.

```cs
[Command("embedimage")]
public async Task SendEmbedWithImageAsync()
{
var fileName = "image.png";
var embed = new EmbedBuilder()
{
ImageUrl = $"attachment://{fileName}"
}.Build();
await Context.Channel.SendFileAsync(fileName, embed: embed);
}
```

+ 25
- 0
docs/_overwrites/Common/EmbedObjectBuilder.Inclusion.md View File

@@ -0,0 +1,25 @@
The example will build a rich embed with an author field, a footer
field, and 2 normal fields using an @Discord.EmbedBuilder:

```cs
var exampleAuthor = new EmbedAuthorBuilder()
.WithName("I am a bot")
.WithIconUrl("https://discord.com/assets/e05ead6e6ebc08df9291738d0aa6986d.png");
var exampleFooter = new EmbedFooterBuilder()
.WithText("I am a nice footer")
.WithIconUrl("https://discord.com/assets/28174a34e77bb5e5310ced9f95cb480b.png");
var exampleField = new EmbedFieldBuilder()
.WithName("Title of Another Field")
.WithValue("I am an [example](https://example.com).")
.WithInline(true);
var otherField = new EmbedFieldBuilder()
.WithName("Title of a Field")
.WithValue("Notice how I'm inline with that other field next to me.")
.WithInline(true);
var embed = new EmbedBuilder()
.AddField(exampleField)
.AddField(otherField)
.WithAuthor(exampleAuthor)
.WithFooter(exampleFooter)
.Build();
```

+ 20
- 0
docs/_overwrites/Common/EmbedObjectBuilder.Overwrites.md View File

@@ -0,0 +1,20 @@
---
uid: Discord.EmbedAuthorBuilder
example: [*content]
---

[!include[Embed Object Builder Sample](EmbedObjectBuilder.Inclusion.md)]

---
uid: Discord.EmbedFooterBuilder
example: [*content]
---

[!include[Embed Object Builder Sample](EmbedObjectBuilder.Inclusion.md)]

---
uid: Discord.EmbedFieldBuilder
example: [*content]
---

[!include[Embed Object Builder Sample](EmbedObjectBuilder.Inclusion.md)]

+ 26
- 0
docs/_overwrites/Common/IEmote.Inclusion.md View File

@@ -0,0 +1,26 @@
The sample below sends a message and adds an @Discord.Emoji and a custom
@Discord.Emote to the message.

```cs
public async Task SendAndReactAsync(ISocketMessageChannel channel)
{
var message = await channel.SendMessageAsync("I am a message.");

// Creates a Unicode-based emoji based on the Unicode string.
// This is effectively the same as new Emoji("💕").
var heartEmoji = new Emoji("\U0001f495");
// Reacts to the message with the Emoji.
await message.AddReactionAsync(heartEmoji);

// Parses a custom emote based on the provided Discord emote format.
// Please note that this does not guarantee the existence of
// the emote.
var emote = Emote.Parse("<:thonkang:282745590985523200>");
// Reacts to the message with the Emote.
await message.AddReactionAsync(emote);
}
```

#### Result

![React Example](images/react-example.png)

+ 81
- 0
docs/_overwrites/Common/IEmote.Overwrites.md View File

@@ -0,0 +1,81 @@
---
uid: Discord.IEmote
seealso:
- linkId: Discord.Emote
- linkId: Discord.Emoji
- linkId: Discord.GuildEmote
- linkId: Discord.IUserMessage
remarks: *content
---

This interface is often used with reactions. It can represent an
unicode-based @Discord.Emoji, or a custom @Discord.Emote.

---
uid: Discord.Emote
seealso:
- linkId: Discord.IEmote
- linkId: Discord.GuildEmote
- linkId: Discord.Emoji
- linkId: Discord.IUserMessage
remarks: *content
---

> [!NOTE]
> A valid @Discord.Emote format is `<:emoteName:emoteId>`. This can be
> obtained by escaping with a `\` in front of the emote using the
> Discord chat client.

This class represents a custom emoji. This type of emoji can be
created via the @Discord.Emote.Parse* or @Discord.Emote.TryParse*
method.

---
uid: Discord.Emoji
seealso:
- linkId: Discord.Emote
- linkId: Discord.GuildEmote
- linkId: Discord.Emoji
- linkId: Discord.IUserMessage
remarks: *content
---

> [!NOTE]
> A valid @Discord.Emoji format is Unicode-based. This means only
> something like `🙃` or `\U0001f643` would work, instead of
> `:upside_down:`.
>
> A Unicode-based emoji can be obtained by escaping with a `\` in
> front of the emote using the Discord chat client or by looking up on
> [Emojipedia](https://emojipedia.org).

This class represents a standard Unicode-based emoji. This type of emoji
can be created by passing the Unicode into the constructor.

---
uid: Discord.IEmote
example: [*content]
---

[!include[Example Section](IEmote.Inclusion.md)]

---
uid: Discord.Emoji
example: [*content]
---

[!include[Example Section](IEmote.Inclusion.md)]

---
uid: Discord.Emote
example: [*content]
---

[!include[Example Section](IEmote.Inclusion.md)]

---
uid: Discord.GuildEmote
example: [*content]
---

[!include[Example Section](IEmote.Inclusion.md)]

+ 174
- 0
docs/_overwrites/Common/ObjectProperties.Overwrites.md View File

@@ -0,0 +1,174 @@
---
uid: Discord.GuildChannelProperties
example: [*content]
---

The following example uses @Discord.IGuildChannel.ModifyAsync* to
apply changes specified in the properties,

```cs
var channel = _client.GetChannel(id) as IGuildChannel;
if (channel == null) return;

await channel.ModifyAsync(x =>
{
x.Name = "new-name";
x.Position = channel.Position - 1;
});
```

---
uid: Discord.TextChannelProperties
example: [*content]
---

The following example uses @Discord.ITextChannel.ModifyAsync* to
apply changes specified in the properties,

```cs
var channel = _client.GetChannel(id) as ITextChannel;
if (channel == null) return;

await channel.ModifyAsync(x =>
{
x.Name = "cool-guys-only";
x.Topic = "This channel is only for cool guys and adults!!!";
x.Position = channel.Position - 1;
x.IsNsfw = true;
});
```

---
uid: Discord.VoiceChannelProperties
example: [*content]
---

The following example uses @Discord.IVoiceChannel.ModifyAsync* to
apply changes specified in the properties,

```cs
var channel = _client.GetChannel(id) as IVoiceChannel;
if (channel == null) return;

await channel.ModifyAsync(x =>
{
x.UserLimit = 5;
});
```

---
uid: Discord.EmoteProperties
example: [*content]
---

The following example uses @Discord.IGuild.ModifyEmoteAsync* to
apply changes specified in the properties,

```cs
await guild.ModifyEmoteAsync(x =>
{
x.Name = "blobo";
});
```

---
uid: Discord.MessageProperties
example: [*content]
---

The following example uses @Discord.IUserMessage.ModifyAsync* to
apply changes specified in the properties,

```cs
var message = await channel.SendMessageAsync("boo");
await Task.Delay(TimeSpan.FromSeconds(1));
await message.ModifyAsync(x => x.Content = "boi");
```

---
uid: Discord.GuildProperties
example: [*content]
---

The following example uses @Discord.IGuild.ModifyAsync* to
apply changes specified in the properties,

```cs
var guild = _client.GetGuild(id);
if (guild == null) return;

await guild.ModifyAsync(x =>
{
x.Name = "VERY Fast Discord Running at Incredible Hihg Speed";
});
```

---
uid: Discord.RoleProperties
example: [*content]
---

The following example uses @Discord.IRole.ModifyAsync* to
apply changes specified in the properties,

```cs
var role = guild.GetRole(id);
if (role == null) return;

await role.ModifyAsync(x =>
{
x.Name = "cool boi";
x.Color = Color.Gold;
x.Hoist = true;
x.Mentionable = true;
});
```

---
uid: Discord.GuildUserProperties
example: [*content]
---

The following example uses @Discord.IGuildUser.ModifyAsync* to
apply changes specified in the properties,

```cs
var user = guild.GetUser(id);
if (user == null) return;

await user.ModifyAsync(x =>
{
x.Nickname = "I need healing";
});
```

---
uid: Discord.SelfUserProperties
example: [*content]
---

The following example uses @Discord.ISelfUser.ModifyAsync* to
apply changes specified in the properties,

```cs
await selfUser.ModifyAsync(x =>
{
x.Username = "Mercy";
});
```

---
uid: Discord.WebhookProperties
example: [*content]
---

The following example uses @Discord.IWebhook.ModifyAsync* to
apply changes specified in the properties,

```cs
await webhook.ModifyAsync(x =>
{
x.Name = "very fast fox";
x.ChannelId = newChannelId;
});
```

+ 24
- 0
docs/_overwrites/Common/OverrideTypeReaderAttribute.Overwrites.md View File

@@ -0,0 +1,24 @@
---
uid: Discord.Commands.OverrideTypeReaderAttribute
remarks: *content
---

This attribute is used to override a command parameter's type reading
behaviour. This may be useful when you have multiple custom
@Discord.Commands.TypeReader and would like to specify one.

---
uid: Discord.Commands.OverrideTypeReaderAttribute
examples: [*content]
---

The following example will override the @Discord.Commands.TypeReader
of @Discord.IUser to `MyUserTypeReader`.

```cs
public async Task PrintUserAsync(
[OverrideTypeReader(typeof(MyUserTypeReader))] IUser user)
{
//...
}
```

BIN
docs/_overwrites/Common/images/embed-example.png View File

Before After
Width: 334  |  Height: 165  |  Size: 15 KiB

BIN
docs/_overwrites/Common/images/react-example.png View File

Before After
Width: 307  |  Height: 95  |  Size: 8.8 KiB

BIN
docs/_template/description-generator/plugins/DocFX.Plugin.DescriptionGenerator.dll View File


+ 21
- 0
docs/_template/description-generator/plugins/LICENSE View File

@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2018 Still Hsu

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.

+ 29
- 0
docs/_template/last-modified/plugins/LICENSE View File

@@ -0,0 +1,29 @@
MIT License

Copyright (c) 2018 Still Hsu

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.

==============================================================================

Humanizer (https://github.com/Humanizr/Humanizer)
The MIT License (MIT)
Copyright (c) .NET Foundation and Contributors

==============================================================================

BIN
docs/_template/last-modified/plugins/LastModifiedPostProcessor.dll View File


BIN
docs/_template/last-modified/plugins/LibGit2Sharp.dll View File


+ 4
- 0
docs/_template/last-modified/plugins/LibGit2Sharp.dll.config View File

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

BIN
docs/_template/last-modified/plugins/lib/alpine-x64/libgit2-a904fc6.so View File


BIN
docs/_template/last-modified/plugins/lib/alpine-x64/libgit2-ef5a385.so View File


BIN
docs/_template/last-modified/plugins/lib/alpine.3.9-x64/libgit2-ef5a385.so View File


BIN
docs/_template/last-modified/plugins/lib/debian-arm64/libgit2-ef5a385.so View File


BIN
docs/_template/last-modified/plugins/lib/debian.9-x64/libgit2-a904fc6.so View File


BIN
docs/_template/last-modified/plugins/lib/debian.9-x64/libgit2-ef5a385.so View File


BIN
docs/_template/last-modified/plugins/lib/fedora-x64/libgit2-a904fc6.so View File


BIN
docs/_template/last-modified/plugins/lib/fedora-x64/libgit2-ef5a385.so View File


BIN
docs/_template/last-modified/plugins/lib/linux-x64/libgit2-a904fc6.so View File


BIN
docs/_template/last-modified/plugins/lib/linux-x64/libgit2-ef5a385.so View File


BIN
docs/_template/last-modified/plugins/lib/osx/libgit2-a904fc6.dylib View File


BIN
docs/_template/last-modified/plugins/lib/osx/libgit2-ef5a385.dylib View File


BIN
docs/_template/last-modified/plugins/lib/rhel-x64/libgit2-a904fc6.so View File


BIN
docs/_template/last-modified/plugins/lib/rhel-x64/libgit2-ef5a385.so View File


BIN
docs/_template/last-modified/plugins/lib/ubuntu.16.04-arm64/libgit2-ef5a385.so View File


BIN
docs/_template/last-modified/plugins/lib/ubuntu.18.04-x64/libgit2-a904fc6.so View File


BIN
docs/_template/last-modified/plugins/lib/ubuntu.18.04-x64/libgit2-ef5a385.so View File


BIN
docs/_template/last-modified/plugins/lib/win32/x64/git2-a904fc6.dll View File


BIN
docs/_template/last-modified/plugins/lib/win32/x64/git2-ef5a385.dll View File


BIN
docs/_template/last-modified/plugins/lib/win32/x86/git2-a904fc6.dll View File


BIN
docs/_template/last-modified/plugins/lib/win32/x86/git2-ef5a385.dll View File


+ 21
- 0
docs/_template/light-dark-theme/docfx-material-license.md 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.

+ 34
- 0
docs/_template/light-dark-theme/partials/affix.tmpl.partial View File

@@ -0,0 +1,34 @@
{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}

<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
<div class="theme-switch-field">
<p>Theme</p>
<select id="theme-switcher">
<option value="dark">Dark</option>
<option value="gray">Gray</option>
<option value="light">Light</option>
</select>
</div>
{{^_disableContribution}}
<div class="contribution">
<ul class="nav">
{{#docurl}}
<li>
<a href="{{docurl}}" class="contribution-link">{{__global.improveThisDoc}}</a>
</li>
{{/docurl}}
{{#sourceurl}}
<li>
<a href="{{sourceurl}}" class="contribution-link">{{__global.viewSource}}</a>
</li>
{{/sourceurl}}
</ul>
</div>
{{/_disableContribution}}
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<h5>{{__global.inThisArticle}}</h5>
<div></div>
</nav>
</div>
</div>

+ 33
- 0
docs/_template/light-dark-theme/partials/head.tmpl.partial View File

@@ -0,0 +1,33 @@
{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}

<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>{{#title}}{{title}}{{/title}}{{^title}}{{>partials/title}}{{/title}} {{#_appTitle}}| {{_appTitle}} {{/_appTitle}}</title>
<meta name="viewport" content="width=device-width">
<meta property="og:title" content="{{#title}}{{title}}{{/title}}{{^title}}{{>partials/title}}{{/title}} {{#_appTitle}}| {{_appTitle}} {{/_appTitle}}">
{{#_description}}<meta property="og:description" content="{{_description}}">{{/_description}}
<meta property="og:locale" content="en-us">
<meta property="og:type" content="website">
<meta property="og:site_name" content="Discord.Net Docs">
<meta property="og:image" content="https://cdn.jsdelivr.net/gh/discord-net/Discord.Net/docs/marketing/logo/PackageLogo.png">
<meta property="og:image:alt" content="Discord.Net Logo">
<meta name="theme-color" content="#995EA7"/>
<meta name="generator" content="docfx {{_docfxVersion}}">
<meta property="docfx:navrel" content="{{_navRel}}">
<meta property="docfx:tocrel" content="{{_tocRel}}">
<meta id="docfx-style:rel" content="{{_rel}}">
<link rel="preload" href="{{_rel}}styles/search-worker.js" as="script">
<link rel="preload" href="{{_rel}}fonts/glyphicons-halflings-regular.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="shortcut icon" href="{{_rel}}{{{_appFaviconPath}}}{{^_appFaviconPath}}favicon.ico{{/_appFaviconPath}}">
<link rel="stylesheet" href="{{_rel}}styles/docfx.vendor.minify.css">
<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" />
{{#_noindex}}<meta name="searchOption" content="noindex">{{/_noindex}}
{{#_enableSearch}}<meta property="docfx:rel" content="{{_rel}}">{{/_enableSearch}}
{{#_enableNewTab}}<meta property="docfx:newtab" content="true">{{/_enableNewTab}}
</head>

+ 8
- 0
docs/_template/light-dark-theme/partials/scripts.tmpl.partial View File

@@ -0,0 +1,8 @@
{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}

<script type="text/javascript" src="{{_rel}}styles/docfx.vendor.js"></script>
<script type="text/javascript" src="{{_rel}}styles/docfx.js"></script>
<script type="text/javascript" src="{{_rel}}styles/main.js"></script>
<script type="text/javascript" src="{{_rel}}styles/styleswitcher.js"></script>
<script type="text/javascript" src="https://malsup.github.io/jquery.corner.js"></script>
<script type="text/javascript" src="{{_rel}}styles/cornerify.js"></script>

+ 3
- 0
docs/_template/light-dark-theme/styles/cornerify.js View File

@@ -0,0 +1,3 @@
window.onload = function (e) {
$('img').corner();
}

+ 322
- 0
docs/_template/light-dark-theme/styles/dark.css View File

@@ -0,0 +1,322 @@
/* Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information. */

@import url('vs2015.css');
html,
body {
background: #212121;
color: #C0C0C0;
}

h1,
h2,
h3,
h4,
h5,
h6 {
color: #E0E0E0;
}

button,
a {
color: #64B5F6;
}

.sidenav{
background-color: rgb(30, 30, 30);
}

button:hover,
button:focus,
a:hover,
a:focus,
.btn:focus,
.btn:hover{
color: #2196F3;
}

a.disable,
a.disable:hover {
color: #EEEEEE;
}

.divider {
color: #37474F;
}

hr {
border-color: #37474F;
}

.subnav {
background: #383838
}

.inheritance h5,
.inheritedMembers h5 {
border-bottom: 1px solid #37474F;
}

article h4 {
border-bottom: 1px solid #37474F;
}

.docs-search {
background: #424242;
}

.search-results-group-heading {
color: #424242;
}

.search-close {
color: #424242;
}

.sidetoc {
background-color: #1b1b1b;
border-left: 0px solid #37474F;
border-right: 0px solid #37474F;
}

.sideaffix {
overflow: visible;
}

.sideaffix>div.contribution>ul>li>a.contribution-link:hover {
background-color: #333333;
}

/* toc */

.toc .nav>li>a {
color: rgb(218, 218, 218);
}

.toc .nav>li>a:hover,
.toc .nav>li>a:focus {
color: #E0E0E0;
}

.toc .nav>li.active>a {
color: #90CAF9;
}

.toc .nav>li.active>a:hover,
.toc .nav>li.active>a:focus {
background-color: #37474F;
color: #4FC3F7;
}

.sidefilter {
background-color: #1b1b1b;
border-left: 0px solid #37474F;
border-right: 0px solid #37474F;
}

.affix ul>li>a:hover {
background: none;
color: #EEEEEE;
}

.affix ul>li.active>a,
.affix ul>li.active>a:before {
color: #B3E5FC;
}

.affix ul>li>a {
color: #EEEEEE;
}

.affix>ul>li.active>a,
.affix>ul>li.active>a:before {
color: #B3E5FC;
}

.tryspan {
border-color: #37474F;
}

.footer {
border-top: 1px solid #5F5F5F;
background: #616161;
}

/* alert */
.alert-info {
color: #d9edf7;
background: #004458;
border-color: #005873;
}

.alert-warning {
color: #fffaf2;
background: #80551a;
border-color: #99661f;
}

.alert-danger {
color: #fff2f2;
background: #4d0000;
border-color: #660000;
}

/* For tabbed content */

.tabGroup {
margin-top: 1rem;
}

.tabGroup ul[role="tablist"] {
margin: 0;
padding: 0;
list-style: none;
}

.tabGroup ul[role="tablist"]>li {
list-style: none;
display: inline-block;
}

.tabGroup a[role="tab"] {
color: white;
box-sizing: border-box;
display: inline-block;
padding: 5px 7.5px;
text-decoration: none;
border-bottom: 2px solid #fff;
}

.tabGroup a[role="tab"]:hover,
.tabGroup a[role="tab"]:focus,
.tabGroup a[role="tab"][aria-selected="true"] {
border-bottom: 2px solid #607D8B;
}

.tabGroup a[role="tab"][aria-selected="true"] {
color: #81D4FA;
}

.tabGroup a[role="tab"]:hover,
.tabGroup a[role="tab"]:focus {
color: #29B6F6;
}

.tabGroup a[role="tab"]:focus {
outline: 1px solid #607D8B;
outline-offset: -1px;
}

@media (min-width: 768px) {
.tabGroup a[role="tab"] {
padding: 5px 15px;
}
}

.tabGroup section[role="tabpanel"] {
border: 1px solid #607D8B;
padding: 15px;
margin: 0;
overflow: hidden;
}

.tabGroup section[role="tabpanel"]>.codeHeader,
.tabGroup section[role="tabpanel"]>pre {
margin-left: -16px;
margin-right: -16px;
}

.tabGroup section[role="tabpanel"]> :first-child {
margin-top: 0;
}

.tabGroup section[role="tabpanel"]>pre:last-child {
display: block;
margin-bottom: -16px;
}

.mainContainer[dir='rtl'] main ul[role="tablist"] {
margin: 0;
}

/* code */

code {
color: white;
background-color: #4a4c52;
border-radius: 4px;
padding: 3px 7px;
}

pre {
background-color: #282a36;
}

/* table */

.table-striped>tbody>tr:nth-of-type(odd) {
background-color: #333333;
color: #d3d3d3
}

tbody>tr {
background-color: #424242;
color: #c0c0c0
}

.table>tbody+tbody {
border-top: 2px solid rgb(173, 173, 173)
}

/* top navbar */
.navbar-inverse[role="navigation"] {
background-color: #2C2F33;
}

/* select */

select {
background-color: #3b3b3b;
border-color: #2e2e2e;
}

/*
Following code regarding collapse container are fetched
or modified from the Materialize project.

The MIT License (MIT)
Copyright (c) 2014-2018 Materialize
https://github.com/Dogfalo/materialize
*/

/* all collapse container */
.collapse-container.last-modified {
-webkit-box-shadow: 0 2px 2px 0 rgba(50, 50, 50, 0.64), 0 3px 1px -2px rgba(50, 50, 50, 0.62), 0 1px 5px 0 rgba(50, 50, 50, 0.7);
box-shadow: 0 2px 2px 0 rgba(50, 50, 50, 0.64), 0 3px 1px -2px rgba(50, 50, 50, 0.62), 0 1px 5px 0 rgba(50, 50, 50, 0.7);
border-top: 1px solid rgba(96, 96, 96, 0.7);
border-right: 1px solid rgba(96, 96, 96, 0.7);
border-left: 1px solid rgba(96, 96, 96, 0.7);
}

/* header */
.collapse-container.last-modified>:nth-child(odd) {
background-color: #3f3f3f;
border-bottom: 1px solid rgba(96, 96, 96, 0.7);
}

/* body */
.collapse-container.last-modified>:nth-child(even) {
border-bottom: 1px solid rgba(96, 96, 96, 0.7);
background-color: inherit;
}

span.arrow-d{
border-top: 5px solid white
}

span.arrow-r{
border-left: 5px solid white
}

.logo-switcher {
background: url("../marketing/logo/SVG/Combinationmark White.svg") no-repeat;
}

+ 1021
- 0
docs/_template/light-dark-theme/styles/docfx.vendor.minify.css
File diff suppressed because it is too large
View File


+ 324
- 0
docs/_template/light-dark-theme/styles/gray.css View File

@@ -0,0 +1,324 @@
/* Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information. */

@import url('vs2015.css');
html,
body {
background: #23272A;
color: #dddddd;
}

h1,
h2,
h3,
h4,
h5,
h6 {
color: #EEEEEE;
}

button,
a {
color: #64B5F6;
}

.sidenav{
background-color: rgb(30, 30, 30);
}

button:hover,
button:focus,
a:hover,
a:focus,
.btn:focus,
.btn:hover{
color: #2196F3;
}

a.disable,
a.disable:hover {
color: #EEEEEE;
}

.divider {
color: #37474F;
}

hr {
border-color: #37474F;
}

/* top navbar */
/*.navbar-inverse[role="navigation"] {
background-color: #2C2F33;
}*/

/* sub navbar (below top) */
.subnav {
background: rgb(69, 75, 82)
}


.inheritance h5,
.inheritedMembers h5 {
border-bottom: 1px solid #37474F;
}

article h4 {
border-bottom: 1px solid #37474F;
}

.docs-search {
background: #424242;
}

.search-results-group-heading {
color: #424242;
}

.search-close {
color: #424242;
}

.sidetoc {
background-color: #1b1b1b;
border-left: 0px solid #37474F;
border-right: 0px solid #37474F;
}

.sideaffix {
overflow: visible;
}

.sideaffix>div.contribution>ul>li>a.contribution-link:hover {
background-color: #333333;
}

/* toc */

.toc .nav>li>a {
color: rgb(218, 218, 218);
}

.toc .nav>li>a:hover,
.toc .nav>li>a:focus {
color: #E0E0E0;
}

.toc .nav>li.active>a {
color: #90CAF9;
}

.toc .nav>li.active>a:hover,
.toc .nav>li.active>a:focus {
background-color: #37474F;
color: #4FC3F7;
}

.sidefilter {
background-color: #1b1b1b;
border-left: 0px solid #37474F;
border-right: 0px solid #37474F;
}

.affix ul>li>a:hover {
background: none;
color: #EEEEEE;
}

.affix ul>li.active>a,
.affix ul>li.active>a:before {
color: #B3E5FC;
}

.affix ul>li>a {
color: #EEEEEE;
}

.affix>ul>li.active>a,
.affix>ul>li.active>a:before {
color: #B3E5FC;
}

.tryspan {
border-color: #37474F;
}

.footer {
border-top: 1px solid #5F5F5F;
background: #2C2F33;
}

/* alert */
.alert-info {
color: #f3fdff;
background: #40788A;
border-color: #2F7A95;
}

.alert-warning {
color: #fffaf2;
background: #936C36;
border-color: #AE8443;
}

.alert-danger {
color: #fff4f4;
background: #834040;
border-color: #8C2F2F
}

/* For tabbed content */

.tabGroup {
margin-top: 1rem;
}

.tabGroup ul[role="tablist"] {
margin: 0;
padding: 0;
list-style: none;
}

.tabGroup ul[role="tablist"]>li {
list-style: none;
display: inline-block;
}

.tabGroup a[role="tab"] {
color: white;
box-sizing: border-box;
display: inline-block;
padding: 5px 7.5px;
text-decoration: none;
border-bottom: 2px solid #fff;
}

.tabGroup a[role="tab"]:hover,
.tabGroup a[role="tab"]:focus,
.tabGroup a[role="tab"][aria-selected="true"] {
border-bottom: 2px solid #607D8B;
}

.tabGroup a[role="tab"][aria-selected="true"] {
color: #81D4FA;
}

.tabGroup a[role="tab"]:hover,
.tabGroup a[role="tab"]:focus {
color: #29B6F6;
}

.tabGroup a[role="tab"]:focus {
outline: 1px solid #607D8B;
outline-offset: -1px;
}

@media (min-width: 768px) {
.tabGroup a[role="tab"] {
padding: 5px 15px;
}
}

.tabGroup section[role="tabpanel"] {
border: 1px solid #607D8B;
padding: 15px;
margin: 0;
overflow: hidden;
}

.tabGroup section[role="tabpanel"]>.codeHeader,
.tabGroup section[role="tabpanel"]>pre {
margin-left: -16px;
margin-right: -16px;
}

.tabGroup section[role="tabpanel"]> :first-child {
margin-top: 0;
}

.tabGroup section[role="tabpanel"]>pre:last-child {
display: block;
margin-bottom: -16px;
}

.mainContainer[dir='rtl'] main ul[role="tablist"] {
margin: 0;
}

/* code */

code {
color: white;
background-color: #5B646B;
border-radius: 4px;
padding: 3px 7px;
}

pre {
background-color: #282a36;
}

/* table */

.table-striped>tbody>tr:nth-of-type(odd) {
background-color: #333333;
color: #d3d3d3
}

tbody>tr {
background-color: #424242;
color: #c0c0c0
}

.table>tbody+tbody {
border-top: 2px solid rgb(173, 173, 173)
}

/* select */

select {
background-color: #3b3b3b;
border-color: #2e2e2e;
}

/*
Following code regarding collapse container are fetched
or modified from the Materialize project.

The MIT License (MIT)
Copyright (c) 2014-2018 Materialize
https://github.com/Dogfalo/materialize
*/

/* all collapse container */
.collapse-container.last-modified {
-webkit-box-shadow: 0 2px 2px 0 rgba(50, 50, 50, 0.64), 0 3px 1px -2px rgba(50, 50, 50, 0.62), 0 1px 5px 0 rgba(50, 50, 50, 0.7);
box-shadow: 0 2px 2px 0 rgba(50, 50, 50, 0.64), 0 3px 1px -2px rgba(50, 50, 50, 0.62), 0 1px 5px 0 rgba(50, 50, 50, 0.7);
border-top: 1px solid rgba(96, 96, 96, 0.7);
border-right: 1px solid rgba(96, 96, 96, 0.7);
border-left: 1px solid rgba(96, 96, 96, 0.7);
}

/* header */
.collapse-container.last-modified>:nth-child(odd) {
background-color: #3f3f3f;
border-bottom: 1px solid rgba(96, 96, 96, 0.7);
}

/* body */
.collapse-container.last-modified>:nth-child(even) {
border-bottom: 1px solid rgba(96, 96, 96, 0.7);
background-color: inherit;
}

span.arrow-d{
border-top: 5px solid white
}

span.arrow-r{
border-left: 5px solid white
}

.logo-switcher {
background: url("../marketing/logo/SVG/Combinationmark White.svg") no-repeat;
}

+ 117
- 0
docs/_template/light-dark-theme/styles/light.css View File

@@ -0,0 +1,117 @@
/* Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information. */

@import url('tomorrow.css');
html,
body {
background: #fff;
color: #000;
}

.sideaffix {
overflow: visible;
}

/* links */

a:active, a:hover, a:visited {
color: #0078d7;
}

a {
color: #0050c5;
cursor: pointer;
text-decoration: none;
word-wrap: break-word;
}

/* alert */
.alert-info {
color: #165e82;
background-color: #c1e0ef;
border-color: #8cbfd8;
}

.alert-warning {
color: #825e16;
background-color: #efe0c1;
border-color: #d8bf8c;
}

.alert-danger {
color: #821616;
background-color: #efc1c1;
border-color: #d88c8c;
}

/* code */

code {
color: #9c3a3f;
background-color: #ececec;
border-radius: 4px;
padding: 3px 7px;
}

/* table */

.table-striped>tbody>tr:nth-of-type(odd) {
color: #333333;
background-color: #d3d3d3
}

tbody>tr {
color: #424242;
background-color: #c0c0c0
}

.table>tbody+tbody {
border-top: 2px solid rgb(173, 173, 173)
}

/* select */

select {
background-color: #fcfcfc;
border-color: #aeb1b5;
}

/*
Following code regarding collapse container are fetched
or modified from the Materialize project.

The MIT License (MIT)
Copyright (c) 2014-2018 Materialize
https://github.com/Dogfalo/materialize
*/

/* all collapse container */
.collapse-container.last-modified {
-webkit-box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12), 0 1px 5px 0 rgba(0, 0, 0, 0.2);
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12), 0 1px 5px 0 rgba(0, 0, 0, 0.2);
border-top: 1px solid #ddd;
border-right: 1px solid #ddd;
border-left: 1px solid #ddd;
}

/* header */
.collapse-container.last-modified>:nth-child(odd) {
background-color: #fff;
border-bottom: 1px solid #ddd;
}

/* body */
.collapse-container.last-modified>:nth-child(even) {
border-bottom: 1px solid #ddd;
}

span.arrow-d{
border-top: 5px solid black
}

span.arrow-r{
border-left: 5px solid black
}

.logo-switcher {
background: url("../marketing/logo/SVG/Combinationmark.svg") no-repeat;
}

+ 234
- 0
docs/_template/light-dark-theme/styles/master.css View File

@@ -0,0 +1,234 @@
@import url('https://fonts.googleapis.com/css?family=Roboto|Muli|Fira+Mono');

html,
body {
font-family: 'Roboto', 'Segoe UI', Tahoma, Helvetica, sans-serif;
font-display: optional;
height: 100%;
font-size: 15px;
}

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;
max-height: 100px;
width: 38pt;
height: 38pt;
padding: 8pt;
}

p,
li,
.toc {
text-rendering: optimizeLegibility;
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;
margin-top: 15px;
margin-bottom: 15px;
}

.big-logo {
display: block;
box-shadow: none !important;
/* Width value was taken from the original size of the combomark svg */
width: 951pt;
/* Height was arbitrarily determined */
min-height: 100pt;
max-width: 90%;
}

article.content p{
-webkit-transition: all .75s ease-in-out;
transition: all .75s ease-in-out;
}

article.content h1,
article.content h2,
article.content h3,
article.content h4,
article.content h5,
article.content h6{
-webkit-transition: all .25s ease-in-out;
transition: all .25s ease-in-out;
}

.sideaffix {
line-height: 140%;
}

.sideaffix > div.contribution {
margin-bottom: 0;
}

header .navbar {
border-width: 0 0 0px;
border-radius: 0;
}

body .toc {
background-color: inherit;
overflow: visible;
}

select {
display: inline-block;
overflow: auto;
-webkit-box-sizing: border-box;
box-sizing: border-box;
margin: 0;
padding: 0 30px 0 6px;
vertical-align: middle;
height: 28px;
border: 1px solid #e3e3e3;
line-height: 16px;
outline: 0;
text-overflow: ellipsis;
-webkit-appearance: none;
-moz-appearance: none;
cursor: pointer;
background-image: linear-gradient(45deg, transparent 50%, #707070 0), linear-gradient(135deg, #707070 50%, transparent 0);
background-position: calc(100% - 13px) 11px, calc(100% - 8px) 11px;
background-size: 5px 5px, 5px 6px;
background-repeat: no-repeat;
}

/*
Following code are fetched or modified from
the Materialize project.

The MIT License (MIT)
Copyright (c) 2014-2018 Materialize
https://github.com/Dogfalo/materialize
*/

/* all collapse container */

.collapse-container.last-modified {
margin: 0.5rem 0 1rem 0;
}

/* header */

.collapse-container.last-modified>:nth-child(odd):focus {
outline: 0;
}

.collapse-container.last-modified>:nth-child(odd) {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
line-height: 1.5;
padding: 0.75rem;
background-image: none;
border: 0px;
}

/* body */

.collapse-container.last-modified>:nth-child(even) {
display: none;
-webkit-box-sizing: border-box;
box-sizing: border-box;
padding: 1rem;
border: 0px;
}

/* nav bar */

.nav {
margin: 0;
}

.nav li {
-webkit-transition: background-color .3s, color .3s;
transition: background-color .3s, color .3s;
}

.nav a {
-webkit-transition: background-color .3s, color .3s;
transition: background-color .3s, color .3s;
cursor: pointer;
}

/* arrow */

span.arrow-d{
top: 6px; position: relative;
}

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%;
}

+ 199
- 0
docs/_template/light-dark-theme/styles/material.css 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);
}

+ 26
- 0
docs/_template/light-dark-theme/styles/styleswitcher.js View File

@@ -0,0 +1,26 @@
const baseUrl = document.getElementById("docfx-style:rel").content;

function onThemeSelect(event) {
const theme = event.target.value;
window.localStorage.setItem("theme", theme);
window.themeElement.href = getUrl(theme);
}

function getUrl(slug) {
return baseUrl + "styles/" + slug + ".css";
}

const themeElement = document.createElement("link");
themeElement.rel = "stylesheet";

const theme = window.localStorage.getItem("theme") || "light";
themeElement.href = getUrl(theme);

document.head.appendChild(themeElement);
window.themeElement = themeElement;

document.addEventListener("DOMContentLoaded", function() {
const themeSwitcher = document.getElementById("theme-switcher");
themeSwitcher.onchange = onThemeSelect;
themeSwitcher.value = theme;
}, false);

+ 9
- 0
docs/_template/light-dark-theme/styles/theme-switcher.css View File

@@ -0,0 +1,9 @@
div.theme-switch-field {
padding-left: 10px;
padding-bottom: 15px
}

div.theme-switch-field > p{
font-weight: bold;
font-size: 1.2em;
}

+ 72
- 0
docs/_template/light-dark-theme/styles/tomorrow.css View File

@@ -0,0 +1,72 @@
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */

/* Tomorrow Comment */
.hljs-comment,
.hljs-quote {
color: #8e908c;
}

/* Tomorrow Red */
.hljs-variable,
.hljs-template-variable,
.hljs-tag,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class,
.hljs-regexp,
.hljs-deletion {
color: #c82829;
}

/* Tomorrow Orange */
.hljs-number,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params,
.hljs-meta,
.hljs-link {
color: #f5871f;
}

/* Tomorrow Yellow */
.hljs-attribute {
color: #eab700;
}

/* Tomorrow Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet,
.hljs-addition {
color: #718c00;
}

/* Tomorrow Blue */
.hljs-title,
.hljs-section {
color: #4271ae;
}

/* Tomorrow Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #8959a8;
}

.hljs {
display: block;
overflow-x: auto;
background: white;
color: #4d4d4c;
padding: 0.5em;
}

.hljs-emphasis {
font-style: italic;
}

.hljs-strong {
font-weight: bold;
}

+ 115
- 0
docs/_template/light-dark-theme/styles/vs2015.css View File

@@ -0,0 +1,115 @@
/*
* Visual Studio 2015 dark style
* Author: Nicolas LLOBERA <nllobera@gmail.com>
*/

.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #282a36;
color: #DCDCDC;
}

.hljs-keyword,
.hljs-literal,
.hljs-symbol,
.hljs-name {
color: #569CD6;
}
.hljs-link {
color: #569CD6;
text-decoration: underline;
}

.hljs-built_in,
.hljs-type {
color: #4EC9B0;
}

.hljs-number,
.hljs-class {
color: #B8D7A3;
}

.hljs-string,
.hljs-meta-string {
color: #D69D85;
}

.hljs-regexp,
.hljs-template-tag {
color: #9A5334;
}

.hljs-subst,
.hljs-function,
.hljs-title,
.hljs-params,
.hljs-formula {
color: #DCDCDC;
}

.hljs-comment,
.hljs-quote {
color: #57A64A;
font-style: italic;
}

.hljs-doctag {
color: #608B4E;
}

.hljs-meta,
.hljs-meta-keyword,
.hljs-tag {
color: #9B9B9B;
}

.hljs-variable,
.hljs-template-variable {
color: #BD63C5;
}

.hljs-attr,
.hljs-attribute,
.hljs-builtin-name {
color: #9CDCFE;
}

.hljs-section {
color: gold;
}

.hljs-emphasis {
font-style: italic;
}

.hljs-strong {
font-weight: bold;
}

/*.hljs-code {
font-family:'Monospace';
}*/

.hljs-bullet,
.hljs-selector-tag,
.hljs-selector-id,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #D7BA7D;
}

.hljs-addition {
background-color: #144212;
display: inline-block;
width: 100%;
}

.hljs-deletion {
background-color: #600;
display: inline-block;
width: 100%;
}

+ 11
- 8
docs/api/index.md View File

@@ -1,13 +1,16 @@
---
uid: API.Docs
---

# API Documentation

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

__Commonly Used Entities__
# Commonly Used Entities

* @Discord.WebSocket
* @Discord.WebSocket.DiscordSocketClient
* @Discord.WebSocket.SocketGuildChannel
* @Discord.WebSocket.SocketGuildUser
* @Discord.WebSocket.SocketMessage
* @Discord.WebSocket.SocketRole
* @Discord.WebSocket
* @Discord.WebSocket.DiscordSocketClient
* @Discord.WebSocket.SocketGuildChannel
* @Discord.WebSocket.SocketGuildUser
* @Discord.WebSocket.SocketMessage
* @Discord.WebSocket.SocketRole

+ 46
- 57
docs/docfx.json View File

@@ -1,74 +1,63 @@
{
"metadata": [
{
"src": [
{
"src": "..",
"files": [
"src/**/*.cs"
],
"exclude": [
"**/obj/**",
"**/bin/**",
"_site/**"
]
}
],
"dest": "api",
"filter": "filterConfig.yml"
"metadata": [{
"src": [{
"src": "../src",
"files": [
"**.csproj"
]
}],
"dest": "api",
"filter": "filterConfig.yml",
"properties": {
"TargetFramework": "netstandard2.0"
}
],
}],
"build": {
"content": [
"content": [{
"files": ["api/**.yml", "api/index.md"]
},
{
"files": [
"api/**.yml",
"api/index.md"
]
"files": ["toc.yml", "index.md"]
},
{
"files": [
"guides/**.md",
"guides/**/toc.yml",
"toc.yml",
"*.md"
],
"exclude": [
"obj/**",
"_site/**"
]
}
],
"resource": [
"files": ["faq/**.md", "faq/**/toc.yml"]
},
{
"files": [
"**/images/**",
"**/samples/**"
],
"exclude": [
"obj/**",
"_site/**"
]
}
],
"overwrite": [
"files": ["guides/**.md", "guides/**/toc.yml"]
},
{
"files": [
"apidoc/**.md"
],
"exclude": [
"obj/**",
"_site/**"
]
"src": "../",
"files": [ "CHANGELOG.md" ]
}
],
"resource": [{
"files": [
"**/images/**",
"**/samples/**",
"langwordMapping.yml",
"marketing/logo/**.svg",
"marketing/logo/**.png",
"favicon.ico"
]
}],
"dest": "_site",
"template": [
"default"
"default",
"_template/light-dark-theme",
"_template/last-modified",
"_template/description-generator"
],
"postProcessors": ["ExtractSearchIndex", "LastModifiedPostProcessor", "DescriptionPostProcessor"],
"overwrite": "_overwrites/**/**.md",
"globalMetadata": {
"_appFooter": "Discord.Net (c) 2015-2018 2.0.0-beta"
"_appTitle": "Discord.Net Documentation",
"_appFooter": "Discord.Net (c) 2015-2020 2.2.0",
"_enableSearch": true,
"_appLogoPath": "marketing/logo/SVG/Logomark Purple.svg",
"_appFaviconPath": "favicon.ico"
},
"noLangKeyword": false
"xrefService": [
"https://xref.docs.microsoft.com/query?uid={uid}"
]
}
}

+ 123
- 0
docs/faq/basics/basic-operations.md View File

@@ -0,0 +1,123 @@
---
uid: FAQ.Basics.BasicOp
title: Questions about Basic Operations
---

# Basic Operations Questions

In the following section, you will find commonly asked questions and
answers regarding basic usage of the library, as well as
language-specific tips when using this library.

## How should I safely check a type?

> [!WARNING]
> 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.
>
> Please refer to [this post] for more details.

In Discord.Net, the idea of polymorphism is used throughout. You may
need to cast the object as a certain type before you can perform any
action.

A good and safe casting example:

[!code-csharp[Casting](samples/cast.cs)]

[InvalidCastException]: https://docs.microsoft.com/en-us/dotnet/api/system.invalidcastexception
[this post]: https://docs.microsoft.com/en-us/dotnet/csharp/how-to/safely-cast-using-pattern-matching-is-and-as-operators

## How do I send a message?

> [!TIP]
> 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]
method. You can get the channel via [GetChannel] under the client.
Remember, when using Discord.Net, polymorphism is a common recurring
theme. This means an object may take in many shapes or form, which
means casting is your friend. You should attempt to cast the channel
as an [IMessageChannel] or any other entity that implements it to be
able to message.

[SendMessageAsync]: xref:Discord.IMessageChannel.SendMessageAsync*
[GetChannel]: xref:Discord.WebSocket.DiscordSocketClient.GetChannel*

## How can I tell if a message is from X, Y, Z channel?

You may check the message channel type. Visit [Glossary] to see the
various types of channels.

[Glossary]: xref:FAQ.Glossary#message-channels

## How can I get the guild from a message?

There are 2 ways to do this. You can do either of the following,

1. Cast the user as an [IGuildUser] and use its [IGuild] property.
2. Cast the channel as an [IGuildChannel] and use its [IGuild] property.

## How do I add hyperlink text to an embed?

Embeds can use standard [markdown] in the description field as well
as in field values. With that in mind, links can be added with
`[text](link)`.

[markdown]: https://support.discordapp.com/hc/en-us/articles/210298617-Markdown-Text-101-Chat-Formatting-Bold-Italic-Underline-

## How do I add reactions to a message?

Any entity that implements [IUserMessage] has an [AddReactionAsync]
method. This method expects an [IEmote] as a parameter.
In Discord.Net, an Emote represents a custom-image emote, while an
Emoji is a Unicode emoji (standard emoji). Both [Emoji] and [Emote]
implement [IEmote] and are valid options.

# [Adding a reaction to another message](#tab/emoji-others)

[!code-csharp[Emoji](samples/emoji-others.cs)]

# [Adding a reaction to a sent message](#tab/emoji-self)

[!code-csharp[Emoji](samples/emoji-self.cs)]

***

[AddReactionAsync]: xref:Discord.IMessage.AddReactionAsync*

## What is a "preemptive rate limit?"

A preemptive rate limit is Discord.Net's way of telling you to slow
down before you get hit by the real rate limit. Hitting a real rate
limit might prevent your entire client from sending any requests for
a period of time. This is calculated based on the HTTP header
returned by a Discord response.

## Why am I getting so many preemptive rate limits when I try to add more than one reactions?

This is due to how HTML header works, mistreating
0.25sec/action to 1sec. This causes the lib to throw preemptive rate
limit more frequently than it should for methods such as adding
reactions.

## Can I opt-out of preemptive rate limits?

Unfortunately, not at the moment. See [#401](https://github.com/RogueException/Discord.Net/issues/401).

[IChannel]: xref:Discord.IChannel
[ICategoryChannel]: xref:Discord.ICategoryChannel
[IGuildChannel]: xref:Discord.IGuildChannel
[ITextChannel]: xref:Discord.ITextChannel
[IGuild]: xref:Discord.IGuild
[IVoiceChannel]: xref:Discord.IVoiceChannel
[IGuildUser]: xref:Discord.IGuildUser
[IMessageChannel]: xref:Discord.IMessageChannel
[IUserMessage]: xref:Discord.IUserMessage
[IEmote]: xref:Discord.IEmote
[Emote]: xref:Discord.Emote
[Emoji]: xref:Discord.Emoji

+ 94
- 0
docs/faq/basics/client-basics.md View File

@@ -0,0 +1,94 @@
---
uid: FAQ.Basics.ClientBasics
title: Basic Questions about Client
---

# Client Basics Questions

In the following section, you will find commonly asked questions and
answers about common issues that you may face when utilizing the
various clients offered by the library.

## My client keeps returning 401 upon logging in!

> [!WARNING]
> Userbot/selfbot (logging in with a user token) is no
> longer supported with this library starting from 2.0, as
> logging in under a user account may result in account termination.
>
> For more information, see issue [827] & [958], as well as the official
> [Discord API Terms of Service].

There are few possible reasons why this may occur.

1. You are not using the appropriate [TokenType]. If you are using a
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 a token is **different** from a *client secret*.

[TokenType]: xref:Discord.TokenType
[827]: https://github.com/RogueException/Discord.Net/issues/827
[958]: https://github.com/RogueException/Discord.Net/issues/958
[Discord API Terms of Service]: https://discord.com/developers/docs/legal

## How do I do X, Y, Z when my bot connects/logs on? Why do I get a `NullReferenceException` upon calling any client methods after connect?

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

[Ready]: xref:Discord.WebSocket.DiscordSocketClient.Ready
[GuildAvailable]: xref:Discord.WebSocket.BaseSocketClient.GuildAvailable

## 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,
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).

1. Message Cache must be enabled.
2. Hook the MessageUpdated event. This event provides a *before* and
*after* object.
3. Only messages received *after* the bot comes online will be
available in the cache.

[MessageCacheSize]: xref:Discord.WebSocket.DiscordSocketConfig.MessageCacheSize
[DiscordSocketConfig]: xref:Discord.WebSocket.DiscordSocketConfig
[MessageUpdated]: xref:Discord.WebSocket.BaseSocketClient.MessageUpdated

## What is a shard/sharded client, and how is it different from the `DiscordSocketClient`?
As your bot grows in popularity, it is recommended that you should section your bot off into separate processes.
The [DiscordShardedClient] is essentially a class that allows you to easily create and manage multiple [DiscordSocketClient]
instances, with each one serving a different amount of guilds.

There are very few differences from the [DiscordSocketClient] class, and it is very straightforward
to modify your existing code to use a [DiscordShardedClient] when necessary.

1. You need to specify the total amount of shards, or shard ids, via [DiscordShardedClient]'s constructors.
2. The [Connected], [Disconnected], [Ready], and [LatencyUpdated] events
are replaced with [ShardConnected], [ShardDisconnected], [ShardReady], and [ShardLatencyUpdated].
3. Every event handler you apply/remove to the [DiscordShardedClient] is applied/removed to each shard.
If you wish to control a specific shard's events, you can access an individual shard through the `Shards` property.

If you do not wish to use the [DiscordShardedClient] and instead reuse the same [DiscordSocketClient] code and manually shard them,
you can do so by specifying the [ShardId] for the [DiscordSocketConfig] and pass that to the [DiscordSocketClient]'s constructor.

[DiscordSocketClient]: xref:Discord.WebSocket.DiscordSocketClient
[DiscordShardedClient]: xref:Discord.WebSocket.DiscordShardedClient
[Connected]: xref:Discord.WebSocket.DiscordSocketClient.Connected
[Disconnected]: xref:Discord.WebSocket.DiscordSocketClient.Disconnected
[LatencyUpdated]: xref:Discord.WebSocket.DiscordSocketClient.LatencyUpdated
[ShardConnected]: xref:Discord.WebSocket.DiscordShardedClient.ShardConnected
[ShardDisconnected]: xref:Discord.WebSocket.DiscordShardedClient.ShardDisconnected
[ShardReady]: xref:Discord.WebSocket.DiscordShardedClient.ShardReady
[ShardLatencyUpdated]: xref:Discord.WebSocket.DiscordShardedClient.ShardLatencyUpdated
[ShardId]: xref:Discord.WebSocket.DiscordSocketConfig.ShardId

+ 82
- 0
docs/faq/basics/getting-started.md View File

@@ -0,0 +1,82 @@
---
uid: FAQ.Basics.GetStarted
title: Beginner Questions / How to Get Started
---

# Basic Concepts / Getting Started

In this following section, you will find commonly asked questions and
answers about how to get started with Discord.Net, as well as basic
introduction to the Discord API ecosystem.

## 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 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 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?

Each user and object on Discord has its own snowflake ID generated
based on various conditions.

![Snowflake Generation](images/snowflake.png)

Anyone can see the ID; it is public. It is merely used to
identify an object in the Discord ecosystem. Many things in the
Discord ecosystem require an ID to retrieve or identify the said
object.

There are 2 common ways to obtain the said ID.

### [Discord Developer Mode](#tab/dev-mode)

By enabling the developer mode you can right click on most objects
to obtain their snowflake IDs (please note that this may not apply to
all objects, such as role IDs, or DM channel IDs).

![Developer Mode](images/dev-mode.png)

### [Escape Character](#tab/escape-char)

You can escape an object by using `\` in front the object in the
Discord client. For example, when you do `\@Example#1234` in chat,
it will return the user ID of the aforementioned user.

![Escaping mentions](images/mention-escape.png)

***

## How do I get the role ID?

> [!WARNING]
> Right-clicking on the role and copying the ID will **not** work.
> This will only copy the message ID.

Several common ways to do this:

1. (Easiest) Right click on the role either in the Server Settings
or in the user's role list.
![Roles](images/role-copy.png)
2. Make the role mentionable and mention the role, and escape it
using the `\` character in front.
3. Inspect the roles collection within the guild via your debugger.

BIN
docs/faq/basics/images/dev-mode.png View File

Before After
Width: 1366  |  Height: 727  |  Size: 79 KiB

BIN
docs/faq/basics/images/mention-escape.png View File

Before After
Width: 1603  |  Height: 400  |  Size: 19 KiB

BIN
docs/faq/basics/images/role-copy.png View File

Before After
Width: 384  |  Height: 530  |  Size: 16 KiB

BIN
docs/faq/basics/images/snowflake.png View File

Before After
Width: 700  |  Height: 365  |  Size: 71 KiB

+ 15
- 0
docs/faq/basics/samples/cast.cs View File

@@ -0,0 +1,15 @@
public async Task MessageReceivedHandler(SocketMessage msg)
{
// Option 1:
// Using the `as` keyword, which will return `null` if the object isn't the desired type.
var usermsg = msg as SocketUserMessage;
// We bail when the message isn't the desired type.
if (msg == null) return;
// Option 2:
// Using the `is` keyword to cast (C#7 or above only)
if (msg is SocketUserMessage usermsg)
{
// Do things
}
}

+ 18
- 0
docs/faq/basics/samples/emoji-others.cs View File

@@ -0,0 +1,18 @@
// bail if the message is not a user one (system messages cannot have reactions)
var usermsg = msg as IUserMessage;
if (usermsg == null) return;

// standard Unicode emojis
Emoji emoji = new Emoji("👍");
// or
// Emoji emoji = new Emoji("\uD83D\uDC4D");

// custom guild emotes
Emote emote = Emote.Parse("<:dotnet:232902710280716288>");
// using Emote.TryParse may be safer in regards to errors being thrown;
// please note that the method does not verify if the emote exists,
// it simply creates the Emote object for you.

// add the reaction to the message
await usermsg.AddReactionAsync(emoji);
await usermsg.AddReactionAsync(emote);

+ 17
- 0
docs/faq/basics/samples/emoji-self.cs View File

@@ -0,0 +1,17 @@
// capture the message you're sending in a variable
var msg = await channel.SendMessageAsync("This will have reactions added.");

// standard Unicode emojis
Emoji emoji = new Emoji("👍");
// or
// Emoji emoji = new Emoji("\uD83D\uDC4D");

// custom guild emotes
Emote emote = Emote.Parse("<:dotnet:232902710280716288>");
// using Emote.TryParse may be safer in regards to errors being thrown;
// please note that the method does not verify if the emote exists,
// it simply creates the Emote object for you.

// add the reaction to the message
await msg.AddReactionAsync(emoji);
await msg.AddReactionAsync(emote);

+ 54
- 0
docs/faq/commands/dependency-injection.md View File

@@ -0,0 +1,54 @@
---
uid: FAQ.Commands.DI
title: Questions about Dependency Injection with Commands
---

# Dependency-injection-related Questions

In the following section, you will find common questions and answers
to utilizing dependency injection with @Discord.Commands, as well as
common troubleshooting steps regarding DI.

## 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; 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,
as well as how it works in [Discord.Net](xref:Guides.Commands.DI#usage-in-modules).

A brief example of service and dependency injection can be seen below.

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

[Dependency Injection]: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection
[video]: https://www.youtube.com/watch?v=QtDTfn8YxXg

## Why is my `CommandService` complaining about a missing dependency?

If you encounter an error similar to `Failed to create MyModule,
dependency MyExternalDependency was not found.`, you may have
forgotten to add the external dependency to the dependency container.

Starting from Discord.Net 2.0, all dependencies required by each
module must be present when the module is loaded into the
[CommandService]. This means when loading the module, you must pass a
valid [IServiceProvider] with the dependency loaded before the module
can be successfully registered.

For example, if your module, `MyModule`, requests a `DatabaseService`
in its constructor, the `DatabaseService` must be present in the
[IServiceProvider] when registering `MyModule`.

[!code-csharp[Missing Dependencies](samples/missing-dep.cs)]

[IServiceProvider]: xref:System.IServiceProvider
[CommandService]: xref:Discord.Commands.CommandService

+ 147
- 0
docs/faq/commands/general.md View File

@@ -0,0 +1,147 @@
---
uid: FAQ.Commands.General
title: General Questions about Commands
---

# Command-related Questions

In the following section, you will find commonly asked questions and
answered regarding general command usage when using @Discord.Commands.

## 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`*).

If, however, you wish to restrict the commands based on the user's
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
custom preconditions.

[RequireUserPermission]: xref:Discord.Commands.RequireUserPermissionAttribute
[Preconditions Addons]: https://github.com/Joe4evr/Discord.Addons/tree/master/src/Discord.Addons.Preconditions

## Why am I getting an error about `Assembly.GetEntryAssembly`?

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

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

[RemainderAttribute]: xref:Discord.Commands.RemainderAttribute

## Discord.Net keeps saying that a `MessageReceived` handler is blocking the gateway, what should I do?

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.

> [!NOTE]
> In rare cases, runtime errors can also cause blockage, usually
> associated with Mono, which is not supported by this library.

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.

1. `RunMode.Sync`
2. `RunMode.Async`

`Sync` is the default behavior and makes the command to be run on the
same thread as the gateway one. `Async` will spin the task off to a
different thread from the gateway one.

> [!IMPORTANT]
> While specifying `RunMode.Async` allows the command to be spun off
> 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.

You can set the `RunMode` either by specifying it individually via
the `CommandAttribute` or by setting the global default with
the [DefaultRunMode] flag under `CommandServiceConfig`.

# [CommandAttribute](#tab/cmdattrib)

[!code-csharp[Command Attribute](samples/runmode-cmdattrib.cs)]

# [CommandServiceConfig](#tab/cmdconfig)

[!code-csharp[Command Service Config](samples/runmode-cmdconfig.cs)]

***

***

[RunMode]: xref:Discord.Commands.RunMode
[CommandAttribute]: xref:Discord.Commands.CommandAttribute
[DefaultRunMode]: xref:Discord.Commands.CommandServiceConfig.DefaultRunMode

## 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 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 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).
4. Exceptions are swallowed in the `ExecuteAsync` result.

However, there are ways to remedy some of these.

For #3, in Discord.Net 2.0, the library introduces a new event called
[CommandService.CommandExecuted], which is raised whenever the command is executed.
This event will be raised regardless of
the `RunMode` type and will return the appropriate execution result
and the associated @Discord.Commands.CommandInfo if applicable.

For #4, exceptions are caught in [CommandService.Log] event under
[LogMessage.Exception] as [CommandException] and in the
[CommandService.CommandExecuted] event under the [IResult] as
[ExecuteResult.Exception].

[Task.Run]: https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.run
[async state machine]: https://www.red-gate.com/simple-talk/dotnet/net-tools/c-async-what-is-it-and-how-does-it-work/
[ExecuteAsync]: xref:Discord.Commands.CommandService.ExecuteAsync*
[ExecuteResult]: xref:Discord.Commands.ExecuteResult
[RuntimeResult]: xref:Discord.Commands.RuntimeResult
[CommandService.CommandExecuted]: xref:Discord.Commands.CommandService.CommandExecuted
[CommandService.Log]: xref:Discord.Commands.CommandService.Log
[LogMessage.Exception]: xref:Discord.LogMessage.Exception*
[ExecuteResult.Exception]: xref:Discord.Commands.ExecuteResult.Exception*
[CommandException]: xref:Discord.Commands.CommandException
[IResult]: xref:Discord.Commands.IResult

+ 28
- 0
docs/faq/commands/samples/DI.cs View File

@@ -0,0 +1,28 @@
public class MyService
{
public string MyCoolString { get; set; }
}
public class Setup
{
public IServiceProvider BuildProvider() =>
new ServiceCollection()
.AddSingleton<MyService>()
.BuildServiceProvider();
}
public class MyModule : ModuleBase<SocketCommandContext>
{
// Inject via public settable prop
public MyService MyService { get; set; }
// ...or via the module's constructor

// private readonly MyService _myService;
// public MyModule (MyService myService) => _myService = myService;
[Command("string")]
public Task GetOrSetStringAsync(string input)
{
if (string.IsNullOrEmpty(_myService.MyCoolString)) _myService.MyCoolString = input;
return ReplyAsync(_myService.MyCoolString);
}
}

+ 20
- 0
docs/faq/commands/samples/Remainder.cs View File

@@ -0,0 +1,20 @@
// Input:
// !echo Coffee Cake

// Output:
// Coffee Cake
[Command("echo")]
public Task EchoRemainderAsync([Remainder]string text) => ReplyAsync(text);

// Output:
// CommandError.BadArgCount
[Command("echo-hassle")]
public Task EchoAsync(string text) => ReplyAsync(text);

// The message would be seen as having multiple parameters,
// while the method only accepts one.
// 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.,
// !echo "Coffee Cake"

+ 29
- 0
docs/faq/commands/samples/missing-dep.cs View File

@@ -0,0 +1,29 @@
public class MyModule : ModuleBase<SocketCommandContext>
{
private readonly DatabaseService _dbService;
public MyModule(DatabaseService dbService)
=> _dbService = dbService;
}
public class CommandHandler
{
private readonly CommandService _commands;
private readonly IServiceProvider _services;
public CommandHandler(DiscordSocketClient client)
{
_services = new ServiceCollection()
.AddService<CommandService>()
.AddService(client)
// We are missing DatabaseService!
.BuildServiceProvider();
}
public async Task RegisterCommandsAsync()
{
// ...
// The method fails here because DatabaseService is a required
// dependency and cannot be resolved by the dependency
// injection service at runtime since the service is not
// registered in this instance of _services.
await _commands.AddModulesAsync(Assembly.GetEntryAssembly(), _services);
// ...
}
}

+ 7
- 0
docs/faq/commands/samples/runmode-cmdattrib.cs View File

@@ -0,0 +1,7 @@
[Command("process", RunMode = RunMode.Async)]
public async Task ProcessAsync(string input)
{
// Does heavy calculation here.
await Task.Delay(TimeSpan.FromMinute(1));
await ReplyAsync(input);
}

+ 10
- 0
docs/faq/commands/samples/runmode-cmdconfig.cs View File

@@ -0,0 +1,10 @@
public class Setup
{
private readonly CommandService _command;
public Setup()
{
var config = new CommandServiceConfig{ DefaultRunMode = RunMode.Async };
_command = new CommandService(config);
}
}

+ 82
- 0
docs/faq/misc/glossary.md View File

@@ -0,0 +1,82 @@
---
uid: FAQ.Glossary
title: Common Terminologies / Glossary
---

# Glossary

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.

## Common Types

* 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)

[IGuild]: xref:Discord.IGuild
[IChannel]: xref:Discord.IChannel

## Channel Types

### Message Channels
* A **Text Channel** ([ITextChannel]) is a message channel from a
Guild.
* A **DM Channel** ([IDMChannel]) is a message channel from a DM.
* A **Group Channel** ([IGroupChannel]) is a message channel from a
Group.
- This is rarely used due to the bot's inability to join groups.
* A **Private Channel** ([IPrivateChannel]) is a DM or a Group.
* A **Message Channel** ([IMessageChannel]) can be any of the above.

### Misc Channels
* A **Guild Channel** ([IGuildChannel]) is a guild channel in a guild.
- This can be any channels that may exist in a guild.
* A **Voice Channel** ([IVoiceChannel]) is a voice channel in a guild.
* A **Category Channel** ([ICategoryChannel]) (2.0+) is a category that
holds one or more sub-channels.
* A **Nested Channel** ([INestedChannel]) (2.0+) is a channel that can
exist under a category.

[INestedChannel]: xref:Discord.INestedChannel
[IGuildChannel]: xref:Discord.IGuildChannel
[IMessageChannel]: xref:Discord.IMessageChannel
[ITextChannel]: xref:Discord.ITextChannel
[IGroupChannel]: xref:Discord.IGroupChannel
[IDMChannel]: xref:Discord.IDMChannel
[IPrivateChannel]: xref:Discord.IPrivateChannel
[IVoiceChannel]: xref:Discord.IVoiceChannel
[ICategoryChannel]: xref:Discord.ICategoryChannel

## Emoji Types

* An **Emote** ([Emote]) is a custom emote from a guild.
- Example: `<:dotnet:232902710280716288>`
* An **Emoji** ([Emoji]) is a Unicode emoji.
- Example: `👍`

[Emote]: xref:Discord.Emote
[Emoji]: xref:Discord.Emoji

## Activity Types

* A **Game** ([Game]) refers to a user's game activity.
* A **Rich Presence** ([RichGame]) refers to a user's detailed
gameplay status.
- Visit [Rich Presence Intro] on Discord docs for more info.
* A **Streaming Status** ([StreamingGame]) refers to user's activity
for streaming on services such as Twitch.
* A **Spotify Status** ([SpotifyGame]) (2.0+) refers to a user's
activity for listening to a song on Spotify.

[Game]: xref:Discord.Game
[RichGame]: xref:Discord.RichGame
[StreamingGame]: xref:Discord.StreamingGame
[SpotifyGame]: xref:Discord.SpotifyGame
[Rich Presence Intro]: https://discord.com/developers/docs/rich-presence/best-practices

+ 29
- 0
docs/faq/misc/legacy.md View File

@@ -0,0 +1,29 @@
---
uid: FAQ.Legacy
title: Questions about Legacy Versions
---

# Legacy Questions

This section refers to legacy library-related questions that do not
apply to the latest or recent version of the Discord.Net library.

## X, Y, Z does not work! It doesn't return a valid value anymore.

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.

Visit the repo's [release tag] to see the latest public pre-release.

[release tag]: https://github.com/RogueException/Discord.Net/releases

## I came from an earlier version of Discord.Net 1.0, and DependencyMap doesn't seem to exist anymore in the later revision? What happened to it?

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

[DependencyInjection]: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save