Added basic service model, even more commands cleanup!
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
<ProjectGuid>{1B5603B4-6F8F-4289-B945-7BAAE523D740}</ProjectGuid>
|
<ProjectGuid>{1B5603B4-6F8F-4289-B945-7BAAE523D740}</ProjectGuid>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>Discord</RootNamespace>
|
<RootNamespace>Discord.Commands</RootNamespace>
|
||||||
<AssemblyName>Discord.Net.Commands</AssemblyName>
|
<AssemblyName>Discord.Net.Commands</AssemblyName>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||||
@@ -43,17 +43,23 @@
|
|||||||
<Compile Include="..\Discord.Net.Commands\CommandBuilder.cs">
|
<Compile Include="..\Discord.Net.Commands\CommandBuilder.cs">
|
||||||
<Link>CommandBuilder.cs</Link>
|
<Link>CommandBuilder.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\Discord.Net.Commands\CommandExtensions.cs">
|
||||||
|
<Link>CommandExtensions.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net.Commands\CommandMap.cs">
|
<Compile Include="..\Discord.Net.Commands\CommandMap.cs">
|
||||||
<Link>CommandMap.cs</Link>
|
<Link>CommandMap.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net.Commands\CommandParser.cs">
|
<Compile Include="..\Discord.Net.Commands\CommandParser.cs">
|
||||||
<Link>CommandParser.cs</Link>
|
<Link>CommandParser.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net.Commands\CommandsPlugin.cs">
|
<Compile Include="..\Discord.Net.Commands\CommandService.cs">
|
||||||
<Link>CommandsPlugin.cs</Link>
|
<Link>CommandService.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net.Commands\CommandsPlugin.Events.cs">
|
<Compile Include="..\Discord.Net.Commands\CommandService.Events.cs">
|
||||||
<Link>CommandsPlugin.Events.cs</Link>
|
<Link>CommandService.Events.cs</Link>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="..\Discord.Net.Commands\CommandServiceConfig.cs">
|
||||||
|
<Link>CommandServiceConfig.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -7,15 +7,15 @@ namespace Discord.Commands
|
|||||||
{
|
{
|
||||||
public sealed class CommandBuilder
|
public sealed class CommandBuilder
|
||||||
{
|
{
|
||||||
private readonly CommandsPlugin _plugin;
|
private readonly CommandService _service;
|
||||||
private readonly Command _command;
|
private readonly Command _command;
|
||||||
private List<CommandParameter> _params;
|
private List<CommandParameter> _params;
|
||||||
private bool _allowRequired, _isClosed;
|
private bool _allowRequired, _isClosed;
|
||||||
private string _prefix;
|
private string _prefix;
|
||||||
|
|
||||||
public CommandBuilder(CommandsPlugin plugin, Command command, string prefix)
|
public CommandBuilder(CommandService service, Command command, string prefix)
|
||||||
{
|
{
|
||||||
_plugin = plugin;
|
_service = service;
|
||||||
_command = command;
|
_command = command;
|
||||||
_params = new List<CommandParameter>();
|
_params = new List<CommandParameter>();
|
||||||
_prefix = prefix;
|
_prefix = prefix;
|
||||||
@@ -75,8 +75,8 @@ namespace Discord.Commands
|
|||||||
{
|
{
|
||||||
_command.SetParameters(_params.ToArray());
|
_command.SetParameters(_params.ToArray());
|
||||||
foreach (var alias in _command.Aliases)
|
foreach (var alias in _command.Aliases)
|
||||||
_plugin.Map.AddCommand(alias, _command);
|
_service.Map.AddCommand(alias, _command);
|
||||||
_plugin.AddCommand(_command);
|
_service.AddCommand(_command);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static string AppendPrefix(string prefix, string cmd)
|
internal static string AppendPrefix(string prefix, string cmd)
|
||||||
@@ -99,13 +99,13 @@ namespace Discord.Commands
|
|||||||
}
|
}
|
||||||
public sealed class CommandGroupBuilder
|
public sealed class CommandGroupBuilder
|
||||||
{
|
{
|
||||||
internal readonly CommandsPlugin _plugin;
|
internal readonly CommandService _service;
|
||||||
private readonly string _prefix;
|
private readonly string _prefix;
|
||||||
private int _defaultMinPermissions;
|
private int _defaultMinPermissions;
|
||||||
|
|
||||||
internal CommandGroupBuilder(CommandsPlugin plugin, string prefix, int defaultMinPermissions)
|
internal CommandGroupBuilder(CommandService service, string prefix, int defaultMinPermissions)
|
||||||
{
|
{
|
||||||
_plugin = plugin;
|
_service = service;
|
||||||
_prefix = prefix;
|
_prefix = prefix;
|
||||||
_defaultMinPermissions = defaultMinPermissions;
|
_defaultMinPermissions = defaultMinPermissions;
|
||||||
}
|
}
|
||||||
@@ -117,7 +117,7 @@ namespace Discord.Commands
|
|||||||
|
|
||||||
public CommandGroupBuilder CreateCommandGroup(string cmd, Action<CommandGroupBuilder> config = null)
|
public CommandGroupBuilder CreateCommandGroup(string cmd, Action<CommandGroupBuilder> config = null)
|
||||||
{
|
{
|
||||||
config(new CommandGroupBuilder(_plugin, _prefix + ' ' + cmd, _defaultMinPermissions));
|
config(new CommandGroupBuilder(_service, _prefix + ' ' + cmd, _defaultMinPermissions));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
public CommandBuilder CreateCommand()
|
public CommandBuilder CreateCommand()
|
||||||
@@ -126,7 +126,7 @@ namespace Discord.Commands
|
|||||||
{
|
{
|
||||||
var command = new Command(CommandBuilder.AppendPrefix(_prefix, cmd));
|
var command = new Command(CommandBuilder.AppendPrefix(_prefix, cmd));
|
||||||
command.MinPermissions = _defaultMinPermissions;
|
command.MinPermissions = _defaultMinPermissions;
|
||||||
return new CommandBuilder(_plugin, command, _prefix);
|
return new CommandBuilder(_service, command, _prefix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
8
src/Discord.Net.Commands/CommandExtensions.cs
Normal file
8
src/Discord.Net.Commands/CommandExtensions.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Discord.Commands
|
||||||
|
{
|
||||||
|
public static class CommandExtensions
|
||||||
|
{
|
||||||
|
public static CommandService Commands(this DiscordClient client)
|
||||||
|
=> client.GetService<CommandService>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,7 +36,7 @@ namespace Discord.Commands
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial class CommandsPlugin
|
public partial class CommandService
|
||||||
{
|
{
|
||||||
public event EventHandler<CommandEventArgs> RanCommand;
|
public event EventHandler<CommandEventArgs> RanCommand;
|
||||||
private void RaiseRanCommand(CommandEventArgs args)
|
private void RaiseRanCommand(CommandEventArgs args)
|
||||||
184
src/Discord.Net.Commands/CommandService.cs
Normal file
184
src/Discord.Net.Commands/CommandService.cs
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Discord.Commands
|
||||||
|
{
|
||||||
|
/// <summary> A Discord.Net client with extensions for handling common bot operations like text commands. </summary>
|
||||||
|
public partial class CommandService : IService
|
||||||
|
{
|
||||||
|
private DiscordClient _client;
|
||||||
|
|
||||||
|
CommandServiceConfig Config { get; }
|
||||||
|
public IEnumerable<Command> Commands => _commands;
|
||||||
|
private readonly List<Command> _commands;
|
||||||
|
|
||||||
|
internal CommandMap Map => _map;
|
||||||
|
private readonly CommandMap _map;
|
||||||
|
|
||||||
|
public CommandService(CommandServiceConfig config)
|
||||||
|
{
|
||||||
|
Config = config;
|
||||||
|
_commands = new List<Command>();
|
||||||
|
_map = new CommandMap(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IService.Install(DiscordClient client)
|
||||||
|
{
|
||||||
|
_client = client;
|
||||||
|
Config.Lock();
|
||||||
|
|
||||||
|
if (Config.HelpMode != HelpMode.Disable)
|
||||||
|
{
|
||||||
|
CreateCommand("help")
|
||||||
|
.Parameter("command", ParameterType.Multiple)
|
||||||
|
.Hide()
|
||||||
|
.Info("Returns information about commands.")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
Channel channel = Config.HelpMode == HelpMode.Public ? e.Channel : await client.CreatePMChannel(e.User);
|
||||||
|
if (e.Args.Length > 0) //Show command help
|
||||||
|
{
|
||||||
|
var cmd = _map.GetCommand(string.Join(" ", e.Args));
|
||||||
|
if (cmd != null)
|
||||||
|
await ShowHelp(cmd, e.User, channel);
|
||||||
|
else
|
||||||
|
await client.SendMessage(channel, "Unable to display help: unknown command.");
|
||||||
|
}
|
||||||
|
else //Show general help
|
||||||
|
await ShowHelp(e.User, channel);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
client.MessageReceived += async (s, e) =>
|
||||||
|
{
|
||||||
|
if (_commands.Count == 0) return;
|
||||||
|
if (e.Message.IsAuthor) return;
|
||||||
|
|
||||||
|
string msg = e.Message.Text;
|
||||||
|
if (msg.Length == 0) return;
|
||||||
|
|
||||||
|
//Check for command char if one is provided
|
||||||
|
var chars = Config.CommandChars;
|
||||||
|
if (chars.Length > 0)
|
||||||
|
{
|
||||||
|
if (!chars.Contains(msg[0]))
|
||||||
|
return;
|
||||||
|
msg = msg.Substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Parse command
|
||||||
|
Command command;
|
||||||
|
int argPos;
|
||||||
|
CommandParser.ParseCommand(msg, _map, out command, out argPos);
|
||||||
|
if (command == null)
|
||||||
|
{
|
||||||
|
CommandEventArgs errorArgs = new CommandEventArgs(e.Message, null, null, null);
|
||||||
|
RaiseCommandError(CommandErrorType.UnknownCommand, errorArgs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int userPermissions = Config.PermissionResolver?.Invoke(e.Message.User) ?? 0;
|
||||||
|
|
||||||
|
//Parse arguments
|
||||||
|
string[] args;
|
||||||
|
var error = CommandParser.ParseArgs(msg, argPos, command, out args);
|
||||||
|
if (error != null)
|
||||||
|
{
|
||||||
|
var errorArgs = new CommandEventArgs(e.Message, command, userPermissions, null);
|
||||||
|
RaiseCommandError(error.Value, errorArgs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var eventArgs = new CommandEventArgs(e.Message, command, userPermissions, args);
|
||||||
|
|
||||||
|
// Check permissions
|
||||||
|
if (userPermissions < command.MinPermissions)
|
||||||
|
{
|
||||||
|
RaiseCommandError(CommandErrorType.BadPermissions, eventArgs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the command
|
||||||
|
try
|
||||||
|
{
|
||||||
|
RaiseRanCommand(eventArgs);
|
||||||
|
await command.Run(eventArgs).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
RaiseCommandError(CommandErrorType.Exception, eventArgs, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task ShowHelp(User user, Channel channel)
|
||||||
|
{
|
||||||
|
int permissions = Config.PermissionResolver(user);
|
||||||
|
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
output.AppendLine("These are the commands you can use:");
|
||||||
|
output.Append(string.Join(", ", _commands
|
||||||
|
.Where(x => permissions >= x.MinPermissions && !x.IsHidden)
|
||||||
|
.Select(x => '`' + x.Text + '`')));
|
||||||
|
|
||||||
|
var chars = Config.CommandChars;
|
||||||
|
if (chars.Length > 0)
|
||||||
|
{
|
||||||
|
if (chars.Length == 1)
|
||||||
|
output.AppendLine($"\nYou can use `{chars[0]}` to call a command.");
|
||||||
|
else
|
||||||
|
output.AppendLine($"\nYou can use `{string.Join(" ", chars.Take(chars.Length - 1))}` or `{chars.Last()}` to call a command.");
|
||||||
|
}
|
||||||
|
|
||||||
|
output.AppendLine("`help <command>` can tell you more about how to use a command.");
|
||||||
|
|
||||||
|
return _client.SendMessage(channel, output.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task ShowHelp(Command command, User user, Channel channel)
|
||||||
|
{
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
|
||||||
|
output.Append($"`{command.Text}`");
|
||||||
|
|
||||||
|
if (command.MinArgs != null && command.MaxArgs != null)
|
||||||
|
{
|
||||||
|
if (command.MinArgs == command.MaxArgs)
|
||||||
|
{
|
||||||
|
if (command.MaxArgs != 0)
|
||||||
|
output.Append($" {command.MinArgs.ToString()} Args");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
output.Append($" {command.MinArgs.ToString()} - {command.MaxArgs.ToString()} Args");
|
||||||
|
}
|
||||||
|
else if (command.MinArgs != null && command.MaxArgs == null)
|
||||||
|
output.Append($" ≥{command.MinArgs.ToString()} Args");
|
||||||
|
else if (command.MinArgs == null && command.MaxArgs != null)
|
||||||
|
output.Append($" ≤{command.MaxArgs.ToString()} Args");
|
||||||
|
|
||||||
|
output.Append($": {command.Description ?? "No description set for this command."}");
|
||||||
|
|
||||||
|
return _client.SendMessage(channel, output.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CreateCommandGroup(string cmd, Action<CommandGroupBuilder> config = null)
|
||||||
|
=> config(new CommandGroupBuilder(this, cmd, 0));
|
||||||
|
public CommandBuilder CreateCommand(string cmd)
|
||||||
|
{
|
||||||
|
var command = new Command(cmd);
|
||||||
|
_commands.Add(command);
|
||||||
|
return new CommandBuilder(this, command, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void AddCommand(Command command)
|
||||||
|
{
|
||||||
|
_commands.Add(command);
|
||||||
|
_map.AddCommand(command.Text, command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
49
src/Discord.Net.Commands/CommandServiceConfig.cs
Normal file
49
src/Discord.Net.Commands/CommandServiceConfig.cs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Discord.Commands
|
||||||
|
{
|
||||||
|
public enum HelpMode
|
||||||
|
{
|
||||||
|
/// <summary> Disable the automatic help command. </summary>
|
||||||
|
Disable,
|
||||||
|
/// <summary> Use the automatic help command and respond in the channel the command is used. </summary>
|
||||||
|
Public,
|
||||||
|
/// <summary> Use the automatic help command and respond in a private message. </summary>
|
||||||
|
Private
|
||||||
|
}
|
||||||
|
public class CommandServiceConfig
|
||||||
|
{
|
||||||
|
public Func<User, int> PermissionResolver { get { return _permissionsResolver; } set { SetValue(ref _permissionsResolver, value); } }
|
||||||
|
private Func<User, int> _permissionsResolver;
|
||||||
|
|
||||||
|
public char? CommandChar
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _commandChars.Length > 0 ? _commandChars[0] : (char?)null;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != null)
|
||||||
|
CommandChars = new char[] { value.Value };
|
||||||
|
else
|
||||||
|
CommandChars = new char[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public char[] CommandChars { get { return _commandChars; } set { SetValue(ref _commandChars, value); } }
|
||||||
|
private char[] _commandChars = new char[] { '!' };
|
||||||
|
|
||||||
|
public HelpMode HelpMode { get { return _helpMode; } set { SetValue(ref _helpMode, value); } }
|
||||||
|
private HelpMode _helpMode = HelpMode.Disable;
|
||||||
|
|
||||||
|
//Lock
|
||||||
|
protected bool _isLocked;
|
||||||
|
internal void Lock() { _isLocked = true; }
|
||||||
|
protected void SetValue<T>(ref T storage, T value)
|
||||||
|
{
|
||||||
|
if (_isLocked)
|
||||||
|
throw new InvalidOperationException("Unable to modify a discord client's configuration after it has been created.");
|
||||||
|
storage = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,211 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Discord.Commands
|
|
||||||
{
|
|
||||||
/// <summary> A Discord.Net client with extensions for handling common bot operations like text commands. </summary>
|
|
||||||
public partial class CommandsPlugin
|
|
||||||
{
|
|
||||||
private readonly DiscordClient _client;
|
|
||||||
private readonly Func<User, int> _getPermissions;
|
|
||||||
|
|
||||||
public IEnumerable<Command> Commands => _commands;
|
|
||||||
private readonly List<Command> _commands;
|
|
||||||
|
|
||||||
internal CommandMap Map => _map;
|
|
||||||
private readonly CommandMap _map;
|
|
||||||
|
|
||||||
public char? ComamndChar
|
|
||||||
{
|
|
||||||
get { return _commandChars.Length > 0 ? _commandChars[0] : (char?)null; }
|
|
||||||
set { _commandChars = value != null ? new char[] { value.Value } : new char[0]; }
|
|
||||||
}
|
|
||||||
public IEnumerable<char> CommandChars { get { return _commandChars; } set { _commandChars = value.ToArray(); } }
|
|
||||||
private char[] _commandChars;
|
|
||||||
|
|
||||||
public bool RequireCommandCharInPublic { get; set; }
|
|
||||||
public bool RequireCommandCharInPrivate { get; set; }
|
|
||||||
public bool HelpInPublic { get; set; }
|
|
||||||
|
|
||||||
public CommandsPlugin(DiscordClient client, Func<User, int> getPermissions = null, bool builtInHelp = false)
|
|
||||||
{
|
|
||||||
_client = client;
|
|
||||||
_getPermissions = getPermissions;
|
|
||||||
|
|
||||||
_commands = new List<Command>();
|
|
||||||
_map = new CommandMap(null);
|
|
||||||
|
|
||||||
_commandChars = new char[] { '!' };
|
|
||||||
RequireCommandCharInPublic = true;
|
|
||||||
RequireCommandCharInPrivate = true;
|
|
||||||
HelpInPublic = true;
|
|
||||||
|
|
||||||
if (builtInHelp)
|
|
||||||
{
|
|
||||||
CreateCommand("help")
|
|
||||||
.Parameter("command", ParameterType.Optional)
|
|
||||||
.Hide()
|
|
||||||
.Info("Returns information about commands.")
|
|
||||||
.Do(async e =>
|
|
||||||
{
|
|
||||||
if (e.Command.Text != "help")
|
|
||||||
await Reply(e, CommandDetails(e.Command));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (e.Args == null)
|
|
||||||
{
|
|
||||||
int permissions = getPermissions(e.User);
|
|
||||||
|
|
||||||
StringBuilder output = new StringBuilder();
|
|
||||||
output.AppendLine("These are the commands you can use:");
|
|
||||||
output.Append("`");
|
|
||||||
output.Append(string.Join(", ", _commands.Select(x => permissions >= x.MinPermissions && !x.IsHidden)));
|
|
||||||
output.Append("`");
|
|
||||||
|
|
||||||
if (_commandChars.Length > 0)
|
|
||||||
{
|
|
||||||
if (_commandChars.Length == 1)
|
|
||||||
output.AppendLine($"\nYou can use `{_commandChars[0]}` to call a command.");
|
|
||||||
else
|
|
||||||
output.AppendLine($"\nYou can use `{string.Join(" ", CommandChars.Take(_commandChars.Length - 1))}` and `{_commandChars.Last()}` to call a command.");
|
|
||||||
}
|
|
||||||
|
|
||||||
output.AppendLine("`help <command>` can tell you more about how to use a command.");
|
|
||||||
|
|
||||||
await Reply(e, output.ToString());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var cmd = _map.GetCommand(e.Args[0]);
|
|
||||||
if (cmd != null)
|
|
||||||
await Reply(e, CommandDetails(cmd));
|
|
||||||
else
|
|
||||||
await Reply(e, $"`{e.Args[0]}` is not a valid command.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
client.MessageReceived += async (s, e) =>
|
|
||||||
{
|
|
||||||
if (_commands.Count == 0) return;
|
|
||||||
if (e.Message.IsAuthor) return;
|
|
||||||
|
|
||||||
string msg = e.Message.Text;
|
|
||||||
if (msg.Length == 0) return;
|
|
||||||
|
|
||||||
//Check for command char if one is provided
|
|
||||||
if (_commandChars.Length > 0)
|
|
||||||
{
|
|
||||||
bool isPrivate = e.Message.Channel.IsPrivate;
|
|
||||||
bool hasCommandChar = _commandChars.Contains(msg[0]);
|
|
||||||
if (hasCommandChar)
|
|
||||||
msg = msg.Substring(1);
|
|
||||||
|
|
||||||
if (isPrivate && RequireCommandCharInPrivate && !hasCommandChar)
|
|
||||||
return; // If private, and command char is required, and it doesn't have it, ignore it.
|
|
||||||
if (!isPrivate && RequireCommandCharInPublic && !hasCommandChar)
|
|
||||||
return; // Same, but public.
|
|
||||||
}
|
|
||||||
|
|
||||||
//Parse command
|
|
||||||
Command command;
|
|
||||||
int argPos;
|
|
||||||
CommandParser.ParseCommand(msg, _map, out command, out argPos);
|
|
||||||
if (command == null)
|
|
||||||
{
|
|
||||||
CommandEventArgs errorArgs = new CommandEventArgs(e.Message, null, null, null);
|
|
||||||
RaiseCommandError(CommandErrorType.UnknownCommand, errorArgs);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int userPermissions = _getPermissions != null ? _getPermissions(e.Message.User) : 0;
|
|
||||||
|
|
||||||
//Parse arguments
|
|
||||||
string[] args;
|
|
||||||
var error = CommandParser.ParseArgs(msg, argPos, command, out args);
|
|
||||||
if (error != null)
|
|
||||||
{
|
|
||||||
var errorArgs = new CommandEventArgs(e.Message, command, userPermissions, null);
|
|
||||||
RaiseCommandError(error.Value, errorArgs);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var eventArgs = new CommandEventArgs(e.Message, command, userPermissions, args);
|
|
||||||
|
|
||||||
// Check permissions
|
|
||||||
if (userPermissions < command.MinPermissions)
|
|
||||||
{
|
|
||||||
RaiseCommandError(CommandErrorType.BadPermissions, eventArgs);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run the command
|
|
||||||
try
|
|
||||||
{
|
|
||||||
RaiseRanCommand(eventArgs);
|
|
||||||
await command.Run(eventArgs).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
RaiseCommandError(CommandErrorType.Exception, eventArgs, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private string CommandDetails(Command command)
|
|
||||||
{
|
|
||||||
StringBuilder output = new StringBuilder();
|
|
||||||
|
|
||||||
output.Append($"`{command.Text}`");
|
|
||||||
|
|
||||||
if (command.MinArgs != null && command.MaxArgs != null)
|
|
||||||
{
|
|
||||||
if (command.MinArgs == command.MaxArgs)
|
|
||||||
{
|
|
||||||
if (command.MaxArgs != 0)
|
|
||||||
output.Append($" {command.MinArgs.ToString()} Args");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
output.Append($" {command.MinArgs.ToString()} - {command.MaxArgs.ToString()} Args");
|
|
||||||
}
|
|
||||||
else if (command.MinArgs != null && command.MaxArgs == null)
|
|
||||||
output.Append($" ≥{command.MinArgs.ToString()} Args");
|
|
||||||
else if (command.MinArgs == null && command.MaxArgs != null)
|
|
||||||
output.Append($" ≤{command.MaxArgs.ToString()} Args");
|
|
||||||
|
|
||||||
output.Append($": {command.Description ?? "No description set for this command."}");
|
|
||||||
|
|
||||||
return output.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal async Task Reply(CommandEventArgs e, string message)
|
|
||||||
{
|
|
||||||
if (HelpInPublic)
|
|
||||||
await _client.SendMessage(e.Channel, message);
|
|
||||||
else
|
|
||||||
await _client.SendPrivateMessage(e.User, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CreateCommandGroup(string cmd, Action<CommandGroupBuilder> config = null)
|
|
||||||
=> config(new CommandGroupBuilder(this, cmd, 0));
|
|
||||||
public CommandBuilder CreateCommand(string cmd)
|
|
||||||
{
|
|
||||||
var command = new Command(cmd);
|
|
||||||
_commands.Add(command);
|
|
||||||
return new CommandBuilder(null, command, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void AddCommand(Command command)
|
|
||||||
{
|
|
||||||
_commands.Add(command);
|
|
||||||
_map.AddCommand(command.Text, command);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -232,6 +232,9 @@
|
|||||||
<Compile Include="..\Discord.Net\HttpException.cs">
|
<Compile Include="..\Discord.Net\HttpException.cs">
|
||||||
<Link>HttpException.cs</Link>
|
<Link>HttpException.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\Discord.Net\IService.cs">
|
||||||
|
<Link>IService.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net\Models\Channel.cs">
|
<Compile Include="..\Discord.Net\Models\Channel.cs">
|
||||||
<Link>Models\Channel.cs</Link>
|
<Link>Models\Channel.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ namespace Discord
|
|||||||
private readonly JsonSerializer _serializer;
|
private readonly JsonSerializer _serializer;
|
||||||
private readonly ConcurrentQueue<Message> _pendingMessages;
|
private readonly ConcurrentQueue<Message> _pendingMessages;
|
||||||
private readonly ConcurrentDictionary<string, DiscordWSClient> _voiceClients;
|
private readonly ConcurrentDictionary<string, DiscordWSClient> _voiceClients;
|
||||||
|
private readonly Dictionary<Type, IService> _services;
|
||||||
private bool _sentInitialLog;
|
private bool _sentInitialLog;
|
||||||
private uint _nextVoiceClientId;
|
private uint _nextVoiceClientId;
|
||||||
private UserStatus _status;
|
private UserStatus _status;
|
||||||
@@ -46,6 +47,7 @@ namespace Discord
|
|||||||
_roles = new Roles(this, cacheLock);
|
_roles = new Roles(this, cacheLock);
|
||||||
_servers = new Servers(this, cacheLock);
|
_servers = new Servers(this, cacheLock);
|
||||||
_globalUsers = new GlobalUsers(this, cacheLock);
|
_globalUsers = new GlobalUsers(this, cacheLock);
|
||||||
|
_services = new Dictionary<Type, IService>();
|
||||||
|
|
||||||
_status = UserStatus.Online;
|
_status = UserStatus.Online;
|
||||||
|
|
||||||
@@ -168,7 +170,6 @@ namespace Discord
|
|||||||
_serializer.MissingMemberHandling = MissingMemberHandling.Error;
|
_serializer.MissingMemberHandling = MissingMemberHandling.Error;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
internal override VoiceWebSocket CreateVoiceSocket()
|
internal override VoiceWebSocket CreateVoiceSocket()
|
||||||
{
|
{
|
||||||
var socket = base.CreateVoiceSocket();
|
var socket = base.CreateVoiceSocket();
|
||||||
@@ -216,7 +217,6 @@ namespace Discord
|
|||||||
await Connect(token).ConfigureAwait(false);
|
await Connect(token).ConfigureAwait(false);
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Connects to the Discord server with the provided token. </summary>
|
/// <summary> Connects to the Discord server with the provided token. </summary>
|
||||||
public async Task Connect(string token)
|
public async Task Connect(string token)
|
||||||
{
|
{
|
||||||
@@ -273,6 +273,22 @@ namespace Discord
|
|||||||
_currentUser = null;
|
_currentUser = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddService<T>(T obj)
|
||||||
|
where T : class, IService
|
||||||
|
{
|
||||||
|
_services.Add(typeof(T), obj);
|
||||||
|
obj.Install(this);
|
||||||
|
}
|
||||||
|
public T GetService<T>()
|
||||||
|
where T : class, IService
|
||||||
|
{
|
||||||
|
IService service;
|
||||||
|
if (_services.TryGetValue(typeof(T), out service))
|
||||||
|
return service as T;
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
protected override IEnumerable<Task> GetTasks()
|
protected override IEnumerable<Task> GetTasks()
|
||||||
{
|
{
|
||||||
if (Config.UseMessageQueue)
|
if (Config.UseMessageQueue)
|
||||||
|
|||||||
7
src/Discord.Net/IService.cs
Normal file
7
src/Discord.Net/IService.cs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
namespace Discord
|
||||||
|
{
|
||||||
|
public interface IService
|
||||||
|
{
|
||||||
|
void Install(DiscordClient client);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user