Help, Conversations, Permissions refactored

This commit is contained in:
Master Kwoth
2016-04-14 23:39:10 +02:00
parent 3e6b2df73d
commit eb90bb5bd1
12 changed files with 788 additions and 800 deletions

View File

@ -0,0 +1,62 @@
using Discord.Commands;
using NadekoBot.Modules;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace NadekoBot.Commands.Conversations.Commands
{
internal class CopyCommand : DiscordCommand
{
private readonly HashSet<ulong> CopiedUsers = new HashSet<ulong>();
public CopyCommand(DiscordModule module) : base(module)
{
NadekoBot.Client.MessageReceived += Client_MessageReceived;
}
private async void Client_MessageReceived(object sender, Discord.MessageEventArgs e)
{
if (e.User.Id == NadekoBot.Client.CurrentUser.Id) return;
try
{
if (string.IsNullOrWhiteSpace(e.Message.Text))
return;
if (CopiedUsers.Contains(e.User.Id))
{
await e.Channel.SendMessage(e.Message.Text);
}
}
catch { }
}
public Func<CommandEventArgs, Task> DoFunc() => async e =>
{
if (CopiedUsers.Contains(e.User.Id)) return;
CopiedUsers.Add(e.User.Id);
await e.Channel.SendMessage(" I'll start copying you now.");
};
internal override void Init(CommandGroupBuilder cgb)
{
cgb.CreateCommand("copyme")
.Alias("cm")
.Description("Nadeko starts copying everything you say. Disable with cs")
.Do(DoFunc());
cgb.CreateCommand("cs")
.Alias("copystop")
.Description("Nadeko stops copying you")
.Do(StopCopy());
}
private Func<CommandEventArgs, Task> StopCopy() => async e =>
{
if (!CopiedUsers.Contains(e.User.Id)) return;
CopiedUsers.Remove(e.User.Id);
await e.Channel.SendMessage(" I wont copy anymore.");
};
}
}

View File

@ -0,0 +1,138 @@
using Discord.Commands;
using NadekoBot.Extensions;
using NadekoBot.Modules;
using System;
using System.Threading.Tasks;
namespace NadekoBot.Commands.Conversations.Commands
{
internal class RequestsCommand : DiscordCommand
{
public void SaveRequest(CommandEventArgs e, string text)
{
Classes.DbHandler.Instance.InsertData(new Classes._DataModels.Request
{
RequestText = text,
UserName = e.User.Name,
UserId = (long)e.User.Id,
ServerId = (long)e.Server.Id,
ServerName = e.Server.Name,
DateAdded = DateTime.Now
});
}
// todo what if it's too long?
public string GetRequests()
{
var task = Classes.DbHandler.Instance.GetAllRows<Classes._DataModels.Request>();
var str = "Here are all current requests for NadekoBot:\n\n";
foreach (var reqObj in task)
{
str += $"{reqObj.Id}. by **{reqObj.UserName}** from **{reqObj.ServerName}** at {reqObj.DateAdded.ToLocalTime()}\n" +
$"**{reqObj.RequestText}**\n----------\n";
}
return str + "\n__Type [@NadekoBot clr] to clear all of my messages.__";
}
public bool DeleteRequest(int requestNumber) =>
Classes.DbHandler.Instance.Delete<Classes._DataModels.Request>(requestNumber) != null;
/// <summary>
/// Delete a request with a number and returns that request object.
/// </summary>
/// <returns>RequestObject of the request. Null if none</returns>
public Classes._DataModels.Request ResolveRequest(int requestNumber) =>
Classes.DbHandler.Instance.Delete<Classes._DataModels.Request>(requestNumber);
internal override void Init(CommandGroupBuilder cgb)
{
cgb.CreateCommand("req")
.Alias("request")
.Description("Requests a feature for nadeko.\n**Usage**: @NadekoBot req new_feature")
.Parameter("all", ParameterType.Unparsed)
.Do(async e =>
{
var str = e.Args[0];
try
{
SaveRequest(e, str);
}
catch
{
await e.Channel.SendMessage("Something went wrong.");
return;
}
await e.Channel.SendMessage("Thank you for your request.");
});
cgb.CreateCommand("lr")
.Description("PMs the user all current nadeko requests.")
.Do(async e =>
{
var str = await Task.Run(() => GetRequests());
if (str.Trim().Length > 110)
await e.User.Send(str);
else
await e.User.Send("No requests atm.");
});
cgb.CreateCommand("dr")
.Description("Deletes a request. Only owner is able to do this.")
.Parameter("reqNumber", ParameterType.Required)
.Do(async e =>
{
if (NadekoBot.IsOwner(e.User.Id))
{
try
{
if (DeleteRequest(int.Parse(e.Args[0])))
{
await e.Channel.SendMessage(e.User.Mention + " Request deleted.");
}
else
{
await e.Channel.SendMessage("No request on that number.");
}
}
catch
{
await e.Channel.SendMessage("Error deleting request, probably NaN error.");
}
}
else await e.Channel.SendMessage("You don't have permission to do that.");
});
cgb.CreateCommand("rr")
.Description("Resolves a request. Only owner is able to do this.")
.Parameter("reqNumber", ParameterType.Required)
.Do(async e =>
{
if (NadekoBot.IsOwner(e.User.Id))
{
try
{
var sc = ResolveRequest(int.Parse(e.Args[0]));
if (sc != null)
{
await e.Channel.SendMessage(e.User.Mention + " Request resolved, notice sent.");
await NadekoBot.Client.GetServer((ulong)sc.ServerId).GetUser((ulong)sc.UserId).Send("**This request of yours has been resolved:**\n" + sc.RequestText);
}
else
{
await e.Channel.SendMessage("No request on that number.");
}
}
catch
{
await e.Channel.SendMessage("Error resolving request, probably NaN error.");
}
}
else await e.Channel.SendMessage("You don't have permission to do that.");
});
}
public RequestsCommand(DiscordModule module) : base(module) { }
}
}

View File

@ -2,7 +2,7 @@ using Discord;
using Discord.Commands;
using Discord.Modules;
using NadekoBot.Classes;
using NadekoBot.Commands;
using NadekoBot.Commands.Conversations.Commands;
using NadekoBot.Extensions;
using NadekoBot.Properties;
using System;
@ -13,7 +13,7 @@ using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace NadekoBot.Modules
namespace NadekoBot.Modules.Conversations
{
internal class Conversations : DiscordModule
{

View File

@ -0,0 +1,145 @@
using Discord.Commands;
using NadekoBot.Extensions;
using NadekoBot.Modules;
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace NadekoBot.Commands.Help.Commands
{
internal class HelpCommand : DiscordCommand
{
public Func<CommandEventArgs, Task> DoFunc() => async e =>
{
#region OldHelp
/*
string helpstr = "**COMMANDS DO NOT WORK IN PERSONAL MESSAGES**\nOfficial repo: **github.com/Kwoth/NadekoBot/**";
string lastCategory = "";
foreach (var com in client.GetService<CommandService>().AllCommands)
{
if (com.Category != lastCategory)
{
helpstr += "\n`----`**`" + com.Category + "`**`----`\n";
lastCategory = com.Category;
}
helpstr += PrintCommandHelp(com);
}
helpstr += "\nBot Creator's server: https://discord.gg/0ehQwTK2RBhxEi0X";
helpstr = helpstr.Replace(NadekoBot.botMention, "@BotName");
while (helpstr.Length > 2000)
{
var curstr = helpstr.Substring(0, 2000);
await e.User.Send(curstr.Substring(0, curstr.LastIndexOf("\n") + 1));
helpstr = curstr.Substring(curstr.LastIndexOf("\n") + 1) + helpstr.Substring(2000);
await Task.Delay(200);
}
*/
#endregion OldHelp
if (string.IsNullOrWhiteSpace(e.GetArg("command")))
{
await e.User.Send(HelpString);
return;
}
await Task.Run(async () =>
{
var comToFind = e.GetArg("command");
var com = NadekoBot.Client.GetService<CommandService>().AllCommands
.FirstOrDefault(c => c.Text.ToLower().Equals(comToFind));
if (com != null)
await e.Channel.SendMessage($"`Help for '{com.Text}':` **{com.Description}**");
});
};
public static string HelpString => (NadekoBot.IsBot
? $"To add me to your server, use this link** -> <https://discordapp.com/oauth2/authorize?client_id=170254782546575360&scope=bot&permissions=66186303>\n"
: $"To invite me to your server, just send me an invite link here.") +
$"You can use `{NadekoBot.Config.CommandPrefixes.Help}modules` command to see a list of all modules.\n" +
$"You can use `{NadekoBot.Config.CommandPrefixes.Help}commands ModuleName`" +
$" (for example `{NadekoBot.Config.CommandPrefixes.Help}commands Administration`) to see a list of all of the commands in that module.\n" +
$"For a specific command help, use `{NadekoBot.Config.CommandPrefixes.Help}h \"Command name\"` (for example `-h \"!m q\"`)\n" +
"**LIST OF COMMANDS CAN BE FOUND ON THIS LINK**\n\n <https://github.com/Kwoth/NadekoBot/blob/master/commandlist.md>";
public static string DMHelpString => NadekoBot.Config.DMHelpString;
public Action<CommandEventArgs> DoGitFunc() => e =>
{
string helpstr =
$@"######For more information and how to setup your own NadekoBot, go to: **http://github.com/Kwoth/NadekoBot/**
######You can donate on paypal: `nadekodiscordbot@gmail.com` or Bitcoin `17MZz1JAqME39akMLrVT4XBPffQJ2n1EPa`
#NadekoBot List Of Commands
Version: `{NadekoStats.Instance.BotVersion}`";
string lastCategory = "";
foreach (var com in NadekoBot.Client.GetService<CommandService>().AllCommands)
{
if (com.Category != lastCategory)
{
helpstr += "\n### " + com.Category + " \n";
helpstr += "Command and aliases | Description | Usage\n";
helpstr += "----------------|--------------|-------\n";
lastCategory = com.Category;
}
helpstr += PrintCommandHelp(com);
}
helpstr = helpstr.Replace(NadekoBot.BotMention, "@BotName");
helpstr = helpstr.Replace("\n**Usage**:", " | ").Replace("**Usage**:", " | ").Replace("**Description:**", " | ").Replace("\n|", " | \n");
#if DEBUG
File.WriteAllText("../../../commandlist.md", helpstr);
#else
File.WriteAllText("commandlist.md", helpstr);
#endif
};
internal override void Init(CommandGroupBuilder cgb)
{
cgb.CreateCommand(Module.Prefix + "h")
.Alias(Module.Prefix + "help", NadekoBot.BotMention + " help", NadekoBot.BotMention + " h", "~h")
.Description("Either shows a help for a single command, or PMs you help link if no arguments are specified.\n**Usage**: '-h !m q' or just '-h' ")
.Parameter("command", ParameterType.Unparsed)
.Do(DoFunc());
cgb.CreateCommand(Module.Prefix + "hgit")
.Description("Generates the commandlist.md file. **Owner Only!**")
.AddCheck(Classes.Permissions.SimpleCheckers.OwnerOnly())
.Do(DoGitFunc());
cgb.CreateCommand(Module.Prefix + "readme")
.Alias(Module.Prefix + "guide")
.Description("Sends a readme and a guide links to the channel.")
.Do(async e =>
await e.Channel.SendMessage(
@"**FULL README**: <https://github.com/Kwoth/NadekoBot/blob/master/README.md>
**GUIDE ONLY**: <https://github.com/Kwoth/NadekoBot/blob/master/ComprehensiveGuide.md>
**LIST OF COMMANDS**: <https://github.com/Kwoth/NadekoBot/blob/master/commandlist.md>"));
cgb.CreateCommand(Module.Prefix + "donate")
.Alias("~donate")
.Description("Instructions for helping the project!")
.Do(async e =>
{
await e.Channel.SendMessage(
$@"I've created a **paypal** email for nadeko, so if you wish to support the project, you can send your donations to `nadekodiscordbot@gmail.com`
Don't forget to leave your discord name or id in the message, so that I can reward people who help out.
You can join nadekobot server by typing {Module.Prefix}h and you will get an invite in a private message.
*If you want to support in some other way or on a different platform, please message me*"
);
});
}
private static string PrintCommandHelp(Command com)
{
var str = "`" + com.Text + "`";
str = com.Aliases.Aggregate(str, (current, a) => current + (", `" + a + "`"));
str += " **Description:** " + com.Description + "\n";
return str;
}
public HelpCommand(DiscordModule module) : base(module) { }
}
}

View File

@ -1,10 +1,10 @@
using Discord.Commands;
using Discord.Modules;
using NadekoBot.Commands;
using NadekoBot.Commands.Help.Commands;
using NadekoBot.Extensions;
using System.Linq;
namespace NadekoBot.Modules
namespace NadekoBot.Modules.Help
{
internal class Help : DiscordModule
{

View File

@ -0,0 +1,114 @@
using Discord;
using Discord.Commands;
using NadekoBot.Classes;
using NadekoBot.Classes.Permissions;
using NadekoBot.Commands;
using System;
using System.Text.RegularExpressions;
using ServerPermissions = NadekoBot.Classes.Permissions.ServerPermissions;
namespace NadekoBot.Modules.Permissions.Commands
{
internal class FilterInvitesCommand : DiscordCommand
{
private readonly Regex filterRegex = new Regex(@"(?:discord(?:\.gg|app\.com\/invite)\/(?<id>([\w]{16}|(?:[\w]+-?){3})))");
public FilterInvitesCommand(DiscordModule module) : base(module)
{
NadekoBot.Client.MessageReceived += async (sender, args) =>
{
if (args.Channel.IsPrivate || args.User.Id == NadekoBot.Client.CurrentUser.Id) return;
try
{
ServerPermissions serverPerms;
if (!IsChannelOrServerFiltering(args.Channel, out serverPerms)) return;
if (filterRegex.IsMatch(args.Message.RawText))
{
await args.Message.Delete();
IncidentsHandler.Add(args.Server.Id, $"User [{args.User.Name}/{args.User.Id}] posted " +
$"INVITE LINK in [{args.Channel.Name}/{args.Channel.Id}] channel. " +
$"Full message: [[{args.Message.Text}]]");
if (serverPerms.Verbose)
await args.Channel.SendMessage($"{args.User.Mention} Invite links are not " +
$"allowed on this channel.");
}
}
catch { }
};
}
private static bool IsChannelOrServerFiltering(Channel channel, out ServerPermissions serverPerms)
{
if (!PermissionsHandler.PermissionsDict.TryGetValue(channel.Server.Id, out serverPerms)) return false;
if (serverPerms.Permissions.FilterInvites)
return true;
Classes.Permissions.Permissions perms;
return serverPerms.ChannelPermissions.TryGetValue(channel.Id, out perms) && perms.FilterInvites;
}
internal override void Init(CommandGroupBuilder cgb)
{
cgb.CreateCommand(Module.Prefix + "cfi")
.Alias(Module.Prefix + "channelfilterinvites")
.Description("Enables or disables automatic deleting of invites on the channel." +
"If no channel supplied, it will default to current one. Use ALL to apply to all existing channels at once." +
"\n**Usage**: ;cfi enable #general-chat")
.Parameter("bool")
.Parameter("channel", ParameterType.Optional)
.Do(async e =>
{
try
{
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
var chanStr = e.GetArg("channel");
if (chanStr?.ToLowerInvariant().Trim() != "all")
{
var chan = string.IsNullOrWhiteSpace(chanStr)
? e.Channel
: PermissionHelper.ValidateChannel(e.Server, chanStr);
PermissionsHandler.SetChannelFilterInvitesPermission(chan, state);
await e.Channel.SendMessage($"Invite Filter has been **{(state ? "enabled" : "disabled")}** for **{chan.Name}** channel.");
return;
}
//all channels
foreach (var curChannel in e.Server.TextChannels)
{
PermissionsHandler.SetChannelFilterInvitesPermission(curChannel, state);
}
await e.Channel.SendMessage($"Invite Filter has been **{(state ? "enabled" : "disabled")}** for **ALL** channels.");
}
catch (Exception ex)
{
await e.Channel.SendMessage($"💢 Error: {ex.Message}");
}
});
cgb.CreateCommand(Module.Prefix + "sfi")
.Alias(Module.Prefix + "serverfilterinvites")
.Description("Enables or disables automatic deleting of invites on the server.\n**Usage**: ;sfi disable")
.Parameter("bool")
.Do(async e =>
{
try
{
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
PermissionsHandler.SetServerFilterInvitesPermission(e.Server, state);
await e.Channel.SendMessage($"Invite Filter has been **{(state ? "enabled" : "disabled")}** for this server.");
}
catch (Exception ex)
{
await e.Channel.SendMessage($"💢 Error: {ex.Message}");
}
});
}
}
}

View File

@ -0,0 +1,174 @@
using Discord;
using Discord.Commands;
using NadekoBot.Classes;
using NadekoBot.Classes.Permissions;
using NadekoBot.Commands;
using System;
using System.Linq;
using ServerPermissions = NadekoBot.Classes.Permissions.ServerPermissions;
namespace NadekoBot.Modules.Permissions.Commands
{
internal class FilterWords : DiscordCommand
{
public FilterWords(DiscordModule module) : base(module)
{
NadekoBot.Client.MessageReceived += async (sender, args) =>
{
if (args.Channel.IsPrivate || args.User.Id == NadekoBot.Client.CurrentUser.Id) return;
try
{
ServerPermissions serverPerms;
if (!IsChannelOrServerFiltering(args.Channel, out serverPerms)) return;
var wordsInMessage = args.Message.RawText.ToLowerInvariant().Split(' ');
if (serverPerms.Words.Any(w => wordsInMessage.Contains(w)))
{
await args.Message.Delete();
IncidentsHandler.Add(args.Server.Id, $"User [{args.User.Name}/{args.User.Id}] posted " +
$"BANNED WORD in [{args.Channel.Name}/{args.Channel.Id}] channel. " +
$"Full message: [[{args.Message.Text}]]");
if (serverPerms.Verbose)
await args.Channel.SendMessage($"{args.User.Mention} One or more of the words you used " +
$"in that sentence are not allowed here.");
}
}
catch { }
};
}
private static bool IsChannelOrServerFiltering(Channel channel, out ServerPermissions serverPerms)
{
if (!PermissionsHandler.PermissionsDict.TryGetValue(channel.Server.Id, out serverPerms)) return false;
if (serverPerms.Permissions.FilterWords)
return true;
Classes.Permissions.Permissions perms;
return serverPerms.ChannelPermissions.TryGetValue(channel.Id, out perms) && perms.FilterWords;
}
internal override void Init(CommandGroupBuilder cgb)
{
cgb.CreateCommand(Module.Prefix + "cfw")
.Alias(Module.Prefix + "channelfilterwords")
.Description("Enables or disables automatic deleting of messages containing banned words on the channel." +
"If no channel supplied, it will default to current one. Use ALL to apply to all existing channels at once." +
"\n**Usage**: ;cfi enable #general-chat")
.Parameter("bool")
.Parameter("channel", ParameterType.Optional)
.Do(async e =>
{
try
{
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
var chanStr = e.GetArg("channel")?.ToLowerInvariant().Trim();
if (chanStr != "all")
{
var chan = string.IsNullOrWhiteSpace(chanStr)
? e.Channel
: PermissionHelper.ValidateChannel(e.Server, chanStr);
PermissionsHandler.SetChannelWordPermission(chan, state);
await e.Channel.SendMessage($"Word filtering has been **{(state ? "enabled" : "disabled")}** for **{chan.Name}** channel.");
return;
}
//all channels
foreach (var curChannel in e.Server.TextChannels)
{
PermissionsHandler.SetChannelWordPermission(curChannel, state);
}
await e.Channel.SendMessage($"Word filtering has been **{(state ? "enabled" : "disabled")}** for **ALL** channels.");
}
catch (Exception ex)
{
await e.Channel.SendMessage($"💢 Error: {ex.Message}");
}
});
cgb.CreateCommand(Module.Prefix + "afw")
.Alias(Module.Prefix + "addfilteredword")
.Description("Adds a new word to the list of filtered words" +
"\n**Usage**: ;aw poop")
.Parameter("word", ParameterType.Unparsed)
.Do(async e =>
{
try
{
var word = e.GetArg("word");
if (string.IsNullOrWhiteSpace(word))
return;
PermissionsHandler.AddFilteredWord(e.Server, word.ToLowerInvariant().Trim());
await e.Channel.SendMessage($"Successfully added new filtered word.");
}
catch (Exception ex)
{
await e.Channel.SendMessage($"💢 Error: {ex.Message}");
}
});
cgb.CreateCommand(Module.Prefix + "rfw")
.Alias(Module.Prefix + "removefilteredword")
.Description("Removes the word from the list of filtered words" +
"\n**Usage**: ;rw poop")
.Parameter("word", ParameterType.Unparsed)
.Do(async e =>
{
try
{
var word = e.GetArg("word");
if (string.IsNullOrWhiteSpace(word))
return;
PermissionsHandler.RemoveFilteredWord(e.Server, word.ToLowerInvariant().Trim());
await e.Channel.SendMessage($"Successfully removed filtered word.");
}
catch (Exception ex)
{
await e.Channel.SendMessage($"💢 Error: {ex.Message}");
}
});
cgb.CreateCommand(Module.Prefix + "lfw")
.Alias(Module.Prefix + "listfilteredwords")
.Description("Shows a list of filtered words" +
"\n**Usage**: ;lfw")
.Do(async e =>
{
try
{
ServerPermissions serverPerms;
if (!PermissionsHandler.PermissionsDict.TryGetValue(e.Server.Id, out serverPerms))
return;
await e.Channel.SendMessage($"There are `{serverPerms.Words.Count}` filtered words.\n" +
string.Join("\n", serverPerms.Words));
}
catch (Exception ex)
{
await e.Channel.SendMessage($"💢 Error: {ex.Message}");
}
});
cgb.CreateCommand(Module.Prefix + "sfw")
.Alias(Module.Prefix + "serverfilterwords")
.Description("Enables or disables automatic deleting of messages containing forbidden words on the server.\n**Usage**: ;sfi disable")
.Parameter("bool")
.Do(async e =>
{
try
{
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
PermissionsHandler.SetServerWordPermission(e.Server, state);
await e.Channel.SendMessage($"Word filtering has been **{(state ? "enabled" : "disabled")}** on this server.");
}
catch (Exception ex)
{
await e.Channel.SendMessage($"💢 Error: {ex.Message}");
}
});
}
}
}