diff --git a/.gitignore b/.gitignore index 1dd55335..67d693a9 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ obj/ NadekoBot/bin/debug/*.* NadekoBot/bin/debug/data/permissions NadekoBot/bin/debug/data/incidents +NadekoBot/bin/debug/data/musicdata NadekoBot/bin/NadekoRelease/*.* !NadekoBot/bin/Debug/data/currency_images/* Tests/bin diff --git a/DockerGuide.md b/DockerGuide.md new file mode 100644 index 00000000..b079c6f3 --- /dev/null +++ b/DockerGuide.md @@ -0,0 +1,47 @@ +## Docker guide with digitalocean + +#####Prerequisites: +- Digital ocean account (you can use my reflink to support the project and get 10$ after you register http://m.do.co/c/46b4d3d44795/ ) +- Putty (get it here http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html) +- A bot account - (follow http://discord.kongslien.net/guide.html) +- Common sense + +Click on the create droplet button +![img](http://i.imgur.com/g2ayOcC.png) + +pick one click apps and select docker on 14.04 + +![img](http://imgur.com/065Xkme.png) + +- pick any droplet size you want (5$ will work ok-ish on a few servers) +- pick location closest to your discord server's location +- Pick a hostname +![img](http://imgur.com/ifPKB6p.png) + +- click create + +You will get an email from digitalocean with your creds now. + +Open putty and type ip adress **you got in your email** with port 22 + +![img](http://imgur.com/Mh5ehsh.png) + +console will open and you will be prompted for a username, type `root` +type in the password you got in the email +confirm the password you just typed in +type in the new password +confirm new password + +when you are successfully logged in, type +`docker run --name nadeko -v /nadeko:/config uirel/nadeko` + +wait for it to download and at one point it is going to start throwing errors due to credentials.json being empty +CTRL+C to exit that +type `docker stop nadeko` +type `nano /nadeko/credentials.json` and type in your credentials +CTRL+X then CTRL+Y to save +type `docker start nadeko` + +Your bot is running, enjoy + +*When you want to update the bot, just type `docker restart nadeko` as it always downloads latest prerelease* diff --git a/NadekoBot/Classes/DBHandler.cs b/NadekoBot/Classes/DBHandler.cs index 3f2963cc..db8dee81 100644 --- a/NadekoBot/Classes/DBHandler.cs +++ b/NadekoBot/Classes/DBHandler.cs @@ -13,129 +13,74 @@ namespace NadekoBot.Classes private string FilePath { get; } = "data/nadekobot.sqlite"; + public SQLiteConnection Connection { get; set; } + static DbHandler() { } public DbHandler() { - using (var conn = new SQLiteConnection(FilePath)) + Connection = new SQLiteConnection(FilePath); + Connection.CreateTable(); + Connection.CreateTable(); + Connection.CreateTable(); + Connection.CreateTable(); + Connection.CreateTable(); + Connection.CreateTable(); + Connection.CreateTable(); + Connection.CreateTable(); + Connection.CreateTable(); + Connection.CreateTable(); + Connection.CreateTable(); + Connection.CreateTable(); + Connection.CreateTable(); + Connection.CreateTable(); + Connection.CreateTable(); + Connection.Execute(Queries.TransactionTriggerQuery); + try { - conn.CreateTable(); - conn.CreateTable(); - conn.CreateTable(); - conn.CreateTable(); - conn.CreateTable(); - conn.CreateTable(); - conn.CreateTable(); - conn.CreateTable(); - conn.CreateTable(); - conn.CreateTable(); - conn.CreateTable(); - conn.CreateTable(); - conn.CreateTable(); - conn.CreateTable(); - conn.CreateTable(); - conn.Execute(Queries.TransactionTriggerQuery); - try - { - conn.Execute(Queries.DeletePlaylistTriggerQuery); - } - catch (Exception ex) - { - Console.WriteLine(ex); - } + Connection.Execute(Queries.DeletePlaylistTriggerQuery); + } + catch (Exception ex) + { + Console.WriteLine(ex); } } internal T FindOne(Expression> p) where T : IDataModel, new() { - using (var conn = new SQLiteConnection(FilePath)) - { - return conn.Table().Where(p).FirstOrDefault(); - } + return Connection.Table().Where(p).FirstOrDefault(); + } internal IList FindAll(Expression> p) where T : IDataModel, new() { - using (var conn = new SQLiteConnection(FilePath)) - { - return conn.Table().Where(p).ToList(); - } - } - internal void DeleteAll() where T : IDataModel - { - using (var conn = new SQLiteConnection(FilePath)) - { - conn.DeleteAll(); - } + return Connection.Table().Where(p).ToList(); + } internal void DeleteWhere(Expression> p) where T : IDataModel, new() { - using (var conn = new SQLiteConnection(FilePath)) - { - var id = conn.Table().Where(p).FirstOrDefault()?.Id; - if (id.HasValue) - conn.Delete(id); - } - } - - internal void InsertData(T o) where T : IDataModel - { - using (var conn = new SQLiteConnection(FilePath)) - { - conn.Insert(o, typeof(T)); - } - } - - internal void InsertMany(T objects) where T : IEnumerable - { - using (var conn = new SQLiteConnection(FilePath)) - { - conn.InsertAll(objects); - } - } - - internal void UpdateData(T o) where T : IDataModel - { - using (var conn = new SQLiteConnection(FilePath)) - { - conn.Update(o, typeof(T)); - } - } - - internal void UpdateAll(IEnumerable objs) where T : IDataModel - { - using (var conn = new SQLiteConnection(FilePath)) - { - conn.UpdateAll(objs); - } + var id = Connection.Table().Where(p).FirstOrDefault()?.Id; + if (id.HasValue) + Connection.Delete(id); } internal HashSet GetAllRows() where T : IDataModel, new() { - using (var conn = new SQLiteConnection(FilePath)) - { - return new HashSet(conn.Table()); - } + return new HashSet(Connection.Table()); } internal CurrencyState GetStateByUserId(long id) { - using (var conn = new SQLiteConnection(FilePath)) - { - return conn.Table().Where(x => x.UserId == id).FirstOrDefault(); - } + return Connection.Table().Where(x => x.UserId == id).FirstOrDefault(); } internal T Delete(int id) where T : IDataModel, new() { - using (var conn = new SQLiteConnection(FilePath)) - { - var found = conn.Find(id); - if (found != null) - conn.Delete(found.Id); - return found; - } + var found = Connection.Find(id); + if (found != null) + Connection.Delete(found.Id); + return found; } /// @@ -143,14 +88,11 @@ namespace NadekoBot.Classes /// internal void Save(T o) where T : IDataModel, new() { - using (var conn = new SQLiteConnection(FilePath)) - { - var found = conn.Find(o.Id); - if (found == null) - conn.Insert(o, typeof(T)); - else - conn.Update(o, typeof(T)); - } + var found = Connection.Find(o.Id); + if (found == null) + Connection.Insert(o, typeof(T)); + else + Connection.Update(o, typeof(T)); } /// @@ -158,20 +100,14 @@ namespace NadekoBot.Classes /// internal void SaveAll(IEnumerable ocol) where T : IDataModel, new() { - using (var conn = new SQLiteConnection(FilePath)) - { - foreach (var o in ocol) - conn.InsertOrReplace(o); - } + foreach (var o in ocol) + Connection.InsertOrReplace(o); } internal T GetRandom(Expression> p) where T : IDataModel, new() { - using (var conn = new SQLiteConnection(FilePath)) - { - var r = new Random(); - return conn.Table().Where(p).ToList().OrderBy(x => r.Next()).FirstOrDefault(); - } + var r = new Random(); + return Connection.Table().Where(p).ToList().OrderBy(x => r.Next()).FirstOrDefault(); } /// /// @@ -180,24 +116,19 @@ namespace NadekoBot.Classes /// internal List GetPlaylistData(int num) { - using (var conn = new SQLiteConnection(FilePath)) - { - return conn.Query( + return Connection.Query( @"SELECT mp.Name as 'Name',mp.Id as 'Id', mp.CreatorName as 'Creator', Count(*) as 'SongCnt' FROM MusicPlaylist as mp INNER JOIN PlaylistSongInfo as psi ON mp.Id = psi.PlaylistId Group BY mp.Name Order By mp.DateAdded desc Limit 20 OFFSET ?", num * 20); - } + } internal IEnumerable GetTopRichest(int n = 10) { - using (var conn = new SQLiteConnection(FilePath)) - { - return conn.Table().OrderByDescending(cs => cs.Value).Take(n).ToList(); - } + return Connection.Table().OrderByDescending(cs => cs.Value).Take(n).ToList(); } } } diff --git a/NadekoBot/Classes/FlowersHandler.cs b/NadekoBot/Classes/FlowersHandler.cs index 6fa042ea..57191c63 100644 --- a/NadekoBot/Classes/FlowersHandler.cs +++ b/NadekoBot/Classes/FlowersHandler.cs @@ -10,7 +10,7 @@ namespace NadekoBot.Classes return; await Task.Run(() => { - DbHandler.Instance.InsertData(new DataModels.CurrencyTransaction + DbHandler.Instance.Connection.Insert(new DataModels.CurrencyTransaction { Reason = reason, UserId = (long)u.Id, @@ -36,7 +36,7 @@ namespace NadekoBot.Classes if (state.Value < amount) return false; - DbHandler.Instance.InsertData(new DataModels.CurrencyTransaction + DbHandler.Instance.Connection.Insert(new DataModels.CurrencyTransaction { Reason = reason, UserId = (long)u.Id, diff --git a/NadekoBot/Classes/IncidentsHandler.cs b/NadekoBot/Classes/IncidentsHandler.cs index 5d8190fe..3042f824 100644 --- a/NadekoBot/Classes/IncidentsHandler.cs +++ b/NadekoBot/Classes/IncidentsHandler.cs @@ -19,7 +19,7 @@ namespace NadekoBot.Classes Read = false }; - DbHandler.Instance.InsertData(incident); + DbHandler.Instance.Connection.Insert(incident, typeof(Incident)); } } } diff --git a/NadekoBot/Classes/NadekoStats.cs b/NadekoBot/Classes/NadekoStats.cs index 3ccbc272..8161348a 100644 --- a/NadekoBot/Classes/NadekoStats.cs +++ b/NadekoBot/Classes/NadekoStats.cs @@ -46,20 +46,7 @@ namespace NadekoBot commandService.CommandExecuted += StatsCollector_RanCommand; commandService.CommandFinished += CommandService_CommandFinished; - commandService.CommandErrored += (s, e) => - { - try - { - if (e.ErrorType == CommandErrorType.Exception) - File.AppendAllText("errors.txt", $@"Command: {e.Command} -{e.Exception} -------------------------------------- -"); - } - catch { - Console.WriteLine("Command errored errorring"); - } - }; + commandService.CommandErrored += CommandService_CommandFinished; Task.Run(StartCollecting); @@ -208,7 +195,7 @@ namespace NadekoBot .ConfigureAwait(false); var connectedServers = NadekoBot.Client.Servers.Count(); - Classes.DbHandler.Instance.InsertData(new DataModels.Stats + Classes.DbHandler.Instance.Connection.Insert(new DataModels.Stats { OnlineUsers = onlineUsers, RealOnlineUsers = realOnlineUsers, @@ -236,10 +223,31 @@ namespace NadekoBot private void CommandService_CommandFinished(object sender, CommandEventArgs e) { + DateTime dt; if (!commandTracker.TryGetValue(e.Message.Id, out dt)) return; - Console.WriteLine($">>COMMAND ENDED after *{(DateTime.UtcNow - dt).TotalSeconds}s*\nCmd: {e.Command.Text}\nMsg: {e.Message.Text}\nUsr: {e.User.Name} [{e.User.Id}]\nSrvr: {e.Server?.Name ?? "PRIVATE"} [{e.Server?.Id}]\n-----"); + try + { + if (e is CommandErrorEventArgs) + { + var er = e as CommandErrorEventArgs; + if (er.ErrorType == CommandErrorType.Exception) + { + File.AppendAllText("errors.txt", $@"Command: {er.Command} +{er.Exception} +------------------------------------- +"); + Console.WriteLine($">>COMMAND ERRORED after *{(DateTime.UtcNow - dt).TotalSeconds}s*\nCmd: {e.Command.Text}\nMsg: {e.Message.Text}\nUsr: {e.User.Name} [{e.User.Id}]\nSrvr: {e.Server?.Name ?? "PRIVATE"} [{e.Server?.Id}]\n-----"); + } + + } + else + { + Console.WriteLine($">>COMMAND ENDED after *{(DateTime.UtcNow - dt).TotalSeconds}s*\nCmd: {e.Command.Text}\nMsg: {e.Message.Text}\nUsr: {e.User.Name} [{e.User.Id}]\nSrvr: {e.Server?.Name ?? "PRIVATE"} [{e.Server?.Id}]\n-----"); + } + } + catch { } } private async void StatsCollector_RanCommand(object sender, CommandEventArgs e) @@ -252,7 +260,7 @@ namespace NadekoBot try { commandsRan++; - Classes.DbHandler.Instance.InsertData(new DataModels.Command + Classes.DbHandler.Instance.Connection.Insert(new DataModels.Command { ServerId = (long)(e.Server?.Id ?? 0), ServerName = e.Server?.Name ?? "--Direct Message--", diff --git a/NadekoBot/Classes/SearchHelper.cs b/NadekoBot/Classes/SearchHelper.cs index 7f26e1da..a0a59e9b 100644 --- a/NadekoBot/Classes/SearchHelper.cs +++ b/NadekoBot/Classes/SearchHelper.cs @@ -25,16 +25,13 @@ namespace NadekoBot.Classes { private static DateTime lastRefreshed = DateTime.MinValue; private static string token { get; set; } = ""; - private static readonly HttpClient httpClient = new HttpClient(); public static async Task GetResponseStreamAsync(string url, IEnumerable> headers = null, RequestHttpMethod method = RequestHttpMethod.Get) { if (string.IsNullOrWhiteSpace(url)) throw new ArgumentNullException(nameof(url)); - //if its a post or there are no headers, use static httpclient - // if there are headers and it's get, it's not threadsafe - var cl = headers == null || method == RequestHttpMethod.Post ? httpClient : new HttpClient(); + var cl = new HttpClient(); cl.DefaultRequestHeaders.Clear(); switch (method) { @@ -178,7 +175,7 @@ namespace NadekoBot.Classes return null; } - public static async Task GetRelatedVideoId(string id) + public static async Task> GetRelatedVideoIds(string id, int count = 1) { if (string.IsNullOrWhiteSpace(id)) throw new ArgumentNullException(nameof(id)); @@ -189,20 +186,14 @@ namespace NadekoBot.Classes } var response = await GetResponseStringAsync( $"https://www.googleapis.com/youtube/v3/search?" + - $"part=snippet&maxResults=1&type=video" + + $"part=snippet&maxResults={count}&type=video" + $"&relatedToVideoId={id}" + $"&key={NadekoBot.Creds.GoogleAPIKey}").ConfigureAwait(false); JObject obj = JObject.Parse(response); var data = JsonConvert.DeserializeObject(response); - if (data.items.Length > 0) - { - var toReturn = "http://www.youtube.com/watch?v=" + data.items[0].id.videoId.ToString(); - return toReturn; - } - else - return null; + return data.items.Select(v => "http://www.youtube.com/watch?v=" + v.id.videoId); } public static async Task GetPlaylistIdByKeyword(string query) diff --git a/NadekoBot/Modules/Administration/AdministrationModule.cs b/NadekoBot/Modules/Administration/AdministrationModule.cs index 036687aa..670d2513 100644 --- a/NadekoBot/Modules/Administration/AdministrationModule.cs +++ b/NadekoBot/Modules/Administration/AdministrationModule.cs @@ -64,7 +64,7 @@ namespace NadekoBot.Modules.Administration 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.") + .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 => { @@ -79,7 +79,7 @@ namespace NadekoBot.Modules.Administration }); cgb.CreateCommand(Prefix + "restart") - .Description("Restarts the bot. Might not work. **Bot Owner Only**") + .Description($"Restarts the bot. Might not work. **Bot Owner Only** | `{Prefix}restart`") .AddCheck(SimpleCheckers.OwnerOnly()) .Do(async e => { @@ -406,7 +406,7 @@ namespace NadekoBot.Modules.Administration { if (!e.User.ServerPermissions.MuteMembers) { - await e.Channel.SendMessage("You do not have permission to do that.").ConfigureAwait(false); + await e.Channel.SendMessage("I most likely don't have the permission necessary for that.").ConfigureAwait(false); return; } if (!e.Message.MentionedUsers.Any()) @@ -421,7 +421,7 @@ namespace NadekoBot.Modules.Administration } catch { - await e.Channel.SendMessage("I do not have permission to do that most likely.").ConfigureAwait(false); + await e.Channel.SendMessage("I most likely don't have the permission necessary for that.").ConfigureAwait(false); } }); @@ -447,7 +447,7 @@ namespace NadekoBot.Modules.Administration } catch { - await e.Channel.SendMessage("I do not have permission to do that most likely.").ConfigureAwait(false); + await e.Channel.SendMessage("I most likely don't have the permission necessary for that.").ConfigureAwait(false); } }); @@ -474,7 +474,7 @@ namespace NadekoBot.Modules.Administration } catch { - await e.Channel.SendMessage("I do not have permission to do that most likely.").ConfigureAwait(false); + await e.Channel.SendMessage("I most likely don't have the permission necessary for that.").ConfigureAwait(false); } }); @@ -501,7 +501,7 @@ namespace NadekoBot.Modules.Administration } catch { - await e.Channel.SendMessage("I do not have permission to do that most likely.").ConfigureAwait(false); + await e.Channel.SendMessage("I most likely don't have the permission necessary for that.").ConfigureAwait(false); } }); @@ -617,7 +617,7 @@ namespace NadekoBot.Modules.Administration }); cgb.CreateCommand(Prefix + "heap") - .Description("Shows allocated memory - **Bot Owner Only!**") + .Description($"Shows allocated memory - **Bot Owner Only!** | `{Prefix}heap`") .AddCheck(SimpleCheckers.OwnerOnly()) .Do(async e => { @@ -628,19 +628,19 @@ namespace NadekoBot.Modules.Administration 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. | `.prune` or `.prune 5` or `.prune @Someone` or `.prune @Someone X`") + "`.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 => { - Message[] msgs; if (string.IsNullOrWhiteSpace(e.GetArg("user_or_num"))) // if nothing is set, clear nadeko's messages, no permissions required { - msgs = (await e.Channel.DownloadMessages(100).ConfigureAwait(false));//.Where(m => m.User.Id == e.Server.CurrentUser.Id).ToArray(); - msgs = msgs.Where(m => m.User.Id == e.Server.CurrentUser.Id).ToArray(); - if (!msgs.Any()) + 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; - await e.Channel.DeleteMessages(msgs).ConfigureAwait(false); + var toDelete = msgs as Message[] ?? msgs.ToArray(); + await e.Channel.DeleteMessages(toDelete).ConfigureAwait(false); return; } if (!e.User.GetPermissions(e.Channel).ManageMessages) @@ -667,14 +667,14 @@ namespace NadekoBot.Modules.Administration val = 100; if (!int.TryParse(e.GetArg("num"), out val)) val = 100; - msgs = (await e.Channel.DownloadMessages(100).ConfigureAwait(false)).Where(m => m.User.Id == usr.Id).Take(val).ToArray(); - if (!msgs.Any()) + 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(msgs).ConfigureAwait(false); + 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!**") + .Description($"Shuts the bot down and notifies users about the restart. **Bot Owner Only!** | `{Prefix}die`") .AddCheck(SimpleCheckers.OwnerOnly()) .Do(async e => { @@ -807,7 +807,7 @@ namespace NadekoBot.Modules.Administration }); cgb.CreateCommand(Prefix + "unstuck") - .Description("Clears the message queue. **Bot Owner Only!**") + .Description($"Clears the message queue. **Bot Owner Only!** | `{Prefix}unstuck`") .AddCheck(SimpleCheckers.OwnerOnly()) .Do(e => { @@ -829,7 +829,7 @@ namespace NadekoBot.Modules.Administration }); cgb.CreateCommand(Prefix + "donadd") - .Description($"Add a donator to the database. | `.donadd Donate Amount`") + .Description($"Add a donator to the database. | `{Prefix}donadd Donate Amount`") .Parameter("donator") .Parameter("amount") .AddCheck(SimpleCheckers.OwnerOnly()) @@ -842,7 +842,7 @@ namespace NadekoBot.Modules.Administration if (donator == null) return; try { - DbHandler.Instance.InsertData(new Donator + DbHandler.Instance.Connection.Insert(new Donator { Amount = amount, UserName = donator.Name, diff --git a/NadekoBot/Modules/Administration/Commands/AutoAssignRole.cs b/NadekoBot/Modules/Administration/Commands/AutoAssignRole.cs index c368aa0b..7ccd0e0e 100644 --- a/NadekoBot/Modules/Administration/Commands/AutoAssignRole.cs +++ b/NadekoBot/Modules/Administration/Commands/AutoAssignRole.cs @@ -34,7 +34,7 @@ namespace NadekoBot.Modules.Administration.Commands { cgb.CreateCommand(Module.Prefix + "autoassignrole") .Alias(Module.Prefix + "aar") - .Description($"Automaticaly assigns a specified role to every user who joins the server. Type `.aar` to disable, `.aar Role Name` to enable") + .Description($"Automaticaly assigns a specified role to every user who joins the server. |`{Prefix}aar` to disable, `{Prefix}aar Role Name` to enable") .Parameter("role", ParameterType.Unparsed) .AddCheck(new SimpleCheckers.ManageRoles()) .Do(async e => diff --git a/NadekoBot/Modules/Administration/Commands/CrossServerTextChannel.cs b/NadekoBot/Modules/Administration/Commands/CrossServerTextChannel.cs index 0d2a3fe7..f8dc2133 100644 --- a/NadekoBot/Modules/Administration/Commands/CrossServerTextChannel.cs +++ b/NadekoBot/Modules/Administration/Commands/CrossServerTextChannel.cs @@ -64,8 +64,8 @@ namespace NadekoBot.Modules.Administration.Commands internal override void Init(CommandGroupBuilder cgb) { cgb.CreateCommand(Module.Prefix + "scsc") - .Description("Starts an instance of cross server channel. You will get a token as a DM" + - "that other people will use to tune in to the same instance") + .Description("Starts an instance of cross server channel. You will get a token as a DM " + + $"that other people will use to tune in to the same instance. | `{Prefix}scsc`") .AddCheck(SimpleCheckers.OwnerOnly()) .Do(async e => { @@ -79,7 +79,7 @@ namespace NadekoBot.Modules.Administration.Commands }); cgb.CreateCommand(Module.Prefix + "jcsc") - .Description("Joins current channel to an instance of cross server channel using the token.") + .Description($"Joins current channel to an instance of cross server channel using the token. | `{Prefix}jcsc`") .Parameter("token") .AddCheck(SimpleCheckers.ManageServer()) .Do(async e => @@ -95,7 +95,7 @@ namespace NadekoBot.Modules.Administration.Commands }); cgb.CreateCommand(Module.Prefix + "lcsc") - .Description("Leaves Cross server channel instance from this channel") + .Description($"Leaves Cross server channel instance from this channel. | `{Prefix}lcsc`") .AddCheck(SimpleCheckers.ManageServer()) .Do(async e => { diff --git a/NadekoBot/Modules/Administration/Commands/CustomReactionsCommands.cs b/NadekoBot/Modules/Administration/Commands/CustomReactionsCommands.cs index a01f9a8d..5105863f 100644 --- a/NadekoBot/Modules/Administration/Commands/CustomReactionsCommands.cs +++ b/NadekoBot/Modules/Administration/Commands/CustomReactionsCommands.cs @@ -23,7 +23,7 @@ namespace NadekoBot.Modules.Administration.Commands cgb.CreateCommand(Prefix + "addcustreact") .Alias(Prefix + "acr") - .Description($"Add a custom reaction. Guide here: **Bot Owner Only!** | {Prefix}acr \"hello\" I love saying hello to %user%") + .Description($"Add a custom reaction. Guide here: **Bot Owner Only!** | `{Prefix}acr \"hello\" I love saying hello to %user%`") .AddCheck(SimpleCheckers.OwnerOnly()) .Parameter("name", ParameterType.Required) .Parameter("message", ParameterType.Unparsed) @@ -47,7 +47,7 @@ namespace NadekoBot.Modules.Administration.Commands cgb.CreateCommand(Prefix + "listcustreact") .Alias(Prefix + "lcr") - .Description($"Lists custom reactions (paginated with 30 commands per page). Use 'all' instead of page number to get all custom reactions DM-ed to you. |{Prefix}lcr 1") + .Description($"Lists custom reactions (paginated with 30 commands per page). Use 'all' instead of page number to get all custom reactions DM-ed to you. |`{Prefix}lcr 1`") .Parameter("num", ParameterType.Required) .Do(async e => { @@ -80,7 +80,7 @@ namespace NadekoBot.Modules.Administration.Commands cgb.CreateCommand(Prefix + "showcustreact") .Alias(Prefix + "scr") - .Description($"Shows all possible responses from a single custom reaction. |{Prefix}scr %mention% bb") + .Description($"Shows all possible responses from a single custom reaction. |`{Prefix}scr %mention% bb`") .Parameter("name", ParameterType.Unparsed) .Do(async e => { @@ -106,7 +106,7 @@ namespace NadekoBot.Modules.Administration.Commands cgb.CreateCommand(Prefix + "editcustreact") .Alias(Prefix + "ecr") - .Description("Edits a custom reaction, arguments are custom reactions name, index to change, and a (multiword) message **Bot Owner Only** | `.ecr \"%mention% disguise\" 2 Test 123`") + .Description($"Edits a custom reaction, arguments are custom reactions name, index to change, and a (multiword) message **Bot Owner Only** | `{Prefix}ecr \"%mention% disguise\" 2 Test 123`") .Parameter("name", ParameterType.Required) .Parameter("index", ParameterType.Required) .Parameter("message", ParameterType.Unparsed) @@ -146,7 +146,7 @@ namespace NadekoBot.Modules.Administration.Commands cgb.CreateCommand(Prefix + "delcustreact") .Alias(Prefix + "dcr") - .Description("Deletes a custom reaction with given name (and index)") + .Description($"Deletes a custom reaction with given name (and index). | `{Prefix}dcr index`") .Parameter("name", ParameterType.Required) .Parameter("index", ParameterType.Optional) .AddCheck(SimpleCheckers.OwnerOnly()) diff --git a/NadekoBot/Modules/Administration/Commands/IncidentsCommands.cs b/NadekoBot/Modules/Administration/Commands/IncidentsCommands.cs index a5854708..d7915bb2 100644 --- a/NadekoBot/Modules/Administration/Commands/IncidentsCommands.cs +++ b/NadekoBot/Modules/Administration/Commands/IncidentsCommands.cs @@ -14,26 +14,26 @@ namespace NadekoBot.Modules.Administration.Commands { cgb.CreateCommand(Module.Prefix + "listincidents") .Alias(Prefix + "lin") - .Description("List all UNREAD incidents and flags them as read.") + .Description($"List all UNREAD incidents and flags them as read. | `{Prefix}lin`") .AddCheck(SimpleCheckers.ManageServer()) .Do(async e => { var sid = (long)e.Server.Id; var incs = DbHandler.Instance.FindAll(i => i.ServerId == sid && i.Read == false); - DbHandler.Instance.UpdateAll(incs.Select(i => { i.Read = true; return i; })); + DbHandler.Instance.Connection.UpdateAll(incs.Select(i => { i.Read = true; return i; })); await e.User.SendMessage(string.Join("\n----------------------", incs.Select(i => i.Text))); }); cgb.CreateCommand(Module.Prefix + "listallincidents") .Alias(Prefix + "lain") - .Description("Sends you a file containing all incidents and flags them as read.") + .Description($"Sends you a file containing all incidents and flags them as read. | `{Prefix}lain`") .AddCheck(SimpleCheckers.ManageServer()) .Do(async e => { var sid = (long)e.Server.Id; var incs = DbHandler.Instance.FindAll(i => i.ServerId == sid); - DbHandler.Instance.UpdateAll(incs.Select(i => { i.Read = true; return i; })); + DbHandler.Instance.Connection.UpdateAll(incs.Select(i => { i.Read = true; return i; })); var data = string.Join("\n----------------------\n", incs.Select(i => i.Text)); MemoryStream ms = new MemoryStream(); var sw = new StreamWriter(ms); diff --git a/NadekoBot/Modules/Administration/Commands/LogCommand.cs b/NadekoBot/Modules/Administration/Commands/LogCommand.cs index 3bbce6d2..db693ae3 100644 --- a/NadekoBot/Modules/Administration/Commands/LogCommand.cs +++ b/NadekoBot/Modules/Administration/Commands/LogCommand.cs @@ -4,7 +4,10 @@ using NadekoBot.Classes; using NadekoBot.Extensions; using NadekoBot.Modules.Permissions.Classes; using System; +using System.Collections.Concurrent; +using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; namespace NadekoBot.Modules.Administration.Commands { @@ -12,6 +15,8 @@ namespace NadekoBot.Modules.Administration.Commands { private string prettyCurrentTime => $"ใ€{DateTime.Now:HH:mm:ss}ใ€‘"; + private ConcurrentBag> voicePresenceUpdates = new ConcurrentBag>(); + public LogCommand(DiscordModule module) : base(module) { NadekoBot.Client.MessageReceived += MsgRecivd; @@ -45,6 +50,36 @@ namespace NadekoBot.Modules.Administration.Commands } catch { } }; + + // start the userpresence queue + + NadekoBot.OnReady += () => Task.Run(async () => + { + while (true) + { + var toSend = new Dictionary(); + //take everything from the queue and merge the messages which are going to the same channel + KeyValuePair item; + while (voicePresenceUpdates.TryTake(out item)) + { + if (toSend.ContainsKey(item.Key)) + { + toSend[item.Key] = toSend[item.Key] + Environment.NewLine + item.Value; + } + else + { + toSend.Add(item.Key, item.Value); + } + } + //send merged messages to each channel + foreach (var k in toSend) + { + try { await k.Key.SendMessage(Environment.NewLine + k.Value).ConfigureAwait(false); } catch { } + } + + await Task.Delay(5000); + } + }); } private async void ChannelUpdated(object sender, ChannelUpdatedEventArgs e) @@ -177,13 +212,13 @@ namespace NadekoBot.Modules.Administration.Commands if (!string.IsNullOrWhiteSpace(e.Message.Text)) { await ch.SendMessage( - $@"๐Ÿ•”`{prettyCurrentTime}` **New Message** `#{e.Channel.Name}` + $@"๐Ÿ•”`{prettyCurrentTime}` **New Message** `#{e.Channel.Name}` ๐Ÿ‘ค`{e.User?.ToString() ?? ("NULL")}` {e.Message.Text.Unmention()}").ConfigureAwait(false); } else { await ch.SendMessage( - $@"๐Ÿ•”`{prettyCurrentTime}` **File Uploaded** `#{e.Channel.Name}` + $@"๐Ÿ•”`{prettyCurrentTime}` **File Uploaded** `#{e.Channel.Name}` ๐Ÿ‘ค`{e.User?.ToString() ?? ("NULL")}` {e.Message.Attachments.FirstOrDefault()?.ProxyUrl}").ConfigureAwait(false); } @@ -206,13 +241,13 @@ namespace NadekoBot.Modules.Administration.Commands if (!string.IsNullOrWhiteSpace(e.Message.Text)) { await ch.SendMessage( - $@"๐Ÿ•”`{prettyCurrentTime}` **Message** ๐Ÿšฎ `#{e.Channel.Name}` + $@"๐Ÿ•”`{prettyCurrentTime}` **Message** ๐Ÿšฎ `#{e.Channel.Name}` ๐Ÿ‘ค`{e.User?.ToString() ?? ("NULL")}` {e.Message.Text.Unmention()}").ConfigureAwait(false); } else { await ch.SendMessage( - $@"๐Ÿ•”`{prettyCurrentTime}` **File Deleted** `#{e.Channel.Name}` + $@"๐Ÿ•”`{prettyCurrentTime}` **File Deleted** `#{e.Channel.Name}` ๐Ÿ‘ค`{e.User?.ToString() ?? ("NULL")}` {e.Message.Attachments.FirstOrDefault()?.ProxyUrl}").ConfigureAwait(false); } } @@ -232,7 +267,7 @@ namespace NadekoBot.Modules.Administration.Commands if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null) return; await ch.SendMessage( -$@"๐Ÿ•”`{prettyCurrentTime}` **Message** ๐Ÿ“ `#{e.Channel.Name}` + $@"๐Ÿ•”`{prettyCurrentTime}` **Message** ๐Ÿ“ `#{e.Channel.Name}` ๐Ÿ‘ค`{e.User?.ToString() ?? ("NULL")}` `Old:` {e.Before.Text.Unmention()} `New:` {e.After.Text.Unmention()}").ConfigureAwait(false); @@ -252,7 +287,7 @@ $@"๐Ÿ•”`{prettyCurrentTime}` **Message** ๐Ÿ“ `#{e.Channel.Name}` { if (e.Before.Status != e.After.Status) { - await ch.SendMessage($"`{prettyCurrentTime}`**{e.Before.Name}** is now **{e.After.Status}**.").ConfigureAwait(false); + voicePresenceUpdates.Add(new KeyValuePair(ch, $"`{prettyCurrentTime}`**{e.Before.Name}** is now **{e.After.Status}**.")); } } } @@ -340,7 +375,7 @@ $@"๐Ÿ•”`{prettyCurrentTime}` **Message** ๐Ÿ“ `#{e.Channel.Name}` { cgb.CreateCommand(Module.Prefix + "spmom") - .Description("Toggles whether mentions of other offline users on your server will send a pm to them.") + .Description($"Toggles whether mentions of other offline users on your server will send a pm to them. | `{Prefix}spmom`") .AddCheck(SimpleCheckers.ManageServer()) .Do(async e => { @@ -356,7 +391,7 @@ $@"๐Ÿ•”`{prettyCurrentTime}` **Message** ๐Ÿ“ `#{e.Channel.Name}` }); cgb.CreateCommand(Module.Prefix + "logserver") - .Description("Toggles logging in this channel. Logs every message sent/deleted/edited on the server. **Bot Owner Only!**") + .Description($"Toggles logging in this channel. Logs every message sent/deleted/edited on the server. **Bot Owner Only!** | `{Prefix}logserver`") .AddCheck(SimpleCheckers.OwnerOnly()) .AddCheck(SimpleCheckers.ManageServer()) .Do(async e => @@ -371,14 +406,14 @@ $@"๐Ÿ•”`{prettyCurrentTime}` **Message** ๐Ÿ“ `#{e.Channel.Name}` Channel ch; if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null) return; - - SpecificConfigurations.Default.Of (e.Server.Id).LogServerChannel = null; + + SpecificConfigurations.Default.Of(e.Server.Id).LogServerChannel = null; await e.Channel.SendMessage($"โ—**NO LONGER LOGGING IN {ch.Mention} CHANNEL**โ—").ConfigureAwait(false); }); cgb.CreateCommand(Prefix + "logignore") - .Description($"Toggles whether the {Prefix}logserver command ignores this channel. Useful if you have hidden admin channel and public log channel.") + .Description($"Toggles whether the {Prefix}logserver command ignores this channel. Useful if you have hidden admin channel and public log channel. | `{Prefix}logignore`") .AddCheck(SimpleCheckers.OwnerOnly()) .AddCheck(SimpleCheckers.ManageServer()) .Do(async e => @@ -396,7 +431,7 @@ $@"๐Ÿ•”`{prettyCurrentTime}` **Message** ๐Ÿ“ `#{e.Channel.Name}` }); cgb.CreateCommand(Module.Prefix + "userpresence") - .Description("Starts logging to this channel when someone from the server goes online/offline/idle.") + .Description($"Starts logging to this channel when someone from the server goes online/offline/idle. | `{Prefix}userpresence`") .AddCheck(SimpleCheckers.ManageServer()) .Do(async e => { @@ -412,7 +447,7 @@ $@"๐Ÿ•”`{prettyCurrentTime}` **Message** ๐Ÿ“ `#{e.Channel.Name}` }); cgb.CreateCommand(Module.Prefix + "voicepresence") - .Description("Toggles logging to this channel whenever someone joins or leaves a voice channel you are in right now.") + .Description("Toggles logging to this channel whenever someone joins or leaves a voice channel you are in right now. | `{Prefix}voicerpresence`") .Parameter("all", ParameterType.Optional) .AddCheck(SimpleCheckers.ManageServer()) .Do(async e => diff --git a/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs b/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs index 4aa521a1..2ea4346d 100644 --- a/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs +++ b/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs @@ -57,7 +57,7 @@ namespace NadekoBot.Modules.Administration.Commands cgb.CreateCommand(Module.Prefix + "repeatinvoke") .Alias(Module.Prefix + "repinv") - .Description("Immediately shows the repeat message and restarts the timer.") + .Description($"Immediately shows the repeat message and restarts the timer. | `{Prefix}repinv`") .AddCheck(SimpleCheckers.ManageMessages()) .Do(async e => { @@ -73,7 +73,7 @@ namespace NadekoBot.Modules.Administration.Commands cgb.CreateCommand(Module.Prefix + "repeat") .Description("Repeat a message every X minutes. If no parameters are specified, " + - "repeat is disabled. Requires manage messages. |`.repeat 5 Hello there`") + $"repeat is disabled. Requires manage messages. |`{Prefix}repeat 5 Hello there`") .Parameter("minutes", ParameterType.Optional) .Parameter("msg", ParameterType.Unparsed) .AddCheck(SimpleCheckers.ManageMessages()) diff --git a/NadekoBot/Modules/Administration/Commands/PlayingRotate.cs b/NadekoBot/Modules/Administration/Commands/PlayingRotate.cs index 2d22d870..4978dbe3 100644 --- a/NadekoBot/Modules/Administration/Commands/PlayingRotate.cs +++ b/NadekoBot/Modules/Administration/Commands/PlayingRotate.cs @@ -96,14 +96,14 @@ namespace NadekoBot.Modules.Administration.Commands { cgb.CreateCommand(Module.Prefix + "rotateplaying") .Alias(Module.Prefix + "ropl") - .Description("Toggles rotation of playing status of the dynamic strings you specified earlier.") + .Description($"Toggles rotation of playing status of the dynamic strings you specified earlier. | `{Prefix}ropl`") .AddCheck(SimpleCheckers.OwnerOnly()) .Do(DoFunc()); cgb.CreateCommand(Module.Prefix + "addplaying") .Alias(Module.Prefix + "adpl") .Description("Adds a specified string to the list of playing strings to rotate. " + - "Supported placeholders: " + string.Join(", ", PlayingPlaceholders.Keys)) + "Supported placeholders: " + string.Join(", ", PlayingPlaceholders.Keys)+ $" | `{Prefix}adpl`") .Parameter("text", ParameterType.Unparsed) .AddCheck(SimpleCheckers.OwnerOnly()) .Do(async e => @@ -126,7 +126,7 @@ namespace NadekoBot.Modules.Administration.Commands cgb.CreateCommand(Module.Prefix + "listplaying") .Alias(Module.Prefix + "lipl") - .Description("Lists all playing statuses with their corresponding number.") + .Description($"Lists all playing statuses with their corresponding number. | `{Prefix}lipl`") .AddCheck(SimpleCheckers.OwnerOnly()) .Do(async e => { @@ -143,7 +143,7 @@ namespace NadekoBot.Modules.Administration.Commands cgb.CreateCommand(Module.Prefix + "removeplaying") .Alias(Module.Prefix + "repl", Module.Prefix + "rmpl") - .Description("Removes a playing string on a given number.") + .Description($"Removes a playing string on a given number. | `{Prefix}rmpl`") .Parameter("number", ParameterType.Required) .AddCheck(SimpleCheckers.OwnerOnly()) .Do(async e => diff --git a/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs b/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs index 22e0d695..c9efe84e 100644 --- a/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs +++ b/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs @@ -41,7 +41,7 @@ namespace NadekoBot.Modules.Administration.Commands internal override void Init(CommandGroupBuilder cgb) { cgb.CreateCommand(Module.Prefix + "slowmode") - .Description("Toggles slow mode. When ON, users will be able to send only 1 message every 5 seconds.") + .Description($"Toggles slow mode. When ON, users will be able to send only 1 message every 5 seconds. | `{Prefix}slowmode`") .AddCheck(SimpleCheckers.ManageMessages()) .Do(async e => { diff --git a/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs b/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs index 2ef54772..4386ab11 100644 --- a/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs +++ b/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs @@ -17,7 +17,7 @@ namespace NadekoBot.Modules.Administration.Commands { cgb.CreateCommand(Module.Prefix + "asar") .Description("Adds a role, or list of roles separated by whitespace" + - "(use quotations for multiword roles) to the list of self-assignable roles. | .asar Gamer") + $"(use quotations for multiword roles) to the list of self-assignable roles. | {Prefix}asar Gamer") .Parameter("roles", ParameterType.Multiple) .AddCheck(SimpleCheckers.CanManageRoles) .Do(async e => @@ -44,7 +44,7 @@ namespace NadekoBot.Modules.Administration.Commands }); cgb.CreateCommand(Module.Prefix + "rsar") - .Description("Removes a specified role from the list of self-assignable roles.") + .Description($"Removes a specified role from the list of self-assignable roles. | `{Prefix}rsar`") .Parameter("role", ParameterType.Unparsed) .AddCheck(SimpleCheckers.CanManageRoles) .Do(async e => @@ -69,14 +69,14 @@ namespace NadekoBot.Modules.Administration.Commands }); cgb.CreateCommand(Module.Prefix + "lsar") - .Description("Lists all self-assignable roles.") + .Description($"Lists all self-assignable roles. | `{Prefix}lsar`") .Parameter("roles", ParameterType.Multiple) .Do(async e => { var config = SpecificConfigurations.Default.Of(e.Server.Id); var msg = new StringBuilder($"There are `{config.ListOfSelfAssignableRoles.Count}` self assignable roles:\n"); var toRemove = new HashSet(); - foreach (var roleId in config.ListOfSelfAssignableRoles.OrderBy(r=>r.ToString())) + foreach (var roleId in config.ListOfSelfAssignableRoles.OrderBy(r => r.ToString())) { var role = e.Server.GetRole(roleId); if (role == null) @@ -98,8 +98,8 @@ namespace NadekoBot.Modules.Administration.Commands - cgb.CreateCommand(Module.Prefix + "togglexclsar").Alias(Module.Prefix +"tesar") - .Description("toggle whether the self-assigned roles should be exclusive") + cgb.CreateCommand(Module.Prefix + "togglexclsar").Alias(Module.Prefix + "tesar") + .Description($"toggle whether the self-assigned roles should be exclusive | `{Prefix}tesar`") .AddCheck(SimpleCheckers.CanManageRoles) .Do(async e => { @@ -112,7 +112,7 @@ namespace NadekoBot.Modules.Administration.Commands cgb.CreateCommand(Module.Prefix + "iam") .Description("Adds a role to you that you choose. " + "Role must be on a list of self-assignable roles." + - " | .iam Gamer") + $" | {Prefix}iam Gamer") .Parameter("role", ParameterType.Unparsed) .Do(async e => { @@ -146,12 +146,13 @@ namespace NadekoBot.Modules.Administration.Commands { await e.User.AddRoles(role).ConfigureAwait(false); } - catch(HttpException ex) when (ex.StatusCode == System.Net.HttpStatusCode.InternalServerError) + catch (HttpException ex) when (ex.StatusCode == System.Net.HttpStatusCode.InternalServerError) { } - catch (Exception) + catch (Exception ex) { await e.Channel.SendMessage($":anger:`I am unable to add that role to you. I can't add roles to owners or other roles higher than my role in the role hierarchy.`").ConfigureAwait(false); + return; } var msg = await e.Channel.SendMessage($":ok:You now have {role.Name} role.").ConfigureAwait(false); await Task.Delay(3000).ConfigureAwait(false); @@ -167,7 +168,7 @@ namespace NadekoBot.Modules.Administration.Commands .Alias(Module.Prefix + "iamn") .Description("Removes a role to you that you choose. " + "Role must be on a list of self-assignable roles." + - " | .iamn Gamer") + $" | {Prefix}iamn Gamer") .Parameter("role", ParameterType.Unparsed) .Do(async e => { diff --git a/NadekoBot/Modules/Administration/Commands/SelfCommands.cs b/NadekoBot/Modules/Administration/Commands/SelfCommands.cs index c3b5fad2..23322e07 100644 --- a/NadekoBot/Modules/Administration/Commands/SelfCommands.cs +++ b/NadekoBot/Modules/Administration/Commands/SelfCommands.cs @@ -14,7 +14,7 @@ namespace NadekoBot.Modules.Administration.Commands internal override void Init(CommandGroupBuilder cgb) { cgb.CreateCommand(Module.Prefix + "leave") - .Description("Makes Nadeko leave the server. Either name or id required. | `.leave 123123123331`") + .Description($"Makes Nadeko leave the server. Either name or id required. | `{Prefix}leave 123123123331`") .Parameter("arg", ParameterType.Required) .AddCheck(SimpleCheckers.OwnerOnly()) .Do(async e => diff --git a/NadekoBot/Modules/Administration/Commands/ServerGreetCommand.cs b/NadekoBot/Modules/Administration/Commands/ServerGreetCommand.cs index 54db0305..5281f9df 100644 --- a/NadekoBot/Modules/Administration/Commands/ServerGreetCommand.cs +++ b/NadekoBot/Modules/Administration/Commands/ServerGreetCommand.cs @@ -219,7 +219,7 @@ namespace NadekoBot.Modules.Administration.Commands internal override void Init(CommandGroupBuilder cgb) { cgb.CreateCommand(Module.Prefix + "grdel") - .Description("Toggles automatic deletion of greet and bye messages.") + .Description($"Toggles automatic deletion of greet and bye messages. | `{Prefix}grdel`") .Do(async e => { if (!e.User.ServerPermissions.ManageServer) return; @@ -232,7 +232,7 @@ namespace NadekoBot.Modules.Administration.Commands }); cgb.CreateCommand(Module.Prefix + "greet") - .Description("Toggles anouncements on the current channel when someone joins the server.") + .Description($"Toggles anouncements on the current channel when someone joins the server. | `{Prefix}greet`") .Do(async e => { if (!e.User.ServerPermissions.ManageServer) return; @@ -245,7 +245,7 @@ namespace NadekoBot.Modules.Administration.Commands }); cgb.CreateCommand(Module.Prefix + "greetmsg") - .Description("Sets a new join announcement message. Type %user% if you want to mention the new member. Using it with no message will show the current greet message. | .greetmsg Welcome to the server, %user%.") + .Description($"Sets a new join announcement message. Type %user% if you want to mention the new member. Using it with no message will show the current greet message. | `{Prefix}greetmsg Welcome to the server, %user%.`") .Parameter("msg", ParameterType.Unparsed) .Do(async e => { @@ -265,7 +265,7 @@ namespace NadekoBot.Modules.Administration.Commands }); cgb.CreateCommand(Module.Prefix + "bye") - .Description("Toggles anouncements on the current channel when someone leaves the server.") + .Description($"Toggles anouncements on the current channel when someone leaves the server. | `{Prefix}bye`") .Do(async e => { if (!e.User.ServerPermissions.ManageServer) return; @@ -278,7 +278,7 @@ namespace NadekoBot.Modules.Administration.Commands }); cgb.CreateCommand(Module.Prefix + "byemsg") - .Description("Sets a new leave announcement message. Type %user% if you want to mention the new member. Using it with no message will show the current bye message. | .byemsg %user% has left the server.") + .Description($"Sets a new leave announcement message. Type %user% if you want to mention the new member. Using it with no message will show the current bye message. | `{Prefix}byemsg %user% has left the server.`") .Parameter("msg", ParameterType.Unparsed) .Do(async e => { @@ -297,7 +297,7 @@ namespace NadekoBot.Modules.Administration.Commands }); cgb.CreateCommand(Module.Prefix + "byepm") - .Description("Toggles whether the good bye messages will be sent in a PM or in the text channel.") + .Description($"Toggles whether the good bye messages will be sent in a PM or in the text channel. | `{Prefix}byepm`") .Do(async e => { if (!e.User.ServerPermissions.ManageServer) return; @@ -313,7 +313,7 @@ namespace NadekoBot.Modules.Administration.Commands }); cgb.CreateCommand(Module.Prefix + "greetpm") - .Description("Toggles whether the greet messages will be sent in a PM or in the text channel.") + .Description($"Toggles whether the greet messages will be sent in a PM or in the text channel. | `{Prefix}greetpm`") .Do(async e => { if (!e.User.ServerPermissions.ManageServer) return; diff --git a/NadekoBot/Modules/Administration/Commands/VoiceNotificationCommand.cs b/NadekoBot/Modules/Administration/Commands/VoiceNotificationCommand.cs deleted file mode 100644 index ae63a7db..00000000 --- a/NadekoBot/Modules/Administration/Commands/VoiceNotificationCommand.cs +++ /dev/null @@ -1,46 +0,0 @@ -๏ปฟusing Discord; -using Discord.Commands; -using NadekoBot.Classes; -using System; -using System.Collections.Concurrent; -using System.Linq; -using System.Threading.Tasks; - -namespace NadekoBot.Modules.Administration.Commands -{ - internal class VoiceNotificationCommand : DiscordCommand - { - - //voicechannel/text channel - private readonly ConcurrentDictionary subscribers = new ConcurrentDictionary(); - - public Func DoFunc() => async e => - { - var arg = e.GetArg("voice_name"); - if (string.IsNullOrWhiteSpace("voice_name")) - return; - var voiceChannel = e.Server.FindChannels(arg, ChannelType.Voice).FirstOrDefault(); - if (voiceChannel == null) - return; - if (subscribers.ContainsKey(voiceChannel)) - { - await e.Channel.SendMessage("`Voice channel notifications disabled.`").ConfigureAwait(false); - return; - } - if (subscribers.TryAdd(voiceChannel, e.Channel)) - { - await e.Channel.SendMessage("`Voice channel notifications enabled.`").ConfigureAwait(false); - } - }; - - internal override void Init(CommandGroupBuilder cgb) - { - cgb.CreateCommand(Module.Prefix + "voicenotif") - .Description("Enables notifications on who joined/left the voice channel. |.voicenotif Karaoke club") - .Parameter("voice_name", ParameterType.Unparsed) - .Do(DoFunc()); - } - - public VoiceNotificationCommand(DiscordModule module) : base(module) { } - } -} diff --git a/NadekoBot/Modules/Administration/Commands/VoicePlusTextCommand.cs b/NadekoBot/Modules/Administration/Commands/VoicePlusTextCommand.cs index be6bae12..bf5e2a73 100644 --- a/NadekoBot/Modules/Administration/Commands/VoicePlusTextCommand.cs +++ b/NadekoBot/Modules/Administration/Commands/VoicePlusTextCommand.cs @@ -88,7 +88,7 @@ namespace NadekoBot.Modules.Administration.Commands { cgb.CreateCommand(Module.Prefix + "cleanv+t") .Alias(Module.Prefix + "cv+t") - .Description("Deletes all text channels ending in `-voice` for which voicechannels are not found. **Use at your own risk.**") + .Description($"Deletes all text channels ending in `-voice` for which voicechannels are not found. **Use at your own risk.** | `{Prefix}cleanv+t`") .AddCheck(SimpleCheckers.CanManageRoles) .AddCheck(SimpleCheckers.ManageChannels()) .Do(async e => @@ -120,7 +120,7 @@ namespace NadekoBot.Modules.Administration.Commands cgb.CreateCommand(Module.Prefix + "voice+text") .Alias(Module.Prefix + "v+t") .Description("Creates a text channel for each voice channel only users in that voice channel can see." + - "If you are server owner, keep in mind you will see them all the time regardless.") + $"If you are server owner, keep in mind you will see them all the time regardless. | `{Prefix}voice+text`") .AddCheck(SimpleCheckers.ManageChannels()) .AddCheck(SimpleCheckers.CanManageRoles) .Do(async e => diff --git a/NadekoBot/Modules/Conversations/Conversations.cs b/NadekoBot/Modules/Conversations/Conversations.cs index 7432803f..a3611d0e 100644 --- a/NadekoBot/Modules/Conversations/Conversations.cs +++ b/NadekoBot/Modules/Conversations/Conversations.cs @@ -8,7 +8,6 @@ using NadekoBot.Modules.Permissions.Classes; using System; using System.Diagnostics; using System.IO; -using System.Linq; using System.Text; using System.Threading.Tasks; @@ -42,7 +41,7 @@ namespace NadekoBot.Modules.Conversations if (string.IsNullOrWhiteSpace(text)) return; await Task.Run(() => - Classes.DbHandler.Instance.InsertData(new DataModels.UserQuote() + Classes.DbHandler.Instance.Connection.Insert(new DataModels.UserQuote() { DateAdded = DateTime.Now, Keyword = e.GetArg("keyword").ToLowerInvariant(), @@ -102,7 +101,7 @@ namespace NadekoBot.Modules.Conversations commands.ForEach(cmd => cmd.Init(cgb)); cgb.CreateCommand("die") - .Description("Works only for the owner. Shuts the bot down.") + .Description("Works only for the owner. Shuts the bot down. | `@NadekoBot die`") .Do(async e => { if (NadekoBot.IsOwner(e.User.Id)) @@ -119,7 +118,7 @@ namespace NadekoBot.Modules.Conversations randServerSw.Start(); cgb.CreateCommand("do you love me") - .Description("Replies with positive answer only to the bot owner.") + .Description("Replies with positive answer only to the bot owner. | `@NadekoBot do you love me`") .Do(async e => { if (NadekoBot.IsOwner(e.User.Id)) @@ -130,7 +129,7 @@ namespace NadekoBot.Modules.Conversations cgb.CreateCommand("how are you") .Alias("how are you?") - .Description("Replies positive only if bot owner is online.") + .Description("Replies positive only if bot owner is online. | `@NadekoBot how are you`") .Do(async e => { if (NadekoBot.IsOwner(e.User.Id)) @@ -150,7 +149,7 @@ namespace NadekoBot.Modules.Conversations }); cgb.CreateCommand("fire") - .Description("Shows a unicode fire message. Optional parameter [x] tells her how many times to repeat the fire. | @NadekoBot fire [x]") + .Description("Shows a unicode fire message. Optional parameter [x] tells her how many times to repeat the fire. | `@NadekoBot fire [x]`") .Parameter("times", ParameterType.Optional) .Do(async e => { @@ -174,7 +173,7 @@ namespace NadekoBot.Modules.Conversations }); cgb.CreateCommand("dump") - .Description("Dumps all of the invites it can to dump.txt.** Owner Only.**") + .Description("Dumps all of the invites it can to dump.txt.** Owner Only.** | `@NadekoBot dump`") .Do(async e => { if (!NadekoBot.IsOwner(e.User.Id)) return; @@ -201,7 +200,7 @@ namespace NadekoBot.Modules.Conversations }); cgb.CreateCommand("ab") - .Description("Try to get 'abalabahaha'") + .Description("Try to get 'abalabahaha'| `@NadekoBot ab`") .Do(async e => { string[] strings = { "ba", "la", "ha" }; diff --git a/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs b/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs index ae6c6819..a908128c 100644 --- a/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs +++ b/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs @@ -1,14 +1,13 @@ -๏ปฟusing NadekoBot.Classes; +๏ปฟusing Discord; +using Discord.Commands; +using NadekoBot.Classes; +using NadekoBot.Extensions; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Discord.Commands; -using System.Collections.Concurrent; -using Discord; -using NadekoBot.Extensions; using System.Threading; +using System.Threading.Tasks; namespace NadekoBot.Modules.Gambling.Commands { @@ -23,8 +22,9 @@ namespace NadekoBot.Modules.Gambling.Commands internal override void Init(CommandGroupBuilder cgb) { cgb.CreateCommand(Prefix + "race") - .Description("Starts a new animal race.") - .Do(e => { + .Description($"Starts a new animal race. | `{Prefix}race`") + .Do(e => + { var ar = new AnimalRace(e.Server.Id, e.Channel); if (ar.Fail) { @@ -35,9 +35,10 @@ namespace NadekoBot.Modules.Gambling.Commands cgb.CreateCommand(Prefix + "joinrace") .Alias(Prefix + "jr") - .Description("Joins a new race. You can specify an amount of flowers for betting (optional). You will get YourBet*(participants-1) back if you win. | `$jr` or `$jr 5`") + .Description($"Joins a new race. You can specify an amount of flowers for betting (optional). You will get YourBet*(participants-1) back if you win. | `{Prefix}jr` or `{Prefix}jr 5`") .Parameter("amount", ParameterType.Optional) - .Do(async e => { + .Do(async e => + { int amount; if (!int.TryParse(e.GetArg("amount"), out amount) || amount < 0) @@ -55,11 +56,13 @@ namespace NadekoBot.Modules.Gambling.Commands await FlowersHandler.RemoveFlowers(e.User, "BetRace", (int)amount, true).ConfigureAwait(false); AnimalRace ar; - if (!AnimalRaces.TryGetValue(e.Server.Id, out ar)) { + if (!AnimalRaces.TryGetValue(e.Server.Id, out ar)) + { await e.Channel.SendMessage("No race exists on this server"); + return; } await ar.JoinRace(e.User, amount); - + }); } @@ -93,7 +96,7 @@ namespace NadekoBot.Modules.Gambling.Commands { try { - await raceChannel.SendMessage($"๐Ÿ`Race is starting in 20 seconds or when the room is full. Type $jr to join the race.`"); + await raceChannel.SendMessage($"๐Ÿ`Race is starting in 20 seconds or when the room is full. Type {NadekoBot.Config.CommandPrefixes.Gambling}jr to join the race.`"); var t = await Task.WhenAny(Task.Delay(20000, token), fullgame); Started = true; cancelSource.Cancel(); @@ -103,7 +106,7 @@ namespace NadekoBot.Modules.Gambling.Commands } else if (participants.Count > 1) { - await raceChannel.SendMessage("๐Ÿ`Game starting with " + participants.Count + " praticipants.`"); + await raceChannel.SendMessage("๐Ÿ`Game starting with " + participants.Count + " participants.`"); } else { @@ -127,7 +130,8 @@ namespace NadekoBot.Modules.Gambling.Commands AnimalRaces.TryRemove(serverId, out throwaway); } - private async Task StartRace() { + private async Task StartRace() + { var rng = new Random(); Participant winner = null; Message msg = null; @@ -163,14 +167,14 @@ namespace NadekoBot.Modules.Gambling.Commands |๐Ÿ๐Ÿ๐Ÿ๐Ÿ๐Ÿ๐Ÿ๐Ÿ๐Ÿ๐Ÿ๐Ÿ๐Ÿ๐Ÿ๐Ÿ๐Ÿ๐Ÿ๐Ÿ”š|"; if (msg == null || messagesSinceGameStarted >= 10) // also resend the message if channel was spammed { - if(msg != null) + if (msg != null) try { await msg.Delete(); } catch { } msg = await raceChannel.SendMessage(text); messagesSinceGameStarted = 0; } else await msg.Edit(text); - + await Task.Delay(2500); } } @@ -199,10 +203,11 @@ namespace NadekoBot.Modules.Gambling.Commands messagesSinceGameStarted++; } - private async Task CheckForFullGameAsync(CancellationToken cancelToken) { + private async Task CheckForFullGameAsync(CancellationToken cancelToken) + { while (animals.Count > 0) { - await Task.Delay(100,cancelToken); + await Task.Delay(100, cancelToken); } } @@ -257,8 +262,8 @@ namespace NadekoBot.Modules.Gambling.Commands public override bool Equals(object obj) { var p = obj as Participant; - return p == null? - false: + return p == null ? + false : p.User == User; } @@ -279,7 +284,8 @@ namespace NadekoBot.Modules.Gambling.Commands { return str + "`3rd`"; } - else { + else + { return str + $"`{Place}th`"; } diff --git a/NadekoBot/Modules/Gambling/DiceRollCommand.cs b/NadekoBot/Modules/Gambling/DiceRollCommand.cs index 68a665fe..55bb5ee1 100644 --- a/NadekoBot/Modules/Gambling/DiceRollCommand.cs +++ b/NadekoBot/Modules/Gambling/DiceRollCommand.cs @@ -21,18 +21,18 @@ namespace NadekoBot.Modules.Gambling { cgb.CreateCommand(Module.Prefix + "roll") .Description("Rolls 0-100. If you supply a number [x] it rolls up to 30 normal dice." + - " If you split 2 numbers with letter d (xdy) it will roll x dice from 1 to y. | $roll or $roll 7 or $roll 3d5") + $" If you split 2 numbers with letter d (xdy) it will roll x dice from 1 to y. | `{Prefix}roll` or `{Prefix}roll 7` or `{Prefix}roll 3d5`") .Parameter("num", ParameterType.Optional) .Do(RollFunc()); cgb.CreateCommand(Module.Prefix + "rolluo") .Description("Rolls 0-100. If you supply a number [x] it rolls up to 30 normal dice (unordered)." + - " If you split 2 numbers with letter d (xdy) it will roll x dice from 1 to y. | $roll or $roll 7 or $roll 3d5") + $" If you split 2 numbers with letter d (xdy) it will roll x dice from 1 to y. | `{Prefix}roll` or `{Prefix}roll` 7 or `{Prefix}roll 3d5`") .Parameter("num", ParameterType.Optional) .Do(RollFunc(false)); cgb.CreateCommand(Module.Prefix + "nroll") - .Description("Rolls in a given range. | `$nroll 5` (rolls 0-5) or `$nroll 5-15`") + .Description($"Rolls in a given range. | `{Prefix}nroll 5` (rolls 0-5) or `{Prefix}nroll 5-15`") .Parameter("range", ParameterType.Required) .Do(NRollFunc()); } diff --git a/NadekoBot/Modules/Gambling/DrawCommand.cs b/NadekoBot/Modules/Gambling/DrawCommand.cs index 35d789bf..dbd023e1 100644 --- a/NadekoBot/Modules/Gambling/DrawCommand.cs +++ b/NadekoBot/Modules/Gambling/DrawCommand.cs @@ -17,13 +17,13 @@ namespace NadekoBot.Modules.Gambling internal override void Init(CommandGroupBuilder cgb) { cgb.CreateCommand(Module.Prefix + "draw") - .Description("Draws a card from the deck.If you supply number [x], she draws up to 5 cards from the deck. | $draw [x]") + .Description($"Draws a card from the deck.If you supply number [x], she draws up to 5 cards from the deck. | `{Prefix}draw [x]`") .Parameter("count", ParameterType.Optional) .Do(DrawCardFunc()); cgb.CreateCommand(Module.Prefix + "shuffle") .Alias(Module.Prefix + "sh") - .Description("Reshuffles all cards back into the deck.") + .Description($"Reshuffles all cards back into the deck.|`{Prefix}shuffle`") .Do(ReshuffleTask()); } diff --git a/NadekoBot/Modules/Gambling/FlipCoinCommand.cs b/NadekoBot/Modules/Gambling/FlipCoinCommand.cs index 6d8edf3c..d0b79919 100644 --- a/NadekoBot/Modules/Gambling/FlipCoinCommand.cs +++ b/NadekoBot/Modules/Gambling/FlipCoinCommand.cs @@ -15,7 +15,7 @@ namespace NadekoBot.Modules.Gambling internal override void Init(CommandGroupBuilder cgb) { cgb.CreateCommand(Module.Prefix + "flip") - .Description("Flips coin(s) - heads or tails, and shows an image. | `$flip` or `$flip 3`") + .Description($"Flips coin(s) - heads or tails, and shows an image. | `{Prefix}flip` or `{Prefix}flip 3`") .Parameter("count", ParameterType.Optional) .Do(FlipCoinFunc()); diff --git a/NadekoBot/Modules/Gambling/GamblingModule.cs b/NadekoBot/Modules/Gambling/GamblingModule.cs index 2b1ddc15..efa3a553 100644 --- a/NadekoBot/Modules/Gambling/GamblingModule.cs +++ b/NadekoBot/Modules/Gambling/GamblingModule.cs @@ -33,7 +33,7 @@ namespace NadekoBot.Modules.Gambling commands.ForEach(com => com.Init(cgb)); cgb.CreateCommand(Prefix + "raffle") - .Description($"Prints a name and ID of a random user from the online list from the (optional) role. | `{Prefix}raffle` or `{Prefix}raffle RoleName") + .Description($"Prints a name and ID of a random user from the online list from the (optional) role. | `{Prefix}raffle` or `{Prefix}raffle RoleName`") .Parameter("role", ParameterType.Optional) .Do(async e => { @@ -63,7 +63,7 @@ namespace NadekoBot.Modules.Gambling }); cgb.CreateCommand(Prefix + "give") - .Description(string.Format("Give someone a certain amount of {0}s", NadekoBot.Config.CurrencyName)) + .Description(string.Format("Give someone a certain amount of {0}s", NadekoBot.Config.CurrencyName)+ $"|`{Prefix}give 1 \"@SomeGuy\"`") .Parameter("amount", ParameterType.Required) .Parameter("receiver", ParameterType.Unparsed) .Do(async e => @@ -140,7 +140,7 @@ namespace NadekoBot.Modules.Gambling cgb.CreateCommand(Prefix + "betroll") .Alias(Prefix + "br") - .Description($"Bets a certain amount of {NadekoBot.Config.CurrencyName}s and rolls a dice. Rolling over 66 yields x2 flowers, over 90 - x3 and 100 x10. | {Prefix}br 5") + .Description($"Bets a certain amount of {NadekoBot.Config.CurrencyName}s and rolls a dice. Rolling over 66 yields x2 flowers, over 90 - x3 and 100 x10. | `{Prefix}br 5`") .Parameter("amount",ParameterType.Required) .Do(async e => { @@ -187,6 +187,7 @@ namespace NadekoBot.Modules.Gambling cgb.CreateCommand(Prefix + "leaderboard") .Alias(Prefix + "lb") + .Description($"Displays bot currency leaderboard | {Prefix}lb") .Do(async e => { var richestTemp = DbHandler.Instance.GetTopRichest(); diff --git a/NadekoBot/Modules/Games/Commands/BetrayGame.cs b/NadekoBot/Modules/Games/Commands/BetrayGame.cs index 0bf410b5..74b98bf6 100644 --- a/NadekoBot/Modules/Games/Commands/BetrayGame.cs +++ b/NadekoBot/Modules/Games/Commands/BetrayGame.cs @@ -20,7 +20,7 @@ namespace NadekoBot.Modules.Games.Commands cgb.CreateCommand(Module.Prefix + "betray") .Description("BETRAY GAME. Betray nadeko next turn." + "If Nadeko cooperates - you get extra points, nadeko loses a LOT." + - "If Nadeko betrays - you both lose some points.") + $"If Nadeko betrays - you both lose some points. | `{Prefix}betray`") .Do(async e => { await ReceiveAnswer(e, Answers.Betray).ConfigureAwait(false); @@ -29,7 +29,7 @@ namespace NadekoBot.Modules.Games.Commands cgb.CreateCommand(Module.Prefix + "cooperate") .Description("BETRAY GAME. Cooperate with nadeko next turn." + "If Nadeko cooperates - you both get bonus points." + - "If Nadeko betrays - you lose A LOT, nadeko gets extra.") + $"If Nadeko betrays - you lose A LOT, nadeko gets extra. | `{Prefix}cooperater`") .Do(async e => { diff --git a/NadekoBot/Modules/Games/Commands/Leet.cs b/NadekoBot/Modules/Games/Commands/Leet.cs index 22cdedbf..e71a80d0 100644 --- a/NadekoBot/Modules/Games/Commands/Leet.cs +++ b/NadekoBot/Modules/Games/Commands/Leet.cs @@ -1,5 +1,6 @@ ๏ปฟusing Discord.Commands; using NadekoBot.Classes; +using NadekoBot.Extensions; using System.Text; //taken from @@ -291,13 +292,13 @@ namespace NadekoBot.Modules.Games.Commands } #endregion } - return sb.ToString(); // Return result. + return sb.ToString().TrimTo(1995); // Return result. } internal override void Init(CommandGroupBuilder cgb) { cgb.CreateCommand(Module.Prefix + "leet") - .Description($"Converts a text to leetspeak with 6 (1-6) severity levels | {Module.Prefix}leet 3 Hello") + .Description($"Converts a text to leetspeak with 6 (1-6) severity levels | `{Module.Prefix}leet 3 Hello`") .Parameter("level", ParameterType.Required) .Parameter("text", ParameterType.Unparsed) .Do(async e => diff --git a/NadekoBot/Modules/Games/Commands/PlantPick.cs b/NadekoBot/Modules/Games/Commands/PlantPick.cs index d2882eb2..2752ad1f 100644 --- a/NadekoBot/Modules/Games/Commands/PlantPick.cs +++ b/NadekoBot/Modules/Games/Commands/PlantPick.cs @@ -65,7 +65,7 @@ namespace NadekoBot.Modules.Games.Commands internal override void Init(CommandGroupBuilder cgb) { cgb.CreateCommand(Module.Prefix + "pick") - .Description("Picks a flower planted in this channel.") + .Description($"Picks a flower planted in this channel. | `{Prefix}pick`") .Do(async e => { IEnumerable msgs; @@ -91,7 +91,7 @@ namespace NadekoBot.Modules.Games.Commands }); cgb.CreateCommand(Module.Prefix + "plant") - .Description("Spend a flower to plant it in this channel. (If bot is restarted or crashes, flower will be lost)") + .Description($"Spend a flower to plant it in this channel. (If bot is restarted or crashes, flower will be lost) | `{Prefix}plant`") .Do(async e => { await locker.WaitAsync().ConfigureAwait(false); @@ -124,7 +124,7 @@ namespace NadekoBot.Modules.Games.Commands cgb.CreateCommand(Prefix + "gencurrency") .Alias(Prefix + "gc") - .Description($"Toggles currency generation on this channel. Every posted message will have 2% chance to spawn a {NadekoBot.Config.CurrencyName}. Optional parameter cooldown time in minutes, 5 minutes by default. Requires Manage Messages permission. | `>gc` or `>gc 60`") + .Description($"Toggles currency generation on this channel. Every posted message will have 2% chance to spawn a {NadekoBot.Config.CurrencyName}. Optional parameter cooldown time in minutes, 5 minutes by default. Requires Manage Messages permission. | `{Prefix}gc` or `{Prefix}gc 60`") .AddCheck(SimpleCheckers.ManageMessages()) .Parameter("cd", ParameterType.Unparsed) .Do(async e => diff --git a/NadekoBot/Modules/Games/Commands/PollCommand.cs b/NadekoBot/Modules/Games/Commands/PollCommand.cs index 0e1bb81c..785d5c5f 100644 --- a/NadekoBot/Modules/Games/Commands/PollCommand.cs +++ b/NadekoBot/Modules/Games/Commands/PollCommand.cs @@ -18,7 +18,7 @@ namespace NadekoBot.Modules.Games.Commands internal override void Init(CommandGroupBuilder cgb) { cgb.CreateCommand(Module.Prefix + "poll") - .Description("Creates a poll, only person who has manage server permission can do it. | >poll Question?;Answer1;Answ 2;A_3") + .Description($"Creates a poll, only person who has manage server permission can do it. | `{Prefix}poll Question?;Answer1;Answ 2;A_3`") .Parameter("allargs", ParameterType.Unparsed) .Do(async e => { @@ -43,7 +43,7 @@ namespace NadekoBot.Modules.Games.Commands }).ConfigureAwait(false); }); cgb.CreateCommand(Module.Prefix + "pollend") - .Description("Stops active poll on this server and prints the results in this channel.") + .Description($"Stops active poll on this server and prints the results in this channel. | `{Prefix}pollend`") .Do(async e => { if (!e.User.ServerPermissions.ManageChannels) diff --git a/NadekoBot/Modules/Games/Commands/SpeedTyping.cs b/NadekoBot/Modules/Games/Commands/SpeedTyping.cs index c224de1d..07100820 100644 --- a/NadekoBot/Modules/Games/Commands/SpeedTyping.cs +++ b/NadekoBot/Modules/Games/Commands/SpeedTyping.cs @@ -168,21 +168,21 @@ namespace NadekoBot.Modules.Games.Commands internal override void Init(CommandGroupBuilder cgb) { cgb.CreateCommand(Module.Prefix + "typestart") - .Description("Starts a typing contest.") + .Description($"Starts a typing contest. | `{Prefix}typestart`") .Do(DoFunc()); cgb.CreateCommand(Module.Prefix + "typestop") - .Description("Stops a typing contest on the current channel.") + .Description($"Stops a typing contest on the current channel. | `{Prefix}typestop`") .Do(QuitFunc()); cgb.CreateCommand(Module.Prefix + "typeadd") - .Description("Adds a new article to the typing contest. Owner only.") + .Description($"Adds a new article to the typing contest. Owner only. | `{Prefix}typeadd wordswords`") .Parameter("text", ParameterType.Unparsed) .Do(async e => { if (!NadekoBot.IsOwner(e.User.Id) || string.IsNullOrWhiteSpace(e.GetArg("text"))) return; - DbHandler.Instance.InsertData(new TypingArticle + DbHandler.Instance.Connection.Insert(new TypingArticle { Text = e.GetArg("text"), DateAdded = DateTime.Now diff --git a/NadekoBot/Modules/Games/Commands/TriviaCommand.cs b/NadekoBot/Modules/Games/Commands/TriviaCommand.cs index 1873c254..75481309 100644 --- a/NadekoBot/Modules/Games/Commands/TriviaCommand.cs +++ b/NadekoBot/Modules/Games/Commands/TriviaCommand.cs @@ -46,7 +46,7 @@ namespace NadekoBot.Modules.Games.Commands }); cgb.CreateCommand(Module.Prefix + "tl") - .Description("Shows a current trivia leaderboard.") + .Description($"Shows a current trivia leaderboard. | `{Prefix}tl`") .Do(async e => { TriviaGame trivia; @@ -57,7 +57,7 @@ namespace NadekoBot.Modules.Games.Commands }); cgb.CreateCommand(Module.Prefix + "tq") - .Description("Quits current trivia after current question.") + .Description($"Quits current trivia after current question. | `{Prefix}tq`") .Do(async e => { TriviaGame trivia; diff --git a/NadekoBot/Modules/Games/GamesModule.cs b/NadekoBot/Modules/Games/GamesModule.cs index 2e222054..acdaf1b3 100644 --- a/NadekoBot/Modules/Games/GamesModule.cs +++ b/NadekoBot/Modules/Games/GamesModule.cs @@ -60,7 +60,7 @@ namespace NadekoBot.Modules.Games try { await e.Channel.SendMessage( - $":question: **Question**: `{question}` \n๐ŸŽฑ **8Ball Answers**: `{NadekoBot.Config._8BallResponses[rng.Next(0, NadekoBot.Config._8BallResponses.Length)]}`") + $":question: `Question` __**{question}**__ \n๐ŸŽฑ `8Ball Answers` __**{NadekoBot.Config._8BallResponses[rng.Next(0, NadekoBot.Config._8BallResponses.Length)]}**__") .ConfigureAwait(false); } catch { } diff --git a/NadekoBot/Modules/Help/Commands/HelpCommand.cs b/NadekoBot/Modules/Help/Commands/HelpCommand.cs index 4d3fa441..d0ba292b 100644 --- a/NadekoBot/Modules/Help/Commands/HelpCommand.cs +++ b/NadekoBot/Modules/Help/Commands/HelpCommand.cs @@ -31,7 +31,7 @@ namespace NadekoBot.Classes.Help.Commands if (alias != null) str = $" / `{ com.Aliases.FirstOrDefault()}`"; if (com != null) - await e.Channel.SendMessage($@"**__Help for:__ `{com.Text}`**" + str + $"\n**Desc:** {new Regex(@"\|").Replace(com.Description, "\n**Usage:**",1)}").ConfigureAwait(false); + await e.Channel.SendMessage($@"**__Help for:__ `{com.Text}`**" + str + $"\n**Desc:** {new Regex(@"\|").Replace(com.Description, "\n**Usage:**", 1)}").ConfigureAwait(false); }).ConfigureAwait(false); }; public static string HelpString { @@ -48,11 +48,11 @@ namespace NadekoBot.Classes.Help.Commands public Action 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` +$@"######For more information and how to setup your own NadekoBot, go to: +######You can donate on patreon: +######or paypal: `nadekodiscordbot@gmail.com` -#NadekoBot List Of Commands -Version: `{NadekoStats.Instance.BotVersion}`"; +#NadekoBot List Of Commands "; string lastCategory = ""; @@ -80,16 +80,16 @@ Version: `{NadekoStats.Instance.BotVersion}`"; { 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. | '-h !m q' or just '-h' ") + .Description($"Either shows a help for a single command, or PMs you help link if no arguments are specified. | `{Prefix}h !m q` or just `{Prefix}h` ") .Parameter("command", ParameterType.Unparsed) .Do(HelpFunc()); cgb.CreateCommand(Module.Prefix + "hgit") - .Description("Generates the commandlist.md file. **Bot Owner Only!**") + .Description($"Generates the commandlist.md file. **Bot Owner Only!** | `{Prefix}hgit`") .AddCheck(SimpleCheckers.OwnerOnly()) .Do(DoGitFunc()); cgb.CreateCommand(Module.Prefix + "readme") .Alias(Module.Prefix + "guide") - .Description("Sends a readme and a guide links to the channel.") + .Description($"Sends a readme and a guide links to the channel. | `{Prefix}readme` or `{Prefix}guide`") .Do(async e => await e.Channel.SendMessage( @"**Wiki with all info**: @@ -102,16 +102,15 @@ Version: `{NadekoStats.Instance.BotVersion}`"; cgb.CreateCommand(Module.Prefix + "donate") .Alias("~donate") - .Description("Instructions for helping the project!") + .Description($"Instructions for helping the project! | `{Prefix}donate` or `~donate`") .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. +$@"You can support the project on patreon. or +You can send donations to `nadekodiscordbot@gmail.com` +Don't forget to leave your discord name or id in the message. -*If you want to support in some other way or on a different platform, please message me*" - ).ConfigureAwait(false); +**Thank you** โ™ฅ๏ธ").ConfigureAwait(false); }); } diff --git a/NadekoBot/Modules/Help/HelpModule.cs b/NadekoBot/Modules/Help/HelpModule.cs index 20e8279c..45e4dc76 100644 --- a/NadekoBot/Modules/Help/HelpModule.cs +++ b/NadekoBot/Modules/Help/HelpModule.cs @@ -29,7 +29,7 @@ namespace NadekoBot.Modules.Help cgb.CreateCommand(Prefix + "modules") .Alias(".modules") - .Description("List all bot modules.") + .Description($"List all bot modules. | `{Prefix}modules` or `.modules`") .Do(async e => { await e.Channel.SendMessage("`List of modules:` \nโ€ข " + string.Join("\nโ€ข ", NadekoBot.Client.GetService().Modules.Select(m => m.Name)) + $"\n`Type \"{Prefix}commands module_name\" to get a list of commands in that module.`") @@ -38,7 +38,7 @@ namespace NadekoBot.Modules.Help cgb.CreateCommand(Prefix + "commands") .Alias(".commands") - .Description("List all of the bot's commands from a certain module.") + .Description($"List all of the bot's commands from a certain module. | `{Prefix}commands` or `.commands`") .Parameter("module", ParameterType.Unparsed) .Do(async e => { diff --git a/NadekoBot/Modules/Music/Classes/MusicControls.cs b/NadekoBot/Modules/Music/Classes/MusicControls.cs index 847070eb..e13239cf 100644 --- a/NadekoBot/Modules/Music/Classes/MusicControls.cs +++ b/NadekoBot/Modules/Music/Classes/MusicControls.cs @@ -34,7 +34,7 @@ namespace NadekoBot.Modules.Music.Classes public IReadOnlyCollection Playlist => playlist; public Song CurrentSong { get; private set; } - private CancellationTokenSource SongCancelSource { get; set; } + public CancellationTokenSource SongCancelSource { get; private set; } private CancellationToken cancelToken { get; set; } public bool Paused { get; set; } diff --git a/NadekoBot/Modules/Music/Classes/Song.cs b/NadekoBot/Modules/Music/Classes/Song.cs index 08be13b8..d235776a 100644 --- a/NadekoBot/Modules/Music/Classes/Song.cs +++ b/NadekoBot/Modules/Music/Classes/Song.cs @@ -32,7 +32,6 @@ namespace NadekoBot.Modules.Music.Classes public SongInfo SongInfo { get; } public string QueuerName { get; set; } - private bool bufferingCompleted { get; set; } = false; public MusicPlayer MusicPlayer { get; set; } public string PrettyCurrentTime() @@ -73,78 +72,22 @@ namespace NadekoBot.Modules.Music.Classes return this; } - private Task BufferSong(string filename, CancellationToken cancelToken) => - Task.Factory.StartNew(async () => - { - Process p = null; - try - { - p = Process.Start(new ProcessStartInfo - { - FileName = "ffmpeg", - Arguments = $"-ss {skipTo} -i {SongInfo.Uri} -f s16le -ar 48000 -ac 2 pipe:1 -loglevel quiet", - UseShellExecute = false, - RedirectStandardOutput = true, - RedirectStandardError = false, - CreateNoWindow = true, - }); - var prebufferSize = 100ul.MiB(); - using (var outStream = new FileStream(filename, FileMode.Append, FileAccess.Write, FileShare.Read)) - { - byte[] buffer = new byte[81920]; - int bytesRead; - while ((bytesRead = await p.StandardOutput.BaseStream.ReadAsync(buffer, 0, buffer.Length, cancelToken).ConfigureAwait(false)) != 0) - { - await outStream.WriteAsync(buffer, 0, bytesRead, cancelToken).ConfigureAwait(false); - while ((ulong)outStream.Length - bytesSent > prebufferSize) - await Task.Delay(100, cancelToken); - } - } - - bufferingCompleted = true; - } - catch (System.ComponentModel.Win32Exception) { - var oldclr = Console.ForegroundColor; - Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine(@"You have not properly installed or configured FFMPEG. -Please install and configure FFMPEG to play music. -Check the guides for your platform on how to setup ffmpeg correctly: - Windows Guide: https://goo.gl/SCv72y - Linux Guide: https://goo.gl/rRhjCp"); - Console.ForegroundColor = oldclr; - } - catch (Exception ex) - { - Console.WriteLine($"Buffering stopped: {ex.Message}"); - } - finally - { - Console.WriteLine($"Buffering done."); - if (p != null) - { - try - { - p.Kill(); - } - catch { } - p.Dispose(); - } - } - }, TaskCreationOptions.LongRunning); - internal async Task Play(IAudioClient voiceClient, CancellationToken cancelToken) { var filename = Path.Combine(MusicModule.MusicDataPath, DateTime.Now.UnixTimestamp().ToString()); - var bufferTask = BufferSong(filename, cancelToken).ConfigureAwait(false); + SongBuffer sb = new SongBuffer(filename, SongInfo, skipTo); + var bufferTask = sb.BufferSong(cancelToken).ConfigureAwait(false); - var inStream = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Read, FileShare.Write); + var inStream = new FileStream(sb.GetNextFile(), FileMode.OpenOrCreate, FileAccess.Read, FileShare.Write); ; bytesSent = 0; try { - var prebufferingTask = CheckPrebufferingAsync(inStream, cancelToken); + var attempt = 0; + + var prebufferingTask = CheckPrebufferingAsync(inStream, sb, cancelToken); var sw = new Stopwatch(); sw.Start(); var t = await Task.WhenAny(prebufferingTask, Task.Delay(5000, cancelToken)); @@ -162,7 +105,6 @@ Check the guides for your platform on how to setup ffmpeg correctly: Console.WriteLine("Prebuffering successfully completed in "+ sw.Elapsed); const int blockSize = 3840; - var attempt = 0; byte[] buffer = new byte[blockSize]; while (!cancelToken.IsCancellationRequested) { @@ -173,14 +115,31 @@ Check the guides for your platform on how to setup ffmpeg correctly: { bytesSent += (ulong)read; } - if (read == 0) - if (attempt++ == 20) + if (read < blockSize) + { + if (sb.IsNextFileReady()) { - voiceClient.Wait(); - break; + inStream.Dispose(); + inStream = new FileStream(sb.GetNextFile(), FileMode.Open, FileAccess.Read, FileShare.Write); + read += inStream.Read(buffer, read, buffer.Length - read); + attempt = 0; + } + if (read == 0) + { + if (sb.BufferingCompleted) + break; + if (attempt++ == 20) + { + voiceClient.Wait(); + MusicPlayer.SongCancelSource.Cancel(); + break; + } + else + await Task.Delay(100, cancelToken).ConfigureAwait(false); } else - await Task.Delay(100, cancelToken).ConfigureAwait(false); + attempt = 0; + } else attempt = 0; @@ -195,14 +154,16 @@ Check the guides for your platform on how to setup ffmpeg correctly: { await bufferTask; await Task.Run(() => voiceClient.Clear()); - inStream.Dispose(); - try { File.Delete(filename); } catch { } + if(inStream != null) + inStream.Dispose(); + Console.WriteLine("l"); + sb.CleanFiles(); } } - private async Task CheckPrebufferingAsync(Stream inStream, CancellationToken cancelToken) + private async Task CheckPrebufferingAsync(Stream inStream, SongBuffer sb, CancellationToken cancelToken) { - while (!bufferingCompleted && inStream.Length < 2.MiB()) + while (!sb.BufferingCompleted && inStream.Length < 2.MiB()) { await Task.Delay(100, cancelToken); } diff --git a/NadekoBot/Modules/Music/Classes/SongBuffer.cs b/NadekoBot/Modules/Music/Classes/SongBuffer.cs new file mode 100644 index 00000000..d9192940 --- /dev/null +++ b/NadekoBot/Modules/Music/Classes/SongBuffer.cs @@ -0,0 +1,159 @@ +๏ปฟusing NadekoBot.Extensions; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace NadekoBot.Modules.Music.Classes +{ + /// + /// Create a buffer for a song file. It will create multiples files to ensure, that radio don't fill up disk space. + /// It also help for large music by deleting files that are already seen. + /// + class SongBuffer + { + + public SongBuffer(string basename, SongInfo songInfo, int skipTo) + { + Basename = basename; + SongInfo = songInfo; + SkipTo = skipTo; + } + + private string Basename; + + private SongInfo SongInfo; + + private int SkipTo; + + private static int MAX_FILE_SIZE = 20.MiB(); + + private long FileNumber = -1; + + private long NextFileToRead = 0; + + public bool BufferingCompleted { get; private set;} = false; + + private ulong CurrentBufferSize = 0; + + public Task BufferSong(CancellationToken cancelToken) => + Task.Factory.StartNew(async () => + { + Process p = null; + FileStream outStream = null; + try + { + p = Process.Start(new ProcessStartInfo + { + FileName = "ffmpeg", + Arguments = $"-ss {SkipTo} -i {SongInfo.Uri} -f s16le -ar 48000 -ac 2 pipe:1 -loglevel quiet", + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = false, + CreateNoWindow = true, + }); + + byte[] buffer = new byte[81920]; + int currentFileSize = 0; + ulong prebufferSize = 100ul.MiB(); + + outStream = new FileStream(Basename + "-" + ++FileNumber, FileMode.Append, FileAccess.Write, FileShare.Read); + while (!p.HasExited) //Also fix low bandwidth + { + int bytesRead = await p.StandardOutput.BaseStream.ReadAsync(buffer, 0, buffer.Length, cancelToken).ConfigureAwait(false); + if (currentFileSize >= MAX_FILE_SIZE) + { + try + { + outStream.Dispose(); + }catch { } + outStream = new FileStream(Basename + "-" + ++FileNumber, FileMode.Append, FileAccess.Write, FileShare.Read); + currentFileSize = bytesRead; + } + else + { + currentFileSize += bytesRead; + } + CurrentBufferSize += Convert.ToUInt64(bytesRead); + await outStream.WriteAsync(buffer, 0, bytesRead, cancelToken).ConfigureAwait(false); + while (CurrentBufferSize > prebufferSize) + await Task.Delay(100, cancelToken); + } + BufferingCompleted = true; + } + catch (System.ComponentModel.Win32Exception) + { + var oldclr = Console.ForegroundColor; + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine(@"You have not properly installed or configured FFMPEG. +Please install and configure FFMPEG to play music. +Check the guides for your platform on how to setup ffmpeg correctly: + Windows Guide: https://goo.gl/SCv72y + Linux Guide: https://goo.gl/rRhjCp"); + Console.ForegroundColor = oldclr; + } + catch (Exception ex) + { + Console.WriteLine($"Buffering stopped: {ex.Message}"); + } + finally + { + if(outStream != null) + outStream.Dispose(); + Console.WriteLine($"Buffering done."); + if (p != null) + { + try + { + p.Kill(); + } + catch { } + p.Dispose(); + } + } + }, TaskCreationOptions.LongRunning); + + /// + /// Return the next file to read, and delete the old one + /// + /// Name of the file to read + public string GetNextFile() + { + string filename = Basename + "-" + NextFileToRead; + + if (NextFileToRead != 0) + { + try + { + CurrentBufferSize -= Convert.ToUInt64(new FileInfo(Basename + "-" + (NextFileToRead - 1)).Length); + File.Delete(Basename + "-" + (NextFileToRead - 1)); + } + catch { } + } + NextFileToRead++; + return filename; + } + + public bool IsNextFileReady() + { + return NextFileToRead <= FileNumber; + } + + public void CleanFiles() + { + for (long i = NextFileToRead - 1 ; i <= FileNumber; i++) + { + try + { + File.Delete(Basename + "-" + i); + } + catch { } + } + } + } +} diff --git a/NadekoBot/Modules/Music/MusicModule.cs b/NadekoBot/Modules/Music/MusicModule.cs index e5c03915..eaf290ba 100644 --- a/NadekoBot/Modules/Music/MusicModule.cs +++ b/NadekoBot/Modules/Music/MusicModule.cs @@ -614,11 +614,11 @@ namespace NadekoBot.Modules.Music }; DbHandler.Instance.SaveAll(songInfos); DbHandler.Instance.Save(playlist); - DbHandler.Instance.InsertMany(songInfos.Select(s => new PlaylistSongInfo + DbHandler.Instance.Connection.InsertAll(songInfos.Select(s => new PlaylistSongInfo { PlaylistId = playlist.Id.Value, SongInfoId = s.Id.Value - })); + }), typeof(PlaylistSongInfo)); await e.Channel.SendMessage($"๐ŸŽต `Saved playlist as {name}-{playlist.Id}`").ConfigureAwait(false); @@ -718,7 +718,7 @@ namespace NadekoBot.Modules.Music }); cgb.CreateCommand(Prefix + "goto") - .Description($"Goes to a specific time in seconds in a song. | {Prefix}goto 30") + .Description($"Goes to a specific time in seconds in a song. | `{Prefix}goto 30`") .Parameter("time") .Do(async e => { @@ -756,16 +756,37 @@ namespace NadekoBot.Modules.Music cgb.CreateCommand(Prefix + "getlink") .Alias(Prefix + "gl") - .Description("Shows a link to the currently playing song.") + .Description("Shows a link to the song in the queue by index, or the currently playing song by default.") + .Parameter("index", ParameterType.Optional) .Do(async e => { MusicPlayer musicPlayer; if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer)) return; - var curSong = musicPlayer.CurrentSong; - if (curSong == null) - return; - await e.Channel.SendMessage($"๐ŸŽถ`Current song:` <{curSong.SongInfo.Query}>").ConfigureAwait(false); + int index; + string arg = e.GetArg("index")?.Trim(); + if (!string.IsNullOrEmpty(arg) && int.TryParse(arg, out index)) + { + + var selSong = musicPlayer.Playlist.DefaultIfEmpty(null).ElementAtOrDefault(index - 1); + if (selSong == null) + { + await e.Channel.SendMessage("Could not select song, likely wrong index"); + + } + else + { + await e.Channel.SendMessage($"๐ŸŽถ`Selected song {selSong.SongInfo.Title}:` <{selSong.SongInfo.Query}>").ConfigureAwait(false); + } + } + else + { + var curSong = musicPlayer.CurrentSong; + if (curSong == null) + return; + await e.Channel.SendMessage($"๐ŸŽถ`Current song:` <{curSong.SongInfo.Query}>").ConfigureAwait(false); + } + }); cgb.CreateCommand(Prefix + "autoplay") @@ -818,7 +839,7 @@ namespace NadekoBot.Modules.Music lastFinishedMessage = await textCh.SendMessage($"๐ŸŽต`Finished`{song.PrettyName}").ConfigureAwait(false); if (mp.Autoplay && mp.Playlist.Count == 0 && song.SongInfo.Provider == "YouTube") { - await QueueSong(queuer, textCh, voiceCh, await SearchHelper.GetRelatedVideoId(song.SongInfo.Query), silent, musicType).ConfigureAwait(false); + await QueueSong(queuer.Server.CurrentUser, textCh, voiceCh, (await SearchHelper.GetRelatedVideoIds(song.SongInfo.Query, 4)).ToList().Shuffle().FirstOrDefault(), silent, musicType).ConfigureAwait(false); } } catch (Exception e) diff --git a/NadekoBot/Modules/NSFW/NSFWModule.cs b/NadekoBot/Modules/NSFW/NSFWModule.cs index a94ab572..ac688fb7 100644 --- a/NadekoBot/Modules/NSFW/NSFWModule.cs +++ b/NadekoBot/Modules/NSFW/NSFWModule.cs @@ -4,6 +4,8 @@ using NadekoBot.Classes; using NadekoBot.Modules.Permissions.Classes; using Newtonsoft.Json.Linq; using System; +using System.Linq; +using System.Threading.Tasks; namespace NadekoBot.Modules.NSFW { @@ -27,16 +29,16 @@ namespace NadekoBot.Modules.NSFW .Do(async e => { var tag = e.GetArg("tag")?.Trim() ?? ""; - var gel = await SearchHelper.GetGelbooruImageLink("rating%3Aexplicit+" + tag).ConfigureAwait(false); - if (gel != null) - await e.Channel.SendMessage(":heart: Gelbooru: " + gel) - .ConfigureAwait(false); - var dan = await SearchHelper.GetDanbooruImageLink("rating%3Aexplicit+" + tag).ConfigureAwait(false); - if (dan != null) - await e.Channel.SendMessage(":heart: Danbooru: " + dan) - .ConfigureAwait(false); - if (dan == null && gel == null) + + var links = await Task.WhenAll(SearchHelper.GetGelbooruImageLink("rating%3Aexplicit+" + tag), SearchHelper.GetDanbooruImageLink("rating%3Aexplicit+" + tag)).ConfigureAwait(false); + + if (links.All(l => l == null)) + { await e.Channel.SendMessage("`No results.`"); + return; + } + + await e.Channel.SendMessage(String.Join("\n\n", links)).ConfigureAwait(false); }); cgb.CreateCommand(Prefix + "danbooru") .Description($"Shows a random hentai image from danbooru with a given tag. Tag is optional but preffered. (multiple tags are appended with +) | `{Prefix}danbooru yuri+kissing`") @@ -84,14 +86,14 @@ namespace NadekoBot.Modules.NSFW await e.Channel.SendMessage(await SearchHelper.GetE621ImageLink(tag).ConfigureAwait(false)).ConfigureAwait(false); }); cgb.CreateCommand(Prefix + "cp") - .Description("We all know where this will lead you to.") + .Description($"We all know where this will lead you to. | `{Prefix}cp`") .Parameter("anything", ParameterType.Unparsed) .Do(async e => { await e.Channel.SendMessage("http://i.imgur.com/MZkY1md.jpg").ConfigureAwait(false); }); cgb.CreateCommand(Prefix + "boobs") - .Description("Real adult content.") + .Description($"Real adult content. | `{Prefix}boobs`") .Do(async e => { try @@ -106,7 +108,7 @@ namespace NadekoBot.Modules.NSFW }); cgb.CreateCommand(Prefix + "butts") .Alias(Prefix + "ass", Prefix + "butt") - .Description("Real adult content.") + .Description($"Real adult content. | `{Prefix}butts` or `{Prefix}ass`") .Do(async e => { try diff --git a/NadekoBot/Modules/Permissions/Commands/FilterInvitesCommand.cs b/NadekoBot/Modules/Permissions/Commands/FilterInvitesCommand.cs index f65902c6..d26a9aca 100644 --- a/NadekoBot/Modules/Permissions/Commands/FilterInvitesCommand.cs +++ b/NadekoBot/Modules/Permissions/Commands/FilterInvitesCommand.cs @@ -55,7 +55,7 @@ namespace NadekoBot.Modules.Permissions.Commands .Alias(Module.Prefix + "cfi") .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." + - " | ;cfi enable #general-chat") + $" | {Prefix}cfi enable #general-chat") .Parameter("bool") .Parameter("channel", ParameterType.Optional) .Do(async e => @@ -95,7 +95,7 @@ namespace NadekoBot.Modules.Permissions.Commands cgb.CreateCommand(Module.Prefix + "srvrfilterinv") .Alias(Module.Prefix + "sfi") - .Description("Enables or disables automatic deleting of invites on the server. | ;sfi disable") + .Description($"Enables or disables automatic deleting of invites on the server. | {Prefix}sfi disable") .Parameter("bool") .Do(async e => { diff --git a/NadekoBot/Modules/Permissions/Commands/FilterWordsCommand.cs b/NadekoBot/Modules/Permissions/Commands/FilterWordsCommand.cs index c187d398..33fd1ac4 100644 --- a/NadekoBot/Modules/Permissions/Commands/FilterWordsCommand.cs +++ b/NadekoBot/Modules/Permissions/Commands/FilterWordsCommand.cs @@ -53,7 +53,7 @@ namespace NadekoBot.Modules.Permissions.Commands .Alias(Module.Prefix + "cfw") .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." + - " | ;cfw enable #general-chat") + $" | {Prefix}cfw enable #general-chat") .Parameter("bool") .Parameter("channel", ParameterType.Optional) .Do(async e => @@ -89,7 +89,7 @@ namespace NadekoBot.Modules.Permissions.Commands cgb.CreateCommand(Module.Prefix + "addfilterword") .Alias(Module.Prefix + "afw") .Description("Adds a new word to the list of filtered words" + - " | ;afw poop") + $" | {Prefix}afw poop") .Parameter("word", ParameterType.Unparsed) .Do(async e => { @@ -111,7 +111,7 @@ namespace NadekoBot.Modules.Permissions.Commands cgb.CreateCommand(Module.Prefix + "rmvfilterword") .Alias(Module.Prefix + "rfw") .Description("Removes the word from the list of filtered words" + - " | ;rw poop") + $" | {Prefix}rw poop") .Parameter("word", ParameterType.Unparsed) .Do(async e => { @@ -133,7 +133,7 @@ namespace NadekoBot.Modules.Permissions.Commands cgb.CreateCommand(Module.Prefix + "lstfilterwords") .Alias(Module.Prefix + "lfw") .Description("Shows a list of filtered words" + - " | ;lfw") + $" | {Prefix}lfw") .Do(async e => { try @@ -152,7 +152,7 @@ namespace NadekoBot.Modules.Permissions.Commands cgb.CreateCommand(Module.Prefix + "srvrfilterwords") .Alias(Module.Prefix + "sfw") - .Description("Enables or disables automatic deleting of messages containing forbidden words on the server. | ;sfw disable") + .Description($"Enables or disables automatic deleting of messages containing forbidden words on the server. | {Prefix}sfw disable") .Parameter("bool") .Do(async e => { diff --git a/NadekoBot/Modules/Permissions/PermissionsModule.cs b/NadekoBot/Modules/Permissions/PermissionsModule.cs index c547bfe5..a201f848 100644 --- a/NadekoBot/Modules/Permissions/PermissionsModule.cs +++ b/NadekoBot/Modules/Permissions/PermissionsModule.cs @@ -33,7 +33,7 @@ namespace NadekoBot.Modules.Permissions cgb.CreateCommand(Prefix + "permrole") .Alias(Prefix + "pr") - .Description("Sets a role which can change permissions. Or supply no parameters to find out the current one. Default one is 'Nadeko'.") + .Description($"Sets a role which can change permissions. Or supply no parameters to find out the current one. Default one is 'Nadeko'. | `{Prefix}pr role`") .Parameter("role", ParameterType.Unparsed) .Do(async e => { @@ -158,7 +158,7 @@ namespace NadekoBot.Modules.Permissions cgb.CreateCommand(Prefix + "srvrperms") .Alias(Prefix + "sp") - .Description("Shows banned permissions for this server.") + .Description($"Shows banned permissions for this server. | `{Prefix}sp`") .Do(async e => { var perms = PermissionsHandler.GetServerPermissions(e.Server); diff --git a/NadekoBot/Modules/Pokemon/PokemonModule.cs b/NadekoBot/Modules/Pokemon/PokemonModule.cs index ae3ae0d9..d494fffa 100644 --- a/NadekoBot/Modules/Pokemon/PokemonModule.cs +++ b/NadekoBot/Modules/Pokemon/PokemonModule.cs @@ -196,7 +196,7 @@ namespace NadekoBot.Modules.Pokemon cgb.CreateCommand(Prefix + "movelist") .Alias(Prefix + "ml") - .Description("Lists the moves you are able to use") + .Description($"Lists the moves you are able to use | `{Prefix}ml`") .Do(async e => { var userType = GetPokeType(e.User.Id); @@ -210,7 +210,7 @@ namespace NadekoBot.Modules.Pokemon }); cgb.CreateCommand(Prefix + "heal") - .Description($"Heals someone. Revives those who fainted. Costs a {NadekoBot.Config.CurrencyName} | {Prefix}heal @someone") + .Description($"Heals someone. Revives those who fainted. Costs a {NadekoBot.Config.CurrencyName} | `{Prefix}heal @someone`") .Parameter("target", ParameterType.Unparsed) .Do(async e => { @@ -263,7 +263,7 @@ namespace NadekoBot.Modules.Pokemon }); cgb.CreateCommand(Prefix + "type") - .Description($"Get the poketype of the target. | {Prefix}type @someone") + .Description($"Get the poketype of the target. | `{Prefix}type @someone`") .Parameter("target", ParameterType.Unparsed) .Do(async e => { @@ -282,7 +282,7 @@ namespace NadekoBot.Modules.Pokemon }); cgb.CreateCommand(Prefix + "settype") - .Description($"Set your poketype. Costs a {NadekoBot.Config.CurrencyName}. | {Prefix}settype fire") + .Description($"Set your poketype. Costs a {NadekoBot.Config.CurrencyName}. | `{Prefix}settype fire`") .Parameter("targetType", ParameterType.Unparsed) .Do(async e => { @@ -319,11 +319,11 @@ namespace NadekoBot.Modules.Pokemon DbHandler.Instance.Delete(Dict[(long)e.User.Id]); } - DbHandler.Instance.InsertData(new UserPokeTypes + DbHandler.Instance.Connection.Insert(new UserPokeTypes { UserId = (long)e.User.Id, type = targetType.Name - }); + }, typeof(UserPokeTypes)); //Now for the response diff --git a/NadekoBot/Modules/Searches/Commands/ConverterCommand.cs b/NadekoBot/Modules/Searches/Commands/ConverterCommand.cs index 2383e718..ada8709a 100644 --- a/NadekoBot/Modules/Searches/Commands/ConverterCommand.cs +++ b/NadekoBot/Modules/Searches/Commands/ConverterCommand.cs @@ -32,7 +32,7 @@ namespace NadekoBot.Modules.Searches.Commands internal override void Init(CommandGroupBuilder cgb) { cgb.CreateCommand(Module.Prefix + "convert") - .Description("Convert quantities from>to. Like `~convert m>km 1000`") + .Description($"Convert quantities from>to. | `{Prefix}convert m>km 1000`") .Parameter("from-to", ParameterType.Required) .Parameter("quantity", ParameterType.Optional) .Do(ConvertFunc()); diff --git a/NadekoBot/Modules/Searches/Commands/EvalCommand.cs b/NadekoBot/Modules/Searches/Commands/EvalCommand.cs index ed469517..0d0108e0 100644 --- a/NadekoBot/Modules/Searches/Commands/EvalCommand.cs +++ b/NadekoBot/Modules/Searches/Commands/EvalCommand.cs @@ -17,7 +17,7 @@ namespace NadekoBot.Modules.Searches.Commands { cgb.CreateCommand(Module.Prefix + "calculate") .Alias(Module.Prefix + "calc") - .Description("Evaluate a mathematical expression. | ~calc 1+1") + .Description($"Evaluate a mathematical expression. | {Prefix}calc 1+1") .Parameter("expression", ParameterType.Unparsed) .Do(EvalFunc()); } diff --git a/NadekoBot/Modules/Searches/Commands/LoLCommands.cs b/NadekoBot/Modules/Searches/Commands/LoLCommands.cs index 8826beaf..5a5b766a 100644 --- a/NadekoBot/Modules/Searches/Commands/LoLCommands.cs +++ b/NadekoBot/Modules/Searches/Commands/LoLCommands.cs @@ -72,7 +72,7 @@ namespace NadekoBot.Modules.Searches.Commands internal override void Init(CommandGroupBuilder cgb) { cgb.CreateCommand(Module.Prefix + "lolchamp") - .Description("Shows League Of Legends champion statistics. If there are spaces/apostrophes or in the name - omit them. Optional second parameter is a role. |~lolchamp Riven or ~lolchamp Annie sup") + .Description($"Shows League Of Legends champion statistics. If there are spaces/apostrophes or in the name - omit them. Optional second parameter is a role. |`{Prefix}lolchamp Riven` or `{Prefix}lolchamp Annie sup`") .Parameter("champ", ParameterType.Required) .Parameter("position", ParameterType.Unparsed) .Do(async e => @@ -280,7 +280,7 @@ Assists: {general["assists"]} Ban: {general["banRate"]}% }); cgb.CreateCommand(Module.Prefix + "lolban") - .Description("Shows top 6 banned champions ordered by ban rate. Ban these champions and you will be Plat 5 in no time.") + .Description($"Shows top 6 banned champions ordered by ban rate. Ban these champions and you will be Plat 5 in no time. | `{Prefix}lolban`") .Do(async e => { diff --git a/NadekoBot/Modules/Searches/Commands/MemegenCommands.cs b/NadekoBot/Modules/Searches/Commands/MemegenCommands.cs index 5eff7c78..a7d23181 100644 --- a/NadekoBot/Modules/Searches/Commands/MemegenCommands.cs +++ b/NadekoBot/Modules/Searches/Commands/MemegenCommands.cs @@ -17,7 +17,7 @@ namespace NadekoBot.Modules.Searches.Commands internal override void Init(CommandGroupBuilder cgb) { cgb.CreateCommand(Prefix + "memelist") - .Description("Pulls a list of memes you can use with `~memegen` from http://memegen.link/templates/") + .Description($"Pulls a list of memes you can use with `~memegen` from http://memegen.link/templates/ | `{Prefix}memelist`") .Do(async e => { int i = 0; @@ -30,7 +30,7 @@ namespace NadekoBot.Modules.Searches.Commands }); cgb.CreateCommand(Prefix + "memegen") - .Description("Generates a meme from memelist with top and bottom text. | `~memegen biw \"gets iced coffee\" \"in the winter\"`") + .Description($"Generates a meme from memelist with top and bottom text. | `{Prefix}memegen biw \"gets iced coffee\" \"in the winter\"`") .Parameter("meme", ParameterType.Required) .Parameter("toptext", ParameterType.Required) .Parameter("bottext", ParameterType.Required) diff --git a/NadekoBot/Modules/Searches/Commands/OsuCommands.cs b/NadekoBot/Modules/Searches/Commands/OsuCommands.cs index 451e9a13..bda99f48 100644 --- a/NadekoBot/Modules/Searches/Commands/OsuCommands.cs +++ b/NadekoBot/Modules/Searches/Commands/OsuCommands.cs @@ -17,7 +17,7 @@ namespace NadekoBot.Modules.Searches.Commands internal override void Init(CommandGroupBuilder cgb) { cgb.CreateCommand(Module.Prefix + "osu") - .Description("Shows osu stats for a player. | `~osu Name` or `~osu Name taiko`") + .Description($"Shows osu stats for a player. | `{Prefix}osu Name` or `{Prefix}osu Name taiko`") .Parameter("usr", ParameterType.Required) .Parameter("mode", ParameterType.Unparsed) .Do(async e => @@ -56,7 +56,7 @@ namespace NadekoBot.Modules.Searches.Commands }); cgb.CreateCommand(Module.Prefix + "osu b") - .Description("Shows information about an osu beatmap. |~osu b https://osu.ppy.sh/s/127712") + .Description($"Shows information about an osu beatmap. |`{Prefix}osu b` https://osu.ppy.sh/s/127712`") .Parameter("map", ParameterType.Unparsed) .Do(async e => { @@ -88,7 +88,7 @@ namespace NadekoBot.Modules.Searches.Commands }); cgb.CreateCommand(Module.Prefix + "osu top5") - .Description("Displays a user's top 5 plays. |~osu top5 Name") + .Description($"Displays a user's top 5 plays. |{Prefix}osu top5 Name") .Parameter("usr", ParameterType.Required) .Parameter("mode", ParameterType.Unparsed) .Do(async e => diff --git a/NadekoBot/Modules/Searches/Commands/PokemonSearchCommands.cs b/NadekoBot/Modules/Searches/Commands/PokemonSearchCommands.cs index a171abe9..b2c13dca 100644 --- a/NadekoBot/Modules/Searches/Commands/PokemonSearchCommands.cs +++ b/NadekoBot/Modules/Searches/Commands/PokemonSearchCommands.cs @@ -22,7 +22,7 @@ namespace NadekoBot.Modules.Searches.Commands { cgb.CreateCommand(Prefix + "pokemon") .Alias(Prefix + "poke") - .Description("Searches for a pokemon.") + .Description($"Searches for a pokemon. | `{Prefix}poke Sylveon`") .Parameter("pokemon", ParameterType.Unparsed) .Do(async e => { @@ -43,7 +43,7 @@ namespace NadekoBot.Modules.Searches.Commands cgb.CreateCommand(Prefix + "pokemonability") .Alias(Prefix + "pokeab") - .Description("Searches for a pokemon ability.") + .Description($"Searches for a pokemon ability. | `{Prefix}pokeab \"water gun\"`") .Parameter("abil", ParameterType.Unparsed) .Do(async e => { diff --git a/NadekoBot/Modules/Searches/Commands/StreamNotifications.cs b/NadekoBot/Modules/Searches/Commands/StreamNotifications.cs index efe521ff..f8720324 100644 --- a/NadekoBot/Modules/Searches/Commands/StreamNotifications.cs +++ b/NadekoBot/Modules/Searches/Commands/StreamNotifications.cs @@ -122,7 +122,7 @@ namespace NadekoBot.Modules.Searches.Commands cgb.CreateCommand(Module.Prefix + "hitbox") .Alias(Module.Prefix + "hb") .Description("Notifies this channel when a certain user starts streaming." + - " | ~hitbox SomeStreamer") + $" | `{Prefix}hitbox SomeStreamer`") .Parameter("username", ParameterType.Unparsed) .AddCheck(SimpleCheckers.ManageServer()) .Do(TrackStream(StreamNotificationConfig.StreamType.Hitbox)); @@ -130,7 +130,7 @@ namespace NadekoBot.Modules.Searches.Commands cgb.CreateCommand(Module.Prefix + "twitch") .Alias(Module.Prefix + "tw") .Description("Notifies this channel when a certain user starts streaming." + - " | ~twitch SomeStreamer") + $" | `{Prefix}twitch SomeStreamer`") .AddCheck(SimpleCheckers.ManageServer()) .Parameter("username", ParameterType.Unparsed) .Do(TrackStream(StreamNotificationConfig.StreamType.Twitch)); @@ -138,7 +138,7 @@ namespace NadekoBot.Modules.Searches.Commands cgb.CreateCommand(Module.Prefix + "beam") .Alias(Module.Prefix + "bm") .Description("Notifies this channel when a certain user starts streaming." + - " | ~beam SomeStreamer") + $" | `{Prefix}beam SomeStreamer`") .AddCheck(SimpleCheckers.ManageServer()) .Parameter("username", ParameterType.Unparsed) .Do(TrackStream(StreamNotificationConfig.StreamType.Beam)); @@ -146,7 +146,7 @@ namespace NadekoBot.Modules.Searches.Commands cgb.CreateCommand(Module.Prefix + "checkhitbox") .Alias(Module.Prefix + "chhb") .Description("Checks if a certain user is streaming on the hitbox platform." + - " | ~chhb SomeStreamer") + $" | `{Prefix}chhb SomeStreamer`") .Parameter("username", ParameterType.Unparsed) .AddCheck(SimpleCheckers.ManageServer()) .Do(async e => @@ -175,7 +175,7 @@ namespace NadekoBot.Modules.Searches.Commands cgb.CreateCommand(Module.Prefix + "checktwitch") .Alias(Module.Prefix + "chtw") .Description("Checks if a certain user is streaming on the twitch platform." + - " | ~chtw SomeStreamer") + $" | `{Prefix}chtw SomeStreamer`") .AddCheck(SimpleCheckers.ManageServer()) .Parameter("username", ParameterType.Unparsed) .Do(async e => @@ -204,7 +204,7 @@ namespace NadekoBot.Modules.Searches.Commands cgb.CreateCommand(Module.Prefix + "checkbeam") .Alias(Module.Prefix + "chbm") .Description("Checks if a certain user is streaming on the beam platform." + - " | ~chbm SomeStreamer") + $" | `{Prefix}chbm SomeStreamer`") .AddCheck(SimpleCheckers.ManageServer()) .Parameter("username", ParameterType.Unparsed) .Do(async e => @@ -233,7 +233,7 @@ namespace NadekoBot.Modules.Searches.Commands cgb.CreateCommand(Module.Prefix + "removestream") .Alias(Module.Prefix + "rms") .Description("Removes notifications of a certain streamer on this channel." + - " | ~rms SomeGuy") + $" | `{Prefix}rms SomeGuy`") .AddCheck(SimpleCheckers.ManageServer()) .Parameter("username", ParameterType.Unparsed) .Do(async e => @@ -261,7 +261,7 @@ namespace NadekoBot.Modules.Searches.Commands cgb.CreateCommand(Module.Prefix + "liststreams") .Alias(Module.Prefix + "ls") .Description("Lists all streams you are following on this server." + - " | ~ls") + $" | `{Prefix}ls`") .Do(async e => { diff --git a/NadekoBot/Modules/Searches/Commands/WowJokes.cs b/NadekoBot/Modules/Searches/Commands/WowJokes.cs index da2f99ae..b3e67eed 100644 --- a/NadekoBot/Modules/Searches/Commands/WowJokes.cs +++ b/NadekoBot/Modules/Searches/Commands/WowJokes.cs @@ -22,7 +22,7 @@ namespace NadekoBot.Modules.Searches.Commands { cgb.CreateCommand(Module.Prefix + "wowjoke") - .Description("Get one of Kwoth's penultimate WoW jokes.") + .Description($"Get one of Kwoth's penultimate WoW jokes. | `{Prefix}wowjoke`") .Do(async e => { if (!jokes.Any()) diff --git a/NadekoBot/Modules/Searches/SearchesModule.cs b/NadekoBot/Modules/Searches/SearchesModule.cs index 45b50c33..84d0c0a1 100644 --- a/NadekoBot/Modules/Searches/SearchesModule.cs +++ b/NadekoBot/Modules/Searches/SearchesModule.cs @@ -86,7 +86,7 @@ $@"๐ŸŒ **Weather for** ใ€{obj["target"]}ใ€‘ cgb.CreateCommand(Prefix + "ani") .Alias(Prefix + "anime", Prefix + "aq") .Parameter("query", ParameterType.Unparsed) - .Description("Queries anilist for an anime and shows the first result.") + .Description($"Queries anilist for an anime and shows the first result. | `{Prefix}aq aquerion evol`") .Do(async e => { if (!(await SearchHelper.ValidateQuery(e.Channel, e.GetArg("query")).ConfigureAwait(false))) return; @@ -341,7 +341,7 @@ $@"๐ŸŒ **Weather for** ใ€{obj["target"]}ใ€‘ }); cgb.CreateCommand(Prefix + "quote") - .Description("Shows a random quote.") + .Description($"Shows a random quote. | `{Prefix}quote`") .Do(async e => { var quote = NadekoBot.Config.Quotes[rng.Next(0, NadekoBot.Config.Quotes.Count)].ToString(); @@ -349,7 +349,7 @@ $@"๐ŸŒ **Weather for** ใ€{obj["target"]}ใ€‘ }); cgb.CreateCommand(Prefix + "catfact") - .Description("Shows a random catfact from ") + .Description($"Shows a random catfact from | `{Prefix}catfact`") .Do(async e => { var response = await SearchHelper.GetResponseStringAsync("http://catfacts-api.appspot.com/api/facts").ConfigureAwait(false); @@ -360,7 +360,7 @@ $@"๐ŸŒ **Weather for** ใ€{obj["target"]}ใ€‘ cgb.CreateCommand(Prefix + "yomama") .Alias(Prefix + "ym") - .Description("Shows a random joke from ") + .Description($"Shows a random joke from | `{Prefix}ym`") .Do(async e => { var response = await SearchHelper.GetResponseStringAsync("http://api.yomomma.info/").ConfigureAwait(false); @@ -369,7 +369,7 @@ $@"๐ŸŒ **Weather for** ใ€{obj["target"]}ใ€‘ cgb.CreateCommand(Prefix + "randjoke") .Alias(Prefix + "rj") - .Description("Shows a random joke from ") + .Description($"Shows a random joke from | `{Prefix}rj`") .Do(async e => { var response = await SearchHelper.GetResponseStringAsync("http://tambal.azurewebsites.net/joke/random").ConfigureAwait(false); @@ -378,7 +378,7 @@ $@"๐ŸŒ **Weather for** ใ€{obj["target"]}ใ€‘ cgb.CreateCommand(Prefix + "chucknorris") .Alias(Prefix + "cn") - .Description("Shows a random chucknorris joke from ") + .Description($"Shows a random chucknorris joke from | `{Prefix}cn`") .Do(async e => { var response = await SearchHelper.GetResponseStringAsync("http://api.icndb.com/jokes/random/").ConfigureAwait(false); @@ -387,7 +387,7 @@ $@"๐ŸŒ **Weather for** ใ€{obj["target"]}ใ€‘ cgb.CreateCommand(Prefix + "magicitem") .Alias(Prefix + "mi") - .Description("Shows a random magicitem from ") + .Description($"Shows a random magicitem from | `{Prefix}mi`") .Do(async e => { var magicItems = JsonConvert.DeserializeObject>(File.ReadAllText("data/magicitems.json")); @@ -397,7 +397,7 @@ $@"๐ŸŒ **Weather for** ใ€{obj["target"]}ใ€‘ }); cgb.CreateCommand(Prefix + "revav") - .Description($"Returns a google reverse image search for someone's avatar. | `{Prefix}revav \"@SomeGuy\"") + .Description($"Returns a google reverse image search for someone's avatar. | `{Prefix}revav \"@SomeGuy\"`") .Parameter("user", ParameterType.Unparsed) .Do(async e => { diff --git a/NadekoBot/Modules/Translator/ValidLanguagesCommand.cs b/NadekoBot/Modules/Translator/ValidLanguagesCommand.cs index ede25f13..438e77de 100644 --- a/NadekoBot/Modules/Translator/ValidLanguagesCommand.cs +++ b/NadekoBot/Modules/Translator/ValidLanguagesCommand.cs @@ -13,7 +13,7 @@ namespace NadekoBot.Modules.Translator internal override void Init(CommandGroupBuilder cgb) { cgb.CreateCommand(Module.Prefix + "translangs") - .Description("List the valid languages for translation.") + .Description($"List the valid languages for translation. | `{Prefix}translangs` or `{Prefix}translangs language`") .Parameter("search", ParameterType.Optional) .Do(ListLanguagesFunc()); } diff --git a/NadekoBot/Modules/Trello/TrelloModule.cs b/NadekoBot/Modules/Trello/TrelloModule.cs index b144a2cf..14938aca 100644 --- a/NadekoBot/Modules/Trello/TrelloModule.cs +++ b/NadekoBot/Modules/Trello/TrelloModule.cs @@ -92,7 +92,7 @@ namespace NadekoBot.Modules.Trello }); cgb.CreateCommand(Prefix + "unbind") - .Description("Unbinds a bot from the channel and board.") + .Description($"Unbinds a bot from the channel and board. | `{Prefix}unbind`") .Do(async e => { if (!NadekoBot.IsOwner(e.User.Id)) return; @@ -106,7 +106,7 @@ namespace NadekoBot.Modules.Trello cgb.CreateCommand(Prefix + "lists") .Alias(Prefix + "list") - .Description("Lists all lists yo ;)") + .Description($"Lists all lists yo ;) | {Prefix}list") .Do(async e => { if (!NadekoBot.IsOwner(e.User.Id)) return; diff --git a/NadekoBot/Modules/Utility/Commands/InfoCommands.cs b/NadekoBot/Modules/Utility/Commands/InfoCommands.cs index 7d14a16f..da1bcd0c 100644 --- a/NadekoBot/Modules/Utility/Commands/InfoCommands.cs +++ b/NadekoBot/Modules/Utility/Commands/InfoCommands.cs @@ -18,7 +18,7 @@ namespace NadekoBot.Modules.Utility.Commands { cgb.CreateCommand(Module.Prefix + "serverinfo") .Alias(Module.Prefix + "sinfo") - .Description($"Shows info about the server the bot is on. If no channel is supplied, it defaults to current one. |{Module.Prefix}sinfo Some Server") + .Description($"Shows info about the server the bot is on. If no channel is supplied, it defaults to current one. |`{Module.Prefix}sinfo Some Server`") .Parameter("server", ParameterType.Optional) .Do(async e => { @@ -49,7 +49,7 @@ namespace NadekoBot.Modules.Utility.Commands cgb.CreateCommand(Module.Prefix + "channelinfo") .Alias(Module.Prefix + "cinfo") - .Description($"Shows info about the channel. If no channel is supplied, it defaults to current one. |{Module.Prefix}cinfo #some-channel") + .Description($"Shows info about the channel. If no channel is supplied, it defaults to current one. |`{Module.Prefix}cinfo #some-channel`") .Parameter("channel", ParameterType.Optional) .Do(async e => { @@ -71,7 +71,7 @@ namespace NadekoBot.Modules.Utility.Commands cgb.CreateCommand(Module.Prefix + "userinfo") .Alias(Module.Prefix + "uinfo") - .Description($"Shows info about the user. If no user is supplied, it defaults a user running the command. |{Module.Prefix}uinfo @SomeUser") + .Description($"Shows info about the user. If no user is supplied, it defaults a user running the command. |`{Module.Prefix}uinfo @SomeUser`") .Parameter("user", ParameterType.Optional) .Do(async e => { diff --git a/NadekoBot/Modules/Utility/Commands/Remind.cs b/NadekoBot/Modules/Utility/Commands/Remind.cs index dabd4158..808f4b11 100644 --- a/NadekoBot/Modules/Utility/Commands/Remind.cs +++ b/NadekoBot/Modules/Utility/Commands/Remind.cs @@ -88,7 +88,7 @@ namespace NadekoBot.Modules.Utility.Commands .Description("Sends a message to you or a channel after certain amount of time. " + "First argument is me/here/'channelname'. Second argument is time in a descending order (mo>w>d>h>m) example: 1w5d3h10m. " + "Third argument is a (multiword)message. " + - " | `.remind me 1d5h Do something` or `.remind #general Start now!`") + $" | `{Prefix}remind me 1d5h Do something` or `{Prefix}remind #general Start now!`") .Parameter("meorchannel", ParameterType.Required) .Parameter("time", ParameterType.Required) .Parameter("message", ParameterType.Unparsed) @@ -171,7 +171,7 @@ namespace NadekoBot.Modules.Utility.Commands UserId = (long)e.User.Id, ServerId = (long)e.Server.Id }; - DbHandler.Instance.InsertData(rem); + DbHandler.Instance.Connection.Insert(rem); reminders.Add(StartNewReminder(rem)); @@ -180,7 +180,7 @@ namespace NadekoBot.Modules.Utility.Commands cgb.CreateCommand(Module.Prefix + "remindmsg") .Description("Sets message for when the remind is triggered. " + " Available placeholders are %user% - user who ran the command, %message% -" + - " Message specified in the remind, %target% - target channel of the remind. **Bot Owner Only!**") + $" Message specified in the remind, %target% - target channel of the remind. **Bot Owner Only!** | `{Prefix}remindmsg do something else`") .Parameter("msg", ParameterType.Unparsed) .AddCheck(SimpleCheckers.OwnerOnly()) .Do(async e => diff --git a/NadekoBot/Modules/Utility/UtilityModule.cs b/NadekoBot/Modules/Utility/UtilityModule.cs index bd172c08..6fd8db53 100644 --- a/NadekoBot/Modules/Utility/UtilityModule.cs +++ b/NadekoBot/Modules/Utility/UtilityModule.cs @@ -87,7 +87,7 @@ namespace NadekoBot.Modules.Utility }); cgb.CreateCommand(Prefix + "checkmyperms") - .Description("Checks your userspecific permissions on this channel.") + .Description($"Checks your userspecific permissions on this channel. | `{Prefix}checkmyperms`") .Do(async e => { var output = "```\n"; @@ -100,21 +100,21 @@ namespace NadekoBot.Modules.Utility }); cgb.CreateCommand(Prefix + "stats") - .Description("Shows some basic stats for Nadeko.") + .Description($"Shows some basic stats for Nadeko. | `{Prefix}stats`") .Do(async e => { await e.Channel.SendMessage(await NadekoStats.Instance.GetStats()).ConfigureAwait(false); }); cgb.CreateCommand(Prefix + "dysyd") - .Description("Shows some basic stats for Nadeko.") + .Description($"Shows some basic stats for Nadeko. | `{Prefix}dysyd`") .Do(async e => { await e.Channel.SendMessage((await NadekoStats.Instance.GetStats()).Matrix().TrimTo(1990)).ConfigureAwait(false); }); cgb.CreateCommand(Prefix + "userid").Alias(Prefix + "uid") - .Description($"Shows user ID. | `{Prefix}uid` or `{Prefix}uid \"@SomeGuy\"") + .Description($"Shows user ID. | `{Prefix}uid` or `{Prefix}uid \"@SomeGuy\"`") .Parameter("user", ParameterType.Unparsed) .Do(async e => { diff --git a/NadekoBot/NadekoBot.cs b/NadekoBot/NadekoBot.cs index ad68beca..a1299d97 100644 --- a/NadekoBot/NadekoBot.cs +++ b/NadekoBot/NadekoBot.cs @@ -117,7 +117,7 @@ namespace NadekoBot Client = new DiscordClient(new DiscordConfigBuilder() { MessageCacheSize = 10, - ConnectionTimeout = 120000, + ConnectionTimeout = 180000, LogLevel = LogSeverity.Warning, LogHandler = (s, e) => Console.WriteLine($"Severity: {e.Severity}" + @@ -197,7 +197,7 @@ namespace NadekoBot return; } #if NADEKO_RELEASE - await Task.Delay(100000).ConfigureAwait(false); + await Task.Delay(120000).ConfigureAwait(false); #else await Task.Delay(1000).ConfigureAwait(false); #endif diff --git a/NadekoBot/NadekoBot.csproj b/NadekoBot/NadekoBot.csproj index bc22b90f..d332dad2 100644 --- a/NadekoBot/NadekoBot.csproj +++ b/NadekoBot/NadekoBot.csproj @@ -161,8 +161,23 @@ False lib\ScaredFingers.UnitsConversion.dll + + ..\packages\sqlite-net-pcl.1.1.2\lib\portable-net45+wp8+wpa81+win8+MonoAndroid10+MonoTouch10+Xamarin.iOS10\SQLite-net.dll + True + + + ..\packages\SQLitePCL.bundle_green.0.9.2\lib\net45\SQLitePCL.batteries.dll + True + + + ..\packages\SQLitePCL.raw.0.9.2\lib\net45\SQLitePCL.raw.dll + True + + + ..\packages\SQLitePCL.plugin.sqlite3.net45.0.9.2\lib\net45\SQLitePCLPlugin_esqlite3.dll + True + - @@ -202,6 +217,7 @@ + @@ -215,6 +231,7 @@ + @@ -264,7 +281,6 @@ - @@ -296,8 +312,6 @@ Resources.resx - - @@ -550,6 +564,13 @@ + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + +