Files
Discord.Net/src/Discord.Net.Commands/CommandsPlugin.cs
2015-10-24 01:39:06 -03:00

139 lines
3.6 KiB
C#

using System;
using System.Collections.Generic;
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 List<Command> _commands;
private Func<Member, int> _getPermissions;
public IEnumerable<Command> Commands => _commands;
public char CommandChar { get; set; }
public bool UseCommandChar { get; set; }
public bool RequireCommandCharInPublic { get; set; }
public bool RequireCommandCharInPrivate { get; set; }
public CommandsPlugin(DiscordClient client, Func<Member, int> getPermissions = null)
{
_client = client;
_getPermissions = getPermissions;
_commands = new List<Command>();
CommandChar = '/';
UseCommandChar = false;
RequireCommandCharInPublic = true;
RequireCommandCharInPrivate = true;
client.MessageCreated += async (s, e) =>
{
//If commands aren't being used, don't bother processing them
if (_commands.Count == 0)
return;
//Ignore messages from ourselves
if (e.Message.UserId == client.CurrentUserId)
return;
//Check for the command character
string msg = e.Message.Text;
if (UseCommandChar)
{
if (msg.Length == 0)
return;
bool isPrivate = e.Message.Channel.IsPrivate;
bool hasCommandChar = msg[0] == CommandChar;
if (hasCommandChar)
msg = msg.Substring(1);
if (!isPrivate && RequireCommandCharInPublic && !hasCommandChar)
return;
if (isPrivate && RequireCommandCharInPrivate && !hasCommandChar)
return;
}
CommandPart[] args;
if (!CommandParser.ParseArgs(msg, out args))
return;
for (int i = 0; i < _commands.Count; i++)
{
Command cmd = _commands[i];
//Check Command Parts
if (args.Length < cmd.Parts.Length)
continue;
bool isValid = true;
for (int j = 0; j < cmd.Parts.Length; j++)
{
if (!string.Equals(args[j].Value, cmd.Parts[j], StringComparison.OrdinalIgnoreCase))
{
isValid = false;
break;
}
}
if (!isValid)
continue;
//Check Arg Count
int argCount = args.Length - cmd.Parts.Length;
if (argCount < cmd.MinArgs || argCount > cmd.MaxArgs)
continue;
//Clean Args
string[] newArgs = new string[argCount];
for (int j = 0; j < newArgs.Length; j++)
newArgs[j] = args[j + cmd.Parts.Length].Value;
//Get ArgText
string argText;
if (argCount == 0)
argText = "";
else
argText = msg.Substring(args[cmd.Parts.Length].Index);
//Check Permissions
int permissions = _getPermissions != null ? _getPermissions(e.Message.Member) : 0;
var eventArgs = new CommandEventArgs(e.Message, cmd, msg, argText, permissions, newArgs);
if (permissions < cmd.MinPerms)
{
RaiseCommandError(eventArgs, new PermissionException());
return;
}
//Run Command
RaiseRanCommand(eventArgs);
try
{
var task = cmd.Handler(eventArgs);
if (task != null)
await task;
}
catch (Exception ex)
{
RaiseCommandError(eventArgs, ex);
}
break;
}
};
}
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(command);
}
internal void AddCommand(Command command)
{
_commands.Add(command);
}
}
}