diff --git a/Discord.Net.sln b/Discord.Net.sln
index db11e8b30..bfcda2fab 100644
--- a/Discord.Net.sln
+++ b/Discord.Net.sln
@@ -1,17 +1,13 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
-VisualStudioVersion = 14.0.24720.0
+VisualStudioVersion = 14.0.25123.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{8D7989F0-66CE-4DBB-8230-D8C811E9B1D7}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "netplatform", "netplatform", "{EA68EBE2-51C8-4440-9EF7-D633C90A5D35}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Discord.Net", "src\Discord.Net\Discord.Net.xproj", "{ACFB060B-EC8A-4926-B293-04C01E17EE23}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Discord.Net.Commands", "src\Discord.Net.Commands\Discord.Net.Commands.xproj", "{19793545-EF89-48F4-8100-3EBAAD0A9141}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "net45", "net45", "{DF03D4E8-38F6-4FE1-BC52-E38124BE8AFD}"
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Discord.Net", "src\Discord.Net\Discord.Net.xproj", "{2C91BDD7-621D-460F-B768-EAD106D9BA62}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{6317A2E6-8E36-4C3E-949B-3F10EC888AB9}"
EndProject
@@ -22,104 +18,44 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
global.json = global.json
EndProjectSection
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.Net", "src\Discord.Net.Net45\Discord.Net.csproj", "{8D71A857-879A-4A10-859E-5FF824ED6688}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.Net.Commands", "src\Discord.Net.Commands.Net45\Discord.Net.Commands.csproj", "{1B5603B4-6F8F-4289-B945-7BAAE523D740}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Discord.Net.Modules", "src\Discord.Net.Modules\Discord.Net.Modules.xproj", "{01584E8A-78DA-486F-9EF9-A894E435841B}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "net45", "net45", "{628A40F4-2D06-4BCE-82EF-0EE70DD5C1CA}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.Net.Modules", "src\Discord.Net.Modules.Net45\Discord.Net.Modules.csproj", "{3091164F-66AE-4543-A63D-167C1116241D}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Discord.Net.Audio", "src\Discord.Net.Audio\Discord.Net.Audio.xproj", "{DFF7AFE3-CA77-4109-BADE-B4B49A4F6648}"
-EndProject
-Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Discord.Net.Shared", "src\Discord.Net.Shared\Discord.Net.Shared.shproj", "{2875DEB5-F248-4105-8EA2-5141E3DE8025}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.Net.Audio", "src\Discord.Net.Audio.Net45\Discord.Net.Audio.csproj", "{7BFEF748-B934-4621-9B11-6302E3A9F6B3}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.Net.Net45", "src\Discord.Net\Discord.Net.Net45.csproj", "{C6A50D24-CBD3-4E76-852C-4DCA60BBD608}"
EndProject
Global
- GlobalSection(SharedMSBuildProjectFiles) = preSolution
- src\Discord.Net.Shared\Discord.Net.Shared.projitems*{2875deb5-f248-4105-8ea2-5141e3de8025}*SharedItemsImports = 13
- src\Discord.Net.Shared\Discord.Net.Shared.projitems*{7bfef748-b934-4621-9b11-6302e3a9f6b3}*SharedItemsImports = 4
- src\Discord.Net.Shared\Discord.Net.Shared.projitems*{1b5603b4-6f8f-4289-b945-7baae523d740}*SharedItemsImports = 4
- src\Discord.Net.Shared\Discord.Net.Shared.projitems*{3091164f-66ae-4543-a63d-167c1116241d}*SharedItemsImports = 4
- src\Discord.Net.Shared\Discord.Net.Shared.projitems*{8d71a857-879a-4a10-859e-5ff824ed6688}*SharedItemsImports = 4
- EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
FullDebug|Any CPU = FullDebug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {ACFB060B-EC8A-4926-B293-04C01E17EE23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {ACFB060B-EC8A-4926-B293-04C01E17EE23}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {ACFB060B-EC8A-4926-B293-04C01E17EE23}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU
- {ACFB060B-EC8A-4926-B293-04C01E17EE23}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
- {ACFB060B-EC8A-4926-B293-04C01E17EE23}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {ACFB060B-EC8A-4926-B293-04C01E17EE23}.Release|Any CPU.Build.0 = Release|Any CPU
- {19793545-EF89-48F4-8100-3EBAAD0A9141}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {19793545-EF89-48F4-8100-3EBAAD0A9141}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {19793545-EF89-48F4-8100-3EBAAD0A9141}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU
- {19793545-EF89-48F4-8100-3EBAAD0A9141}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
- {19793545-EF89-48F4-8100-3EBAAD0A9141}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {19793545-EF89-48F4-8100-3EBAAD0A9141}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2C91BDD7-621D-460F-B768-EAD106D9BA62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2C91BDD7-621D-460F-B768-EAD106D9BA62}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2C91BDD7-621D-460F-B768-EAD106D9BA62}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2C91BDD7-621D-460F-B768-EAD106D9BA62}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
+ {2C91BDD7-621D-460F-B768-EAD106D9BA62}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2C91BDD7-621D-460F-B768-EAD106D9BA62}.Release|Any CPU.Build.0 = Release|Any CPU
{855D6B1D-847B-42DA-BE6A-23683EA89511}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{855D6B1D-847B-42DA-BE6A-23683EA89511}.Debug|Any CPU.Build.0 = Debug|Any CPU
{855D6B1D-847B-42DA-BE6A-23683EA89511}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU
{855D6B1D-847B-42DA-BE6A-23683EA89511}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
{855D6B1D-847B-42DA-BE6A-23683EA89511}.Release|Any CPU.ActiveCfg = Release|Any CPU
{855D6B1D-847B-42DA-BE6A-23683EA89511}.Release|Any CPU.Build.0 = Release|Any CPU
- {8D71A857-879A-4A10-859E-5FF824ED6688}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {8D71A857-879A-4A10-859E-5FF824ED6688}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {8D71A857-879A-4A10-859E-5FF824ED6688}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU
- {8D71A857-879A-4A10-859E-5FF824ED6688}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
- {8D71A857-879A-4A10-859E-5FF824ED6688}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {8D71A857-879A-4A10-859E-5FF824ED6688}.Release|Any CPU.Build.0 = Release|Any CPU
- {1B5603B4-6F8F-4289-B945-7BAAE523D740}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {1B5603B4-6F8F-4289-B945-7BAAE523D740}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {1B5603B4-6F8F-4289-B945-7BAAE523D740}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU
- {1B5603B4-6F8F-4289-B945-7BAAE523D740}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
- {1B5603B4-6F8F-4289-B945-7BAAE523D740}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {1B5603B4-6F8F-4289-B945-7BAAE523D740}.Release|Any CPU.Build.0 = Release|Any CPU
- {01584E8A-78DA-486F-9EF9-A894E435841B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {01584E8A-78DA-486F-9EF9-A894E435841B}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {01584E8A-78DA-486F-9EF9-A894E435841B}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU
- {01584E8A-78DA-486F-9EF9-A894E435841B}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
- {01584E8A-78DA-486F-9EF9-A894E435841B}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {01584E8A-78DA-486F-9EF9-A894E435841B}.Release|Any CPU.Build.0 = Release|Any CPU
- {3091164F-66AE-4543-A63D-167C1116241D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {3091164F-66AE-4543-A63D-167C1116241D}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {3091164F-66AE-4543-A63D-167C1116241D}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU
- {3091164F-66AE-4543-A63D-167C1116241D}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
- {3091164F-66AE-4543-A63D-167C1116241D}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {3091164F-66AE-4543-A63D-167C1116241D}.Release|Any CPU.Build.0 = Release|Any CPU
- {DFF7AFE3-CA77-4109-BADE-B4B49A4F6648}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {DFF7AFE3-CA77-4109-BADE-B4B49A4F6648}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {DFF7AFE3-CA77-4109-BADE-B4B49A4F6648}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU
- {DFF7AFE3-CA77-4109-BADE-B4B49A4F6648}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
- {DFF7AFE3-CA77-4109-BADE-B4B49A4F6648}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {DFF7AFE3-CA77-4109-BADE-B4B49A4F6648}.Release|Any CPU.Build.0 = Release|Any CPU
- {7BFEF748-B934-4621-9B11-6302E3A9F6B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {7BFEF748-B934-4621-9B11-6302E3A9F6B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {7BFEF748-B934-4621-9B11-6302E3A9F6B3}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU
- {7BFEF748-B934-4621-9B11-6302E3A9F6B3}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
- {7BFEF748-B934-4621-9B11-6302E3A9F6B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {7BFEF748-B934-4621-9B11-6302E3A9F6B3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C6A50D24-CBD3-4E76-852C-4DCA60BBD608}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C6A50D24-CBD3-4E76-852C-4DCA60BBD608}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C6A50D24-CBD3-4E76-852C-4DCA60BBD608}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C6A50D24-CBD3-4E76-852C-4DCA60BBD608}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
+ {C6A50D24-CBD3-4E76-852C-4DCA60BBD608}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C6A50D24-CBD3-4E76-852C-4DCA60BBD608}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{EA68EBE2-51C8-4440-9EF7-D633C90A5D35} = {8D7989F0-66CE-4DBB-8230-D8C811E9B1D7}
- {ACFB060B-EC8A-4926-B293-04C01E17EE23} = {EA68EBE2-51C8-4440-9EF7-D633C90A5D35}
- {19793545-EF89-48F4-8100-3EBAAD0A9141} = {EA68EBE2-51C8-4440-9EF7-D633C90A5D35}
- {DF03D4E8-38F6-4FE1-BC52-E38124BE8AFD} = {8D7989F0-66CE-4DBB-8230-D8C811E9B1D7}
+ {2C91BDD7-621D-460F-B768-EAD106D9BA62} = {EA68EBE2-51C8-4440-9EF7-D633C90A5D35}
{855D6B1D-847B-42DA-BE6A-23683EA89511} = {6317A2E6-8E36-4C3E-949B-3F10EC888AB9}
- {8D71A857-879A-4A10-859E-5FF824ED6688} = {DF03D4E8-38F6-4FE1-BC52-E38124BE8AFD}
- {1B5603B4-6F8F-4289-B945-7BAAE523D740} = {DF03D4E8-38F6-4FE1-BC52-E38124BE8AFD}
- {01584E8A-78DA-486F-9EF9-A894E435841B} = {EA68EBE2-51C8-4440-9EF7-D633C90A5D35}
- {3091164F-66AE-4543-A63D-167C1116241D} = {DF03D4E8-38F6-4FE1-BC52-E38124BE8AFD}
- {DFF7AFE3-CA77-4109-BADE-B4B49A4F6648} = {EA68EBE2-51C8-4440-9EF7-D633C90A5D35}
- {2875DEB5-F248-4105-8EA2-5141E3DE8025} = {DF03D4E8-38F6-4FE1-BC52-E38124BE8AFD}
- {7BFEF748-B934-4621-9B11-6302E3A9F6B3} = {DF03D4E8-38F6-4FE1-BC52-E38124BE8AFD}
+ {628A40F4-2D06-4BCE-82EF-0EE70DD5C1CA} = {8D7989F0-66CE-4DBB-8230-D8C811E9B1D7}
+ {C6A50D24-CBD3-4E76-852C-4DCA60BBD608} = {628A40F4-2D06-4BCE-82EF-0EE70DD5C1CA}
EndGlobalSection
EndGlobal
diff --git a/NuGet.config b/NuGet.config
new file mode 100644
index 000000000..91bc2845a
--- /dev/null
+++ b/NuGet.config
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/features/commands.rst b/docs/features/commands.rst
index e6bd6bf82..8abfb18a9 100644
--- a/docs/features/commands.rst
+++ b/docs/features/commands.rst
@@ -1,7 +1,7 @@
|stub| Commands
===============
-The `Discord.Net.Commands`_ package extends DiscordClient with a built-in Commands Handler.
+The `Discord.Net.Commands`_ package DiscordBotClient extends DiscordClient with support for commands.
.. _Discord.Net.Commands: https://www.nuget.org/packages/Discord.Net.Commands
diff --git a/docs/features/events.rst b/docs/features/events.rst
index d782c438e..2cfe27f54 100644
--- a/docs/features/events.rst
+++ b/docs/features/events.rst
@@ -3,19 +3,21 @@ Events
Usage
-----
-Messages from the Discord server are exposed via events on the DiscordClient class and follow the standard EventHandler C# pattern.
+Messages from the Discord server are exposed via events on the DiscordClient class and follow the standard EventHandler C# pattern.
.. warning::
- Note that all synchronous code in an event handler will run on the gateway socket's thread and should be handled as quickly as possible.
+ Note that all synchronous code in an event handler will run on the gateway socket's thread and should be handled as quickly as possible.
Using the async-await pattern to let the thread continue immediately is recommended and is demonstrated in the examples below.
-Ready
------
-
-The Ready Event is raised only once, when your client finishes processing the READY packet from Discord.
+Connection State
+----------------
-This has replaced the previous "Connected" event, and indicates that it is safe to begin retrieving users, channels, or servers from the cache.
+Connection Events will be raised when the Connection State of your client changes.
+.. warning::
+ You should not use DiscordClient.Connected to run code when your client first connects to Discord.
+ If you lose connection and automatically reconnect, this code will be ran again, which may lead to unexpected behavior.
+
Messages
--------
@@ -24,7 +26,7 @@ Messages
Example of MessageReceived:
-.. code-block:: csharp6
+.. code-block:: c#
// (Preface: Echo Bots are discouraged, make sure your bot is not running in a public server if you use them)
@@ -54,7 +56,7 @@ There are several user events:
Examples:
-.. code-block:: csharp6
+.. code-block:: c#
// Register a Hook into the UserBanned event using a Lambda
_client.UserBanned += async (s, e) => {
diff --git a/docs/features/logging.rst b/docs/features/logging.rst
index c2f9d6ce3..4b9f254a5 100644
--- a/docs/features/logging.rst
+++ b/docs/features/logging.rst
@@ -2,12 +2,12 @@ Logging
=======
Discord.Net will log all of its events/exceptions using a built-in LogManager.
-This LogManager can be accessed through ``DiscordClient.Log``
+This LogManager can be accessed through DiscordClient.Log
Usage
-----
-To handle Log Messages through Discord.Net's Logger, you must hook into the ``Log.Message`` Event.
+To handle Log Messages through Discord.Net's Logger, you must hook into the Log.Message Event.
The LogManager does not provide a string-based result for the message, you must put your own message format together using the data provided through LogMessageEventArgs
See the Example for a snippet of logging.
@@ -17,25 +17,19 @@ Logging Your Own Data
The LogManager included in Discord.Net can also be used to log your own messages.
-You can use ``DiscordClient.Log.Log(LogSeverity, Source, Message, [Exception])``, or one of the shortcut helpers, to log data.
+You can use DiscordClient.Log.Log(LogSeverity, Source, Message, Exception), or one of the shortcut helpers, to log data.
Example:
-
-.. code-block:: csharp6
+.. code-block:: c#
_client.MessageReceived += async (s, e) {
// Log a new Message with Severity Info, Sourced from 'MessageReceived', with the Message Contents.
_client.Log.Info("MessageReceived", e.Message.Text, null);
};
-
-.. warning::
-
- Starting in Discord.Net 1.0, you will not be able to log your own messages. You will need to create your own Logging manager, or use a pre-existing one.
-
Example
-------
.. literalinclude:: /samples/logging.cs
- :language: csharp6
+ :language: c#
:tab-width: 2
diff --git a/docs/features/permissions.rst b/docs/features/permissions.rst
index aa3856807..058fe07cf 100644
--- a/docs/features/permissions.rst
+++ b/docs/features/permissions.rst
@@ -1,21 +1,8 @@
Permissions
===========
-|outdated|
-
There are two types of permissions: *Channel Permissions* and *Server Permissions*.
-Permission Overrides
---------------------
-
-Channel Permissions are expressed using an enum, ``PermValue``.
-
-The three states are fairly straightforward -
-
-``PermValue.Allow``: Allow the user to perform a permission.
-``PermValue.Deny``: Deny the user to perform a permission.
-``PermValue.Inherit``: The user will inherit the permission from its role.
-
Channel Permissions
-------------------
Channel Permissions are controlled using a set of flags:
@@ -42,24 +29,27 @@ Speak Voice Speak in a voice channel.
UseVoiceActivation Voice Use Voice Activation in a text channel (for large channels where PTT is preferred)
======================= ======= ==============
-Each flag is a PermValue; see the section above.
+If a user has a permission, the value is true. Otherwise, it must be null.
-Setting Channel Permissions
----------------------------
+Dual Channel Permissions
+------------------------
+You may also access a user's permissions in a channel with the DualChannelPermissions class.
+Unlike normal ChannelPermissions, DualChannelPermissions hold three values:
-To set channel permissions, create a new ``ChannelPermissionOverrides``, and specify the flags/values that you want to override.
+If a user has a permission, the value is true. If a user is denied a permission, it will be false. If the permission is not set, the value will return null.
-Then, update the user, by doing ``Channel.AddPermissionsRule(_user, _overwrites);``
+Setting Channel Permissions
+---------------------------
-Roles
------
+To set channel permissions, you may use either two ChannelPermissions, or one DualChannelPermissions.
-Accessing/modifying permissions for roles is done the same way as user permissions, just using the overload for a Role. See above sections.
+In the case of using two Channel Permissions, you must create one list of allowed permissions, and one list of denied permissions.
+Otherwise, you can use a single DualChannelPermissions.
Server Permissions
------------------
-Server Permissions can be viewed with ``User.ServerPermissions``, but **at the time of this writing** cannot be set.
+Server Permissions can be accessed by ``Server.GetPermissions(User)``, and updated with ``Server.UpdatePermissions(User, ServerPermissions)``
A user's server permissions also contain the default values for it's channel permissions, so the channel permissions listed above are also valid flags for Server Permissions. There are also a few extra Server Permissions:
@@ -71,7 +61,11 @@ KickMembers Server Kick users from the server. They can still rejoi
ManageRoles Server Manage roles on the server, and their permissions.
ManageChannels Server Manage channels that exist on the server (add, remove them)
ManageServer Server Manage the server settings.
-======================= ======= ==============
+
+Roles
+-----
+
+Managing permissions for roles is much easier than for users in channels. For roles, just access the flag under `Role.Permissions`.
Example
-------
diff --git a/docs/features/server-management.rst b/docs/features/server-management.rst
index 765fd4e0f..d555875a8 100644
--- a/docs/features/server-management.rst
+++ b/docs/features/server-management.rst
@@ -10,7 +10,7 @@ You can create Channels, Invites, and Roles on a server using the CreateChannel,
You may also edit a server's name, icon, and region.
-.. code-block:: csharp6
+.. code-block:: c#
// Create a Channel and retrieve the Channel object
var _channel = await _server.CreateChannel("announcements", ChannelType.Text);
diff --git a/docs/features/user-management.rst b/docs/features/user-management.rst
index cf3305312..972b3ab4b 100644
--- a/docs/features/user-management.rst
+++ b/docs/features/user-management.rst
@@ -6,7 +6,7 @@ Banning
To ban a user, invoke the Ban function on a Server object.
-.. code-block:: csharp6
+.. code-block:: c#
_server.Ban(_user, 30);
@@ -17,6 +17,6 @@ Kicking
To kick a user, invoke the Kick function on the User.
-.. code-block:: csharp6
+.. code-block:: c#
_user.Kick();
diff --git a/docs/features/voice.rst b/docs/features/voice.rst
index a4dddeff5..fc6867b58 100644
--- a/docs/features/voice.rst
+++ b/docs/features/voice.rst
@@ -1,180 +1,13 @@
-Voice
-=====
+|stub| Voice
+=================
-Installation
-------------
-
-Before setting up the AudioService, you must first install the package `from NuGet`_ or `GitHub`_.
-
-Add the package to your solution, and then import the namespace ``Discord.Audio``.
-
-.. _from NuGet: https://www.nuget.org/packages/Discord.Net.Audio/0.9.0-rc3
-.. _GitHub: https://github.com/RogueException/Discord.Net/tree/master/src/Discord.Net.Audio
-
-Setup
------
-
-To use audio, you must install the AudioService to your DiscordClient.
-
-.. code-block:: csharp6
-
- var _client = new DiscordClient();
-
- _client.UsingAudio(x => // Opens an AudioConfigBuilder so we can configure our AudioService
- {
- x.Mode = AudioMode.Outgoing; // Tells the AudioService that we will only be sending audio
- });
-
-Joining a Channel
------------------
-
-Joining Voice Channels is pretty straight-forward, and is required to send Audio. This will also allow us to get an IAudioClient, which we will later use to send Audio.
-
-.. code-block:: csharp6
-
- var voiceChannel = _client.FindServers("Music Bot Server").FirstOrDefault().VoiceChannels.FirstOrDefault(); // Finds the first VoiceChannel on the server 'Music Bot Server'
-
- var _vClient = await _client.GetService() // We use GetService to find the AudioService that we installed earlier. In previous versions, this was equivelent to _client.Audio()
- .Join(VoiceChannel); // Join the Voice Channel, and return the IAudioClient.
-
-The client will sustain a connection to this channel until it is kicked, disconnected from Discord, or told to Disconnect.
-
-The IAudioClient
-----------------
-
-The IAudioClient is used to connect/disconnect to/from a Voice Channel, and to send audio to that Voice Channel.
-
-.. function:: IAudioClient.Disconnect();
-
- Disconnects the IAudioClient from the Voice Server.
-
-
-.. function:: IAudioClient.Join(Channel);
-
- Moves the IAudioClient to another channel on the Voice Server, or starts a connection if one has already been terminated.
-
-.. note::
-
- Because versions previous to 0.9 do not discretely differentiate between Text and Voice Channels, you may want to ensure that users cannot request the audio client to join a text channel, as this will throw an exception, leading to potentially unexpected behavior
-
-.. function:: IAudioClient.Wait();
-
- Blocks the current thread until the sending audio buffer has cleared out.
-
-.. function:: IAudioClient.Clear();
-
- Clears the sending audio buffer.
-
-.. function:: IAudioClient.Send(byte[] data, int offset, int count);
-
- Adds a stream of data to the Audio Client's internal buffer, to be sent to Discord. Follows the standard c# Stream.Send() format.
+|stub-desc|
Broadcasting
------------
-There are multiple approaches to broadcasting audio. Discord.Net will convert your audio packets into Opus format, so the only work you need to do is converting your audio into a format that Discord will accept. The format Discord takes is 16-bit 48000Hz PCM.
-
-Broadcasting with NAudio
-------------------------
-
-`NAudio`_ is one of the easiest approaches to sending audio, although it is not multi-platform compatible. The following example will show you how to read an mp3 file, and send it to Discord.
-You can `download NAudio from NuGet`_.
-
-.. code-block:: csharp6
-
- using NAudio;
- using NAudio.Wave;
- using NAudio.CoreAudioApi;
-
- public void SendAudio(string filePath)
- {
- var channelCount = _client.GetService().Config.Channels; // Get the number of AudioChannels our AudioService has been configured to use.
- var OutFormat = new WaveFormat(48000, 16, channelCount); // Create a new Output Format, using the spec that Discord will accept, and with the number of channels that our client supports.
- using (var MP3Reader = new Mp3FileReader(filePath)) // Create a new Disposable MP3FileReader, to read audio from the filePath parameter
- using (var resampler = new MediaFoundationResampler(MP3Reader, OutFormat)) // Create a Disposable Resampler, which will convert the read MP3 data to PCM, using our Output Format
- {
- resampler.ResamplerQuality = 60; // Set the quality of the resampler to 60, the highest quality
- int blockSize = outFormat.AverageBytesPerSecond / 50; // Establish the size of our AudioBuffer
- byte[] buffer = new byte[blockSize];
- int byteCount;
-
- while((byteCount = resampler.Read(buffer, 0, blockSize)) > 0) // Read audio into our buffer, and keep a loop open while data is present
- {
- if (byteCount < blockSize)
- {
- // Incomplete Frame
- for (int i = byteCount; i < blockSize; i++)
- buffer[i] = 0;
- }
- _vClient.Send(buffer, 0, blockSize); // Send the buffer to Discord
- }
- }
-
- }
-
-.. _NAudio: https://naudio.codeplex.com/
-.. _download NAudio from NuGet: https://www.nuget.org/packages/NAudio/
-
-Broadcasting with FFmpeg
-------------------------
-
-`FFmpeg`_ allows for a more advanced approach to sending audio, although it is multiplatform safe. The following example will show you how to stream a file to Discord.
-
-.. code-block:: csharp6
-
- public void SendAudio(string pathOrUrl)
- {
- var process = Process.Start(new ProcessStartInfo { // FFmpeg requires us to spawn a process and hook into its stdout, so we will create a Process
- FileName = "ffmpeg",
- Arguments = $"-i {pathOrUrl}" + // Here we provide a list of arguments to feed into FFmpeg. -i means the location of the file/URL it will read from
- "-f s16le -ar 48000 -ac 2 pipe:1", // Next, we tell it to output 16-bit 48000Hz PCM, over 2 channels, to stdout.
- UseShellExecute = false,
- RedirectStandardOutput = true // Capture the stdout of the process
- });
- Thread.Sleep(2000); // Sleep for a few seconds to FFmpeg can prebuffer.
-
- int blockSize = 3840; // The size of bytes to read per frame; 1920 for mono
- byte[] buffer = new byte[blockSize];
- int byteCount;
-
- while (true) // Loop forever, so data will always be read
- {
- byteCount = process.StandardOutput.BaseStream // Access the underlying MemoryStream from the stdout of FFmpeg
- .Read(buffer, 0, blockSize); // Read stdout into the buffer
-
- if (byteCount == 0) // FFmpeg did not output anything
- break; // Break out of the while(true) loop, since there was nothing to read.
-
- _vClient.Send(buffer, 0, byteCount); // Send our data to Discord
- }
- _vClient.Wait(); // Wait for the Voice Client to finish sending data, as ffMPEG may have already finished buffering out a song, and it is unsafe to return now.
- }
-
-.. _FFmpeg: https://ffmpeg.org/
-
-.. note::
-
- The code-block above assumes that your client is configured to stream 2-channel audio. It also may prematurely end a song. FFmpeg can — especially when streaming from a URL — stop to buffer data from a source, and cause your output stream to read empty data. Because the snippet above does not safely track for failed attempts, or buffers, an empty buffer will cause playback to stop. This is also not 'memory-friendly'.
-
Multi-Server Broadcasting
-------------------------
-.. warning:: Multi-Server broadcasting is not supported by Discord, will cause performance issues for you, and is not encouraged. Proceed with caution.
-
-To prepare for Multi-Server Broadcasting, you must first enable it in your config.
-
-.. code-block::csharp6
-
- _client.UsingAudio(x =>
- {
- x.Mode = AudioMode.Outgoing;
- x.EnableMultiserver = true; // Enable Multiserver
- });
-
-From here on, it is as easy as creating an IAudioClient for each server you want to join. See the sections on broadcasting to proceed.
-
-
Receiving
----------
-
-**Receiving is not implemented in the latest version of Discord.Net**
\ No newline at end of file
+---------
\ No newline at end of file
diff --git a/docs/getting_started.rst b/docs/getting_started.rst
index f86b36231..f9dfd857d 100644
--- a/docs/getting_started.rst
+++ b/docs/getting_started.rst
@@ -22,12 +22,12 @@ You can get Discord.Net from NuGet:
If you have trouble installing from NuGet, try installing dependencies manually.
-You can also pull the latest source from `GitHub`_
+You can also pull the latest source from `GitHub`_
.. _Discord.Net: https://www.nuget.org/packages/Discord.Net
.. _Discord.Net.Commands: https://www.nuget.org/packages/Discord.Net.Commands
.. _Discord.Net.Modules: https://www.nuget.org/packages/Discord.Net.Modules
-.. _Discord.Net.Audio: https://www.nuget.org/packages/Discord.Net.Audio
+.. _Discord.Net.Modules: https://www.nuget.org/packages/Discord.Net.Audio
.. _GitHub: https://github.com/RogueException/Discord.Net/
Async
@@ -42,7 +42,7 @@ For more information, go to `MSDN's Await-Async section`_.
Example
-------
-
+
.. literalinclude:: samples/getting_started.cs
:language: csharp6
:tab-width: 2
diff --git a/docs/global.txt b/docs/global.txt
index 25b33510e..e5b572c93 100644
--- a/docs/global.txt
+++ b/docs/global.txt
@@ -1,4 +1,2 @@
.. |stub| unicode:: U+1F527
-.. |stub-desc| replace:: This page is a placeholder and has not been written yet. It should be coming soon!
-.. |outdated| replace:: **This page is currently out-of-date. The information below may be inaccurate.**
-.. |incomplete| replace:: **This page is incomplete. While the information below is accurate, it should be noted that it is not thorough.**
\ No newline at end of file
+.. |stub-desc| replace:: This page is a placeholder and has not been written yet. It should be coming soon!
\ No newline at end of file
diff --git a/docs/index.rst b/docs/index.rst
index bf5676406..d2ff662af 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -9,13 +9,13 @@ Feel free to join us in the `Discord API chat`_.
.. _Discord chat service: https://discordapp.com
.. _Discord API chat: https://discord.gg/0SBTUU1wZTVjAMPx
-.. warning::
+.. warn::
- This is a beta!
+This is a beta!
- This library has been built thanks to a community effort reverse engineering the Discord client.
- As the API is still unofficial, it may change at any time without notice, breaking this library as well.
- Discord.Net itself is still in development (and is currently undergoing a rewrite) and you may encounter breaking changes throughout development until the official Discord API is released.
+This library has been built thanks to a community effort reverse engineering the Discord client.
+As the API is still unofficial, it may change at any time without notice, breaking this library as well.
+Discord.Net itself is still in development (and is currently undergoing a rewrite) and you may encounter breaking changes throughout development until the official Discord API is released.
It is highly recommended that you always use the latest version and please report any bugs you find to our `Discord chat`_.
@@ -23,8 +23,6 @@ It is highly recommended that you always use the latest version and please repor
This Documentation is **currently undergoing a rewrite**. Some pages (marked with a wrench) are not updated, or are not completed yet.
-**The documentation is currently being written to reflect ``0.9-rc4``, which can be accessed via the latest git-master.**
-
.. toctree::
:caption: Documentation
:maxdepth: 2
diff --git a/docs/samples/events.cs b/docs/samples/events.cs
index 8a53c0bbc..7f68bf6cb 100644
--- a/docs/samples/events.cs
+++ b/docs/samples/events.cs
@@ -1,20 +1,20 @@
class Program
{
- private static DiscordClient _client;
+ private static DiscordBotClient _client;
static void Main(string[] args)
{
- _client = new DiscordClient();
+ var client = new DiscordClient();
// Handle Events using Lambdas
- _client.MessageReceived += (s, e) =>
+ client.MessageCreated += (s, e) =>
{
if (!e.Message.IsAuthor)
- await e.Channel.SendMessage("foo");
+ await client.SendMessage(e.Message.ChannelId, "foo");
}
// Handle Events using Event Handlers
EventHandler handler = new EventHandler(HandleMessageCreated);
- client.MessageReceived += handler;
+ client.MessageCreated += handler;
}
@@ -22,6 +22,6 @@ class Program
static void HandleMessageCreated(object sender, EventArgs e)
{
if (!e.Message.IsAuthor)
- await e.Channel.SendMessage("bar");
+ await client.SendMessage(e.Message.ChannelId, "foo");
}
-}
+}
\ No newline at end of file
diff --git a/docs/samples/getting_started.cs b/docs/samples/getting_started.cs
index d471fbc65..55f7923a4 100644
--- a/docs/samples/getting_started.cs
+++ b/docs/samples/getting_started.cs
@@ -2,13 +2,10 @@ class Program
{
static void Main(string[] args)
{
- var client = new DiscordClient(x =>
- {
- LogLevel = LogSeverity.Info
- });
+ var client = new DiscordClient();
//Display all log messages in the console
- client.Log.Message += (s, e) => Console.WriteLine($"[{e.Severity}] {e.Source}: {e.Message}");
+ client.LogMessage += (s, e) => Console.WriteLine($"[{e.Severity}] {e.Source}: {e.Message}");
//Echo back any message received, provided it didn't come from the bot itself
client.MessageReceived += async (s, e) =>
@@ -25,7 +22,7 @@ class Program
//If we are not a member of any server, use our invite code (made beforehand in the official Discord Client)
if (!client.Servers.Any())
- await (client.GetInvite("aaabbbcccdddeee")).Accept();
+ await client.AcceptInvite(client.GetInvite("aaabbbcccdddeee"));
});
}
}
diff --git a/docs/samples/logging.cs b/docs/samples/logging.cs
index 4fd3e4959..c68b8aded 100644
--- a/docs/samples/logging.cs
+++ b/docs/samples/logging.cs
@@ -1,5 +1,6 @@
class Program
{
+ private static DiscordBotClient _client;
static void Main(string[] args)
{
var client = new DiscordClient(x =>
@@ -7,13 +8,13 @@ class Program
LogLevel = LogSeverity.Info
});
- client.Log.Message += (s, e) => Console.WriteLine($"[{e.Severity}] {e.Source}: {e.Message}");
+ _client.Log.Message += (s, e) => Console.WriteLine($"[{e.Severity}] {e.Source}: {e.Message}");
client.ExecuteAndWait(async () =>
{
await client.Connect("discordtest@email.com", "Password123");
if (!client.Servers.Any())
- await (client.GetInvite("aaabbbcccdddeee")).Accept();
+ await client.AcceptInvite("aaabbbcccdddeee");
});
}
}
diff --git a/docs/samples/permissions.cs b/docs/samples/permissions.cs
index 65681d0f9..419026714 100644
--- a/docs/samples/permissions.cs
+++ b/docs/samples/permissions.cs
@@ -1,8 +1,14 @@
-
// Find a User's Channel Permissions
-var UserPerms = _channel.GetPermissionsRule(_user);
+var userChannelPermissions = user.GetPermissions(channel);
+
+// Find a User's Server Permissions
+var userServerPermissions = user.ServerPermissions();
+var userServerPermissions = server.GetPermissions(user);
-// Set a User's Channel Permissions
+// Set a User's Channel Permissions (using DualChannelPermissions)
-var NewOverwrites = new ChannelPermissionOverrides(sendMessages: PermValue.Deny);
-await channel.AddPermissionsRule(_user, NewOverwrites);
+var userPerms = user.GetPermissions(channel);
+userPerms.ReadMessageHistory = false;
+userPerms.AttachFiles = null;
+channel.AddPermissionsRule(user, userPerms);
+}
diff --git a/global.json b/global.json
index 4357be0d5..7f3ac9f7e 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,6 @@
{
- "projects": [ "src" ],
- "sdk": {
- "version": "1.0.0-rc1-update1"
- }
+ "projects": [ "src" ],
+ "sdk": {
+ "version": "1.0.0-rc2-20221"
+ }
}
\ No newline at end of file
diff --git a/ref/Discord.Net.xproj b/ref/Discord.Net.xproj
deleted file mode 100644
index d3559797d..000000000
--- a/ref/Discord.Net.xproj
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
- 14.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
-
-
- 5b2afee6-fff6-4ba2-be12-61b283b72ac0
- Discord
- ..\..\artifacts\obj\$(MSBuildProjectName)
- ..\..\artifacts\bin\$(MSBuildProjectName)\
-
-
- 2.0
-
-
- True
-
-
-
\ No newline at end of file
diff --git a/ref/DiscordClient.cs b/ref/DiscordClient.cs
deleted file mode 100644
index aa777e04f..000000000
--- a/ref/DiscordClient.cs
+++ /dev/null
@@ -1,75 +0,0 @@
-using Discord.Net.Rest;
-using Discord.Net.WebSockets;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Discord
-{
- /// Provides a connection to the DiscordApp service.
- public class DiscordClient : IDisposable
- {
- public event EventHandler Log = delegate { };
-
- public event EventHandler LoggedIn = delegate { };
- public event EventHandler LoggedOut = delegate { };
- public event EventHandler Connected = delegate { };
- public event EventHandler Disconnected = delegate { };
- public event EventHandler VoiceConnected = delegate { };
- public event EventHandler VoiceDisconnected = delegate { };
-
- public event EventHandler ChannelCreated = delegate { };
- public event EventHandler ChannelUpdated = delegate { };
- public event EventHandler ChannelDestroyed = delegate { };
- public event EventHandler MessageAcknowledged = delegate { };
- public event EventHandler MessageDeleted = delegate { };
- public event EventHandler MessageReceived = delegate { };
- public event EventHandler MessageSent = delegate { };
- public event EventHandler MessageUpdated = delegate { };
- public event EventHandler ProfileUpdated = delegate { };
- public event EventHandler RoleCreated = delegate { };
- public event EventHandler RoleUpdated = delegate { };
- public event EventHandler RoleDeleted = delegate { };
- public event EventHandler JoinedServer = delegate { };
- public event EventHandler LeftServer = delegate { };
- public event EventHandler ServerAvailable = delegate { };
- public event EventHandler ServerUpdated = delegate { };
- public event EventHandler ServerUnavailable = delegate { };
- public event EventHandler UserBanned = delegate { };
- public event EventHandler UserIsTyping = delegate { };
- public event EventHandler UserJoined = delegate { };
- public event EventHandler UserLeft = delegate { };
- public event EventHandler UserUpdated = delegate { };
- public event EventHandler UserUnbanned = delegate { };
-
- public MessageQueue MessageQueue { get; }
- public IRestClient RestClient { get; }
- public GatewaySocket GatewaySocket { get; }
- public Profile CurrentUser { get; }
-
- public DiscordClient() { }
- public DiscordClient(DiscordConfig config) { }
-
- public Task Login(string token) => null;
- public Task Logout() => null;
-
- public Task Connect() => null;
- public Task Connect(int connectionId, int totalConnections) => null;
- public Task Disconnect() => null;
-
- public Task> GetPrivateChannels() => null;
- public Task GetPrivateChannel(ulong userId) => null;
- public Task GetInvite(string inviteIdOrXkcd) => null;
- public Task> GetRegions() => null;
- public Task GetRegion(string id) => null;
- public Task> GetServers() => null;
- public Task GetServer(ulong id) => null;
-
- public Task CreatePrivateChannel(ulong userId) => null;
- public Task CreateServer(string name, Region region, ImageType iconType = ImageType.None, Stream icon = null) => null;
-
- public void Dispose() { }
- }
-}
\ No newline at end of file
diff --git a/ref/DiscordConfig.cs b/ref/DiscordConfig.cs
deleted file mode 100644
index e6b1a5568..000000000
--- a/ref/DiscordConfig.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-using Discord.Net.Rest;
-using Discord.Net.WebSockets;
-using System.Reflection;
-
-namespace Discord
-{
- public class DiscordConfig
- {
- public const int MaxMessageSize = 2000;
- public const int MaxMessagesPerBatch = 100;
-
- public const string LibName = "Discord.Net";
- public static string LibVersion => typeof(DiscordConfig).GetTypeInfo().Assembly?.GetName().Version.ToString(3) ?? "Unknown";
- public const string LibUrl = "https://github.com/RogueException/Discord.Net";
-
- public const string ClientAPIUrl = "https://discordapp.com/api/";
- public const string CDNUrl = "https://cdn.discordapp.com/";
- public const string InviteUrl = "https://discord.gg/";
-
- /// Gets or sets name of your application, used in the user agent.
- public string AppName { get; set; } = null;
- /// Gets or sets url to your application, used in the user agent.
- public string AppUrl { get; set; } = null;
- /// Gets or sets the version of your application, used in the user agent.
- public string AppVersion { get; set; } = null;
-
- /// Gets or sets the minimum log level severity that will be sent to the LogMessage event.
- public LogSeverity LogLevel { get; set; } = LogSeverity.Info;
-
- /// Gets or sets the time (in milliseconds) to wait for the websocket to connect and initialize.
- public int ConnectionTimeout { get; set; } = 30000;
- /// Gets or sets the time (in milliseconds) to wait after an unexpected disconnect before reconnecting.
- public int ReconnectDelay { get; set; } = 1000;
- /// Gets or sets the time (in milliseconds) to wait after an reconnect fails before retrying.
- public int FailedReconnectDelay { get; set; } = 15000;
-
- //Performance
-
- /// Gets or sets the number of messages per channel that should be kept in cache. Setting this to zero disables the message cache entirely.
- public int MessageCacheSize { get; set; } = 100;
- ///
- /// Gets or sets whether the permissions cache should be used.
- /// This makes operations such as User.GetPermissions(Channel), User.ServerPermissions, Channel.GetUser, and Channel.Members much faster while increasing memory usage.
- ///
- public bool UsePermissionsCache { get; set; } = true;
- /// Gets or sets whether the a copy of a model is generated on an update event to allow you to check which properties changed.
- public bool EnablePreUpdateEvents { get; set; } = true;
- ///
- /// Gets or sets the max number of users a server may have for offline users to be included in the READY packet. Max is 250.
- /// Decreasing this may reduce CPU usage while increasing login time and network usage.
- ///
- public int LargeThreshold { get; set; } = 250;
-
- //Engines
-
- /// Gets or sets the REST engine to use.. Defaults to DefaultRestClientProvider, which uses .Net's HttpClient class.
- public IRestClientProvider RestClientProvider { get; set; } = null;
- ///
- /// Gets or sets the WebSocket engine to use. Defaults to DefaultWebSocketProvider, which uses .Net's WebSocketClient class.
- /// WebSockets are only used if DiscordClient.Connect() is called.
- ///
- public IWebSocketProvider WebSocketProvider { get; set; } = null;
- }
-}
-
diff --git a/ref/Entities/Channels/IPublicChannel.cs b/ref/Entities/Channels/IPublicChannel.cs
deleted file mode 100644
index bd005a288..000000000
--- a/ref/Entities/Channels/IPublicChannel.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-using System.Collections.Generic;
-using System.Threading.Tasks;
-
-namespace Discord
-{
- public interface IPublicChannel : IChannel
- {
- /// Gets the server this channel is a member of.
- Server Server { get; }
- /// Gets a collection of permission overwrites for this channel.
- IEnumerable PermissionOverwrites { get; }
- /// Gets the position of this public channel relative to others of the same type.
- int Position { get; }
-
- /// Gets a user in this channel with the given id.
- new Task GetUser(ulong id);
- /// Gets a collection of all users in this channel.
- new Task> GetUsers();
-
- /// Gets the permission overwrite for a specific user, or null if one does not exist.
- OverwritePermissions? GetPermissionOverwrite(ServerUser user);
- /// Gets the permission overwrite for a specific role, or null if one does not exist.
- OverwritePermissions? GetPermissionOverwrite(Role role);
- /// Downloads a collection of all invites to this server.
- Task> GetInvites();
-
- /// Adds or updates the permission overwrite for the given user.
- Task UpdatePermissionOverwrite(ServerUser user, OverwritePermissions permissions);
- /// Adds or updates the permission overwrite for the given role.
- Task UpdatePermissionOverwrite(Role role, OverwritePermissions permissions);
- /// Removes the permission overwrite for the given user, if one exists.
- Task RemovePermissionOverwrite(ServerUser user);
- /// Removes the permission overwrite for the given role, if one exists.
- Task RemovePermissionOverwrite(Role role);
-
- /// Creates a new invite to this channel.
- /// Time (in seconds) until the invite expires. Set to null to never expire.
- /// The max amount of times this invite may be used. Set to null to have unlimited uses.
- /// If true, a user accepting this invite will be kicked from the server after closing their client.
- /// If true, creates a human-readable link. Not supported if maxAge is set to null.
- Task CreateInvite(int? maxAge = 1800, int? maxUses = null, bool tempMembership = false, bool withXkcd = false);
- }
-}
diff --git a/ref/Entities/Channels/PrivateChannel.cs b/ref/Entities/Channels/PrivateChannel.cs
deleted file mode 100644
index ee72c0828..000000000
--- a/ref/Entities/Channels/PrivateChannel.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-using System.Collections.Generic;
-using System.IO;
-using System.Threading.Tasks;
-
-namespace Discord
-{
- public class PrivateChannel : ITextChannel, IChannel
- {
- ///
- public DiscordClient Discord { get; }
- ///
- public EntityState State { get; }
- ///
- public ulong Id { get; }
- ///
- public PrivateUser Recipient { get; }
- ///
- public PrivateUser CurrentUser { get; }
-
- ///
- ChannelType IChannel.Type => ChannelType.Private | ChannelType.Text;
- ///
- public string Name { get; }
-
- ///
- public Task GetUser(ulong id) => null;
- ///
- Task IChannel.GetUser(ulong id) => null;
- ///
- public Task> GetUsers() => null;
- ///
- Task> IChannel.GetUsers() => null;
- ///
- public Task GetMessage(ulong id) => null;
- ///
- public Task> GetMessages(int limit = 100) => null;
- ///
- public Task> GetMessages(int limit = 100, ulong? relativeMessageId = null, Relative relativeDir = Relative.Before) => null;
-
- ///
- public Task SendMessage(string text, bool isTTS = false) => null;
- ///
- public Task SendFile(string filePath, string text = null, bool isTTS = false) => null;
- ///
- public Task SendFile(Stream stream, string filename, string text = null, bool isTTS = false) => null;
-
- ///
- public Task SendIsTyping() => null;
-
- ///
- public Task Update() => null;
- ///
- public Task Delete() => null;
- }
-}
diff --git a/ref/Entities/Channels/TextChannel.cs b/ref/Entities/Channels/TextChannel.cs
deleted file mode 100644
index 0b1b81c77..000000000
--- a/ref/Entities/Channels/TextChannel.cs
+++ /dev/null
@@ -1,91 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Threading.Tasks;
-
-namespace Discord
-{
- public class TextChannel : ITextChannel, IMentionable, IModifiable
- {
- public sealed class Properties
- {
- public string Name { get; }
- public string Topic { get; }
- public int Position { get; }
- }
-
- ///
- public EntityState State { get; }
- ///
- public ulong Id { get; }
- ///
- public Server Server { get; }
-
- ///
- public DiscordClient Discord { get; }
- ///
- public ChannelType Type => ChannelType.Public | ChannelType.Text;
-
- ///
- public string Name { get; }
- ///
- public string Topic { get; }
- ///
- public int Position { get; }
-
- ///
- public string Mention { get; }
- ///
- public IEnumerable PermissionOverwrites { get; }
-
- ///
- public OverwritePermissions? GetPermissionOverwrite(ServerUser user) => null;
- ///
- public OverwritePermissions? GetPermissionOverwrite(Role role) => null;
- ///
- public Task GetUser(ulong id) => null;
- ///
- Task IChannel.GetUser(ulong id) => null;
- ///
- public Task> GetUsers() => null;
- ///
- Task> IChannel.GetUsers() => null;
- ///
- public Task GetMessage(ulong id) => null;
- ///
- public Task> GetMessages(int limit = 100) => null;
- ///
- public Task> GetMessages(int limit = 100, ulong? relativeMessageId = null, Relative relativeDir = Relative.Before) => null;
- ///
- public Task> GetInvites() => null;
-
- ///
- public Task UpdatePermissionOverwrite(ServerUser user, OverwritePermissions permissions) => null;
- ///
- public Task UpdatePermissionOverwrite(Role role, OverwritePermissions permissions) => null;
- ///
- public Task RemovePermissionOverwrite(ServerUser user) => null;
- ///
- public Task RemovePermissionOverwrite(Role role) => null;
-
- ///
- public Task SendMessage(string text, bool isTTS = false) => null;
- ///
- public Task SendFile(string filePath, string text = null, bool isTTS = false) => null;
- ///
- public Task SendFile(Stream stream, string filename, string text = null, bool isTTS = false) => null;
-
- ///
- public Task SendIsTyping() => null;
-
- ///
- public Task CreateInvite(int? maxAge = 1800, int? maxUses = null, bool tempMembership = false, bool withXkcd = false) => null;
-
- ///
- public Task Update() => null;
- ///
- public Task Modify(Action func) => null;
- ///
- public Task Delete() => null;
- }
-}
diff --git a/ref/Entities/Channels/VoiceChannel.cs b/ref/Entities/Channels/VoiceChannel.cs
deleted file mode 100644
index 6552fadd7..000000000
--- a/ref/Entities/Channels/VoiceChannel.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-
-namespace Discord
-{
- public class VoiceChannel : IPublicChannel, IModifiable
- {
- public sealed class Properties
- {
- public string Name { get; }
- public int Bitrate { get; set; }
- public int Position { get; }
- }
-
- ///
- public ulong Id { get; }
- ///
- public EntityState State { get; }
- ///
- public Server Server { get; }
-
- ///
- public DiscordClient Discord { get; }
- ///
- ChannelType IChannel.Type => ChannelType.Public | ChannelType.Voice;
-
- ///
- public string Name { get; }
- ///
- public int Position { get; }
- ///
- public int Bitrate { get; }
-
- ///
- public string Mention { get; }
- ///
- public IEnumerable PermissionOverwrites { get; }
-
- ///
- public OverwritePermissions? GetPermissionOverwrite(ServerUser user) => null;
- ///
- public OverwritePermissions? GetPermissionOverwrite(Role role) => null;
- ///
- public Task GetUser(ulong id) => null;
- ///
- Task IChannel.GetUser(ulong id) => null;
- ///
- public Task> GetUsers() => null;
- ///
- Task> IChannel.GetUsers() => null;
- ///
- public Task> GetInvites() => null;
-
- ///
- public Task UpdatePermissionOverwrite(ServerUser user, OverwritePermissions permissions) => null;
- ///
- public Task UpdatePermissionOverwrite(Role role, OverwritePermissions permissions) => null;
- ///
- public Task RemovePermissionOverwrite(ServerUser user) => null;
- ///
- public Task RemovePermissionOverwrite(Role role) => null;
-
- ///
- public Task CreateInvite(int? maxAge = 1800, int? maxUses = null, bool tempMembership = false, bool withXkcd = false) => null;
-
- ///
- public Task Update() => null;
- ///
- public Task Modify(Action func) => null;
- ///
- public Task Delete() => null;
- }
-}
diff --git a/ref/Entities/Color.cs b/ref/Entities/Color.cs
deleted file mode 100644
index b3c78debf..000000000
--- a/ref/Entities/Color.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-namespace Discord
-{
- public class Color
- {
- public static readonly Color Default = new Color(0);
-
- public uint RawValue { get; }
-
- public Color(uint rawValue) { }
- public Color(byte r, byte g, byte b) { }
- public Color(float r, float g, float b) { }
-
- public byte R { get; }
- public byte G { get; }
- public byte B { get; }
- }
-}
diff --git a/ref/Entities/IModifiable.cs b/ref/Entities/IModifiable.cs
deleted file mode 100644
index f264c96f2..000000000
--- a/ref/Entities/IModifiable.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using System;
-using System.Threading.Tasks;
-
-namespace Discord
-{
- public interface IModifiable
- {
- /// Modifies one or more of the properties of this object.
- Task Modify(Action func);
- }
-}
diff --git a/ref/Entities/Invite/BasicInvite.cs b/ref/Entities/Invite/BasicInvite.cs
deleted file mode 100644
index 37cd1704d..000000000
--- a/ref/Entities/Invite/BasicInvite.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System.Threading.Tasks;
-
-namespace Discord
-{
- public class BasicInvite : IEntity
- {
- public class TargetInfo
- {
- public ulong Id { get; }
- public string Name { get; }
- }
- public class InviterInfo
- {
- public ulong Id { get; }
- public string Name { get; }
- public ushort Discriminator { get; }
- public string AvatarId { get; }
- public string AvatarUrl { get; }
- }
-
- string IEntity.Id => Code;
- public DiscordClient Discord { get; }
- public EntityState State { get; }
-
- public string Code { get; }
- public string XkcdCode { get; }
-
- public TargetInfo Server { get; }
- public TargetInfo Channel { get; }
-
- public string Url { get; }
-
- public Task Accept() => null;
-
- public virtual Task Update() => null;
- }
-}
diff --git a/ref/Entities/Invite/Invite.cs b/ref/Entities/Invite/Invite.cs
deleted file mode 100644
index 11fead2af..000000000
--- a/ref/Entities/Invite/Invite.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System;
-using System.Threading.Tasks;
-
-namespace Discord
-{
- public class Invite : BasicInvite
- {
- public int? MaxAge { get; }
- public int Uses { get; }
- public int? MaxUses { get; }
- public bool IsRevoked { get; }
- public bool IsTemporary { get; }
- public DateTime CreatedAt { get; }
-
- public override Task Update() => null;
- public Task Delete() => null;
- }
-}
diff --git a/ref/Entities/Message.cs b/ref/Entities/Message.cs
deleted file mode 100644
index 78c4e41bd..000000000
--- a/ref/Entities/Message.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-
-namespace Discord
-{
- public class Message : IEntity
- {
- public class Attachment : File
- {
- public string Id { get; }
- public int Size { get; }
- public string Filename { get; }
- }
-
- public class Embed
- {
- public string Url { get; }
- public string Type { get; }
- public string Title { get; }
- public string Description { get; }
- public EmbedLink Author { get; }
- public EmbedLink Provider { get; }
- public File Thumbnail { get; }
- public File Video { get; }
- }
-
- public class EmbedLink
- {
- public string Url { get; }
- public string Name { get; }
- }
-
- public class File
- {
- public string Url { get; }
- public string ProxyUrl { get; }
- public int? Width { get; }
- public int? Height { get; }
- }
-
- public ulong Id { get; }
- public DiscordClient Discord { get; }
- public EntityState State { get; }
-
- public ITextChannel Channel { get; }
- public IUser User { get; }
- public bool IsTTS { get; }
- public string RawText { get; }
- public string Text { get; }
- public DateTime Timestamp { get; }
- public DateTime? EditedTimestamp { get; }
- public Attachment[] Attachments { get; }
- public Embed[] Embeds { get; }
-
- public IReadOnlyList MentionedUsers { get; }
- public IReadOnlyList MentionedChannels { get; }
- public IReadOnlyList MentionedRoles { get; }
-
- public Server Server => null;
- public bool IsAuthor => false;
-
- public bool IsMentioningMe(bool includeRoles = false) => false;
-
- public Task Update() => null;
- public Task Delete() => null;
- }
-}
diff --git a/ref/Entities/Permissions/ChannelPermissions.cs b/ref/Entities/Permissions/ChannelPermissions.cs
deleted file mode 100644
index d01f0430e..000000000
--- a/ref/Entities/Permissions/ChannelPermissions.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-namespace Discord
-{
- public struct ChannelPermissions
- {
- public static ChannelPermissions None { get; }
- public static ChannelPermissions TextOnly { get; }
- public static ChannelPermissions PrivateOnly { get; }
- public static ChannelPermissions VoiceOnly { get; }
- public static ChannelPermissions All(ChannelType channelType) => default(ChannelPermissions);
-
- public uint RawValue { get; }
-
- public bool CreateInstantInvite { get; }
- public bool ManagePermission { get; }
- public bool ManageChannel { get; }
-
- public bool ReadMessages { get; }
- public bool SendMessages { get; }
- public bool SendTTSMessages { get; }
- public bool ManageMessages { get; }
- public bool EmbedLinks { get; }
- public bool AttachFiles { get; }
- public bool ReadMessageHistory { get; }
- public bool MentionEveryone { get; }
-
- public bool Connect { get; }
- public bool Speak { get; }
- public bool MuteMembers { get; }
- public bool DeafenMembers { get; }
- public bool MoveMembers { get; }
- public bool UseVoiceActivation { get; }
-
- public ChannelPermissions(bool? createInstantInvite = null, bool? managePermissions = null,
- bool? manageChannel = null, bool? readMessages = null, bool? sendMessages = null, bool? sendTTSMessages = null,
- bool? manageMessages = null, bool? embedLinks = null, bool? attachFiles = null, bool? readMessageHistory = null,
- bool? mentionEveryone = null, bool? connect = null, bool? speak = null, bool? muteMembers = null, bool? deafenMembers = null,
- bool? moveMembers = null, bool? useVoiceActivation = null)
- : this()
- {
- }
- public ChannelPermissions(uint rawValue)
- : this()
- {
- }
-
- public ChannelPermissions Modify(bool? createInstantInvite = null, bool? managePermissions = null,
- bool? manageChannel = null, bool? readMessages = null, bool? sendMessages = null, bool? sendTTSMessages = null,
- bool? manageMessages = null, bool? embedLinks = null, bool? attachFiles = null, bool? readMessageHistory = null,
- bool? mentionEveryone = null, bool? connect = null, bool? speak = null, bool? muteMembers = null, bool? deafenMembers = null,
- bool? moveMembers = null, bool? useVoiceActivation = null)
- => default(ChannelPermissions);
- }
-}
diff --git a/ref/Entities/Permissions/OverwritePermissions.cs b/ref/Entities/Permissions/OverwritePermissions.cs
deleted file mode 100644
index 1cda173ec..000000000
--- a/ref/Entities/Permissions/OverwritePermissions.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-namespace Discord
-{
- public struct OverwritePermissions
- {
- public static OverwritePermissions InheritAll { get; }
-
- public uint AllowValue { get; }
- public uint DenyValue { get; }
-
- public PermValue CreateInstantInvite { get; }
- public PermValue ManagePermissions { get; }
- public PermValue ManageChannel { get; }
- public PermValue ReadMessages { get; }
- public PermValue SendMessages { get; }
- public PermValue SendTTSMessages { get; }
- public PermValue ManageMessages { get; }
- public PermValue EmbedLinks { get; }
- public PermValue AttachFiles { get; }
- public PermValue ReadMessageHistory { get; }
- public PermValue MentionEveryone { get; }
-
- public PermValue Connect { get; }
- public PermValue Speak { get; }
- public PermValue MuteMembers { get; }
- public PermValue DeafenMembers { get; }
- public PermValue MoveMembers { get; }
- public PermValue UseVoiceActivation { get; }
-
- public OverwritePermissions(PermValue? createInstantInvite = null, PermValue? managePermissions = null,
- PermValue? manageChannel = null, PermValue? readMessages = null, PermValue? sendMessages = null, PermValue? sendTTSMessages = null,
- PermValue? manageMessages = null, PermValue? embedLinks = null, PermValue? attachFiles = null, PermValue? readMessageHistory = null,
- PermValue? mentionEveryone = null, PermValue? connect = null, PermValue? speak = null, PermValue? muteMembers = null, PermValue? deafenMembers = null,
- PermValue? moveMembers = null, PermValue? useVoiceActivation = null)
- : this()
- {
- }
-
- public OverwritePermissions(uint allow = 0, uint deny = 0)
- : this()
- {
- }
-
- public OverwritePermissions Modify(PermValue? createInstantInvite = null, PermValue? managePermissions = null,
- PermValue? manageChannel = null, PermValue? readMessages = null, PermValue? sendMessages = null, PermValue? sendTTSMessages = null,
- PermValue? manageMessages = null, PermValue? embedLinks = null, PermValue? attachFiles = null, PermValue? readMessageHistory = null,
- PermValue? mentionEveryone = null, PermValue? connect = null, PermValue? speak = null, PermValue? muteMembers = null, PermValue? deafenMembers = null,
- PermValue? moveMembers = null, PermValue? useVoiceActivation = null)
- => default(OverwritePermissions);
- }
-}
diff --git a/ref/Entities/Permissions/PermissionOverwriteEntry.cs b/ref/Entities/Permissions/PermissionOverwriteEntry.cs
deleted file mode 100644
index bbc11fba8..000000000
--- a/ref/Entities/Permissions/PermissionOverwriteEntry.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Discord
-{
- public struct PermissionOverwriteEntry
- {
- public PermissionTarget TargetType { get; }
- public ulong TargetId { get; }
- public OverwritePermissions Permissions { get; }
- }
-}
diff --git a/ref/Entities/Permissions/ServerPermissions.cs b/ref/Entities/Permissions/ServerPermissions.cs
deleted file mode 100644
index fe85c07dd..000000000
--- a/ref/Entities/Permissions/ServerPermissions.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-namespace Discord
-{
- public struct ServerPermissions
- {
- public static ServerPermissions None { get; }
- public static ServerPermissions All { get; }
-
- public uint RawValue { get; }
-
- public bool CreateInstantInvite { get; }
- public bool BanMembers { get; }
- public bool KickMembers { get; }
- public bool ManageRoles { get; }
- public bool ManageChannels { get; }
- public bool ManageServer { get; }
-
- public bool ReadMessages { get; }
- public bool SendMessages { get; }
- public bool SendTTSMessages { get; }
- public bool ManageMessages { get; }
- public bool EmbedLinks { get; }
- public bool AttachFiles { get; }
- public bool ReadMessageHistory { get; }
- public bool MentionEveryone { get; }
-
- public bool Connect { get; }
- public bool Speak { get; }
- public bool MuteMembers { get; }
- public bool DeafenMembers { get; }
- public bool MoveMembers { get; }
- public bool UseVoiceActivation { get; }
-
- public ServerPermissions(bool? createInstantInvite = null, bool? manageRoles = null,
- bool? kickMembers = null, bool? banMembers = null, bool? manageChannel = null, bool? manageServer = null,
- bool? readMessages = null, bool? sendMessages = null, bool? sendTTSMessages = null, bool? manageMessages = null,
- bool? embedLinks = null, bool? attachFiles = null, bool? readMessageHistory = null, bool? mentionEveryone = null,
- bool? connect = null, bool? speak = null, bool? muteMembers = null, bool? deafenMembers = null,
- bool? moveMembers = null, bool? useVoiceActivation = null)
- : this()
- {
- }
- public ServerPermissions(uint rawValue)
- : this()
- {
- }
-
- public ServerPermissions Modify(bool? createInstantInvite = null, bool? manageRoles = null,
- bool? kickMembers = null, bool? banMembers = null, bool? manageChannel = null, bool? manageServer = null,
- bool? readMessages = null, bool? sendMessages = null, bool? sendTTSMessages = null, bool? manageMessages = null,
- bool? embedLinks = null, bool? attachFiles = null, bool? readMessageHistory = null, bool? mentionEveryone = null,
- bool? connect = null, bool? speak = null, bool? muteMembers = null, bool? deafenMembers = null,
- bool? moveMembers = null, bool? useVoiceActivation = null)
- => default(ServerPermissions);
- }
-}
diff --git a/ref/Entities/Profile.cs b/ref/Entities/Profile.cs
deleted file mode 100644
index aa61e51b2..000000000
--- a/ref/Entities/Profile.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using System.Threading.Tasks;
-
-namespace Discord
-{
- public class Profile : IEntity
- {
- public ulong Id { get; }
- public DiscordClient Discord { get; }
- public EntityState State { get; }
-
- public string AvatarId { get; }
- public string AvatarUrl { get; }
- public ushort Discriminator { get; }
- public string CurrentGame { get; }
- public UserStatus Status { get; }
- public string Mention { get; }
- public string Email { get; }
- public bool? IsVerified { get; }
-
- public string Name { get; set; }
-
- public Task Update() => null;
- public Task Delete() => null;
- }
-}
diff --git a/ref/Entities/Region.cs b/ref/Entities/Region.cs
deleted file mode 100644
index fbb801eaa..000000000
--- a/ref/Entities/Region.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace Discord
-{
- public class Region
- {
- public string Id { get; }
- public string Name { get; }
- public string Hostname { get; }
- public int Port { get; }
- public bool Vip { get; }
- }
-}
diff --git a/ref/Entities/Role.cs b/ref/Entities/Role.cs
deleted file mode 100644
index f5155db2e..000000000
--- a/ref/Entities/Role.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using System.Collections.Generic;
-using System.Threading.Tasks;
-
-namespace Discord
-{
- public class Role : IEntity, IMentionable
- {
- public ulong Id { get; }
- public DiscordClient Discord { get; }
- public EntityState State { get; }
-
- public Server Server { get; }
-
- public string Name { get; }
- public bool IsHoisted { get; }
- public int Position { get; }
- public bool IsManaged { get; }
- public ServerPermissions Permissions { get; }
- public Color Color { get; }
-
- public bool IsEveryone { get; }
- public IEnumerable Members { get; }
-
- public string Mention { get; }
-
- public Task Update() => null;
- public Task Delete() => null;
- }
-}
diff --git a/ref/Entities/Server.cs b/ref/Entities/Server.cs
deleted file mode 100644
index a9078cb4b..000000000
--- a/ref/Entities/Server.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-
-namespace Discord
-{
- public class Server : IEntity
- {
- public class Emoji
- {
- public string Id { get; }
- public string Name { get; }
- public bool IsManaged { get; }
- public bool RequireColons { get; }
- public IEnumerable Roles { get; }
- }
-
- public ulong Id { get; }
- public DiscordClient Discord { get; }
- public EntityState State { get; }
-
- public ServerUser CurrentUser { get; }
- public string IconId { get; }
- public string SplashId { get; }
- public string IconUrl { get; }
- public string SplashUrl { get; }
- public int ChannelCount { get; }
- public int UserCount { get; }
- public int RoleCount { get; }
- public TextChannel DefaultChannel { get; }
- public Role EveryoneRole { get; }
- public IEnumerable Features { get; }
- public IEnumerable CustomEmojis { get; }
- public IEnumerable Channels { get; }
- public IEnumerable TextChannels { get; }
- public IEnumerable VoiceChannels { get; }
- public IEnumerable Users { get; }
- public IEnumerable Roles { get; }
-
- public string Name { get; set; }
- public Region Region { get; set; }
- public int AFKTimeout { get; set; }
- public DateTime JoinedAt { get; set; }
- public ServerUser Owner { get; set; }
- public VoiceChannel AFKChannel { get; set; }
-
- public Task GetChannel(ulong id) => null;
- public Task GetChannel(string mention) => null;
- public Task GetRole(ulong id) => null;
- public Task GetUser(ulong id) => null;
- public Task GetUser(string name, ushort discriminator) => null;
- public Task GetUser(string mention) => null;
- public Task> GetBans() => null;
- public Task> GetInvites() => null;
-
- public Task CreateTextChannel(string name) => null;
- public Task CreateVoiceChannel(string name) => null;
- public Task CreateInvite(int? maxAge = 1800, int? maxUses = null, bool tempMembership = false, bool withXkcd = false) => null;
- public Task CreateRole(string name, ServerPermissions? permissions = null, Color color = null, bool isHoisted = false) => null;
-
- public Task PruneUsers(int days = 30, bool simulate = false) => null;
-
- public Task Update() => null;
- public Task Leave() => null;
- public Task Delete() => null;
- }
-}
diff --git a/ref/Entities/Users/IUser.cs b/ref/Entities/Users/IUser.cs
deleted file mode 100644
index 02dd2d85b..000000000
--- a/ref/Entities/Users/IUser.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System.Threading.Tasks;
-
-namespace Discord
-{
- public interface IUser : IEntity, IMentionable
- {
- bool IsPrivate { get; }
-
- string Name { get; }
- ushort Discriminator { get; }
- bool IsBot { get; }
- string AvatarId { get; }
- string AvatarUrl { get; }
- string CurrentGame { get; }
- UserStatus Status { get; }
-
- Task GetPrivateChannel();
- }
-}
diff --git a/ref/Entities/Users/PrivateUser.cs b/ref/Entities/Users/PrivateUser.cs
deleted file mode 100644
index a6cc9d6e7..000000000
--- a/ref/Entities/Users/PrivateUser.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-using System.Threading.Tasks;
-
-namespace Discord
-{
- //TODO: Should this be linked directly to the Profile when it represents us, instead of maintaining a cache of values?
- public class PrivateUser : IUser
- {
- ///
- public EntityState State { get; internal set; }
- ///
- public ulong Id { get; }
- /// Returns the private channel for this user.
- public PrivateChannel Channel { get; }
-
- ///
- bool IUser.IsPrivate => true;
-
- ///
- public string Name { get; }
- ///
- public ushort Discriminator { get; }
- ///
- public bool IsBot { get; }
- ///
- public string AvatarId { get; }
- ///
- public string CurrentGame { get; }
- ///
- public UserStatus Status { get; }
-
- ///
- public DiscordClient Discord => Channel.Discord;
- ///
- public string AvatarUrl { get; }
- ///
- public string Mention { get; }
-
- ///
- Task IUser.GetPrivateChannel() => Task.FromResult(Channel);
-
- public Task Update() => null;
- }
-}
diff --git a/ref/Entities/Users/ServerUser.cs b/ref/Entities/Users/ServerUser.cs
deleted file mode 100644
index 4ff86f67a..000000000
--- a/ref/Entities/Users/ServerUser.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-
-namespace Discord
-{
- public class ServerUser : IUser
- {
- ///
- public EntityState State { get; }
- ///
- public ulong Id { get; }
- /// Returns the private channel for this user.
- public Server Server { get; }
-
- ///
- bool IUser.IsPrivate => false;
-
- ///
- public string Name { get; }
- ///
- public ushort Discriminator { get; }
- ///
- public bool IsBot { get; }
- ///
- public string AvatarId { get; }
- ///
- public string CurrentGame { get; }
- ///
- public UserStatus Status { get; }
- ///
- public DateTime JoinedAt { get; }
- ///
- public IReadOnlyList Roles { get; }
-
- /// Returns true if this user has marked themselves as muted.
- public bool IsSelfMuted { get; }
- /// Returns true if this user has marked themselves as deafened.
- public bool IsSelfDeafened { get; }
- /// Returns true if the server is blocking audio from this user.
- public bool IsServerMuted { get; }
- /// Returns true if the server is blocking audio to this user.
- public bool IsServerDeafened { get; }
- /// Returns true if the server is temporarily blocking audio to/from this user.
- public bool IsServerSuppressed { get; }
- /// Gets this user's current voice channel.
- public VoiceChannel VoiceChannel { get; }
-
- ///
- public DiscordClient Discord { get; }
- ///
- public string AvatarUrl { get; }
- ///
- public string Mention { get; }
-
- public ServerPermissions ServerPermissions { get; }
-
- public ChannelPermissions GetPermissions(IPublicChannel channel) => default(ChannelPermissions);
- ///
- public Task GetPrivateChannel() => null;
- public Task> GetChannels() => null;
-
- public bool HasRole(Role role) => false;
-
- public Task AddRoles(params Role[] roles) => null;
- public Task RemoveRoles(params Role[] roles) => null;
-
- public Task Update() => null;
- public Task Kick() => null;
- public Task Ban(int pruneDays = 0) => null;
- public Task Unban() => null;
- }
-}
\ No newline at end of file
diff --git a/ref/Enums/ChannelType.cs b/ref/Enums/ChannelType.cs
deleted file mode 100644
index 5ebbf3aa6..000000000
--- a/ref/Enums/ChannelType.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System;
-
-namespace Discord
-{
- [Flags]
- public enum ChannelType : byte
- {
- Public = 0x01,
- Private = 0x02,
- Text = 0x10,
- Voice = 0x20
- }
-}
diff --git a/ref/Enums/ConnectionState.cs b/ref/Enums/ConnectionState.cs
deleted file mode 100644
index dfd4ac9eb..000000000
--- a/ref/Enums/ConnectionState.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Discord
-{
- public enum ConnectionState
- {
- Disconnected,
- Connecting,
- Connected,
- Disconnecting
- }
-}
diff --git a/ref/Enums/EntityState.cs b/ref/Enums/EntityState.cs
deleted file mode 100644
index 6ae71e4a3..000000000
--- a/ref/Enums/EntityState.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace Discord
-{
- public enum EntityState : byte
- {
- /// Object is not attached to a cache manager nor receiving live updates.
- Detached = 0,
- /// Object is attached to a cache manager and receiving live updates.
- Attached,
- /// Object was deleted.
- Deleted,
- /// Object is currently waiting to be created.
- Queued,
- /// Object's creation was aborted.
- Aborted,
- /// Object's creation failed.
- Failed
- }
-}
diff --git a/ref/Enums/ImageType.cs b/ref/Enums/ImageType.cs
deleted file mode 100644
index 738c67a3d..000000000
--- a/ref/Enums/ImageType.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Discord
-{
- public enum ImageType
- {
- None,
- Jpeg,
- Png
- }
-}
diff --git a/ref/Enums/LogSeverity.cs b/ref/Enums/LogSeverity.cs
deleted file mode 100644
index 785b0ef46..000000000
--- a/ref/Enums/LogSeverity.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace Discord
-{
- public enum LogSeverity
- {
- Critical = 0,
- Error = 1,
- Warning = 2,
- Info = 3,
- Verbose = 4,
- Debug = 5
- }
-}
diff --git a/ref/Enums/PermValue.cs b/ref/Enums/PermValue.cs
deleted file mode 100644
index fe048b016..000000000
--- a/ref/Enums/PermValue.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Discord
-{
- public enum PermValue
- {
- Allow,
- Deny,
- Inherit
- }
-}
diff --git a/ref/Enums/PermissionTarget.cs b/ref/Enums/PermissionTarget.cs
deleted file mode 100644
index 96595fb69..000000000
--- a/ref/Enums/PermissionTarget.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Discord
-{
- public enum PermissionTarget
- {
- Role,
- User
- }
-}
diff --git a/ref/Enums/Relative.cs b/ref/Enums/Relative.cs
deleted file mode 100644
index aade047d1..000000000
--- a/ref/Enums/Relative.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Discord
-{
- public enum Relative
- {
- Before,
- After
- }
-}
diff --git a/ref/Enums/UserStatus.cs b/ref/Enums/UserStatus.cs
deleted file mode 100644
index f2fdfda7c..000000000
--- a/ref/Enums/UserStatus.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Discord
-{
- public enum UserStatus
- {
- Online,
- Idle,
- Offline
- }
-}
diff --git a/ref/Events/ChannelEventArgs.cs b/ref/Events/ChannelEventArgs.cs
deleted file mode 100644
index 583075e08..000000000
--- a/ref/Events/ChannelEventArgs.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System;
-
-namespace Discord
-{
- public class ChannelEventArgs : EventArgs
- {
- public IChannel Channel => null;
- }
-}
diff --git a/ref/Events/ChannelUpdatedEventArgs.cs b/ref/Events/ChannelUpdatedEventArgs.cs
deleted file mode 100644
index bcd809521..000000000
--- a/ref/Events/ChannelUpdatedEventArgs.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System;
-
-namespace Discord
-{
- public class ChannelUpdatedEventArgs : EventArgs
- {
- public IChannel Before => null;
- public IChannel After => null;
- }
-}
diff --git a/ref/Events/DisconnectedEventArgs.cs b/ref/Events/DisconnectedEventArgs.cs
deleted file mode 100644
index 616f3f09d..000000000
--- a/ref/Events/DisconnectedEventArgs.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System;
-
-namespace Discord
-{
- public class DisconnectedEventArgs : EventArgs
- {
- public bool WasUnexpected => false;
- public Exception Exception => null;
- }
-}
diff --git a/ref/Events/LogMessageEventArgs.cs b/ref/Events/LogMessageEventArgs.cs
deleted file mode 100644
index 7dec182d1..000000000
--- a/ref/Events/LogMessageEventArgs.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System;
-
-namespace Discord
-{
- public class LogMessageEventArgs : EventArgs
- {
- public LogSeverity Severity => default(LogSeverity);
- public string Source => null;
- public string Message => null;
- public Exception Exception => null;
- }
-}
diff --git a/ref/Events/MessageEventArgs.cs b/ref/Events/MessageEventArgs.cs
deleted file mode 100644
index f75c7f1a8..000000000
--- a/ref/Events/MessageEventArgs.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using System;
-
-namespace Discord
-{
- public class MessageEventArgs : EventArgs
- {
- public Message Message => null;
- public IUser User => null;
- public ITextChannel Channel => null;
- }
-}
diff --git a/ref/Events/MessageUpdatedEventArgs.cs b/ref/Events/MessageUpdatedEventArgs.cs
deleted file mode 100644
index d323bf809..000000000
--- a/ref/Events/MessageUpdatedEventArgs.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System;
-
-namespace Discord
-{
- public class MessageUpdatedEventArgs : EventArgs
- {
- public Message Before => null;
- public Message After => null;
- public IUser User => null;
- public ITextChannel Channel => null;
- }
-}
diff --git a/ref/Events/ProfileUpdatedEventArgs.cs b/ref/Events/ProfileUpdatedEventArgs.cs
deleted file mode 100644
index dba55af3b..000000000
--- a/ref/Events/ProfileUpdatedEventArgs.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System;
-
-namespace Discord
-{
- public class ProfileUpdatedEventArgs : EventArgs
- {
- public Profile Before => null;
- public Profile After => null;
- }
-}
diff --git a/ref/Events/RoleEventArgs.cs b/ref/Events/RoleEventArgs.cs
deleted file mode 100644
index db1d09cbc..000000000
--- a/ref/Events/RoleEventArgs.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System;
-
-namespace Discord
-{
- public class RoleEventArgs : EventArgs
- {
- public Role Role => null;
- public Server Server => null;
- }
-}
diff --git a/ref/Events/RoleUpdatedEventArgs.cs b/ref/Events/RoleUpdatedEventArgs.cs
deleted file mode 100644
index 1fa0f2a81..000000000
--- a/ref/Events/RoleUpdatedEventArgs.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using System;
-
-namespace Discord
-{
- public class RoleUpdatedEventArgs : EventArgs
- {
- public Role Before => null;
- public Role After => null;
- public Server Server => null;
- }
-}
diff --git a/ref/Events/ServerEventArgs.cs b/ref/Events/ServerEventArgs.cs
deleted file mode 100644
index b06993de9..000000000
--- a/ref/Events/ServerEventArgs.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System;
-
-namespace Discord
-{
- public class ServerEventArgs : EventArgs
- {
- public Server Server => null;
- }
-}
diff --git a/ref/Events/ServerUpdatedEventArgs.cs b/ref/Events/ServerUpdatedEventArgs.cs
deleted file mode 100644
index 1e05f1721..000000000
--- a/ref/Events/ServerUpdatedEventArgs.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System;
-
-namespace Discord
-{
- public class ServerUpdatedEventArgs : EventArgs
- {
- public Server Before => null;
- public Server After => null;
- }
-}
diff --git a/ref/Events/TypingEventArgs.cs b/ref/Events/TypingEventArgs.cs
deleted file mode 100644
index f45313687..000000000
--- a/ref/Events/TypingEventArgs.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-namespace Discord
-{
- public class TypingEventArgs
- {
- public ITextChannel Channel { get; }
- public IUser User { get; }
-
- public TypingEventArgs(ITextChannel channel, IUser user)
- {
- Channel = channel;
- User = user;
- }
- }
-}
diff --git a/ref/Events/UserEventArgs.cs b/ref/Events/UserEventArgs.cs
deleted file mode 100644
index f1cce29fc..000000000
--- a/ref/Events/UserEventArgs.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using System;
-namespace Discord
-{
- public class UserEventArgs : EventArgs
- {
- public IUser User => null;
- }
-}
diff --git a/ref/Events/UserUpdatedEventArgs.cs b/ref/Events/UserUpdatedEventArgs.cs
deleted file mode 100644
index c45c60701..000000000
--- a/ref/Events/UserUpdatedEventArgs.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System;
-namespace Discord
-{
- public class UserUpdatedEventArgs : EventArgs
- {
- public IUser Before => null;
- public IUser After => null;
- }
-}
diff --git a/ref/Format.cs b/ref/Format.cs
deleted file mode 100644
index e30931ae9..000000000
--- a/ref/Format.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-namespace Discord
-{
- public static class Format
- {
- public static string Escape(string text) => null;
-
- public static string Bold(string text, bool escape = true) => null;
- public static string Italics(string text, bool escape = true) => null;
- public static string Underline(string text, bool escape = true) => null;
- public static string Strikeout(string text, bool escape = true) => null;
-
- public static string Code(string text, string language = null) => null;
- }
-}
diff --git a/ref/ILogger.cs b/ref/ILogger.cs
deleted file mode 100644
index a3123edc9..000000000
--- a/ref/ILogger.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using System;
-
-namespace Discord.Logging
-{
- public interface ILogger
- {
- LogSeverity Level { get; }
-
- void Log(LogSeverity severity, string message, Exception exception = null);
- void Error(string message, Exception exception = null);
- void Error(Exception exception);
- void Warning(string message, Exception exception = null);
- void Warning(Exception exception);
- void Info(string message, Exception exception = null);
- void Info(Exception exception);
- void Verbose(string message, Exception exception = null);
- void Verbose(Exception exception);
- void Debug(string message, Exception exception = null);
- void Debug(Exception exception);
-
-#if DOTNET5_4
- void Log(LogSeverity severity, FormattableString message, Exception exception = null);
- void Error(FormattableString message, Exception exception = null);
- void Warning(FormattableString message, Exception exception = null);
- void Info(FormattableString message, Exception exception = null);
- void Verbose(FormattableString message, Exception exception = null);
- void Debug(FormattableString message, Exception exception = null);
-#endif
- }
-}
diff --git a/ref/MessageQueue.cs b/ref/MessageQueue.cs
deleted file mode 100644
index 5f56abd1e..000000000
--- a/ref/MessageQueue.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Discord
-{
- public class MessageQueue
- {
- public int Count { get; }
-
- public void Clear() { }
- }
-}
diff --git a/ref/Net/HttpException.cs b/ref/Net/HttpException.cs
deleted file mode 100644
index 3704ffb83..000000000
--- a/ref/Net/HttpException.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-using System.Net;
-
-namespace Discord.Net
-{
- public class HttpException : Exception
- {
- public HttpStatusCode StatusCode { get; }
-
- public HttpException(HttpStatusCode statusCode)
- : base($"The server responded with error {(int)statusCode} ({statusCode})")
- {
- StatusCode = statusCode;
- }
- }
-}
diff --git a/ref/Net/Rest/CompletedRequestEventArgs.cs b/ref/Net/Rest/CompletedRequestEventArgs.cs
deleted file mode 100644
index ed9d1673f..000000000
--- a/ref/Net/Rest/CompletedRequestEventArgs.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-namespace Discord.Net.Rest
-{
- public class CompletedRequestEventArgs : RequestEventArgs
- {
- public object Response { get; set; }
- public string ResponseJson { get; set; }
- public double Milliseconds { get; set; }
-
- public CompletedRequestEventArgs(IRestRequest request, object response, string responseJson, double milliseconds)
- : base(request)
- {
- Response = response;
- ResponseJson = responseJson;
- Milliseconds = milliseconds;
- }
- }
-}
diff --git a/ref/Net/Rest/IRestClient.cs b/ref/Net/Rest/IRestClient.cs
deleted file mode 100644
index 83c0405c7..000000000
--- a/ref/Net/Rest/IRestClient.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Discord.Net.Rest
-{
- public interface IRestClient
- {
- event EventHandler SendingRequest;
- event EventHandler SentRequest;
-
- CancellationToken CancelToken { get; }
- string Token { get; }
-
- Task Send(IRestRequest request)
- where ResponseT : class;
- Task Send(IRestRequest request);
-
- Task Send(IRestFileRequest request)
- where ResponseT : class;
- Task Send(IRestFileRequest request);
- }
-}
diff --git a/ref/Net/Rest/IRestClientProvider.cs b/ref/Net/Rest/IRestClientProvider.cs
deleted file mode 100644
index cb22a7474..000000000
--- a/ref/Net/Rest/IRestClientProvider.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System.Collections.Generic;
-using System.Threading;
-
-namespace Discord.Net.Rest
-{
- public interface IRestClientProvider
- {
- IRestClient Create(string baseUrl, CancellationToken cancelToken);
- }
-}
diff --git a/ref/Net/Rest/RequestEventArgs.cs b/ref/Net/Rest/RequestEventArgs.cs
deleted file mode 100644
index cac734fc6..000000000
--- a/ref/Net/Rest/RequestEventArgs.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System;
-
-namespace Discord.Net.Rest
-{
- public class RequestEventArgs : EventArgs
- {
- public IRestRequest Request { get; set; }
- public bool Cancel { get; set; }
-
- public RequestEventArgs(IRestRequest request) { }
- }
-}
diff --git a/ref/Net/TimeoutException.cs b/ref/Net/TimeoutException.cs
deleted file mode 100644
index d1a644049..000000000
--- a/ref/Net/TimeoutException.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System;
-
-namespace Discord.Net
-{
- public class TimeoutException : OperationCanceledException
- {
- public TimeoutException() { }
- }
-}
diff --git a/ref/Net/WebSocketException.cs b/ref/Net/WebSocketException.cs
deleted file mode 100644
index df6377e13..000000000
--- a/ref/Net/WebSocketException.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System;
-
-namespace Discord.Net
-{
- public class WebSocketException : Exception
- {
- public int Code { get; }
- public string Reason { get; }
-
- public WebSocketException(int code, string reason) { }
- }
-}
diff --git a/ref/Net/WebSockets/BinaryMessageEventArgs.cs b/ref/Net/WebSockets/BinaryMessageEventArgs.cs
deleted file mode 100644
index 3fd4425fa..000000000
--- a/ref/Net/WebSockets/BinaryMessageEventArgs.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using System;
-
-namespace Discord.Net.WebSockets
-{
- public class BinaryMessageEventArgs : EventArgs
- {
- public byte[] Data { get; }
-
- public BinaryMessageEventArgs(byte[] data) { }
- }
-}
diff --git a/ref/Net/WebSockets/GatewaySocket.cs b/ref/Net/WebSockets/GatewaySocket.cs
deleted file mode 100644
index e8f2ddd3d..000000000
--- a/ref/Net/WebSockets/GatewaySocket.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using Discord.Net.Rest;
-using System;
-using System.Collections.Generic;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Discord.Net.WebSockets
-{
- public class GatewaySocket
- {
- public string SessionId { get; }
-
- public event EventHandler ReceivedDispatch = delegate { };
-
- public Task Connect(IRestClient rest, CancellationToken parentCancelToken) => null;
- public Task Disconnect() => null;
-
- public void SendIdentify(string token) { }
-
- public void SendResume() { }
- public void SendHeartbeat() { }
- public void SendUpdateStatus(long? idleSince, string gameName) { }
- public void SendUpdateVoice(ulong? serverId, ulong? channelId, bool isSelfMuted, bool isSelfDeafened) { }
- public void SendRequestMembers(IEnumerable serverId, string query, int limit) { }
-
- public void WaitForConnection(CancellationToken cancelToken) { }
- }
-}
diff --git a/ref/Net/WebSockets/IWebSocket.cs b/ref/Net/WebSockets/IWebSocket.cs
deleted file mode 100644
index 06a274305..000000000
--- a/ref/Net/WebSockets/IWebSocket.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-using System.Threading;
-
-namespace Discord.Net.WebSockets
-{
- public interface IWebSocket
- {
- CancellationToken CancelToken { get; }
- ConnectionState State { get; }
- string Host { get; set; }
-
- event EventHandler Connected;
- event EventHandler Disconnected;
- }
-}
diff --git a/ref/Net/WebSockets/IWebSocketEngine.cs b/ref/Net/WebSockets/IWebSocketEngine.cs
deleted file mode 100644
index 68f31f12b..000000000
--- a/ref/Net/WebSockets/IWebSocketEngine.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Discord.Net.WebSockets
-{
- public interface IWebSocketEngine
- {
- event EventHandler BinaryMessage;
- event EventHandler TextMessage;
-
- Task Connect(string host, CancellationToken cancelToken);
- Task Disconnect();
- void QueueMessage(string message);
- IEnumerable GetTasks(CancellationToken cancelToken);
- }
-}
diff --git a/ref/Net/WebSockets/IWebSocketProvider.cs b/ref/Net/WebSockets/IWebSocketProvider.cs
deleted file mode 100644
index 20f7559be..000000000
--- a/ref/Net/WebSockets/IWebSocketProvider.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System.Threading;
-
-namespace Discord.Net.WebSockets
-{
- public interface IWebSocketProvider
- {
- IWebSocket Create(CancellationToken cancelToken);
- }
-}
diff --git a/ref/Net/WebSockets/TextMessageEventArgs.cs b/ref/Net/WebSockets/TextMessageEventArgs.cs
deleted file mode 100644
index e4e186044..000000000
--- a/ref/Net/WebSockets/TextMessageEventArgs.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using System;
-
-namespace Discord.Net.WebSockets
-{
- public class TextMessageEventArgs : EventArgs
- {
- public string Message { get; }
-
- public TextMessageEventArgs(string msg) { Message = msg; }
- }
-}
diff --git a/ref/Net/WebSockets/WebSocketEventEventArgs.cs b/ref/Net/WebSockets/WebSocketEventEventArgs.cs
deleted file mode 100644
index 676c0ba6e..000000000
--- a/ref/Net/WebSockets/WebSocketEventEventArgs.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using Newtonsoft.Json.Linq;
-using System;
-
-namespace Discord.Net.WebSockets
-{
- public class WebSocketEventEventArgs : EventArgs
- {
- public string Type { get; }
- public JToken Payload { get; }
- }
-}
diff --git a/ref/project.json b/ref/project.json
deleted file mode 100644
index 565bc2e86..000000000
--- a/ref/project.json
+++ /dev/null
@@ -1,81 +0,0 @@
-{
- "version": "0.9.0-rc3-3",
- "description": "An unofficial .Net API wrapper for the Discord client.",
- "authors": [
- "RogueException"
- ],
- "tags": [
- "discord",
- "discordapp"
- ],
- "projectUrl": "https://github.com/RogueException/Discord.Net",
- "licenseUrl": "http://opensource.org/licenses/MIT",
- "repository": {
- "type": "git",
- "url": "git://github.com/RogueException/Discord.Net"
- },
- "compile": [ "**/*.cs", "../Discord.Net.Shared/*.cs" ],
-
- "compilationOptions": {
- "allowUnsafe": true,
- "warningsAsErrors": true
- },
-
- "configurations": {
- "TestResponses": {
- "compilationOptions": {
- "define": [
- "DEBUG",
- "TRACE",
- "TEST_RESPONSES"
- ]
- }
- }
- },
-
- "dependencies": {
- "Newtonsoft.Json": "8.0.1",
- "Nito.AsyncEx": "3.0.1"
- },
-
- "frameworks": {
- "dotnet5.4": {
- "dependencies": {
- "System.Collections": "4.0.11-beta-23516",
- "System.Collections.Concurrent": "4.0.11-beta-23516",
- "System.Dynamic.Runtime": "4.0.11-beta-23516",
- "System.IO.FileSystem": "4.0.1-beta-23516",
- "System.IO.Compression": "4.1.0-beta-23516",
- "System.Linq": "4.0.1-beta-23516",
- "System.Net.Http": "4.0.1-beta-23516",
- "System.Net.NameResolution": "4.0.0-beta-23516",
- "System.Net.Sockets": "4.1.0-beta-23409",
- "System.Net.Requests": "4.0.11-beta-23516",
- "System.Net.WebSockets.Client": "4.0.0-beta-23516",
- "System.Reflection": "4.1.0-beta-23516",
- "System.Reflection.Emit.Lightweight": "4.0.1-beta-23516",
- "System.Runtime.InteropServices": "4.0.21-beta-23516",
- "System.Runtime.Serialization.Primitives": "4.1.0-beta-23516",
- "System.Security.Cryptography.Algorithms": "4.0.0-beta-23516",
- "System.Text.RegularExpressions": "4.0.11-beta-23516",
- "System.Threading": "4.0.11-beta-23516"
- }
- },
- "net45": {
- "frameworkAssemblies": {
- "System.Runtime": {
- "type": "build",
- "version": ""
- },
- "System.Threading.Tasks": {
- "type": "build",
- "version": ""
- }
- },
- "dependencies": {
- "WebSocket4Net": "0.14.1",
- "RestSharp": "105.2.3"
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Discord.Net.Audio/AudioClient.cs b/src/Discord.Net.Audio/AudioClient.cs
deleted file mode 100644
index 882dca1fe..000000000
--- a/src/Discord.Net.Audio/AudioClient.cs
+++ /dev/null
@@ -1,283 +0,0 @@
-using Discord.API.Client.GatewaySocket;
-using Discord.API.Client.Rest;
-using Discord.Logging;
-using Discord.Net.Rest;
-using Discord.Net.WebSockets;
-using Newtonsoft.Json;
-using Nito.AsyncEx;
-using System;
-using System.Diagnostics;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Discord.Audio
-{
- internal class AudioClient : IAudioClient
- {
- private readonly DiscordConfig _config;
- private readonly AsyncLock _connectionLock;
- private readonly TaskManager _taskManager;
- private ConnectionState _gatewayState;
-
- internal Logger Logger { get; }
-
- public int Id { get; }
- public AudioService Service { get; }
- public AudioServiceConfig Config { get; }
- public RestClient ClientAPI { get; }
- public GatewaySocket GatewaySocket { get; }
- public VoiceSocket VoiceSocket { get; }
- public JsonSerializer Serializer { get; }
-
- public CancellationToken CancelToken { get; private set; }
- public string SessionId => GatewaySocket.SessionId;
-
- public ConnectionState State => VoiceSocket.State;
- public Server Server => VoiceSocket.Server;
- public VoiceChannel Channel => VoiceSocket.Channel;
-
- public AudioClient(DiscordClient client, Server server, int id)
- {
- Id = id;
- Service = client.GetService();
- Config = Service.Config;
- Serializer = client.Serializer;
- _gatewayState = (int)ConnectionState.Disconnected;
-
- //Logging
- Logger = client.Log.CreateLogger($"AudioClient #{id}");
-
- //Async
- _taskManager = new TaskManager(Cleanup, false);
- _connectionLock = new AsyncLock();
- CancelToken = new CancellationToken(true);
-
- //Networking
- if (Config.EnableMultiserver)
- {
- //TODO: We can remove this hack when official API launches
- var baseConfig = client.Config;
- var builder = new DiscordConfigBuilder
- {
- AppName = baseConfig.AppName,
- AppUrl = baseConfig.AppUrl,
- AppVersion = baseConfig.AppVersion,
- CacheToken = baseConfig.CacheDir != null,
- ConnectionTimeout = baseConfig.ConnectionTimeout,
- EnablePreUpdateEvents = false,
- FailedReconnectDelay = baseConfig.FailedReconnectDelay,
- LargeThreshold = 1,
- LogLevel = baseConfig.LogLevel,
- MessageCacheSize = 0,
- ReconnectDelay = baseConfig.ReconnectDelay,
- UsePermissionsCache = false
- };
- _config = builder.Build();
-
- ClientAPI = new JsonRestClient(_config, DiscordConfig.ClientAPIUrl, client.Log.CreateLogger($"ClientAPI #{id}"));
- GatewaySocket = new GatewaySocket(_config, client.Serializer, client.Log.CreateLogger($"Gateway #{id}"));
- GatewaySocket.Connected += (s, e) =>
- {
- if (_gatewayState == ConnectionState.Connecting)
- EndGatewayConnect();
- };
- }
- else
- {
- _config = client.Config;
- GatewaySocket = client.GatewaySocket;
- }
- GatewaySocket.ReceivedDispatch += (s, e) => OnReceivedEvent(e);
- VoiceSocket = new VoiceSocket(_config, Config, client.Serializer, client.Log.CreateLogger($"Voice #{id}"));
- VoiceSocket.Server = server;
- }
-
- public async Task Connect()
- {
- if (Config.EnableMultiserver)
- await BeginGatewayConnect().ConfigureAwait(false);
- else
- {
- var cancelSource = new CancellationTokenSource();
- CancelToken = cancelSource.Token;
- await _taskManager.Start(new Task[0], cancelSource).ConfigureAwait(false);
- }
- }
- private async Task BeginGatewayConnect()
- {
- try
- {
- using (await _connectionLock.LockAsync().ConfigureAwait(false))
- {
- await Disconnect().ConfigureAwait(false);
- _taskManager.ClearException();
-
- ClientAPI.Token = Service.Client.ClientAPI.Token;
-
- Stopwatch stopwatch = null;
- if (_config.LogLevel >= LogSeverity.Verbose)
- stopwatch = Stopwatch.StartNew();
- _gatewayState = ConnectionState.Connecting;
-
- var cancelSource = new CancellationTokenSource();
- CancelToken = cancelSource.Token;
- ClientAPI.CancelToken = CancelToken;
-
- await GatewaySocket.Connect(ClientAPI, CancelToken).ConfigureAwait(false);
-
- await _taskManager.Start(new Task[0], cancelSource).ConfigureAwait(false);
- GatewaySocket.WaitForConnection(CancelToken);
-
- if (_config.LogLevel >= LogSeverity.Verbose)
- {
- stopwatch.Stop();
- double seconds = Math.Round(stopwatch.ElapsedTicks / (double)TimeSpan.TicksPerSecond, 2);
- Logger.Verbose($"Connection took {seconds} sec");
- }
- }
- }
- catch (Exception ex)
- {
- await _taskManager.SignalError(ex).ConfigureAwait(false);
- throw;
- }
- }
- private void EndGatewayConnect()
- {
- _gatewayState = ConnectionState.Connected;
- }
-
- public async Task Disconnect()
- {
- await _taskManager.Stop(true).ConfigureAwait(false);
- if (Config.EnableMultiserver)
- ClientAPI.Token = null;
- }
- private async Task Cleanup()
- {
- var oldState = _gatewayState;
- _gatewayState = ConnectionState.Disconnecting;
-
- if (Config.EnableMultiserver)
- {
- if (oldState == ConnectionState.Connected)
- {
- try { await ClientAPI.Send(new LogoutRequest()).ConfigureAwait(false); }
- catch (OperationCanceledException) { }
- }
-
- await GatewaySocket.Disconnect().ConfigureAwait(false);
- ClientAPI.Token = null;
- }
-
- var server = VoiceSocket.Server;
- VoiceSocket.Server = null;
- VoiceSocket.Channel = null;
- if (Config.EnableMultiserver)
- await Service.RemoveClient(server, this).ConfigureAwait(false);
- SendVoiceUpdate(server.Id, null);
-
- await VoiceSocket.Disconnect().ConfigureAwait(false);
- if (Config.EnableMultiserver)
- await GatewaySocket.Disconnect().ConfigureAwait(false);
-
- _gatewayState = (int)ConnectionState.Disconnected;
- }
-
- public async Task Join(VoiceChannel channel)
- {
- if (channel == null) throw new ArgumentNullException(nameof(channel));
- if (channel.Type != ChannelType.Voice)
- throw new ArgumentException("Channel must be a voice channel.", nameof(channel));
- if (channel == VoiceSocket.Channel) return;
- var server = channel.Server;
- if (server != VoiceSocket.Server)
- throw new ArgumentException("This is channel is not part of the current server.", nameof(channel));
- if (VoiceSocket.Server == null)
- throw new InvalidOperationException("This client has been closed.");
-
- SendVoiceUpdate(channel.Server.Id, channel.Id);
- using (await _connectionLock.LockAsync().ConfigureAwait(false))
- await Task.Run(() => VoiceSocket.WaitForConnection(CancelToken)).ConfigureAwait(false);
- }
-
- private async void OnReceivedEvent(WebSocketEventEventArgs e)
- {
- try
- {
- switch (e.Type)
- {
- case "VOICE_STATE_UPDATE":
- {
- var data = e.Payload.ToObject(Serializer);
- if (data.GuildId == VoiceSocket.Server?.Id && data.UserId == Service.Client.CurrentUser?.Id)
- {
- if (data.ChannelId == null)
- await Disconnect().ConfigureAwait(false);
- else
- {
- var channel = Service.Client.GetChannel(data.ChannelId.Value) as VoiceChannel;
- if (channel != null)
- VoiceSocket.Channel = channel;
- else
- {
- Logger.Warning("VOICE_STATE_UPDATE referenced an unknown channel, disconnecting.");
- await Disconnect().ConfigureAwait(false);
- }
- }
- }
- }
- break;
- case "VOICE_SERVER_UPDATE":
- {
- var data = e.Payload.ToObject(Serializer);
- if (data.GuildId == VoiceSocket.Server?.Id)
- {
- var client = Service.Client;
- var id = client.CurrentUser?.Id;
- if (id != null)
- {
- var host = "wss://" + e.Payload.Value("endpoint").Split(':')[0];
- await VoiceSocket.Connect(host, data.Token, id.Value, GatewaySocket.SessionId, CancelToken).ConfigureAwait(false);
- }
- }
- }
- break;
- }
- }
- catch (Exception ex)
- {
- Logger.Error($"Error handling {e.Type} event", ex);
- }
- }
-
- public void Send(byte[] data, int offset, int count)
- {
- if (data == null) throw new ArgumentException(nameof(data));
- if (count < 0) throw new ArgumentOutOfRangeException(nameof(count));
- if (offset < 0) throw new ArgumentOutOfRangeException(nameof(offset));
- if (VoiceSocket.Server == null) return; //Has been closed
- if (count == 0) return;
-
- VoiceSocket.SendPCMFrames(data, offset, count);
- }
-
- public void Clear()
- {
- if (VoiceSocket.Server == null) return; //Has been closed
- VoiceSocket.ClearPCMFrames();
- }
- public void Wait()
- {
- if (VoiceSocket.Server == null) return; //Has been closed
- VoiceSocket.WaitForQueue();
- }
-
- public void SendVoiceUpdate(ulong? serverId, ulong? channelId)
- {
- GatewaySocket.SendUpdateVoice(serverId, channelId,
- (Service.Config.Mode | AudioMode.Outgoing) == 0,
- (Service.Config.Mode | AudioMode.Incoming) == 0);
- }
- }
-}
diff --git a/src/Discord.Net.Audio/AudioExtensions.cs b/src/Discord.Net.Audio/AudioExtensions.cs
deleted file mode 100644
index 7def445a6..000000000
--- a/src/Discord.Net.Audio/AudioExtensions.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System;
-using System.Threading.Tasks;
-
-namespace Discord.Audio
-{
- public static class AudioExtensions
- {
- public static DiscordClient UsingAudio(this DiscordClient client, AudioServiceConfig config = null)
- {
- client.AddService(new AudioService(config));
- return client;
- }
- public static DiscordClient UsingAudio(this DiscordClient client, Action configFunc = null)
- {
- var builder = new AudioServiceConfigBuilder();
- configFunc(builder);
- client.AddService(new AudioService(builder));
- return client;
- }
-
- public static Task JoinAudio(this VoiceChannel channel) => channel.Client.GetService().Join(channel);
- public static Task LeaveAudio(this VoiceChannel channel) => channel.Client.GetService().Leave(channel);
- public static Task LeaveAudio(this Server server) => server.Client.GetService().Leave(server);
- public static IAudioClient GetAudioClient(this Server server) => server.Client.GetService().GetClient(server);
- }
-}
diff --git a/src/Discord.Net.Audio/AudioMode.cs b/src/Discord.Net.Audio/AudioMode.cs
deleted file mode 100644
index b9acdbf89..000000000
--- a/src/Discord.Net.Audio/AudioMode.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Discord.Audio
-{
- public enum AudioMode : byte
- {
- Outgoing = 1,
- Incoming = 2,
- Both = Outgoing | Incoming
- }
-}
diff --git a/src/Discord.Net.Audio/AudioService.cs b/src/Discord.Net.Audio/AudioService.cs
deleted file mode 100644
index e44a4a1ce..000000000
--- a/src/Discord.Net.Audio/AudioService.cs
+++ /dev/null
@@ -1,193 +0,0 @@
-using Nito.AsyncEx;
-using System;
-using System.Collections.Concurrent;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace Discord.Audio
-{
- public class AudioService : IService
- {
- private readonly AsyncLock _asyncLock;
- private AudioClient _defaultClient; //Only used for single server
- private VirtualClient _currentClient; //Only used for single server
- private ConcurrentDictionary _voiceClients;
- private ConcurrentDictionary _talkingUsers;
- private int _nextClientId;
-
- public DiscordClient Client { get; private set; }
- public AudioServiceConfig Config { get; }
-
- public event EventHandler Connected = delegate { };
- public event EventHandler Disconnected = delegate { };
- public event EventHandler UserIsSpeakingUpdated = delegate { };
-
- private void OnConnected()
- => Connected(this, EventArgs.Empty);
- private void OnDisconnected(ulong serverId, bool wasUnexpected, Exception ex)
- => Disconnected(this, new VoiceDisconnectedEventArgs(serverId, wasUnexpected, ex));
- private void OnUserIsSpeakingUpdated(User user, bool isSpeaking)
- => UserIsSpeakingUpdated(this, new UserIsSpeakingEventArgs(user, isSpeaking));
-
- public AudioService()
- : this(new AudioServiceConfigBuilder())
- {
- }
- public AudioService(AudioServiceConfigBuilder builder)
- : this(builder.Build())
- {
- }
- public AudioService(AudioServiceConfig config)
- {
- Config = config;
- _asyncLock = new AsyncLock();
-
- }
- void IService.Install(DiscordClient client)
- {
- Client = client;
-
- if (Config.EnableMultiserver)
- _voiceClients = new ConcurrentDictionary();
- else
- {
- var logger = Client.Log.CreateLogger("Voice");
- _defaultClient = new AudioClient(Client, null, 0);
- }
- _talkingUsers = new ConcurrentDictionary();
-
- client.GatewaySocket.Disconnected += async (s, e) =>
- {
- if (Config.EnableMultiserver)
- {
- var tasks = _voiceClients
- .Select(x =>
- {
- var val = x.Value;
- if (val != null)
- return x.Value.Disconnect();
- else
- return TaskHelper.CompletedTask;
- })
- .ToArray();
- await Task.WhenAll(tasks).ConfigureAwait(false);
- _voiceClients.Clear();
- }
- foreach (var member in _talkingUsers)
- {
- bool ignored;
- if (_talkingUsers.TryRemove(member.Key, out ignored))
- OnUserIsSpeakingUpdated(member.Key, false);
- }
- };
- }
-
- public IAudioClient GetClient(Server server)
- {
- if (server == null) throw new ArgumentNullException(nameof(server));
-
- if (Config.EnableMultiserver)
- {
- AudioClient client;
- if (_voiceClients.TryGetValue(server.Id, out client))
- return client;
- else
- return null;
- }
- else
- {
- if (server == _currentClient.Server)
- return _currentClient;
- else
- return null;
- }
- }
-
- //Called from AudioClient.Disconnect
- internal async Task RemoveClient(Server server, AudioClient client)
- {
- using (await _asyncLock.LockAsync().ConfigureAwait(false))
- {
- if (_voiceClients.TryUpdate(server.Id, null, client))
- _voiceClients.TryRemove(server.Id, out client);
- }
- }
-
- public async Task Join(VoiceChannel channel)
- {
- if (channel == null) throw new ArgumentNullException(nameof(channel));
-
- var server = channel.Server;
- using (await _asyncLock.LockAsync().ConfigureAwait(false))
- {
- if (Config.EnableMultiserver)
- {
- AudioClient client;
- if (!_voiceClients.TryGetValue(server.Id, out client))
- {
- client = new AudioClient(Client, server, unchecked(++_nextClientId));
- _voiceClients[server.Id] = client;
-
- await client.Connect().ConfigureAwait(false);
-
- /*voiceClient.VoiceSocket.FrameReceived += (s, e) =>
- {
- OnFrameReceieved(e);
- };
- voiceClient.VoiceSocket.UserIsSpeaking += (s, e) =>
- {
- var user = server.GetUser(e.UserId);
- OnUserIsSpeakingUpdated(user, e.IsSpeaking);
- };*/
- }
-
- await client.Join(channel).ConfigureAwait(false);
- return client;
- }
- else
- {
- if (_defaultClient.Server != server)
- {
- await _defaultClient.Disconnect().ConfigureAwait(false);
- _defaultClient.VoiceSocket.Server = server;
- await _defaultClient.Connect().ConfigureAwait(false);
- }
- var client = new VirtualClient(_defaultClient, server);
- _currentClient = client;
-
- await client.Join(channel).ConfigureAwait(false);
- return client;
- }
-
- }
- }
-
- public Task Leave(Server server) => Leave(server, null);
- public Task Leave(VoiceChannel channel) => Leave(channel.Server, channel);
- private async Task Leave(Server server, VoiceChannel channel)
- {
- if (server == null) throw new ArgumentNullException(nameof(server));
-
- if (Config.EnableMultiserver)
- {
- AudioClient client;
- //Potential race condition if changing channels during this call, but that's acceptable
- if (channel == null || (_voiceClients.TryGetValue(server.Id, out client) && client.Channel == channel))
- {
- if (_voiceClients.TryRemove(server.Id, out client))
- await client.Disconnect().ConfigureAwait(false);
- }
- }
- else
- {
- using (await _asyncLock.LockAsync().ConfigureAwait(false))
- {
- var client = GetClient(server) as VirtualClient;
- if (client != null && client.Channel == channel)
- await _defaultClient.Disconnect().ConfigureAwait(false);
- }
- }
-
- }
- }
-}
diff --git a/src/Discord.Net.Audio/AudioServiceConfig.cs b/src/Discord.Net.Audio/AudioServiceConfig.cs
deleted file mode 100644
index 89d05d85b..000000000
--- a/src/Discord.Net.Audio/AudioServiceConfig.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-namespace Discord.Audio
-{
- public class AudioServiceConfigBuilder
- {
- /// Enables the voice websocket and UDP client and specifies how it will be used.
- public AudioMode Mode { get; set; } = AudioMode.Outgoing;
-
- /// Enables the voice websocket and UDP client. This option requires the libsodium .dll or .so be in the local or system folder.
- public bool EnableEncryption { get; set; } = true;
- ///
- /// Enables the client to be simultaneously connected to multiple channels at once (Discord still limits you to one channel per server).
- /// This option uses a lot of CPU power and network bandwidth, as a new gateway connection needs to be spun up per server. Use sparingly.
- ///
- public bool EnableMultiserver { get; set; } = false;
-
- /// Gets or sets the buffer length (in milliseconds) for outgoing voice packets.
- public int BufferLength { get; set; } = 1000;
- /// Gets or sets the bitrate used (in kbit/s, between 1 and MaxBitrate inclusively) for outgoing voice packets. A null value will use default Opus settings.
- public int? Bitrate { get; set; } = null;
- /// Gets or sets the number of channels (1 or 2) used in both input provided to IAudioClient and output send to Discord. Defaults to 2 (stereo).
- public int Channels { get; set; } = 2;
-
- public AudioServiceConfig Build() => new AudioServiceConfig(this);
- }
-
- public class AudioServiceConfig
- {
- public const int MaxBitrate = 128;
-
- public AudioMode Mode { get; }
-
- public bool EnableEncryption { get; }
- public bool EnableMultiserver { get; }
-
- public int BufferLength { get; }
- public int? Bitrate { get; }
- public int Channels { get; }
-
- internal AudioServiceConfig(AudioServiceConfigBuilder builder)
- {
- Mode = builder.Mode;
-
- EnableEncryption = builder.EnableEncryption;
- EnableMultiserver = builder.EnableMultiserver;
-
- BufferLength = builder.BufferLength;
- Bitrate = builder.Bitrate;
- Channels = builder.Channels;
- }
- }
-}
diff --git a/src/Discord.Net.Audio/Discord.Net.Audio.xproj b/src/Discord.Net.Audio/Discord.Net.Audio.xproj
deleted file mode 100644
index 4eb480f88..000000000
--- a/src/Discord.Net.Audio/Discord.Net.Audio.xproj
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
- 14.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
-
-
- dff7afe3-ca77-4109-bade-b4b49a4f6648
- Discord.Audio
- ..\..\artifacts\obj\$(MSBuildProjectName)
- ..\..\artifacts\bin\$(MSBuildProjectName)\
-
-
- 2.0
-
-
- True
-
-
-
\ No newline at end of file
diff --git a/src/Discord.Net.Audio/IAudioClient.cs b/src/Discord.Net.Audio/IAudioClient.cs
deleted file mode 100644
index a986fad7d..000000000
--- a/src/Discord.Net.Audio/IAudioClient.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using Discord.Net.Rest;
-using Discord.Net.WebSockets;
-using System.IO;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Discord.Audio
-{
- public interface IAudioClient
- {
- /// Gets the unique identifier for this client.
- int Id { get; }
- /// Gets the session id for the current connection.
- string SessionId { get; }
- /// Gets the current state of this client.
- ConnectionState State { get; }
- /// Gets the channel this client is currently a member of.
- VoiceChannel Channel { get; }
- /// Gets the server this client is bound to.
- Server Server { get; }
- /// Gets a cancellation token that triggers when the client is manually disconnected.
- CancellationToken CancelToken { get; }
-
- /// Gets the internal RestClient for the Client API endpoint.
- RestClient ClientAPI { get; }
- /// Gets the internal WebSocket for the Gateway event stream.
- GatewaySocket GatewaySocket { get; }
- /// Gets the internal WebSocket for the Voice control stream.
- VoiceSocket VoiceSocket { get; }
-
- /// Moves the client to another channel on the same server.
- Task Join(VoiceChannel channel);
- /// Disconnects from the Discord server, canceling any pending requests.
- Task Disconnect();
-
- /// Sends a PCM frame to the voice server. Will block until space frees up in the outgoing buffer.
- /// PCM frame to send. This must be a single or collection of uncompressed 48Kz monochannel 20ms PCM frames.
- /// Offset .
- /// Number of bytes in this frame.
- void Send(byte[] data, int offset, int count);
- /// Clears the PCM buffer.
- void Clear();
- /// Blocks until the voice output buffer is empty.
- void Wait();
- }
-}
diff --git a/src/Discord.Net.Audio/InternalFrameEventArgs.cs b/src/Discord.Net.Audio/InternalFrameEventArgs.cs
deleted file mode 100644
index b74dc8295..000000000
--- a/src/Discord.Net.Audio/InternalFrameEventArgs.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System;
-
-namespace Discord
-{
- internal class InternalFrameEventArgs : EventArgs
- {
- public ulong UserId { get; }
- public ulong ChannelId { get; }
- public byte[] Buffer { get; }
- public int Offset { get; }
- public int Count { get; }
-
- public InternalFrameEventArgs(ulong userId, ulong channelId, byte[] buffer, int offset, int count)
- {
- UserId = userId;
- ChannelId = channelId;
- Buffer = buffer;
- Offset = offset;
- Count = count;
- }
- }
-}
diff --git a/src/Discord.Net.Audio/InternalIsSpeakingEventArgs.cs b/src/Discord.Net.Audio/InternalIsSpeakingEventArgs.cs
deleted file mode 100644
index 641e863f4..000000000
--- a/src/Discord.Net.Audio/InternalIsSpeakingEventArgs.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-namespace Discord.Audio
-{
- internal class InternalIsSpeakingEventArgs
- {
- public ulong UserId { get; }
- public bool IsSpeaking { get; }
-
- public InternalIsSpeakingEventArgs(ulong userId, bool isSpeaking)
- {
- UserId = userId;
- IsSpeaking = isSpeaking;
- }
- }
-}
diff --git a/src/Discord.Net.Audio/Net/VoiceSocket.cs b/src/Discord.Net.Audio/Net/VoiceSocket.cs
deleted file mode 100644
index 9ee5c60e0..000000000
--- a/src/Discord.Net.Audio/Net/VoiceSocket.cs
+++ /dev/null
@@ -1,516 +0,0 @@
-using Discord.API.Client;
-using Discord.API.Client.VoiceSocket;
-using Discord.Audio;
-using Discord.Audio.Opus;
-using Discord.Audio.Sodium;
-using Discord.Logging;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Net;
-using System.Net.Sockets;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Discord.Net.WebSockets
-{
- public partial class VoiceSocket : WebSocket
- {
- private const int MaxOpusSize = 4000;
- private const string EncryptedMode = "xsalsa20_poly1305";
- private const string UnencryptedMode = "plain";
-
- private readonly int _targetAudioBufferLength;
- private readonly ConcurrentDictionary _decoders;
- private readonly AudioServiceConfig _audioConfig;
- private Task _sendTask, _receiveTask;
- private VoiceBuffer _sendBuffer;
- private OpusEncoder _encoder;
- private uint _ssrc;
- private ConcurrentDictionary _ssrcMapping;
- private UdpClient _udp;
- private IPEndPoint _endpoint;
- private bool _isEncrypted;
- private byte[] _secretKey, _encodingBuffer;
- private ushort _sequence;
- private string _encryptionMode;
- private int _ping;
- private ulong? _userId;
- private string _sessionId;
-
- public string Token { get; internal set; }
- public Server Server { get; internal set; }
- public VoiceChannel Channel { get; internal set; }
-
- public int Ping => _ping;
- internal VoiceBuffer OutputBuffer => _sendBuffer;
-
- internal event EventHandler UserIsSpeaking = delegate { };
- internal event EventHandler FrameReceived = delegate { };
-
- private void OnUserIsSpeaking(ulong userId, bool isSpeaking)
- => UserIsSpeaking(this, new InternalIsSpeakingEventArgs(userId, isSpeaking));
- internal void OnFrameReceived(ulong userId, ulong channelId, byte[] buffer, int offset, int count)
- => FrameReceived(this, new InternalFrameEventArgs(userId, channelId, buffer, offset, count));
-
- internal VoiceSocket(DiscordConfig config, AudioServiceConfig audioConfig, JsonSerializer serializer, Logger logger)
- : base(config, serializer, logger)
- {
- _audioConfig = audioConfig;
- _decoders = new ConcurrentDictionary();
- _targetAudioBufferLength = _audioConfig.BufferLength / 20; //20 ms frames
- _encodingBuffer = new byte[MaxOpusSize];
- _ssrcMapping = new ConcurrentDictionary();
- _encoder = new OpusEncoder(48000, _audioConfig.Channels, 20, _audioConfig.Bitrate, OpusApplication.MusicOrMixed);
- _sendBuffer = new VoiceBuffer((int)Math.Ceiling(_audioConfig.BufferLength / (double)_encoder.FrameLength), _encoder.FrameSize);
- }
-
- public Task Connect(string host, string token, ulong userId, string sessionId, CancellationToken parentCancelToken)
- {
- Host = host;
- Token = token;
- _userId = userId;
- _sessionId = sessionId;
- return BeginConnect(parentCancelToken);
- }
- private async Task Reconnect()
- {
- try
- {
- var cancelToken = _parentCancelToken;
- await Task.Delay(_config.ReconnectDelay, cancelToken).ConfigureAwait(false);
- while (!cancelToken.IsCancellationRequested)
- {
- try
- {
- await BeginConnect(_parentCancelToken).ConfigureAwait(false);
- break;
- }
- catch (OperationCanceledException) { throw; }
- catch (Exception ex)
- {
- Logger.Error("Reconnect failed", ex);
- //Net is down? We can keep trying to reconnect until the user runs Disconnect()
- await Task.Delay(_config.FailedReconnectDelay, cancelToken).ConfigureAwait(false);
- }
- }
- }
- catch (OperationCanceledException) { }
- }
- public async Task Disconnect()
- {
- await _taskManager.Stop(true).ConfigureAwait(false);
- _userId = null;
- }
-
- protected override async Task Run()
- {
- _udp = new UdpClient(new IPEndPoint(IPAddress.Any, 0));
-
- List tasks = new List();
- if (_audioConfig.Mode.HasFlag(AudioMode.Outgoing))
- _sendTask = Task.Run(() => SendVoiceAsync(CancelToken));
- _receiveTask = Task.Run(() => ReceiveVoiceAsync(CancelToken));
-
- SendIdentify(_userId.Value, _sessionId);
-
-#if !DOTNET5_4
- tasks.Add(WatcherAsync());
-#endif
- tasks.AddRange(_engine.GetTasks(CancelToken));
- tasks.Add(HeartbeatAsync(CancelToken));
- await _taskManager.Start(tasks, _cancelSource).ConfigureAwait(false);
- }
- protected override async Task Cleanup()
- {
- var sendThread = _sendTask;
- if (sendThread != null)
- {
- try { await sendThread.ConfigureAwait(false); }
- catch (Exception) { } //Ignore any errors during cleanup
- }
- _sendTask = null;
-
- var receiveThread = _receiveTask;
- if (receiveThread != null)
- {
- try { await receiveThread.ConfigureAwait(false); }
- catch (Exception) { } //Ignore any errors during cleanup
- }
- _receiveTask = null;
-
- OpusDecoder decoder;
- foreach (var pair in _decoders)
- {
- if (_decoders.TryRemove(pair.Key, out decoder))
- decoder.Dispose();
- }
-
- ClearPCMFrames();
- _udp = null;
-
- await base.Cleanup().ConfigureAwait(false);
- }
-
- private async Task ReceiveVoiceAsync(CancellationToken cancelToken)
- {
- var closeTask = cancelToken.Wait();
- try
- {
- byte[] packet, decodingBuffer = null, nonce = null, result;
- int packetLength, resultOffset, resultLength;
- IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 0);
-
- if ((_audioConfig.Mode & AudioMode.Incoming) != 0)
- {
- decodingBuffer = new byte[MaxOpusSize];
- nonce = new byte[24];
- }
-
- while (!cancelToken.IsCancellationRequested)
- {
- await Task.Delay(1).ConfigureAwait(false);
- if (_udp.Available > 0)
- {
-#if !DOTNET5_4
- packet = _udp.Receive(ref endpoint);
-#else
- //TODO: Is this really the only way to end a Receive call in DOTNET5_4?
- var receiveTask = _udp.ReceiveAsync();
- var task = Task.WhenAny(closeTask, receiveTask).Result;
- if (task == closeTask)
- break;
- var udpPacket = receiveTask.Result;
- packet = udpPacket.Buffer;
- endpoint = udpPacket.RemoteEndPoint;
-#endif
- packetLength = packet.Length;
-
- if (packetLength > 0 && endpoint.Equals(_endpoint))
- {
- if (State != ConnectionState.Connected)
- {
- if (packetLength != 70)
- return;
-
- string ip = Encoding.UTF8.GetString(packet, 4, 70 - 6).TrimEnd('\0');
- int port = packet[68] | packet[69] << 8;
-
- SendSelectProtocol(ip, port);
- if ((_audioConfig.Mode & AudioMode.Incoming) == 0)
- return; //We dont need this thread anymore
- }
- else
- {
- //Parse RTP Data
- if (packetLength < 12) return;
- if (packet[0] != 0x80) return; //Flags
- if (packet[1] != 0x78) return; //Payload Type
-
- ushort sequenceNumber = (ushort)((packet[2] << 8) |
- packet[3] << 0);
- uint timestamp = (uint)((packet[4] << 24) |
- (packet[5] << 16) |
- (packet[6] << 8) |
- (packet[7] << 0));
- uint ssrc = (uint)((packet[8] << 24) |
- (packet[9] << 16) |
- (packet[10] << 8) |
- (packet[11] << 0));
-
- //Decrypt
- if (_isEncrypted)
- {
- if (packetLength < 28) //12 + 16 (RTP + Poly1305 MAC)
- return;
-
- Buffer.BlockCopy(packet, 0, nonce, 0, 12);
- int ret = SecretBox.Decrypt(packet, 12, packetLength - 12, decodingBuffer, nonce, _secretKey);
- if (ret != 0)
- continue;
- result = decodingBuffer;
- resultOffset = 0;
- resultLength = packetLength - 28;
- }
- else //Plain
- {
- result = packet;
- resultOffset = 12;
- resultLength = packetLength - 12;
- }
-
- /*if (_logLevel >= LogMessageSeverity.Debug)
- RaiseOnLog(LogMessageSeverity.Debug, $"Received {buffer.Length - 12} bytes.");*/
-
- ulong userId;
- if (_ssrcMapping.TryGetValue(ssrc, out userId))
- OnFrameReceived(userId, Channel.Id, result, resultOffset, resultLength);
- }
- }
- }
- }
- }
- catch (OperationCanceledException) { }
- catch (InvalidOperationException) { } //Includes ObjectDisposedException
- }
-
- private async Task SendVoiceAsync(CancellationToken cancelToken)
- {
- try
- {
- while (!cancelToken.IsCancellationRequested && State != ConnectionState.Connected)
- await Task.Delay(1).ConfigureAwait(false);
-
- if (cancelToken.IsCancellationRequested)
- return;
-
- byte[] frame = new byte[_encoder.FrameSize];
- byte[] encodedFrame = new byte[MaxOpusSize];
- byte[] voicePacket, pingPacket, nonce = null;
- uint timestamp = 0;
- double nextTicks = 0.0, nextPingTicks = 0.0;
- long ticksPerSeconds = Stopwatch.Frequency;
- double ticksPerMillisecond = Stopwatch.Frequency / 1000.0;
- double ticksPerFrame = ticksPerMillisecond * _encoder.FrameLength;
- double spinLockThreshold = 3 * ticksPerMillisecond;
- uint samplesPerFrame = (uint)_encoder.SamplesPerFrame;
- Stopwatch sw = Stopwatch.StartNew();
-
- if (_isEncrypted)
- {
- nonce = new byte[24];
- voicePacket = new byte[MaxOpusSize + 12 + 16];
- }
- else
- voicePacket = new byte[MaxOpusSize + 12];
-
- pingPacket = new byte[8];
-
- int rtpPacketLength = 0;
- voicePacket[0] = 0x80; //Flags;
- voicePacket[1] = 0x78; //Payload Type
- voicePacket[8] = (byte)(_ssrc >> 24);
- voicePacket[9] = (byte)(_ssrc >> 16);
- voicePacket[10] = (byte)(_ssrc >> 8);
- voicePacket[11] = (byte)(_ssrc >> 0);
-
- if (_isEncrypted)
- Buffer.BlockCopy(voicePacket, 0, nonce, 0, 12);
-
- bool hasFrame = false;
- while (!cancelToken.IsCancellationRequested)
- {
- if (!hasFrame && _sendBuffer.Pop(frame))
- {
- ushort sequence = unchecked(_sequence++);
- voicePacket[2] = (byte)(sequence >> 8);
- voicePacket[3] = (byte)(sequence >> 0);
- voicePacket[4] = (byte)(timestamp >> 24);
- voicePacket[5] = (byte)(timestamp >> 16);
- voicePacket[6] = (byte)(timestamp >> 8);
- voicePacket[7] = (byte)(timestamp >> 0);
-
- //Encode
- int encodedLength = _encoder.EncodeFrame(frame, 0, encodedFrame);
-
- //Encrypt
- if (_isEncrypted)
- {
- Buffer.BlockCopy(voicePacket, 2, nonce, 2, 6); //Update nonce
- int ret = SecretBox.Encrypt(encodedFrame, encodedLength, voicePacket, 12, nonce, _secretKey);
- if (ret != 0)
- continue;
- rtpPacketLength = encodedLength + 12 + 16;
- }
- else
- {
- Buffer.BlockCopy(encodedFrame, 0, voicePacket, 12, encodedLength);
- rtpPacketLength = encodedLength + 12;
- }
-
- timestamp = unchecked(timestamp + samplesPerFrame);
- hasFrame = true;
- }
-
- long currentTicks = sw.ElapsedTicks;
- double ticksToNextFrame = nextTicks - currentTicks;
- if (ticksToNextFrame <= 0.0)
- {
- if (hasFrame)
- {
- try
- {
- _udp.Send(voicePacket, rtpPacketLength);
- }
- catch (SocketException ex)
- {
- Logger.Error("Failed to send UDP packet.", ex);
- }
- hasFrame = false;
- }
- nextTicks += ticksPerFrame;
-
- //Is it time to send out another ping?
- if (currentTicks > nextPingTicks)
- {
- //Increment in LE
- for (int i = 0; i < 8; i++)
- {
- var b = pingPacket[i];
- if (b == byte.MaxValue)
- pingPacket[i] = 0;
- else
- {
- pingPacket[i] = (byte)(b + 1);
- break;
- }
- }
- await _udp.SendAsync(pingPacket, pingPacket.Length).ConfigureAwait(false);
- nextPingTicks = currentTicks + 5 * ticksPerSeconds;
- }
- }
- else
- {
- if (hasFrame)
- {
- int time = (int)Math.Floor(ticksToNextFrame / ticksPerMillisecond);
- if (time > 0)
- await Task.Delay(time).ConfigureAwait(false);
- }
- else
- await Task.Delay(1).ConfigureAwait(false); //Give as much time to the encrypter as possible
- }
- }
- }
- catch (OperationCanceledException) { }
- catch (InvalidOperationException) { } //Includes ObjectDisposedException
- }
-#if !DOTNET5_4
- //Closes the UDP socket when _disconnectToken is triggered, since UDPClient doesn't allow passing a canceltoken
- private async Task WatcherAsync()
- {
- await CancelToken.Wait().ConfigureAwait(false);
- _udp.Close();
- }
-#endif
-
- protected override async Task ProcessMessage(string json)
- {
- await base.ProcessMessage(json).ConfigureAwait(false);
-
- WebSocketMessage msg;
- using (var reader = new JsonTextReader(new StringReader(json)))
- msg = _serializer.Deserialize(reader, typeof(WebSocketMessage)) as WebSocketMessage;
-
- var opCode = (OpCodes)msg.Operation;
- switch (opCode)
- {
- case OpCodes.Ready:
- {
- if (State != ConnectionState.Connected)
- {
- var payload = (msg.Payload as JToken).ToObject(_serializer);
- _heartbeatInterval = payload.HeartbeatInterval;
- _ssrc = payload.SSRC;
- var address = (await Dns.GetHostAddressesAsync(Host.Replace("wss://", "")).ConfigureAwait(false)).FirstOrDefault();
- _endpoint = new IPEndPoint(address, payload.Port);
-
- if (_audioConfig.EnableEncryption)
- {
- if (payload.Modes.Contains(EncryptedMode))
- {
- _encryptionMode = EncryptedMode;
- _isEncrypted = true;
- }
- else
- throw new InvalidOperationException("Unexpected encryption format.");
- }
- else
- {
- _encryptionMode = UnencryptedMode;
- _isEncrypted = false;
- }
- _udp.Connect(_endpoint);
-
- _sequence = 0;// (ushort)_rand.Next(0, ushort.MaxValue);
- //No thread issue here because SendAsync doesn't start until _isReady is true
- byte[] packet = new byte[70];
- packet[0] = (byte)(_ssrc >> 24);
- packet[1] = (byte)(_ssrc >> 16);
- packet[2] = (byte)(_ssrc >> 8);
- packet[3] = (byte)(_ssrc >> 0);
- await _udp.SendAsync(packet, 70).ConfigureAwait(false);
- }
- }
- break;
- case OpCodes.Heartbeat:
- {
- long time = EpochTime.GetMilliseconds();
- var payload = (long)msg.Payload;
- _ping = (int)(payload - time);
- //TODO: Use this to estimate latency
- }
- break;
- case OpCodes.SessionDescription:
- {
- var payload = (msg.Payload as JToken).ToObject(_serializer);
- _secretKey = payload.SecretKey;
- SendSetSpeaking(true);
- await EndConnect().ConfigureAwait(false);
- }
- break;
- case OpCodes.Speaking:
- {
- var payload = (msg.Payload as JToken).ToObject(_serializer);
- OnUserIsSpeaking(payload.UserId, payload.IsSpeaking);
- }
- break;
- default:
- Logger.Warning($"Unknown Opcode: {opCode}");
- break;
- }
- }
-
- public void SendPCMFrames(byte[] data, int offset, int count)
- {
- _sendBuffer.Push(data, offset, count, CancelToken);
- }
- public void ClearPCMFrames()
- {
- _sendBuffer.Clear(CancelToken);
- }
-
- public void WaitForQueue()
- {
- _sendBuffer.Wait(CancelToken);
- }
-
- public override void SendHeartbeat()
- => QueueMessage(new HeartbeatCommand());
- public void SendIdentify(ulong id, string sessionId)
- => QueueMessage(new IdentifyCommand
- {
- GuildId = Server.Id,
- UserId = id,
- SessionId = sessionId,
- Token = Token
- });
- public void SendSelectProtocol(string externalAddress, int externalPort)
- => QueueMessage(new SelectProtocolCommand
- {
- Protocol = "udp",
- ExternalAddress = externalAddress,
- ExternalPort = externalPort,
- EncryptionMode = _encryptionMode
- });
- public void SendSetSpeaking(bool value)
- => QueueMessage(new SetSpeakingCommand { IsSpeaking = value, Delay = 0 });
-
- }
-}
\ No newline at end of file
diff --git a/src/Discord.Net.Audio/Opus/OpusConverter.cs b/src/Discord.Net.Audio/Opus/OpusConverter.cs
deleted file mode 100644
index d93337138..000000000
--- a/src/Discord.Net.Audio/Opus/OpusConverter.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-#if NET45
-using System.Security;
-#endif
-
-namespace Discord.Audio.Opus
-{
- internal enum OpusApplication : int
- {
- Voice = 2048,
- MusicOrMixed = 2049,
- LowLatency = 2051
- }
- internal enum OpusError : int
- {
- OK = 0,
- BadArg = -1,
- BufferToSmall = -2,
- InternalError = -3,
- InvalidPacket = -4,
- Unimplemented = -5,
- InvalidState = -6,
- AllocFail = -7
- }
-
- internal abstract class OpusConverter : IDisposable
- {
- protected enum Ctl : int
- {
- SetBitrateRequest = 4002,
- GetBitrateRequest = 4003,
- SetInbandFECRequest = 4012,
- GetInbandFECRequest = 4013
- }
-
-#if NET45
- [SuppressUnmanagedCodeSecurity]
-#endif
- protected unsafe static class UnsafeNativeMethods
- {
- [DllImport("opus", EntryPoint = "opus_encoder_create", CallingConvention = CallingConvention.Cdecl)]
- public static extern IntPtr CreateEncoder(int Fs, int channels, int application, out OpusError error);
- [DllImport("opus", EntryPoint = "opus_encoder_destroy", CallingConvention = CallingConvention.Cdecl)]
- public static extern void DestroyEncoder(IntPtr encoder);
- [DllImport("opus", EntryPoint = "opus_encode", CallingConvention = CallingConvention.Cdecl)]
- public static extern int Encode(IntPtr st, byte* pcm, int frame_size, byte[] data, int max_data_bytes);
- [DllImport("opus", EntryPoint = "opus_encoder_ctl", CallingConvention = CallingConvention.Cdecl)]
- public static extern int EncoderCtl(IntPtr st, Ctl request, int value);
-
- [DllImport("opus", EntryPoint = "opus_decoder_create", CallingConvention = CallingConvention.Cdecl)]
- public static extern IntPtr CreateDecoder(int Fs, int channels, out OpusError error);
- [DllImport("opus", EntryPoint = "opus_decoder_destroy", CallingConvention = CallingConvention.Cdecl)]
- public static extern void DestroyDecoder(IntPtr decoder);
- [DllImport("opus", EntryPoint = "opus_decode", CallingConvention = CallingConvention.Cdecl)]
- public static extern int Decode(IntPtr st, byte* data, int len, byte[] pcm, int frame_size, int decode_fec);
- }
-
- protected IntPtr _ptr;
-
- /// Gets the bit rate of this converter.
- public const int BitsPerSample = 16;
- /// Gets the input sampling rate of this converter.
- public int InputSamplingRate { get; }
- /// Gets the number of channels of this converter.
- public int InputChannels { get; }
- /// Gets the milliseconds per frame.
- public int FrameLength { get; }
- /// Gets the number of samples per frame.
- public int SamplesPerFrame { get; }
- /// Gets the bytes per frame.
- public int FrameSize { get; }
- /// Gets the bytes per sample.
- public int SampleSize { get; }
-
- protected OpusConverter(int samplingRate, int channels, int frameLength)
- {
- if (samplingRate != 8000 && samplingRate != 12000 &&
- samplingRate != 16000 && samplingRate != 24000 &&
- samplingRate != 48000)
- throw new ArgumentOutOfRangeException(nameof(samplingRate));
- if (channels != 1 && channels != 2)
- throw new ArgumentOutOfRangeException(nameof(channels));
-
- InputSamplingRate = samplingRate;
- InputChannels = channels;
- FrameLength = frameLength;
- SampleSize = (BitsPerSample / 8) * channels;
- SamplesPerFrame = samplingRate / 1000 * FrameLength;
- FrameSize = SamplesPerFrame * SampleSize;
- }
-
- #region IDisposable Support
- private bool disposedValue = false; // To detect redundant calls
-
- protected virtual void Dispose(bool disposing)
- {
- if (!disposedValue)
- disposedValue = true;
- }
- ~OpusConverter() {
- Dispose(false);
- }
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- #endregion
- }
-}
diff --git a/src/Discord.Net.Audio/Opus/OpusDecoder.cs b/src/Discord.Net.Audio/Opus/OpusDecoder.cs
deleted file mode 100644
index d8e6b8087..000000000
--- a/src/Discord.Net.Audio/Opus/OpusDecoder.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-using System;
-
-namespace Discord.Audio.Opus
-{
- internal class OpusDecoder : OpusConverter
- {
- /// Creates a new Opus decoder.
- /// Sampling rate of the input PCM (in Hz). Supported Values: 8000, 12000, 16000, 24000, or 48000
- /// Length, in milliseconds, of each frame. Supported Values: 2.5, 5, 10, 20, 40, or 60
- public OpusDecoder(int samplingRate, int channels, int frameLength)
- : base(samplingRate, channels, frameLength)
- {
- OpusError error;
- _ptr = UnsafeNativeMethods.CreateDecoder(samplingRate, channels, out error);
- if (error != OpusError.OK)
- throw new InvalidOperationException($"Error occured while creating decoder: {error}");
- }
-
- /// Produces PCM samples from Opus-encoded audio.
- /// PCM samples to decode.
- /// Offset of the frame in input.
- /// Buffer to store the decoded frame.
- public unsafe int DecodeFrame(byte[] input, int inputOffset, int inputCount, byte[] output)
- {
- int result = 0;
- fixed (byte* inPtr = input)
- result = UnsafeNativeMethods.Decode(_ptr, inPtr + inputOffset, inputCount, output, SamplesPerFrame, 0);
-
- if (result < 0)
- throw new Exception(((OpusError)result).ToString());
- return result;
- }
-
- protected override void Dispose(bool disposing)
- {
- if (_ptr != IntPtr.Zero)
- {
- UnsafeNativeMethods.DestroyDecoder(_ptr);
- _ptr = IntPtr.Zero;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Discord.Net.Audio/Opus/OpusEncoder.cs b/src/Discord.Net.Audio/Opus/OpusEncoder.cs
deleted file mode 100644
index be0623c6b..000000000
--- a/src/Discord.Net.Audio/Opus/OpusEncoder.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-using System;
-
-namespace Discord.Audio.Opus
-{
- internal class OpusEncoder : OpusConverter
- {
- /// Gets the bit rate in kbit/s.
- public int? BitRate { get; }
- /// Gets the coding mode of the encoder.
- public OpusApplication Application { get; }
-
- /// Creates a new Opus encoder.
- /// Sampling rate of the input signal (Hz). Supported Values: 8000, 12000, 16000, 24000, or 48000
- /// Number of channels in input signal. Supported Values: 1 or 2
- /// Length, in milliseconds, that each frame takes. Supported Values: 2.5, 5, 10, 20, 40, 60
- /// Bitrate (kbit/s) used for this encoder. Supported Values: 1-512. Null will use the recommended bitrate.
- /// Coding mode.
- public OpusEncoder(int samplingRate, int channels, int frameLength, int? bitrate, OpusApplication application)
- : base(samplingRate, channels, frameLength)
- {
- if (bitrate != null && (bitrate < 1 || bitrate > AudioServiceConfig.MaxBitrate))
- throw new ArgumentOutOfRangeException(nameof(bitrate));
-
- BitRate = bitrate;
- Application = application;
-
- OpusError error;
- _ptr = UnsafeNativeMethods.CreateEncoder(samplingRate, channels, (int)application, out error);
- if (error != OpusError.OK)
- throw new InvalidOperationException($"Error occured while creating encoder: {error}");
-
- SetForwardErrorCorrection(true);
- if (bitrate != null)
- SetBitrate(bitrate.Value);
- }
-
- /// Produces Opus encoded audio from PCM samples.
- /// PCM samples to encode.
- /// Offset of the frame in pcmSamples.
- /// Buffer to store the encoded frame.
- /// Length of the frame contained in outputBuffer.
- public unsafe int EncodeFrame(byte[] input, int inputOffset, byte[] output)
- {
- int result = 0;
- fixed (byte* inPtr = input)
- result = UnsafeNativeMethods.Encode(_ptr, inPtr + inputOffset, SamplesPerFrame, output, output.Length);
-
- if (result < 0)
- throw new Exception(((OpusError)result).ToString());
- return result;
- }
-
- /// Gets or sets whether Forward Error Correction is enabled.
- public void SetForwardErrorCorrection(bool value)
- {
- var result = UnsafeNativeMethods.EncoderCtl(_ptr, Ctl.SetInbandFECRequest, value ? 1 : 0);
- if (result < 0)
- throw new Exception(((OpusError)result).ToString());
- }
-
- /// Gets or sets whether Forward Error Correction is enabled.
- public void SetBitrate(int value)
- {
- var result = UnsafeNativeMethods.EncoderCtl(_ptr, Ctl.SetBitrateRequest, value * 1000);
- if (result < 0)
- throw new Exception(((OpusError)result).ToString());
- }
-
- protected override void Dispose(bool disposing)
- {
- if (_ptr != IntPtr.Zero)
- {
- UnsafeNativeMethods.DestroyEncoder(_ptr);
- _ptr = IntPtr.Zero;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Discord.Net.Audio/Sodium/SecretBox.cs b/src/Discord.Net.Audio/Sodium/SecretBox.cs
deleted file mode 100644
index f73093316..000000000
--- a/src/Discord.Net.Audio/Sodium/SecretBox.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using System.Runtime.InteropServices;
-#if NET45
-using System.Security;
-#endif
-
-namespace Discord.Audio.Sodium
-{
- internal unsafe static class SecretBox
- {
-#if NET45
- [SuppressUnmanagedCodeSecurity]
-#endif
- private static class SafeNativeMethods
- {
- [DllImport("libsodium", EntryPoint = "crypto_secretbox_easy", CallingConvention = CallingConvention.Cdecl)]
- public static extern int SecretBoxEasy(byte* output, byte[] input, long inputLength, byte[] nonce, byte[] secret);
- [DllImport("libsodium", EntryPoint = "crypto_secretbox_open_easy", CallingConvention = CallingConvention.Cdecl)]
- public static extern int SecretBoxOpenEasy(byte[] output, byte* input, long inputLength, byte[] nonce, byte[] secret);
- }
-
- public static int Encrypt(byte[] input, long inputLength, byte[] output, int outputOffset, byte[] nonce, byte[] secret)
- {
- fixed (byte* outPtr = output)
- return SafeNativeMethods.SecretBoxEasy(outPtr + outputOffset, input, inputLength, nonce, secret);
- }
- public static int Decrypt(byte[] input, int inputOffset, long inputLength, byte[] output, byte[] nonce, byte[] secret)
- {
- fixed (byte* inPtr = input)
- return SafeNativeMethods.SecretBoxOpenEasy(output, inPtr + inputLength, inputLength, nonce, secret);
- }
- }
-}
diff --git a/src/Discord.Net.Audio/UserIsTalkingEventArgs.cs b/src/Discord.Net.Audio/UserIsTalkingEventArgs.cs
deleted file mode 100644
index 698f44d4c..000000000
--- a/src/Discord.Net.Audio/UserIsTalkingEventArgs.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace Discord
-{
- public class UserIsSpeakingEventArgs : UserEventArgs
- {
- public bool IsSpeaking { get; }
-
- public UserIsSpeakingEventArgs(User user, bool isSpeaking)
- : base(user)
- {
- IsSpeaking = isSpeaking;
- }
- }
-}
diff --git a/src/Discord.Net.Audio/VirtualClient.cs b/src/Discord.Net.Audio/VirtualClient.cs
deleted file mode 100644
index 9c8100e47..000000000
--- a/src/Discord.Net.Audio/VirtualClient.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using Discord.Net.Rest;
-using Discord.Net.WebSockets;
-using System.IO;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Discord.Audio
-{
- internal class VirtualClient : IAudioClient
- {
- private readonly AudioClient _client;
-
- public Server Server { get; }
-
- public int Id => 0;
- public string SessionId => _client.Server == Server ? _client.SessionId : null;
-
- public ConnectionState State => _client.Server == Server ? _client.State : ConnectionState.Disconnected;
- public VoiceChannel Channel => _client.Server == Server ? _client.Channel : null;
- public CancellationToken CancelToken => _client.Server == Server ? _client.CancelToken : CancellationToken.None;
-
- public RestClient ClientAPI => _client.Server == Server ? _client.ClientAPI : null;
- public GatewaySocket GatewaySocket => _client.Server == Server ? _client.GatewaySocket : null;
- public VoiceSocket VoiceSocket => _client.Server == Server ? _client.VoiceSocket : null;
-
- public VirtualClient(AudioClient client, Server server)
- {
- _client = client;
- Server = server;
- }
-
- public Task Disconnect() => _client.Service.Leave(Server);
- public Task Join(VoiceChannel channel) => _client.Join(channel);
-
- public void Send(byte[] data, int offset, int count) => _client.Send(data, offset, count);
- public void Clear() => _client.Clear();
- public void Wait() => _client.Wait();
- }
-}
diff --git a/src/Discord.Net.Audio/VoiceBuffer.cs b/src/Discord.Net.Audio/VoiceBuffer.cs
deleted file mode 100644
index 054ab81a0..000000000
--- a/src/Discord.Net.Audio/VoiceBuffer.cs
+++ /dev/null
@@ -1,140 +0,0 @@
-using Nito.AsyncEx;
-using System;
-using System.Threading;
-
-namespace Discord.Audio
-{
- internal class VoiceBuffer
- {
- private readonly int _frameSize, _frameCount, _bufferSize;
- private readonly byte[] _buffer;
- private readonly byte[] _blankFrame;
- private ushort _readCursor, _writeCursor;
- private ManualResetEventSlim _notOverflowEvent;
- private bool _isClearing;
- private AsyncLock _lock;
-
- public int FrameSize => _frameSize;
- public int FrameCount => _frameCount;
- public ushort ReadPos => _readCursor;
- public ushort WritePos => _writeCursor;
-
- public VoiceBuffer(int frameCount, int frameSize)
- {
- _frameSize = frameSize;
- _frameCount = frameCount;
- _bufferSize = _frameSize * _frameCount;
- _readCursor = 0;
- _writeCursor = 0;
- _buffer = new byte[_bufferSize];
- _blankFrame = new byte[_frameSize];
- _notOverflowEvent = new ManualResetEventSlim(); //Notifies when an overflow is solved
- _lock = new AsyncLock();
- }
-
- public void Push(byte[] buffer, int offset, int count, CancellationToken cancelToken)
- {
- if (cancelToken.IsCancellationRequested)
- throw new OperationCanceledException("Client is disconnected.", cancelToken);
-
- int wholeFrames = count / _frameSize;
- int expectedBytes = wholeFrames * _frameSize;
- int lastFrameSize = count - expectedBytes;
-
- using (_lock.Lock())
- {
- for (int i = 0, pos = offset; i <= wholeFrames; i++, pos += _frameSize)
- {
- //If the read cursor is in the next position, wait for it to move.
- ushort nextPosition = _writeCursor;
- AdvanceCursorPos(ref nextPosition);
- if (_readCursor == nextPosition)
- {
- _notOverflowEvent.Reset();
- try
- {
- _notOverflowEvent.Wait(cancelToken);
- }
- catch (OperationCanceledException ex)
- {
- throw new OperationCanceledException("Client is disconnected.", ex, cancelToken);
- }
- }
-
- if (i == wholeFrames)
- {
- //If there are no partial frames, skip this step
- if (lastFrameSize == 0)
- break;
-
- //Copy partial frame
- Buffer.BlockCopy(buffer, pos, _buffer, _writeCursor * _frameSize, lastFrameSize);
-
- //Wipe the end of the buffer
- Buffer.BlockCopy(_blankFrame, 0, _buffer, _writeCursor * _frameSize + lastFrameSize, _frameSize - lastFrameSize);
- }
- else
- {
- //Copy full frame
- Buffer.BlockCopy(buffer, pos, _buffer, _writeCursor * _frameSize, _frameSize);
- }
-
- //Advance the write cursor to the next position
- AdvanceCursorPos(ref _writeCursor);
- }
- }
- }
-
- public bool Pop(byte[] buffer)
- {
- //using (_lock.Lock())
- //{
- if (_writeCursor == _readCursor)
- {
- _notOverflowEvent.Set();
- return false;
- }
-
- bool isClearing = _isClearing;
- if (!isClearing)
- Buffer.BlockCopy(_buffer, _readCursor * _frameSize, buffer, 0, _frameSize);
-
- //Advance the read cursor to the next position
- AdvanceCursorPos(ref _readCursor);
- _notOverflowEvent.Set();
- return !isClearing;
- //}
- }
-
- public void Clear(CancellationToken cancelToken)
- {
- using (_lock.Lock())
- {
- _isClearing = true;
- for (int i = 0; i < _frameCount; i++)
- Buffer.BlockCopy(_blankFrame, 0, _buffer, i * _frameCount, i++);
-
- _writeCursor = 0;
- _readCursor = 0;
- _isClearing = false;
- }
- }
-
- public void Wait(CancellationToken cancelToken)
- {
- while (true)
- {
- _notOverflowEvent.Wait(cancelToken);
- if (_writeCursor == _readCursor)
- break;
- }
- }
-
- private void AdvanceCursorPos(ref ushort pos)
- {
- pos++;
- if (pos == _frameCount)
- pos = 0;
- }
- }
-}
\ No newline at end of file
diff --git a/src/Discord.Net.Audio/VoiceDisconnectedEventArgs.cs b/src/Discord.Net.Audio/VoiceDisconnectedEventArgs.cs
deleted file mode 100644
index 4f46abde2..000000000
--- a/src/Discord.Net.Audio/VoiceDisconnectedEventArgs.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-
-namespace Discord
-{
- public class VoiceDisconnectedEventArgs : DisconnectedEventArgs
- {
- public ulong ServerId { get; }
-
- public VoiceDisconnectedEventArgs(ulong serverId, bool wasUnexpected, Exception ex)
- : base(wasUnexpected, ex)
- {
- ServerId = serverId;
- }
- }
-}
diff --git a/src/Discord.Net.Audio/libsodium.dll b/src/Discord.Net.Audio/libsodium.dll
deleted file mode 100644
index a9ab5078e..000000000
Binary files a/src/Discord.Net.Audio/libsodium.dll and /dev/null differ
diff --git a/src/Discord.Net.Audio/opus.dll b/src/Discord.Net.Audio/opus.dll
deleted file mode 100644
index a9eec802c..000000000
Binary files a/src/Discord.Net.Audio/opus.dll and /dev/null differ
diff --git a/src/Discord.Net.Audio/project.json b/src/Discord.Net.Audio/project.json
deleted file mode 100644
index c41a619c7..000000000
--- a/src/Discord.Net.Audio/project.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "version": "1.0.0-alpha1",
- "description": "A Discord.Net extension adding voice support.",
- "authors": [ "RogueException" ],
- "tags": [ "discord", "discordapp" ],
- "projectUrl": "https://github.com/RogueException/Discord.Net",
- "licenseUrl": "http://opensource.org/licenses/MIT",
- "repository": {
- "type": "git",
- "url": "git://github.com/RogueException/Discord.Net"
- },
- "compile": [ "**/*.cs", "../Discord.Net.Shared/*.cs" ],
- "contentFiles": [ "libsodium.dll", "opus.dll" ],
-
- "compilationOptions": {
- "allowUnsafe": true,
- "warningsAsErrors": true
- },
-
- "dependencies": {
- "Discord.Net": "1.0.0-alpha1"
- },
- "frameworks": {
- "net45": { },
- "dotnet5.4": { }
- }
-}
diff --git a/src/Discord.Net.Commands/Command.cs b/src/Discord.Net.Commands/Command.cs
deleted file mode 100644
index ccd62798b..000000000
--- a/src/Discord.Net.Commands/Command.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-using Discord.Commands.Permissions;
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-
-namespace Discord.Commands
-{
- //TODO: Make this more friendly and expose it to be extendable
- public class Command
- {
- private string[] _aliases;
- internal CommandParameter[] _parameters;
- private IPermissionChecker[] _checks;
- private Func _runFunc;
- internal readonly Dictionary _parametersByName;
-
- public string Text { get; }
- public string Category { get; internal set; }
- public bool IsHidden { get; internal set; }
- public string Description { get; internal set; }
-
- public IEnumerable Aliases => _aliases;
- public IEnumerable Parameters => _parameters;
- public CommandParameter this[string name] => _parametersByName[name];
-
- internal Command(string text)
- {
- Text = text;
- IsHidden = false;
- _aliases = new string[0];
- _parameters = new CommandParameter[0];
- _parametersByName = new Dictionary();
- }
-
-
- internal void SetAliases(string[] aliases)
- {
- _aliases = aliases;
- }
- internal void SetParameters(CommandParameter[] parameters)
- {
- _parametersByName.Clear();
- for (int i = 0; i < parameters.Length; i++)
- {
- parameters[i].Id = i;
- _parametersByName[parameters[i].Name] = parameters[i];
- }
- _parameters = parameters;
- }
- internal void SetChecks(IPermissionChecker[] checks)
- {
- _checks = checks;
- }
-
- internal bool CanRun(User user, ITextChannel channel, out string error)
- {
- for (int i = 0; i < _checks.Length; i++)
- {
- if (!_checks[i].CanRun(this, user, channel, out error))
- return false;
- }
- error = null;
- return true;
- }
-
- internal void SetRunFunc(Func func)
- {
- _runFunc = func;
- }
- internal void SetRunFunc(Action func)
- {
- _runFunc = TaskHelper.ToAsync(func);
- }
- internal Task Run(CommandEventArgs args)
- {
- var task = _runFunc(args);
- if (task != null)
- return task;
- else
- return TaskHelper.CompletedTask;
- }
- }
-}
diff --git a/src/Discord.Net.Commands/CommandBuilder.cs b/src/Discord.Net.Commands/CommandBuilder.cs
deleted file mode 100644
index 6b945841c..000000000
--- a/src/Discord.Net.Commands/CommandBuilder.cs
+++ /dev/null
@@ -1,163 +0,0 @@
-using Discord.Commands.Permissions;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace Discord.Commands
-{
- //TODO: Make this more friendly and expose it to be extendable
- public sealed class CommandBuilder
- {
- private readonly CommandService _service;
- private readonly Command _command;
- private readonly List _params;
- private readonly List _checks;
- private readonly List _aliases;
- private readonly string _prefix;
- private bool _allowRequiredParams, _areParamsClosed;
-
- public CommandService Service => _service;
-
- internal CommandBuilder(CommandService service, string text, string prefix = "", string category = "", IEnumerable initialChecks = null)
- {
- _service = service;
- _prefix = prefix;
-
- _command = new Command(AppendPrefix(prefix, text));
- _command.Category = category;
-
- if (initialChecks != null)
- _checks = new List(initialChecks);
- else
- _checks = new List();
-
- _params = new List();
- _aliases = new List();
-
- _allowRequiredParams = true;
- _areParamsClosed = false;
- }
-
- public CommandBuilder Alias(params string[] aliases)
- {
- _aliases.AddRange(aliases);
- return this;
- }
- /*public CommandBuilder Category(string category)
- {
- _command.Category = category;
- return this;
- }*/
- public CommandBuilder Description(string description)
- {
- _command.Description = description;
- return this;
- }
- public CommandBuilder Parameter(string name, ParameterType type = ParameterType.Required)
- {
- if (_areParamsClosed)
- throw new Exception($"No parameters may be added after a {nameof(ParameterType.Multiple)} or {nameof(ParameterType.Unparsed)} parameter.");
- if (!_allowRequiredParams && type == ParameterType.Required)
- throw new Exception($"{nameof(ParameterType.Required)} parameters may not be added after an optional one");
-
- _params.Add(new CommandParameter(name, type));
-
- if (type == ParameterType.Optional)
- _allowRequiredParams = false;
- if (type == ParameterType.Multiple || type == ParameterType.Unparsed)
- _areParamsClosed = true;
- return this;
- }
- public CommandBuilder Hide()
- {
- _command.IsHidden = true;
- return this;
- }
- public CommandBuilder AddCheck(IPermissionChecker check)
- {
- _checks.Add(check);
- return this;
- }
- public CommandBuilder AddCheck(Func checkFunc, string errorMsg = null)
- {
- _checks.Add(new GenericPermissionChecker(checkFunc, errorMsg));
- return this;
- }
-
- public void Do(Func func)
- {
- _command.SetRunFunc(func);
- Build();
- }
- public void Do(Action func)
- {
- _command.SetRunFunc(func);
- Build();
- }
- private void Build()
- {
- _command.SetParameters(_params.ToArray());
- _command.SetChecks(_checks.ToArray());
- _command.SetAliases(_aliases.Select(x => AppendPrefix(_prefix, x)).ToArray());
- _service.AddCommand(_command);
- }
-
- internal static string AppendPrefix(string prefix, string cmd)
- {
- if (cmd != "")
- {
- if (prefix != "")
- return prefix + ' ' + cmd;
- else
- return cmd;
- }
- else
- return prefix;
- }
- }
- public class CommandGroupBuilder
- {
- private readonly CommandService _service;
- private readonly string _prefix;
- private readonly List _checks;
- private string _category;
-
- public CommandService Service => _service;
-
- internal CommandGroupBuilder(CommandService service, string prefix = "", string category = null, IEnumerable initialChecks = null)
- {
- _service = service;
- _prefix = prefix;
- _category = category;
- if (initialChecks != null)
- _checks = new List(initialChecks);
- else
- _checks = new List();
- }
-
- public CommandGroupBuilder Category(string category)
- {
- _category = category;
- return this;
- }
- public void AddCheck(IPermissionChecker checker)
- {
- _checks.Add(checker);
- }
- public void AddCheck(Func checkFunc, string errorMsg = null)
- {
- _checks.Add(new GenericPermissionChecker(checkFunc, errorMsg));
- }
-
- public CommandGroupBuilder CreateGroup(string cmd, Action config)
- {
- config(new CommandGroupBuilder(_service, CommandBuilder.AppendPrefix(_prefix, cmd), _category, _checks));
- return this;
- }
- public CommandBuilder CreateCommand()
- => CreateCommand("");
- public CommandBuilder CreateCommand(string cmd)
- => new CommandBuilder(_service, cmd, _prefix, _category, _checks);
- }
-}
diff --git a/src/Discord.Net.Commands/CommandErrorEventArgs.cs b/src/Discord.Net.Commands/CommandErrorEventArgs.cs
deleted file mode 100644
index 5f47c6d7c..000000000
--- a/src/Discord.Net.Commands/CommandErrorEventArgs.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System;
-
-namespace Discord.Commands
-{
- public enum CommandErrorType { Exception, UnknownCommand, BadPermissions, BadArgCount, InvalidInput }
- public class CommandErrorEventArgs : CommandEventArgs
- {
- public CommandErrorType ErrorType { get; }
- public Exception Exception { get; }
-
- public CommandErrorEventArgs(CommandErrorType errorType, CommandEventArgs baseArgs, Exception ex)
- : base(baseArgs.Message, baseArgs.Command, baseArgs.Args)
- {
- Exception = ex;
- ErrorType = errorType;
- }
- }
-}
diff --git a/src/Discord.Net.Commands/CommandEventArgs.cs b/src/Discord.Net.Commands/CommandEventArgs.cs
deleted file mode 100644
index 70793f5e1..000000000
--- a/src/Discord.Net.Commands/CommandEventArgs.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System;
-
-namespace Discord.Commands
-{
- public class CommandEventArgs : EventArgs
- {
- private readonly string[] _args;
-
- public Message Message { get; }
- public Command Command { get; }
-
- public User User => Message.User;
- public ITextChannel Channel => Message.Channel;
-
- public CommandEventArgs(Message message, Command command, string[] args)
- {
- Message = message;
- Command = command;
- _args = args;
- }
-
- public string[] Args => _args;
- public string GetArg(int index) => _args[index];
- public string GetArg(string name) => _args[Command[name].Id];
- }
-}
diff --git a/src/Discord.Net.Commands/CommandExtensions.cs b/src/Discord.Net.Commands/CommandExtensions.cs
deleted file mode 100644
index c57cf099f..000000000
--- a/src/Discord.Net.Commands/CommandExtensions.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System;
-
-namespace Discord.Commands
-{
- public static class CommandExtensions
- {
- public static DiscordClient UsingCommands(this DiscordClient client, CommandServiceConfig config = null)
- {
- client.AddService(new CommandService(config));
- return client;
- }
- public static DiscordClient UsingCommands(this DiscordClient client, Action configFunc = null)
- {
- var builder = new CommandServiceConfigBuilder();
- configFunc(builder);
- client.AddService(new CommandService(builder));
- return client;
- }
- }
-}
diff --git a/src/Discord.Net.Commands/CommandMap.cs b/src/Discord.Net.Commands/CommandMap.cs
deleted file mode 100644
index ad280b335..000000000
--- a/src/Discord.Net.Commands/CommandMap.cs
+++ /dev/null
@@ -1,141 +0,0 @@
-using System.Collections.Generic;
-
-namespace Discord.Commands
-{
- //Represents either a single function, command group, or both
- internal class CommandMap
- {
- private readonly CommandMap _parent;
- private readonly string _name, _fullName;
-
- private readonly List _commands;
- private readonly Dictionary _items;
- private bool _isVisible, _hasNonAliases, _hasSubGroups;
-
- public string Name => _name;
- public string FullName => _fullName;
- public bool IsVisible => _isVisible;
- public bool HasNonAliases => _hasNonAliases;
- public bool HasSubGroups => _hasSubGroups;
- public IEnumerable Commands => _commands;
- public IEnumerable SubGroups => _items.Values;
-
- public CommandMap()
- {
- _items = new Dictionary();
- _commands = new List();
- _isVisible = false;
- _hasNonAliases = false;
- _hasSubGroups = false;
- }
- public CommandMap(CommandMap parent, string name, string fullName)
- : this()
- {
- _parent = parent;
- _name = name;
- _fullName = fullName;
- }
-
- public CommandMap GetItem(string text)
- {
- return GetItem(0, text.Split(' '));
- }
- public CommandMap GetItem(int index, string[] parts)
- {
- if (index != parts.Length)
- {
- string nextPart = parts[index];
- CommandMap nextGroup;
- if (_items.TryGetValue(nextPart.ToLowerInvariant(), out nextGroup))
- return nextGroup.GetItem(index + 1, parts);
- else
- return null;
- }
- return this;
- }
-
- public IEnumerable GetCommands()
- {
- if (_commands.Count > 0)
- return _commands;
- else if (_parent != null)
- return _parent.GetCommands();
- else
- return null;
- }
- public IEnumerable GetCommands(string text)
- {
- return GetCommands(0, text.Split(' '));
- }
- public IEnumerable GetCommands(int index, string[] parts)
- {
- if (index != parts.Length)
- {
- string nextPart = parts[index];
- CommandMap nextGroup;
- if (_items.TryGetValue(nextPart.ToLowerInvariant(), out nextGroup))
- {
- var cmd = nextGroup.GetCommands(index + 1, parts);
- if (cmd != null)
- return cmd;
- }
- }
-
- if (_commands != null)
- return _commands;
- return null;
- }
-
- public void AddCommand(string text, Command command, bool isAlias)
- {
- AddCommand(0, text.Split(' '), command, isAlias);
- }
- private void AddCommand(int index, string[] parts, Command command, bool isAlias)
- {
- if (!command.IsHidden)
- _isVisible = true;
-
- if (index != parts.Length)
- {
- CommandMap nextGroup;
- string name = parts[index].ToLowerInvariant();
- string fullName = string.Join(" ", parts, 0, index + 1);
- if (!_items.TryGetValue(name, out nextGroup))
- {
- nextGroup = new CommandMap(this, name, fullName);
- _items.Add(name, nextGroup);
- _hasSubGroups = true;
- }
- nextGroup.AddCommand(index + 1, parts, command, isAlias);
- }
- else
- {
- _commands.Add(command);
- if (!isAlias)
- _hasNonAliases = true;
- }
- }
-
- public bool CanRun(User user, ITextChannel channel, out string error)
- {
- error = null;
- if (_commands.Count > 0)
- {
- foreach (var cmd in _commands)
- {
- if (cmd.CanRun(user, channel, out error))
- return true;
- }
- }
- if (_items.Count > 0)
- {
- foreach (var item in _items)
- {
- if (item.Value.CanRun(user, channel, out error))
- return true;
- }
- }
- return false;
- }
- }
-}
diff --git a/src/Discord.Net.Commands/CommandParameter.cs b/src/Discord.Net.Commands/CommandParameter.cs
deleted file mode 100644
index d7361bef4..000000000
--- a/src/Discord.Net.Commands/CommandParameter.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-namespace Discord.Commands
-{
- public enum ParameterType
- {
- /// Catches a single required parameter.
- Required,
- /// Catches a single optional parameter.
- Optional,
- /// Catches a zero or more optional parameters.
- Multiple,
- /// Catches all remaining text as a single optional parameter.
- Unparsed
- }
- public class CommandParameter
- {
- public string Name { get; }
- public int Id { get; internal set; }
- public ParameterType Type { get; }
-
- internal CommandParameter(string name, ParameterType type)
- {
- Name = name;
- Type = type;
- }
- }
-}
diff --git a/src/Discord.Net.Commands/CommandParser.cs b/src/Discord.Net.Commands/CommandParser.cs
deleted file mode 100644
index cfdbe6903..000000000
--- a/src/Discord.Net.Commands/CommandParser.cs
+++ /dev/null
@@ -1,188 +0,0 @@
-using System.Collections.Generic;
-
-namespace Discord.Commands
-{
- internal static class CommandParser
- {
- private enum ParserPart
- {
- None,
- Parameter,
- QuotedParameter,
- DoubleQuotedParameter
- }
-
- public static bool ParseCommand(string input, CommandMap map, out IEnumerable commands, out int endPos)
- {
- int startPosition = 0;
- int endPosition = 0;
- int inputLength = input.Length;
- bool isEscaped = false;
- commands = null;
- endPos = 0;
-
- if (input == "")
- return false;
-
- while (endPosition < inputLength)
- {
- char currentChar = input[endPosition++];
- if (isEscaped)
- isEscaped = false;
- else if (currentChar == '\\')
- isEscaped = true;
-
- bool isWhitespace = IsWhiteSpace(currentChar);
- if ((!isEscaped && isWhitespace) || endPosition >= inputLength)
- {
- int length = (isWhitespace ? endPosition - 1 : endPosition) - startPosition;
- string temp = input.Substring(startPosition, length);
- if (temp == "")
- startPosition = endPosition;
- else
- {
- var newMap = map.GetItem(temp);
- if (newMap != null)
- {
- map = newMap;
- endPos = endPosition;
- }
- else
- break;
- startPosition = endPosition;
- }
- }
- }
- commands = map.GetCommands(); //Work our way backwards to find a command that matches our input
- return commands != null;
- }
- private static bool IsWhiteSpace(char c) => c == ' ' || c == '\n' || c == '\r' || c == '\t';
-
- //TODO: Check support for escaping
- public static CommandErrorType? ParseArgs(string input, int startPos, Command command, out string[] args)
- {
- ParserPart currentPart = ParserPart.None;
- int startPosition = startPos;
- int endPosition = startPos;
- int inputLength = input.Length;
- bool isEscaped = false;
-
- var expectedArgs = command._parameters;
- List argList = new List();
- CommandParameter parameter = null;
-
- args = null;
-
- if (input == "")
- return CommandErrorType.InvalidInput;
-
- while (endPosition < inputLength)
- {
- if (startPosition == endPosition && (parameter == null || parameter.Type != ParameterType.Multiple)) //Is first char of a new arg
- {
- if (argList.Count >= expectedArgs.Length)
- return CommandErrorType.BadArgCount; //Too many args
- parameter = expectedArgs[argList.Count];
- if (parameter.Type == ParameterType.Unparsed)
- {
- argList.Add(input.Substring(startPosition));
- break;
- }
- }
-
- char currentChar = input[endPosition++];
- if (isEscaped)
- isEscaped = false;
- else if (currentChar == '\\')
- isEscaped = true;
-
- bool isWhitespace = IsWhiteSpace(currentChar);
- if (endPosition == startPosition + 1 && isWhitespace) //Has no text yet, and is another whitespace
- {
- startPosition = endPosition;
- continue;
- }
-
- switch (currentPart)
- {
- case ParserPart.None:
- if ((!isEscaped && currentChar == '\"'))
- {
- currentPart = ParserPart.DoubleQuotedParameter;
- startPosition = endPosition;
- }
- else if ((!isEscaped && currentChar == '\''))
- {
- currentPart = ParserPart.QuotedParameter;
- startPosition = endPosition;
- }
- else if ((!isEscaped && isWhitespace) || endPosition >= inputLength)
- {
- int length = (isWhitespace ? endPosition - 1 : endPosition) - startPosition;
- if (length == 0)
- startPosition = endPosition;
- else
- {
- string temp = input.Substring(startPosition, length);
- argList.Add(temp);
- currentPart = ParserPart.None;
- startPosition = endPosition;
- }
- }
- break;
- case ParserPart.QuotedParameter:
- if ((!isEscaped && currentChar == '\''))
- {
- string temp = input.Substring(startPosition, endPosition - startPosition - 1);
- argList.Add(temp);
- currentPart = ParserPart.None;
- startPosition = endPosition;
- }
- else if (endPosition >= inputLength)
- return CommandErrorType.InvalidInput;
- break;
- case ParserPart.DoubleQuotedParameter:
- if ((!isEscaped && currentChar == '\"'))
- {
- string temp = input.Substring(startPosition, endPosition - startPosition - 1);
- argList.Add(temp);
- currentPart = ParserPart.None;
- startPosition = endPosition;
- }
- else if (endPosition >= inputLength)
- return CommandErrorType.InvalidInput;
- break;
- }
- }
-
- //Unclosed quotes
- if (currentPart == ParserPart.QuotedParameter ||
- currentPart == ParserPart.DoubleQuotedParameter)
- return CommandErrorType.InvalidInput;
-
- //Too few args
- for (int i = argList.Count; i < expectedArgs.Length; i++)
- {
- var param = expectedArgs[i];
- switch (param.Type)
- {
- case ParameterType.Required:
- return CommandErrorType.BadArgCount;
- case ParameterType.Optional:
- case ParameterType.Unparsed:
- argList.Add("");
- break;
- }
- }
-
- /*if (argList.Count > expectedArgs.Length)
- {
- if (expectedArgs.Length == 0 || expectedArgs[expectedArgs.Length - 1].Type != ParameterType.Multiple)
- return CommandErrorType.BadArgCount;
- }*/
-
- args = argList.ToArray();
- return null;
- }
- }
-}
diff --git a/src/Discord.Net.Commands/CommandService.cs b/src/Discord.Net.Commands/CommandService.cs
deleted file mode 100644
index ea530d27b..000000000
--- a/src/Discord.Net.Commands/CommandService.cs
+++ /dev/null
@@ -1,347 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Discord.Commands
-{
- public partial class CommandService : IService
- {
- private readonly List _allCommands;
- private readonly Dictionary _categories;
- private readonly CommandMap _map; //Command map stores all commands by their input text, used for fast resolving and parsing
-
- public CommandServiceConfig Config { get; }
- public CommandGroupBuilder Root { get; }
- public DiscordClient Client { get; private set; }
-
- //AllCommands store a flattened collection of all commands
- public IEnumerable AllCommands => _allCommands;
- //Groups store all commands by their module, used for more informative help
- internal IEnumerable Categories => _categories.Values;
-
- public event EventHandler CommandExecuted = delegate { };
- public event EventHandler CommandErrored = delegate { };
-
- private void OnCommand(CommandEventArgs args)
- => CommandExecuted(this, args);
- private void OnCommandError(CommandErrorType errorType, CommandEventArgs args, Exception ex = null)
- => CommandErrored(this, new CommandErrorEventArgs(errorType, args, ex));
-
- public CommandService()
- : this(new CommandServiceConfigBuilder())
- {
- }
- public CommandService(CommandServiceConfigBuilder builder)
- : this(builder.Build())
- {
- if (builder.ExecuteHandler != null)
- CommandExecuted += builder.ExecuteHandler;
- if (builder.ErrorHandler != null)
- CommandErrored += builder.ErrorHandler;
- }
- public CommandService(CommandServiceConfig config)
- {
- Config = config;
-
- _allCommands = new List();
- _map = new CommandMap();
- _categories = new Dictionary();
- Root = new CommandGroupBuilder(this);
- }
-
- void IService.Install(DiscordClient client)
- {
- Client = client;
-
- if (Config.HelpMode != HelpMode.Disabled)
- {
- CreateCommand("help")
- .Parameter("command", ParameterType.Multiple)
- .Hide()
- .Description("Returns information about commands.")
- .Do(async e =>
- {
- ITextChannel replyChannel = Config.HelpMode == HelpMode.Public ? e.Channel : await e.User.CreatePMChannel().ConfigureAwait(false);
- if (e.Args.Length > 0) //Show command help
- {
- var map = _map.GetItem(string.Join(" ", e.Args));
- if (map != null)
- await ShowCommandHelp(map, e.User, e.Channel, replyChannel).ConfigureAwait(false);
- else
- await replyChannel.SendMessage("Unable to display help: Unknown command.").ConfigureAwait(false);
- }
- else //Show general help
- await ShowGeneralHelp(e.User, e.Channel, replyChannel).ConfigureAwait(false);
- });
- }
-
- client.MessageReceived += async (s, e) =>
- {
- if (_allCommands.Count == 0) return;
- if (e.Message.User == null || e.Message.User.Id == Client.CurrentUser.Id) return;
-
- string msg = e.Message.RawText;
- if (msg.Length == 0) return;
-
- string cmdMsg = null;
-
- //Check for command char
- if (Config.PrefixChar.HasValue)
- {
- if (msg[0] == Config.PrefixChar.Value)
- cmdMsg = msg.Substring(1);
- }
-
- //Check for mention
- if (cmdMsg == null && Config.AllowMentionPrefix)
- {
- string mention = client.CurrentUser.Mention;
- if (msg.StartsWith(mention) && msg.Length > mention.Length)
- cmdMsg = msg.Substring(mention.Length + 1);
- else
- {
- mention = $"@{client.CurrentUser.Name}";
- if (msg.StartsWith(mention) && msg.Length > mention.Length)
- cmdMsg = msg.Substring(mention.Length + 1);
- }
- }
-
- //Check using custom activator
- if (cmdMsg == null && Config.CustomPrefixHandler != null)
- {
- int index = Config.CustomPrefixHandler(e.Message);
- if (index >= 0)
- cmdMsg = msg.Substring(index);
- }
-
- if (cmdMsg == null) return;
-
- //Parse command
- IEnumerable commands;
- int argPos;
- CommandParser.ParseCommand(cmdMsg, _map, out commands, out argPos);
- if (commands == null)
- {
- CommandEventArgs errorArgs = new CommandEventArgs(e.Message, null, null);
- OnCommandError(CommandErrorType.UnknownCommand, errorArgs);
- return;
- }
- else
- {
- foreach (var command in commands)
- {
- //Parse arguments
- string[] args;
- var error = CommandParser.ParseArgs(cmdMsg, argPos, command, out args);
- if (error != null)
- {
- if (error == CommandErrorType.BadArgCount)
- continue;
- else
- {
- var errorArgs = new CommandEventArgs(e.Message, command, null);
- OnCommandError(error.Value, errorArgs);
- return;
- }
- }
-
- var eventArgs = new CommandEventArgs(e.Message, command, args);
-
- // Check permissions
- string errorText;
- if (!command.CanRun(eventArgs.User, eventArgs.Channel, out errorText))
- {
- OnCommandError(CommandErrorType.BadPermissions, eventArgs, errorText != null ? new Exception(errorText) : null);
- return;
- }
-
- // Run the command
- try
- {
- OnCommand(eventArgs);
- await command.Run(eventArgs).ConfigureAwait(false);
- }
- catch (Exception ex)
- {
- OnCommandError(CommandErrorType.Exception, eventArgs, ex);
- }
- return;
- }
- var errorArgs2 = new CommandEventArgs(e.Message, null, null);
- OnCommandError(CommandErrorType.BadArgCount, errorArgs2);
- }
- };
- }
-
- public Task ShowGeneralHelp(User user, ITextChannel channel, ITextChannel replyChannel = null)
- {
- StringBuilder output = new StringBuilder();
- bool isFirstCategory = true;
- foreach (var category in _categories)
- {
- bool isFirstItem = true;
- foreach (var group in category.Value.SubGroups)
- {
- string error;
- if (group.IsVisible && (group.HasSubGroups || group.HasNonAliases) && group.CanRun(user, channel, out error))
- {
- if (isFirstItem)
- {
- isFirstItem = false;
- //This is called for the first item in each category. If we never get here, we dont bother writing the header for a category type (since it's empty)
- if (isFirstCategory)
- {
- isFirstCategory = false;
- //Called for the first non-empty category
- output.AppendLine("These are the commands you can use:");
- }
- else
- output.AppendLine();
- if (category.Key != "")
- {
- output.Append(Format.Bold(category.Key));
- output.Append(": ");
- }
- }
- else
- output.Append(", ");
- output.Append('`');
- output.Append(group.Name);
- if (group.HasSubGroups)
- output.Append("*");
- output.Append('`');
- }
- }
- }
-
- if (output.Length == 0)
- output.Append("There are no commands you have permission to run.");
- else
- output.AppendLine("\n\nRun `help ` for more information.");
-
- return (replyChannel ?? channel).SendMessage(output.ToString());
- }
-
- private Task ShowCommandHelp(CommandMap map, User user, ITextChannel channel, ITextChannel replyChannel = null)
- {
- StringBuilder output = new StringBuilder();
-
- IEnumerable cmds = map.Commands;
- bool isFirstCmd = true;
- string error;
- if (cmds.Any())
- {
- foreach (var cmd in cmds)
- {
- if (cmd.CanRun(user, channel, out error))
- {
- if (isFirstCmd)
- isFirstCmd = false;
- else
- output.AppendLine();
- ShowCommandHelpInternal(cmd, user, channel, output);
- }
- }
- }
- else
- {
- output.Append('`');
- output.Append(map.FullName);
- output.Append("`\n");
- }
-
- bool isFirstSubCmd = true;
- foreach (var subCmd in map.SubGroups.Where(x => x.CanRun(user, channel, out error) && x.IsVisible))
- {
- if (isFirstSubCmd)
- {
- isFirstSubCmd = false;
- output.AppendLine("Sub Commands: ");
- }
- else
- output.Append(", ");
- output.Append('`');
- output.Append(subCmd.Name);
- if (subCmd.SubGroups.Any())
- output.Append("*");
- output.Append('`');
- }
-
- if (isFirstCmd && isFirstSubCmd) //Had no commands and no subcommands
- {
- output.Clear();
- output.AppendLine("There are no commands you have permission to run.");
- }
-
- return (replyChannel ?? channel).SendMessage(output.ToString());
- }
- public Task ShowCommandHelp(Command command, User user, ITextChannel channel, ITextChannel replyChannel = null)
- {
- StringBuilder output = new StringBuilder();
- string error;
- if (!command.CanRun(user, channel, out error))
- output.AppendLine(error ?? "You do not have permission to access this command.");
- else
- ShowCommandHelpInternal(command, user, channel, output);
- return (replyChannel ?? channel).SendMessage(output.ToString());
- }
- private void ShowCommandHelpInternal(Command command, User user, ITextChannel channel, StringBuilder output)
- {
- output.Append('`');
- output.Append(command.Text);
- foreach (var param in command.Parameters)
- {
- switch (param.Type)
- {
- case ParameterType.Required:
- output.Append($" <{param.Name}>");
- break;
- case ParameterType.Optional:
- output.Append($" [{param.Name}]");
- break;
- case ParameterType.Multiple:
- output.Append($" [{param.Name}...]");
- break;
- case ParameterType.Unparsed:
- output.Append($" [-]");
- break;
- }
- }
- output.AppendLine("`");
- output.AppendLine($"{command.Description ?? "No description."}");
-
- if (command.Aliases.Any())
- output.AppendLine($"Aliases: `" + string.Join("`, `", command.Aliases) + '`');
- }
-
- public void CreateGroup(string cmd, Action config = null) => Root.CreateGroup(cmd, config);
- public CommandBuilder CreateCommand(string cmd) => Root.CreateCommand(cmd);
-
- internal void AddCommand(Command command)
- {
- _allCommands.Add(command);
-
- //Get category
- CommandMap category;
- string categoryName = command.Category ?? "";
- if (!_categories.TryGetValue(categoryName, out category))
- {
- category = new CommandMap();
- _categories.Add(categoryName, category);
- }
-
- //Add main command
- category.AddCommand(command.Text, command, false);
- _map.AddCommand(command.Text, command, false);
-
- //Add aliases
- foreach (var alias in command.Aliases)
- {
- category.AddCommand(alias, command, true);
- _map.AddCommand(alias, command, true);
- }
- }
- }
-}
diff --git a/src/Discord.Net.Commands/CommandServiceConfig.cs b/src/Discord.Net.Commands/CommandServiceConfig.cs
deleted file mode 100644
index f43c838fb..000000000
--- a/src/Discord.Net.Commands/CommandServiceConfig.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using System;
-
-namespace Discord.Commands
-{
- public class CommandServiceConfigBuilder
- {
- /// Gets or sets the prefix character used to trigger commands, if ActivationMode has the Char flag set.
- public char? PrefixChar { get; set; } = null;
- /// Gets or sets whether a message beginning with a mention to the logged-in user should be treated as a command.
- public bool AllowMentionPrefix { get; set; } = true;
- ///
- /// Gets or sets a custom function used to detect messages that should be treated as commands.
- /// This function should a positive one indicating the index of where the in the message's RawText the command begins,
- /// and a negative value if the message should be ignored.
- ///
- public Func CustomPrefixHandler { get; set; } = null;
-
- /// Gets or sets whether a help function should be automatically generated.
- public HelpMode HelpMode { get; set; } = HelpMode.Disabled;
-
-
- /// Gets or sets a handler that is called on any successful command execution.
- public EventHandler ExecuteHandler { get; set; }
- /// Gets or sets a handler that is called on any error during command parsing or execution.
- public EventHandler ErrorHandler { get; set; }
-
- public CommandServiceConfig Build() => new CommandServiceConfig(this);
- }
- public class CommandServiceConfig
- {
- public char? PrefixChar { get; }
- public bool AllowMentionPrefix { get; }
- public Func CustomPrefixHandler { get; }
-
- /// Gets or sets whether a help function should be automatically generated.
- public HelpMode HelpMode { get; set; } = HelpMode.Disabled;
-
- internal CommandServiceConfig(CommandServiceConfigBuilder builder)
- {
- PrefixChar = builder.PrefixChar;
- AllowMentionPrefix = builder.AllowMentionPrefix;
- CustomPrefixHandler = builder.CustomPrefixHandler;
- HelpMode = builder.HelpMode;
- }
- }
-}
diff --git a/src/Discord.Net.Commands/Discord.Net.Commands.xproj b/src/Discord.Net.Commands/Discord.Net.Commands.xproj
deleted file mode 100644
index 6c0d0ca91..000000000
--- a/src/Discord.Net.Commands/Discord.Net.Commands.xproj
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
- 14.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
-
-
- 19793545-ef89-48f4-8100-3ebaad0a9141
- Discord.Commands
- ..\..\artifacts\obj\$(MSBuildProjectName)
- ..\..\artifacts\bin\$(MSBuildProjectName)\
-
-
- 2.0
-
-
- True
-
-
-
\ No newline at end of file
diff --git a/src/Discord.Net.Commands/GenericPermissionChecker.cs b/src/Discord.Net.Commands/GenericPermissionChecker.cs
deleted file mode 100644
index 10d665811..000000000
--- a/src/Discord.Net.Commands/GenericPermissionChecker.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System;
-
-namespace Discord.Commands.Permissions
-{
- internal class GenericPermissionChecker : IPermissionChecker
- {
- private readonly Func _checkFunc;
- private readonly string _error;
-
- public GenericPermissionChecker(Func checkFunc, string error = null)
- {
- _checkFunc = checkFunc;
- _error = error;
- }
-
- public bool CanRun(Command command, User user, ITextChannel channel, out string error)
- {
- error = _error;
- return _checkFunc(command, user, channel);
- }
- }
-}
diff --git a/src/Discord.Net.Commands/HelpMode.cs b/src/Discord.Net.Commands/HelpMode.cs
deleted file mode 100644
index 272403f42..000000000
--- a/src/Discord.Net.Commands/HelpMode.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace Discord.Commands
-{
- public enum HelpMode
- {
- /// Disable the automatic help command.
- Disabled,
- /// Use the automatic help command and respond in the channel the command is used.
- Public,
- /// Use the automatic help command and respond in a private message.
- Private
- }
-}
diff --git a/src/Discord.Net.Commands/IPermissionChecker.cs b/src/Discord.Net.Commands/IPermissionChecker.cs
deleted file mode 100644
index 0f317ffef..000000000
--- a/src/Discord.Net.Commands/IPermissionChecker.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Discord.Commands.Permissions
-{
- public interface IPermissionChecker
- {
- bool CanRun(Command command, User user, ITextChannel channel, out string error);
- }
-}
diff --git a/src/Discord.Net.Commands/project.json b/src/Discord.Net.Commands/project.json
deleted file mode 100644
index 124a29dfe..000000000
--- a/src/Discord.Net.Commands/project.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "version": "1.0.0-alpha1",
- "description": "A Discord.Net extension adding basic command support.",
- "authors": [ "RogueException" ],
- "tags": [ "discord", "discordapp" ],
- "projectUrl": "https://github.com/RogueException/Discord.Net",
- "licenseUrl": "http://opensource.org/licenses/MIT",
- "repository": {
- "type": "git",
- "url": "git://github.com/RogueException/Discord.Net"
- },
- "compile": [ "**/*.cs", "../Discord.Net.Shared/*.cs" ],
-
- "compilationOptions": {
- "warningsAsErrors": true
- },
-
- "dependencies": {
- "Discord.Net": "1.0.0-alpha1"
- },
- "frameworks": {
- "net45": { },
- "dotnet5.4": { }
- }
-}
diff --git a/src/Discord.Net.Modules/Discord.Net.Modules.xproj b/src/Discord.Net.Modules/Discord.Net.Modules.xproj
deleted file mode 100644
index 77112cd5d..000000000
--- a/src/Discord.Net.Modules/Discord.Net.Modules.xproj
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
- 14.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
-
-
- 01584e8a-78da-486f-9ef9-a894e435841b
- Discord.Modules
- ..\..\artifacts\obj\$(MSBuildProjectName)
- ..\..\artifacts\bin\$(MSBuildProjectName)\
-
-
- 2.0
-
-
- True
-
-
-
\ No newline at end of file
diff --git a/src/Discord.Net.Modules/IModule.cs b/src/Discord.Net.Modules/IModule.cs
deleted file mode 100644
index 48a594eef..000000000
--- a/src/Discord.Net.Modules/IModule.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Discord.Modules
-{
- public interface IModule
- {
- void Install(ModuleManager manager);
- }
-}
diff --git a/src/Discord.Net.Modules/ModuleChecker.cs b/src/Discord.Net.Modules/ModuleChecker.cs
deleted file mode 100644
index 5f9b8e116..000000000
--- a/src/Discord.Net.Modules/ModuleChecker.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using Discord.Commands;
-using Discord.Commands.Permissions;
-
-namespace Discord.Modules
-{
- public class ModuleChecker : IPermissionChecker
- {
- private readonly ModuleManager _manager;
- private readonly ModuleFilter _filterType;
-
- internal ModuleChecker(ModuleManager manager)
- {
- _manager = manager;
- _filterType = manager.FilterType;
- }
-
- public bool CanRun(Command command, User user, ITextChannel channel, out string error)
- {
- if (_filterType == ModuleFilter.None ||
- _filterType == ModuleFilter.AlwaysAllowPrivate ||
- (channel.IsPublic && _manager.HasChannel(channel)))
- {
- error = null;
- return true;
- }
- else
- {
- error = "This module is currently disabled.";
- return false;
- }
- }
- }
-}
diff --git a/src/Discord.Net.Modules/ModuleExtensions.cs b/src/Discord.Net.Modules/ModuleExtensions.cs
deleted file mode 100644
index a96517c06..000000000
--- a/src/Discord.Net.Modules/ModuleExtensions.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-namespace Discord.Modules
-{
- public static class ModuleExtensions
- {
- public static DiscordClient UsingModules(this DiscordClient client)
- {
- client.AddService(new ModuleService());
- return client;
- }
-
- public static void AddModule(this DiscordClient client, IModule instance, string name = null, ModuleFilter filter = ModuleFilter.None)
- {
- client.GetService().Add(instance, name, filter);
- }
- public static void AddModule(this DiscordClient client, string name = null, ModuleFilter filter = ModuleFilter.None)
- where T : class, IModule, new()
- {
- client.GetService().Add(name, filter);
- }
- public static void AddModule(this DiscordClient client, T instance, string name = null, ModuleFilter filter = ModuleFilter.None)
- where T : class, IModule
- {
- client.GetService().Add(instance, name, filter);
- }
- public static ModuleManager GetModule(this DiscordClient client)
- where T : class, IModule
- => client.GetService().Get();
- }
-}
diff --git a/src/Discord.Net.Modules/ModuleFilter.cs b/src/Discord.Net.Modules/ModuleFilter.cs
deleted file mode 100644
index 08fa09a5d..000000000
--- a/src/Discord.Net.Modules/ModuleFilter.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System;
-
-namespace Discord.Modules
-{
- [Flags]
- public enum ModuleFilter
- {
- /// Disables the event and command filters.
- None = 0x0,
- /// Uses the server whitelist to filter events and commands.
- ServerWhitelist = 0x1,
- /// Uses the channel whitelist to filter events and commands.
- ChannelWhitelist = 0x2,
- /// Enables this module in all private messages.
- AlwaysAllowPrivate = 0x4
- }
-}
diff --git a/src/Discord.Net.Modules/ModuleManager.cs b/src/Discord.Net.Modules/ModuleManager.cs
deleted file mode 100644
index 71b5b0c08..000000000
--- a/src/Discord.Net.Modules/ModuleManager.cs
+++ /dev/null
@@ -1,278 +0,0 @@
-using Discord.Commands;
-using Nito.AsyncEx;
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Discord.Modules
-{
- public class ModuleManager : ModuleManager
- where T : class, IModule
- {
- public new T Instance => base.Instance as T;
-
- internal ModuleManager(DiscordClient client, T instance, string name, ModuleFilter filterType)
- : base(client, instance, name, filterType)
- {
- }
- }
-
- public class ModuleManager
- {
- public event EventHandler JoinedServer = delegate { };
- public event EventHandler LeftServer = delegate { };
- public event EventHandler ServerUpdated = delegate { };
- public event EventHandler ServerUnavailable = delegate { };
- public event EventHandler ServerAvailable = delegate { };
-
- public event EventHandler ChannelCreated = delegate { };
- public event EventHandler ChannelDestroyed = delegate { };
- public event EventHandler ChannelUpdated = delegate { };
-
- public event EventHandler RoleCreated = delegate { };
- public event EventHandler RoleUpdated = delegate { };
- public event EventHandler RoleDeleted = delegate { };
-
- public event EventHandler UserBanned = delegate { };
- public event EventHandler UserJoined = delegate { };
- public event EventHandler UserLeft = delegate { };
- public event EventHandler UserUpdated = delegate { };
- public event EventHandler UserUnbanned = delegate { };
- public event EventHandler UserIsTyping = delegate { };
-
- public event EventHandler MessageReceived = delegate { };
- public event EventHandler MessageSent = delegate { };
- public event EventHandler MessageDeleted = delegate { };
- public event EventHandler MessageUpdated = delegate { };
- public event EventHandler MessageReadRemotely = delegate { };
-
- private readonly bool _useServerWhitelist, _useChannelWhitelist, _allowAll, _allowPrivate;
- private readonly ConcurrentDictionary _enabledServers;
- private readonly ConcurrentDictionary _enabledChannels;
- private readonly ConcurrentDictionary _indirectServers;
- private readonly AsyncLock _lock;
-
- public DiscordClient Client { get; }
- public IModule Instance { get; }
- public string Name { get; }
- public string Id { get; }
- public ModuleFilter FilterType { get; }
-
- public IEnumerable