@@ -26,10 +26,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.Net.Commands", "src | |||
EndProject | |||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dotnet", "dotnet", "{EA68EBE2-51C8-4440-9EF7-D633C90A5D35}" | |||
EndProject | |||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Opus.Net", "src\Opus.Net\Opus.Net.xproj", "{42AB6A2D-2F2C-4003-80EF-33B5B5B0ED8E}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Opus.Net", "src\Opus.Net.Net45\Opus.Net.csproj", "{114C8C10-7354-4EC3-819A-33E83AA57768}" | |||
EndProject | |||
Global | |||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||
Debug|Any CPU = Debug|Any CPU | |||
@@ -56,14 +52,6 @@ Global | |||
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.Debug|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 | |||
{42AB6A2D-2F2C-4003-80EF-33B5B5B0ED8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
{42AB6A2D-2F2C-4003-80EF-33B5B5B0ED8E}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
{42AB6A2D-2F2C-4003-80EF-33B5B5B0ED8E}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
{42AB6A2D-2F2C-4003-80EF-33B5B5B0ED8E}.Release|Any CPU.Build.0 = Release|Any CPU | |||
{114C8C10-7354-4EC3-819A-33E83AA57768}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
{114C8C10-7354-4EC3-819A-33E83AA57768}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
{114C8C10-7354-4EC3-819A-33E83AA57768}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
{114C8C10-7354-4EC3-819A-33E83AA57768}.Release|Any CPU.Build.0 = Release|Any CPU | |||
EndGlobalSection | |||
GlobalSection(SolutionProperties) = preSolution | |||
HideSolutionNode = FALSE | |||
@@ -76,7 +64,5 @@ Global | |||
{8D71A857-879A-4A10-859E-5FF824ED6688} = {B47C4063-C4EB-46AA-886D-B868DA1BF0A0} | |||
{1B5603B4-6F8F-4289-B945-7BAAE523D740} = {B47C4063-C4EB-46AA-886D-B868DA1BF0A0} | |||
{EA68EBE2-51C8-4440-9EF7-D633C90A5D35} = {8D7989F0-66CE-4DBB-8230-D8C811E9B1D7} | |||
{42AB6A2D-2F2C-4003-80EF-33B5B5B0ED8E} = {EA68EBE2-51C8-4440-9EF7-D633C90A5D35} | |||
{114C8C10-7354-4EC3-819A-33E83AA57768} = {B47C4063-C4EB-46AA-886D-B868DA1BF0A0} | |||
EndGlobalSection | |||
EndGlobal |
@@ -31,10 +31,6 @@ | |||
<WarningLevel>4</WarningLevel> | |||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors> | |||
</PropertyGroup> | |||
<ItemGroup /> | |||
<ItemGroup> | |||
<Reference Include="System" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\Discord.Net.Net45\Discord.Net.csproj"> | |||
<Project>{8d71a857-879a-4a10-859e-5ff824ed6688}</Project> | |||
@@ -42,6 +38,12 @@ | |||
</ProjectReference> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Reference Include="System" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Compile Include="..\Discord.Net.Commands\Command.cs"> | |||
<Link>Command.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net.Commands\CommandBuilder.cs"> | |||
<Link>CommandBuilder.cs</Link> | |||
</Compile> | |||
@@ -13,5 +13,5 @@ using System.Runtime.InteropServices; | |||
[assembly: ComVisible(false)] | |||
[assembly: Guid("76ea00e6-ea24-41e1-acb2-639c0313fa80")] | |||
[assembly: AssemblyVersion("0.5.0.0")] | |||
[assembly: AssemblyFileVersion("0.5.0.0")] | |||
[assembly: AssemblyVersion("0.6.0.0")] | |||
[assembly: AssemblyFileVersion("0.6.0.0")] |
@@ -0,0 +1,21 @@ | |||
using System; | |||
using System.Threading.Tasks; | |||
namespace Discord.Commands | |||
{ | |||
public sealed class Command | |||
{ | |||
public string Text { get; } | |||
public int? MinArgs { get; internal set; } | |||
public int? MaxArgs { get; internal set; } | |||
public int MinPerms { get; internal set; } | |||
internal readonly string[] Parts; | |||
internal Func<DiscordBotClient.CommandEventArgs, Task> Handler; | |||
internal Command(string text) | |||
{ | |||
Text = text; | |||
Parts = text.ToLowerInvariant().Split(' '); | |||
} | |||
} | |||
} |
@@ -1,32 +1,106 @@ | |||
using System; | |||
using System.Threading.Tasks; | |||
namespace Discord | |||
namespace Discord.Commands | |||
{ | |||
public sealed class CommandBuilder | |||
{ | |||
private readonly Command _command; | |||
public CommandBuilder(Command command) | |||
{ | |||
_command = command; | |||
} | |||
public CommandBuilder ArgsEqual(int argCount) | |||
{ | |||
_command.MinArgs = argCount; | |||
_command.MaxArgs = argCount; | |||
return this; | |||
} | |||
public CommandBuilder ArgsAtLeast(int minArgCount) | |||
{ | |||
_command.MinArgs = minArgCount; | |||
_command.MaxArgs = null; | |||
return this; | |||
} | |||
public CommandBuilder ArgsAtMost(int maxArgCount) | |||
{ | |||
_command.MinArgs = null; | |||
_command.MaxArgs = maxArgCount; | |||
return this; | |||
} | |||
public CommandBuilder ArgsBetween(int minArgCount, int maxArgCount) | |||
{ | |||
_command.MinArgs = minArgCount; | |||
_command.MaxArgs = maxArgCount; | |||
return this; | |||
} | |||
public CommandBuilder NoArgs() | |||
{ | |||
_command.MinArgs = 0; | |||
_command.MaxArgs = 0; | |||
return this; | |||
} | |||
public CommandBuilder AnyArgs() | |||
{ | |||
_command.MinArgs = null; | |||
_command.MaxArgs = null; | |||
return this; | |||
} | |||
public CommandBuilder MinPermissions(int level) | |||
{ | |||
_command.MinPerms = level; | |||
return this; | |||
} | |||
public CommandBuilder Do(Func<DiscordBotClient.CommandEventArgs, Task> func) | |||
{ | |||
_command.Handler = func; | |||
return this; | |||
} | |||
public CommandBuilder Do(Action<DiscordBotClient.CommandEventArgs> func) | |||
{ | |||
#if DNXCORE50 | |||
_command.Handler = e => { func(e); return Task.CompletedTask; }; | |||
#else | |||
_command.Handler = e => { func(e); return Task.Delay(0); }; | |||
#endif | |||
return this; | |||
} | |||
} | |||
public sealed class CommandGroupBuilder | |||
{ | |||
private readonly DiscordBotClient _client; | |||
private readonly string _prefix; | |||
private readonly bool _useWhitelist; | |||
private int _defaultMinPermissions; | |||
public CommandBuilder(DiscordBotClient client, string prefix, bool useWhitelist = false) | |||
internal CommandGroupBuilder(DiscordBotClient client, string prefix, int defaultMinPermissions) | |||
{ | |||
_client = client; | |||
_prefix = prefix; | |||
_useWhitelist = useWhitelist; | |||
} | |||
_defaultMinPermissions = defaultMinPermissions; | |||
} | |||
public void AddCommandGroup(string cmd, Action<CommandBuilder> config, bool useWhitelist = false) | |||
public CommandGroupBuilder DefaultMinPermissions(int level) | |||
{ | |||
config(new CommandBuilder(_client, _prefix + ' ' + cmd, useWhitelist)); | |||
_defaultMinPermissions = level; | |||
return this; | |||
} | |||
public void AddCommand(string cmd, int minArgs, int maxArgs, Action<DiscordBotClient.CommandEventArgs> handler, bool? useWhitelist = null) | |||
public CommandGroupBuilder CreateCommandGroup(string cmd, Action<CommandGroupBuilder> config = null) | |||
{ | |||
AddCommand(cmd, minArgs, maxArgs, e => { handler(e); return null; }, useWhitelist); | |||
config(new CommandGroupBuilder(_client, _prefix + ' ' + cmd, _defaultMinPermissions)); | |||
return this; | |||
} | |||
public void AddCommand(string cmd, int minArgs, int maxArgs, Func<DiscordBotClient.CommandEventArgs, Task> handler, bool? useWhitelist = null) | |||
public CommandBuilder CreateCommand() | |||
=> CreateCommand(""); | |||
public CommandBuilder CreateCommand(string cmd) | |||
{ | |||
_client.AddCommand(cmd != "" ? _prefix + ' ' + cmd : _prefix, minArgs, maxArgs, handler, useWhitelist ?? _useWhitelist); | |||
var command = new Command(cmd != "" ? _prefix + ' ' + cmd : _prefix); | |||
command.MinPerms = _defaultMinPermissions; | |||
_client._commands.Add(command); | |||
return new CommandBuilder(command); | |||
} | |||
} | |||
} |
@@ -1,6 +1,6 @@ | |||
using System.Collections.Generic; | |||
namespace Discord | |||
namespace Discord.Commands | |||
{ | |||
public static class CommandParser | |||
{ | |||
@@ -119,36 +119,5 @@ namespace Discord | |||
args = argList.ToArray(); | |||
return true; | |||
} | |||
public static bool ArgsEqual(string[] args, int expected) | |||
{ | |||
return args.Length == expected; | |||
} | |||
public static bool ArgsAtLeast(string[] args, int expected) | |||
{ | |||
return args.Length >= expected; | |||
} | |||
public static bool ArgsAtMost(string[] args, int expected) | |||
{ | |||
return args.Length <= expected; | |||
} | |||
public static bool ArgsIn(string[] args, params int[] expected) | |||
{ | |||
int count = args.Length; | |||
for (int i = 0; i < expected.Length; i++) | |||
{ | |||
if (count == expected[i]) | |||
return true; | |||
} | |||
return false; | |||
} | |||
public static bool ArgsBetween(string[] args, int min, int max) | |||
{ | |||
return args.Length >= min && args.Length <= max; | |||
} | |||
public static bool NoArgs(string[] args, params int[] expected) | |||
{ | |||
return args.Length == 0; | |||
} | |||
} | |||
} |
@@ -1,14 +1,19 @@ | |||
using System; | |||
using Discord.Commands; | |||
using System; | |||
namespace Discord | |||
{ | |||
public partial class DiscordBotClient : DiscordClient | |||
{ | |||
public class PermissionException : Exception { public PermissionException() : base("User does not have permission to run this command.") { } } | |||
public class CommandEventArgs | |||
{ | |||
public readonly Message Message; | |||
public readonly Command Command; | |||
public readonly string[] Args; | |||
public Message Message { get; } | |||
public Command Command { get; } | |||
public string CommandText { get; } | |||
public int? Permissions { get; } | |||
public string[] Args { get; } | |||
public User User => Message.User; | |||
public string UserId => Message.UserId; | |||
@@ -17,18 +22,21 @@ namespace Discord | |||
public Server Server => Message.Channel.Server; | |||
public string ServerId => Message.Channel.ServerId; | |||
public CommandEventArgs(Message message, Command command, string[] args) | |||
public CommandEventArgs(Message message, Command command, string commandText, int? permissions, string[] args) | |||
{ | |||
Message = message; | |||
Command = command; | |||
CommandText = commandText; | |||
Permissions = permissions; | |||
Args = args; | |||
} | |||
} | |||
public class CommandErrorEventArgs : CommandEventArgs | |||
{ | |||
public readonly Exception Exception; | |||
public CommandErrorEventArgs(Message message, Command command, string[] args, Exception ex) | |||
: base(message, command, args) | |||
public Exception Exception { get; } | |||
public CommandErrorEventArgs(CommandEventArgs baseArgs, Exception ex) | |||
: base(baseArgs.Message, baseArgs.Command, baseArgs.CommandText, baseArgs.Permissions, baseArgs.Args) | |||
{ | |||
Exception = ex; | |||
} | |||
@@ -40,11 +48,17 @@ namespace Discord | |||
if (RanCommand != null) | |||
RanCommand(this, args); | |||
} | |||
public event EventHandler<CommandEventArgs> UnknownCommand; | |||
private void RaiseUnknownCommand(CommandEventArgs args) | |||
{ | |||
if (UnknownCommand != null) | |||
UnknownCommand(this, args); | |||
} | |||
public event EventHandler<CommandErrorEventArgs> CommandError; | |||
private void RaiseCommandError(Message msg, Command command, string[] args, Exception ex) | |||
private void RaiseCommandError(CommandEventArgs args, Exception ex) | |||
{ | |||
if (CommandError != null) | |||
CommandError(this, new CommandErrorEventArgs(msg, command, args, ex)); | |||
CommandError(this, new CommandErrorEventArgs(args, ex)); | |||
} | |||
} | |||
} |
@@ -1,33 +1,13 @@ | |||
using System; | |||
using Discord.Commands; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Threading.Tasks; | |||
namespace Discord | |||
{ | |||
public sealed class Command | |||
{ | |||
public readonly string[] Text; | |||
public readonly int MinArgs, MaxArgs; | |||
public readonly bool UseWhitelist; | |||
internal readonly Func<DiscordBotClient.CommandEventArgs, Task> Handler; | |||
public Command(string[] text, int minArgs, int maxArgs, bool useWhitelist, Func<DiscordBotClient.CommandEventArgs, Task> handler) | |||
{ | |||
Text = text; | |||
MinArgs = minArgs; | |||
MaxArgs = maxArgs; | |||
UseWhitelist = useWhitelist; | |||
Handler = handler; | |||
} | |||
} | |||
/// <summary> | |||
/// A Discord.Net client with extensions for handling common bot operations like text commands. | |||
/// </summary> | |||
/// <summary> A Discord.Net client with extensions for handling common bot operations like text commands. </summary> | |||
public partial class DiscordBotClient : DiscordClient | |||
{ | |||
private List<Command> _commands; | |||
private List<string> _whitelist; | |||
internal List<Command> _commands; | |||
public IEnumerable<Command> Commands => _commands; | |||
@@ -35,17 +15,15 @@ namespace Discord | |||
public bool UseCommandChar { get; set; } | |||
public bool RequireCommandCharInPublic { get; set; } | |||
public bool RequireCommandCharInPrivate { get; set; } | |||
public bool AlwaysUseWhitelist { get; set; } | |||
public DiscordBotClient() | |||
public DiscordBotClient(DiscordClientConfig config = null, Func<User, int> getPermissions = null) | |||
: base(config) | |||
{ | |||
_commands = new List<Command>(); | |||
_whitelist = new List<string>(); | |||
CommandChar = '~'; | |||
RequireCommandCharInPublic = true; | |||
RequireCommandCharInPrivate = true; | |||
AlwaysUseWhitelist = false; | |||
MessageCreated += async (s, e) => | |||
{ | |||
@@ -53,10 +31,6 @@ namespace Discord | |||
if (e.Message.UserId == UserId) | |||
return; | |||
//Check the global whitelist | |||
if (AlwaysUseWhitelist && !_whitelist.Contains(e.Message.UserId)) | |||
return; | |||
//Check for the command character | |||
string msg = e.Message.Text; | |||
if (UseCommandChar) | |||
@@ -86,9 +60,9 @@ namespace Discord | |||
continue; | |||
bool isValid = true; | |||
for (int j = 0; j < cmd.Text.Length; j++) | |||
for (int j = 0; j < cmd.Parts.Length; j++) | |||
{ | |||
if (!string.Equals(args[j], cmd.Text[j], StringComparison.OrdinalIgnoreCase)) | |||
if (!string.Equals(args[j], cmd.Parts[j], StringComparison.OrdinalIgnoreCase)) | |||
{ | |||
isValid = false; | |||
break; | |||
@@ -97,21 +71,26 @@ namespace Discord | |||
if (!isValid) | |||
continue; | |||
//Check Whitelist | |||
if (cmd.UseWhitelist && !_whitelist.Contains(e.Message.UserId)) | |||
continue; | |||
//Check Arg Count | |||
int argCount = args.Length - cmd.Text.Length; | |||
int argCount = args.Length - cmd.Parts.Length; | |||
if (argCount < cmd.MinArgs || argCount > cmd.MaxArgs) | |||
continue; | |||
//Run Command | |||
string[] newArgs = new string[argCount]; | |||
//Clean Args | |||
string[] newArgs = new string[argCount]; | |||
for (int j = 0; j < newArgs.Length; j++) | |||
newArgs[j] = args[j + cmd.Text.Length]; | |||
newArgs[j] = args[j + cmd.Parts.Length]; | |||
var eventArgs = new CommandEventArgs(e.Message, cmd, newArgs); | |||
//Check Permissions | |||
int permissions = getPermissions != null ? getPermissions(e.Message.User) : 0; | |||
var eventArgs = new CommandEventArgs(e.Message, cmd, msg, permissions, newArgs); | |||
if (permissions < cmd.MinPerms) | |||
{ | |||
RaiseCommandError(eventArgs, new PermissionException()); | |||
return; | |||
} | |||
//Run Command | |||
RaiseRanCommand(eventArgs); | |||
try | |||
{ | |||
@@ -121,31 +100,20 @@ namespace Discord | |||
} | |||
catch (Exception ex) | |||
{ | |||
RaiseCommandError(e.Message, cmd, newArgs, ex); | |||
RaiseCommandError(eventArgs, ex); | |||
} | |||
break; | |||
} | |||
}; | |||
} | |||
public void AddCommandGroup(string cmd, Action<CommandBuilder> config, bool useWhitelist = false) | |||
{ | |||
config(new CommandBuilder(this, cmd, useWhitelist)); | |||
} | |||
public void AddCommand(string cmd, int minArgs, int maxArgs, Action<CommandEventArgs> handler, bool useWhitelist = false) | |||
{ | |||
AddCommand(cmd, minArgs, maxArgs, e => { handler(e); return null; }, useWhitelist); | |||
} | |||
public void AddCommand(string cmd, int minArgs, int maxArgs, Func<CommandEventArgs, Task> handler, bool useWhitelist = false) | |||
{ | |||
_commands.Add(new Command(cmd.Split(' '), minArgs, maxArgs, useWhitelist, handler)); | |||
} | |||
public void AddWhitelist(User user) | |||
=> AddWhitelist(user.Id); | |||
public void AddWhitelist(string userId) | |||
public void CreateCommandGroup(string cmd, Action<CommandGroupBuilder> config = null) | |||
=> config(new CommandGroupBuilder(this, cmd, 0)); | |||
public CommandBuilder CreateCommand(string cmd) | |||
{ | |||
_whitelist.Add(userId); | |||
var command = new Command(cmd); | |||
_commands.Add(command); | |||
return new CommandBuilder(command); | |||
} | |||
} | |||
} |
@@ -1,5 +1,5 @@ | |||
{ | |||
"version": "0.5.0-*", | |||
"version": "0.6.0-beta1", | |||
"description": "A small Discord.Net extension to make bot creation easier.", | |||
"authors": [ "RogueException" ], | |||
"tags": [ "discord", "discordapp" ], | |||
@@ -13,7 +13,7 @@ | |||
"warningsAsErrors": true | |||
}, | |||
"dependencies": { | |||
"Discord.Net": "0.5.0" | |||
"Discord.Net": "0.6.0-*" | |||
}, | |||
"frameworks": { | |||
"net45": { }, | |||
@@ -23,6 +23,7 @@ | |||
<ErrorReport>prompt</ErrorReport> | |||
<WarningLevel>2</WarningLevel> | |||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors> | |||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | |||
</PropertyGroup> | |||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | |||
<DebugType>pdbonly</DebugType> | |||
@@ -32,16 +33,13 @@ | |||
<ErrorReport>prompt</ErrorReport> | |||
<WarningLevel>4</WarningLevel> | |||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors> | |||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> | |||
<HintPath>..\..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath> | |||
<Private>True</Private> | |||
</Reference> | |||
<Reference Include="Sodium, Version=0.8.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||
<HintPath>..\..\packages\libsodium-net.0.8.0\lib\Net40\Sodium.dll</HintPath> | |||
<Private>True</Private> | |||
</Reference> | |||
<Reference Include="System" /> | |||
<Reference Include="System.Net.Http" /> | |||
</ItemGroup> | |||
@@ -124,6 +122,12 @@ | |||
<Compile Include="..\Discord.Net\Message.cs"> | |||
<Link>Message.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\Opus\API.cs"> | |||
<Link>Opus\API.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\Opus\OpusEncoder.cs"> | |||
<Link>Opus\OpusEncoder.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\PackedPermissions.cs"> | |||
<Link>PackedPermissions.cs</Link> | |||
</Compile> | |||
@@ -141,20 +145,8 @@ | |||
</Compile> | |||
<Compile Include="Properties\AssemblyInfo.cs" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\Opus.Net.Net45\Opus.Net.csproj"> | |||
<Project>{114c8c10-7354-4ec3-819a-33e83aa57768}</Project> | |||
<Name>Opus.Net</Name> | |||
</ProjectReference> | |||
</ItemGroup> | |||
<ItemGroup /> | |||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | |||
<Import Project="..\..\packages\Baseclass.Contrib.Nuget.Output.1.0.0\build\net40\Baseclass.Contrib.Nuget.Output.targets" Condition="Exists('..\..\packages\Baseclass.Contrib.Nuget.Output.1.0.0\build\net40\Baseclass.Contrib.Nuget.Output.targets')" /> | |||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> | |||
<PropertyGroup> | |||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> | |||
</PropertyGroup> | |||
<Error Condition="!Exists('..\..\packages\Baseclass.Contrib.Nuget.Output.1.0.0\build\net40\Baseclass.Contrib.Nuget.Output.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Baseclass.Contrib.Nuget.Output.1.0.0\build\net40\Baseclass.Contrib.Nuget.Output.targets'))" /> | |||
</Target> | |||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. | |||
Other similar extension points exist, see Microsoft.Common.targets. | |||
<Target Name="BeforeBuild"> | |||
@@ -13,5 +13,5 @@ using System.Runtime.InteropServices; | |||
[assembly: ComVisible(false)] | |||
[assembly: Guid("76ea00e6-ea24-41e1-acb2-639c0313fa80")] | |||
[assembly: AssemblyVersion("0.5.0.0")] | |||
[assembly: AssemblyFileVersion("0.5.0.0")] | |||
[assembly: AssemblyVersion("0.6.0.0")] | |||
[assembly: AssemblyFileVersion("0.6.0.0")] |
@@ -1,6 +1,4 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<packages> | |||
<package id="Baseclass.Contrib.Nuget.Output" version="1.0.0" targetFramework="net45" /> | |||
<package id="libsodium-net" version="0.8.0" targetFramework="net45" /> | |||
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" /> | |||
</packages> |
@@ -1,5 +1,6 @@ | |||
using Discord.API.Models; | |||
using Discord.Helpers; | |||
using System; | |||
using System.IO; | |||
using System.Threading.Tasks; | |||
@@ -124,7 +125,7 @@ namespace Discord.API | |||
} | |||
public static Task<SelfUserInfo> ChangeEmail(string newEmail, string currentPassword) | |||
{ | |||
var request = new APIRequests.ChangeEmail { Email = newEmail, CurrentPassword = currentPassword }; | |||
var request = new APIRequests.ChangeEmail { NewEmail = newEmail, CurrentPassword = currentPassword }; | |||
return Http.Patch<SelfUserInfo>(Endpoints.UserMe, request); | |||
} | |||
public static Task<SelfUserInfo> ChangePassword(string newPassword, string currentEmail, string currentPassword) | |||
@@ -132,5 +133,12 @@ namespace Discord.API | |||
var request = new APIRequests.ChangePassword { NewPassword = newPassword, CurrentEmail = currentEmail, CurrentPassword = currentPassword }; | |||
return Http.Patch<SelfUserInfo>(Endpoints.UserMe, request); | |||
} | |||
public static Task<SelfUserInfo> ChangeAvatar(DiscordClient.AvatarImageType imageType, byte[] bytes, string currentEmail, string currentPassword) | |||
{ | |||
string base64 = Convert.ToBase64String(bytes); | |||
string type = imageType == DiscordClient.AvatarImageType.Jpeg ? "image/jpeg;base64" : "image/png;base64"; | |||
var request = new APIRequests.ChangeAvatar { Avatar = $"data:{type},/9j/{base64}", CurrentEmail = currentEmail, CurrentPassword = currentPassword }; | |||
return Http.Patch<SelfUserInfo>(Endpoints.UserMe, request); | |||
} | |||
} | |||
} |
@@ -78,30 +78,34 @@ namespace Discord.API.Models | |||
public bool Deaf; | |||
} | |||
public class ChangeUsername | |||
public abstract class ChangeProfile | |||
{ | |||
[JsonProperty(PropertyName = "username")] | |||
public string Username; | |||
[JsonProperty(PropertyName = "email")] | |||
public string CurrentEmail; | |||
[JsonProperty(PropertyName = "password")] | |||
public string CurrentPassword; | |||
} | |||
public class ChangeUsername : ChangeProfile | |||
{ | |||
[JsonProperty(PropertyName = "username")] | |||
public string Username; | |||
} | |||
public class ChangeEmail | |||
{ | |||
[JsonProperty(PropertyName = "email")] | |||
public string Email; | |||
public string NewEmail; | |||
[JsonProperty(PropertyName = "password")] | |||
public string CurrentPassword; | |||
} | |||
public class ChangePassword | |||
public class ChangePassword : ChangeProfile | |||
{ | |||
[JsonProperty(PropertyName = "new_password")] | |||
public string NewPassword; | |||
[JsonProperty(PropertyName = "email")] | |||
public string CurrentEmail; | |||
[JsonProperty(PropertyName = "password")] | |||
public string CurrentPassword; | |||
} | |||
public class ChangeAvatar : ChangeProfile | |||
{ | |||
[JsonProperty(PropertyName = "avatar")] | |||
public string Avatar; | |||
} | |||
} | |||
} |
@@ -3,7 +3,6 @@ | |||
#pragma warning disable CS0169 | |||
using Newtonsoft.Json; | |||
using Newtonsoft.Json.Linq; | |||
using System; | |||
namespace Discord.API.Models | |||
@@ -64,7 +64,7 @@ namespace Discord | |||
#if !DNXCORE50 | |||
private string _currentVoiceServerId, _currentVoiceEndpoint, _currentVoiceToken; | |||
public string CurrentVoiceServerId { get { return _currentVoiceEndpoint != null ? _currentVoiceToken : null; } } | |||
public string CurrentVoiceServerId => _currentVoiceEndpoint != null ? _currentVoiceToken : null; | |||
public Server CurrentVoiceServer => _servers[CurrentVoiceServerId]; | |||
#endif | |||
/// <summary> Returns true if the user has successfully logged in and the websocket connection has been established. </summary> | |||
@@ -1384,6 +1384,20 @@ namespace Discord | |||
_users.Update(response.Id, response); | |||
} | |||
public enum AvatarImageType | |||
{ | |||
Jpeg, | |||
Png | |||
} | |||
/// <summary> Changes your avatar. </summary> | |||
/// <remarks>Only supports PNG and JPEG (see AvatarImageType)</remarks> | |||
public async Task ChangeAvatar(AvatarImageType imageType, byte[] bytes, string currentEmail, string currentPassword) | |||
{ | |||
CheckReady(); | |||
var response = await DiscordAPI.ChangeAvatar(imageType, bytes, currentEmail, currentPassword); | |||
_users.Update(response.Id, response); | |||
} | |||
//Helpers | |||
private void CheckReady() | |||
{ | |||
@@ -1,6 +1,7 @@ | |||
//#define USE_THREAD | |||
#if !DNXCORE50 | |||
using Discord.API.Models; | |||
using Discord.Opus; | |||
using Newtonsoft.Json; | |||
using Newtonsoft.Json.Linq; | |||
using System; | |||
@@ -13,7 +14,6 @@ using System.Threading; | |||
using System.Threading.Tasks; | |||
using System.Text; | |||
using WebSocketMessage = Discord.API.Models.VoiceWebSocketCommands.WebSocketMessage; | |||
using Opus.Net; | |||
namespace Discord | |||
{ | |||
@@ -1,11 +1,7 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.IO; | |||
using System.Linq; | |||
using System.Runtime.InteropServices; | |||
using System.Threading.Tasks; | |||
namespace Opus.Net | |||
namespace Discord.Opus | |||
{ | |||
internal class API | |||
{ | |||
@@ -42,9 +38,7 @@ namespace Opus.Net | |||
GetInbandFECRequest = 4013 | |||
} | |||
/// <summary> | |||
/// Supported coding modes. | |||
/// </summary> | |||
/// <summary>Supported coding modes.</summary> | |||
public enum Application : int | |||
{ | |||
/// <summary> | |||
@@ -58,45 +52,27 @@ namespace Opus.Net | |||
/// Use this mode for music and mixed (music/voice) content, broadcast, and applications requiring less than 15 ms of coding delay. | |||
/// </summary> | |||
Audio = 2049, | |||
/// <summary> | |||
/// Low-delay mode that disables the speech-optimized mode in exchange for slightly reduced delay. | |||
/// </summary> | |||
/// <summary> Low-delay mode that disables the speech-optimized mode in exchange for slightly reduced delay. </summary> | |||
Restricted_LowLatency = 2051 | |||
} | |||
public enum Error : int | |||
{ | |||
/// <summary> | |||
/// No error. | |||
/// </summary> | |||
/// <summary> No error. </summary> | |||
OK = 0, | |||
/// <summary> | |||
/// One or more invalid/out of range arguments. | |||
/// </summary> | |||
/// <summary> One or more invalid/out of range arguments. </summary> | |||
BadArg = -1, | |||
/// <summary> | |||
/// The mode struct passed is invalid. | |||
/// </summary> | |||
/// <summary> The mode struct passed is invalid. </summary> | |||
BufferToSmall = -2, | |||
/// <summary> | |||
/// An internal error was detected. | |||
/// </summary> | |||
/// <summary> An internal error was detected. </summary> | |||
InternalError = -3, | |||
/// <summary> | |||
/// The compressed data passed is corrupted. | |||
/// </summary> | |||
/// <summary> The compressed data passed is corrupted. </summary> | |||
InvalidPacket = -4, | |||
/// <summary> | |||
/// Invalid/unsupported request number. | |||
/// </summary> | |||
/// <summary> Invalid/unsupported request number. </summary> | |||
Unimplemented = -5, | |||
/// <summary> | |||
/// An encoder or decoder structure is invalid or already freed. | |||
/// </summary> | |||
/// <summary> An encoder or decoder structure is invalid or already freed. </summary> | |||
InvalidState = -6, | |||
/// <summary> | |||
/// Memory allocation has failed. | |||
/// </summary> | |||
/// <summary> Memory allocation has failed. </summary> | |||
AllocFail = -7 | |||
} | |||
} |
@@ -1,6 +1,6 @@ | |||
using System; | |||
namespace Opus.Net | |||
namespace Discord.Opus | |||
{ | |||
/// <summary> Opus codec wrapper. </summary> | |||
public class OpusEncoder : IDisposable |
@@ -29,7 +29,7 @@ namespace Discord | |||
public bool IsVerified { get; internal set; } | |||
/// <summary> Returns the string "<@Id>" to be used as a shortcut when including mentions in text. </summary> | |||
public string Mention { get { return $"<@{Id}>"; } } | |||
public string Mention => $"<@{Id}>"; | |||
public string PrivateChannelId { get; internal set; } | |||
public Channel PrivateChannel => _client.GetChannel(PrivateChannelId); | |||
@@ -1,5 +1,5 @@ | |||
{ | |||
"version": "0.5.0-*", | |||
"version": "0.6.0-beta1", | |||
"description": "An unofficial .Net API wrapper for the Discord client.", | |||
"authors": [ "RogueException" ], | |||
"tags": [ "discord", "discordapp" ], | |||
@@ -9,6 +9,9 @@ | |||
"type": "git", | |||
"url": "git://github.com/RogueException/Discord.Net" | |||
}, | |||
"compilationOptions": { | |||
"allowUnsafe": true | |||
}, | |||
"configurations": { | |||
"FullDebug": { | |||
"compilationOptions": { | |||
@@ -24,18 +27,12 @@ | |||
"frameworks": { | |||
"net45": { | |||
"dependencies": { | |||
"Microsoft.Net.Http": "2.2.22", | |||
"libsodium-net": "0.8.0", | |||
"Baseclass.Contrib.Nuget.Output": "2.1.0", | |||
"Opus.Net": "0.1.0" | |||
"Microsoft.Net.Http": "2.2.22" | |||
} | |||
}, | |||
"dnx451": { | |||
"dependencies": { | |||
"Microsoft.Net.Http": "2.2.22", | |||
"libsodium-net": "0.8.0", | |||
"Baseclass.Contrib.Nuget.Output": "2.1.0", | |||
"Opus.Net": "0.1.0" | |||
"Microsoft.Net.Http": "2.2.22" | |||
} | |||
}, | |||
"dnxcore50": { | |||
@@ -1,76 +0,0 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> | |||
<PropertyGroup> | |||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | |||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | |||
<ProjectGuid>{114C8C10-7354-4EC3-819A-33E83AA57768}</ProjectGuid> | |||
<OutputType>Library</OutputType> | |||
<AppDesignerFolder>Properties</AppDesignerFolder> | |||
<RootNamespace>Discord.Net</RootNamespace> | |||
<AssemblyName>Discord.Net</AssemblyName> | |||
<FileAlignment>512</FileAlignment> | |||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion> | |||
<NuGetPackageImportStamp> | |||
</NuGetPackageImportStamp> | |||
</PropertyGroup> | |||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | |||
<DebugSymbols>true</DebugSymbols> | |||
<DebugType>full</DebugType> | |||
<Optimize>false</Optimize> | |||
<OutputPath>bin\Debug\</OutputPath> | |||
<DefineConstants>DEBUG;TRACE</DefineConstants> | |||
<ErrorReport>prompt</ErrorReport> | |||
<WarningLevel>2</WarningLevel> | |||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors> | |||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | |||
</PropertyGroup> | |||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | |||
<DebugType>pdbonly</DebugType> | |||
<Optimize>true</Optimize> | |||
<OutputPath>bin\Release\</OutputPath> | |||
<DefineConstants>TRACE</DefineConstants> | |||
<ErrorReport>prompt</ErrorReport> | |||
<WarningLevel>4</WarningLevel> | |||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> | |||
<HintPath>..\..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath> | |||
<Private>True</Private> | |||
</Reference> | |||
<Reference Include="Sodium, Version=0.8.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||
<HintPath>..\..\packages\libsodium-net.0.8.0\lib\Net40\Sodium.dll</HintPath> | |||
<Private>True</Private> | |||
</Reference> | |||
<Reference Include="System" /> | |||
<Reference Include="System.Net.Http" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<None Include="packages.config" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Compile Include="..\Opus.Net\API.cs"> | |||
<Link>API.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Opus.Net\OpusEncoder.cs"> | |||
<Link>OpusEncoder.cs</Link> | |||
</Compile> | |||
<Compile Include="Properties\AssemblyInfo.cs" /> | |||
</ItemGroup> | |||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | |||
<Import Project="..\..\packages\Baseclass.Contrib.Nuget.Output.1.0.0\build\net40\Baseclass.Contrib.Nuget.Output.targets" Condition="Exists('..\..\packages\Baseclass.Contrib.Nuget.Output.1.0.0\build\net40\Baseclass.Contrib.Nuget.Output.targets')" /> | |||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> | |||
<PropertyGroup> | |||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> | |||
</PropertyGroup> | |||
<Error Condition="!Exists('..\..\packages\Baseclass.Contrib.Nuget.Output.1.0.0\build\net40\Baseclass.Contrib.Nuget.Output.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Baseclass.Contrib.Nuget.Output.1.0.0\build\net40\Baseclass.Contrib.Nuget.Output.targets'))" /> | |||
</Target> | |||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. | |||
Other similar extension points exist, see Microsoft.Common.targets. | |||
<Target Name="BeforeBuild"> | |||
</Target> | |||
<Target Name="AfterBuild"> | |||
</Target> | |||
--> | |||
</Project> |
@@ -1,17 +0,0 @@ | |||
using System.Reflection; | |||
using System.Runtime.InteropServices; | |||
[assembly: AssemblyTitle("Opus.Net")] | |||
[assembly: AssemblyDescription("Opus .NET Wrapper")] | |||
[assembly: AssemblyConfiguration("")] | |||
[assembly: AssemblyCompany("John Carruthers")] | |||
[assembly: AssemblyProduct("Opus.Net")] | |||
[assembly: AssemblyCopyright("Copyright © 2013")] | |||
[assembly: AssemblyTrademark("")] | |||
[assembly: AssemblyCulture("")] | |||
[assembly: ComVisible(false)] | |||
[assembly: Guid("76ea00e6-ea24-41e1-acb2-639c0313fa80")] | |||
[assembly: AssemblyVersion("0.1.0.0")] | |||
[assembly: AssemblyFileVersion("0.1.0.0")] |
@@ -1,6 +0,0 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<packages> | |||
<package id="Baseclass.Contrib.Nuget.Output" version="1.0.0" targetFramework="net45" /> | |||
<package id="libsodium-net" version="0.8.0" targetFramework="net45" /> | |||
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" /> | |||
</packages> |
@@ -1,20 +0,0 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||
<PropertyGroup> | |||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion> | |||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> | |||
</PropertyGroup> | |||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" /> | |||
<PropertyGroup Label="Globals"> | |||
<ProjectGuid>42ab6a2d-2f2c-4003-80ef-33b5b5b0ed8e</ProjectGuid> | |||
<RootNamespace>Opus.Net</RootNamespace> | |||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath> | |||
<OutputPath Condition="'$(OutputPath)'=='' ">..\artifacts\bin\$(MSBuildProjectName)\</OutputPath> | |||
</PropertyGroup> | |||
<PropertyGroup> | |||
<SchemaVersion>2.0</SchemaVersion> | |||
</PropertyGroup> | |||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" /> | |||
</Project> |
@@ -1,20 +0,0 @@ | |||
{ | |||
"version": "0.1.0-*", | |||
"description": "Opus.Net", | |||
"authors": [ "John Carruthers" ], | |||
"tags": [ "opus" ], | |||
"projectUrl": "https://github.com/JohnACarruthers/Opus.NET", | |||
"licenseUrl": "https://github.com/JohnACarruthers/Opus.NET/blob/master/license.txt", | |||
"compilationOptions": { | |||
"allowUnsafe": true | |||
}, | |||
"dependencies": { | |||
}, | |||
"frameworks": { | |||
"dnx451": { }, | |||
"net45": { } | |||
} | |||
} |