diff --git a/Discord.Net.sln b/Discord.Net.sln index 931fd3e00..1d7cbfd25 100644 --- a/Discord.Net.sln +++ b/Discord.Net.sln @@ -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 diff --git a/src/Discord.Net.Commands.Net45/Discord.Net.Commands.csproj b/src/Discord.Net.Commands.Net45/Discord.Net.Commands.csproj index f3db55a0d..edfba877c 100644 --- a/src/Discord.Net.Commands.Net45/Discord.Net.Commands.csproj +++ b/src/Discord.Net.Commands.Net45/Discord.Net.Commands.csproj @@ -31,10 +31,6 @@ 4 true - - - - {8d71a857-879a-4a10-859e-5ff824ed6688} @@ -42,6 +38,12 @@ + + + + + Command.cs + CommandBuilder.cs diff --git a/src/Discord.Net.Commands.Net45/Properties/AssemblyInfo.cs b/src/Discord.Net.Commands.Net45/Properties/AssemblyInfo.cs index c48df8f60..7cd983ae9 100644 --- a/src/Discord.Net.Commands.Net45/Properties/AssemblyInfo.cs +++ b/src/Discord.Net.Commands.Net45/Properties/AssemblyInfo.cs @@ -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")] diff --git a/src/Discord.Net.Commands/Command.cs b/src/Discord.Net.Commands/Command.cs new file mode 100644 index 000000000..df7ecb950 --- /dev/null +++ b/src/Discord.Net.Commands/Command.cs @@ -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 Handler; + + internal Command(string text) + { + Text = text; + Parts = text.ToLowerInvariant().Split(' '); + } + } +} diff --git a/src/Discord.Net.Commands/CommandBuilder.cs b/src/Discord.Net.Commands/CommandBuilder.cs index 78a505ea9..e6f5ce245 100644 --- a/src/Discord.Net.Commands/CommandBuilder.cs +++ b/src/Discord.Net.Commands/CommandBuilder.cs @@ -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 func) + { + _command.Handler = func; + return this; + } + public CommandBuilder Do(Action 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 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 handler, bool? useWhitelist = null) + + public CommandGroupBuilder CreateCommandGroup(string cmd, Action 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 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); } } } diff --git a/src/Discord.Net.Commands/CommandParser.cs b/src/Discord.Net.Commands/CommandParser.cs index ef854fea2..4742bbfb1 100644 --- a/src/Discord.Net.Commands/CommandParser.cs +++ b/src/Discord.Net.Commands/CommandParser.cs @@ -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; - } } } diff --git a/src/Discord.Net.Commands/DiscordBotClient.Events.cs b/src/Discord.Net.Commands/DiscordBotClient.Events.cs index edddc4953..38f6f98af 100644 --- a/src/Discord.Net.Commands/DiscordBotClient.Events.cs +++ b/src/Discord.Net.Commands/DiscordBotClient.Events.cs @@ -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 UnknownCommand; + private void RaiseUnknownCommand(CommandEventArgs args) + { + if (UnknownCommand != null) + UnknownCommand(this, args); + } public event EventHandler 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)); } } } diff --git a/src/Discord.Net.Commands/DiscordBotClient.cs b/src/Discord.Net.Commands/DiscordBotClient.cs index 35d0f4c4b..857473acd 100644 --- a/src/Discord.Net.Commands/DiscordBotClient.cs +++ b/src/Discord.Net.Commands/DiscordBotClient.cs @@ -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 Handler; - - public Command(string[] text, int minArgs, int maxArgs, bool useWhitelist, Func handler) - { - Text = text; - MinArgs = minArgs; - MaxArgs = maxArgs; - UseWhitelist = useWhitelist; - Handler = handler; - } - } - - /// - /// A Discord.Net client with extensions for handling common bot operations like text commands. - /// + /// A Discord.Net client with extensions for handling common bot operations like text commands. public partial class DiscordBotClient : DiscordClient { - private List _commands; - private List _whitelist; + internal List _commands; public IEnumerable 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 getPermissions = null) + : base(config) { _commands = new List(); - _whitelist = new List(); 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 config, bool useWhitelist = false) - { - config(new CommandBuilder(this, cmd, useWhitelist)); - } - public void AddCommand(string cmd, int minArgs, int maxArgs, Action handler, bool useWhitelist = false) - { - AddCommand(cmd, minArgs, maxArgs, e => { handler(e); return null; }, useWhitelist); - } - public void AddCommand(string cmd, int minArgs, int maxArgs, Func 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 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); } } } diff --git a/src/Discord.Net.Commands/project.json b/src/Discord.Net.Commands/project.json index 707c42284..a2e150e19 100644 --- a/src/Discord.Net.Commands/project.json +++ b/src/Discord.Net.Commands/project.json @@ -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": { }, diff --git a/src/Discord.Net.Net45/Discord.Net.csproj b/src/Discord.Net.Net45/Discord.Net.csproj index 46ac504d3..3155b01d9 100644 --- a/src/Discord.Net.Net45/Discord.Net.csproj +++ b/src/Discord.Net.Net45/Discord.Net.csproj @@ -23,6 +23,7 @@ prompt 2 false + true pdbonly @@ -32,16 +33,13 @@ prompt 4 true + true ..\..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll True - - ..\..\packages\libsodium-net.0.8.0\lib\Net40\Sodium.dll - True - @@ -124,6 +122,12 @@ Message.cs + + Opus\API.cs + + + Opus\OpusEncoder.cs + PackedPermissions.cs @@ -141,20 +145,8 @@ - - - {114c8c10-7354-4ec3-819a-33e83aa57768} - Opus.Net - - + - - - - 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}. - - - - \ No newline at end of file diff --git a/src/Opus.Net.Net45/Properties/AssemblyInfo.cs b/src/Opus.Net.Net45/Properties/AssemblyInfo.cs deleted file mode 100644 index 1e97e3ca9..000000000 --- a/src/Opus.Net.Net45/Properties/AssemblyInfo.cs +++ /dev/null @@ -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")] diff --git a/src/Opus.Net.Net45/packages.config b/src/Opus.Net.Net45/packages.config deleted file mode 100644 index 46251e3d3..000000000 --- a/src/Opus.Net.Net45/packages.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/Opus.Net/Opus.Net.xproj b/src/Opus.Net/Opus.Net.xproj deleted file mode 100644 index 8e1675b53..000000000 --- a/src/Opus.Net/Opus.Net.xproj +++ /dev/null @@ -1,20 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - 42ab6a2d-2f2c-4003-80ef-33b5b5b0ed8e - Opus.Net - ..\artifacts\obj\$(MSBuildProjectName) - ..\artifacts\bin\$(MSBuildProjectName)\ - - - - 2.0 - - - diff --git a/src/Opus.Net/project.json b/src/Opus.Net/project.json deleted file mode 100644 index 6563f889f..000000000 --- a/src/Opus.Net/project.json +++ /dev/null @@ -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": { } - } -}