diff --git a/src/NadekoBot/Modules/Administration/AdministrationModule.cs b/src/NadekoBot/Modules/Administration/AdministrationModule.cs new file mode 100644 index 00000000..4e35e603 --- /dev/null +++ b/src/NadekoBot/Modules/Administration/AdministrationModule.cs @@ -0,0 +1,765 @@ +using Discord; +using Discord.Commands; +using Discord.Modules; +using NadekoBot.Classes; +using NadekoBot.DataModels; +using NadekoBot.Extensions; +using NadekoBot.Modules.Administration.Commands; +using NadekoBot.Modules.Permissions.Classes; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using NadekoBot.Services; +using NadekoBot.Attributes; + +//todo fix delmsgoncmd +//todo DB +namespace NadekoBot.Modules.Administration +{ + [Module(".", AppendSpace = false)] + public partial class AdministrationModule : DiscordModule + { + public AdministrationModule(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client) + { + } + + //todo owner only + //[LocalizedCommand, LocalizedDescription, LocalizedSummary] + //[RequireContext(ContextType.Guild)] + //public async Task Restart(IMessage imsg) + //{ + // var channel = imsg.Channel as IGuildChannel; + + // await imsg.Channel.SendMessageAsync("`Restarting in 2 seconds...`"); + // await Task.Delay(2000); + // System.Diagnostics.Process.Start(System.Reflection.Assembly.GetEntryAssembly().Location); + // Environment.Exit(0); + //} + + //[LocalizedCommand, LocalizedDescription, LocalizedSummary] + //[RequireContext(ContextType.Guild)] + //[RequirePermission(GuildPermission.ManageGuild)] + //public async Task Delmsgoncmd(IMessage imsg) + //{ + // var channel = imsg.Channel as IGuildChannel; + + // var conf = SpecificConfigurations.Default.Of(channel.Guild.Id); + // conf.AutoDeleteMessagesOnCommand = !conf.AutoDeleteMessagesOnCommand; + // await Classes.JSONModels.ConfigHandler.SaveConfig().ConfigureAwait(false); + // if (conf.AutoDeleteMessagesOnCommand) + // await imsg.Channel.SendMessageAsync("ā—`Now automatically deleting successfull command invokations.`"); + // else + // await imsg.Channel.SendMessageAsync("ā—`Stopped automatic deletion of successfull command invokations.`"); + //} + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.ManageRoles)] + public async Task Setrole(IMessage imsg, IUser userName, [Remainder] string roleName) + { + var channel = imsg.Channel as IGuildChannel; + + if (string.IsNullOrWhiteSpace(roleName)) return; + + var usr = channel.Guild.FindUsers(userName).FirstOrDefault(); + if (usr == null) + { + await imsg.Channel.SendMessageAsync("You failed to supply a valid username").ConfigureAwait(false); + return; + } + + var role = channel.Guild.FindRoles(roleName).FirstOrDefault(); + if (role == null) + { + await imsg.Channel.SendMessageAsync("You failed to supply a valid role").ConfigureAwait(false); + return; + } + + try + { + await usr.AddRoles(role).ConfigureAwait(false); + await imsg.Channel.SendMessageAsync($"Successfully added role **{role.Name}** to user **{usr.Name}**").ConfigureAwait(false); + } + catch (Exception ex) + { + await imsg.Channel.SendMessageAsync("Failed to add roles. Bot has insufficient permissions.\n").ConfigureAwait(false); + Console.WriteLine(ex.ToString()); + } + } + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.ManageRoles)] + public async Task Removerole(IMessage imsg, IUser userName, [Remainder] string roleName) + { + var channel = imsg.Channel as IGuildChannel; + + if (string.IsNullOrWhiteSpace(roleName)) return; + + var usr = channel.Guild.FindUsers(userName).FirstOrDefault(); + if (usr == null) + { + await imsg.Channel.SendMessageAsync("You failed to supply a valid username").ConfigureAwait(false); + return; + } + + var role = channel.Guild.FindRoles(roleName).FirstOrDefault(); + if (role == null) + { + await imsg.Channel.SendMessageAsync("You failed to supply a valid role").ConfigureAwait(false); + return; + } + + try + { + await usr.RemoveRoles(role).ConfigureAwait(false); + await imsg.Channel.SendMessageAsync($"Successfully removed role **{role.Name}** from user **{usr.Name}**").ConfigureAwait(false); + } + catch + { + await imsg.Channel.SendMessageAsync("Failed to remove roles. Most likely reason: Insufficient permissions.").ConfigureAwait(false); + } + } + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.ManageRoles)] + public async Task RenameRole(IMessage imsg, string r1, string r2) + { + var channel = imsg.Channel as IGuildChannel; + + var roleToEdit = channel.Guild.FindRoles(r1).FirstOrDefault(); + if (roleToEdit == null) + { + await imsg.Channel.SendMessageAsync("Can't find that role.").ConfigureAwait(false); + return; + } + + try + { + if (roleToEdit.Position > channel.Guild.CurrentUser.Roles.Max(r => r.Position)) + { + await imsg.Channel.SendMessageAsync("I can't edit roles higher than my highest role.").ConfigureAwait(false); + return; + } + await roleToEdit.Edit(r2); + await imsg.Channel.SendMessageAsync("Role renamed.").ConfigureAwait(false); + } + catch (Exception) + { + await imsg.Channel.SendMessageAsync("Failed to rename role. Probably insufficient permissions.").ConfigureAwait(false); + } + } + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.ManageRoles)] + public async Task RemoveAllRoles(IMessage imsg, [Remainder] string userName) + { + var channel = imsg.Channel as IGuildChannel; + + var usr = channel.Guild.FindUsers(userName).FirstOrDefault(); + if (usr == null) + { + await imsg.Channel.SendMessageAsync("You failed to supply a valid username").ConfigureAwait(false); + return; + } + + try + { + await usr.RemoveRoles(usr.Roles.ToArray()).ConfigureAwait(false); + await imsg.Channel.SendMessageAsync($"Successfully removed **all** roles from user **{usr.Name}**").ConfigureAwait(false); + } + catch + { + await imsg.Channel.SendMessageAsync("Failed to remove roles. Most likely reason: Insufficient permissions.").ConfigureAwait(false); + } + } + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.ManageRoles)] + public async Task CreateRole(IMessage imsg, [Remainder] string roleName) + { + var channel = imsg.Channel as IGuildChannel; + + + if (string.IsNullOrWhiteSpace(e.GetArg("role_name"))) + return; + try + { + var r = await channel.Guild.CreateRole(e.GetArg("role_name")).ConfigureAwait(false); + await imsg.Channel.SendMessageAsync($"Successfully created role **{r.Name}**.").ConfigureAwait(false); + } + catch (Exception) + { + await imsg.Channel.SendMessageAsync(":warning: Unspecified error.").ConfigureAwait(false); + } + } + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.ManageRoles)] + public async Task RoleColor(IMessage imsg, string roleName, string r="", string g="", string b="") + { + var channel = imsg.Channel as IGuildChannel; + + var args = e.Args.Where(s => s != string.Empty); + + if (args.Count() != 2 && args.Count() != 4) + { + await imsg.Channel.SendMessageAsync("The parameters are invalid.").ConfigureAwait(false); + return; + } + + var role = channel.Guild.FindRoles(e.Args[0]).FirstOrDefault(); + + if (role == null) + { + await imsg.Channel.SendMessageAsync("That role does not exist.").ConfigureAwait(false); + return; + } + try + { + var rgb = args.Count() == 4; + var arg1 = e.Args[1].Replace("#", ""); + + var red = Convert.ToByte(rgb ? int.Parse(arg1) : Convert.ToInt32(arg1.Substring(0, 2), 16)); + var green = Convert.ToByte(rgb ? int.Parse(e.Args[2]) : Convert.ToInt32(arg1.Substring(2, 2), 16)); + var blue = Convert.ToByte(rgb ? int.Parse(e.Args[3]) : Convert.ToInt32(arg1.Substring(4, 2), 16)); + + await role.Edit(color: new Color(red, green, blue)).ConfigureAwait(false); + await imsg.Channel.SendMessageAsync($"Role {role.Name}'s color has been changed.").ConfigureAwait(false); + } + catch (Exception) + { + await imsg.Channel.SendMessageAsync("Error occured, most likely invalid parameters or insufficient permissions.").ConfigureAwait(false); + } + } + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.BanMembers)] + public async Task Ban(IMessage imsg, IUser user, [Remainder] string msg) + { + var channel = imsg.Channel as IGuildChannel; + if (user == null) + { + await imsg.Channel.SendMessageAsync("User not found.").ConfigureAwait(false); + return; + } + if (!string.IsNullOrWhiteSpace(msg)) + { + await user.SendMessage($"**You have been BANNED from `{channel.Guild.Name}` server.**\n" + + $"Reason: {msg}").ConfigureAwait(false); + await Task.Delay(2000).ConfigureAwait(false); // temp solution; give time for a message to be send, fu volt + } + try + { + await channel.Guild.Ban(user, 7).ConfigureAwait(false); + + await imsg.Channel.SendMessageAsync("Banned user " + user.Name + " Id: " + user.Id).ConfigureAwait(false); + } + catch + { + await imsg.Channel.SendMessageAsync("Error. Most likely I don't have sufficient permissions.").ConfigureAwait(false); + } + } + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.BanMembers)] + public async Task Softban(IMessage imsg, IUser user, [Remainder] string msg) + { + var channel = imsg.Channel as IGuildChannel; + + if (user == null) + { + await imsg.Channel.SendMessageAsync("User not found.").ConfigureAwait(false); + return; + } + if (!string.IsNullOrWhiteSpace(msg)) + { + await user.SendMessage($"**You have been SOFT-BANNED from `{channel.Guild.Name}` server.**\n" + + $"Reason: {msg}").ConfigureAwait(false); + await Task.Delay(2000).ConfigureAwait(false); // temp solution; give time for a message to be send, fu volt + } + try + { + await channel.Guild.Ban(user, 7).ConfigureAwait(false); + await channel.Guild.Unban(user).ConfigureAwait(false); + + await imsg.Channel.SendMessageAsync("Soft-Banned user " + user.Username + " Id: " + user.Id).ConfigureAwait(false); + } + catch + { + await imsg.Channel.SendMessageAsync("Error. Most likely I don't have sufficient permissions.").ConfigureAwait(false); + } + } + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + public async Task Kick(IMessage imsg, IUser user, [Remainder] string msg) + { + var channel = imsg.Channel as IGuildChannel; + + var usr = channel.Guild.FindUsers(user).FirstOrDefault(); + if (usr == null) + { + await imsg.Channel.SendMessageAsync("User not found.").ConfigureAwait(false); + return; + } + if (!string.IsNullOrWhiteSpace(msg)) + { + await usr.SendMessage($"**You have been KICKED from `{channel.Guild.Name}` server.**\n" + + $"Reason: {msg}").ConfigureAwait(false); + await Task.Delay(2000).ConfigureAwait(false); // temp solution; give time for a message to be send, fu volt + } + try + { + await usr.Kick().ConfigureAwait(false); + await imsg.Channel.SendMessageAsync("Kicked user " + usr.Name + " Id: " + usr.Id).ConfigureAwait(false); + } + catch + { + await imsg.Channel.SendMessageAsync("Error. Most likely I don't have sufficient permissions.").ConfigureAwait(false); + } + } + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.MuteMembers)] + public async Task Mute(IMessage imsg, [Remainder] string throwaway) + { + var channel = imsg.Channel as IGuildChannel; + + if (!e.Message.MentionedUsers.Any()) + return; + try + { + foreach (var u in e.Message.MentionedUsers) + { + await u.Edit(isMuted: true).ConfigureAwait(false); + } + await imsg.Channel.SendMessageAsync("Mute successful").ConfigureAwait(false); + } + catch + { + await imsg.Channel.SendMessageAsync("I most likely don't have the permission necessary for that.").ConfigureAwait(false); + } + } + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + public async Task Unmute(IMessage imsg, [Remainder] string throwaway) + { + var channel = imsg.Channel as IGuildChannel; + + if (!e.Message.MentionedUsers.Any()) + return; + try + { + foreach (var u in e.Message.MentionedUsers) + { + await u.Edit(isMuted: false).ConfigureAwait(false); + } + await imsg.Channel.SendMessageAsync("Unmute successful").ConfigureAwait(false); + } + catch + { + await imsg.Channel.SendMessageAsync("I most likely don't have the permission necessary for that.").ConfigureAwait(false); + } + } + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.DeafenMembers)] + public async Task Deafen(IMessage imsg, [Remainder] string throwaway) + { + var channel = imsg.Channel as IGuildChannel; + + if (!e.Message.MentionedUsers.Any()) + return; + try + { + foreach (var u in e.Message.MentionedUsers) + { + await u.Edit(isDeafened: true).ConfigureAwait(false); + } + await imsg.Channel.SendMessageAsync("Deafen successful").ConfigureAwait(false); + } + catch + { + await imsg.Channel.SendMessageAsync("I most likely don't have the permission necessary for that.").ConfigureAwait(false); + } + + } + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.DeafenMembers)] + public async Task UnDeafen(IMessage imsg, [Remainder] string throwaway) + { + var channel = imsg.Channel as IGuildChannel; + + if (!e.Message.MentionedUsers.Any()) + return; + try + { + foreach (var u in e.Message.MentionedUsers) + { + await u.Edit(isDeafened: false).ConfigureAwait(false); + } + await imsg.Channel.SendMessageAsync("Undeafen successful").ConfigureAwait(false); + } + catch + { + await imsg.Channel.SendMessageAsync("I most likely don't have the permission necessary for that.").ConfigureAwait(false); + } + } + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + public async Task DelVoiChanl(IMessage imsg, [Remainder] channelName) + { + var channel = imsg.Channel as IGuildChannel; + var ch = channel.Guild.FindChannels(channelName, ChannelType.Voice).FirstOrDefault(); + if (ch == null) + return; + await ch.Delete().ConfigureAwait(false); + await imsg.Channel.SendMessageAsync($"Removed channel **{channelName}**.").ConfigureAwait(false); + } + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + public async Task CreatVoiChanl(IMessage imsg, [Remainder] string channelName) + { + var channel = imsg.Channel as IGuildChannel; + + await channel.Guild.CreateChannel(e.GetArg("channel_name"), ChannelType.Voice).ConfigureAwait(false); + await imsg.Channel.SendMessageAsync($"Created voice channel **{e.GetArg("channel_name")}**.").ConfigureAwait(false); + } + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + public async Task DelTxtChanl(IMessage imsg, [Remainder] string channelName) + { + var channel = imsg.Channel as IGuildChannel; + + var channel = channel.Guild.FindChannels(e.GetArg("channel_name"), ChannelType.Text).FirstOrDefault(); + if (channel == null) return; + await channel.Delete().ConfigureAwait(false); + await imsg.Channel.SendMessageAsync($"Removed text channel **{e.GetArg("channel_name")}**.").ConfigureAwait(false); + } + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.ManageChannels)] + public async Task CreaTxtChanl(IMessage imsg, [Remainder] string arg) + { + var channel = imsg.Channel as IGuildChannel; + await channel.Guild.CreateChannel(e.GetArg("channel_name"), ChannelType.Text).ConfigureAwait(false); + await imsg.Channel.SendMessageAsync($"Added text channel **{e.GetArg("channel_name")}**.").ConfigureAwait(false); + } + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.ManageChannels)] + public async Task SetTopic(IMessage imsg, [Remainder] string arg) + { + var topic = e.GetArg("topic")?.Trim() ?? ""; + await e.Channel.Edit(topic: topic).ConfigureAwait(false); + await imsg.Channel.SendMessageAsync(":ok: **New channel topic set.**").ConfigureAwait(false); + + } + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.ManageChannels)] + public async Task SetChanlName(IMessage imsg, [Remainder] string arg) + { + var channel = imsg.Channel as IGuildChannel; + + var name = e.GetArg("name"); + if (string.IsNullOrWhiteSpace(name)) + return; + await e.Channel.Edit(name: name).ConfigureAwait(false); + await imsg.Channel.SendMessageAsync(":ok: **New channel name set.**").ConfigureAwait(false); + } + + + //todo maybe split into 3/4 different commands with the same name + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + public async Task Prune(IMessage msg, [Remainder] string target = null) + { + var channel = msg.Channel as IGuildChannel; + + var user = await channel.Guild.GetCurrentUserAsync(); + if (string.IsNullOrWhiteSpace(target)) + { + + var enumerable = (await msg.Channel.GetMessagesAsync()).Where(x => x.Author.Id == user.Id); + await msg.Channel.DeleteMessagesAsync(enumerable); + return; + } + target = target.Trim(); + if (!user.GetPermissions(channel).ManageMessages) + { + await msg.Reply("Don't have permissions to manage messages in channel"); + return; + } + int count; + if (int.TryParse(target, out count)) + { + while (count > 0) + { + int limit = (count < 100) ? count : 100; + var enumerable = (await msg.Channel.GetMessagesAsync(limit: limit)); + await msg.Channel.DeleteMessagesAsync(enumerable); + await Task.Delay(1000); // there is a 1 per second per guild ratelimit for deletemessages + if (enumerable.Count < limit) break; + count -= limit; + } + } + else if (msg.MentionedUsers.Count > 0) + { + var toDel = new List(); + + var match = Regex.Match(target, @"\s(\d+)\s"); + if (match.Success) + { + int.TryParse(match.Groups[1].Value, out count); + var messages = new List(count); + + while (count > 0) + { + var toAdd = await msg.Channel.GetMessagesAsync(limit: count < 100 ? count : 100); + messages.AddRange(toAdd); + count -= toAdd.Count; + } + + foreach (var mention in msg.MentionedUsers) + { + toDel.AddRange(messages.Where(m => m.Author.Id == mention.Id)); + } + + var messagesEnum = messages.AsEnumerable(); + while (messagesEnum.Count() > 0) + { + await msg.Channel.DeleteMessagesAsync(messagesEnum.Take(100)); + await Task.Delay(1000); // 1 second ratelimit + messagesEnum = messagesEnum.Skip(100); + } + } + } + } + + //todo owner only + //[LocalizedCommand, LocalizedDescription, LocalizedSummary] + //[RequireContext(ContextType.Guild)] + //public async Task Die(IMessage imsg) + //{ + // var channel = imsg.Channel as IGuildChannel; + + // await imsg.Channel.SendMessageAsync("`Shutting down.`").ConfigureAwait(false); + // await Task.Delay(2000).ConfigureAwait(false); + // Environment.Exit(0); + //} + + ////todo owner only + //[LocalizedCommand, LocalizedDescription, LocalizedSummary] + //[RequireContext(ContextType.Guild)] + //public async Task Setname(IMessage imsg, [Remainder] string newName) + //{ + // var channel = imsg.Channel as IGuildChannel; + + //} + + ////todo owner only + //[LocalizedCommand, LocalizedDescription, LocalizedSummary] + //[RequireContext(ContextType.Guild)] + //public async Task NewAvatar(IMessage imsg, [Remainder] string img) + //{ + // var channel = imsg.Channel as IGuildChannel; + + // if (string.IsNullOrWhiteSpace(e.GetArg("img"))) + // return; + // // Gather user provided URL. + // var avatarAddress = e.GetArg("img"); + // var imageStream = await SearchHelper.GetResponseStreamAsync(avatarAddress).ConfigureAwait(false); + // var image = System.Drawing.Image.FromStream(imageStream); + // await client.CurrentUser.Edit("", avatar: image.ToStream()).ConfigureAwait(false); + + // // Send confirm. + // await imsg.Channel.SendMessageAsync("New avatar set.").ConfigureAwait(false); + //} + + ////todo owner only + //[LocalizedCommand, LocalizedDescription, LocalizedSummary] + //[RequireContext(ContextType.Guild)] + //public async Task SetGame(IMessage imsg, [Remainder] string game) + //{ + // var channel = imsg.Channel as IGuildChannel; + + // game = game ?? ""; + + // client.SetGame(e.GetArg("set_game")); + //} + + ////todo owner only + //[LocalizedCommand, LocalizedDescription, LocalizedSummary] + //[RequireContext(ContextType.Guild)] + //public async Task Send(IMessage imsg, string where, [Remainder] string msg) + //{ + // var channel = imsg.Channel as IGuildChannel; + + // if (string.IsNullOrWhiteSpace(msg)) + // return; + + // var ids = where.Split('|'); + // if (ids.Length != 2) + // return; + // var sid = ulong.Parse(ids[0]); + // var server = NadekoBot.Client.Servers.Where(s => s.Id == sid).FirstOrDefault(); + + // if (server == null) + // return; + + // if (ids[1].ToUpperInvariant().StartsWith("C:")) + // { + // var cid = ulong.Parse(ids[1].Substring(2)); + // var channel = server.TextChannels.Where(c => c.Id == cid).FirstOrDefault(); + // if (channel == null) + // { + // return; + // } + // await channel.SendMessage(msg); + // } + // else if (ids[1].ToUpperInvariant().StartsWith("U:")) + // { + // var uid = ulong.Parse(ids[1].Substring(2)); + // var user = server.Users.Where(u => u.Id == uid).FirstOrDefault(); + // if (user == null) + // { + // return; + // } + // await user.SendMessage(msg); + // } + // else + // { + // await imsg.Channel.SendMessageAsync("`Invalid format.`"); + // } + //} + + ////todo owner only + ////todo DB + //[LocalizedCommand, LocalizedDescription, LocalizedSummary] + //[RequireContext(ContextType.Guild)] + //public async Task Donadd(IMessage imsg, IUser donator, int amount) + //{ + // var channel = imsg.Channel as IGuildChannel; + // var donator = channel.Guild.FindUsers(e.GetArg("donator")).FirstOrDefault(); + // var amount = int.Parse(e.GetArg("amount")); + // if (donator == null) return; + // try + // { + // DbHandler.Instance.Connection.Insert(new Donator + // { + // Amount = amount, + // UserName = donator.Name, + // UserId = (long)donator.Id + // }); + // imsg.Channel.SendMessageAsync("Successfuly added a new donator. šŸ‘‘").ConfigureAwait(false); + // } + // catch { } + + //} + + //todo owner only + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + public async Task Announce(IMessage imsg, [Remainder] string message) + { + var channel = imsg.Channel as IGuildChannel; + + + foreach (var ch in NadekoBot.Client.Servers.Select(s => s.DefaultChannel)) + { + await ch.SendMessage(e.GetArg("msg")).ConfigureAwait(false); + } + + await imsg.Channel.SendMessageAsync(":ok:").ConfigureAwait(false); + } + + //todo owner only + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + public async Task SaveChat(IMessage imsg, int cnt) + { + var channel = imsg.Channel as IGuildChannel; + + ulong? lastmsgId = null; + var sb = new StringBuilder(); + var msgs = new List(cnt); + while (cnt > 0) + { + var dlcnt = cnt < 100 ? cnt : 100; + + var dledMsgs = await e.Channel.DownloadMessages(dlcnt, lastmsgId); + if (!dledMsgs.Any()) + break; + msgs.AddRange(dledMsgs); + lastmsgId = msgs[msgs.Count - 1].Id; + cnt -= 100; + } + await e.User.SendFile($"Chatlog-{channel.Guild.Name}/#{e.Channel.Name}-{DateTime.Now}.txt", + JsonConvert.SerializeObject(new { Messages = msgs.Select(s => s.ToString()) }, Formatting.Indented).ToStream()).ConfigureAwait(false); + } + + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.MentionEveryone)] + public async Task MentionRole(IMessage imsg, [Remainder] string roles) + { + var channel = imsg.Channel as IGuildChannel; + + var arg = e.GetArg("roles").Split(',').Select(r => r.Trim()); + string send = $"--{e.User.Mention} has invoked a mention on the following roles--"; + foreach (var roleStr in arg.Where(str => !string.IsNullOrWhiteSpace(str))) + { + var role = channel.Guild.FindRoles(roleStr).FirstOrDefault(); + if (role == null) continue; + send += $"\n`{role.Name}`\n"; + send += string.Join(", ", role.Members.Select(r => r.Mention)); + } + + while (send.Length > 2000) + { + var curstr = send.Substring(0, 2000); + await + e.Channel.Send(curstr.Substring(0, + curstr.LastIndexOf(", ", StringComparison.Ordinal) + 1)).ConfigureAwait(false); + send = curstr.Substring(curstr.LastIndexOf(", ", StringComparison.Ordinal) + 1) + + send.Substring(2000); + } + await e.Channel.Send(send).ConfigureAwait(false); + } + + //todo DB + //[LocalizedCommand, LocalizedDescription, LocalizedSummary] + //[RequireContext(ContextType.Guild)] + //public async Task Donators(IMessage imsg) + //{ + // var channel = imsg.Channel as IGuildChannel; + + // var rows = DbHandler.Instance.GetAllRows(); + // var donatorsOrdered = rows.OrderByDescending(d => d.Amount); + // string str = $"**Thanks to the people listed below for making this project happen!**\n"; + + // await imsg.Channel.SendMessageAsync(str + string.Join("ā­", donatorsOrdered.Select(d => d.UserName))).ConfigureAwait(false); + //} + } +} diff --git a/src/NadekoBot/_Modules/Administration/Commands/AutoAssignRole.cs b/src/NadekoBot/Modules/Administration/Commands/AutoAssignRole.cs similarity index 100% rename from src/NadekoBot/_Modules/Administration/Commands/AutoAssignRole.cs rename to src/NadekoBot/Modules/Administration/Commands/AutoAssignRole.cs diff --git a/src/NadekoBot/_Modules/Administration/Commands/CrossServerTextChannel.cs b/src/NadekoBot/Modules/Administration/Commands/CrossServerTextChannel.cs similarity index 100% rename from src/NadekoBot/_Modules/Administration/Commands/CrossServerTextChannel.cs rename to src/NadekoBot/Modules/Administration/Commands/CrossServerTextChannel.cs diff --git a/src/NadekoBot/_Modules/Administration/Commands/CustomReactionsCommands.cs b/src/NadekoBot/Modules/Administration/Commands/CustomReactionsCommands.cs similarity index 100% rename from src/NadekoBot/_Modules/Administration/Commands/CustomReactionsCommands.cs rename to src/NadekoBot/Modules/Administration/Commands/CustomReactionsCommands.cs diff --git a/src/NadekoBot/_Modules/Administration/Commands/IncidentsCommands.cs b/src/NadekoBot/Modules/Administration/Commands/IncidentsCommands.cs similarity index 100% rename from src/NadekoBot/_Modules/Administration/Commands/IncidentsCommands.cs rename to src/NadekoBot/Modules/Administration/Commands/IncidentsCommands.cs diff --git a/src/NadekoBot/_Modules/Administration/Commands/LogCommand.cs b/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs similarity index 100% rename from src/NadekoBot/_Modules/Administration/Commands/LogCommand.cs rename to src/NadekoBot/Modules/Administration/Commands/LogCommand.cs diff --git a/src/NadekoBot/_Modules/Administration/Commands/MessageRepeater.cs b/src/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs similarity index 100% rename from src/NadekoBot/_Modules/Administration/Commands/MessageRepeater.cs rename to src/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs diff --git a/src/NadekoBot/_Modules/Administration/Commands/PlayingRotate.cs b/src/NadekoBot/Modules/Administration/Commands/PlayingRotate.cs similarity index 100% rename from src/NadekoBot/_Modules/Administration/Commands/PlayingRotate.cs rename to src/NadekoBot/Modules/Administration/Commands/PlayingRotate.cs diff --git a/src/NadekoBot/_Modules/Administration/Commands/RatelimitCommand.cs b/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs similarity index 100% rename from src/NadekoBot/_Modules/Administration/Commands/RatelimitCommand.cs rename to src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs diff --git a/src/NadekoBot/_Modules/Administration/Commands/SelfAssignedRolesCommand.cs b/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs similarity index 100% rename from src/NadekoBot/_Modules/Administration/Commands/SelfAssignedRolesCommand.cs rename to src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs diff --git a/src/NadekoBot/_Modules/Administration/Commands/SelfCommands.cs b/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs similarity index 100% rename from src/NadekoBot/_Modules/Administration/Commands/SelfCommands.cs rename to src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs diff --git a/src/NadekoBot/_Modules/Administration/Commands/ServerGreetCommand.cs b/src/NadekoBot/Modules/Administration/Commands/ServerGreetCommand.cs similarity index 100% rename from src/NadekoBot/_Modules/Administration/Commands/ServerGreetCommand.cs rename to src/NadekoBot/Modules/Administration/Commands/ServerGreetCommand.cs diff --git a/src/NadekoBot/_Modules/Administration/Commands/VoicePlusTextCommand.cs b/src/NadekoBot/Modules/Administration/Commands/VoicePlusTextCommand.cs similarity index 100% rename from src/NadekoBot/_Modules/Administration/Commands/VoicePlusTextCommand.cs rename to src/NadekoBot/Modules/Administration/Commands/VoicePlusTextCommand.cs diff --git a/src/NadekoBot/Modules/Utility/UtilityModule.cs b/src/NadekoBot/Modules/Utility/UtilityModule.cs index aeb5cd4f..9b79914e 100644 --- a/src/NadekoBot/Modules/Utility/UtilityModule.cs +++ b/src/NadekoBot/Modules/Utility/UtilityModule.cs @@ -127,73 +127,6 @@ namespace NadekoBot.Modules.Utility await msg.Reply("`List of roles:` \nā€¢ " + string.Join("\nā€¢ ", (msg.Channel as IGuildChannel).Guild.Roles.Except(new[] { guild.EveryoneRole }))); } } - - //todo maybe split into 3/4 different commands with the same name - [LocalizedCommand, LocalizedDescription, LocalizedSummary] - [RequireContext(ContextType.Guild)] - public async Task Prune(IMessage msg, [Remainder] string target = null) - { - var channel = msg.Channel as IGuildChannel; - - var user = await channel.Guild.GetCurrentUserAsync(); - if (string.IsNullOrWhiteSpace(target)) - { - - var enumerable = (await msg.Channel.GetMessagesAsync()).Where(x => x.Author.Id == user.Id); - await msg.Channel.DeleteMessagesAsync(enumerable); - return; - } - target = target.Trim(); - if (!user.GetPermissions(channel).ManageMessages) - { - await msg.Reply("Don't have permissions to manage messages in channel"); - return; - } - int count; - if (int.TryParse(target, out count)) - { - while (count > 0) - { - int limit = (count < 100) ? count : 100; - var enumerable = (await msg.Channel.GetMessagesAsync(limit: limit)); - await msg.Channel.DeleteMessagesAsync(enumerable); - await Task.Delay(1000); // there is a 1 per second per guild ratelimit for deletemessages - if (enumerable.Count < limit) break; - count -= limit; - } - } - else if (msg.MentionedUsers.Count > 0) - { - var toDel = new List(); - - var match = Regex.Match(target, @"\s(\d+)\s"); - if (match.Success) - { - int.TryParse(match.Groups[1].Value, out count); - var messages = new List(count); - - while (count > 0) - { - var toAdd = await msg.Channel.GetMessagesAsync(limit: count < 100 ? count : 100); - messages.AddRange(toAdd); - count -= toAdd.Count; - } - - foreach (var mention in msg.MentionedUsers) - { - toDel.AddRange(messages.Where(m => m.Author.Id == mention.Id)); - } - - var messagesEnum = messages.AsEnumerable(); - while (messagesEnum.Count() > 0) - { - await msg.Channel.DeleteMessagesAsync(messagesEnum.Take(100)); - await Task.Delay(1000); // 1 second ratelimit - messagesEnum = messagesEnum.Skip(100); - } - } - } - } } } diff --git a/src/NadekoBot/_Modules/Administration/AdministrationModule.cs b/src/NadekoBot/_Modules/Administration/AdministrationModule.cs deleted file mode 100644 index f325c0c9..00000000 --- a/src/NadekoBot/_Modules/Administration/AdministrationModule.cs +++ /dev/null @@ -1,901 +0,0 @@ -using Discord; -using Discord.Commands; -using Discord.Modules; -using NadekoBot.Classes; -using NadekoBot.DataModels; -using NadekoBot.Extensions; -using NadekoBot.Modules.Administration.Commands; -using NadekoBot.Modules.Permissions.Classes; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace NadekoBot.Modules.Administration -{ - internal class AdministrationModule : DiscordModule - { - public AdministrationModule() - { - commands.Add(new ServerGreetCommand(this)); - commands.Add(new LogCommand(this)); - commands.Add(new MessageRepeater(this)); - commands.Add(new PlayingRotate(this)); - commands.Add(new RatelimitCommand(this)); - commands.Add(new VoicePlusTextCommand(this)); - commands.Add(new CrossServerTextChannel(this)); - commands.Add(new SelfAssignedRolesCommand(this)); - commands.Add(new CustomReactionsCommands(this)); - commands.Add(new AutoAssignRole(this)); - commands.Add(new SelfCommands(this)); - commands.Add(new IncidentsCommands(this)); - - NadekoBot.Client.GetService().CommandExecuted += DeleteCommandMessage; - } - - private void DeleteCommandMessage(object sender, CommandEventArgs e) - { - if (e.Server == null || e.Channel.IsPrivate) - return; - var conf = SpecificConfigurations.Default.Of(e.Server.Id); - if (!conf.AutoDeleteMessagesOnCommand) - return; - try - { - e.Message.Delete(); - } - catch { } - } - - public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.Administration; - - public override void Install(ModuleManager manager) - { - - manager.CreateCommands("", cgb => - { - - cgb.AddCheck(PermissionChecker.Instance); - - var client = manager.Client; - - commands.ForEach(cmd => cmd.Init(cgb)); - - cgb.CreateCommand(Prefix + "delmsgoncmd") - .Description($"Toggles the automatic deletion of user's successful command message to prevent chat flood. **Server Manager Only.** | `{Prefix}delmsgoncmd`") - .AddCheck(SimpleCheckers.ManageServer()) - .Do(async e => - { - var conf = SpecificConfigurations.Default.Of(e.Server.Id); - conf.AutoDeleteMessagesOnCommand = !conf.AutoDeleteMessagesOnCommand; - await Classes.JSONModels.ConfigHandler.SaveConfig().ConfigureAwait(false); - if (conf.AutoDeleteMessagesOnCommand) - await imsg.Channel.SendMessageAsync("ā—`Now automatically deleting successfull command invokations.`"); - else - await imsg.Channel.SendMessageAsync("ā—`Stopped automatic deletion of successfull command invokations.`"); - - }); - - cgb.CreateCommand(Prefix + "restart") - .Description($"Restarts the bot. Might not work. **Bot Owner Only** | `{Prefix}restart`") - .AddCheck(SimpleCheckers.OwnerOnly()) - .Do(async e => - { - await imsg.Channel.SendMessageAsync("`Restarting in 2 seconds...`"); - await Task.Delay(2000); - System.Diagnostics.Process.Start(System.Reflection.Assembly.GetExecutingAssembly().Location); - Environment.Exit(0); - }); - - cgb.CreateCommand(Prefix + "setrole").Alias(Prefix + "sr") - .Description($"Sets a role for a given user. **Needs Manage Roles Permissions.**| `{Prefix}sr @User Guest`") - .Parameter("user_name", ParameterType.Required) - .Parameter("role_name", ParameterType.Unparsed) - .AddCheck(SimpleCheckers.CanManageRoles) - .Do(async e => - { - var userName = e.GetArg("user_name"); - var roleName = e.GetArg("role_name"); - - if (string.IsNullOrWhiteSpace(roleName)) return; - - if (!e.User.ServerPermissions.ManageRoles) - { - await imsg.Channel.SendMessageAsync("You have insufficient permissions.").ConfigureAwait(false); - } - - var usr = e.Server.FindUsers(userName).FirstOrDefault(); - if (usr == null) - { - await imsg.Channel.SendMessageAsync("You failed to supply a valid username").ConfigureAwait(false); - return; - } - - var role = e.Server.FindRoles(roleName).FirstOrDefault(); - if (role == null) - { - await imsg.Channel.SendMessageAsync("You failed to supply a valid role").ConfigureAwait(false); - return; - } - - try - { - await usr.AddRoles(role).ConfigureAwait(false); - await imsg.Channel.SendMessageAsync($"Successfully added role **{role.Name}** to user **{usr.Name}**").ConfigureAwait(false); - } - catch (Exception ex) - { - await imsg.Channel.SendMessageAsync("Failed to add roles. Bot has insufficient permissions.\n").ConfigureAwait(false); - Console.WriteLine(ex.ToString()); - } - }); - - cgb.CreateCommand(Prefix + "removerole").Alias(Prefix + "rr") - .Description($"Removes a role from a given user. **Needs Manage Roles Permissions.**| `{Prefix}rr @User Admin`") - .Parameter("user_name", ParameterType.Required) - .Parameter("role_name", ParameterType.Unparsed) - .AddCheck(SimpleCheckers.CanManageRoles) - .Do(async e => - { - var userName = e.GetArg("user_name"); - var roleName = e.GetArg("role_name"); - - if (string.IsNullOrWhiteSpace(roleName)) return; - - var usr = e.Server.FindUsers(userName).FirstOrDefault(); - if (usr == null) - { - await imsg.Channel.SendMessageAsync("You failed to supply a valid username").ConfigureAwait(false); - return; - } - - var role = e.Server.FindRoles(roleName).FirstOrDefault(); - if (role == null) - { - await imsg.Channel.SendMessageAsync("You failed to supply a valid role").ConfigureAwait(false); - return; - } - - try - { - await usr.RemoveRoles(role).ConfigureAwait(false); - await imsg.Channel.SendMessageAsync($"Successfully removed role **{role.Name}** from user **{usr.Name}**").ConfigureAwait(false); - } - catch - { - await imsg.Channel.SendMessageAsync("Failed to remove roles. Most likely reason: Insufficient permissions.").ConfigureAwait(false); - } - }); - - cgb.CreateCommand(Prefix + "renamerole") - .Alias(Prefix + "renr") - .Description($"Renames a role. Roles you are renaming must be lower than bot's highest role. **Manage Roles Permissions.** | `{Prefix}renr \"First role\" SecondRole`") - .Parameter("r1", ParameterType.Required) - .Parameter("r2", ParameterType.Required) - .AddCheck(new SimpleCheckers.ManageRoles()) - .Do(async e => - { - var r1 = e.GetArg("r1").Trim(); - var r2 = e.GetArg("r2").Trim(); - - var roleToEdit = e.Server.FindRoles(r1).FirstOrDefault(); - if (roleToEdit == null) - { - await imsg.Channel.SendMessageAsync("Can't find that role.").ConfigureAwait(false); - return; - } - - try - { - if (roleToEdit.Position > e.Server.CurrentUser.Roles.Max(r => r.Position)) - { - await imsg.Channel.SendMessageAsync("I can't edit roles higher than my highest role.").ConfigureAwait(false); - return; - } - await roleToEdit.Edit(r2); - await imsg.Channel.SendMessageAsync("Role renamed.").ConfigureAwait(false); - } - catch (Exception) - { - await imsg.Channel.SendMessageAsync("Failed to rename role. Probably insufficient permissions.").ConfigureAwait(false); - } - }); - - cgb.CreateCommand(Prefix + "removeallroles").Alias(Prefix + "rar") - .Description($"Removes all roles from a mentioned user. **Needs Manage Roles Permissions.**| `{Prefix}rar @User`") - .Parameter("user_name", ParameterType.Unparsed) - .AddCheck(SimpleCheckers.CanManageRoles) - .Do(async e => - { - var userName = e.GetArg("user_name"); - - var usr = e.Server.FindUsers(userName).FirstOrDefault(); - if (usr == null) - { - await imsg.Channel.SendMessageAsync("You failed to supply a valid username").ConfigureAwait(false); - return; - } - - try - { - await usr.RemoveRoles(usr.Roles.ToArray()).ConfigureAwait(false); - await imsg.Channel.SendMessageAsync($"Successfully removed **all** roles from user **{usr.Name}**").ConfigureAwait(false); - } - catch - { - await imsg.Channel.SendMessageAsync("Failed to remove roles. Most likely reason: Insufficient permissions.").ConfigureAwait(false); - } - }); - - cgb.CreateCommand(Prefix + "createrole").Alias(Prefix + "cr") - .Description($"Creates a role with a given name. **Needs Manage Roles Permissions.**| `{Prefix}cr Awesome Role`") - .Parameter("role_name", ParameterType.Unparsed) - .AddCheck(SimpleCheckers.CanManageRoles) - .Do(async e => - { - if (string.IsNullOrWhiteSpace(e.GetArg("role_name"))) - return; - try - { - var r = await e.Server.CreateRole(e.GetArg("role_name")).ConfigureAwait(false); - await imsg.Channel.SendMessageAsync($"Successfully created role **{r.Name}**.").ConfigureAwait(false); - } - catch (Exception) - { - await imsg.Channel.SendMessageAsync(":warning: Unspecified error.").ConfigureAwait(false); - } - }); - - cgb.CreateCommand(Prefix + "rolecolor").Alias(Prefix + "rc") - .Parameter("role_name", ParameterType.Required) - .Parameter("r", ParameterType.Optional) - .Parameter("g", ParameterType.Optional) - .Parameter("b", ParameterType.Optional) - .Description($"Set a role's color to the hex or 0-255 rgb color value provided. **Needs Manage Roles Permissions.** | `{Prefix}rc Admin 255 200 100` or `{Prefix}rc Admin ffba55`") - .Do(async e => - { - if (!e.User.ServerPermissions.ManageRoles) - { - await imsg.Channel.SendMessageAsync("You don't have permission to use this!").ConfigureAwait(false); - return; - } - - var args = e.Args.Where(s => s != string.Empty); - - if (args.Count() != 2 && args.Count() != 4) - { - await imsg.Channel.SendMessageAsync("The parameters are invalid.").ConfigureAwait(false); - return; - } - - var role = e.Server.FindRoles(e.Args[0]).FirstOrDefault(); - - if (role == null) - { - await imsg.Channel.SendMessageAsync("That role does not exist.").ConfigureAwait(false); - return; - } - try - { - var rgb = args.Count() == 4; - var arg1 = e.Args[1].Replace("#", ""); - - var red = Convert.ToByte(rgb ? int.Parse(arg1) : Convert.ToInt32(arg1.Substring(0, 2), 16)); - var green = Convert.ToByte(rgb ? int.Parse(e.Args[2]) : Convert.ToInt32(arg1.Substring(2, 2), 16)); - var blue = Convert.ToByte(rgb ? int.Parse(e.Args[3]) : Convert.ToInt32(arg1.Substring(4, 2), 16)); - - await role.Edit(color: new Color(red, green, blue)).ConfigureAwait(false); - await imsg.Channel.SendMessageAsync($"Role {role.Name}'s color has been changed.").ConfigureAwait(false); - } - catch (Exception) - { - await imsg.Channel.SendMessageAsync("Error occured, most likely invalid parameters or insufficient permissions.").ConfigureAwait(false); - } - }); - - cgb.CreateCommand(Prefix + "ban").Alias(Prefix + "b") - .Parameter("user", ParameterType.Required) - .Parameter("msg", ParameterType.Unparsed) - .Description($"Bans a user by id or name with an optional message. **Needs Ban Permissions.**| `{Prefix}b \"@some Guy\" Your behaviour is toxic.`") - .Do(async e => - { - var msg = e.GetArg("msg"); - var user = e.GetArg("user"); - if (e.User.ServerPermissions.BanMembers) - { - var usr = e.Server.FindUsers(user).FirstOrDefault(); - if (usr == null) - { - await imsg.Channel.SendMessageAsync("User not found.").ConfigureAwait(false); - return; - } - if (!string.IsNullOrWhiteSpace(msg)) - { - await usr.SendMessage($"**You have been BANNED from `{e.Server.Name}` server.**\n" + - $"Reason: {msg}").ConfigureAwait(false); - await Task.Delay(2000).ConfigureAwait(false); // temp solution; give time for a message to be send, fu volt - } - try - { - await e.Server.Ban(usr, 7).ConfigureAwait(false); - - await imsg.Channel.SendMessageAsync("Banned user " + usr.Name + " Id: " + usr.Id).ConfigureAwait(false); - } - catch - { - await imsg.Channel.SendMessageAsync("Error. Most likely I don't have sufficient permissions.").ConfigureAwait(false); - } - } - }); - - cgb.CreateCommand(Prefix + "softban").Alias(Prefix + "sb") - .Parameter("user", ParameterType.Required) - .Parameter("msg", ParameterType.Unparsed) - .Description($"Bans and then unbans a user by id or name with an optional message. **Needs Ban Permissions.**| `{Prefix}sb \"@some Guy\" Your behaviour is toxic.`") - .Do(async e => - { - var msg = e.GetArg("msg"); - var user = e.GetArg("user"); - if (e.User.ServerPermissions.BanMembers) - { - var usr = e.Server.FindUsers(user).FirstOrDefault(); - if (usr == null) - { - await imsg.Channel.SendMessageAsync("User not found.").ConfigureAwait(false); - return; - } - if (!string.IsNullOrWhiteSpace(msg)) - { - await usr.SendMessage($"**You have been SOFT-BANNED from `{e.Server.Name}` server.**\n" + - $"Reason: {msg}").ConfigureAwait(false); - await Task.Delay(2000).ConfigureAwait(false); // temp solution; give time for a message to be send, fu volt - } - try - { - await e.Server.Ban(usr, 7).ConfigureAwait(false); - await e.Server.Unban(usr).ConfigureAwait(false); - - await imsg.Channel.SendMessageAsync("Soft-Banned user " + usr.Name + " Id: " + usr.Id).ConfigureAwait(false); - } - catch - { - await imsg.Channel.SendMessageAsync("Error. Most likely I don't have sufficient permissions.").ConfigureAwait(false); - } - } - }); - - cgb.CreateCommand(Prefix + "kick").Alias(Prefix + "k") - .Parameter("user") - .Parameter("msg", ParameterType.Unparsed) - .Description($"Kicks a mentioned user. **Needs Kick Permissions.**| `{Prefix}k \"@some Guy\" Your behaviour is toxic.`") - .Do(async e => - { - var msg = e.GetArg("msg"); - var user = e.GetArg("user"); - if (e.User.ServerPermissions.KickMembers) - { - var usr = e.Server.FindUsers(user).FirstOrDefault(); - if (usr == null) - { - await imsg.Channel.SendMessageAsync("User not found.").ConfigureAwait(false); - return; - } - if (!string.IsNullOrWhiteSpace(msg)) - { - await usr.SendMessage($"**You have been KICKED from `{e.Server.Name}` server.**\n" + - $"Reason: {msg}").ConfigureAwait(false); - await Task.Delay(2000).ConfigureAwait(false); // temp solution; give time for a message to be send, fu volt - } - try - { - await usr.Kick().ConfigureAwait(false); - await imsg.Channel.SendMessageAsync("Kicked user " + usr.Name + " Id: " + usr.Id).ConfigureAwait(false); - } - catch - { - await imsg.Channel.SendMessageAsync("Error. Most likely I don't have sufficient permissions.").ConfigureAwait(false); - } - } - }); - cgb.CreateCommand(Prefix + "mute") - .Description($"Mutes mentioned user or users. **Needs Mute Permissions.**| `{Prefix}mute \"@Someguy\"` or `{Prefix}mute \"@Someguy\" \"@Someguy\"`") - .Parameter("throwaway", ParameterType.Unparsed) - .Do(async e => - { - if (!e.User.ServerPermissions.MuteMembers) - { - await imsg.Channel.SendMessageAsync("I most likely don't have the permission necessary for that.").ConfigureAwait(false); - return; - } - if (!e.Message.MentionedUsers.Any()) - return; - try - { - foreach (var u in e.Message.MentionedUsers) - { - await u.Edit(isMuted: true).ConfigureAwait(false); - } - await imsg.Channel.SendMessageAsync("Mute successful").ConfigureAwait(false); - } - catch - { - await imsg.Channel.SendMessageAsync("I most likely don't have the permission necessary for that.").ConfigureAwait(false); - } - }); - - cgb.CreateCommand(Prefix + "unmute") - .Description($"Unmutes mentioned user or users. **Needs Mute Permissions.**| `{Prefix}unmute \"@Someguy\"` or `{Prefix}unmute \"@Someguy\" \"@Someguy\"`") - .Parameter("throwaway", ParameterType.Unparsed) - .Do(async e => - { - if (!e.User.ServerPermissions.MuteMembers) - { - await imsg.Channel.SendMessageAsync("You do not have permission to do that.").ConfigureAwait(false); - return; - } - if (!e.Message.MentionedUsers.Any()) - return; - try - { - foreach (var u in e.Message.MentionedUsers) - { - await u.Edit(isMuted: false).ConfigureAwait(false); - } - await imsg.Channel.SendMessageAsync("Unmute successful").ConfigureAwait(false); - } - catch - { - await imsg.Channel.SendMessageAsync("I most likely don't have the permission necessary for that.").ConfigureAwait(false); - } - }); - - cgb.CreateCommand(Prefix + "deafen") - .Alias(Prefix + "deaf") - .Description($"Deafens mentioned user or users. **Needs Deafen Permissions.**| `{Prefix}deaf \"@Someguy\"` or `{Prefix}deaf \"@Someguy\" \"@Someguy\"`") - .Parameter("throwaway", ParameterType.Unparsed) - .Do(async e => - { - if (!e.User.ServerPermissions.DeafenMembers) - { - await imsg.Channel.SendMessageAsync("You do not have permission to do that.").ConfigureAwait(false); - return; - } - if (!e.Message.MentionedUsers.Any()) - return; - try - { - foreach (var u in e.Message.MentionedUsers) - { - await u.Edit(isDeafened: true).ConfigureAwait(false); - } - await imsg.Channel.SendMessageAsync("Deafen successful").ConfigureAwait(false); - } - catch - { - await imsg.Channel.SendMessageAsync("I most likely don't have the permission necessary for that.").ConfigureAwait(false); - } - }); - - cgb.CreateCommand(Prefix + "undeafen") - .Alias(Prefix + "undef") - .Description($"Undeafens mentioned user or users. **Needs Deafen Permissions.** | `{Prefix}undef \"@Someguy\"` or `{Prefix}undef \"@Someguy\" \"@Someguy\"`") - .Parameter("throwaway", ParameterType.Unparsed) - .Do(async e => - { - if (!e.User.ServerPermissions.DeafenMembers) - { - await imsg.Channel.SendMessageAsync("You do not have permission to do that.").ConfigureAwait(false); - return; - } - if (!e.Message.MentionedUsers.Any()) - return; - try - { - foreach (var u in e.Message.MentionedUsers) - { - await u.Edit(isDeafened: false).ConfigureAwait(false); - } - await imsg.Channel.SendMessageAsync("Undeafen successful").ConfigureAwait(false); - } - catch - { - await imsg.Channel.SendMessageAsync("I most likely don't have the permission necessary for that.").ConfigureAwait(false); - } - }); - - cgb.CreateCommand(Prefix + "delvoichanl") - .Alias(Prefix + "dvch") - .Description($"Deletes a voice channel with a given name. **Needs Manage Channel Permissions.**| `{Prefix}dvch VoiceChannelName`") - .Parameter("channel_name", ParameterType.Required) - .Do(async e => - { - try - { - if (e.User.ServerPermissions.ManageChannels) - { - var ch = e.Server.FindChannels(e.GetArg("channel_name"), ChannelType.Voice).FirstOrDefault(); - if (ch == null) - return; - await ch.Delete().ConfigureAwait(false); - await imsg.Channel.SendMessageAsync($"Removed channel **{e.GetArg("channel_name")}**.").ConfigureAwait(false); - } - } - catch - { - await imsg.Channel.SendMessageAsync("Insufficient permissions."); - } - }); - - cgb.CreateCommand(Prefix + "creatvoichanl") - .Alias(Prefix + "cvch") - .Description($"Creates a new voice channel with a given name. **Needs Manage Channel Permissions.** | `{Prefix}cvch VoiceChannelName`") - .Parameter("channel_name", ParameterType.Required) - .Do(async e => - { - try - { - if (e.User.ServerPermissions.ManageChannels) - { - await e.Server.CreateChannel(e.GetArg("channel_name"), ChannelType.Voice).ConfigureAwait(false); - await imsg.Channel.SendMessageAsync($"Created voice channel **{e.GetArg("channel_name")}**.").ConfigureAwait(false); - } - } - catch - { - await imsg.Channel.SendMessageAsync("Insufficient permissions.").ConfigureAwait(false); - } - }); - - cgb.CreateCommand(Prefix + "deltxtchanl") - .Alias(Prefix + "dtch") - .Description($"Deletes a text channel with a given name. **Needs Manage Channel Permissions.** | `{Prefix}dtch TextChannelName`") - .Parameter("channel_name", ParameterType.Required) - .Do(async e => - { - try - { - if (e.User.ServerPermissions.ManageChannels) - { - var channel = e.Server.FindChannels(e.GetArg("channel_name"), ChannelType.Text).FirstOrDefault(); - if (channel == null) return; - await channel.Delete().ConfigureAwait(false); - await imsg.Channel.SendMessageAsync($"Removed text channel **{e.GetArg("channel_name")}**.").ConfigureAwait(false); - } - } - catch - { - await imsg.Channel.SendMessageAsync("Insufficient permissions.").ConfigureAwait(false); - } - }); - - cgb.CreateCommand(Prefix + "creatxtchanl") - .Alias(Prefix + "ctch") - .Description($"Creates a new text channel with a given name. **Needs Manage Channel Permissions.** | `{Prefix}ctch TextChannelName`") - .Parameter("channel_name", ParameterType.Required) - .Do(async e => - { - try - { - if (e.User.ServerPermissions.ManageChannels) - { - await e.Server.CreateChannel(e.GetArg("channel_name"), ChannelType.Text).ConfigureAwait(false); - await imsg.Channel.SendMessageAsync($"Added text channel **{e.GetArg("channel_name")}**.").ConfigureAwait(false); - } - } - catch - { - await imsg.Channel.SendMessageAsync("Insufficient permissions.").ConfigureAwait(false); - } - }); - - cgb.CreateCommand(Prefix + "settopic") - .Alias(Prefix + "st") - .Description($"Sets a topic on the current channel. **Needs Manage Channel Permissions.** | `{Prefix}st My new topic`") - .AddCheck(SimpleCheckers.ManageChannels()) - .Parameter("topic", ParameterType.Unparsed) - .Do(async e => - { - var topic = e.GetArg("topic")?.Trim() ?? ""; - await e.Channel.Edit(topic: topic).ConfigureAwait(false); - await imsg.Channel.SendMessageAsync(":ok: **New channel topic set.**").ConfigureAwait(false); - }); - - cgb.CreateCommand(Prefix + "setchanlname") - .Alias(Prefix + "schn") - .Description($"Changed the name of the current channel. **Needs Manage Channel Permissions.**| `{Prefix}schn NewName`") - .AddCheck(SimpleCheckers.ManageChannels()) - .Parameter("name", ParameterType.Unparsed) - .Do(async e => - { - var name = e.GetArg("name"); - if (string.IsNullOrWhiteSpace(name)) - return; - await e.Channel.Edit(name: name).ConfigureAwait(false); - await imsg.Channel.SendMessageAsync(":ok: **New channel name set.**").ConfigureAwait(false); - }); - - cgb.CreateCommand(Prefix + "heap") - .Description($"Shows allocated memory - **Bot Owner Only!** | `{Prefix}heap`") - .AddCheck(SimpleCheckers.OwnerOnly()) - .Do(async e => - { - var heap = await Task.Run(() => NadekoStats.Instance.Heap()).ConfigureAwait(false); - await imsg.Channel.SendMessageAsync($"`Heap Size:` {heap}").ConfigureAwait(false); - }); - - cgb.CreateCommand(Prefix + "prune") - .Alias(Prefix + "clr") - .Description( - "`.prune` removes all nadeko's messages in the last 100 messages.`.prune X` removes last X messages from the channel (up to 100)`.prune @Someone` removes all Someone's messages in the last 100 messages.`.prune @Someone X` removes last X 'Someone's' messages in the channel. " + - $"| `{Prefix}prune` or `{Prefix}prune 5` or `{Prefix}prune @Someone` or `{Prefix}prune @Someone X`") - .Parameter("user_or_num", ParameterType.Optional) - .Parameter("num", ParameterType.Optional) - .Do(async e => - { - if (string.IsNullOrWhiteSpace(e.GetArg("user_or_num"))) // if nothing is set, clear nadeko's messages, no permissions required - { - var msgs = (await e.Channel.DownloadMessages(100).ConfigureAwait(false)).Where(m => m.User?.Id == e.Server.CurrentUser.Id)?.ToArray(); - if (msgs == null || !msgs.Any()) - return; - var toDelete = msgs as Message[] ?? msgs.ToArray(); - await e.Channel.DeleteMessages(toDelete).ConfigureAwait(false); - return; - } - if (!e.User.GetPermissions(e.Channel).ManageMessages) - return; - else if (!e.Server.CurrentUser.GetPermissions(e.Channel).ManageMessages) - { - await imsg.Channel.SendMessageAsync("šŸ’¢I don't have the permission to manage messages."); - return; - } - int val; - if (int.TryParse(e.GetArg("user_or_num"), out val)) // if num is set in the first argument, - //delete that number of messages. - { - if (val <= 0) - return; - val++; - await e.Channel.DeleteMessages((await e.Channel.DownloadMessages(val).ConfigureAwait(false)).ToArray()).ConfigureAwait(false); - return; - } - //else if first argument is user - var usr = e.Server.FindUsers(e.GetArg("user_or_num")).FirstOrDefault(); - if (usr == null) - return; - val = 100; - if (!int.TryParse(e.GetArg("num"), out val)) - val = 100; - var mesgs = (await e.Channel.DownloadMessages(100).ConfigureAwait(false)).Where(m => m.User?.Id == usr.Id).Take(val); - if (mesgs == null || !mesgs.Any()) - return; - await e.Channel.DeleteMessages(mesgs as Message[] ?? mesgs.ToArray()).ConfigureAwait(false); - }); - - cgb.CreateCommand(Prefix + "die") - .Description($"Shuts the bot down and notifies users about the restart. **Bot Owner Only!** | `{Prefix}die`") - .AddCheck(SimpleCheckers.OwnerOnly()) - .Do(async e => - { - await imsg.Channel.SendMessageAsync("`Shutting down.`").ConfigureAwait(false); - await Task.Delay(2000).ConfigureAwait(false); - Environment.Exit(0); - }); - - cgb.CreateCommand(Prefix + "setname") - .Alias(Prefix + "newnm") - .Description($"Give the bot a new name. **Bot Owner Only!** | {Prefix}newnm BotName") - .Parameter("new_name", ParameterType.Unparsed) - .AddCheck(SimpleCheckers.OwnerOnly()) - .Do(async e => - { - if (e.GetArg("new_name") == null) return; - - await client.CurrentUser.Edit("", e.GetArg("new_name")).ConfigureAwait(false); - }); - - cgb.CreateCommand(Prefix + "newavatar") - .Alias(Prefix + "setavatar") - .Description($"Sets a new avatar image for the NadekoBot. Argument is a direct link to an image. **Bot Owner Only!** | `{Prefix}setavatar https://i.ytimg.com/vi/WDudkR1eTMM/maxresdefault.jpg`") - .Parameter("img", ParameterType.Unparsed) - .AddCheck(SimpleCheckers.OwnerOnly()) - .Do(async e => - { - if (string.IsNullOrWhiteSpace(e.GetArg("img"))) - return; - // Gather user provided URL. - var avatarAddress = e.GetArg("img"); - var imageStream = await SearchHelper.GetResponseStreamAsync(avatarAddress).ConfigureAwait(false); - var image = System.Drawing.Image.FromStream(imageStream); - await client.CurrentUser.Edit("", avatar: image.ToStream()).ConfigureAwait(false); - - // Send confirm. - await imsg.Channel.SendMessageAsync("New avatar set.").ConfigureAwait(false); - - // Save the image to disk. - image.Save("data/avatar.png", System.Drawing.Imaging.ImageFormat.Png); - }); - - cgb.CreateCommand(Prefix + "setgame") - .Description($"Sets the bots game. **Bot Owner Only!** | `{Prefix}setgame Playing with kwoth`") - .Parameter("set_game", ParameterType.Unparsed) - .Do(e => - { - if (!NadekoBot.IsOwner(e.User.Id) || e.GetArg("set_game") == null) return; - - client.SetGame(e.GetArg("set_game")); - }); - - cgb.CreateCommand(Prefix + "send") - .Description($"Send a message to someone on a different server through the bot. **Bot Owner Only!** | `{Prefix}send serverid|u:user_id Send this to a user!` or `{Prefix}send serverid|c:channel_id Send this to a channel!`") - .Parameter("ids", ParameterType.Required) - .Parameter("msg", ParameterType.Unparsed) - .AddCheck(SimpleCheckers.OwnerOnly()) - .Do(async e => - { - var msg = e.GetArg("msg")?.Trim(); - - if (string.IsNullOrWhiteSpace(msg)) - return; - - var ids = e.GetArg("ids").Split('|'); - if (ids.Length != 2) - return; - var sid = ulong.Parse(ids[0]); - var server = NadekoBot.Client.Servers.Where(s => s.Id == sid).FirstOrDefault(); - - if (server == null) - return; - - if (ids[1].ToUpperInvariant().StartsWith("C:")) - { - var cid = ulong.Parse(ids[1].Substring(2)); - var channel = server.TextChannels.Where(c => c.Id == cid).FirstOrDefault(); - if (channel == null) - { - return; - } - await channel.SendMessage(msg); - } - else if (ids[1].ToUpperInvariant().StartsWith("U:")) - { - var uid = ulong.Parse(ids[1].Substring(2)); - var user = server.Users.Where(u => u.Id == uid).FirstOrDefault(); - if (user == null) - { - return; - } - await user.SendMessage(msg); - } - else - { - await imsg.Channel.SendMessageAsync("`Invalid format.`"); - } - }); - - cgb.CreateCommand(Prefix + "mentionrole") - .Alias(Prefix + "menro") - .Description($"Mentions every person from the provided role or roles (separated by a ',') on this server. Requires you to have mention everyone permission. | `{Prefix}menro RoleName`") - .Parameter("roles", ParameterType.Unparsed) - .Do(async e => - { - await Task.Run(async () => - { - if (!e.User.ServerPermissions.MentionEveryone) return; - var arg = e.GetArg("roles").Split(',').Select(r => r.Trim()); - string send = $"--{e.User.Mention} has invoked a mention on the following roles--"; - foreach (var roleStr in arg.Where(str => !string.IsNullOrWhiteSpace(str))) - { - var role = e.Server.FindRoles(roleStr).FirstOrDefault(); - if (role == null) continue; - send += $"\n`{role.Name}`\n"; - send += string.Join(", ", role.Members.Select(r => r.Mention)); - } - - while (send.Length > 2000) - { - var curstr = send.Substring(0, 2000); - await - e.Channel.Send(curstr.Substring(0, - curstr.LastIndexOf(", ", StringComparison.Ordinal) + 1)).ConfigureAwait(false); - send = curstr.Substring(curstr.LastIndexOf(", ", StringComparison.Ordinal) + 1) + - send.Substring(2000); - } - await e.Channel.Send(send).ConfigureAwait(false); - }).ConfigureAwait(false); - }); - - cgb.CreateCommand(Prefix + "unstuck") - .Description($"Clears the message queue. **Bot Owner Only!** | `{Prefix}unstuck`") - .AddCheck(SimpleCheckers.OwnerOnly()) - .Do(e => - { - NadekoBot.Client.MessageQueue.Clear(); - }); - - cgb.CreateCommand(Prefix + "donators") - .Description($"List of lovely people who donated to keep this project alive. | `{Prefix}donators`") - .Do(async e => - { - await Task.Run(async () => - { - var rows = DbHandler.Instance.GetAllRows(); - var donatorsOrdered = rows.OrderByDescending(d => d.Amount); - string str = $"**Thanks to the people listed below for making this project happen!**\n"; - - await imsg.Channel.SendMessageAsync(str + string.Join("ā­", donatorsOrdered.Select(d => d.UserName))).ConfigureAwait(false); - }).ConfigureAwait(false); - }); - - cgb.CreateCommand(Prefix + "donadd") - .Description($"Add a donator to the database. **Kwoth Only** | `{Prefix}donadd Donate Amount`") - .Parameter("donator") - .Parameter("amount") - .AddCheck(SimpleCheckers.OwnerOnly()) - .Do(async e => - { - await Task.Run(() => - { - var donator = e.Server.FindUsers(e.GetArg("donator")).FirstOrDefault(); - var amount = int.Parse(e.GetArg("amount")); - if (donator == null) return; - try - { - DbHandler.Instance.Connection.Insert(new Donator - { - Amount = amount, - UserName = donator.Name, - UserId = (long)donator.Id - }); - imsg.Channel.SendMessageAsync("Successfuly added a new donator. šŸ‘‘").ConfigureAwait(false); - } - catch { } - }).ConfigureAwait(false); - }); - - cgb.CreateCommand(Prefix + "announce") - .Description($"Sends a message to all servers' general channel bot is connected to.**Bot Owner Only!** | `{Prefix}announce Useless spam`") - .Parameter("msg", ParameterType.Unparsed) - .AddCheck(SimpleCheckers.OwnerOnly()) - .Do(async e => - { - foreach (var ch in NadekoBot.Client.Servers.Select(s => s.DefaultChannel)) - { - await ch.SendMessage(e.GetArg("msg")).ConfigureAwait(false); - } - - await imsg.Channel.SendMessageAsync(":ok:").ConfigureAwait(false); - }); - - cgb.CreateCommand(Prefix + "savechat") - .Description($"Saves a number of messages to a text file and sends it to you. **Bot Owner Only** | `{Prefix}savechat 150`") - .Parameter("cnt", ParameterType.Required) - .AddCheck(SimpleCheckers.OwnerOnly()) - .Do(async e => - { - var cntstr = e.GetArg("cnt")?.Trim(); - int cnt; - if (!int.TryParse(cntstr, out cnt)) - return; - ulong? lastmsgId = null; - var sb = new StringBuilder(); - var msgs = new List(cnt); - while (cnt > 0) - { - var dlcnt = cnt < 100 ? cnt : 100; - - var dledMsgs = await e.Channel.DownloadMessages(dlcnt, lastmsgId); - if (!dledMsgs.Any()) - break; - msgs.AddRange(dledMsgs); - lastmsgId = msgs[msgs.Count - 1].Id; - cnt -= 100; - } - await e.User.SendFile($"Chatlog-{e.Server.Name}/#{e.Channel.Name}-{DateTime.Now}.txt", JsonConvert.SerializeObject(new { Messages = msgs.Select(s => s.ToString()) }, Formatting.Indented).ToStream()).ConfigureAwait(false); - }); - - }); - } - } -}