diff --git a/Discord.Net.code-workspace b/Discord.Net.code-workspace deleted file mode 100644 index 709eb0e95..000000000 --- a/Discord.Net.code-workspace +++ /dev/null @@ -1,23 +0,0 @@ -{ - "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, - } - } -} \ No newline at end of file diff --git a/Discord.Net.sln b/Discord.Net.sln deleted file mode 100644 index 245515c7c..000000000 --- a/Discord.Net.sln +++ /dev/null @@ -1,198 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27004.2009 -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 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Impls", "Impls", "{288C363D-A636-4EAE-9AC1-4698B641B26E}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Rest", "src\Discord.Net.Rest\Discord.Net.Rest.csproj", "{BFC6DC28-0351-4573-926A-D4124244C04F}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Commands", "src\Discord.Net.Commands\Discord.Net.Commands.csproj", "{078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.WebSocket", "src\Discord.Net.WebSocket\Discord.Net.WebSocket.csproj", "{688FD1D8-7F01-4539-B2E9-F473C5D699C7}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Providers", "Providers", "{B0657AAE-DCC5-4FBF-8E5D-1FB578CF3012}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Providers.WS4Net", "src\Discord.Net.Providers.WS4Net\Discord.Net.Providers.WS4Net.csproj", "{6BDEEC08-417B-459F-9CA3-FF8BAB18CAC7}" -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("{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("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "03_sharded_client", "samples\03_sharded_client\03_sharded_client.csproj", "{9B4C4AFB-3D15-44C6-9E36-12ED625AAA26}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {91E9E7BD-75C9-4E98-84AA-2C271922E5C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {91E9E7BD-75C9-4E98-84AA-2C271922E5C2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {91E9E7BD-75C9-4E98-84AA-2C271922E5C2}.Debug|x64.ActiveCfg = Debug|Any CPU - {91E9E7BD-75C9-4E98-84AA-2C271922E5C2}.Debug|x64.Build.0 = Debug|Any CPU - {91E9E7BD-75C9-4E98-84AA-2C271922E5C2}.Debug|x86.ActiveCfg = Debug|Any CPU - {91E9E7BD-75C9-4E98-84AA-2C271922E5C2}.Debug|x86.Build.0 = Debug|Any CPU - {91E9E7BD-75C9-4E98-84AA-2C271922E5C2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {91E9E7BD-75C9-4E98-84AA-2C271922E5C2}.Release|Any CPU.Build.0 = Release|Any CPU - {91E9E7BD-75C9-4E98-84AA-2C271922E5C2}.Release|x64.ActiveCfg = Release|Any CPU - {91E9E7BD-75C9-4E98-84AA-2C271922E5C2}.Release|x64.Build.0 = Release|Any CPU - {91E9E7BD-75C9-4E98-84AA-2C271922E5C2}.Release|x86.ActiveCfg = Release|Any CPU - {91E9E7BD-75C9-4E98-84AA-2C271922E5C2}.Release|x86.Build.0 = Release|Any CPU - {BFC6DC28-0351-4573-926A-D4124244C04F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BFC6DC28-0351-4573-926A-D4124244C04F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BFC6DC28-0351-4573-926A-D4124244C04F}.Debug|x64.ActiveCfg = Debug|Any CPU - {BFC6DC28-0351-4573-926A-D4124244C04F}.Debug|x64.Build.0 = Debug|Any CPU - {BFC6DC28-0351-4573-926A-D4124244C04F}.Debug|x86.ActiveCfg = Debug|Any CPU - {BFC6DC28-0351-4573-926A-D4124244C04F}.Debug|x86.Build.0 = Debug|Any CPU - {BFC6DC28-0351-4573-926A-D4124244C04F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BFC6DC28-0351-4573-926A-D4124244C04F}.Release|Any CPU.Build.0 = Release|Any CPU - {BFC6DC28-0351-4573-926A-D4124244C04F}.Release|x64.ActiveCfg = Debug|Any CPU - {BFC6DC28-0351-4573-926A-D4124244C04F}.Release|x64.Build.0 = Debug|Any CPU - {BFC6DC28-0351-4573-926A-D4124244C04F}.Release|x86.ActiveCfg = Debug|Any CPU - {BFC6DC28-0351-4573-926A-D4124244C04F}.Release|x86.Build.0 = Debug|Any CPU - {078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.Debug|x64.ActiveCfg = Debug|Any CPU - {078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.Debug|x64.Build.0 = Debug|Any CPU - {078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.Debug|x86.ActiveCfg = Debug|Any CPU - {078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.Debug|x86.Build.0 = Debug|Any CPU - {078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.Release|Any CPU.Build.0 = Release|Any CPU - {078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.Release|x64.ActiveCfg = Debug|Any CPU - {078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.Release|x64.Build.0 = Debug|Any CPU - {078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.Release|x86.ActiveCfg = Debug|Any CPU - {078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.Release|x86.Build.0 = Debug|Any CPU - {688FD1D8-7F01-4539-B2E9-F473C5D699C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {688FD1D8-7F01-4539-B2E9-F473C5D699C7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {688FD1D8-7F01-4539-B2E9-F473C5D699C7}.Debug|x64.ActiveCfg = Debug|Any CPU - {688FD1D8-7F01-4539-B2E9-F473C5D699C7}.Debug|x64.Build.0 = Debug|Any CPU - {688FD1D8-7F01-4539-B2E9-F473C5D699C7}.Debug|x86.ActiveCfg = Debug|Any CPU - {688FD1D8-7F01-4539-B2E9-F473C5D699C7}.Debug|x86.Build.0 = Debug|Any CPU - {688FD1D8-7F01-4539-B2E9-F473C5D699C7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {688FD1D8-7F01-4539-B2E9-F473C5D699C7}.Release|Any CPU.Build.0 = Release|Any CPU - {688FD1D8-7F01-4539-B2E9-F473C5D699C7}.Release|x64.ActiveCfg = Release|Any CPU - {688FD1D8-7F01-4539-B2E9-F473C5D699C7}.Release|x64.Build.0 = Release|Any CPU - {688FD1D8-7F01-4539-B2E9-F473C5D699C7}.Release|x86.ActiveCfg = Release|Any CPU - {688FD1D8-7F01-4539-B2E9-F473C5D699C7}.Release|x86.Build.0 = Release|Any CPU - {6BDEEC08-417B-459F-9CA3-FF8BAB18CAC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6BDEEC08-417B-459F-9CA3-FF8BAB18CAC7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6BDEEC08-417B-459F-9CA3-FF8BAB18CAC7}.Debug|x64.ActiveCfg = Debug|Any CPU - {6BDEEC08-417B-459F-9CA3-FF8BAB18CAC7}.Debug|x64.Build.0 = Debug|Any CPU - {6BDEEC08-417B-459F-9CA3-FF8BAB18CAC7}.Debug|x86.ActiveCfg = Debug|Any CPU - {6BDEEC08-417B-459F-9CA3-FF8BAB18CAC7}.Debug|x86.Build.0 = Debug|Any CPU - {6BDEEC08-417B-459F-9CA3-FF8BAB18CAC7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6BDEEC08-417B-459F-9CA3-FF8BAB18CAC7}.Release|Any CPU.Build.0 = Release|Any CPU - {6BDEEC08-417B-459F-9CA3-FF8BAB18CAC7}.Release|x64.ActiveCfg = Release|Any CPU - {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 - {9AFAB80E-D2D3-4EDB-B58C-BACA78D1EA30}.Debug|x64.Build.0 = Debug|Any CPU - {9AFAB80E-D2D3-4EDB-B58C-BACA78D1EA30}.Debug|x86.ActiveCfg = Debug|Any CPU - {9AFAB80E-D2D3-4EDB-B58C-BACA78D1EA30}.Debug|x86.Build.0 = Debug|Any CPU - {9AFAB80E-D2D3-4EDB-B58C-BACA78D1EA30}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9AFAB80E-D2D3-4EDB-B58C-BACA78D1EA30}.Release|Any CPU.Build.0 = Release|Any CPU - {9AFAB80E-D2D3-4EDB-B58C-BACA78D1EA30}.Release|x64.ActiveCfg = Release|Any CPU - {9AFAB80E-D2D3-4EDB-B58C-BACA78D1EA30}.Release|x64.Build.0 = Release|Any CPU - {9AFAB80E-D2D3-4EDB-B58C-BACA78D1EA30}.Release|x86.ActiveCfg = Release|Any CPU - {9AFAB80E-D2D3-4EDB-B58C-BACA78D1EA30}.Release|x86.Build.0 = Release|Any CPU - {BBA8E7FB-C834-40DC-822F-B112CB7F0140}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BBA8E7FB-C834-40DC-822F-B112CB7F0140}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BBA8E7FB-C834-40DC-822F-B112CB7F0140}.Debug|x64.ActiveCfg = Debug|Any CPU - {BBA8E7FB-C834-40DC-822F-B112CB7F0140}.Debug|x64.Build.0 = Debug|Any CPU - {BBA8E7FB-C834-40DC-822F-B112CB7F0140}.Debug|x86.ActiveCfg = Debug|Any CPU - {BBA8E7FB-C834-40DC-822F-B112CB7F0140}.Debug|x86.Build.0 = Debug|Any CPU - {BBA8E7FB-C834-40DC-822F-B112CB7F0140}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BBA8E7FB-C834-40DC-822F-B112CB7F0140}.Release|Any CPU.Build.0 = Release|Any CPU - {BBA8E7FB-C834-40DC-822F-B112CB7F0140}.Release|x64.ActiveCfg = Release|Any CPU - {BBA8E7FB-C834-40DC-822F-B112CB7F0140}.Release|x64.Build.0 = Release|Any CPU - {BBA8E7FB-C834-40DC-822F-B112CB7F0140}.Release|x86.ActiveCfg = Release|Any CPU - {BBA8E7FB-C834-40DC-822F-B112CB7F0140}.Release|x86.Build.0 = Release|Any CPU - {F2FF84FB-F6AD-47E5-9EE5-18206CAE136E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F2FF84FB-F6AD-47E5-9EE5-18206CAE136E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F2FF84FB-F6AD-47E5-9EE5-18206CAE136E}.Debug|x64.ActiveCfg = Debug|Any CPU - {F2FF84FB-F6AD-47E5-9EE5-18206CAE136E}.Debug|x64.Build.0 = Debug|Any CPU - {F2FF84FB-F6AD-47E5-9EE5-18206CAE136E}.Debug|x86.ActiveCfg = Debug|Any CPU - {F2FF84FB-F6AD-47E5-9EE5-18206CAE136E}.Debug|x86.Build.0 = Debug|Any CPU - {F2FF84FB-F6AD-47E5-9EE5-18206CAE136E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F2FF84FB-F6AD-47E5-9EE5-18206CAE136E}.Release|Any CPU.Build.0 = Release|Any CPU - {F2FF84FB-F6AD-47E5-9EE5-18206CAE136E}.Release|x64.ActiveCfg = Release|Any CPU - {F2FF84FB-F6AD-47E5-9EE5-18206CAE136E}.Release|x64.Build.0 = Release|Any CPU - {F2FF84FB-F6AD-47E5-9EE5-18206CAE136E}.Release|x86.ActiveCfg = Release|Any CPU - {F2FF84FB-F6AD-47E5-9EE5-18206CAE136E}.Release|x86.Build.0 = Release|Any CPU - {4E1F1F40-B1DD-40C9-A4B1-A2046A4C9C76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4E1F1F40-B1DD-40C9-A4B1-A2046A4C9C76}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4E1F1F40-B1DD-40C9-A4B1-A2046A4C9C76}.Debug|x64.ActiveCfg = Debug|Any CPU - {4E1F1F40-B1DD-40C9-A4B1-A2046A4C9C76}.Debug|x64.Build.0 = Debug|Any CPU - {4E1F1F40-B1DD-40C9-A4B1-A2046A4C9C76}.Debug|x86.ActiveCfg = Debug|Any CPU - {4E1F1F40-B1DD-40C9-A4B1-A2046A4C9C76}.Debug|x86.Build.0 = Debug|Any CPU - {4E1F1F40-B1DD-40C9-A4B1-A2046A4C9C76}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4E1F1F40-B1DD-40C9-A4B1-A2046A4C9C76}.Release|Any CPU.Build.0 = Release|Any CPU - {4E1F1F40-B1DD-40C9-A4B1-A2046A4C9C76}.Release|x64.ActiveCfg = Release|Any CPU - {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 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {BFC6DC28-0351-4573-926A-D4124244C04F} = {288C363D-A636-4EAE-9AC1-4698B641B26E} - {078DD7E6-943D-4D09-AFC2-D2BA58B76C9C} = {CC3D4B1C-9DE0-448B-8AE7-F3F1F3EC5C3A} - {688FD1D8-7F01-4539-B2E9-F473C5D699C7} = {288C363D-A636-4EAE-9AC1-4698B641B26E} - {6BDEEC08-417B-459F-9CA3-FF8BAB18CAC7} = {B0657AAE-DCC5-4FBF-8E5D-1FB578CF3012} - {9AFAB80E-D2D3-4EDB-B58C-BACA78D1EA30} = {CC3D4B1C-9DE0-448B-8AE7-F3F1F3EC5C3A} - {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} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {D2404771-EEC8-45F2-9D71-F3373F6C1495} - EndGlobalSection - GlobalSection(CodealikeProperties) = postSolution - SolutionGuid = a45217b4-a401-4dbf-8654-34d2ec034cd9 - EndGlobalSection -EndGlobal diff --git a/Discord.Net.sln.DotSettings b/Discord.Net.sln.DotSettings deleted file mode 100644 index ca75a7f1b..000000000 --- a/Discord.Net.sln.DotSettings +++ /dev/null @@ -1,16 +0,0 @@ - - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True diff --git a/Discord.Net.targets b/Discord.Net.targets deleted file mode 100644 index 410e21cb8..000000000 --- a/Discord.Net.targets +++ /dev/null @@ -1,26 +0,0 @@ - - - 2.0.2 - dev - RogueException - discord;discordapp - https://github.com/RogueException/Discord.Net - http://opensource.org/licenses/MIT - https://github.com/RogueException/Discord.Net/raw/dev/docs/marketing/logo/PackageLogo.png - git - git://github.com/RogueException/Discord.Net - - - $(VersionSuffix)-dev - dev - - - $(VersionSuffix)-$(BuildNumber) - build-$(BuildNumber) - - - $(NoWarn);CS1573;CS1591 - true - true - - diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index ef5f1667e..000000000 --- a/appveyor.yml +++ /dev/null @@ -1,94 +0,0 @@ -version: build-{build} -branches: - only: - - dev -image: -- Visual Studio 2017 -- Ubuntu - -nuget: - disable_publish_on_pr: true -pull_requests: - do_not_increment_build_number: true -# Use the default clone_folder -# Windows: C:\Projects\discord-net -# Ubuntu: /home/appveyor/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: >- - if ($isLinux) - { - # AppVeyor Linux images do not have appveyor-retry, which retries the commands a few times - # until the command exits with code 0. - # So, this is done with a short script. - $code = 0 - $counter = 0 - do - { - dotnet restore Discord.Net.sln -v Minimal /p:BuildNumber="$Env:BUILD" /p:IsTagBuild="$Env:APPVEYOR_REPO_TAG" - $code = $LASTEXITCODE - $counter++ - if ($code -ne 0) - { - # Wait 5s before attempting to run again - Start-sleep -Seconds 5 - } - } - until ($counter -eq 5 -or $code -eq 0) - } - else - { - 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: if ($isWindows) { 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: if ($isWindows) { 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: if ($isWindows) { 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: if ($isWindows) { 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: if ($isWindows) { 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: if ($isWindows) { 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: if ($isWindows) { 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 ($isWindows) - { - 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: if ($isWindows) { 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 - CI_WINDOWS: true -- 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 - CI_WINDOWS: true diff --git a/docs/.gitignore b/docs/.gitignore deleted file mode 100644 index 1d9c17c21..000000000 --- a/docs/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ - -############### -# folder # -############### -/**/DROP/ -/**/TEMP/ -/**/packages/ -/**/bin/ -/**/obj/ -_site \ No newline at end of file diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md deleted file mode 100644 index 8641d377e..000000000 --- a/docs/CONTRIBUTING.md +++ /dev/null @@ -1,35 +0,0 @@ -# Contributing to Docs - -## General Guidelines - -We do not have any strict conditions for writing documentation, -but keep these guidelines in mind: - -* Keep code samples in the `guides/samples` folder -* When referencing an object in the API, link to its page in the - API documentation -* Documentation should be written in an FAQ/Wiki-style format -* Documentation should be written in clear and proper English* - -\* If anyone is interested in translating documentation into other -languages, please open an issue or contact me on -Discord (`foxbot#0282`). - -## Style Consistencies - -* Use a ruler set at 70 characters -* 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 -``` - -## Recommended Reads - -* http://docs.microsoft.com -* http://flask.pocoo.org/docs/0.12/ \ No newline at end of file diff --git a/docs/Discord.Net.Docs.code-workspace b/docs/Discord.Net.Docs.code-workspace deleted file mode 100644 index d9f442869..000000000 --- a/docs/Discord.Net.Docs.code-workspace +++ /dev/null @@ -1,21 +0,0 @@ -{ - "folders": [ - { - "path": "." - } - ], - "settings": { - "editor.rulers": [ - 70 - ], - "files.exclude": { - "**/.git": true, - "**/.svn": true, - "**/.hg": true, - "**/CVS": true, - "**/.DS_Store": true, - "obj/": true, - "_site/": true, - } - } -} \ No newline at end of file diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 4a06dccab..000000000 --- a/docs/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# 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]. - -1. Navigate to the root of the repository. -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 \ No newline at end of file diff --git a/docs/_overwrites/Commands/CommandException.Overwrite.md b/docs/_overwrites/Commands/CommandException.Overwrite.md deleted file mode 100644 index 166a011de..000000000 --- a/docs/_overwrites/Commands/CommandException.Overwrite.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -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; -} -``` \ No newline at end of file diff --git a/docs/_overwrites/Commands/DontAutoLoadAttribute.Overwrite.md b/docs/_overwrites/Commands/DontAutoLoadAttribute.Overwrite.md deleted file mode 100644 index d47980df7..000000000 --- a/docs/_overwrites/Commands/DontAutoLoadAttribute.Overwrite.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -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 -{ - // ... -} -``` \ No newline at end of file diff --git a/docs/_overwrites/Commands/DontInjectAttribute.Overwrite.md b/docs/_overwrites/Commands/DontInjectAttribute.Overwrite.md deleted file mode 100644 index 950d2990c..000000000 --- a/docs/_overwrites/Commands/DontInjectAttribute.Overwrite.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -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 -{ - [DontInject] - public MyService MyService { get; set; } - - public MyModule() - { - MyService = new MyService(); - } -} -``` \ No newline at end of file diff --git a/docs/_overwrites/Commands/ICommandContext.Inclusion.md b/docs/_overwrites/Commands/ICommandContext.Inclusion.md deleted file mode 100644 index 4c1257b23..000000000 --- a/docs/_overwrites/Commands/ICommandContext.Inclusion.md +++ /dev/null @@ -1,5 +0,0 @@ -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)] \ No newline at end of file diff --git a/docs/_overwrites/Commands/ICommandContext.Overwrite.md b/docs/_overwrites/Commands/ICommandContext.Overwrite.md deleted file mode 100644 index d9e50b46d..000000000 --- a/docs/_overwrites/Commands/ICommandContext.Overwrite.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -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)] \ No newline at end of file diff --git a/docs/_overwrites/Commands/PreconditionAttribute.Overwrites.md b/docs/_overwrites/Commands/PreconditionAttribute.Overwrites.md deleted file mode 100644 index 75b9f93a5..000000000 --- a/docs/_overwrites/Commands/PreconditionAttribute.Overwrites.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -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 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 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(); - } -} -``` \ No newline at end of file diff --git a/docs/_overwrites/Commands/PreconditionAttribute.Remarks.Inclusion.md b/docs/_overwrites/Commands/PreconditionAttribute.Remarks.Inclusion.md deleted file mode 100644 index 499cdb0ad..000000000 --- a/docs/_overwrites/Commands/PreconditionAttribute.Remarks.Inclusion.md +++ /dev/null @@ -1,6 +0,0 @@ -A "precondidtion" in the command system is used to determine if a -condition is met before entering the command task. Using a -precondidtion may aid in keeping a well-organized command logic. - -The most common use case being whether a user has sufficient -permission to execute the command. \ No newline at end of file diff --git a/docs/_overwrites/Common/EmbedBuilder.Overwrites.md b/docs/_overwrites/Common/EmbedBuilder.Overwrites.md deleted file mode 100644 index 2dcb1e004..000000000 --- a/docs/_overwrites/Common/EmbedBuilder.Overwrites.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -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() - .Build(); - await ReplyAsync(embed: embed); -} -``` - -![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); -} -``` \ No newline at end of file diff --git a/docs/_overwrites/Common/EmbedObjectBuilder.Inclusion.md b/docs/_overwrites/Common/EmbedObjectBuilder.Inclusion.md deleted file mode 100644 index eac0d9ca5..000000000 --- a/docs/_overwrites/Common/EmbedObjectBuilder.Inclusion.md +++ /dev/null @@ -1,25 +0,0 @@ -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://discordapp.com/assets/e05ead6e6ebc08df9291738d0aa6986d.png"); -var exampleFooter = new EmbedFooterBuilder() - .WithText("I am a nice footer") - .WithIconUrl("https://discordapp.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(); -``` \ No newline at end of file diff --git a/docs/_overwrites/Common/EmbedObjectBuilder.Overwrites.md b/docs/_overwrites/Common/EmbedObjectBuilder.Overwrites.md deleted file mode 100644 index c633c29b1..000000000 --- a/docs/_overwrites/Common/EmbedObjectBuilder.Overwrites.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -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)] \ No newline at end of file diff --git a/docs/_overwrites/Common/IEmote.Inclusion.md b/docs/_overwrites/Common/IEmote.Inclusion.md deleted file mode 100644 index cf93c7eb5..000000000 --- a/docs/_overwrites/Common/IEmote.Inclusion.md +++ /dev/null @@ -1,26 +0,0 @@ -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) \ No newline at end of file diff --git a/docs/_overwrites/Common/IEmote.Overwrites.md b/docs/_overwrites/Common/IEmote.Overwrites.md deleted file mode 100644 index 034533d1d..000000000 --- a/docs/_overwrites/Common/IEmote.Overwrites.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -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)] \ No newline at end of file diff --git a/docs/_overwrites/Common/ObjectProperties.Overwrites.md b/docs/_overwrites/Common/ObjectProperties.Overwrites.md deleted file mode 100644 index e9c365d39..000000000 --- a/docs/_overwrites/Common/ObjectProperties.Overwrites.md +++ /dev/null @@ -1,174 +0,0 @@ ---- -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; -}); -``` \ No newline at end of file diff --git a/docs/_overwrites/Common/OverrideTypeReaderAttribute.Overwrites.md b/docs/_overwrites/Common/OverrideTypeReaderAttribute.Overwrites.md deleted file mode 100644 index 29b547e49..000000000 --- a/docs/_overwrites/Common/OverrideTypeReaderAttribute.Overwrites.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -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) -{ - //... -} -``` \ No newline at end of file diff --git a/docs/_overwrites/Common/images/embed-example.png b/docs/_overwrites/Common/images/embed-example.png deleted file mode 100644 index f23fb4d70..000000000 Binary files a/docs/_overwrites/Common/images/embed-example.png and /dev/null differ diff --git a/docs/_overwrites/Common/images/react-example.png b/docs/_overwrites/Common/images/react-example.png deleted file mode 100644 index 822857d3d..000000000 Binary files a/docs/_overwrites/Common/images/react-example.png and /dev/null differ diff --git a/docs/_template/description-generator/plugins/DocFX.Plugin.DescriptionGenerator.dll b/docs/_template/description-generator/plugins/DocFX.Plugin.DescriptionGenerator.dll deleted file mode 100644 index 644e9220e..000000000 Binary files a/docs/_template/description-generator/plugins/DocFX.Plugin.DescriptionGenerator.dll and /dev/null differ diff --git a/docs/_template/description-generator/plugins/LICENSE b/docs/_template/description-generator/plugins/LICENSE deleted file mode 100644 index eb92c0a03..000000000 --- a/docs/_template/description-generator/plugins/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -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. diff --git a/docs/_template/last-modified/plugins/LICENSE b/docs/_template/last-modified/plugins/LICENSE deleted file mode 100644 index d74703f3d..000000000 --- a/docs/_template/last-modified/plugins/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ -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 - -============================================================================== \ No newline at end of file diff --git a/docs/_template/last-modified/plugins/LastModifiedPostProcessor.dll b/docs/_template/last-modified/plugins/LastModifiedPostProcessor.dll deleted file mode 100644 index 283f45297..000000000 Binary files a/docs/_template/last-modified/plugins/LastModifiedPostProcessor.dll and /dev/null differ diff --git a/docs/_template/last-modified/plugins/LibGit2Sharp.dll b/docs/_template/last-modified/plugins/LibGit2Sharp.dll deleted file mode 100644 index b8e7f4a7b..000000000 Binary files a/docs/_template/last-modified/plugins/LibGit2Sharp.dll and /dev/null differ diff --git a/docs/_template/last-modified/plugins/LibGit2Sharp.dll.config b/docs/_template/last-modified/plugins/LibGit2Sharp.dll.config deleted file mode 100644 index d59fd738f..000000000 --- a/docs/_template/last-modified/plugins/LibGit2Sharp.dll.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/docs/_template/last-modified/plugins/lib/alpine-x64/libgit2-8e0b172.so b/docs/_template/last-modified/plugins/lib/alpine-x64/libgit2-8e0b172.so deleted file mode 100644 index efd678335..000000000 Binary files a/docs/_template/last-modified/plugins/lib/alpine-x64/libgit2-8e0b172.so and /dev/null differ diff --git a/docs/_template/last-modified/plugins/lib/debian.9-x64/libgit2-8e0b172.so b/docs/_template/last-modified/plugins/lib/debian.9-x64/libgit2-8e0b172.so deleted file mode 100644 index b51cf2342..000000000 Binary files a/docs/_template/last-modified/plugins/lib/debian.9-x64/libgit2-8e0b172.so and /dev/null differ diff --git a/docs/_template/last-modified/plugins/lib/fedora-x64/libgit2-8e0b172.so b/docs/_template/last-modified/plugins/lib/fedora-x64/libgit2-8e0b172.so deleted file mode 100644 index 7071c172f..000000000 Binary files a/docs/_template/last-modified/plugins/lib/fedora-x64/libgit2-8e0b172.so and /dev/null differ diff --git a/docs/_template/last-modified/plugins/lib/linux-x64/libgit2-8e0b172.so b/docs/_template/last-modified/plugins/lib/linux-x64/libgit2-8e0b172.so deleted file mode 100644 index 3b678b6ec..000000000 Binary files a/docs/_template/last-modified/plugins/lib/linux-x64/libgit2-8e0b172.so and /dev/null differ diff --git a/docs/_template/last-modified/plugins/lib/osx/libgit2-8e0b172.dylib b/docs/_template/last-modified/plugins/lib/osx/libgit2-8e0b172.dylib deleted file mode 100644 index 517c8135a..000000000 Binary files a/docs/_template/last-modified/plugins/lib/osx/libgit2-8e0b172.dylib and /dev/null differ diff --git a/docs/_template/last-modified/plugins/lib/rhel-x64/libgit2-8e0b172.so b/docs/_template/last-modified/plugins/lib/rhel-x64/libgit2-8e0b172.so deleted file mode 100644 index aac190aaf..000000000 Binary files a/docs/_template/last-modified/plugins/lib/rhel-x64/libgit2-8e0b172.so and /dev/null differ diff --git a/docs/_template/last-modified/plugins/lib/win32/x64/git2-8e0b172.dll b/docs/_template/last-modified/plugins/lib/win32/x64/git2-8e0b172.dll deleted file mode 100644 index 117a78b49..000000000 Binary files a/docs/_template/last-modified/plugins/lib/win32/x64/git2-8e0b172.dll and /dev/null differ diff --git a/docs/_template/last-modified/plugins/lib/win32/x86/git2-8e0b172.dll b/docs/_template/last-modified/plugins/lib/win32/x86/git2-8e0b172.dll deleted file mode 100644 index 7b709023c..000000000 Binary files a/docs/_template/last-modified/plugins/lib/win32/x86/git2-8e0b172.dll and /dev/null differ diff --git a/docs/_template/light-dark-theme/partials/affix.tmpl.partial b/docs/_template/light-dark-theme/partials/affix.tmpl.partial deleted file mode 100644 index aafcdf05b..000000000 --- a/docs/_template/light-dark-theme/partials/affix.tmpl.partial +++ /dev/null @@ -1,33 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - - diff --git a/docs/_template/light-dark-theme/partials/head.tmpl.partial b/docs/_template/light-dark-theme/partials/head.tmpl.partial deleted file mode 100644 index 94670f432..000000000 --- a/docs/_template/light-dark-theme/partials/head.tmpl.partial +++ /dev/null @@ -1,27 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - - - - - {{#title}}{{title}}{{/title}}{{^title}}{{>partials/title}}{{/title}} {{#_appTitle}}| {{_appTitle}} {{/_appTitle}} - - - - {{#_description}}{{/_description}} - - - - - - - - - - - - - - {{#_noindex}}{{/_noindex}} - {{#_enableSearch}}{{/_enableSearch}} - {{#_enableNewTab}}{{/_enableNewTab}} - diff --git a/docs/_template/light-dark-theme/partials/scripts.tmpl.partial b/docs/_template/light-dark-theme/partials/scripts.tmpl.partial deleted file mode 100644 index 1b048feb9..000000000 --- a/docs/_template/light-dark-theme/partials/scripts.tmpl.partial +++ /dev/null @@ -1,10 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - - - - - - - - - \ No newline at end of file diff --git a/docs/_template/light-dark-theme/styles/cornerify.js b/docs/_template/light-dark-theme/styles/cornerify.js deleted file mode 100644 index 4430f2d01..000000000 --- a/docs/_template/light-dark-theme/styles/cornerify.js +++ /dev/null @@ -1,3 +0,0 @@ -window.onload = function (e) { - $('img').corner(); -} diff --git a/docs/_template/light-dark-theme/styles/dark.css b/docs/_template/light-dark-theme/styles/dark.css deleted file mode 100644 index 8ae0049d1..000000000 --- a/docs/_template/light-dark-theme/styles/dark.css +++ /dev/null @@ -1,308 +0,0 @@ -/* 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; -} - -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) -} - -/* 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; -} diff --git a/docs/_template/light-dark-theme/styles/docfx.vendor.minify.css b/docs/_template/light-dark-theme/styles/docfx.vendor.minify.css deleted file mode 100644 index f9eb380d6..000000000 --- a/docs/_template/light-dark-theme/styles/docfx.vendor.minify.css +++ /dev/null @@ -1,1022 +0,0 @@ -@font-face { - font-family: 'Glyphicons Halflings'; - font-display: fallback; - src: url(../fonts/glyphicons-halflings-regular.eot); - src: url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'), url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'), url(../fonts/glyphicons-halflings-regular.woff) format('woff'), url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'), url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg') -} - -body { - margin: 0; -} - -html { - font-family: sans-serif; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; -} - -article, -footer, -header, -nav { - display: block; -} - -a { - background-color: transparent; -} - -a:active, -a:hover { - outline: 0; -} - -strong { - font-weight: 700; -} - -h1 { - margin: .67em 0; -} - -svg:not(:root) { - overflow: hidden; -} - -pre { - overflow: auto; -} - -code, -pre { - font-size: 1em; -} - -button, -input, -select { - margin: 0; - font: inherit; - color: inherit; -} - -.glyphicon { - font-style: normal; -} - -button { - overflow: visible; -} - -button, -select { - text-transform: none; -} - -button { - -webkit-appearance: button; - cursor: pointer; -} - -button::-moz-focus-inner, -input::-moz-focus-inner { - padding: 0; - border: 0; -} - -table { - border-spacing: 0; - border-collapse: collapse; -} - -td, -th { - padding: 0; -} - -@media print { - - pre, - tr { - page-break-inside: avoid; - } - - *, - :after, - :before { - color: #000 !important; - text-shadow: none !important; - background: 0 0 !important; - -webkit-box-shadow: none !important; - box-shadow: none !important; - } - - a, - a:visited { - text-decoration: underline; - } - - a[href]:after { - content: " ("attr(href) ")"; - } - - a[href^="#"]:after { - content: ""; - } - - pre { - border: 1px solid #999; - } - - thead { - display: table-header-group; - } - - h3, - p { - orphans: 3; - widows: 3; - } - - h3 { - page-break-after: avoid; - } - - .navbar { - display: none; - } - - .table { - border-collapse: collapse !important; - } - - .table td, - .table th { - background-color: #fff !important; - } - - .table-bordered td, - .table-bordered th { - border: 1px solid #ddd !important; - } -} - -.collapsing, -.dropdown, -.dropup { - position: relative -} - -.collapsing { - height: 0; - overflow: hidden; - -webkit-transition-timing-function: ease; - -o-transition-timing-function: ease; - transition-timing-function: ease; - -webkit-transition-duration: .35s; - -o-transition-duration: .35s; - transition-duration: .35s; - -webkit-transition-property: height, visibility; - -o-transition-property: height, visibility; - transition-property: height, visibility -} - -.btn, -.btn:active, -.form-control, -.navbar-toggle { - background-image: none; -} - -body { - background-color: #fff; -} - -.glyphicon { - position: relative; - top: 1px; - display: inline-block; - font-family: 'Glyphicons Halflings'; - font-weight: 400; - line-height: 1; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.glyphicon-refresh:before { - content: "\e031"; -} - -.glyphicon-filter:before { - content: "\e138"; -} - -*, -:after, -:before { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -html { - font-size: 10px; - -webkit-tap-highlight-color: transparent; -} - -body { - font-size: 14px; - line-height: 1.42857143; - color: #333; -} - -button, -input, -select { - font-family: inherit; - font-size: inherit; - line-height: inherit; -} - -a { - color: #337ab7; - text-decoration: none; -} - -a:focus, -a:hover { - color: #23527c; - text-decoration: underline; -} - -a:focus { - outline: -webkit-focus-ring-color auto 5px; - outline-offset: -2px; -} - -.sr-only { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip: rect(0, 0, 0, 0); - border: 0; -} - -h1, -h3, -h4, -h5, -h6 { - font-family: inherit; - font-weight: 500; - line-height: 1.1; - color: inherit; -} - -h1, -h3 { - margin-top: 20px; - margin-bottom: 10px; -} - -h4, -h5, -h6 { - margin-top: 10px; - margin-bottom: 10px; -} - -h1 { - font-size: 36px; -} - -h3 { - font-size: 24px; -} - -h4 { - font-size: 18px; -} - -h5 { - font-size: 14px; -} - -h6 { - font-size: 12px; -} - -p { - margin: 0 0 10px; -} - -pre { - line-height: 1.42857143; -} - -.small { - font-size: 85%; -} - -pre code, -table { - background-color: transparent; -} - -ul { - margin-top: 0; -} - -ul ul { - margin-bottom: 0; -} - -ul { - margin-bottom: 10px; -} - -@media (min-width:768px) { - .container { - width: 750px; - } -} - -code { - padding: 2px 4px; - font-size: 90%; -} - -th { - text-align: left; -} - -pre { - display: block; - padding: 9.5px; - margin: 0 0 10px; - font-size: 13px; - word-break: break-all; - word-wrap: break-word; - color: #333; - border: 1px solid #ccc; - border-radius: 4px; -} - -.container { - margin-right: auto; - margin-left: auto; -} - -pre code { - padding: 0; - font-size: inherit; - color: inherit; - white-space: pre-wrap; - border-radius: 0; -} - -.container { - padding-right: 15px; - padding-left: 15px; -} - -@media (min-width:992px) { - .container { - width: 970px; - } -} - -@media (min-width:1200px) { - .container { - width: 1170px; - } -} - -.row { - margin-right: -15px; - margin-left: -15px; -} - -.col-md-10, -.col-md-2 { - position: relative; - min-height: 1px; - padding-right: 15px; - padding-left: 15px; -} - -@media (min-width:992px) { - - .col-md-10, - .col-md-2 { - float: left; - } - - .col-md-10 { - width: 83.33333333%; - } - - .col-md-2 { - width: 16.66666667%; - } -} - -.table { - width: 100%; - max-width: 100%; - margin-bottom: 20px; -} - -.table>tbody>tr>td, -.table>thead>tr>th { - padding: 8px; - line-height: 1.42857143; - vertical-align: top; - border-top: 1px solid #ddd; -} - -.table>thead>tr>th { - vertical-align: bottom; - border-bottom: 2px solid #ddd; -} - -.table>thead:first-child>tr:first-child>th { - border-top: 0; -} - -.table-condensed>tbody>tr>td, -.table-condensed>thead>tr>th { - padding: 5px; -} - -.table-bordered, -.table-bordered>tbody>tr>td, -.table-bordered>thead>tr>th { - border: 1px solid #ddd; -} - -.table-bordered>thead>tr>th { - border-bottom-width: 2px; -} - -.table-striped>tbody>tr:nth-of-type(odd) { - background-color: #f9f9f9; -} - -.table-responsive { - min-height: .01%; - overflow-x: auto; -} - -@media screen and (max-width:767px) { - .table-responsive { - width: 100%; - margin-bottom: 15px; - overflow-y: hidden; - -ms-overflow-style: -ms-autohiding-scrollbar; - border: 1px solid #ddd; - } - - .table-responsive>.table { - margin-bottom: 0; - } - - .table-responsive>.table>tbody>tr>td, - .table-responsive>.table>thead>tr>th { - white-space: nowrap; - } - - .table-responsive>.table-bordered { - border: 0; - } - - .table-responsive>.table-bordered>tbody>tr>td:first-child, - .table-responsive>.table-bordered>thead>tr>th:first-child { - border-left: 0; - } - - .table-responsive>.table-bordered>tbody>tr>td:last-child, - .table-responsive>.table-bordered>thead>tr>th:last-child { - border-right: 0; - } - - .table-responsive>.table-bordered>tbody>tr:last-child>td { - border-bottom: 0; - } -} - -.form-control { - font-size: 14px; - line-height: 1.42857143; - color: #555; - display: block; -} - -.form-control { - width: 100%; - height: 34px; - padding: 6px 12px; - background-color: #fff; - border: 1px solid #ccc; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); - -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; - -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; - transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; -} - -.form-control:focus { - border-color: #66afe9; - outline: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6); -} - -.form-control::-moz-placeholder { - color: #999; - opacity: 1; -} - -.form-control:-ms-input-placeholder { - color: #999; -} - -.form-control::-webkit-input-placeholder { - color: #999; -} - -.form-control::-ms-expand { - background-color: transparent; - border: 0; -} - -.form-group { - margin-bottom: 15px; -} - -.btn { - display: inline-block; - padding: 6px 12px; - margin-bottom: 0; - font-size: 14px; - font-weight: 400; - line-height: 1.42857143; - text-align: center; - white-space: nowrap; - vertical-align: middle; - -ms-touch-action: manipulation; - touch-action: manipulation; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - border: 1px solid transparent; - border-radius: 4px; -} - -.btn:active:focus, -.btn:focus { - outline: -webkit-focus-ring-color auto 5px; - outline-offset: -2px; -} - -.btn:focus, -.btn:hover { - color: #333; - text-decoration: none; -} - -.btn:active { - outline: 0; - -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); - box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); -} - -.collapse { - display: none -} - -.collapse.in { - display: block -} - -.nav>li, -.nav>li>a { - display: block; - position: relative; -} - -.nav { - padding-left: 0; - margin-bottom: 0; - list-style: none; -} - -.nav>li>a { - padding: 10px 15px; -} - -.nav>li>a:focus, -.nav>li>a:hover { - text-decoration: none; - background-color: #eee; -} - -.navbar { - position: relative; - min-height: 50px; - margin-bottom: 20px; - border: 1px solid transparent; -} - -.navbar-collapse { - padding-right: 15px; - padding-left: 15px; - overflow-x: visible; - -webkit-overflow-scrolling: touch; - border-top: 1px solid transparent; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); -} - -@media (min-width:768px) { - .navbar { - border-radius: 4px; - } - - .navbar-header { - float: left; - } - - .navbar-collapse { - width: auto; - border-top: 0; - -webkit-box-shadow: none; - box-shadow: none; - } - - .navbar-collapse.collapse { - display: block !important; - height: auto !important; - padding-bottom: 0; - overflow: visible !important; - } -} - -.container>.navbar-collapse, -.container>.navbar-header { - margin-right: -15px; - margin-left: -15px; -} - -.navbar-brand { - float: left; - height: 50px; - padding: 15px; - font-size: 18px; - line-height: 20px; -} - -.navbar-brand:focus, -.navbar-brand:hover { - text-decoration: none; -} - -@media (min-width:768px) { - - .container>.navbar-collapse, - .container>.navbar-header { - margin-right: 0; - margin-left: 0; - } - - .navbar>.container .navbar-brand { - margin-left: -15px; - } -} - -.navbar-toggle { - position: relative; - float: right; - padding: 9px 10px; - margin-top: 8px; - margin-right: 15px; - margin-bottom: 8px; - background-color: transparent; - border: 1px solid transparent; - border-radius: 4px; -} - -.navbar-toggle:focus { - outline: 0; -} - -.navbar-toggle .icon-bar { - display: block; - width: 22px; - height: 2px; - border-radius: 1px; -} - -.navbar-toggle .icon-bar+.icon-bar { - margin-top: 4px; -} - -.navbar-nav { - margin: 7.5px -15px; -} - -.navbar-nav>li>a { - padding-top: 10px; - padding-bottom: 10px; - line-height: 20px; -} - -@media (min-width:768px) { - .navbar-toggle { - display: none; - } - - .navbar-nav { - float: left; - margin: 0; - } - - .navbar-nav>li { - float: left; - } - - .navbar-nav>li>a { - padding-top: 15px; - padding-bottom: 15px; - } -} - -.navbar-form { - padding: 10px 15px; - border-top: 1px solid transparent; - border-bottom: 1px solid transparent; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); - margin: 8px -15px; -} - -@media (min-width:768px) { - .navbar-form .form-group { - display: inline-block; - } - - .navbar-form .form-group { - margin-bottom: 0; - vertical-align: middle; - } - - .navbar-form .form-control { - display: inline-block; - width: auto; - vertical-align: middle; - } - - .navbar-form { - width: auto; - padding-top: 0; - padding-bottom: 0; - margin-right: 0; - margin-left: 0; - border: 0; - -webkit-box-shadow: none; - box-shadow: none; - } -} - -.breadcrumb>li { - display: inline-block; -} - -@media (max-width:767px) { - .navbar-form .form-group { - margin-bottom: 5px; - } - - .navbar-form .form-group:last-child { - margin-bottom: 0; - } -} - -@media (min-width:768px) { - .navbar-right { - float: right !important; - margin-right: -15px; - } -} - -.navbar-default { - background-color: #f8f8f8; - border-color: #e7e7e7; -} - -.navbar-inverse { - background-color: #222; - border-color: #080808; -} - -.navbar-inverse .navbar-brand { - color: #9d9d9d; -} - -.navbar-inverse .navbar-brand:focus, -.navbar-inverse .navbar-brand:hover { - color: #fff; - background-color: transparent; -} - -.navbar-inverse .navbar-nav>li>a { - color: #9d9d9d; -} - -.navbar-inverse .navbar-nav>li>a:focus, -.navbar-inverse .navbar-nav>li>a:hover { - color: #fff; - background-color: transparent; -} - -.navbar-inverse .navbar-nav>.active>a, -.navbar-inverse .navbar-nav>.active>a:focus, -.navbar-inverse .navbar-nav>.active>a:hover { - color: #fff; - background-color: #080808; -} - -.navbar-inverse .navbar-toggle { - border-color: #333; -} - -.navbar-inverse .navbar-toggle:focus, -.navbar-inverse .navbar-toggle:hover { - background-color: #333; -} - -.navbar-inverse .navbar-toggle .icon-bar { - background-color: #fff; -} - -.navbar-inverse .navbar-collapse, -.navbar-inverse .navbar-form { - border-color: #101010; -} - -.breadcrumb { - padding: 8px 15px; - margin-bottom: 20px; - list-style: none; - background-color: #f5f5f5; - border-radius: 4px; -} - -.breadcrumb>li+li:before { - padding: 0 5px; - color: #ccc; - content: "/\00a0"; -} - -.alert { - margin-bottom: 20px; -} - -.alert { - padding: 15px; - border: 1px solid transparent; - border-radius: 4px; -} - -.alert>p { - margin-bottom: 0; -} - -.container:after, -.container:before, -.nav:after, -.nav:before, -.navbar-collapse:after, -.navbar-collapse:before, -.navbar-header:after, -.navbar-header:before, -.navbar:after, -.navbar:before, -.row:after, -.row:before { - display: table; - content: " "; -} - -.container:after, -.nav:after, -.navbar-collapse:after, -.navbar-header:after, -.navbar:after, -.row:after { - clear: both; -} - -.pull-right { - float: right !important; -} - -.affix { - position: fixed; -} - -@media (max-width:767px) { - .hidden-xs { - display: none !important; - } -} - -@media (min-width:768px) and (max-width:991px) { - .hidden-sm { - display: none !important; - } -} - -@media print { - .hidden-print { - display: none !important; - } -} - -.hide { - display: none !important; -} - -.show { - display: block !important; -} - -.pagination { - display: inline-block; -} - -.pagination { - padding-left: 0; - margin: 20px 0; - border-radius: 4px; -} - -.pagination>li { - display: inline; -} - -.pagination>li>a { - position: relative; - float: left; - padding: 6px 12px; - margin-left: -1px; - line-height: 1.42857143; - color: #337ab7; - text-decoration: none; - background-color: #fff; - border: 1px solid #ddd; -} - -.pagination>li:first-child>a { - margin-left: 0; - border-top-left-radius: 4px; - border-bottom-left-radius: 4px; -} - -.pagination>li:last-child>a { - border-top-right-radius: 4px; - border-bottom-right-radius: 4px; -} - -.pagination>li>a:focus, -.pagination>li>a:hover { - z-index: 2; - color: #23527c; - background-color: #eee; - border-color: #ddd; -} - -.pagination>.active>a, -.pagination>.active>a:focus, -.pagination>.active>a:hover { - z-index: 3; - color: #fff; - cursor: default; - background-color: #337ab7; - border-color: #337ab7; -} - -.pagination>.disabled>a, -.pagination>.disabled>a:focus, -.pagination>.disabled>a:hover { - color: #777; - cursor: not-allowed; - background-color: #fff; - border-color: #ddd; -} diff --git a/docs/_template/light-dark-theme/styles/gray.css b/docs/_template/light-dark-theme/styles/gray.css deleted file mode 100644 index 32ff7d208..000000000 --- a/docs/_template/light-dark-theme/styles/gray.css +++ /dev/null @@ -1,315 +0,0 @@ -/* 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; -} - -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: #282B2F -} - - -.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; -} diff --git a/docs/_template/light-dark-theme/styles/light.css b/docs/_template/light-dark-theme/styles/light.css deleted file mode 100644 index 71910e774..000000000 --- a/docs/_template/light-dark-theme/styles/light.css +++ /dev/null @@ -1,117 +0,0 @@ -/* 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; -} diff --git a/docs/_template/light-dark-theme/styles/master.css b/docs/_template/light-dark-theme/styles/master.css deleted file mode 100644 index e0f7befb5..000000000 --- a/docs/_template/light-dark-theme/styles/master.css +++ /dev/null @@ -1,175 +0,0 @@ -@import url('https://fonts.googleapis.com/css?family=Titillium+Web|Noto+Sans'); - -html, -body { - font-family: 'Titillium Web', 'Segoe UI', Tahoma, Helvetica, sans-serif; - font-display: optional; - height: 100%; - font-size: 15px; - scroll-behavior: smooth; -} - -#logo -{ - max-width: 100px; - max-height: 100px; - width: 38pt; - height: 38pt; - padding: 8pt; -} - -p, -li, -.toc { - text-rendering: optimizeLegibility; - line-height: 160%; -} - -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; -} - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: 'Noto Sans', Verdana, Geneva, Tahoma, sans-serif; - line-height: 130%; -} - -.sideaffix { - line-height: 140%; -} - -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; -} diff --git a/docs/_template/light-dark-theme/styles/plugin-featherlight.js b/docs/_template/light-dark-theme/styles/plugin-featherlight.js deleted file mode 100644 index 2fd056fa0..000000000 --- a/docs/_template/light-dark-theme/styles/plugin-featherlight.js +++ /dev/null @@ -1,37 +0,0 @@ -// MIT License - -// Copyright (c) 2017 Roel Fauconnier - -// 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. - -$(document).ready(function() { - //find all images, but not the logo, and add the lightbox - $('img').not('#logo').each(function(){ - var $img = $(this); - var filename = $img.attr('src') - //add cursor - $img.css('cursor','zoom-in'); - $img.css('cursor','-moz-zoom-in'); - $img.css('cursor','-webkit-zoom-in'); - - //add featherlight - $img.attr('alt', filename); - $img.featherlight(filename); - }); -}); \ No newline at end of file diff --git a/docs/_template/light-dark-theme/styles/styleswitcher.js b/docs/_template/light-dark-theme/styles/styleswitcher.js deleted file mode 100644 index a87b89525..000000000 --- a/docs/_template/light-dark-theme/styles/styleswitcher.js +++ /dev/null @@ -1,26 +0,0 @@ -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); diff --git a/docs/_template/light-dark-theme/styles/theme-switcher.css b/docs/_template/light-dark-theme/styles/theme-switcher.css deleted file mode 100644 index c6e27c93a..000000000 --- a/docs/_template/light-dark-theme/styles/theme-switcher.css +++ /dev/null @@ -1,9 +0,0 @@ -div.theme-switch-field { - padding-left: 10px; - padding-bottom: 15px -} - -div.theme-switch-field > p{ - font-weight: bold; - font-size: 1.2em; -} \ No newline at end of file diff --git a/docs/_template/light-dark-theme/styles/tomorrow.css b/docs/_template/light-dark-theme/styles/tomorrow.css deleted file mode 100644 index 026a62fe3..000000000 --- a/docs/_template/light-dark-theme/styles/tomorrow.css +++ /dev/null @@ -1,72 +0,0 @@ -/* 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; -} diff --git a/docs/_template/light-dark-theme/styles/vs2015.css b/docs/_template/light-dark-theme/styles/vs2015.css deleted file mode 100644 index d8c14a046..000000000 --- a/docs/_template/light-dark-theme/styles/vs2015.css +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Visual Studio 2015 dark style - * Author: Nicolas LLOBERA - */ - -.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%; -} diff --git a/docs/api/.gitignore b/docs/api/.gitignore deleted file mode 100644 index bffdb3075..000000000 --- a/docs/api/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ - -############### -# temp file # -############### -*.yml -.manifest \ No newline at end of file diff --git a/docs/api/index.md b/docs/api/index.md deleted file mode 100644 index c16ca1363..000000000 --- a/docs/api/index.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -uid: API.Docs ---- - -# API Documentation - -This is where you will find documentation for all members and objects in Discord.Net. - -# Commonly Used Entities - -* @Discord.WebSocket -* @Discord.WebSocket.DiscordSocketClient -* @Discord.WebSocket.SocketGuildChannel -* @Discord.WebSocket.SocketGuildUser -* @Discord.WebSocket.SocketMessage -* @Discord.WebSocket.SocketRole \ No newline at end of file diff --git a/docs/docfx.json b/docs/docfx.json deleted file mode 100644 index 5ea6b895b..000000000 --- a/docs/docfx.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "metadata": [{ - "src": [{ - "src": "../src", - "files": [ - "**.csproj" - ] - }], - "dest": "api", - "filter": "filterConfig.yml", - "properties": { - "TargetFramework": "netstandard1.3" - } - }], - "build": { - "content": [{ - "files": ["api/**.yml", "api/index.md"] - }, - { - "files": ["toc.yml", "index.md"] - }, - { - "files": ["faq/**.md", "faq/**/toc.yml"] - }, - { - "files": ["guides/**.md", "guides/**/toc.yml"] - }, - { - "src": "../", - "files": [ "CHANGELOG.md" ] - } - ], - "resource": [{ - "files": [ - "**/images/**", - "**/samples/**", - "langwordMapping.yml", - "marketing/logo/SVG/**.svg", - "favicon.ico" - ] - }], - "dest": "_site", - "template": [ - "default", - "_template/light-dark-theme", - "_template/last-modified", - "_template/description-generator" - ], - "postProcessors": ["ExtractSearchIndex", "LastModifiedPostProcessor", "DescriptionPostProcessor"], - "overwrite": "_overwrites/**/**.md", - "globalMetadata": { - "_appTitle": "Discord.Net Documentation", - "_appFooter": "Discord.Net (c) 2015-2018 2.0.0-beta", - "_enableSearch": true, - "_appLogoPath": "marketing/logo/SVG/Logomark Purple.svg", - "_appFaviconPath": "favicon.ico" - }, - "xrefService": [ - "https://xref.docs.microsoft.com/query?uid={uid}" - ] - } -} diff --git a/docs/faq/basics/basic-operations.md b/docs/faq/basics/basic-operations.md deleted file mode 100644 index 93811977f..000000000 --- a/docs/faq/basics/basic-operations.md +++ /dev/null @@ -1,123 +0,0 @@ ---- -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.IUserMessage.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 \ No newline at end of file diff --git a/docs/faq/basics/client-basics.md b/docs/faq/basics/client-basics.md deleted file mode 100644 index 9377ac2e9..000000000 --- a/docs/faq/basics/client-basics.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -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://discordapp.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 diff --git a/docs/faq/basics/getting-started.md b/docs/faq/basics/getting-started.md deleted file mode 100644 index f38d2cea7..000000000 --- a/docs/faq/basics/getting-started.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -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. Make the role mentionable and mention the role, and escape it - using the `\` character in front. -2. Inspect the roles collection within the guild via your debugger. \ No newline at end of file diff --git a/docs/faq/basics/images/dev-mode.png b/docs/faq/basics/images/dev-mode.png deleted file mode 100644 index fd20b95d1..000000000 Binary files a/docs/faq/basics/images/dev-mode.png and /dev/null differ diff --git a/docs/faq/basics/images/mention-escape.png b/docs/faq/basics/images/mention-escape.png deleted file mode 100644 index 927978061..000000000 Binary files a/docs/faq/basics/images/mention-escape.png and /dev/null differ diff --git a/docs/faq/basics/images/snowflake.png b/docs/faq/basics/images/snowflake.png deleted file mode 100644 index 816a10eee..000000000 Binary files a/docs/faq/basics/images/snowflake.png and /dev/null differ diff --git a/docs/faq/basics/samples/cast.cs b/docs/faq/basics/samples/cast.cs deleted file mode 100644 index 73ef5237f..000000000 --- a/docs/faq/basics/samples/cast.cs +++ /dev/null @@ -1,15 +0,0 @@ -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 - } -} \ No newline at end of file diff --git a/docs/faq/basics/samples/emoji-others.cs b/docs/faq/basics/samples/emoji-others.cs deleted file mode 100644 index dd3e6317f..000000000 --- a/docs/faq/basics/samples/emoji-others.cs +++ /dev/null @@ -1,18 +0,0 @@ -// 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); \ No newline at end of file diff --git a/docs/faq/basics/samples/emoji-self.cs b/docs/faq/basics/samples/emoji-self.cs deleted file mode 100644 index cd4cff171..000000000 --- a/docs/faq/basics/samples/emoji-self.cs +++ /dev/null @@ -1,17 +0,0 @@ -// 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); \ No newline at end of file diff --git a/docs/faq/commands/dependency-injection.md b/docs/faq/commands/dependency-injection.md deleted file mode 100644 index 0a5de3e32..000000000 --- a/docs/faq/commands/dependency-injection.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -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 diff --git a/docs/faq/commands/general.md b/docs/faq/commands/general.md deleted file mode 100644 index de6d48dc1..000000000 --- a/docs/faq/commands/general.md +++ /dev/null @@ -1,147 +0,0 @@ ---- -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 \ No newline at end of file diff --git a/docs/faq/commands/samples/DI.cs b/docs/faq/commands/samples/DI.cs deleted file mode 100644 index ce4454bc2..000000000 --- a/docs/faq/commands/samples/DI.cs +++ /dev/null @@ -1,28 +0,0 @@ -public class MyService -{ - public string MyCoolString { get; set; } -} -public class Setup -{ - public IServiceProvider BuildProvider() => - new ServiceCollection() - .AddSingleton() - .BuildServiceProvider(); -} -public class MyModule : ModuleBase -{ - // 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); - } -} \ No newline at end of file diff --git a/docs/faq/commands/samples/Remainder.cs b/docs/faq/commands/samples/Remainder.cs deleted file mode 100644 index 337fb6e45..000000000 --- a/docs/faq/commands/samples/Remainder.cs +++ /dev/null @@ -1,20 +0,0 @@ -// 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" \ No newline at end of file diff --git a/docs/faq/commands/samples/missing-dep.cs b/docs/faq/commands/samples/missing-dep.cs deleted file mode 100644 index d3fb9085b..000000000 --- a/docs/faq/commands/samples/missing-dep.cs +++ /dev/null @@ -1,29 +0,0 @@ -public class MyModule : ModuleBase -{ - 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() - .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); - // ... - } -} \ No newline at end of file diff --git a/docs/faq/commands/samples/runmode-cmdattrib.cs b/docs/faq/commands/samples/runmode-cmdattrib.cs deleted file mode 100644 index 253acc4a9..000000000 --- a/docs/faq/commands/samples/runmode-cmdattrib.cs +++ /dev/null @@ -1,7 +0,0 @@ -[Command("process", RunMode = RunMode.Async)] -public async Task ProcessAsync(string input) -{ - // Does heavy calculation here. - await Task.Delay(TimeSpan.FromMinute(1)); - await ReplyAsync(input); -} \ No newline at end of file diff --git a/docs/faq/commands/samples/runmode-cmdconfig.cs b/docs/faq/commands/samples/runmode-cmdconfig.cs deleted file mode 100644 index 11d9cc295..000000000 --- a/docs/faq/commands/samples/runmode-cmdconfig.cs +++ /dev/null @@ -1,10 +0,0 @@ -public class Setup -{ - private readonly CommandService _command; - - public Setup() - { - var config = new CommandServiceConfig{ DefaultRunMode = RunMode.Async }; - _command = new CommandService(config); - } -} \ No newline at end of file diff --git a/docs/faq/misc/glossary.md b/docs/faq/misc/glossary.md deleted file mode 100644 index 95bdbaa03..000000000 --- a/docs/faq/misc/glossary.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -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://discordapp.com/developers/docs/rich-presence/best-practices \ No newline at end of file diff --git a/docs/faq/misc/legacy.md b/docs/faq/misc/legacy.md deleted file mode 100644 index 5931579d3..000000000 --- a/docs/faq/misc/legacy.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -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 \ No newline at end of file diff --git a/docs/faq/toc.yml b/docs/faq/toc.yml deleted file mode 100644 index 393e948f6..000000000 --- a/docs/faq/toc.yml +++ /dev/null @@ -1,18 +0,0 @@ -- name: Basic Concepts - items: - - name: Getting Started - topicUid: FAQ.Basics.GetStarted - - name: Basic Operations - topicUid: FAQ.Basics.BasicOp - - name: Client Basics - topicUid: FAQ.Basics.ClientBasics -- name: Commands - items: - - name: General - topicUid: FAQ.Commands.General - - name: Dependency Injection - topicUid: FAQ.Commands.DI -- name: Glossary - topicUid: FAQ.Glossary -- name: Legacy or Upgrade - topicUid: FAQ.Legacy diff --git a/docs/favicon.ico b/docs/favicon.ico deleted file mode 100644 index 34a2cd1ca..000000000 Binary files a/docs/favicon.ico and /dev/null differ diff --git a/docs/filterConfig.yml b/docs/filterConfig.yml deleted file mode 100644 index 410a80d25..000000000 --- a/docs/filterConfig.yml +++ /dev/null @@ -1,7 +0,0 @@ -apiRules: -- exclude: - uidRegex: ^Discord\.Net\..*$ - type: Namespace -- exclude: - uidRegex: ^Discord\.Analyzers$ - type: Namespace \ No newline at end of file diff --git a/docs/guides/commands/dependency-injection.md b/docs/guides/commands/dependency-injection.md deleted file mode 100644 index 5dc5b02d2..000000000 --- a/docs/guides/commands/dependency-injection.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -uid: Guides.Commands.DI -title: Dependency Injection ---- - -# Dependency Injection - -The Command Service is bundled with a very barebone Dependency -Injection service for your convenience. It is recommended that you use -DI when writing your modules. - -## Setup - -1. Create a @Microsoft.Extensions.DependencyInjection.ServiceCollection. -2. Add the dependencies to the service collection that you wish - to use in the modules. -3. Build the service collection into a service provider. -4. Pass the service collection into @Discord.Commands.CommandService.AddModulesAsync* / @Discord.Commands.CommandService.AddModuleAsync* , @Discord.Commands.CommandService.ExecuteAsync* . - -### Example - Setting up Injection - -[!code-csharp[IServiceProvider Setup](samples/dependency-injection/dependency_map_setup.cs)] - -## Usage in Modules - -In the constructor of your module, any parameters will be filled in by -the @System.IServiceProvider that you've passed. - -Any publicly settable properties will also be filled in the same -manner. - -> [!NOTE] -> Annotating a property with a [DontInjectAttribute] attribute will -> prevent the property from being injected. - -> [!NOTE] -> If you accept `CommandService` or `IServiceProvider` as a parameter -> in your constructor or as an injectable property, these entries will -> be filled by the `CommandService` that the module is loaded from and -> the `IServiceProvider` that is passed into it respectively. - -### Example - Injection in Modules - -[!code-csharp[Injection Modules](samples/dependency-injection/dependency_module.cs)] -[!code-csharp[Disallow Dependency Injection](samples/dependency-injection/dependency_module_noinject.cs)] - -[DontInjectAttribute]: xref:Discord.Commands.DontInjectAttribute \ No newline at end of file diff --git a/docs/guides/commands/intro.md b/docs/guides/commands/intro.md deleted file mode 100644 index c815175bd..000000000 --- a/docs/guides/commands/intro.md +++ /dev/null @@ -1,221 +0,0 @@ ---- -uid: Guides.Commands.Intro -title: Introduction to Command Service ---- - -# The Command Service - -[Discord.Commands](xref:Discord.Commands) provides an attribute-based -command parser. - -## Get Started - -To use commands, you must create a [Command Service] and a command -handler. - -Included below is a barebone command handler. You can extend your -command handler as much as you like; however, the below is the bare -minimum. - -> [!NOTE] -> The `CommandService` will optionally accept a [CommandServiceConfig], -> which *does* set a few default values for you. It is recommended to -> look over the properties in [CommandServiceConfig] and their default -> values. - -[!code-csharp[Command Handler](samples/intro/command_handler.cs)] - -[Command Service]: xref:Discord.Commands.CommandService -[CommandServiceConfig]: xref:Discord.Commands.CommandServiceConfig - -## With Attributes - -Starting from 1.0, commands can be defined ahead of time with -attributes, or at runtime with builders. - -For most bots, ahead-of-time commands should be all you need, and this -is the recommended method of defining commands. - -### Modules - -The first step to creating commands is to create a _module_. - -A module is an organizational pattern that allows you to write your -commands in different classes and have them automatically loaded. - -Discord.Net's implementation of "modules" is influenced heavily by the -ASP.NET Core's Controller pattern. This means that the lifetime of a -module instance is only as long as the command is being invoked. - -Before we create a module, it is **crucial** for you to remember that -in order to create a module and have it automatically discovered, -your module must: - -* Be public -* Inherit [ModuleBase] - -By now, your module should look like this: - -[!code-csharp[Empty Module](samples/intro/empty-module.cs)] - -> [!NOTE] -> [ModuleBase] is an `abstract` class, meaning that you may extend it -> or override it as you see fit. Your module may inherit from any -> extension of ModuleBase. - -[IoC]: https://msdn.microsoft.com/en-us/library/ff921087.aspx -[Dependency Injection]: https://msdn.microsoft.com/en-us/library/ff921152.aspx -[ModuleBase]: xref:Discord.Commands.ModuleBase`1 - -### Adding/Creating Commands - -> [!WARNING] -> **Avoid using long-running code** in your modules wherever possible. -> You should **not** be implementing very much logic into your -> modules, instead, outsource to a service for that. -> -> If you are unfamiliar with Inversion of Control, it is recommended -> to read the MSDN article on [IoC] and [Dependency Injection]. - -The next step to creating commands is actually creating the commands. - -For a command to be valid, it **must** have a return type of `Task` -or `Task`. Typically, you might want to mark this -method as `async`, although it is not required. - -Then, flag your command with the [CommandAttribute]. Note that you must -specify a name for this command, except for when it is part of a -[Module Group](#module-groups). - -### Command Parameters - -Adding parameters to a command is done by adding parameters to the -parent `Task`. - -For example: - -* To take an integer as an argument from the user, add `int num`. -* To take a user as an argument from the user, add `IUser user`. -* ...etc. - -Starting from 1.0, a command can accept nearly any type of argument; -a full list of types that are parsed by default can -be found in @Guides.Commands.TypeReaders. - -[CommandAttribute]: xref:Discord.Commands.CommandAttribute - -#### Optional Parameters - -Parameters, by default, are always required. To make a parameter -optional, give it a default value (i.e., `int num = 0`). - -#### Parameters with Spaces - -To accept a comma-separated list, set the parameter to `params Type[]`. - -Should a parameter include spaces, the parameter **must** be -wrapped in quotes. For example, for a command with a parameter -`string food`, you would execute it with -`!favoritefood "Key Lime Pie"`. - -If you would like a parameter to parse until the end of a command, -flag the parameter with the [RemainderAttribute]. This will -allow a user to invoke a command without wrapping a -parameter in quotes. - -[RemainderAttribute]: xref:Discord.Commands.RemainderAttribute - -### Command Overloads - -You may add overloads to your commands, and the command parser will -automatically pick up on it. - -If, for whatever reason, you have two commands which are ambiguous to -each other, you may use the @Discord.Commands.PriorityAttribute to -specify which should be tested before the other. - -The `Priority` attributes are sorted in ascending order; the higher -priority will be called first. - -### Command Context - -Every command can access the execution context through the [Context] -property on [ModuleBase]. `ICommandContext` allows you to access the -message, channel, guild, user, and the underlying Discord client -that the command was invoked from. - -Different types of `Context` may be specified using the generic variant -of [ModuleBase]. When using a [SocketCommandContext], for example, the -properties on this context will already be Socket entities, so you -will not need to cast them. - -To reply to messages, you may also invoke [ReplyAsync], instead of -accessing the channel through the [Context] and sending a message. - -> [!WARNING] -> Contexts should **NOT** be mixed! You cannot have one module that -> uses `CommandContext` and another that uses `SocketCommandContext`. - -[Context]: xref:Discord.Commands.ModuleBase`1.Context -[SocketCommandContext]: xref:Discord.Commands.SocketCommandContext -[ReplyAsync]: xref:Discord.Commands.ModuleBase`1.ReplyAsync* - -> [!TIP] -> At this point, your module should look comparable to this example: -> [!code-csharp[Example Module](samples/intro/module.cs)] - -#### Loading Modules Automatically - -The Command Service can automatically discover all classes in an -`Assembly` that inherit [ModuleBase] and load them. Invoke -[CommandService.AddModulesAsync] to discover modules and -install them. - -To opt a module out of auto-loading, flag it with -[DontAutoLoadAttribute]. - -[DontAutoLoadAttribute]: xref:Discord.Commands.DontAutoLoadAttribute -[CommandService.AddModulesAsync]: xref:Discord.Commands.CommandService.AddModulesAsync* - -#### Loading Modules Manually - -To manually load a module, invoke [CommandService.AddModuleAsync] by -passing in the generic type of your module and optionally, a -service provider. - -[CommandService.AddModuleAsync]: xref:Discord.Commands.CommandService.AddModuleAsync* - -### Module Constructors - -Modules are constructed using @Guides.Commands.DI. Any parameters -that are placed in the Module's constructor must be injected into an -@System.IServiceProvider first. - -> [!TIP] -> Alternatively, you may accept an -> `IServiceProvider` as an argument and extract services yourself, -> although this is discouraged. - -### Module Properties - -Modules with `public` settable properties will have the dependencies -injected after the construction of the module. See @Guides.Commands.DI -to learn more. - -### Module Groups - -Module Groups allow you to create a module where commands are -prefixed. To create a group, flag a module with the -@Discord.Commands.GroupAttribute. - -Module Groups also allow you to create **nameless Commands**, where -the [CommandAttribute] is configured with no name. In this case, the -command will inherit the name of the group it belongs to. - -### Submodules - -Submodules are "modules" that reside within another one. Typically, -submodules are used to create nested groups (although not required to -create nested groups). - -[!code-csharp[Groups and Submodules](samples/intro/groups.cs)] \ No newline at end of file diff --git a/docs/guides/commands/post-execution.md b/docs/guides/commands/post-execution.md deleted file mode 100644 index 782d256b2..000000000 --- a/docs/guides/commands/post-execution.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -uid: Guides.Commands.PostExecution -title: Post-command Execution Handling ---- - -# Post-execution Handling for Commands - -When developing commands, you may want to consider building a -post-execution handling system so you can have finer control -over commands. Discord.Net offers several post-execution workflows -for you to work with. - -If you recall, in the [Command Guide], we have shown the following -example for executing and handling commands, - -[!code[Command Handler](samples/intro/command_handler.cs)] - -You may notice that after we perform [ExecuteAsync], we store the -result and print it to the chat, essentially creating the most -fundamental form of a post-execution handler. - -With this in mind, we could start doing things like the following, - -[!code[Basic Command Handler](samples/post-execution/post-execution_basic.cs)] - -However, this may not always be preferred, because you are -creating your post-execution logic *with* the essential command -handler. This design could lead to messy code and could potentially -be a violation of the SRP (Single Responsibility Principle). - -Another major issue is if your command is marked with -`RunMode.Async`, [ExecuteAsync] will **always** return a successful -[ExecuteResult] instead of the actual result. You can learn more -about the impact in @FAQ.Commands.General. - -## CommandExecuted Event - -Enter [CommandExecuted], an event that was introduced in -Discord.Net 2.0. This event is raised whenever a command is -executed regardless of its execution status. This means this -event can be used to streamline your post-execution design, -is not prone to `RunMode.Async`'s [ExecuteAsync] drawbacks. - -Thus, we can begin working on code such as: - -[!code[CommandExecuted demo](samples/post-execution/command_executed_demo.cs)] - -So now we have a streamlined post-execution pipeline, great! What's -next? We can take this further by using [RuntimeResult]. - -### RuntimeResult - -`RuntimeResult` was initially introduced in 1.0 to allow -developers to centralize their command result logic. -In other words, it is a result type that is designed to be -returned when the command has finished its execution. - -However, it wasn't widely adopted due to the aforementioned -[ExecuteAsync] drawback. Since we now have access to a proper -result-handler via the [CommandExecuted] event, we can start -making use of this class. - -The best way to make use of it is to create your version of -`RuntimeResult`. You can achieve this by inheriting the `RuntimeResult` -class. - -The following creates a bare-minimum required for a sub-class -of `RuntimeResult`, - -[!code[Base Use](samples/post-execution/customresult_base.cs)] - -The sky is the limit from here. You can add any additional information -you would like regarding the execution result. - -For example, you may want to add your result type or other -helpful information regarding the execution, or something -simple like static methods to help you create return types easily. - -[!code[Extended Use](samples/post-execution/customresult_extended.cs)] - -After you're done creating your [RuntimeResult], you can -implement it in your command by marking the command return type to -`Task`. - -> [!NOTE] -> You must mark the return type as `Task` instead of -> `Task`. Only the former will be picked up when -> building the module. - -Here's an example of a command that utilizes such logic: - -[!code[Usage](samples/post-execution/customresult_usage.cs)] - -And now we can check for it in our [CommandExecuted] handler: - -[!code[Usage](samples/post-execution/command_executed_adv_demo.cs)] - -## CommandService.Log Event - -We have so far covered the handling of various result types, but we -have not talked about what to do if the command enters a catastrophic -failure (i.e., exceptions). To resolve this, we can make use of the -[CommandService.Log] event. - -All exceptions thrown during a command execution are caught and sent -to the Log event under the [LogMessage.Exception] property -as a [CommandException] type. The [CommandException] class allows -us to access the exception thrown, as well as the context -of the command. - -[!code[Logger Sample](samples/post-execution/command_exception_log.cs)] - -[CommandException]: xref:Discord.Commands.CommandException -[LogMessage.Exception]: xref:Discord.LogMessage.Exception -[CommandService.Log]: xref:Discord.Commands.CommandService.Log -[RuntimeResult]: xref:Discord.Commands.RuntimeResult -[CommandExecuted]: xref:Discord.Commands.CommandService.CommandExecuted -[ExecuteAsync]: xref:Discord.Commands.CommandService.ExecuteAsync* -[ExecuteResult]: xref:Discord.Commands.ExecuteResult -[Command Guide]: xref:Guides.Commands.Intro \ No newline at end of file diff --git a/docs/guides/commands/preconditions.md b/docs/guides/commands/preconditions.md deleted file mode 100644 index 8e8298b86..000000000 --- a/docs/guides/commands/preconditions.md +++ /dev/null @@ -1,83 +0,0 @@ ---- -uid: Guides.Commands.Preconditions -title: Preconditions ---- - -# Preconditions - -Preconditions serve as a permissions system for your Commands. Keep in -mind, however, that they are not limited to _just_ permissions and can -be as complex as you want them to be. - -There are two types of Preconditions you can use: - -* [PreconditionAttribute] can be applied to Modules, Groups, or Commands. -* [ParameterPreconditionAttribute] can be applied to Parameters. - -You may visit their respective API documentation to find out more. - -[PreconditionAttribute]: xref:Discord.Commands.PreconditionAttribute -[ParameterPreconditionAttribute]: xref:Discord.Commands.ParameterPreconditionAttribute - -## Bundled Preconditions - -@Discord.Commands ships with several bundled Preconditions for you -to use. - -* @Discord.Commands.RequireContextAttribute -* @Discord.Commands.RequireOwnerAttribute -* @Discord.Commands.RequireBotPermissionAttribute -* @Discord.Commands.RequireUserPermissionAttribute -* @Discord.Commands.RequireNsfwAttribute - -## Using Preconditions - -To use a precondition, simply apply any valid precondition candidate to -a command method signature as an attribute. - -### Example - Using a Precondition - -[!code-csharp[Precondition usage](samples/preconditions/precondition_usage.cs)] - -## ORing Preconditions - -When writing commands, you may want to allow some of them to be -executed when only some of the precondition checks are passed. - -This is where the [Group] property of a precondition attribute comes in -handy. By assigning two or more preconditions to a group, the command -system will allow the command to be executed when one of the -precondition passes. - -### Example - ORing Preconditions - -[!code-csharp[OR Precondition](samples/preconditions/group_precondition.cs)] - -[Group]: xref:Discord.Commands.PreconditionAttribute.Group - -## Custom Preconditions - -To write your own Precondition, create a new class that inherits from -either [PreconditionAttribute] or [ParameterPreconditionAttribute] -depending on your use. - -In order for your Precondition to function, you will need to override -the [CheckPermissionsAsync] method. - -If the context meets the required parameters, return -[PreconditionResult.FromSuccess], otherwise return -[PreconditionResult.FromError] and include an error message if -necessary. - -> [!NOTE] -> Visual Studio can help you implement missing members -> from the abstract class by using the "Implement Abstract Class" -> IntelliSense hint. - -### Example - Creating a Custom Precondition - -[!code-csharp[Custom Precondition](samples/preconditions/require_role.cs)] - -[CheckPermissionsAsync]: xref:Discord.Commands.PreconditionAttribute.CheckPermissionsAsync* -[PreconditionResult.FromSuccess]: xref:Discord.Commands.PreconditionResult.FromSuccess* -[PreconditionResult.FromError]: xref:Discord.Commands.PreconditionResult.FromError* diff --git a/docs/guides/commands/samples/dependency-injection/dependency_map_setup.cs b/docs/guides/commands/samples/dependency-injection/dependency_map_setup.cs deleted file mode 100644 index 118c032ed..000000000 --- a/docs/guides/commands/samples/dependency-injection/dependency_map_setup.cs +++ /dev/null @@ -1,62 +0,0 @@ -public class Initialize -{ - private readonly CommandService _commands; - private readonly DiscordSocketClient _client; - - public Initialize(CommandService commands = null, DiscordSocketClient client = null) - { - _commands = commands ?? new CommandService(); - _client = client ?? new DiscordSocketClient(); - } - - public IServiceProvider BuildServiceProvider() => new ServiceCollection() - .AddSingleton(_client) - .AddSingleton(_commands) - // You can pass in an instance of the desired type - .AddSingleton(new NotificationService()) - // ...or by using the generic method. - // - // The benefit of using the generic method is that - // ASP.NET DI will attempt to inject the required - // dependencies that are specified under the constructor - // for us. - .AddSingleton() - .AddSingleton() - .BuildServiceProvider(); -} -public class CommandHandler -{ - private readonly DiscordSocketClient _client; - private readonly CommandService _commands; - private readonly IServiceProvider _services; - - public CommandHandler(IServiceProvider services, CommandService commands, DiscordSocketClient client) - { - _commands = commands; - _services = services; - _client = client; - } - - public async Task InitializeAsync() - { - // Pass the service provider to the second parameter of - // AddModulesAsync to inject dependencies to all modules - // that may require them. - await _commands.AddModulesAsync( - assembly: Assembly.GetEntryAssembly(), - services: _services); - _client.MessageReceived += HandleCommandAsync; - } - - public async Task HandleCommandAsync(SocketMessage msg) - { - // ... - // Pass the service provider to the ExecuteAsync method for - // precondition checks. - await _commands.ExecuteAsync( - context: context, - argPos: argPos, - services: _services); - // ... - } -} diff --git a/docs/guides/commands/samples/dependency-injection/dependency_module.cs b/docs/guides/commands/samples/dependency-injection/dependency_module.cs deleted file mode 100644 index f0625e503..000000000 --- a/docs/guides/commands/samples/dependency-injection/dependency_module.cs +++ /dev/null @@ -1,37 +0,0 @@ -// After setting up dependency injection, modules will need to request -// the dependencies to let the library know to pass -// them along during execution. - -// Dependency can be injected in two ways with Discord.Net. -// You may inject any required dependencies via... -// the module constructor -// -or- -// public settable properties - -// Injection via constructor -public class DatabaseModule : ModuleBase -{ - private readonly DatabaseService _database; - public DatabaseModule(DatabaseService database) - { - _database = database; - } - - [Command("read")] - public async Task ReadFromDbAsync() - { - await ReplyAsync(_database.GetData()); - } -} - -// Injection via public settable properties -public class DatabaseModule : ModuleBase -{ - public DatabaseService DbService { get; set; } - - [Command("read")] - public async Task ReadFromDbAsync() - { - await ReplyAsync(_database.GetData()); - } -} \ No newline at end of file diff --git a/docs/guides/commands/samples/dependency-injection/dependency_module_noinject.cs b/docs/guides/commands/samples/dependency-injection/dependency_module_noinject.cs deleted file mode 100644 index 48cd52308..000000000 --- a/docs/guides/commands/samples/dependency-injection/dependency_module_noinject.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Sometimes injecting dependencies automatically with the provided -// methods in the prior example may not be desired. - -// You may explicitly tell Discord.Net to **not** inject the properties -// by either... -// restricting the access modifier -// -or- -// applying DontInjectAttribute to the property - -// Restricting the access modifier of the property -public class ImageModule : ModuleBase -{ - public ImageService ImageService { get; } - public ImageModule() - { - ImageService = new ImageService(); - } -} - -// Applying DontInjectAttribute -public class ImageModule : ModuleBase -{ - [DontInject] - public ImageService ImageService { get; set; } - public ImageModule() - { - ImageService = new ImageService(); - } -} diff --git a/docs/guides/commands/samples/intro/command_handler.cs b/docs/guides/commands/samples/intro/command_handler.cs deleted file mode 100644 index b962cdd6c..000000000 --- a/docs/guides/commands/samples/intro/command_handler.cs +++ /dev/null @@ -1,64 +0,0 @@ -public class CommandHandler -{ - private readonly DiscordSocketClient _client; - private readonly CommandService _commands; - - public CommandHandler(DiscordSocketClient client, CommandService commands) - { - _commands = commands; - _client = client; - } - - public async Task InstallCommandsAsync() - { - // Hook the MessageReceived event into our command handler - _client.MessageReceived += HandleCommandAsync; - - // Here we discover all of the command modules in the entry - // assembly and load them. Starting from Discord.NET 2.0, a - // service provider is required to be passed into the - // module registration method to inject the - // required dependencies. - // - // If you do not use Dependency Injection, pass null. - // See Dependency Injection guide for more information. - await _commands.AddModulesAsync(assembly: Assembly.GetEntryAssembly(), - services: null); - } - - private async Task HandleCommandAsync(SocketMessage messageParam) - { - // Don't process the command if it was a system message - var message = messageParam as SocketUserMessage; - if (message == null) return; - - // Create a number to track where the prefix ends and the command begins - int argPos = 0; - - // Determine if the message is a command based on the prefix and make sure no bots trigger commands - if (!(message.HasCharPrefix('!', ref argPos) || - message.HasMentionPrefix(_client.CurrentUser, ref argPos)) || - message.Author.IsBot) - return; - - // Create a WebSocket-based command context based on the message - var context = new SocketCommandContext(_client, message); - - // Execute the command with the command context we just - // created, along with the service provider for precondition checks. - - // Keep in mind that result does not indicate a return value - // rather an object stating if the command executed successfully. - var result = await _commands.ExecuteAsync( - context: context, - argPos: argPos, - services: null); - - // Optionally, we may inform the user if the command fails - // to be executed; however, this may not always be desired, - // as it may clog up the request queue should a user spam a - // command. - // if (!result.IsSuccess) - // await context.Channel.SendMessageAsync(result.ErrorReason); - } -} diff --git a/docs/guides/commands/samples/intro/empty-module.cs b/docs/guides/commands/samples/intro/empty-module.cs deleted file mode 100644 index db62032c2..000000000 --- a/docs/guides/commands/samples/intro/empty-module.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Discord.Commands; - -// Keep in mind your module **must** be public and inherit ModuleBase. -// If it isn't, it will not be discovered by AddModulesAsync! -public class InfoModule : ModuleBase -{ - -} \ No newline at end of file diff --git a/docs/guides/commands/samples/intro/groups.cs b/docs/guides/commands/samples/intro/groups.cs deleted file mode 100644 index e117a52da..000000000 --- a/docs/guides/commands/samples/intro/groups.cs +++ /dev/null @@ -1,25 +0,0 @@ -[Group("admin")] -public class AdminModule : ModuleBase -{ - [Group("clean")] - public class CleanModule : ModuleBase - { - // ~admin clean - [Command] - public async Task DefaultCleanAsync() - { - // ... - } - - // ~admin clean messages 15 - [Command("messages")] - public async Task CleanAsync(int count) - { - // ... - } - } - // ~admin ban foxbot#0282 - [Command("ban")] - public Task BanAsync(IGuildUser user) => - Context.Guild.AddBanAsync(user); -} \ No newline at end of file diff --git a/docs/guides/commands/samples/intro/module.cs b/docs/guides/commands/samples/intro/module.cs deleted file mode 100644 index e5fe70534..000000000 --- a/docs/guides/commands/samples/intro/module.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Create a module with no prefix -public class InfoModule : ModuleBase -{ - // ~say hello world -> hello world - [Command("say")] - [Summary("Echoes a message.")] - public Task SayAsync([Remainder] [Summary("The text to echo")] string echo) - => ReplyAsync(echo); - - // ReplyAsync is a method on ModuleBase -} - -// Create a module with the 'sample' prefix -[Group("sample")] -public class SampleModule : ModuleBase -{ - // ~sample square 20 -> 400 - [Command("square")] - [Summary("Squares a number.")] - public async Task SquareAsync( - [Summary("The number to square.")] - int num) - { - // We can also access the channel from the Command Context. - await Context.Channel.SendMessageAsync($"{num}^2 = {Math.Pow(num, 2)}"); - } - - // ~sample userinfo --> foxbot#0282 - // ~sample userinfo @Khionu --> Khionu#8708 - // ~sample userinfo Khionu#8708 --> Khionu#8708 - // ~sample userinfo Khionu --> Khionu#8708 - // ~sample userinfo 96642168176807936 --> Khionu#8708 - // ~sample whois 96642168176807936 --> Khionu#8708 - [Command("userinfo")] - [Summary - ("Returns info about the current user, or the user parameter, if one passed.")] - [Alias("user", "whois")] - public async Task UserInfoAsync( - [Summary("The (optional) user to get info from")] - SocketUser user = null) - { - var userInfo = user ?? Context.Client.CurrentUser; - await ReplyAsync($"{userInfo.Username}#{userInfo.Discriminator}"); - } -} diff --git a/docs/guides/commands/samples/post-execution/command_exception_log.cs b/docs/guides/commands/samples/post-execution/command_exception_log.cs deleted file mode 100644 index 2956a0203..000000000 --- a/docs/guides/commands/samples/post-execution/command_exception_log.cs +++ /dev/null @@ -1,13 +0,0 @@ -public async Task LogAsync(LogMessage logMessage) -{ - // This casting type requries C#7 - if (logMessage.Exception is CommandException cmdException) - { - // We can tell the user that something unexpected has happened - await cmdException.Context.Channel.SendMessageAsync("Something went catastrophically wrong!"); - - // We can also log this incident - Console.WriteLine($"{cmdException.Context.User} failed to execute '{cmdException.Command.Name}' in {cmdException.Context.Channel}."); - Console.WriteLine(cmdException.ToString()); - } -} \ No newline at end of file diff --git a/docs/guides/commands/samples/post-execution/command_executed_adv_demo.cs b/docs/guides/commands/samples/post-execution/command_executed_adv_demo.cs deleted file mode 100644 index dbd75f040..000000000 --- a/docs/guides/commands/samples/post-execution/command_executed_adv_demo.cs +++ /dev/null @@ -1,13 +0,0 @@ -public async Task OnCommandExecutedAsync(Optional command, ICommandContext context, IResult result) -{ - switch(result) - { - case MyCustomResult customResult: - // do something extra with it - break; - default: - if (!string.IsNullOrEmpty(result.ErrorReason)) - await context.Channel.SendMessageAsync(result.ErrorReason); - break; - } -} \ No newline at end of file diff --git a/docs/guides/commands/samples/post-execution/command_executed_demo.cs b/docs/guides/commands/samples/post-execution/command_executed_demo.cs deleted file mode 100644 index a0b26183e..000000000 --- a/docs/guides/commands/samples/post-execution/command_executed_demo.cs +++ /dev/null @@ -1,38 +0,0 @@ -public async Task SetupAsync() -{ - await _command.AddModulesAsync(Assembly.GetEntryAssembly(), _services); - // Hook the execution event - _command.CommandExecuted += OnCommandExecutedAsync; - // Hook the command handler - _client.MessageReceived += HandleCommandAsync; -} -public async Task OnCommandExecutedAsync(Optional command, ICommandContext context, IResult result) -{ - // We have access to the information of the command executed, - // the context of the command, and the result returned from the - // execution in this event. - - // We can tell the user what went wrong - if (!string.IsNullOrEmpty(result?.ErrorReason)) - { - await context.Channel.SendMessageAsync(result.ErrorReason); - } - - // ...or even log the result (the method used should fit into - // your existing log handler) - var commandName = command.IsSpecified ? command.Value.Name : "A command"; - await _log.LogAsync(new LogMessage(LogSeverity.Info, - "CommandExecution", - $"{commandName} was executed at {DateTime.UtcNow}.")); -} -public async Task HandleCommandAsync(SocketMessage msg) -{ - var message = messageParam as SocketUserMessage; - if (message == null) return; - int argPos = 0; - if (!(message.HasCharPrefix('!', ref argPos) || - message.HasMentionPrefix(_client.CurrentUser, ref argPos)) || - message.Author.IsBot) return; - var context = new SocketCommandContext(_client, message); - await _commands.ExecuteAsync(context, argPos, _services); -} diff --git a/docs/guides/commands/samples/post-execution/customresult_base.cs b/docs/guides/commands/samples/post-execution/customresult_base.cs deleted file mode 100644 index 895a370c7..000000000 --- a/docs/guides/commands/samples/post-execution/customresult_base.cs +++ /dev/null @@ -1,6 +0,0 @@ -public class MyCustomResult : RuntimeResult -{ - public MyCustomResult(CommandError? error, string reason) : base(error, reason) - { - } -} \ No newline at end of file diff --git a/docs/guides/commands/samples/post-execution/customresult_extended.cs b/docs/guides/commands/samples/post-execution/customresult_extended.cs deleted file mode 100644 index 6754c96aa..000000000 --- a/docs/guides/commands/samples/post-execution/customresult_extended.cs +++ /dev/null @@ -1,10 +0,0 @@ -public class MyCustomResult : RuntimeResult -{ - public MyCustomResult(CommandError? error, string reason) : base(error, reason) - { - } - public static MyCustomResult FromError(string reason) => - new MyCustomResult(CommandError.Unsuccessful, reason); - public static MyCustomResult FromSuccess(string reason = null) => - new MyCustomResult(null, reason); -} \ No newline at end of file diff --git a/docs/guides/commands/samples/post-execution/customresult_usage.cs b/docs/guides/commands/samples/post-execution/customresult_usage.cs deleted file mode 100644 index 44266cfb4..000000000 --- a/docs/guides/commands/samples/post-execution/customresult_usage.cs +++ /dev/null @@ -1,10 +0,0 @@ -public class MyModule : ModuleBase -{ - [Command("eat")] - public async Task ChooseAsync(string food) - { - if (food == "salad") - return MyCustomResult.FromError("No, I don't want that!"); - return MyCustomResult.FromSuccess($"Give me the {food}!"). - } -} \ No newline at end of file diff --git a/docs/guides/commands/samples/post-execution/post-execution_basic.cs b/docs/guides/commands/samples/post-execution/post-execution_basic.cs deleted file mode 100644 index d1361a1f2..000000000 --- a/docs/guides/commands/samples/post-execution/post-execution_basic.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Bad code!!! -var result = await _commands.ExecuteAsync(context, argPos, _services); -if (result.CommandError != null) - switch(result.CommandError) - { - case CommandError.BadArgCount: - await context.Channel.SendMessageAsync( - "Parameter count does not match any command's."); - break; - default: - await context.Channel.SendMessageAsync( - $"An error has occurred {result.ErrorReason}"); - break; - } \ No newline at end of file diff --git a/docs/guides/commands/samples/preconditions/group_precondition.cs b/docs/guides/commands/samples/preconditions/group_precondition.cs deleted file mode 100644 index bae102b9a..000000000 --- a/docs/guides/commands/samples/preconditions/group_precondition.cs +++ /dev/null @@ -1,9 +0,0 @@ -// The following example only requires the user to either have the -// Administrator permission in this guild or own the bot application. -[RequireUserPermission(GuildPermission.Administrator, Group = "Permission")] -[RequireOwner(Group = "Permission")] -public class AdminModule : ModuleBase -{ - [Command("ban")] - public Task BanAsync(IUser user) => Context.Guild.AddBanAsync(user); -} \ No newline at end of file diff --git a/docs/guides/commands/samples/preconditions/precondition_usage.cs b/docs/guides/commands/samples/preconditions/precondition_usage.cs deleted file mode 100644 index eacee932a..000000000 --- a/docs/guides/commands/samples/preconditions/precondition_usage.cs +++ /dev/null @@ -1,3 +0,0 @@ -[RequireOwner] -[Command("echo")] -public Task EchoAsync(string input) => ReplyAsync(input); \ No newline at end of file diff --git a/docs/guides/commands/samples/preconditions/require_role.cs b/docs/guides/commands/samples/preconditions/require_role.cs deleted file mode 100644 index 77d09b525..000000000 --- a/docs/guides/commands/samples/preconditions/require_role.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Threading.Tasks; -using Discord.Commands; -using Discord.WebSocket; - -// Inherit from PreconditionAttribute -public class RequireRoleAttribute : PreconditionAttribute -{ - // Create a field to store the specified name - private readonly string _name; - - // Create a constructor so the name can be specified - public RequireRoleAttribute(string name) => _name = name; - - // Override the CheckPermissions method - public override Task CheckPermissionsAsync(ICommandContext context, CommandInfo command, IServiceProvider services) - { - // Check if this user is a Guild User, which is the only context where roles exist - if (context.User is SocketGuildUser gUser) - { - // If this command was executed by a user with the appropriate role, return a success - if (gUser.Roles.Any(r => r.Name == _name)) - // Since no async work is done, the result has to be wrapped with `Task.FromResult` to avoid compiler errors - return Task.FromResult(PreconditionResult.FromSuccess()); - // Since it wasn't, fail - else - return Task.FromResult(PreconditionResult.FromError($"You must have a role named {_name} to run this command.")); - } - else - return Task.FromResult(PreconditionResult.FromError("You must be in a guild to run this command.")); - } -} diff --git a/docs/guides/commands/samples/typereaders/typereader-register.cs b/docs/guides/commands/samples/typereaders/typereader-register.cs deleted file mode 100644 index 292caea6f..000000000 --- a/docs/guides/commands/samples/typereaders/typereader-register.cs +++ /dev/null @@ -1,29 +0,0 @@ -public class CommandHandler -{ - private readonly CommandService _commands; - private readonly DiscordSocketClient _client; - private readonly IServiceProvider _services; - - public CommandHandler(CommandService commands, DiscordSocketClient client, IServiceProvider services) - { - _commands = commands; - _client = client; - _services = services; - } - - public async Task SetupAsync() - { - _client.MessageReceived += CommandHandleAsync; - - // Add BooleanTypeReader to type read for the type "bool" - _commands.AddTypeReader(typeof(bool), new BooleanTypeReader()); - - // Then register the modules - await _commands.AddModulesAsync(Assembly.GetEntryAssembly(), _services); - } - - public async Task CommandHandleAsync(SocketMessage msg) - { - // ... - } -} \ No newline at end of file diff --git a/docs/guides/commands/samples/typereaders/typereader.cs b/docs/guides/commands/samples/typereaders/typereader.cs deleted file mode 100644 index a2a4627d2..000000000 --- a/docs/guides/commands/samples/typereaders/typereader.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Note: This example is obsolete, a boolean type reader is bundled -// with Discord.Commands -using Discord; -using Discord.Commands; - -public class BooleanTypeReader : TypeReader -{ - public override Task ReadAsync(ICommandContext context, string input, IServiceProvider services) - { - bool result; - if (bool.TryParse(input, out result)) - return Task.FromResult(TypeReaderResult.FromSuccess(result)); - - return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "Input could not be parsed as a boolean.")); - } -} diff --git a/docs/guides/commands/typereaders.md b/docs/guides/commands/typereaders.md deleted file mode 100644 index f942c9341..000000000 --- a/docs/guides/commands/typereaders.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -uid: Guides.Commands.TypeReaders -title: Type Readers ---- - -# Type Readers - -Type Readers allow you to parse different types of arguments in -your commands. - -By default, the following Types are supported arguments: - -* `bool` -* `char` -* `sbyte`/`byte` -* `ushort`/`short` -* `uint`/`int` -* `ulong`/`long` -* `float`, `double`, `decimal` -* `string` -* `enum` -* `DateTime`/`DateTimeOffset`/`TimeSpan` -* Any nullable value-type (e.g. `int?`, `bool?`) -* Any implementation of `IChannel`/`IMessage`/`IUser`/`IRole` - -## Creating a Type Reader - -To create a `TypeReader`, create a new class that imports @Discord and -@Discord.Commands and ensure the class inherits from -@Discord.Commands.TypeReader. Next, satisfy the `TypeReader` class by -overriding the [ReadAsync] method. - -Inside this Task, add whatever logic you need to parse the input -string. - -If you are able to successfully parse the input, return -[TypeReaderResult.FromSuccess] with the parsed input, otherwise return -[TypeReaderResult.FromError] and include an error message if -necessary. - -> [!NOTE] -> Visual Studio can help you implement missing members -> from the abstract class by using the "Implement Abstract Class" -> IntelliSense hint. - -[TypeReaderResult]: xref:Discord.Commands.TypeReaderResult -[TypeReaderResult.FromSuccess]: xref:Discord.Commands.TypeReaderResult.FromSuccess* -[TypeReaderResult.FromError]: xref:Discord.Commands.TypeReaderResult.FromError* -[ReadAsync]: xref:Discord.Commands.TypeReader.ReadAsync* - -### Example - Creating a Type Reader - -[!code-csharp[TypeReaders](samples/typereaders/typereader.cs)] - -## Registering a Type Reader - -TypeReaders are not automatically discovered by the Command Service -and must be explicitly added. - -To register a TypeReader, invoke [CommandService.AddTypeReader]. - -> [!IMPORTANT] -> TypeReaders must be added prior to module discovery, otherwise your -> TypeReaders may not work! - -[CommandService.AddTypeReader]: xref:Discord.Commands.CommandService.AddTypeReader* - -### Example - Adding a Type Reader - -[!code-csharp[Adding TypeReaders](samples/typereaders/typereader-register.cs)] \ No newline at end of file diff --git a/docs/guides/concepts/connections.md b/docs/guides/concepts/connections.md deleted file mode 100644 index 3d7b77cb8..000000000 --- a/docs/guides/concepts/connections.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -uid: Guides.Concepts.ManageConnections -title: Managing Connections ---- - -# Managing Connections with Discord.Net - -In Discord.Net, once a client has been started, it will automatically -maintain a connection to Discord's gateway until it is manually -stopped. - -## Usage - -To start a connection, invoke the `StartAsync` method on a client that -supports a WebSocket connection; to end a connection, invoke the -`StopAsync` method, which gracefully closes any open WebSocket or -UdpSocket connections. - -Since the Start/Stop methods only signal to an underlying connection -manager that a connection needs to be started, **they return before a -connection is made.** - -As a result, you need to hook into one of the connection-state -based events to have an accurate representation of when a client is -ready for use. - -All clients provide a `Connected` and `Disconnected` event, which is -raised respectively when a connection opens or closes. In the case of -the [DiscordSocketClient], this does **not** mean that the client is -ready to be used. - -A separate event, `Ready`, is provided on [DiscordSocketClient], which -is raised only when the client has finished guild stream or guild -sync and has a completed guild cache. - -[DiscordSocketClient]: xref:Discord.WebSocket.DiscordSocketClient - -### Samples - -[!code-csharp[Connection Sample](samples/events.cs)] - -## Reconnection - -> [!TIP] -> Avoid running long-running code on the gateway! If you deadlock the -> gateway (as explained in [events]), the connection manager will -> **NOT** be able to recover and reconnect. - -Assuming the client disconnected because of a fault on Discord's end, -and not a deadlock on your end, we will always attempt to reconnect -and resume a connection. - -Don't worry about trying to maintain your own connections, the -connection manager is designed to be bulletproof and never fail - if -your client does not manage to reconnect, you have found a bug! - -[events]: xref:Guides.Concepts.Events diff --git a/docs/guides/concepts/entities.md b/docs/guides/concepts/entities.md deleted file mode 100644 index 7415f043a..000000000 --- a/docs/guides/concepts/entities.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -uid: Guides.Concepts.Entities -title: Entities ---- - -# Entities in Discord.Net - -> [!NOTE] -> This article is written with the Socket variants of entities in mind, -> not the general interfaces or Rest/Rpc entities. - -Discord.Net provides a versatile entity system for navigating the -Discord API. - -## Inheritance - -Due to the nature of the Discord API, some entities are designed with -multiple variants; for example, `SocketUser` and `SocketGuildUser`. - -All models will contain the most detailed version of an entity -possible, even if the type is less detailed. - -For example, in the case of the `MessageReceived` event, a -`SocketMessage` is passed in with a channel property of type -`SocketMessageChannel`. All messages come from channels capable of -messaging, so this is the only variant of a channel that can cover -every single case. - -But that doesn't mean a message _can't_ come from a -`SocketTextChannel`, which is a message channel in a guild. To -retrieve information about a guild from a message entity, you will -need to cast its channel object to a `SocketTextChannel`. - -You can find out various types of entities in the @FAQ.Misc.Glossary -page. - -## Navigation - -All socket entities have navigation properties on them, which allow -you to easily navigate to an entity's parent or children. As explained -above, you will sometimes need to cast to a more detailed version of -an entity to navigate to its parent. - -## Accessing Entities - -The most basic forms of entities, `SocketGuild`, `SocketUser`, and -`SocketChannel` can be pulled from the DiscordSocketClient's global -cache, and can be retrieved using the respective `GetXXX` method on -DiscordSocketClient. - -> [!TIP] -> It is **vital** that you use the proper IDs for an entity when using -> a `GetXXX` method. It is recommended that you enable Discord's -> _developer mode_ to allow easy access to entity IDs, found in -> Settings > Appearance > Advanced. Read more about it in the -> [FAQ](xref:FAQ.Basics.GetStarted) page. - -More detailed versions of entities can be pulled from the basic -entities, e.g., `SocketGuild.GetUser`, which returns a -`SocketGuildUser`, or `SocketGuild.GetChannel`, which returns a -`SocketGuildChannel`. Again, you may need to cast these objects to get -a variant of the type that you need. - -## Sample - -[!code-csharp[Entity Sample](samples/entities.cs)] \ No newline at end of file diff --git a/docs/guides/concepts/events.md b/docs/guides/concepts/events.md deleted file mode 100644 index 293b5dc72..000000000 --- a/docs/guides/concepts/events.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -uid: Guides.Concepts.Events -title: Working with Events ---- - -# Events in Discord.Net - -Events in Discord.Net are consumed in a similar manner to the standard -convention, with the exception that every event must be of the type -@System.Threading.Tasks.Task and instead of using @System.EventArgs, -the event's parameters are passed directly into the handler. - -This allows for events to be handled in an async context directly -instead of relying on `async void`. - -## Usage - -To receive data from an event, hook into it using C#'s delegate -event pattern. - -You may either opt to hook an event to an anonymous function (lambda) -or a named function. - -## Safety - -All events are designed to be thread-safe; events are executed -synchronously off the gateway task in the same context as the gateway -task. - -As a side effect, this makes it possible to deadlock the gateway task -and kill a connection. As a general rule of thumb, any task that takes -longer than three seconds should **not** be awaited directly in the -context of an event, but should be wrapped in a `Task.Run` or -offloaded to another task. - -This also means that you should not await a task that requests data -from Discord's gateway in the same context of an event. Since the -gateway will wait on all invoked event handlers to finish before -processing any additional data from the gateway, this will create -a deadlock that will be impossible to recover from. - -Exceptions in commands will be swallowed by the gateway and logged out -through the client's log method. - -## Common Patterns - -As you may know, events in Discord.Net are only given a signature of -`Func`. There is no room for predefined argument names, -so you must either consult IntelliSense, or view the API documentation -directly. - -That being said, there are a variety of common patterns that allow you -to infer what the parameters in an event mean. - -### Entity, Entity - -An event handler with a signature of `Func` -typically means that the first object will be a clone of the entity -_before_ a change was made, and the latter object will be an attached -model of the entity _after_ the change was made. - -This pattern is typically only found on `EntityUpdated` events. - -### Cacheable - -An event handler with a signature of `Func` -means that the `before` state of the entity was not provided by the -API, so it can either be pulled from the client's cache or -downloaded from the API. - -See the documentation for [Cacheable] for more information on this -object. - -[Cacheable]: xref:Discord.Cacheable`2 - -> [!NOTE] -> Many events relating to a Message entity (i.e., `MessageUpdated` and -> `ReactionAdded`) rely on the client's message cache, which is -> **not** enabled by default. Set the `MessageCacheSize` flag in -> @Discord.WebSocket.DiscordSocketConfig to enable it. - -## Sample - -[!code-csharp[Event Sample](samples/events.cs)] diff --git a/docs/guides/concepts/logging.md b/docs/guides/concepts/logging.md deleted file mode 100644 index b92d2bd53..000000000 --- a/docs/guides/concepts/logging.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -uid: Guides.Concepts.Logging -title: Logging Events/Data ---- - -# Logging in Discord.Net - -Discord.Net's clients provide a log event that all messages will be -dispatched over. - -For more information about events in Discord.Net, see the [Events] -section. - -[Events]: xref:Guides.Concepts.Events - -> [!WARNING] -> Due to the nature of Discord.Net's event system, all log event -> handlers will be executed synchronously on the gateway thread. If your -> log output will be dumped to a Web API (e.g., Sentry), you are advised -> to wrap your output in a `Task.Run` so the gateway thread does not -> become blocked while waiting for logging data to be written. - -## Usage in Client(s) - -To receive log events, simply hook the Discord client's @Discord.Rest.BaseDiscordClient.Log -to a `Task` with a single parameter of type [LogMessage]. - -It is recommended that you use an established function instead of a -lambda for handling logs, because most addons accept a reference -to a logging function to write their own messages. - -[LogMessage]: xref:Discord.LogMessage - -## Usage in Commands - -Discord.Net's [CommandService] also provides a @Discord.Commands.CommandService.Log -event, identical in signature to other log events. - -Data logged through this event is typically coupled with a -[CommandException], where information about the command's context -and error can be found and handled. - -[CommandService]: xref:Discord.Commands.CommandService -[CommandException]: xref:Discord.Commands.CommandException - -## Sample - -[!code-csharp[Logging Sample](samples/logging.cs)] diff --git a/docs/guides/concepts/samples/connections.cs b/docs/guides/concepts/samples/connections.cs deleted file mode 100644 index b610da524..000000000 --- a/docs/guides/concepts/samples/connections.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Discord; -using Discord.WebSocket; - -public class Program -{ - private DiscordSocketClient _client; - static void Main(string[] args) => new Program().MainAsync().GetAwaiter().GetResult(); - - public async Task MainAsync() - { - _client = new DiscordSocketClient(); - - await _client.LoginAsync(TokenType.Bot, Environment.GetEnvironmentVariable("DiscordToken")); - await _client.StartAsync(); - - Console.WriteLine("Press any key to exit..."); - Console.ReadKey(); - - await _client.StopAsync(); - // Wait a little for the client to finish disconnecting before allowing the program to return - await Task.Delay(500); - } -} \ No newline at end of file diff --git a/docs/guides/concepts/samples/entities.cs b/docs/guides/concepts/samples/entities.cs deleted file mode 100644 index 64383858d..000000000 --- a/docs/guides/concepts/samples/entities.cs +++ /dev/null @@ -1,11 +0,0 @@ -public string GetChannelTopic(ulong id) -{ - var channel = client.GetChannel(81384956881809408) as SocketTextChannel; - return channel?.Topic; -} - -public SocketGuildUser GetGuildOwner(SocketChannel channel) -{ - var guild = (channel as SocketGuildChannel)?.Guild; - return guild?.Owner; -} \ No newline at end of file diff --git a/docs/guides/concepts/samples/events.cs b/docs/guides/concepts/samples/events.cs deleted file mode 100644 index dce625b33..000000000 --- a/docs/guides/concepts/samples/events.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Discord; -using Discord.WebSocket; - -public class Program -{ - private DiscordSocketClient _client; - static void Main(string[] args) => new Program().MainAsync().GetAwaiter().GetResult(); - - public async Task MainAsync() - { - // When working with events that have Cacheable parameters, - // you must enable the message cache in your config settings if you plan to - // use the cached message entity. - var _config = new DiscordSocketConfig { MessageCacheSize = 100 }; - _client = new DiscordSocketClient(_config); - - await _client.LoginAsync(TokenType.Bot, Environment.GetEnvironmentVariable("DiscordToken")); - await _client.StartAsync(); - - _client.MessageUpdated += MessageUpdated; - _client.Ready += () => - { - Console.WriteLine("Bot is connected!"); - return Task.CompletedTask; - } - - await Task.Delay(-1); - } - - private async Task MessageUpdated(Cacheable before, SocketMessage after, ISocketMessageChannel channel) - { - // If the message was not in the cache, downloading it will result in getting a copy of `after`. - var message = await before.GetOrDownloadAsync(); - Console.WriteLine($"{message} -> {after}"); - } -} diff --git a/docs/guides/concepts/samples/logging.cs b/docs/guides/concepts/samples/logging.cs deleted file mode 100644 index 2419452f0..000000000 --- a/docs/guides/concepts/samples/logging.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Discord; -using Discord.WebSocket; - -public class Program -{ - private DiscordSocketClient _client; - static void Main(string[] args) => new Program().MainAsync().GetAwaiter().GetResult(); - - public async Task MainAsync() - { - _client = new DiscordSocketClient(new DiscordSocketConfig - { - LogLevel = LogSeverity.Info - }); - - _client.Log += Log; - - await _client.LoginAsync(TokenType.Bot, Environment.GetEnvironmentVariable("DiscordToken")); - await _client.StartAsync(); - - await Task.Delay(-1); - } - - private Task Log(LogMessage message) - { - Console.WriteLine(message.ToString()); - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/docs/guides/deployment/deployment.md b/docs/guides/deployment/deployment.md deleted file mode 100644 index 0491e841d..000000000 --- a/docs/guides/deployment/deployment.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -uid: Guides.Deployment -title: Deploying the Bot ---- - -# Deploying a Discord.Net Bot - -After finishing your application, you may want to deploy your bot to a -remote location such as a Virtual Private Server (VPS) or another -computer so you can keep the bot up and running 24/7. - -## Recommended VPS - -For small-medium scaled bots, a cheap VPS (~$5) might be sufficient -enough. Here is a list of recommended VPS provider. - -* [DigitalOcean](https://www.digitalocean.com/) - * Description: American cloud infrastructure provider headquartered - in New York City with data centers worldwide. - * Location(s): - * Asia: Singapore, India - * America: Canada, United States - * Europe: Netherlands, Germany, United Kingdom - * Based in: United States -* [Vultr](https://www.vultr.com/) - * Description: DigitalOcean-like - * Location(s): - * Asia: Japan, Australia, Singapore - * America: United States - * Europe: United Kingdom, France, Netherlands, Germany - * Based in: United States -* [OVH](https://www.ovh.com/) - * Description: French cloud computing company that offers VPS, - dedicated servers and other web services. - * Location(s): - * Asia: Australia, Singapore - * America: United States, Canada - * Europe: United Kingdom, Poland, Germany - * Based in: Europe -* [Scaleway](https://www.scaleway.com/) - * Description: Cheap but powerful VPS owned by [Online.net](https://online.net/). - * Location(s): - * Europe: France, Netherlands - * Based in: Europe -* [Time4VPS](https://www.time4vps.eu/) - * Description: Affordable and powerful VPS Hosting in Europe. - * Location(s): - * Europe: Lithuania - * Based in: Europe - -## .NET Core Deployment - -> [!NOTE] -> This section only covers the very basics of .NET Core deployment. -> To learn more about .NET Core deployment, -> visit [.NET Core application deployment] by Microsoft. - -When redistributing the application - whether for deployment on a -remote machine or for sharing with another user - you may want to -publish the application; in other words, to create a -self-contained package without installing the dependencies -and the runtime on the target platform. - -### Framework-dependent Deployment - -To deploy a framework-dependent package (i.e. files to be used on a -remote machine with the `dotnet` command), simply publish -the package with: - -* `dotnet publish -c Release` - -This will create a package with the **least dependencies** -included with the application; however, the remote machine -must have `dotnet` runtime installed before the remote could run the -program. - -> [!TIP] -> Do not know how to run a .NET Core application with -> the `dotnet` runtime? Navigate to the folder of the program -> (typically under `$projFolder/bin/Release`) and -> enter `dotnet program.dll` where `program.dll` is your compiled -> binaries. - -### Self-contained Deployment - -To deploy a self-contained package (i.e. files to be used on a remote -machine without the `dotnet` runtime), publish with a specific -[Runtime ID] with the `-r` switch. - -This will create a package with dependencies compiled for the target -platform, meaning that all the required dependencies will be included -with the program. This will result in **larger package size**; -however, that means the copy of the runtime that can be run -natively on the target platform. - -For example, the following command will create a Windows -executable (`.exe`) that is ready to be executed on any -Windows 10 x64 based machine: - -* `dotnet publish -c Release -r win10-x64` - -[.NET Core application deployment]: https://docs.microsoft.com/en-us/dotnet/core/deploying/ -[Runtime ID]: https://docs.microsoft.com/en-us/dotnet/core/rid-catalog \ No newline at end of file diff --git a/docs/guides/emoji/emoji.md b/docs/guides/emoji/emoji.md deleted file mode 100644 index 60a84409c..000000000 --- a/docs/guides/emoji/emoji.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -uid: Guides.Emoji -title: Emoji ---- - -# Emoji in Discord.Net - -Before we delve into the difference between an @Discord.Emoji and an -@Discord.Emote in Discord.Net, it is **crucial** to understand what -they both look like behind the scene. When the end-users are sending -or receiving an emoji or emote, they are typically in the form of -`:ok_hand:` or `:reeee:`; however, what goes under the hood is that, -depending on the type of emoji, they are sent in an entirely -different format. - -What does this all mean? It means that you should know that by -reacting with a string like `“:ok_hand:”` will **NOT** automatically -translate to `👌`; rather, it will be treated as-is, -like `:ok_hand:`, thus the server will return a `400 Bad Request`. - -## Emoji - -An emoji is a standard emoji that can be found anywhere else outside -of Discord, which means strings like `👌`, `♥`, `👀` are all -considered an emoji in Discord. However, from the -introduction paragraph we have learned that we cannot -simply send `:ok_hand:` and have Discord take -care of it, but what do we need to send exactly? - -To send an emoji correctly, one must send the emoji in its Unicode -form; this can be obtained in several different ways. - -1. (Easiest) Escape the emoji by using the escape character, `\`, in - your Discord chat client; this will reveal the emoji’s pure Unicode - form, which will allow you to copy-paste into your code. -2. Look it up on Emojipedia, from which you can copy the emoji - easily into your code. - ![Emojipedia](images/emojipedia.png) -3. (Recommended) Look it up in the Emoji list from [FileFormat.Info]; - this will give you the .NET-compatible code that - represents the emoji. - * This is the most recommended method because some systems or - IDE sometimes do not render the Unicode emoji correctly. - ![Fileformat Emoji Source Code](images/fileformat-emoji-src.png) - -### Emoji Declaration - -After obtaining the Unicode representation of the emoji, you may -create the @Discord.Emoji object by passing the string into its -constructor (e.g. `new Emoji("👌");` or `new Emoji("\uD83D\uDC4C");`). - -Your method of declaring an @Discord.Emoji should look similar to -this: - -[!code-csharp[Emoji Sample](samples/emoji-sample.cs)] - -[FileFormat.Info]: https://www.fileformat.info/info/emoji/list.htm - -## Emote - -The meat of the debate is here; what is an emote and how does it -differ from an emoji? An emote refers to a **custom emoji** -created on Discord. - -The underlying structure of an emote also differs drastically; an -emote looks sort-of like a mention on Discord. It consists of two -main elements as illustrated below: - -![Emote illustration](images/emote-format.png) - -As you can see, emote uses a completely different format. To obtain -the raw string as shown above for your emote, you would need to -escape the emote using the escape character `\` in chat somewhere. - -### Emote Declaration - -After obtaining the raw emote string, you would need to use -@Discord.Emote.Parse* or @Discord.Emote.TryParse* to create a valid -emote object. - -Your method of declaring an @Discord.Emote should look similar to -this: - -[!code[Emote Sample](samples/emote-sample.cs)] - -> [!TIP] -> For WebSocket users, you may also consider fetching the Emote -> via the @Discord.WebSocket.SocketGuild.Emotes collection. -> [!code-csharp[Socket emote sample](samples/socket-emote-sample.cs)] - -> [!TIP] -> On Discord, any user with Discord Nitro subscription may use -> custom emotes from any guilds they are currently in. This is also -> true for _any_ standard bot accounts; this does not require -> the bot owner to have a Nitro subscription. - -## Additional Information - -To learn more about emote and emojis and how they could be used, -see the documentation of @Discord.IEmote. \ No newline at end of file diff --git a/docs/guides/emoji/images/emojipedia.png b/docs/guides/emoji/images/emojipedia.png deleted file mode 100644 index acad16f28..000000000 Binary files a/docs/guides/emoji/images/emojipedia.png and /dev/null differ diff --git a/docs/guides/emoji/images/emote-format.png b/docs/guides/emoji/images/emote-format.png deleted file mode 100644 index 981e18227..000000000 Binary files a/docs/guides/emoji/images/emote-format.png and /dev/null differ diff --git a/docs/guides/emoji/images/fileformat-emoji-src.png b/docs/guides/emoji/images/fileformat-emoji-src.png deleted file mode 100644 index a43eebb62..000000000 Binary files a/docs/guides/emoji/images/fileformat-emoji-src.png and /dev/null differ diff --git a/docs/guides/emoji/samples/emoji-sample.cs b/docs/guides/emoji/samples/emoji-sample.cs deleted file mode 100644 index a36e6f70a..000000000 --- a/docs/guides/emoji/samples/emoji-sample.cs +++ /dev/null @@ -1,6 +0,0 @@ -public async Task ReactAsync(SocketUserMessage userMsg) -{ - // equivalent to "👌" - var emoji = new Emoji("\uD83D\uDC4C"); - await userMsg.AddReactionAsync(emoji); -} \ No newline at end of file diff --git a/docs/guides/emoji/samples/emote-sample.cs b/docs/guides/emoji/samples/emote-sample.cs deleted file mode 100644 index b05ecc269..000000000 --- a/docs/guides/emoji/samples/emote-sample.cs +++ /dev/null @@ -1,7 +0,0 @@ -public async Task ReactWithEmoteAsync(SocketUserMessage userMsg, string escapedEmote) -{ - if (Emote.TryParse(escapedEmote, out var emote)) - { - await userMsg.AddReactionAsync(emote); - } -} \ No newline at end of file diff --git a/docs/guides/emoji/samples/socket-emote-sample.cs b/docs/guides/emoji/samples/socket-emote-sample.cs deleted file mode 100644 index 397111512..000000000 --- a/docs/guides/emoji/samples/socket-emote-sample.cs +++ /dev/null @@ -1,11 +0,0 @@ -private readonly DiscordSocketClient _client; - -public async Task ReactAsync(SocketUserMessage userMsg, string emoteName) -{ - var emote = _client.Guilds - .SelectMany(x => x.Emotes) - .FirstOrDefault(x => x.Name.IndexOf( - emoteName, StringComparison.OrdinalIgnoreCase) != -1); - if (emote == null) return; - await userMsg.AddReactionAsync(emote); -} \ No newline at end of file diff --git a/docs/guides/getting_started/first-bot.md b/docs/guides/getting_started/first-bot.md deleted file mode 100644 index a33e72aff..000000000 --- a/docs/guides/getting_started/first-bot.md +++ /dev/null @@ -1,263 +0,0 @@ ---- -uid: Guides.GettingStarted.FirstBot -title: Start making a bot ---- - -# Making Your First Bot with Discord.Net - -One of the ways to get started with the Discord API is to write a -basic ping-pong bot. This bot will respond to a simple command "ping." -We will expand on this to create more diverse commands later, but for -now, it is a good starting point. - -## Creating a Discord Bot - -Before writing your bot, it is necessary to create a bot account via -the Discord Applications Portal first. - -1. Visit the [Discord Applications Portal]. -2. Create a new application. -3. Give the application a name (this will be the bot's initial username). -4. On the left-hand side, under `Settings`, click `Bot`. - - ![Step 4](images/intro-bot-settings.png) - -5. Click on `Add Bot`. - - ![Step 5](images/intro-add-bot.png) - -6. Confirm the popup. -7. (Optional) If this bot will be public, tick `Public Bot`. - - ![Step 7](images/intro-public-bot.png) - -[Discord Applications Portal]: https://discordapp.com/developers/applications/ - -## Adding your bot to a server - -Bots **cannot** use invite links; they must be explicitly invited -through the OAuth2 flow. - -1. Open your bot's application on the [Discord Applications Portal]. -2. On the left-hand side, under `Settings`, click `OAuth2`. - - ![Step 2](images/intro-oauth-settings.png) - -3. Scroll down to `OAuth2 URL Generator` and under `Scopes` tick `bot`. - - ![Step 3](images/intro-scopes-bot.png) - -4. Scroll down further to `Bot Permissions` and select the - permissions that you wish to assign your bot with. - - > [!NOTE] - > This will assign the bot with a special "managed" role that no - > one else can use. The permissions can be changed later in the - > roles settings if you ever change your mind! - -5. Open the generated authorization URL in your browser. -6. Select a server. -7. Click on Authorize. - - > [!NOTE] - > Only servers where you have the `MANAGE_SERVER` permission will be - > present in this list. - - ![Step 6](images/intro-authorize.png) - -## Connecting to Discord - -If you have not already created a project and installed Discord.Net, -do that now. - -For more information, see @Guides.GettingStarted.Installation. - -### Async - -Discord.Net uses .NET's [Task-based Asynchronous Pattern (TAP)] -extensively - nearly every operation is asynchronous. It is highly -recommended for these operations to be awaited in a -properly established async context whenever possible. - -To establish an async context, we will be creating an async main method -in your console application, and rewriting the static main method to -invoke the new async main. - -[!code-csharp[Async Context](samples/first-bot/async-context.cs)] - -As a result of this, your program will now start and immediately -jump into an async context. This allows us to create a connection -to Discord later on without having to worry about setting up the -correct async implementation. - -> [!WARNING] -> If your application throws any exceptions within an async context, -> they will be thrown all the way back up to the first non-async method; -> since our first non-async method is the program's `Main` method, this -> means that **all** unhandled exceptions will be thrown up there, which -> will crash your application. -> -> Discord.Net will prevent exceptions in event handlers from crashing -> your program, but any exceptions in your async main **will** cause -> the application to crash. - -[Task-based Asynchronous Pattern (TAP)]: https://docs.microsoft.com/en-us/dotnet/articles/csharp/async - -### Creating a logging method - -Before we create and configure a Discord client, we will add a method -to handle Discord.Net's log events. - -To allow agnostic support of as many log providers as possible, we -log information through a `Log` event with a proprietary `LogMessage` -parameter. See the [API Documentation] for this event. - -If you are using your own logging framework, this is where you would -invoke it. For the sake of simplicity, we will only be logging to -the console. - -You may learn more about this concept in @Guides.Concepts.Logging. - -[!code-csharp[Async Context](samples/first-bot/logging.cs)] - -[API Documentation]: xref:Discord.Rest.BaseDiscordClient.Log - -### Creating a Discord Client - -Finally, we can create a new connection to Discord. - -Since we are writing a bot, we will be using a [DiscordSocketClient] -along with socket entities. See @Guides.GettingStarted.Terminology -if you are unsure of the differences. - -To establish a new connection, we will create an instance of -[DiscordSocketClient] in the new async main. You may pass in an -optional @Discord.WebSocket.DiscordSocketConfig if necessary. For most -users, the default will work fine. - -Before connecting, we should hook the client's `Log` event to the -log handler that we had just created. Events in Discord.Net work -similarly to any other events in C#. - -Next, you will need to "log in to Discord" with the [LoginAsync] -method with the application's "token." - -> [!NOTE] -> Pay attention to what you are copying from the developer portal! -> A token is not the same as the application's "client secret." - -![Token](images/intro-token.png) - -> [!IMPORTANT] -> Your bot's token can be used to gain total access to your bot, so -> **do __NOT__ share this token with anyone else!** It may behoove you -> to store this token in an external source if you plan on distributing -> the source code for your bot. - -We may now invoke the client's [StartAsync] method, which will -start connection/reconnection logic. It is important to note that -**this method will return as soon as connection logic has been started!** - -Any methods that rely on the client's state should go in an event -handler. This means that you should **not** directly be interacting with -the client before it is fully ready. - -Finally, we will want to block the async main method from returning -when running the application. To do this, we can await an infinite delay -or any other blocking method, such as reading from the console. - -The following lines can now be added: - -[!code-csharp[Create client](samples/first-bot/client.cs)] - -At this point, feel free to start your program and see your bot come -online in Discord. - -> [!TIP] -> Getting a warning about `A supplied token was invalid.` and/or -> having trouble logging in? Double-check whether you have put in -> the correct credentials and make sure that it is _not_ a client -> secret, which is different from a token. - -> [!TIP] -> Encountering a `PlatformNotSupportedException` when starting your bot? -> This means that you are targeting a platform where .NET's default -> WebSocket client is not supported. Refer to the [installation guide] -> for how to fix this. - -[DiscordSocketClient]: xref:Discord.WebSocket.DiscordSocketClient -[LoginAsync]: xref:Discord.Rest.BaseDiscordClient.LoginAsync* -[StartAsync]: xref:Discord.WebSocket.DiscordSocketClient.StartAsync* -[installation guide]: xref:Guides.GettingStarted.Installation - -### Handling a 'ping' - -> [!WARNING] -> Please note that this is *not* a proper way to create a command. -> Use the `CommandService` provided by the library instead, as explained -> in the [Command Guide](xref:Guides.Commands.Intro) section. - -Now that we have learned to open a connection to Discord, we can -begin handling messages that the users are sending. To start out, our -bot will listen for any message whose content is equal to `!ping` and -will respond back with "Pong!". - -Since we want to listen for new messages, the event to hook into -is [MessageReceived]. - -In your program, add a method that matches the signature of the -`MessageReceived` event - it must be a method (`Func`) that returns -the type `Task` and takes a single parameter, a [SocketMessage]. Also, -since we will be sending data to Discord in this method, we will flag -it as `async`. - -In this method, we will add an `if` block to determine if the message -content fits the rules of our scenario - recall that it must be equal -to `!ping`. - -Inside the branch of this condition, we will want to send a message, -`Pong!`, back to the channel from which the message comes from. To -find the channel, look for the `Channel` property on the message -parameter. - -Next, we will want to send a message to this channel. Since the -channel object is of type [ISocketMessageChannel], we can invoke the -[SendMessageAsync] instance method. For the message content, send back -a string, "Pong!". - -You should have now added the following lines, - -[!code-csharp[Message](samples/first-bot/message.cs)] - -Now that your first bot is complete. You may continue to add on to this -if you desire, but for any bots that will be carrying out multiple -commands, it is strongly recommended to use the command framework as -shown below. - -> [!NOTE] -> For your reference, you may view the [completed program]. - -[MessageReceived]: xref:Discord.WebSocket.BaseSocketClient.MessageReceived -[SocketMessage]: xref:Discord.WebSocket.SocketMessage -[ISocketMessageChannel]: xref:Discord.WebSocket.ISocketMessageChannel -[SendMessageAsync]: xref:Discord.WebSocket.ISocketMessageChannel.SendMessageAsync* -[completed program]: samples/first-bot/complete.cs - -# Building a bot with commands - -@Guides.Commands.Intro will guide you through how to setup a program -that is ready for [CommandService], a service that is ready for -advanced command usage. - -For reference, view an [annotated example] of this structure. - -[annotated example]: samples/first-bot/structure.cs - -It is important to know that the recommended design pattern of bots -should be to separate... - -1. the program (initialization and command handler) -2. the modules (handle commands) -3. the services (persistent storage, pure functions, data manipulation) - -[CommandService]: xref:Discord.Commands.CommandService \ No newline at end of file diff --git a/docs/guides/getting_started/images/appveyor-artifacts.png b/docs/guides/getting_started/images/appveyor-artifacts.png deleted file mode 100644 index 2f31b77a9..000000000 Binary files a/docs/guides/getting_started/images/appveyor-artifacts.png and /dev/null differ diff --git a/docs/guides/getting_started/images/appveyor-nupkg.png b/docs/guides/getting_started/images/appveyor-nupkg.png deleted file mode 100644 index 0cf3cf6c4..000000000 Binary files a/docs/guides/getting_started/images/appveyor-nupkg.png and /dev/null differ diff --git a/docs/guides/getting_started/images/install-rider-add.png b/docs/guides/getting_started/images/install-rider-add.png deleted file mode 100644 index 3f0dc729e..000000000 Binary files a/docs/guides/getting_started/images/install-rider-add.png and /dev/null differ diff --git a/docs/guides/getting_started/images/install-rider-nuget-manager.png b/docs/guides/getting_started/images/install-rider-nuget-manager.png deleted file mode 100644 index 884b32d6b..000000000 Binary files a/docs/guides/getting_started/images/install-rider-nuget-manager.png and /dev/null differ diff --git a/docs/guides/getting_started/images/install-rider-search.png b/docs/guides/getting_started/images/install-rider-search.png deleted file mode 100644 index 32f2f9722..000000000 Binary files a/docs/guides/getting_started/images/install-rider-search.png and /dev/null differ diff --git a/docs/guides/getting_started/images/install-vs-deps.png b/docs/guides/getting_started/images/install-vs-deps.png deleted file mode 100644 index ab10bd1bd..000000000 Binary files a/docs/guides/getting_started/images/install-vs-deps.png and /dev/null differ diff --git a/docs/guides/getting_started/images/install-vs-nuget.png b/docs/guides/getting_started/images/install-vs-nuget.png deleted file mode 100644 index ecf627d11..000000000 Binary files a/docs/guides/getting_started/images/install-vs-nuget.png and /dev/null differ diff --git a/docs/guides/getting_started/images/intro-add-bot.png b/docs/guides/getting_started/images/intro-add-bot.png deleted file mode 100644 index 3b5343ac6..000000000 Binary files a/docs/guides/getting_started/images/intro-add-bot.png and /dev/null differ diff --git a/docs/guides/getting_started/images/intro-authorize.png b/docs/guides/getting_started/images/intro-authorize.png deleted file mode 100644 index 66ca4cb04..000000000 Binary files a/docs/guides/getting_started/images/intro-authorize.png and /dev/null differ diff --git a/docs/guides/getting_started/images/intro-bot-settings.png b/docs/guides/getting_started/images/intro-bot-settings.png deleted file mode 100644 index 6ac40bfe6..000000000 Binary files a/docs/guides/getting_started/images/intro-bot-settings.png and /dev/null differ diff --git a/docs/guides/getting_started/images/intro-oauth-settings.png b/docs/guides/getting_started/images/intro-oauth-settings.png deleted file mode 100644 index 7d8c2a64a..000000000 Binary files a/docs/guides/getting_started/images/intro-oauth-settings.png and /dev/null differ diff --git a/docs/guides/getting_started/images/intro-public-bot.png b/docs/guides/getting_started/images/intro-public-bot.png deleted file mode 100644 index da91366a6..000000000 Binary files a/docs/guides/getting_started/images/intro-public-bot.png and /dev/null differ diff --git a/docs/guides/getting_started/images/intro-scopes-bot.png b/docs/guides/getting_started/images/intro-scopes-bot.png deleted file mode 100644 index fa17deb16..000000000 Binary files a/docs/guides/getting_started/images/intro-scopes-bot.png and /dev/null differ diff --git a/docs/guides/getting_started/images/intro-token.png b/docs/guides/getting_started/images/intro-token.png deleted file mode 100644 index 0fcdac077..000000000 Binary files a/docs/guides/getting_started/images/intro-token.png and /dev/null differ diff --git a/docs/guides/getting_started/images/nightlies-vs-note.png b/docs/guides/getting_started/images/nightlies-vs-note.png deleted file mode 100644 index 0dcf2dea3..000000000 Binary files a/docs/guides/getting_started/images/nightlies-vs-note.png and /dev/null differ diff --git a/docs/guides/getting_started/images/nightlies-vs-step1.png b/docs/guides/getting_started/images/nightlies-vs-step1.png deleted file mode 100644 index a399ca66c..000000000 Binary files a/docs/guides/getting_started/images/nightlies-vs-step1.png and /dev/null differ diff --git a/docs/guides/getting_started/images/nightlies-vs-step2.png b/docs/guides/getting_started/images/nightlies-vs-step2.png deleted file mode 100644 index 75cecbb8d..000000000 Binary files a/docs/guides/getting_started/images/nightlies-vs-step2.png and /dev/null differ diff --git a/docs/guides/getting_started/images/nightlies-vs-step4.png b/docs/guides/getting_started/images/nightlies-vs-step4.png deleted file mode 100644 index 6462ab994..000000000 Binary files a/docs/guides/getting_started/images/nightlies-vs-step4.png and /dev/null differ diff --git a/docs/guides/getting_started/installing.md b/docs/guides/getting_started/installing.md deleted file mode 100644 index bb2592c02..000000000 --- a/docs/guides/getting_started/installing.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -uid: Guides.GettingStarted.Installation -title: Installing Discord.Net ---- - -# Discord.Net Installation - -Discord.Net is distributed through the NuGet package manager; the most -recommended way for you to install this library. Alternatively, you -may also compile this library yourself should you so desire. - -## Supported Platforms - -Discord.Net targets [.NET Standard] both 1.3 and 2.0; this also means -that creating applications using the latest version of [.NET Core] is -the most recommended. If you are bound by Windows-specific APIs or -other limitations, you may also consider targeting [.NET Framework] -4.6.1 or higher. - -> [!WARNING] -> Using this library with [Mono] is not supported until further -> notice. It is known to have issues with the library's WebSockets -> implementation and may crash the application upon startup. - -[Mono]: https://www.mono-project.com/ -[.NET Standard]: https://docs.microsoft.com/en-us/dotnet/articles/standard/library -[.NET Core]: https://docs.microsoft.com/en-us/dotnet/articles/core/ -[.NET Framework]: https://docs.microsoft.com/en-us/dotnet/framework/get-started/ -[additional steps]: #installing-on-net-standard-11 - -## Installing with NuGet - -Release builds of Discord.Net will be published to the -[official NuGet feed]. - -Development builds of Discord.Net, as well as add-ons, will be -published to our [MyGet feed]. See -@Guides.GettingStarted.Installation.Nightlies to learn more. - -[official NuGet feed]: https://nuget.org -[MyGet feed]: https://www.myget.org/feed/Packages/discord-net - -### [Using Visual Studio](#tab/vs-install) - -1. Create a new solution for your bot. -2. In the Solution Explorer, find the "Dependencies" element under your - bot's project. -3. Right click on "Dependencies", and select "Manage NuGet packages." - ![Step 3](images/install-vs-deps.png) -4. In the "Browse" tab, search for `Discord.Net`. -5. Install the `Discord.Net` package. - ![Step 5](images/install-vs-nuget.png) - -### [Using JetBrains Rider](#tab/rider-install) - -1. Create a new solution for your bot. -2. Open the NuGet window (Tools > NuGet > Manage NuGet packages for - Solution). -![Step 2](images/install-rider-nuget-manager.png) -3. In the "Packages" tab, search for `Discord.Net`. -![Step 3](images/install-rider-search.png) -4. Install by adding the package to your project. -![Step 4](images/install-rider-add.png) - -### [Using Visual Studio Code](#tab/vs-code) - -1. Create a new project for your bot. -2. Add `Discord.Net` to your .csproj. - -[!code[Sample .csproj](samples/project.xml)] - -### [Using dotnet CLI](#tab/dotnet-cli) - -1. Open command-line and navigate to where your .csproj is located. -2. Enter `dotnet add package Discord.Net`. - -*** - -## Compiling from Source - -In order to compile Discord.Net, you will need the following: - -### Using Visual Studio - -* [Visual Studio 2017](https://www.visualstudio.com/) -* [.NET Core SDK] - -The .NET Core and Docker workload is required during Visual Studio -installation. - -### Using Command Line - -* [.NET Core SDK] - -## Additional Information - -### Installing on Unsupported WebSocket Platform - -When running any Discord.Net-powered bot on an older operating system -(e.g. Windows 7) that does not natively support WebSocket, -you may encounter a @System.PlatformNotSupportedException upon -connecting. - -You may resolve this by either targeting .NET Core 2.1 or later, or -by installing one or more custom packages as listed below. - -#### [Targeting .NET Core 2.1](#tab/core2-1) - -1. Download the latest [.NET Core SDK]. -2. Create or move your existing project to use .NET Core. -3. Modify your `` tag to at least `netcoreapp2.1`, or - by adding the `--framework netcoreapp2.1` switch when building. - -#### [Custom Packages](#tab/custom-pkg) - -1. Install or compile the following packages: - - * `Discord.Net.Providers.WS4Net` - * `Discord.Net.Providers.UDPClient` (Optional) - * This is _only_ required if your bot will be utilizing voice chat. - -2. Configure your [DiscordSocketClient] to use these custom providers -over the default ones. - - * To do this, set the `WebSocketProvider` and the optional - `UdpSocketProvider` properties on the [DiscordSocketConfig] that you - are passing into your client. - -[!code-csharp[Example](samples/netstd11.cs)] - -[DiscordSocketClient]: xref:Discord.WebSocket.DiscordSocketClient -[DiscordSocketConfig]: xref:Discord.WebSocket.DiscordSocketConfig - -*** - -[.NET Core SDK]: https://www.microsoft.com/net/download/ \ No newline at end of file diff --git a/docs/guides/getting_started/nightlies.md b/docs/guides/getting_started/nightlies.md deleted file mode 100644 index 39bcc1c9f..000000000 --- a/docs/guides/getting_started/nightlies.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -uid: Guides.GettingStarted.Installation.Nightlies -title: Installing Nightly Build ---- - -# Installing Discord.Net Nightly Build - -Before Discord.Net pushes a new set of features into the stable -version, we use nightly builds to test the features with the -community for an extensive period of time. Each nightly build is -compiled by AppVeyor whenever a new commit is made and will be pushed -to our MyGet feed. - -> [!IMPORTANT] -> Although nightlies are generally stable and have more features -> and bug fixes than the current stable build on NuGet, there -> will be breaking changes during the development or -> breaking bugs; these bugs are usually fixed as soon as they -> are discovered, but you should still be aware of that. - -## Installing with MyGet (Recommended) - -MyGet is typically used by many development teams to publish their -latest pre-release packages before the features are finalized and -pushed to NuGet. - -The following is the feed link of Discord.Net, - -* `https://www.myget.org/F/discord-net/api/v3/index.json` - -Depending on which IDE you use, there are many different ways of -adding the feed to your package source. - -### [Visual Studio](#tab/vs) - -1. Go to `Tools` > `NuGet Package Manager` > `Package Manager Settings` - ![VS](images/nightlies-vs-step1.png) -2. Go to `Package Sources` - ![Package Sources](images/nightlies-vs-step2.png) -3. Click on the add icon -4. Fill in the desired name and source as shown below and hit `Update` - ![Add Source](images/nightlies-vs-step4.png) - -> [!NOTE] -> Remember to tick the `Include prerelease` checkbox to see the -> nightly builds! -> ![Checkbox](images/nightlies-vs-note.png) - -### [Local NuGet.Config](#tab/local-nuget-config) - -If you plan on deploying your bot or developing outside of Visual -Studio, you will need to create a local NuGet configuration file for -your project. - -To do this, create a file named `NuGet.Config` alongside the root of -your application, where the project is located. - -Paste the following snippets into this configuration file, adding any -additional feeds if necessary. - -[!code[NuGet Configuration](samples/nuget.config)] - -After which, you may install the packages by directly modifying the -project file and specifying a version, or by using -the [Package Manager Console](https://docs.microsoft.com/en-us/nuget/tools/powershell-reference) -(`Install-Package Discord.Net -IncludePrerelease`). - -*** - -## Installing from AppVeyor Artifacts - -As mentioned in the first paragraph, we utilize AppVeyor to perform -automated tests and publish the new build. During the publishing -process, we also upload the NuGet packages onto -AppVeyor's Artifact collection. - -The latest build status can be found within our [AppVeyor project]. - -[AppVeyor project]: https://ci.appveyor.com/project/rogueexception/discord-net - -1. In the project, you may find our latest build including the - aforementioned artifacts. - ![Artifacts](images/appveyor-artifacts.png) -2. In the artifacts collection, you should see the latest packages - packed in `*.nupkg` form which you could download from and use. - ![NuPkgs](images/appveyor-nupkg.png) diff --git a/docs/guides/getting_started/samples/first-bot/async-context.cs b/docs/guides/getting_started/samples/first-bot/async-context.cs deleted file mode 100644 index 3c98c9e46..000000000 --- a/docs/guides/getting_started/samples/first-bot/async-context.cs +++ /dev/null @@ -1,9 +0,0 @@ -public class Program -{ - public static void Main(string[] args) - => new Program().MainAsync().GetAwaiter().GetResult(); - - public async Task MainAsync() - { - } -} \ No newline at end of file diff --git a/docs/guides/getting_started/samples/first-bot/client.cs b/docs/guides/getting_started/samples/first-bot/client.cs deleted file mode 100644 index bced2224d..000000000 --- a/docs/guides/getting_started/samples/first-bot/client.cs +++ /dev/null @@ -1,21 +0,0 @@ -private DiscordSocketClient _client; - -public async Task MainAsync() -{ - _client = new DiscordSocketClient(); - - _client.Log += Log; - - // Remember to keep token private or to read it from an - // external source! In this case, we are reading the token - // from an environment variable. If you do not know how to set-up - // environment variables, you may find more information on the - // Internet or by using other methods such as reading from - // a configuration. - await _client.LoginAsync(TokenType.Bot, - Environment.GetEnvironmentVariable("DiscordToken")); - await _client.StartAsync(); - - // Block this task until the program is closed. - await Task.Delay(-1); -} \ No newline at end of file diff --git a/docs/guides/getting_started/samples/first-bot/complete.cs b/docs/guides/getting_started/samples/first-bot/complete.cs deleted file mode 100644 index 3a7cb061d..000000000 --- a/docs/guides/getting_started/samples/first-bot/complete.cs +++ /dev/null @@ -1,34 +0,0 @@ -public class Program -{ - private DiscordSocketClient _client; - - public static void Main(string[] args) - => new Program().MainAsync().GetAwaiter().GetResult(); - - public async Task MainAsync() - { - _client = new DiscordSocketClient(); - _client.Log += Log; - _client.MessageReceived += MessageReceivedAsync; - await _client.LoginAsync(TokenType.Bot, - Environment.GetEnvironmentVariable("DiscordToken")); - await _client.StartAsync(); - - // Block this task until the program is closed. - await Task.Delay(-1); - } - - private async Task MessageReceivedAsync(SocketMessage message) - { - if (message.Content == "!ping") - { - await message.Channel.SendMessageAsync("Pong!"); - } - } - - private Task Log(LogMessage msg) - { - Console.WriteLine(msg.ToString()); - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/docs/guides/getting_started/samples/first-bot/logging.cs b/docs/guides/getting_started/samples/first-bot/logging.cs deleted file mode 100644 index c6ffc406e..000000000 --- a/docs/guides/getting_started/samples/first-bot/logging.cs +++ /dev/null @@ -1,5 +0,0 @@ -private Task Log(LogMessage msg) -{ - Console.WriteLine(msg.ToString()); - return Task.CompletedTask; -} \ No newline at end of file diff --git a/docs/guides/getting_started/samples/first-bot/message.cs b/docs/guides/getting_started/samples/first-bot/message.cs deleted file mode 100644 index f636d6f35..000000000 --- a/docs/guides/getting_started/samples/first-bot/message.cs +++ /dev/null @@ -1,14 +0,0 @@ -public async Task MainAsync() -{ - // ... - _client.MessageReceived += MessageReceived; - // ... -} - -private async Task MessageReceived(SocketMessage message) -{ - if (message.Content == "!ping") - { - await message.Channel.SendMessageAsync("Pong!"); - } -} diff --git a/docs/guides/getting_started/samples/first-bot/structure.cs b/docs/guides/getting_started/samples/first-bot/structure.cs deleted file mode 100644 index 5165e2fdb..000000000 --- a/docs/guides/getting_started/samples/first-bot/structure.cs +++ /dev/null @@ -1,175 +0,0 @@ -using System; -using System.Reflection; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; -using Discord; -using Discord.Commands; -using Discord.WebSocket; - -class Program -{ - // Program entry point - static void Main(string[] args) - { - // Call the Program constructor, followed by the - // MainAsync method and wait until it finishes (which should be never). - new Program().MainAsync().GetAwaiter().GetResult(); - } - - private readonly DiscordSocketClient _client; - - // Keep the CommandService and DI container around for use with commands. - // These two types require you install the Discord.Net.Commands package. - private readonly CommandService _commands; - private readonly IServiceProvider _services; - - private Program() - { - _client = new DiscordSocketClient(new DiscordSocketConfig - { - // How much logging do you want to see? - LogLevel = LogSeverity.Info, - - // If you or another service needs to do anything with messages - // (eg. checking Reactions, checking the content of edited/deleted messages), - // you must set the MessageCacheSize. You may adjust the number as needed. - //MessageCacheSize = 50, - - // If your platform doesn't have native WebSockets, - // add Discord.Net.Providers.WS4Net from NuGet, - // add the `using` at the top, and uncomment this line: - //WebSocketProvider = WS4NetProvider.Instance - }); - - _commands = new CommandService(new CommandServiceConfig - { - // Again, log level: - LogLevel = LogSeverity.Info, - - // There's a few more properties you can set, - // for example, case-insensitive commands. - CaseSensitiveCommands = false, - }); - - // Subscribe the logging handler to both the client and the CommandService. - _client.Log += Log; - _commands.Log += Log; - - // Setup your DI container. - _services = ConfigureServices(); - - } - - // If any services require the client, or the CommandService, or something else you keep on hand, - // pass them as parameters into this method as needed. - // If this method is getting pretty long, you can seperate it out into another file using partials. - private static IServiceProvider ConfigureServices() - { - var map = new ServiceCollection() - // Repeat this for all the service classes - // and other dependencies that your commands might need. - .AddSingleton(new SomeServiceClass()); - - // When all your required services are in the collection, build the container. - // Tip: There's an overload taking in a 'validateScopes' bool to make sure - // you haven't made any mistakes in your dependency graph. - return map.BuildServiceProvider(); - } - - // Example of a logging handler. This can be re-used by addons - // that ask for a Func. - private static Task Log(LogMessage message) - { - switch (message.Severity) - { - case LogSeverity.Critical: - case LogSeverity.Error: - Console.ForegroundColor = ConsoleColor.Red; - break; - case LogSeverity.Warning: - Console.ForegroundColor = ConsoleColor.Yellow; - break; - case LogSeverity.Info: - Console.ForegroundColor = ConsoleColor.White; - break; - case LogSeverity.Verbose: - case LogSeverity.Debug: - Console.ForegroundColor = ConsoleColor.DarkGray; - break; - } - Console.WriteLine($"{DateTime.Now,-19} [{message.Severity,8}] {message.Source}: {message.Message} {message.Exception}"); - Console.ResetColor(); - - // If you get an error saying 'CompletedTask' doesn't exist, - // your project is targeting .NET 4.5.2 or lower. You'll need - // to adjust your project's target framework to 4.6 or higher - // (instructions for this are easily Googled). - // If you *need* to run on .NET 4.5 for compat/other reasons, - // the alternative is to 'return Task.Delay(0);' instead. - return Task.CompletedTask; - } - - private async Task MainAsync() - { - // Centralize the logic for commands into a separate method. - await InitCommands(); - - // Login and connect. - await _client.LoginAsync(TokenType.Bot, - // < DO NOT HARDCODE YOUR TOKEN > - Environment.GetEnvironmentVariable("DiscordToken")); - await _client.StartAsync(); - - // Wait infinitely so your bot actually stays connected. - await Task.Delay(Timeout.Infinite); - } - - private async Task InitCommands() - { - // Either search the program and add all Module classes that can be found. - // Module classes MUST be marked 'public' or they will be ignored. - // You also need to pass your 'IServiceProvider' instance now, - // so make sure that's done before you get here. - await _commands.AddModulesAsync(Assembly.GetEntryAssembly(), _services); - // Or add Modules manually if you prefer to be a little more explicit: - await _commands.AddModuleAsync(_services); - // Note that the first one is 'Modules' (plural) and the second is 'Module' (singular). - - // Subscribe a handler to see if a message invokes a command. - _client.MessageReceived += HandleCommandAsync; - } - - private async Task HandleCommandAsync(SocketMessage arg) - { - // Bail out if it's a System Message. - var msg = arg as SocketUserMessage; - if (msg == null) return; - - // We don't want the bot to respond to itself or other bots. - if (msg.Author.Id == _client.CurrentUser.Id || msg.Author.IsBot) return; - - // Create a number to track where the prefix ends and the command begins - int pos = 0; - // Replace the '!' with whatever character - // you want to prefix your commands with. - // Uncomment the second half if you also want - // commands to be invoked by mentioning the bot instead. - if (msg.HasCharPrefix('!', ref pos) /* || msg.HasMentionPrefix(_client.CurrentUser, ref pos) */) - { - // Create a Command Context. - var context = new SocketCommandContext(_client, msg); - - // Execute the command. (result does not indicate a return value, - // rather an object stating if the command executed successfully). - var result = await _commands.ExecuteAsync(context, pos, _services); - - // Uncomment the following lines if you want the bot - // to send a message if it failed. - // This does not catch errors from commands with 'RunMode.Async', - // subscribe a handler for '_commands.CommandExecuted' to see those. - //if (!result.IsSuccess && result.Error != CommandError.UnknownCommand) - // await msg.Channel.SendMessageAsync(result.ErrorReason); - } - } -} diff --git a/docs/guides/getting_started/samples/netstd11.cs b/docs/guides/getting_started/samples/netstd11.cs deleted file mode 100644 index a8573696a..000000000 --- a/docs/guides/getting_started/samples/netstd11.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Discord.Providers.WS4Net; -using Discord.Providers.UDPClient; -using Discord.WebSocket; -// ... -var client = new DiscordSocketClient(new DiscordSocketConfig -{ - WebSocketProvider = WS4NetProvider.Instance, - UdpSocketProvider = UDPClientProvider.Instance, -}); \ No newline at end of file diff --git a/docs/guides/getting_started/samples/nuget.config b/docs/guides/getting_started/samples/nuget.config deleted file mode 100644 index bf706a08b..000000000 --- a/docs/guides/getting_started/samples/nuget.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/docs/guides/getting_started/samples/project.xml b/docs/guides/getting_started/samples/project.xml deleted file mode 100644 index 179d3f97b..000000000 --- a/docs/guides/getting_started/samples/project.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - Exe - netcoreapp2.1 - - - - - - - diff --git a/docs/guides/getting_started/terminology.md b/docs/guides/getting_started/terminology.md deleted file mode 100644 index 0f24edd6f..000000000 --- a/docs/guides/getting_started/terminology.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -uid: Guides.GettingStarted.Terminology -title: Terminology ---- - -# Terminology - -## Preface - -Most terms for objects remain the same between 0.9 and 1.0 and above. -The major difference is that the ``Server`` is now called ``Guild`` -to stay in line with Discord internally. - -## Implementation Specific Entities - -Discord.Net is split into a core library and two different -implementations - `Discord.Net.Core`, `Discord.Net.Rest`, and -`Discord.Net.WebSockets`. - -As a bot developer, you will only need to use `Discord.Net.WebSockets`, -but you should be aware of the differences between them. - -`Discord.Net.Core` provides a set of interfaces that models Discord's -API. These interfaces are consistent throughout all implementations of -Discord.Net, and if you are writing an implementation-agnostic library -or addon, you can rely on the core interfaces to ensure that your -addon will run on all platforms. - -`Discord.Net.Rest` provides a set of concrete classes to be used -**strictly** with the REST portion of Discord's API. Entities in this -implementation are prefixed with `Rest` (e.g., `RestChannel`). - -`Discord.Net.WebSocket` provides a set of concrete classes that are -used primarily with Discord's WebSocket API or entities that are kept -in cache. When developing bots, you will be using this implementation. -All entities are prefixed with `Socket` (e.g., `SocketChannel`). \ No newline at end of file diff --git a/docs/guides/introduction/intro.md b/docs/guides/introduction/intro.md deleted file mode 100644 index 14d4aa49e..000000000 --- a/docs/guides/introduction/intro.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -uid: Guides.Introduction -title: Introduction to Discord.Net ---- - -# Introduction - -## Looking to get started? - -Welcome! Before you dive into this library, however, you should have -some decent understanding of the language -you are about to use. This library touches on -[Task-based Asynchronous Pattern] \(TAP), [polymorphism], [interface] -and many more advanced topics extensively. Please make sure that you -understand these topics to some extent before proceeding. With all -that being said, feel free to visit us on Discord at the link below -if you have any questions! - -Here are some examples: - -1. [Official samples] -2. [Official template] - -> [!NOTE] -> Please note that you should *not* try to blindly copy paste -> the code. The examples are meant to be a template or a guide. - -[Official template]: https://github.com/foxbot/DiscordBotBase/tree/csharp/src/DiscordBot -[Official samples]: https://github.com/RogueException/Discord.Net/tree/dev/samples -[Task-based Asynchronous Pattern]: https://docs.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap -[polymorphism]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/polymorphism -[interface]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/interfaces/ - -## New to .NET/C#? - -All examples or snippets featured in this guide and all API -documentation will be written in C#. - -If you are new to the language, using this wrapper may prove to be -difficult, but don't worry! There are many resources online that can -help you get started in the wonderful world of .NET. Here are some -resources to get you started. - -- [C# Programming Guide (MSDN/Microsoft, Free)](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/) -- [C# Fundamentals For Absolute Beginners (Channel9/Microsoft, Free)](https://channel9.msdn.com/Series/C-Fundamentals-for-Absolute-Beginners) -- [C# Path (Pluralsight, Paid)](https://www.pluralsight.com/paths/csharp) - -## Still have questions? - -Please visit us at `#dotnet_discord-net` on the [Discord API] server. -Describe the problem in details to us, what you've done, and, -if any, the problematic code uploaded onto [Hastebin](https://hastebin.com). - -[Discord API]: https://discord.gg/jkrBmQR \ No newline at end of file diff --git a/docs/guides/toc.yml b/docs/guides/toc.yml deleted file mode 100644 index 01c245301..000000000 --- a/docs/guides/toc.yml +++ /dev/null @@ -1,41 +0,0 @@ -- name: Introduction - topicUid: Guides.Introduction -- name: Getting Started - items: - - name: Installation - topicUid: Guides.GettingStarted.Installation - items: - - name: Nightly Builds - topicUid: Guides.GettingStarted.Installation.Nightlies - - name: Your First Bot - topicUid: Guides.GettingStarted.FirstBot - - name: Terminology - topicUid: Guides.GettingStarted.Terminology -- name: Basic Concepts - items: - - name: Logging Data - topicUid: Guides.Concepts.Logging - - name: Working with Events - topicUid: Guides.Concepts.Events - - name: Managing Connections - topicUid: Guides.Concepts.ManageConnections - - name: Entities - topicUid: Guides.Concepts.Entities -- name: Working with Commands - items: - - name: Introduction - topicUid: Guides.Commands.Intro - - name: TypeReaders - topicUid: Guides.Commands.TypeReaders - - name: Preconditions - topicUid: Guides.Commands.Preconditions - - name: Dependency Injection - topicUid: Guides.Commands.DI - - name: Post-execution Handling - topicUid: Guides.Commands.PostExecution -- name: Emoji - topicUid: Guides.Emoji -- name: Voice - topicUid: Guides.Voice.SendingVoice -- name: Deployment - topicUid: Guides.Deployment \ No newline at end of file diff --git a/docs/guides/voice/samples/audio_create_ffmpeg.cs b/docs/guides/voice/samples/audio_create_ffmpeg.cs deleted file mode 100644 index dda560efe..000000000 --- a/docs/guides/voice/samples/audio_create_ffmpeg.cs +++ /dev/null @@ -1,10 +0,0 @@ -private Process CreateStream(string path) -{ - return Process.Start(new ProcessStartInfo - { - FileName = "ffmpeg", - Arguments = $"-hide_banner -loglevel panic -i \"{path}\" -ac 2 -f s16le -ar 48000 pipe:1", - UseShellExecute = false, - RedirectStandardOutput = true, - }); -} diff --git a/docs/guides/voice/samples/audio_ffmpeg.cs b/docs/guides/voice/samples/audio_ffmpeg.cs deleted file mode 100644 index d36fbbc20..000000000 --- a/docs/guides/voice/samples/audio_ffmpeg.cs +++ /dev/null @@ -1,11 +0,0 @@ -private async Task SendAsync(IAudioClient client, string path) -{ - // Create FFmpeg using the previous example - using (var ffmpeg = CreateStream(path)) - using (var output = ffmpeg.StandardOutput.BaseStream) - using (var discord = client.CreatePCMStream(AudioApplication.Mixed)) - { - try { await output.CopyToAsync(discord); } - finally { await discord.FlushAsync(); } - } -} diff --git a/docs/guides/voice/samples/joining_audio.cs b/docs/guides/voice/samples/joining_audio.cs deleted file mode 100644 index 8803d3596..000000000 --- a/docs/guides/voice/samples/joining_audio.cs +++ /dev/null @@ -1,11 +0,0 @@ -// The command's Run Mode MUST be set to RunMode.Async, otherwise, being connected to a voice channel will block the gateway thread. -[Command("join", RunMode = RunMode.Async)] -public async Task JoinChannel(IVoiceChannel channel = null) -{ - // Get the audio channel - channel = channel ?? (Context.User as IGuildUser)?.VoiceChannel; - if (channel == null) { await Context.Channel.SendMessageAsync("User must be in a voice channel, or a voice channel must be passed as an argument."); return; } - - // For the next step with transmitting audio, you would want to pass this Audio Client in to a service. - var audioClient = await channel.ConnectAsync(); -} diff --git a/docs/guides/voice/sending-voice.md b/docs/guides/voice/sending-voice.md deleted file mode 100644 index 476f2f42e..000000000 --- a/docs/guides/voice/sending-voice.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -uid: Guides.Voice.SendingVoice -title: Sending Voice ---- - -**Information on this page is subject to change!** - ->[!WARNING] ->This article is out of date, and has not been rewritten yet. -Information is not guaranteed to be accurate. - -## Installing - -Audio requires two native libraries, `libsodium` and `opus`. -Both of these libraries must be placed in the runtime directory of your -bot. (When developing on .NET Framework, this would be `bin/debug`, -when developing on .NET Core, this is where you execute `dotnet run` -from; typically the same directory as your csproj). - -For Windows Users, precompiled binaries are available for your -convienence [here](https://discord.foxbot.me/binaries/). - -For Linux Users, you will need to compile [Sodium] and [Opus] from -source, or install them from your package manager. - -[Sodium]: https://download.libsodium.org/libsodium/releases/ -[Opus]: http://downloads.xiph.org/releases/opus/ - -## Joining a Channel - -Joining a channel is the first step to sending audio, and will return -an [IAudioClient] to send data with. - -To join a channel, simply await [ConnectAsync] on any instance of an -@Discord.IAudioChannel. - -[!code-csharp[Joining a Channel](samples/joining_audio.cs)] - ->[!WARNING] ->Commands which mutate voice states, such as those where you join/leave ->an audio channel, or send audio, should use [RunMode.Async]. RunMode.Async ->is necessary to prevent a feedback loop which will deadlock clients ->in their default configuration. If you know that you're running your ->commands in a different task than the gateway task, RunMode.Async is ->not required. - -The client will sustain a connection to this channel until it is -kicked, disconnected from Discord, or told to disconnect. - -It should be noted that voice connections are created on a per-guild -basis; only one audio connection may be open by the bot in a single -guild. To switch channels within a guild, invoke [ConnectAsync] on -another voice channel in the guild. - -[IAudioClient]: xref:Discord.Audio.IAudioClient -[ConnectAsync]: xref:Discord.IAudioChannel.ConnectAsync* -[RunMode.Async]: xref:Discord.Commands.RunMode - -## Transmitting Audio - -### With FFmpeg - -[FFmpeg] is an open source, highly versatile AV-muxing tool. This is -the recommended method of transmitting audio. - -Before you begin, you will need to have a version of FFmpeg downloaded -and placed somewhere in your PATH (or alongside the bot, in the same -location as libsodium and opus). Windows binaries are available on -[FFmpeg's download page]. - -[FFmpeg]: https://ffmpeg.org/ -[FFmpeg's download page]: https://ffmpeg.org/download.html - -First, you will need to create a Process that starts FFmpeg. An -example of how to do this is included below, though it is important -that you return PCM at 48000hz. - ->[!NOTE] ->As of the time of this writing, Discord.Audio struggles significantly ->with processing audio that is already opus-encoded; you will need to ->use the PCM write streams. - -[!code-csharp[Creating FFmpeg](samples/audio_create_ffmpeg.cs)] - -Next, to transmit audio from FFmpeg to Discord, you will need to -pull an [AudioOutStream] from your [IAudioClient]. Since we're using -PCM audio, use [IAudioClient.CreatePCMStream]. - -The sample rate argument doesn't particularly matter, so long as it is -a valid rate (120, 240, 480, 960, 1920, or 2880). For the sake of -simplicity, I recommend using 1920. - -Channels should be left at `2`, unless you specified a different value -for `-ac 2` when creating FFmpeg. - -[AudioOutStream]: xref:Discord.Audio.AudioOutStream -[IAudioClient.CreatePCMStream]: xref:Discord.Audio.IAudioClient#Discord_Audio_IAudioClient_CreateDirectPCMStream_Discord_Audio_AudioApplication_System_Nullable_System_Int32__System_Int32_ - -Finally, audio will need to be piped from FFmpeg's stdout into your -AudioOutStream. This step can be as complex as you'd like it to be, but -for the majority of cases, you can just use [Stream.CopyToAsync], as -shown below. - -[Stream.CopyToAsync]: https://msdn.microsoft.com/en-us/library/hh159084(v=vs.110).aspx - -If you are implementing a queue for sending songs, it's likely that -you will want to wait for audio to stop playing before continuing on -to the next song. You can await `AudioOutStream.FlushAsync` to wait for -the audio client's internal buffer to clear out. - -[!code-csharp[Sending Audio](samples/audio_ffmpeg.cs)] diff --git a/docs/index.md b/docs/index.md deleted file mode 100644 index 79899e068..000000000 --- a/docs/index.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -uid: Root.Landing -title: Home ---- - -# Discord.Net Documentation - -