Submodule Discord.Net updated: b9f767337d...f27cce0854
									
								
							| @@ -28,15 +28,21 @@ If you entered your Droplets IP address correctly, it should show **login as:** | ||||
|  | ||||
|  | ||||
|  | ||||
| Ubuntu:  | ||||
|  | ||||
| `sudo apt-get install git -y` | ||||
|  | ||||
| CentOS:  | ||||
|  | ||||
| `yum -y install git` | ||||
|  | ||||
| **NOTE:** If the command is not being initiated, hit **Enter** | ||||
|  | ||||
| ####Installing .NET Core SDK | ||||
|  | ||||
|  | ||||
|  | ||||
| Go to [this link](https://www.microsoft.com/net/core#ubuntu) provided by microsoft for instructions on how to get the most up to date version of the dotnet core sdk!   | ||||
| Go to [this link](https://www.microsoft.com/net/core#ubuntu) (for Ubuntu) or to [this link](https://www.microsoft.com/net/core#linuxcentos) (for CentOS) provided by microsoft for instructions on how to get the most up to date version of the dotnet core sdk!   | ||||
| Make sure that you're on the correct page for your distribution of linux as the guides are different for the various distributions   | ||||
|  | ||||
| We'll go over the steps here for Ubuntu 16.04 anyway (these will **only** work on Ubuntu 16.04), accurate as of 25/11/2016 | ||||
| @@ -53,14 +59,29 @@ sudo apt-get update && sudo apt-get install dotnet-dev-1.0.0-preview2.1-003177 - | ||||
|  | ||||
|  | ||||
|  | ||||
| Ubuntu:  | ||||
|  | ||||
| `sudo apt-get install libopus0 opus-tools libopus-dev libsodium-dev -y` | ||||
|  | ||||
| CentOS:  | ||||
|  | ||||
| `yum -y install opus opus-devel` | ||||
|  | ||||
| ####Installing FFMPEG | ||||
|  | ||||
|  | ||||
|  | ||||
| Ubuntu: | ||||
|  | ||||
| `apt-get install ffmpeg -y` | ||||
|  | ||||
| Centos:  | ||||
|  | ||||
| ``` | ||||
| yum -y install http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-5.el7.nux.noarch.rpm epel-release | ||||
| yum -y install ffmpeg | ||||
| ``` | ||||
|  | ||||
| **NOTE:** If you are running **UBUNTU 14.04**, you must run these first: | ||||
|  | ||||
| ``` | ||||
| @@ -84,8 +105,14 @@ sudo apt-get update && sudo apt-get install ffmpeg -y | ||||
|  | ||||
|  | ||||
|  | ||||
| Ubuntu:  | ||||
|  | ||||
| `sudo apt-get install tmux -y` | ||||
|  | ||||
| Centos:  | ||||
|  | ||||
| `yum -y install tmux` | ||||
|  | ||||
| ####Getting NadekoBot | ||||
|  | ||||
| Use the following command to get and run `linuxAIO.sh`:		 | ||||
|   | ||||
| @@ -12,37 +12,37 @@ namespace NadekoBot.Migrations | ||||
|                 name: "BetflipMultiplier", | ||||
|                 table: "BotConfig", | ||||
|                 nullable: false, | ||||
|                 defaultValue: 0f); | ||||
|                 defaultValue: 1.8f); | ||||
|  | ||||
|             migrationBuilder.AddColumn<float>( | ||||
|                 name: "Betroll100Multiplier", | ||||
|                 table: "BotConfig", | ||||
|                 nullable: false, | ||||
|                 defaultValue: 0f); | ||||
|                 defaultValue: 10f); | ||||
|  | ||||
|             migrationBuilder.AddColumn<float>( | ||||
|                 name: "Betroll67Multiplier", | ||||
|                 table: "BotConfig", | ||||
|                 nullable: false, | ||||
|                 defaultValue: 0f); | ||||
|                 defaultValue: 2f); | ||||
|  | ||||
|             migrationBuilder.AddColumn<float>( | ||||
|                 name: "Betroll91Multiplier", | ||||
|                 table: "BotConfig", | ||||
|                 nullable: false, | ||||
|                 defaultValue: 0f); | ||||
|                 defaultValue: 3f); | ||||
|  | ||||
|             migrationBuilder.AddColumn<int>( | ||||
|                 name: "CurrencyDropAmount", | ||||
|                 table: "BotConfig", | ||||
|                 nullable: false, | ||||
|                 defaultValue: 0); | ||||
|                 defaultValue: 1); | ||||
|  | ||||
|             migrationBuilder.AddColumn<int>( | ||||
|                 name: "MinimumBetAmount", | ||||
|                 table: "BotConfig", | ||||
|                 nullable: false, | ||||
|                 defaultValue: 0); | ||||
|                 defaultValue: 3); | ||||
|  | ||||
|             migrationBuilder.AddColumn<int>( | ||||
|                 name: "TriviaCurrencyReward", | ||||
|   | ||||
| @@ -4,8 +4,6 @@ using Microsoft.EntityFrameworkCore.Infrastructure; | ||||
| using Microsoft.EntityFrameworkCore.Metadata; | ||||
| using Microsoft.EntityFrameworkCore.Migrations; | ||||
| using NadekoBot.Services.Database; | ||||
| using NadekoBot.Services.Database.Models; | ||||
| using NadekoBot.Modules.Music.Classes; | ||||
|  | ||||
| namespace NadekoBot.Migrations | ||||
| { | ||||
|   | ||||
| @@ -25,7 +25,7 @@ namespace NadekoBot.Modules.Administration | ||||
|         { | ||||
|             private const string clockEmojiUrl = "https://cdn.discordapp.com/attachments/155726317222887425/258309524966866945/clock.png"; | ||||
|  | ||||
|             private static ShardedDiscordClient _client { get; } | ||||
|             private static DiscordShardedClient _client { get; } | ||||
|             private static Logger _log { get; } | ||||
|  | ||||
|             private static string prettyCurrentTime => $"【{DateTime.Now:HH:mm:ss}】"; | ||||
| @@ -81,7 +81,7 @@ namespace NadekoBot.Modules.Administration | ||||
|                 _client.UserPresenceUpdated += _client_UserPresenceUpdated; | ||||
|                 _client.UserVoiceStateUpdated += _client_UserVoiceStateUpdated; | ||||
|                 _client.UserVoiceStateUpdated += _client_UserVoiceStateUpdated_TTS; | ||||
|                 _client.GuildUserUpdated += _client_GuildUserUpdated; | ||||
|                 _client.GuildMemberUpdated += _client_GuildUserUpdated; | ||||
| #if !GLOBAL_NADEKO | ||||
|                 _client.UserUpdated += _client_UserUpdated; | ||||
| #endif | ||||
| @@ -94,7 +94,7 @@ namespace NadekoBot.Modules.Administration | ||||
|                 MuteCommands.UserUnmuted += MuteCommands_UserUnmuted; | ||||
|             } | ||||
|  | ||||
|             private static async void _client_UserUpdated(SocketUser before, SocketUser uAfter) | ||||
|             private static async Task _client_UserUpdated(SocketUser before, SocketUser uAfter) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
| @@ -162,7 +162,7 @@ namespace NadekoBot.Modules.Administration | ||||
|                 { } | ||||
|             } | ||||
|  | ||||
|             private static async void _client_UserVoiceStateUpdated_TTS(SocketUser iusr, SocketVoiceState before, SocketVoiceState after) | ||||
|             private static async Task _client_UserVoiceStateUpdated_TTS(SocketUser iusr, SocketVoiceState before, SocketVoiceState after) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
| @@ -317,7 +317,7 @@ namespace NadekoBot.Modules.Administration | ||||
|                 catch { } | ||||
|             } | ||||
|  | ||||
|             private static async void _client_GuildUserUpdated(SocketGuildUser before, SocketGuildUser after) | ||||
|             private static async Task _client_GuildUserUpdated(SocketGuildUser before, SocketGuildUser after) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
| @@ -360,7 +360,7 @@ namespace NadekoBot.Modules.Administration | ||||
|                 catch { } | ||||
|             } | ||||
|  | ||||
|             private static async void _client_ChannelUpdated(IChannel cbefore, IChannel cafter) | ||||
|             private static async Task _client_ChannelUpdated(IChannel cbefore, IChannel cafter) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
| @@ -403,7 +403,7 @@ namespace NadekoBot.Modules.Administration | ||||
|                 catch { } | ||||
|             } | ||||
|  | ||||
|             private static async void _client_ChannelDestroyed(IChannel ich) | ||||
|             private static async Task _client_ChannelDestroyed(IChannel ich) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
| @@ -430,7 +430,7 @@ namespace NadekoBot.Modules.Administration | ||||
|                 catch { } | ||||
|             } | ||||
|  | ||||
|             private static async void _client_ChannelCreated(IChannel ich) | ||||
|             private static async Task _client_ChannelCreated(IChannel ich) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
| @@ -456,7 +456,7 @@ namespace NadekoBot.Modules.Administration | ||||
|                 catch (Exception ex) { _log.Warn(ex); } | ||||
|             } | ||||
|  | ||||
|             private static async void _client_UserVoiceStateUpdated(SocketUser iusr, SocketVoiceState before, SocketVoiceState after) | ||||
|             private static async Task _client_UserVoiceStateUpdated(SocketUser iusr, SocketVoiceState before, SocketVoiceState after) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
| @@ -498,7 +498,7 @@ namespace NadekoBot.Modules.Administration | ||||
|                 catch { } | ||||
|             } | ||||
|  | ||||
|             private static async void _client_UserPresenceUpdated(Optional<SocketGuild> optGuild, SocketUser usr, SocketPresence before, SocketPresence after) | ||||
|             private static async Task _client_UserPresenceUpdated(Optional<SocketGuild> optGuild, SocketUser usr, SocketPresence before, SocketPresence after) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
| @@ -532,7 +532,7 @@ namespace NadekoBot.Modules.Administration | ||||
|                 catch { } | ||||
|             } | ||||
|  | ||||
|             private static async void _client_UserLeft(IGuildUser usr) | ||||
|             private static async Task _client_UserLeft(IGuildUser usr) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
| @@ -556,7 +556,7 @@ namespace NadekoBot.Modules.Administration | ||||
|                 catch { } | ||||
|             } | ||||
|  | ||||
|             private static async void _client_UserJoined(IGuildUser usr) | ||||
|             private static async Task _client_UserJoined(IGuildUser usr) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
| @@ -580,7 +580,7 @@ namespace NadekoBot.Modules.Administration | ||||
|                 catch (Exception ex) { _log.Warn(ex); } | ||||
|             } | ||||
|  | ||||
|             private static async void _client_UserUnbanned(IUser usr, IGuild guild) | ||||
|             private static async Task _client_UserUnbanned(IUser usr, IGuild guild) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
| @@ -604,7 +604,7 @@ namespace NadekoBot.Modules.Administration | ||||
|                 catch (Exception ex) { _log.Warn(ex); } | ||||
|             } | ||||
|  | ||||
|             private static async void _client_UserBanned(IUser usr, IGuild guild) | ||||
|             private static async Task _client_UserBanned(IUser usr, IGuild guild) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
| @@ -627,7 +627,7 @@ namespace NadekoBot.Modules.Administration | ||||
|                 catch (Exception ex) { _log.Warn(ex); } | ||||
|             } | ||||
|  | ||||
|             private static async void _client_MessageDeleted(ulong arg1, Optional<SocketMessage> imsg) | ||||
|             private static async Task _client_MessageDeleted(ulong arg1, Optional<SocketMessage> imsg) | ||||
|             { | ||||
|  | ||||
|                 try | ||||
| @@ -664,7 +664,7 @@ namespace NadekoBot.Modules.Administration | ||||
|                 catch { } | ||||
|             } | ||||
|  | ||||
|             private static async void _client_MessageUpdated(Optional<SocketMessage> optmsg, SocketMessage imsg2) | ||||
|             private static async Task _client_MessageUpdated(Optional<SocketMessage> optmsg, SocketMessage imsg2) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|   | ||||
| @@ -89,54 +89,66 @@ namespace NadekoBot.Modules.Administration | ||||
|                 db.Open(); | ||||
|  | ||||
|                 var com = db.CreateCommand(); | ||||
|                 com.CommandText = "SELECT * FROM Announcement"; | ||||
|  | ||||
|                 var reader = com.ExecuteReader(); | ||||
|                 var i = 0; | ||||
|                 while (reader.Read()) | ||||
|                 try | ||||
|                 { | ||||
|                     var gid = (ulong)(long)reader["ServerId"]; | ||||
|                     var greet = (long)reader["Greet"] == 1; | ||||
|                     var greetDM = (long)reader["GreetPM"] == 1; | ||||
|                     var greetChannel = (ulong)(long)reader["GreetChannelId"]; | ||||
|                     var greetMsg = (string)reader["GreetText"]; | ||||
|                     var bye = (long)reader["Bye"] == 1; | ||||
|                     var byeDM = (long)reader["ByePM"] == 1; | ||||
|                     var byeChannel = (ulong)(long)reader["ByeChannelId"]; | ||||
|                     var byeMsg = (string)reader["ByeText"]; | ||||
|                     var grdel = false; | ||||
|                     var byedel = grdel; | ||||
|                     var gc = uow.GuildConfigs.For(gid, set => set); | ||||
|                     com.CommandText = "SELECT * FROM Announcement"; | ||||
|  | ||||
|                     if (greetDM) | ||||
|                         gc.SendDmGreetMessage = greet; | ||||
|                     else | ||||
|                         gc.SendChannelGreetMessage = greet; | ||||
|                     gc.GreetMessageChannelId = greetChannel; | ||||
|                     gc.ChannelGreetMessageText = greetMsg; | ||||
|                     var reader = com.ExecuteReader(); | ||||
|                     while (reader.Read()) | ||||
|                     { | ||||
|                         var gid = (ulong)(long)reader["ServerId"]; | ||||
|                         var greet = (long)reader["Greet"] == 1; | ||||
|                         var greetDM = (long)reader["GreetPM"] == 1; | ||||
|                         var greetChannel = (ulong)(long)reader["GreetChannelId"]; | ||||
|                         var greetMsg = (string)reader["GreetText"]; | ||||
|                         var bye = (long)reader["Bye"] == 1; | ||||
|                         var byeDM = (long)reader["ByePM"] == 1; | ||||
|                         var byeChannel = (ulong)(long)reader["ByeChannelId"]; | ||||
|                         var byeMsg = (string)reader["ByeText"]; | ||||
|                         var grdel = false; | ||||
|                         var byedel = grdel; | ||||
|                         var gc = uow.GuildConfigs.For(gid, set => set); | ||||
|  | ||||
|                     gc.SendChannelByeMessage = bye; | ||||
|                     gc.ByeMessageChannelId = byeChannel; | ||||
|                     gc.ChannelByeMessageText = byeMsg; | ||||
|                         if (greetDM) | ||||
|                             gc.SendDmGreetMessage = greet; | ||||
|                         else | ||||
|                             gc.SendChannelGreetMessage = greet; | ||||
|                         gc.GreetMessageChannelId = greetChannel; | ||||
|                         gc.ChannelGreetMessageText = greetMsg; | ||||
|  | ||||
|                     gc.AutoDeleteGreetMessagesTimer = gc.AutoDeleteByeMessagesTimer = grdel ? 30 : 0; | ||||
|                     _log.Info(++i); | ||||
|                         gc.SendChannelByeMessage = bye; | ||||
|                         gc.ByeMessageChannelId = byeChannel; | ||||
|                         gc.ChannelByeMessageText = byeMsg; | ||||
|  | ||||
|                         gc.AutoDeleteGreetMessagesTimer = gc.AutoDeleteByeMessagesTimer = grdel ? 30 : 0; | ||||
|                         _log.Info(++i); | ||||
|                     } | ||||
|                 } | ||||
|                 catch { | ||||
|                     _log.Warn("Greet/bye messages won't be migrated"); | ||||
|                 } | ||||
|  | ||||
|                 var com2 = db.CreateCommand(); | ||||
|                 com.CommandText = "SELECT * FROM CurrencyState GROUP BY UserId"; | ||||
|  | ||||
|                 i = 0; | ||||
|                 var reader2 = com.ExecuteReader(); | ||||
|                 while (reader2.Read()) | ||||
|                 try | ||||
|                 { | ||||
|                     _log.Info(++i); | ||||
|                     var curr = new Currency() | ||||
|                     var reader2 = com.ExecuteReader(); | ||||
|                     while (reader2.Read()) | ||||
|                     { | ||||
|                         Amount = (long)reader2["Value"], | ||||
|                         UserId = (ulong)(long)reader2["UserId"] | ||||
|                     }; | ||||
|                     uow.Currency.Add(curr); | ||||
|                         _log.Info(++i); | ||||
|                         var curr = new Currency() | ||||
|                         { | ||||
|                             Amount = (long)reader2["Value"], | ||||
|                             UserId = (ulong)(long)reader2["UserId"] | ||||
|                         }; | ||||
|                         uow.Currency.Add(curr); | ||||
|                     } | ||||
|                 } | ||||
|                 catch | ||||
|                 { | ||||
|                     _log.Warn("Currency won't be migrated"); | ||||
|                 } | ||||
|                 db.Close(); | ||||
|                 try { File.Move("data/nadekobot.sqlite", "data/DELETE_ME_nadekobot.sqlite"); } catch { } | ||||
|   | ||||
| @@ -37,8 +37,7 @@ namespace NadekoBot.Modules.Administration | ||||
|             static MuteCommands() | ||||
|             { | ||||
|                 var _log = LogManager.GetCurrentClassLogger(); | ||||
|                 var sw = Stopwatch.StartNew(); | ||||
|                  | ||||
|  | ||||
|                 var configs = NadekoBot.AllGuildConfigs; | ||||
|                 GuildMuteRoles = new ConcurrentDictionary<ulong, string>(configs | ||||
|                         .Where(c => !string.IsNullOrWhiteSpace(c.MuteRoleName)) | ||||
| @@ -50,12 +49,9 @@ namespace NadekoBot.Modules.Administration | ||||
|                 )); | ||||
|  | ||||
|                 NadekoBot.Client.UserJoined += Client_UserJoined; | ||||
|  | ||||
|                 sw.Stop(); | ||||
|                 _log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s"); | ||||
|             } | ||||
|  | ||||
|             private static async void Client_UserJoined(IGuildUser usr) | ||||
|             private static async Task Client_UserJoined(IGuildUser usr) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|   | ||||
| @@ -50,7 +50,7 @@ namespace NadekoBot.Modules.Administration | ||||
|                                 if (string.IsNullOrWhiteSpace(status)) | ||||
|                                     continue; | ||||
|                                 PlayingPlaceholders.ForEach(e => status = status.Replace(e.Key, e.Value())); | ||||
|                                 await NadekoBot.Client.SetGame(status); | ||||
|                                 await NadekoBot.Client.SetGameAsync(status).ConfigureAwait(false); | ||||
|                             } | ||||
|                         } | ||||
|                         catch (Exception ex) | ||||
| @@ -67,7 +67,7 @@ namespace NadekoBot.Modules.Administration | ||||
|  | ||||
|             public static Dictionary<string, Func<string>> PlayingPlaceholders { get; } = | ||||
|                 new Dictionary<string, Func<string>> { | ||||
|                     {"%servers%", () => NadekoBot.Client.GetGuildsCount().ToString()}, | ||||
|                     {"%servers%", () => NadekoBot.Client.GetGuildCount().ToString()}, | ||||
|                     {"%users%", () => NadekoBot.Client.GetGuilds().Sum(s => s.Users.Count).ToString()}, | ||||
|                     {"%playing%", () => { | ||||
|                             var cnt = Music.Music.MusicPlayers.Count(kvp => kvp.Value.CurrentSong != null); | ||||
|   | ||||
| @@ -28,7 +28,7 @@ namespace NadekoBot.Modules.Administration | ||||
|                     await Context.Channel.SendErrorAsync("⚠️ Cannot find that server").ConfigureAwait(false); | ||||
|                     return; | ||||
|                 } | ||||
|                 if (server.OwnerId != NadekoBot.Client.CurrentUser().Id) | ||||
|                 if (server.OwnerId != NadekoBot.Client.CurrentUser.Id) | ||||
|                 { | ||||
|                     await server.LeaveAsync().ConfigureAwait(false); | ||||
|                     await Context.Channel.SendConfirmAsync("✅ Left server " + server.Name).ConfigureAwait(false); | ||||
| @@ -57,7 +57,7 @@ namespace NadekoBot.Modules.Administration | ||||
|                 if (string.IsNullOrWhiteSpace(newName)) | ||||
|                     return; | ||||
|  | ||||
|                 await NadekoBot.Client.CurrentUser().ModifyAsync(u => u.Username = newName).ConfigureAwait(false); | ||||
|                 await NadekoBot.Client.CurrentUser.ModifyAsync(u => u.Username = newName).ConfigureAwait(false); | ||||
|  | ||||
|                 await Context.Channel.SendConfirmAsync($"Bot name changed to **{newName}**").ConfigureAwait(false); | ||||
|             } | ||||
| @@ -66,7 +66,7 @@ namespace NadekoBot.Modules.Administration | ||||
|             [OwnerOnly] | ||||
|             public async Task SetStatus([Remainder] SettableUserStatus status) | ||||
|             { | ||||
|                 await NadekoBot.Client.SetStatus(status); | ||||
|                 await NadekoBot.Client.SetStatusAsync(SettableUserStatusToUserStatus(status)).ConfigureAwait(false); | ||||
|  | ||||
|                 await Context.Channel.SendConfirmAsync($"Bot status changed to **{status}**").ConfigureAwait(false); | ||||
|             } | ||||
| @@ -86,7 +86,7 @@ namespace NadekoBot.Modules.Administration | ||||
|                         await sr.CopyToAsync(imgStream); | ||||
|                         imgStream.Position = 0; | ||||
|  | ||||
|                         await NadekoBot.Client.CurrentUser().ModifyAsync(u => u.Avatar = new Image(imgStream)).ConfigureAwait(false); | ||||
|                         await NadekoBot.Client.CurrentUser.ModifyAsync(u => u.Avatar = new Image(imgStream)).ConfigureAwait(false); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
| @@ -97,7 +97,7 @@ namespace NadekoBot.Modules.Administration | ||||
|             [OwnerOnly] | ||||
|             public async Task SetGame([Remainder] string game = null) | ||||
|             { | ||||
|                 await NadekoBot.Client.SetGame(game).ConfigureAwait(false); | ||||
|                 await NadekoBot.Client.SetGameAsync(game).ConfigureAwait(false); | ||||
|  | ||||
|                 await Context.Channel.SendConfirmAsync("👾 **New game set.**").ConfigureAwait(false); | ||||
|             } | ||||
| @@ -108,7 +108,7 @@ namespace NadekoBot.Modules.Administration | ||||
|             { | ||||
|                 name = name ?? ""; | ||||
|  | ||||
|                 await NadekoBot.Client.SetStream(name, url).ConfigureAwait(false); | ||||
|                 await NadekoBot.Client.SetGameAsync(name, url, StreamType.Twitch).ConfigureAwait(false); | ||||
|  | ||||
|                 await Context.Channel.SendConfirmAsync("ℹ️ **New stream set.**").ConfigureAwait(false); | ||||
|             } | ||||
| @@ -169,6 +169,23 @@ namespace NadekoBot.Modules.Administration | ||||
|  | ||||
|                 await Context.Channel.SendConfirmAsync("🆗").ConfigureAwait(false); | ||||
|             } | ||||
|  | ||||
|             private static UserStatus SettableUserStatusToUserStatus(SettableUserStatus sus) | ||||
|             { | ||||
|                 switch (sus) | ||||
|                 { | ||||
|                     case SettableUserStatus.Online: | ||||
|                         return UserStatus.Online; | ||||
|                     case SettableUserStatus.Invisible: | ||||
|                         return UserStatus.Invisible; | ||||
|                     case SettableUserStatus.Idle: | ||||
|                         return UserStatus.AFK; | ||||
|                     case SettableUserStatus.Dnd: | ||||
|                         return UserStatus.DoNotDisturb; | ||||
|                 } | ||||
|  | ||||
|                 return UserStatus.Online; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -26,7 +26,7 @@ namespace NadekoBot.Modules.Administration | ||||
|                 _log = LogManager.GetCurrentClassLogger(); | ||||
|             } | ||||
|             //todo optimize ASAP | ||||
|             private static async void UserLeft(IGuildUser user) | ||||
|             private static async Task UserLeft(IGuildUser user) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
| @@ -58,7 +58,7 @@ namespace NadekoBot.Modules.Administration | ||||
|                 catch { } | ||||
|             } | ||||
|  | ||||
|             private static async void UserJoined(IGuildUser user) | ||||
|             private static async Task UserJoined(IGuildUser user) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|   | ||||
| @@ -36,7 +36,7 @@ namespace NadekoBot.Modules.Administration | ||||
|                 _log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s"); | ||||
|             } | ||||
|  | ||||
|             private static async void UserUpdatedEventHandler(SocketUser iuser, SocketVoiceState before, SocketVoiceState after) | ||||
|             private static async Task UserUpdatedEventHandler(SocketUser iuser, SocketVoiceState before, SocketVoiceState after) | ||||
|             { | ||||
|                 var user = (iuser as SocketGuildUser); | ||||
|                 var guild = user?.Guild; | ||||
|   | ||||
| @@ -18,7 +18,7 @@ namespace NadekoBot.Modules.CustomReactions | ||||
|  | ||||
|         public static Dictionary<string, Func<IUserMessage, string>> placeholders = new Dictionary<string, Func<IUserMessage, string>>() | ||||
|         { | ||||
|             {"%mention%", (ctx) => { return $"<@{NadekoBot.Client.CurrentUser().Id}>"; } }, | ||||
|             {"%mention%", (ctx) => { return $"<@{NadekoBot.Client.CurrentUser.Id}>"; } }, | ||||
|             {"%user%", (ctx) => { return ctx.Author.Mention; } }, | ||||
|             {"%rnduser%", (ctx) => { | ||||
|                 var ch = ctx.Channel as ITextChannel; | ||||
|   | ||||
| @@ -207,15 +207,15 @@ namespace NadekoBot.Modules.Gambling | ||||
|  | ||||
|                 } | ||||
|  | ||||
|                 private void Client_MessageReceived(SocketMessage imsg) | ||||
|                 private Task Client_MessageReceived(SocketMessage imsg) | ||||
|                 { | ||||
|                     var msg = imsg as SocketUserMessage; | ||||
|                     if (msg == null) | ||||
|                         return; | ||||
|                         return Task.CompletedTask; | ||||
|                     if (msg.IsAuthor() || !(imsg.Channel is ITextChannel) || imsg.Channel != raceChannel) | ||||
|                         return; | ||||
|                         return Task.CompletedTask; | ||||
|                     messagesSinceGameStarted++; | ||||
|                     return; | ||||
|                     return Task.CompletedTask; | ||||
|                 } | ||||
|  | ||||
|                 private async Task CheckForFullGameAsync(CancellationToken cancelToken) | ||||
|   | ||||
							
								
								
									
										84
									
								
								src/NadekoBot/Modules/Gambling/Commands/CurrencyEvents.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								src/NadekoBot/Modules/Gambling/Commands/CurrencyEvents.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | ||||
| using Discord; | ||||
| using Discord.Commands; | ||||
| using NadekoBot.Attributes; | ||||
| using NadekoBot.Extensions; | ||||
| using NadekoBot.Services; | ||||
| using System; | ||||
| using System.Collections.Concurrent; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
|  | ||||
| namespace NadekoBot.Modules.Gambling | ||||
| { | ||||
|     public partial class Gambling | ||||
|     { | ||||
|         [Group] | ||||
|         public class CurrencyEvents : ModuleBase | ||||
|         { | ||||
|             public enum CurrencyEvent | ||||
|             { | ||||
|                 FlowerReaction | ||||
|             } | ||||
|             //flower reaction event | ||||
|             public static readonly ConcurrentHashSet<ulong> _flowerReactionAwardedUsers = new ConcurrentHashSet<ulong>(); | ||||
|  | ||||
|             [NadekoCommand, Usage, Description, Aliases] | ||||
|             [RequireContext(ContextType.Guild)] | ||||
|             [OwnerOnly] | ||||
|             public async Task StartEvent(CurrencyEvent e) | ||||
|             { | ||||
|                 var channel = (ITextChannel)Context.Channel; | ||||
|                 try | ||||
|                 { | ||||
|  | ||||
|                     switch (e) | ||||
|                     { | ||||
|                         case CurrencyEvent.FlowerReaction: | ||||
|                             await FlowerReactionEvent(Context).ConfigureAwait(false); | ||||
|                             break; | ||||
|                         default: | ||||
|                             break; | ||||
|                     } | ||||
|                 } | ||||
|                 catch { } | ||||
|             } | ||||
|  | ||||
|  | ||||
|             public static async Task FlowerReactionEvent(CommandContext Context) | ||||
|             { | ||||
|                 var msg = await Context.Channel.SendConfirmAsync("Flower reaction event started!",  | ||||
|                     "Add 🌸 reaction to this message to get 100" + NadekoBot.BotConfig.CurrencySign, | ||||
|                     footer: "This event is active for 24 hours.") | ||||
|                                                .ConfigureAwait(false); | ||||
|                 try { await msg.AddReactionAsync("🌸").ConfigureAwait(false); } | ||||
|                 catch | ||||
|                 { | ||||
|                     try { await msg.AddReactionAsync("🌸").ConfigureAwait(false); } | ||||
|                     catch | ||||
|                     { | ||||
|                         try { await msg.DeleteAsync().ConfigureAwait(false); } | ||||
|                         catch { } | ||||
|                     } | ||||
|                 } | ||||
|                 using (msg.OnReaction(async (r) => | ||||
|                  { | ||||
|                      try | ||||
|                      { | ||||
|                          if (r.Emoji.Name == "🌸" && r.User.IsSpecified && _flowerReactionAwardedUsers.Add(r.User.Value.Id)) | ||||
|                          { | ||||
|                              try { await CurrencyHandler.AddCurrencyAsync(r.User.Value, "Flower Reaction Event", 100, false).ConfigureAwait(false); } catch { } | ||||
|                          } | ||||
|                      } | ||||
|                      catch { } | ||||
|                  })) | ||||
|                 { | ||||
|                     await Task.Delay(TimeSpan.FromHours(24)).ConfigureAwait(false); | ||||
|                     try { await msg.DeleteAsync().ConfigureAwait(false); } catch { } | ||||
|                     _flowerReactionAwardedUsers.Clear(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -168,7 +168,7 @@ namespace NadekoBot.Modules.Games | ||||
|                 await End().ConfigureAwait(false); | ||||
|             } | ||||
|  | ||||
|             private async void PotentialAcro(SocketMessage arg) | ||||
|             private async Task PotentialAcro(SocketMessage arg) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|   | ||||
| @@ -58,7 +58,7 @@ namespace NadekoBot.Modules.Games | ||||
|                 if (!CleverbotGuilds.TryGetValue(channel.Guild.Id, out cleverbot)) | ||||
|                     return false; | ||||
|  | ||||
|                 var nadekoId = NadekoBot.Client.CurrentUser().Id; | ||||
|                 var nadekoId = NadekoBot.Client.CurrentUser.Id; | ||||
|                 var normalMention = $"<@{nadekoId}> "; | ||||
|                 var nickMention = $"<@!{nadekoId}> "; | ||||
|                 string message; | ||||
|   | ||||
| @@ -114,7 +114,7 @@ namespace NadekoBot.Modules.Games.Commands.Hangman | ||||
|                 await GameChannel.EmbedAsync(embed.WithOkColor()).ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         private async void PotentialGuess(SocketMessage msg) | ||||
|         private async Task PotentialGuess(SocketMessage msg) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|   | ||||
| @@ -51,7 +51,7 @@ namespace NadekoBot.Modules.Games | ||||
|                     .SelectMany(c => c.GenerateCurrencyChannelIds.Select(obj => obj.ChannelId))); | ||||
|             } | ||||
|  | ||||
|             private static async void PotentialFlowerGeneration(SocketMessage imsg) | ||||
|             private static async Task PotentialFlowerGeneration(SocketMessage imsg) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|   | ||||
| @@ -153,7 +153,7 @@ namespace NadekoBot.Modules.Games | ||||
|                 await originalMessage.Channel.EmbedAsync(GetStats("POLL CLOSED")).ConfigureAwait(false); | ||||
|             } | ||||
|  | ||||
|             private async void Vote(SocketMessage imsg) | ||||
|             private async Task Vote(SocketMessage imsg) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|   | ||||
| @@ -106,7 +106,7 @@ namespace NadekoBot.Modules.Games | ||||
|                 NadekoBot.Client.MessageReceived += AnswerReceived; | ||||
|             } | ||||
|  | ||||
|             private async void AnswerReceived(SocketMessage imsg) | ||||
|             private async Task AnswerReceived(SocketMessage imsg) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|   | ||||
| @@ -56,7 +56,9 @@ namespace NadekoBot.Modules.Games.Trivia | ||||
|  | ||||
|                 // load question | ||||
|                 CurrentQuestion = TriviaQuestionPool.Instance.GetRandomQuestion(oldQuestions); | ||||
|                 if (CurrentQuestion == null) | ||||
|                 if (CurrentQuestion == null ||  | ||||
|                     string.IsNullOrWhiteSpace(CurrentQuestion.Answer) ||  | ||||
|                     string.IsNullOrWhiteSpace(CurrentQuestion.Question)) | ||||
|                 { | ||||
|                     await channel.SendErrorAsync("Trivia Game", "Failed loading a question.").ConfigureAwait(false); | ||||
|                     return; | ||||
| @@ -74,7 +76,9 @@ namespace NadekoBot.Modules.Games.Trivia | ||||
|  | ||||
|                     questionMessage = await channel.EmbedAsync(questionEmbed).ConfigureAwait(false); | ||||
|                 } | ||||
|                 catch (HttpException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound || ex.StatusCode == System.Net.HttpStatusCode.Forbidden) | ||||
|                 catch (HttpException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound ||  | ||||
|                                                ex.StatusCode == System.Net.HttpStatusCode.Forbidden || | ||||
|                                                ex.StatusCode == System.Net.HttpStatusCode.BadRequest) | ||||
|                 { | ||||
|                     return; | ||||
|                 } | ||||
| @@ -143,7 +147,7 @@ namespace NadekoBot.Modules.Games.Trivia | ||||
|                 try { await channel.SendConfirmAsync("Trivia Game", "Stopping after this question.").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } | ||||
|         } | ||||
|  | ||||
|         private async void PotentialGuess(SocketMessage imsg) | ||||
|         private async Task PotentialGuess(SocketMessage imsg) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|   | ||||
| @@ -80,7 +80,7 @@ namespace NadekoBot.Modules.Games | ||||
|             else if ((pick == 0 && nadekoPick == 1) || | ||||
|                      (pick == 1 && nadekoPick == 2) || | ||||
|                      (pick == 2 && nadekoPick == 0)) | ||||
|                 msg = $"{NadekoBot.Client.CurrentUser().Mention} won! {GetRPSPick(nadekoPick)} beats {GetRPSPick(pick)}"; | ||||
|                 msg = $"{NadekoBot.Client.CurrentUser.Mention} won! {GetRPSPick(nadekoPick)} beats {GetRPSPick(pick)}"; | ||||
|             else | ||||
|                 msg = $"{Context.User.Mention} won! {GetRPSPick(pick)} beats {GetRPSPick(nadekoPick)}"; | ||||
|  | ||||
|   | ||||
| @@ -137,7 +137,7 @@ namespace NadekoBot.Modules.Help | ||||
|                 } | ||||
|                 helpstr.AppendLine($"{string.Join(" ", com.Aliases.Select(a => "`" + a + "`"))} | {string.Format(com.Summary, com.Module.GetPrefix())} {GetCommandRequirements(com)} | {string.Format(com.Remarks, com.Module.GetPrefix())}"); | ||||
|             } | ||||
|             helpstr = helpstr.Replace(NadekoBot.Client.CurrentUser().Username , "@BotName"); | ||||
|             helpstr = helpstr.Replace(NadekoBot.Client.CurrentUser.Username , "@BotName"); | ||||
|             File.WriteAllText("../../docs/Commands List.md", helpstr.ToString()); | ||||
|             await Context.Channel.SendConfirmAsync("Commandlist Regenerated").ConfigureAwait(false); | ||||
|         } | ||||
|   | ||||
| @@ -140,9 +140,15 @@ namespace NadekoBot.Modules.Music.Classes | ||||
|                             RemoveSongAt(index, true); | ||||
|  | ||||
|                         OnStarted(this, CurrentSong); | ||||
|                         await CurrentSong.Play(audioClient, cancelToken); | ||||
|  | ||||
|                         OnCompleted(this, CurrentSong); | ||||
|                         try | ||||
|                         { | ||||
|                             await CurrentSong.Play(audioClient, cancelToken); | ||||
|                         } | ||||
|                         catch(OperationCanceledException) | ||||
|                         { | ||||
|                             OnCompleted(this, CurrentSong); | ||||
|                         } | ||||
|                          | ||||
|  | ||||
|                         if (RepeatPlaylist) | ||||
|                             AddSong(CurrentSong, CurrentSong.QueuerName); | ||||
| @@ -151,7 +157,6 @@ namespace NadekoBot.Modules.Music.Classes | ||||
|                             AddSong(CurrentSong, 0); | ||||
|  | ||||
|                     } | ||||
|                     catch (OperationCanceledException) { } | ||||
|                     catch (Exception ex) | ||||
|                     { | ||||
|                         Console.WriteLine("Music thread almost crashed."); | ||||
| @@ -337,13 +342,13 @@ namespace NadekoBot.Modules.Music.Classes | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         public Task MoveToVoiceChannel(IVoiceChannel voiceChannel) | ||||
|         { | ||||
|             if (audioClient?.ConnectionState != ConnectionState.Connected) | ||||
|                 throw new InvalidOperationException("Can't move while bot is not connected to voice channel."); | ||||
|             PlaybackVoiceChannel = voiceChannel; | ||||
|             return PlaybackVoiceChannel.ConnectAsync(); | ||||
|         } | ||||
|         //public async Task MoveToVoiceChannel(IVoiceChannel voiceChannel) | ||||
|         //{ | ||||
|         //    if (audioClient?.ConnectionState != ConnectionState.Connected) | ||||
|         //        throw new InvalidOperationException("Can't move while bot is not connected to voice channel."); | ||||
|         //    PlaybackVoiceChannel = voiceChannel; | ||||
|         //    audioClient = await voiceChannel.ConnectAsync().ConfigureAwait(false); | ||||
|         //} | ||||
|  | ||||
|         public bool ToggleRepeatSong() => this.RepeatSong = !this.RepeatSong; | ||||
|  | ||||
|   | ||||
| @@ -37,30 +37,49 @@ namespace NadekoBot.Modules.Music | ||||
|             Directory.CreateDirectory(MusicDataPath); | ||||
|         } | ||||
|  | ||||
|         private static async void Client_UserVoiceStateUpdated(SocketUser iusr, SocketVoiceState oldState, SocketVoiceState newState) | ||||
|         private static Task Client_UserVoiceStateUpdated(SocketUser iusr, SocketVoiceState oldState, SocketVoiceState newState) | ||||
|         { | ||||
|             var usr = iusr as SocketGuildUser; | ||||
|             if (usr == null || | ||||
|                 oldState.VoiceChannel == newState.VoiceChannel) | ||||
|                 return; | ||||
|                 return Task.CompletedTask; | ||||
|  | ||||
|             MusicPlayer player; | ||||
|             if (!MusicPlayers.TryGetValue(usr.Guild.Id, out player)) | ||||
|                 return; | ||||
|                 return Task.CompletedTask; | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 var users = await player.PlaybackVoiceChannel.GetUsersAsync().Flatten().ConfigureAwait(false); | ||||
|  | ||||
|  | ||||
|                 //if bot moved | ||||
|                 if ((player.PlaybackVoiceChannel == oldState.VoiceChannel) && | ||||
|                         usr.Id == NadekoBot.Client.CurrentUser.Id) | ||||
|                 { | ||||
|                     if (player.Paused && newState.VoiceChannel.Users.Count > 1) //unpause if there are people in the new channel | ||||
|                         player.TogglePause(); | ||||
|                     else if (!player.Paused && newState.VoiceChannel.Users.Count <= 1) // pause if there are no users in the new channel | ||||
|                         player.TogglePause(); | ||||
|  | ||||
|                     return Task.CompletedTask; | ||||
|                 } | ||||
|  | ||||
|  | ||||
|                 //if some other user moved | ||||
|                 if ((player.PlaybackVoiceChannel == newState.VoiceChannel && //if joined first, and player paused, unpause  | ||||
|                         player.Paused && | ||||
|                         users.Count() == 2) ||  // keep in mind bot is in the channel (+1) | ||||
|                         newState.VoiceChannel.Users.Count == 2) ||  // keep in mind bot is in the channel (+1) | ||||
|                     (player.PlaybackVoiceChannel == oldState.VoiceChannel && // if left last, and player unpaused, pause | ||||
|                         !player.Paused && | ||||
|                         users.Count() == 1)) | ||||
|                         oldState.VoiceChannel.Users.Count == 1)) | ||||
|                 { | ||||
|                     player.TogglePause(); | ||||
|                     return Task.CompletedTask; | ||||
|                 } | ||||
|  | ||||
|             } | ||||
|             catch { } | ||||
|             return Task.CompletedTask; | ||||
|         } | ||||
|  | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
| @@ -192,7 +211,7 @@ namespace NadekoBot.Modules.Music | ||||
|                 int startAt = itemsPerPage * (curPage - 1); | ||||
|                 var number = 0 + startAt; | ||||
|                 var embed = new EmbedBuilder() | ||||
|                     .WithAuthor(eab => eab.WithName($"Player Queue") | ||||
|                     .WithAuthor(eab => eab.WithName($"Player Queue - Page {curPage}/{lastPage + 1}") | ||||
|                                           .WithMusicIcon()) | ||||
|                     .WithDescription(string.Join("\n", musicPlayer.Playlist | ||||
|                         .Skip(startAt) | ||||
| @@ -217,7 +236,7 @@ namespace NadekoBot.Modules.Music | ||||
|                 } | ||||
|                 return embed; | ||||
|             }; | ||||
|             await Context.Channel.SendPaginatedConfirmAsync(page, printAction, lastPage).ConfigureAwait(false); | ||||
|             await Context.Channel.SendPaginatedConfirmAsync(page, printAction, lastPage, false).ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
| @@ -448,17 +467,17 @@ namespace NadekoBot.Modules.Music | ||||
|  | ||||
|         } | ||||
|  | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task Move() | ||||
|         { | ||||
|         //[NadekoCommand, Usage, Description, Aliases] | ||||
|         //[RequireContext(ContextType.Guild)] | ||||
|         //public async Task Move() | ||||
|         //{ | ||||
|  | ||||
|             MusicPlayer musicPlayer; | ||||
|             var voiceChannel = ((IGuildUser)Context.User).VoiceChannel; | ||||
|             if (voiceChannel == null || voiceChannel.Guild != Context.Guild || !MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer)) | ||||
|                 return; | ||||
|             await musicPlayer.MoveToVoiceChannel(voiceChannel); | ||||
|         } | ||||
|         //    MusicPlayer musicPlayer; | ||||
|         //    var voiceChannel = ((IGuildUser)Context.User).VoiceChannel; | ||||
|         //    if (voiceChannel == null || voiceChannel.Guild != Context.Guild || !MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer)) | ||||
|         //        return; | ||||
|         //    await musicPlayer.MoveToVoiceChannel(voiceChannel); | ||||
|         //} | ||||
|  | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
| @@ -814,7 +833,7 @@ namespace NadekoBot.Modules.Music | ||||
|                                                   .WithFooter(ef => ef.WithText(song.PrettyInfo))) | ||||
|                                                     .ConfigureAwait(false); | ||||
|  | ||||
|                         if (mp.Autoplay && mp.Playlist.Count == 0 && song.SongInfo.Provider == "YouTube") | ||||
|                         if (mp.Autoplay && mp.Playlist.Count == 0 && song.SongInfo.ProviderType == MusicType.Normal) | ||||
|                         { | ||||
|                             await QueueSong(await queuer.Guild.GetCurrentUserAsync(), textCh, voiceCh, (await NadekoBot.Google.GetRelatedVideosAsync(song.SongInfo.Query, 4)).ToList().Shuffle().FirstOrDefault(), silent, musicType).ConfigureAwait(false); | ||||
|                         } | ||||
|   | ||||
| @@ -20,6 +20,7 @@ namespace NadekoBot.Modules.NSFW | ||||
|     public class NSFW : DiscordModule | ||||
|     { | ||||
|         private static ConcurrentDictionary<ulong, Timer> AutoHentaiTimers { get; } = new ConcurrentDictionary<ulong, Timer>(); | ||||
|         private static ConcurrentHashSet<ulong> _hentaiBombBlacklist { get; } = new ConcurrentHashSet<ulong>(); | ||||
|  | ||||
|         private async Task InternalHentai(IMessageChannel channel, string tag, bool noError) | ||||
|         { | ||||
| @@ -56,7 +57,8 @@ namespace NadekoBot.Modules.NSFW | ||||
|  | ||||
|             await channel.EmbedAsync(new EmbedBuilder().WithOkColor() | ||||
|                 .WithImageUrl(link) | ||||
|                 .WithDescription("Tag: " + tag)).ConfigureAwait(false); | ||||
|                 .WithDescription("Tag: " + tag)) | ||||
|                 .ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
| @@ -90,7 +92,7 @@ namespace NadekoBot.Modules.NSFW | ||||
|                     if (tagsArr == null || tagsArr.Length == 0) | ||||
|                         await InternalHentai(Context.Channel, null, true).ConfigureAwait(false); | ||||
|                     else | ||||
|                         await InternalHentai(Context.Channel, tagsArr[new NadekoRandom().Next(0, tagsArr.Length)], true); | ||||
|                         await InternalHentai(Context.Channel, tagsArr[new NadekoRandom().Next(0, tagsArr.Length)], true).ConfigureAwait(false); | ||||
|                 } | ||||
|                 catch { } | ||||
|             }, null, interval * 1000, interval * 1000); | ||||
| @@ -101,29 +103,39 @@ namespace NadekoBot.Modules.NSFW | ||||
|                 return t; | ||||
|             }); | ||||
|  | ||||
|             await Context.Channel.SendConfirmAsync($"Autohentai started. Reposting every {interval}s with one of the following tags:\n{string.Join(", ", tagsArr)}").ConfigureAwait(false); | ||||
|             await Context.Channel.SendConfirmAsync($"Autohentai started. Reposting every {interval}s with one of the following tags:\n{string.Join(", ", tagsArr)}") | ||||
|                                  .ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
|         public async Task HentaiBomb([Remainder] string tag = null) | ||||
|         { | ||||
|             tag = tag?.Trim() ?? ""; | ||||
|             tag = "rating%3Aexplicit+" + tag; | ||||
|  | ||||
|             var links = await Task.WhenAll(GetGelbooruImageLink(tag), | ||||
|                                            GetDanbooruImageLink(tag), | ||||
|                                            GetKonachanImageLink(tag), | ||||
|                                            GetYandereImageLink(tag)).ConfigureAwait(false); | ||||
|  | ||||
|             var linksEnum = links?.Where(l => l != null); | ||||
|             if (links == null || !linksEnum.Any()) | ||||
|             { | ||||
|                 await Context.Channel.SendErrorAsync("No results found.").ConfigureAwait(false); | ||||
|             if (!_hentaiBombBlacklist.Add(Context.User.Id)) | ||||
|                 return; | ||||
|             } | ||||
|             try | ||||
|             { | ||||
|                 tag = tag?.Trim() ?? ""; | ||||
|                 tag = "rating%3Aexplicit+" + tag; | ||||
|  | ||||
|             await Context.Channel.SendMessageAsync(String.Join("\n\n", linksEnum)).ConfigureAwait(false); | ||||
|                 var links = await Task.WhenAll(GetGelbooruImageLink(tag), | ||||
|                                                GetDanbooruImageLink(tag), | ||||
|                                                GetKonachanImageLink(tag), | ||||
|                                                GetYandereImageLink(tag)).ConfigureAwait(false); | ||||
|  | ||||
|                 var linksEnum = links?.Where(l => l != null); | ||||
|                 if (links == null || !linksEnum.Any()) | ||||
|                 { | ||||
|                     await Context.Channel.SendErrorAsync("No results found.").ConfigureAwait(false); | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 await Context.Channel.SendMessageAsync(String.Join("\n\n", linksEnum)).ConfigureAwait(false); | ||||
|             } | ||||
|             finally { | ||||
|                 await Task.Delay(5000).ConfigureAwait(false); | ||||
|                 _hentaiBombBlacklist.TryRemove(Context.User.Id); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|  | ||||
| @@ -135,12 +147,13 @@ namespace NadekoBot.Modules.NSFW | ||||
|             var url = await GetDanbooruImageLink(tag).ConfigureAwait(false); | ||||
|  | ||||
|             if (url == null) | ||||
|                 await Context.Channel.SendErrorAsync(Context.User.Mention + " No results."); | ||||
|                 await Context.Channel.SendErrorAsync(Context.User.Mention + " No results.").ConfigureAwait(false); | ||||
|             else | ||||
|                 await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() | ||||
|                     .WithDescription(Context.User.Mention + " " + tag) | ||||
|                     .WithImageUrl(url) | ||||
|                     .WithFooter(efb => efb.WithText("Danbooru"))).ConfigureAwait(false); | ||||
|                     .WithFooter(efb => efb.WithText("Danbooru"))) | ||||
|                     .ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
| @@ -172,7 +185,8 @@ namespace NadekoBot.Modules.NSFW | ||||
|                 await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() | ||||
|                     .WithDescription(Context.User.Mention + " " + tag) | ||||
|                     .WithImageUrl(url) | ||||
|                     .WithFooter(efb => efb.WithText("e621"))).ConfigureAwait(false); | ||||
|                     .WithFooter(efb => efb.WithText("e621"))) | ||||
|                     .ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
| @@ -217,14 +231,14 @@ namespace NadekoBot.Modules.NSFW | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public static async Task<string> GetDanbooruImageLink(string tag) | ||||
|         public static Task<string> GetDanbooruImageLink(string tag) => Task.Run(async () => | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 using (var http = new HttpClient()) | ||||
|                 { | ||||
|                     http.AddFakeHeaders(); | ||||
|                     var data = await http.GetStreamAsync("https://danbooru.donmai.us/posts.xml?limit=100&tags=" + tag); | ||||
|                     var data = await http.GetStreamAsync("https://danbooru.donmai.us/posts.xml?limit=100&tags=" + tag).ConfigureAwait(false); | ||||
|                     var doc = new XmlDocument(); | ||||
|                     doc.Load(data); | ||||
|                     var nodes = doc.GetElementsByTagName("file-url"); | ||||
| @@ -237,17 +251,17 @@ namespace NadekoBot.Modules.NSFW | ||||
|             { | ||||
|                 return null; | ||||
|             } | ||||
|         } | ||||
|         }); | ||||
|  | ||||
|  | ||||
|         public static async Task<string> GetE621ImageLink(string tag) | ||||
|         public static Task<string> GetE621ImageLink(string tag) => Task.Run(async () => | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 using (var http = new HttpClient()) | ||||
|                 { | ||||
|                     http.AddFakeHeaders(); | ||||
|                     var data = await http.GetStreamAsync("http://e621.net/post/index.xml?tags=" + tag); | ||||
|                     var data = await http.GetStreamAsync("http://e621.net/post/index.xml?tags=" + tag).ConfigureAwait(false); | ||||
|                     var doc = new XmlDocument(); | ||||
|                     doc.Load(data); | ||||
|                     var nodes = doc.GetElementsByTagName("file_url"); | ||||
| @@ -260,7 +274,7 @@ namespace NadekoBot.Modules.NSFW | ||||
|             { | ||||
|                 return null; | ||||
|             } | ||||
|         } | ||||
|         }); | ||||
|  | ||||
|         public static Task<string> GetYandereImageLink(string tag) => | ||||
|             Searches.Searches.InternalDapiSearch(tag, Searches.Searches.DapiSearchType.Yandere); | ||||
|   | ||||
| @@ -0,0 +1,101 @@ | ||||
| using Discord; | ||||
| using Discord.Commands; | ||||
| using NadekoBot.Attributes; | ||||
| using NadekoBot.Extensions; | ||||
| using NadekoBot.Services; | ||||
| using NadekoBot.Services.Database; | ||||
| using NadekoBot.Services.Database.Models; | ||||
| using System; | ||||
| using System.Collections.Concurrent; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
|  | ||||
| namespace NadekoBot.Modules.Permissions | ||||
| { | ||||
|     public partial class Permissions | ||||
|     { | ||||
|         [Group] | ||||
|         public class CommandCostCommands : ModuleBase | ||||
|         { | ||||
|             private static readonly ConcurrentDictionary<string, int> _commandCosts = new ConcurrentDictionary<string, int>(); | ||||
|             public static IReadOnlyDictionary<string, int> CommandCosts => _commandCosts; | ||||
|  | ||||
|             static CommandCostCommands() | ||||
|             { | ||||
|                 //_commandCosts = new ConcurrentDictionary<string, int>(NadekoBot.BotConfig.CommandCosts.ToDictionary( | ||||
|                 //    x => x.CommandName.Trim().ToUpperInvariant(), | ||||
|                 //    x => x.Cost)); | ||||
|             } | ||||
|  | ||||
|             [NadekoCommand, Usage, Description, Aliases] | ||||
|             public async Task CmdCosts(int page = 1) | ||||
|             { | ||||
|                 var prices = _commandCosts.ToList(); | ||||
|  | ||||
|                 if (!prices.Any()) | ||||
|                 { | ||||
|                     await Context.Channel.SendConfirmAsync("No costs set.").ConfigureAwait(false); | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 await Context.Channel.SendPaginatedConfirmAsync(page, (curPage) => { | ||||
|                     var embed = new EmbedBuilder().WithOkColor() | ||||
|                         .WithTitle("Command Costs"); | ||||
|                     var current = prices.Skip((curPage - 1) * 9) | ||||
|                         .Take(9); | ||||
|                     foreach (var price in current) | ||||
|                     { | ||||
|                         embed.AddField(efb => efb.WithName(price.Key).WithValue(price.Value.ToString()).WithIsInline(true)); | ||||
|                     } | ||||
|                     return embed; | ||||
|                 }, prices.Count / 9).ConfigureAwait(false); | ||||
|             } | ||||
|  | ||||
|             //[NadekoCommand, Usage, Description, Aliases] | ||||
|             //public async Task CommandCost(int cost, CommandInfo cmd) | ||||
|             //{ | ||||
|             //    if (cost < 0) | ||||
|             //        return; | ||||
|  | ||||
|             //    var cmdName = cmd.Aliases.First().ToLowerInvariant(); | ||||
|  | ||||
|             //    var cmdPrice = new CommandCost() | ||||
|             //    { | ||||
|             //        CommandName = cmdName, | ||||
|             //        Cost = cost | ||||
|             //    }; | ||||
|  | ||||
|             //    using (var uow = DbHandler.UnitOfWork()) | ||||
|             //    { | ||||
|             //        var bc = uow.BotConfig.GetOrCreate(); | ||||
|                      | ||||
|             //        if (cost != 0) | ||||
|             //        { | ||||
|             //            var elem = bc.CommandCosts.Where(cc => cc.CommandName == cmdPrice.CommandName).FirstOrDefault(); | ||||
|             //            if (elem == null) | ||||
|             //                bc.CommandCosts.Add(cmdPrice); | ||||
|             //            else | ||||
|             //                elem.Cost = cost; | ||||
|  | ||||
|             //            _commandCosts.AddOrUpdate(cmdName, cost, (key, old) => cost); | ||||
|             //        } | ||||
|             //        else | ||||
|             //        { | ||||
|             //            bc.CommandCosts.RemoveAt(bc.CommandCosts.IndexOf(cmdPrice)); | ||||
|             //            int throwaway; | ||||
|             //            _commandCosts.TryRemove(cmdName, out throwaway); | ||||
|             //        } | ||||
|  | ||||
|             //        await uow.CompleteAsync().ConfigureAwait(false); | ||||
|             //    } | ||||
|  | ||||
|             //    if (cost == 0) | ||||
|             //        await Context.Channel.SendConfirmAsync($"Removed the cost from the {Format.Bold(cmd.Name)} command.").ConfigureAwait(false); | ||||
|             //    else | ||||
|             //        await Context.Channel.SendConfirmAsync($"{Format.Bold(cmd.Name)} now costs {cost}{NadekoBot.BotConfig.CurrencySign} to run.").ConfigureAwait(false); | ||||
|             //} | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -517,7 +517,8 @@ namespace NadekoBot.Modules.Searches | ||||
|                                                                  .WithAuthor(eab => eab.WithUrl(link) | ||||
|                                                                                        .WithIconUrl("http://res.cloudinary.com/urbandictionary/image/upload/a_exif,c_fit,h_200,w_200/v1394975045/b8oszuu3tbq7ebyo7vo1.jpg") | ||||
|                                                                                        .WithName(query)) | ||||
|                                                                  .WithDescription(desc)); | ||||
|                                                                  .WithDescription(desc)) | ||||
|                                                                  .ConfigureAwait(false); | ||||
|             } | ||||
|             catch | ||||
|             { | ||||
| @@ -572,9 +573,9 @@ namespace NadekoBot.Modules.Searches | ||||
|                 var result = await http.GetStringAsync("https://en.wikipedia.org//w/api.php?action=query&format=json&prop=info&redirects=1&formatversion=2&inprop=url&titles=" + Uri.EscapeDataString(query)); | ||||
|                 var data = JsonConvert.DeserializeObject<WikipediaApiModel>(result); | ||||
|                 if (data.Query.Pages[0].Missing) | ||||
|                     await Context.Channel.SendErrorAsync("That page could not be found."); | ||||
|                     await Context.Channel.SendErrorAsync("That page could not be found.").ConfigureAwait(false); | ||||
|                 else | ||||
|                     await Context.Channel.SendMessageAsync(data.Query.Pages[0].FullUrl); | ||||
|                     await Context.Channel.SendMessageAsync(data.Query.Pages[0].FullUrl).ConfigureAwait(false); | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -588,7 +589,7 @@ namespace NadekoBot.Modules.Searches | ||||
|  | ||||
|             img.BackgroundColor(new ImageSharp.Color(color)); | ||||
|  | ||||
|             await Context.Channel.SendFileAsync(img.ToStream(), $"{color}.png"); | ||||
|             await Context.Channel.SendFileAsync(img.ToStream(), $"{color}.png").ConfigureAwait(false); ; | ||||
|         } | ||||
|  | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
| @@ -642,7 +643,7 @@ namespace NadekoBot.Modules.Searches | ||||
|                     var response = $@"`Title:` {found["title"].ToString()} | ||||
| `Quality:` {found["quality"]} | ||||
| `URL:` {await NadekoBot.Google.ShortenUrl(found["url"].ToString()).ConfigureAwait(false)}"; | ||||
|                     await Context.Channel.SendMessageAsync(response); | ||||
|                     await Context.Channel.SendMessageAsync(response).ConfigureAwait(false); | ||||
|                 } | ||||
|                 catch | ||||
|                 { | ||||
| @@ -774,20 +775,24 @@ namespace NadekoBot.Modules.Searches | ||||
|             } | ||||
|             try | ||||
|             { | ||||
|                 using (var http = new HttpClient()) | ||||
|                 var toReturn = await Task.Run(async () => | ||||
|                 { | ||||
|                     http.AddFakeHeaders(); | ||||
|                     var data = await http.GetStreamAsync(website); | ||||
|                     var doc = new XmlDocument(); | ||||
|                     doc.Load(data); | ||||
|                     using (var http = new HttpClient()) | ||||
|                     { | ||||
|                         http.AddFakeHeaders(); | ||||
|                         var data = await http.GetStreamAsync(website).ConfigureAwait(false); | ||||
|                         var doc = new XmlDocument(); | ||||
|                         doc.Load(data); | ||||
|  | ||||
|                     var node = doc.LastChild.ChildNodes[new NadekoRandom().Next(0, doc.LastChild.ChildNodes.Count)]; | ||||
|                         var node = doc.LastChild.ChildNodes[new NadekoRandom().Next(0, doc.LastChild.ChildNodes.Count)]; | ||||
|  | ||||
|                     var url = node.Attributes["file_url"].Value; | ||||
|                     if (!url.StartsWith("http")) | ||||
|                         url = "https:" + url; | ||||
|                     return url; | ||||
|                 } | ||||
|                         var url = node.Attributes["file_url"].Value; | ||||
|                         if (!url.StartsWith("http")) | ||||
|                             url = "https:" + url; | ||||
|                         return url; | ||||
|                     } | ||||
|                 }).ConfigureAwait(false); | ||||
|                 return toReturn; | ||||
|             } | ||||
|             catch | ||||
|             { | ||||
|   | ||||
| @@ -31,7 +31,7 @@ namespace NadekoBot.Modules.Utility | ||||
|                         var channel = imsg.Channel as ITextChannel; | ||||
|                         if (channel == null) | ||||
|                             return; | ||||
|                         if (msg.Author.Id == NadekoBot.Client.CurrentUser().Id) return; | ||||
|                         if (msg.Author.Id == NadekoBot.Client.CurrentUser.Id) return; | ||||
|                         foreach (var subscriber in Subscribers) | ||||
|                         { | ||||
|                             var set = subscriber.Value; | ||||
|   | ||||
| @@ -277,27 +277,25 @@ namespace NadekoBot.Modules.Utility | ||||
|                                           .WithIconUrl("https://cdn.discordapp.com/avatars/116275390695079945/b21045e778ef21c96d175400e779f0fb.jpg")) | ||||
|                     .AddField(efb => efb.WithName(Format.Bold("Author")).WithValue(stats.Author).WithIsInline(true)) | ||||
|                     .AddField(efb => efb.WithName(Format.Bold("Library")).WithValue(stats.Library).WithIsInline(true)) | ||||
|                     .AddField(efb => efb.WithName(Format.Bold("Bot ID")).WithValue(NadekoBot.Client.CurrentUser().Id.ToString()).WithIsInline(true)) | ||||
|                     .AddField(efb => efb.WithName(Format.Bold("Bot ID")).WithValue(NadekoBot.Client.CurrentUser.Id.ToString()).WithIsInline(true)) | ||||
|                     .AddField(efb => efb.WithName(Format.Bold("Commands Ran")).WithValue(stats.CommandsRan.ToString()).WithIsInline(true)) | ||||
|                     .AddField(efb => efb.WithName(Format.Bold("Messages")).WithValue($"{stats.MessageCounter} ({stats.MessagesPerSecond:F2}/sec)").WithIsInline(true)) | ||||
|                     .AddField(efb => efb.WithName(Format.Bold("Memory")).WithValue($"{stats.Heap} MB").WithIsInline(true)) | ||||
|                     .AddField(efb => efb.WithName(Format.Bold("Owner ID(s)")).WithValue(string.Join("\n", NadekoBot.Credentials.OwnerIds)).WithIsInline(true)) | ||||
|                     .AddField(efb => efb.WithName(Format.Bold("Uptime")).WithValue(stats.GetUptimeString("\n")).WithIsInline(true)) | ||||
|                     .AddField(efb => efb.WithName(Format.Bold("Presence")).WithValue($"{NadekoBot.Client.GetGuildsCount()} Servers\n{stats.TextChannels} Text Channels\n{stats.VoiceChannels} Voice Channels").WithIsInline(true)) | ||||
|                     .AddField(efb => efb.WithName(Format.Bold("Presence")).WithValue($"{NadekoBot.Client.GetGuildCount()} Servers\n{stats.TextChannels} Text Channels\n{stats.VoiceChannels} Voice Channels").WithIsInline(true)) | ||||
| #if !GLOBAL_NADEKO | ||||
|                     .WithFooter(efb => efb.WithText($"Playing {Music.Music.MusicPlayers.Where(mp => mp.Value.CurrentSong != null).Count()} songs, {Music.Music.MusicPlayers.Sum(mp => mp.Value.Playlist.Count)} queued.")) | ||||
| #endif | ||||
|                     ); | ||||
|         } | ||||
|  | ||||
|         private Regex emojiFinder { get; } = new Regex(@"<:(?<name>.+?):(?<id>\d*)>", RegexOptions.Compiled); | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
|         public async Task Showemojis([Remainder] string emojis) | ||||
|         { | ||||
|             var matches = emojiFinder.Matches(emojis); | ||||
|             var tags = Context.Message.Tags.Where(t => t.Type == TagType.Emoji).Select(t => (Emoji)t.Value); | ||||
|  | ||||
|             var result = string.Join("\n", matches.Cast<Match>() | ||||
|                                                   .Select(m => $"**Name:** {m.Groups["name"]} **Link:** http://discordapp.com/api/emojis/{m.Groups["id"]}.png")); | ||||
|             var result = string.Join("\n", tags.Select(m => $"**Name:** {m} **Link:** {m.Url}")); | ||||
|  | ||||
|             if (string.IsNullOrWhiteSpace(result)) | ||||
|                 await Context.Channel.SendErrorAsync("No special emojis found."); | ||||
|   | ||||
| @@ -28,7 +28,7 @@ namespace NadekoBot | ||||
|  | ||||
|         public static CommandService CommandService { get; private set; } | ||||
|         public static CommandHandler CommandHandler { get; private set; } | ||||
|         public static ShardedDiscordClient Client { get; private set; } | ||||
|         public static DiscordShardedClient Client { get; private set; } | ||||
|         public static BotCredentials Credentials { get; private set; } | ||||
|  | ||||
|         public static GoogleApiService Google { get; private set; } | ||||
| @@ -59,7 +59,7 @@ namespace NadekoBot | ||||
|             _log.Info("Starting NadekoBot v" + StatsService.BotVersion); | ||||
|  | ||||
|             //create client | ||||
|             Client = new ShardedDiscordClient(new DiscordSocketConfig | ||||
|             Client = new DiscordShardedClient(new DiscordSocketConfig | ||||
|             { | ||||
|                 AudioMode = Discord.Audio.AudioMode.Outgoing, | ||||
|                 MessageCacheSize = 10, | ||||
| @@ -67,6 +67,9 @@ namespace NadekoBot | ||||
|                 TotalShards = Credentials.TotalShards, | ||||
|                 ConnectionTimeout = int.MaxValue | ||||
|             }); | ||||
| #if GLOBAL_NADEKO | ||||
|             Client.Log += Client_Log; | ||||
| #endif | ||||
|  | ||||
|             //initialize Services | ||||
|             CommandService = new CommandService(new CommandServiceConfig() { | ||||
| @@ -93,9 +96,8 @@ namespace NadekoBot | ||||
|             //connect | ||||
|             await Client.LoginAsync(TokenType.Bot, Credentials.Token).ConfigureAwait(false); | ||||
|             await Client.ConnectAsync().ConfigureAwait(false); | ||||
| #if !GLOBAL_NADEKO | ||||
|             await Client.DownloadAllUsersAsync().ConfigureAwait(false); | ||||
| #endif | ||||
|             Stats.Initialize(); | ||||
|  | ||||
|             _log.Info("Connected"); | ||||
|  | ||||
| @@ -104,6 +106,7 @@ namespace NadekoBot | ||||
|             ModulePrefixes = new ConcurrentDictionary<string, string>(NadekoBot.BotConfig.ModulePrefixes.OrderByDescending(mp => mp.Prefix.Length).ToDictionary(m => m.ModuleName, m => m.Prefix)); | ||||
|  | ||||
|             // start handling messages received in commandhandler | ||||
|              | ||||
|             await CommandHandler.StartHandling().ConfigureAwait(false); | ||||
|  | ||||
|             await CommandService.AddModulesAsync(this.GetType().GetTypeInfo().Assembly).ConfigureAwait(false); | ||||
| @@ -114,6 +117,15 @@ namespace NadekoBot | ||||
|             Console.WriteLine(await Stats.Print().ConfigureAwait(false)); | ||||
|         } | ||||
|  | ||||
|         private Task Client_Log(LogMessage arg) | ||||
|         { | ||||
|             _log.Warn(arg.Source + " | " + arg.Message); | ||||
|             if (arg.Exception != null) | ||||
|                 _log.Warn(arg.Exception); | ||||
|  | ||||
|             return Task.CompletedTask; | ||||
|         } | ||||
|  | ||||
|         public async Task RunAndBlockAsync(params string[] args) | ||||
|         { | ||||
|             await RunAsync(args).ConfigureAwait(false); | ||||
|   | ||||
							
								
								
									
										81
									
								
								src/NadekoBot/Resources/CommandStrings.Designer.cs
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										81
									
								
								src/NadekoBot/Resources/CommandStrings.Designer.cs
									
									
									
										generated
									
									
									
								
							| @@ -1760,6 +1760,33 @@ namespace NadekoBot.Resources { | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///    Looks up a localized string similar to cmdcosts. | ||||
|         /// </summary> | ||||
|         public static string cmdcosts_cmd { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("cmdcosts_cmd", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///    Looks up a localized string similar to Shows a list of command costs. Paginated with 9 command per page.. | ||||
|         /// </summary> | ||||
|         public static string cmdcosts_desc { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("cmdcosts_desc", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///    Looks up a localized string similar to `{0}cmdcosts` or `{0}cmdcosts 2`. | ||||
|         /// </summary> | ||||
|         public static string cmdcosts_usage { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("cmdcosts_usage", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///    Looks up a localized string similar to color clr. | ||||
|         /// </summary> | ||||
| @@ -1787,6 +1814,33 @@ namespace NadekoBot.Resources { | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///    Looks up a localized string similar to commandcost cmdcost. | ||||
|         /// </summary> | ||||
|         public static string commandcost_cmd { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("commandcost_cmd", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///    Looks up a localized string similar to Sets a price for a command. Running that command will take currency from users. Set 0 to remove the price.. | ||||
|         /// </summary> | ||||
|         public static string commandcost_desc { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("commandcost_desc", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///    Looks up a localized string similar to `{0}cmdcost 0 !!q` or `{0}cmdcost 1 >8ball`. | ||||
|         /// </summary> | ||||
|         public static string commandcost_usage { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("commandcost_usage", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///    Looks up a localized string similar to commands cmds. | ||||
|         /// </summary> | ||||
| @@ -7241,6 +7295,33 @@ namespace NadekoBot.Resources { | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///    Looks up a localized string similar to startevent. | ||||
|         /// </summary> | ||||
|         public static string startevent_cmd { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("startevent_cmd", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///    Looks up a localized string similar to Starts one of the events seen on public nadeko.. | ||||
|         /// </summary> | ||||
|         public static string startevent_desc { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("startevent_desc", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///    Looks up a localized string similar to `{0}startevent flowerreaction`. | ||||
|         /// </summary> | ||||
|         public static string startevent_usage { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("startevent_usage", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///    Looks up a localized string similar to startwar sw. | ||||
|         /// </summary> | ||||
|   | ||||
| @@ -2925,4 +2925,31 @@ | ||||
|   <data name="antispamignore_usage" xml:space="preserve"> | ||||
|     <value>`{0}antispamignore`</value> | ||||
|   </data> | ||||
|   <data name="cmdcosts_cmd" xml:space="preserve"> | ||||
|     <value>cmdcosts</value> | ||||
|   </data> | ||||
|   <data name="cmdcosts_desc" xml:space="preserve"> | ||||
|     <value>Shows a list of command costs. Paginated with 9 command per page.</value> | ||||
|   </data> | ||||
|   <data name="cmdcosts_usage" xml:space="preserve"> | ||||
|     <value>`{0}cmdcosts` or `{0}cmdcosts 2`</value> | ||||
|   </data> | ||||
|   <data name="commandcost_cmd" xml:space="preserve"> | ||||
|     <value>commandcost cmdcost</value> | ||||
|   </data> | ||||
|   <data name="commandcost_desc" xml:space="preserve"> | ||||
|     <value>Sets a price for a command. Running that command will take currency from users. Set 0 to remove the price.</value> | ||||
|   </data> | ||||
|   <data name="commandcost_usage" xml:space="preserve"> | ||||
|     <value>`{0}cmdcost 0 !!q` or `{0}cmdcost 1 >8ball`</value> | ||||
|   </data> | ||||
|   <data name="startevent_cmd" xml:space="preserve"> | ||||
|     <value>startevent</value> | ||||
|   </data> | ||||
|   <data name="startevent_desc" xml:space="preserve"> | ||||
|     <value>Starts one of the events seen on public nadeko.</value> | ||||
|   </data> | ||||
|   <data name="startevent_usage" xml:space="preserve"> | ||||
|     <value>`{0}startevent flowerreaction`</value> | ||||
|   </data> | ||||
| </root> | ||||
| @@ -32,9 +32,9 @@ namespace NadekoBot.Services | ||||
|     { | ||||
|         public const int GlobalCommandsCooldown = 1500; | ||||
|  | ||||
|         private ShardedDiscordClient _client; | ||||
|         private CommandService _commandService; | ||||
|         private Logger _log; | ||||
|         private readonly DiscordShardedClient _client; | ||||
|         private readonly CommandService _commandService; | ||||
|         private readonly Logger _log; | ||||
|  | ||||
|         private List<IDMChannel> ownerChannels { get; set; } | ||||
|  | ||||
| @@ -46,7 +46,7 @@ namespace NadekoBot.Services | ||||
|         public ConcurrentHashSet<ulong> UsersOnShortCooldown { get; } = new ConcurrentHashSet<ulong>(); | ||||
|         private Timer clearUsersOnShortCooldown { get; } | ||||
|  | ||||
|         public CommandHandler(ShardedDiscordClient client, CommandService commandService) | ||||
|         public CommandHandler(DiscordShardedClient client, CommandService commandService) | ||||
|         { | ||||
|             _client = client; | ||||
|             _commandService = commandService; | ||||
| @@ -100,8 +100,8 @@ namespace NadekoBot.Services | ||||
|             BlacklistCommands.BlacklistedChannels.Contains(usrMsg.Channel.Id) || | ||||
|             BlacklistCommands.BlacklistedUsers.Contains(usrMsg.Author.Id); | ||||
|  | ||||
|  | ||||
|         private async Task LogSuccessfulExecution(SocketUserMessage usrMsg, ExecuteCommandResult exec, SocketTextChannel channel, Stopwatch sw) | ||||
|         const float oneThousandth = 1.0f / 1000; | ||||
|         private async Task LogSuccessfulExecution(SocketUserMessage usrMsg, ExecuteCommandResult exec, SocketTextChannel channel, int ticks) | ||||
|         { | ||||
|             await CommandExecuted(usrMsg, exec.CommandInfo).ConfigureAwait(false); | ||||
|             _log.Info("Command Executed after {4}s\n\t" + | ||||
| @@ -113,10 +113,10 @@ namespace NadekoBot.Services | ||||
|                         (channel == null ? "PRIVATE" : channel.Guild.Name + " [" + channel.Guild.Id + "]"), // {1} | ||||
|                         (channel == null ? "PRIVATE" : channel.Name + " [" + channel.Id + "]"), // {2} | ||||
|                         usrMsg.Content, // {3} | ||||
|                         sw.Elapsed.TotalSeconds); | ||||
|                         ticks * oneThousandth); | ||||
|         } | ||||
|  | ||||
|         private void LogErroredExecution(SocketUserMessage usrMsg, ExecuteCommandResult exec, SocketTextChannel channel, Stopwatch sw) | ||||
|         private void LogErroredExecution(SocketUserMessage usrMsg, ExecuteCommandResult exec, SocketTextChannel channel, int ticks) | ||||
|         { | ||||
|             _log.Warn("Command Errored after {5}s\n\t" + | ||||
|                                 "User: {0}\n\t" + | ||||
| @@ -129,7 +129,7 @@ namespace NadekoBot.Services | ||||
|                                 (channel == null ? "PRIVATE" : channel.Name + " [" + channel.Id + "]"), // {2} | ||||
|                                 usrMsg.Content,// {3} | ||||
|                                 exec.Result.ErrorReason, // {4} | ||||
|                                 sw.Elapsed.TotalSeconds // {5} | ||||
|                                 ticks * oneThousandth // {5} | ||||
|                                 ); | ||||
|         } | ||||
|  | ||||
| @@ -180,13 +180,15 @@ namespace NadekoBot.Services | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         private async void MessageReceivedHandler(SocketMessage msg) | ||||
|         private async Task MessageReceivedHandler(SocketMessage msg) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 if (msg.Author.IsBot || !NadekoBot.Ready) //no bots, wait until bot connected and initialized | ||||
|                     return; | ||||
|  | ||||
|                 var execTime = Environment.TickCount; | ||||
|  | ||||
|                 var usrMsg = msg as SocketUserMessage; | ||||
|                 if (usrMsg == null) //has to be an user message, not system/other messages. | ||||
|                     return; | ||||
| @@ -226,17 +228,16 @@ namespace NadekoBot.Services | ||||
|                 string messageContent = usrMsg.Content; | ||||
|  | ||||
|                 // execute the command and measure the time it took | ||||
|                 var sw = Stopwatch.StartNew(); | ||||
|                 var exec = await ExecuteCommand(new CommandContext(_client.MainClient, usrMsg), messageContent, DependencyMap.Empty, MultiMatchHandling.Best); | ||||
|                 sw.Stop(); | ||||
|                 var exec = await ExecuteCommand(new CommandContext(_client, usrMsg), messageContent, DependencyMap.Empty, MultiMatchHandling.Best); | ||||
|                 execTime = Environment.TickCount - execTime; | ||||
|  | ||||
|                 if (exec.Result.IsSuccess) | ||||
|                 { | ||||
|                     await LogSuccessfulExecution(usrMsg, exec, channel, sw).ConfigureAwait(false); | ||||
|                     await LogSuccessfulExecution(usrMsg, exec, channel, execTime).ConfigureAwait(false); | ||||
|                 } | ||||
|                 else if (!exec.Result.IsSuccess && exec.Result.Error != CommandError.UnknownCommand) | ||||
|                 { | ||||
|                     LogErroredExecution(usrMsg, exec, channel, sw); | ||||
|                     LogErroredExecution(usrMsg, exec, channel, execTime); | ||||
|                     if (guild != null && exec.CommandInfo != null && exec.Result.Error == CommandError.Exception) | ||||
|                     { | ||||
|                         if (exec.PermissionCache != null && exec.PermissionCache.Verbose) | ||||
| @@ -354,6 +355,16 @@ namespace NadekoBot.Services | ||||
|                             return new ExecuteCommandResult(cmd, pc, SearchResult.FromError(CommandError.Exception, $"You need the **{pc.PermRole}** role in order to use permission commands.")); | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     int price; | ||||
|                     if (Permissions.CommandCostCommands.CommandCosts.TryGetValue(cmd.Aliases.First().Trim().ToLowerInvariant(), out price) && price > 0) | ||||
|                     { | ||||
|                         var success = await CurrencyHandler.RemoveCurrencyAsync(context.User.Id, $"Running {cmd.Name} command.", price).ConfigureAwait(false); | ||||
|                         if (!success) | ||||
|                         { | ||||
|                             return new ExecuteCommandResult(cmd, pc, SearchResult.FromError(CommandError.Exception, $"Insufficient funds. You need {price}{NadekoBot.BotConfig.CurrencySign} to run this command.")); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -31,6 +31,11 @@ namespace NadekoBot.Services.Database.Models | ||||
|         public float Betroll67Multiplier { get; set; } = 2; | ||||
|         public float Betroll91Multiplier { get; set; } = 3; | ||||
|         public float Betroll100Multiplier { get; set; } = 10; | ||||
|         //public HashSet<CommandCost> CommandCosts { get; set; } = new HashSet<CommandCost>(); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// I messed up, don't use | ||||
|         /// </summary> | ||||
|         public HashSet<CommandPrice> CommandPrices { get; set; } = new HashSet<CommandPrice>(); | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										27
									
								
								src/NadekoBot/Services/Database/Models/CommandCost.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/NadekoBot/Services/Database/Models/CommandCost.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
|  | ||||
| namespace NadekoBot.Services.Database.Models | ||||
| { | ||||
|     public class CommandCost : DbEntity | ||||
|     { | ||||
|         public int Cost { get; set; } | ||||
|         public string CommandName { get; set; } | ||||
|  | ||||
|         public override int GetHashCode() => | ||||
|             CommandName.GetHashCode(); | ||||
|  | ||||
|         public override bool Equals(object obj) | ||||
|         { | ||||
|             var instance = obj as CommandCost; | ||||
|  | ||||
|             if (instance == null) | ||||
|                 return false; | ||||
|  | ||||
|             return instance.CommandName == CommandName; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -11,18 +11,5 @@ namespace NadekoBot.Services.Database.Models | ||||
|         public int Price { get; set; } | ||||
|         //this is unique | ||||
|         public string CommandName { get; set; } | ||||
|  | ||||
|         public override int GetHashCode() =>  | ||||
|             CommandName.GetHashCode(); | ||||
|  | ||||
|         public override bool Equals(object obj) | ||||
|         { | ||||
|             var instance = obj as CommandPrice; | ||||
|  | ||||
|             if (instance == null) | ||||
|                 return false; | ||||
|  | ||||
|             return instance.CommandName == CommandName; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -235,9 +235,14 @@ namespace NadekoBot.Services.Database | ||||
|             #endregion | ||||
|  | ||||
|             #region CommandPrice | ||||
|             //well, i failed | ||||
|             modelBuilder.Entity<CommandPrice>() | ||||
|                 .HasIndex(cp => cp.Price) | ||||
|                 .IsUnique(); | ||||
|  | ||||
|             //modelBuilder.Entity<CommandCost>() | ||||
|             //    .HasIndex(cp => cp.CommandName) | ||||
|             //    .IsUnique(); | ||||
|             #endregion | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -17,6 +17,7 @@ namespace NadekoBot.Services.Database.Repositories.Impl | ||||
|                              .Include(bc => bc.Blacklist) | ||||
|                              .Include(bc => bc.EightBallResponses) | ||||
|                              .Include(bc => bc.ModulePrefixes) | ||||
|                              //.Include(bc => bc.CommandCosts) | ||||
|                              .FirstOrDefault(); | ||||
|  | ||||
|             if (config == null) | ||||
|   | ||||
| @@ -26,7 +26,7 @@ namespace NadekoBot.Services.Discord | ||||
|             NadekoBot.Client.ReactionsCleared += Discord_ReactionsCleared; | ||||
|         } | ||||
|  | ||||
|         private void Discord_ReactionsCleared(ulong messageId, Optional<SocketUserMessage> reaction) | ||||
|         private Task Discord_ReactionsCleared(ulong messageId, Optional<SocketUserMessage> reaction) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
| @@ -34,9 +34,11 @@ namespace NadekoBot.Services.Discord | ||||
|                     OnReactionsCleared?.Invoke(); | ||||
|             } | ||||
|             catch { } | ||||
|  | ||||
|             return Task.CompletedTask; | ||||
|         } | ||||
|  | ||||
|         private void Discord_ReactionRemoved(ulong messageId, Optional<SocketUserMessage> arg2, SocketReaction reaction) | ||||
|         private Task Discord_ReactionRemoved(ulong messageId, Optional<SocketUserMessage> arg2, SocketReaction reaction) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
| @@ -44,9 +46,11 @@ namespace NadekoBot.Services.Discord | ||||
|                     OnReactionRemoved?.Invoke(reaction); | ||||
|             } | ||||
|             catch { } | ||||
|  | ||||
|             return Task.CompletedTask; | ||||
|         } | ||||
|  | ||||
|         private void Discord_ReactionAdded(ulong messageId, Optional<SocketUserMessage> message, SocketReaction reaction) | ||||
|         private Task Discord_ReactionAdded(ulong messageId, Optional<SocketUserMessage> message, SocketReaction reaction) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
| @@ -54,6 +58,8 @@ namespace NadekoBot.Services.Discord | ||||
|                     OnReactionAdded?.Invoke(reaction); | ||||
|             } | ||||
|             catch { } | ||||
|  | ||||
|             return Task.CompletedTask; | ||||
|         } | ||||
|  | ||||
|         public void UnsubAll() | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| using Discord; | ||||
| using Discord.WebSocket; | ||||
| using NadekoBot.Extensions; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| @@ -11,10 +12,10 @@ namespace NadekoBot.Services.Impl | ||||
| { | ||||
|     public class StatsService : IStatsService | ||||
|     { | ||||
|         private ShardedDiscordClient client; | ||||
|         private DiscordShardedClient client; | ||||
|         private DateTime started; | ||||
|  | ||||
|         public const string BotVersion = "1.1.0"; | ||||
|         public const string BotVersion = "1.1.1"; | ||||
|  | ||||
|         public string Author => "Kwoth#2560"; | ||||
|         public string Library => "Discord.Net"; | ||||
| @@ -30,7 +31,7 @@ namespace NadekoBot.Services.Impl | ||||
|  | ||||
|         Timer carbonitexTimer { get; } | ||||
|  | ||||
|         public StatsService(ShardedDiscordClient client, CommandHandler cmdHandler) | ||||
|         public StatsService(DiscordShardedClient client, CommandHandler cmdHandler) | ||||
|         { | ||||
|  | ||||
|             this.client = client; | ||||
| @@ -39,21 +40,14 @@ namespace NadekoBot.Services.Impl | ||||
|             this.client.MessageReceived += _ => Task.FromResult(MessageCounter++); | ||||
|             cmdHandler.CommandExecuted += (_, e) => Task.FromResult(CommandsRan++); | ||||
|  | ||||
|             this.client.Disconnected += _ => Reset(); | ||||
|  | ||||
|             this.client.Connected += () => | ||||
|             { | ||||
|                 var guilds = this.client.GetGuilds(); | ||||
|                 _textChannels = guilds.Sum(g => g.Channels.Where(cx => cx is ITextChannel).Count()); | ||||
|                 _voiceChannels = guilds.Sum(g => g.Channels.Count) - _textChannels; | ||||
|             }; | ||||
|  | ||||
|             this.client.ChannelCreated += (c) => | ||||
|             { | ||||
|                 if (c is ITextChannel) | ||||
|                     ++_textChannels; | ||||
|                 else if (c is IVoiceChannel) | ||||
|                     ++_voiceChannels; | ||||
|  | ||||
|                 return Task.CompletedTask; | ||||
|             }; | ||||
|  | ||||
|             this.client.ChannelDestroyed += (c) => | ||||
| @@ -62,6 +56,8 @@ namespace NadekoBot.Services.Impl | ||||
|                     --_textChannels; | ||||
|                 else if (c is IVoiceChannel) | ||||
|                     --_voiceChannels; | ||||
|  | ||||
|                 return Task.CompletedTask; | ||||
|             }; | ||||
|  | ||||
|             this.client.JoinedGuild += (g) => | ||||
| @@ -70,6 +66,8 @@ namespace NadekoBot.Services.Impl | ||||
|                 var vc = g.Channels.Count - tc; | ||||
|                 _textChannels += tc; | ||||
|                 _voiceChannels += vc; | ||||
|  | ||||
|                 return Task.CompletedTask; | ||||
|             }; | ||||
|  | ||||
|             this.client.LeftGuild += (g) => | ||||
| @@ -78,6 +76,8 @@ namespace NadekoBot.Services.Impl | ||||
|                 var vc = g.Channels.Count - tc; | ||||
|                 _textChannels -= tc; | ||||
|                 _voiceChannels -= vc; | ||||
|  | ||||
|                 return Task.CompletedTask; | ||||
|             }; | ||||
|  | ||||
|             this.carbonitexTimer = new Timer(async (state) => | ||||
| @@ -90,7 +90,7 @@ namespace NadekoBot.Services.Impl | ||||
|                     { | ||||
|                         using (var content = new FormUrlEncodedContent( | ||||
|                             new Dictionary<string, string> { | ||||
|                                 { "servercount", this.client.GetGuildsCount().ToString() }, | ||||
|                                 { "servercount", this.client.GetGuildCount().ToString() }, | ||||
|                                 { "key", NadekoBot.Credentials.CarbonKey }})) | ||||
|                         { | ||||
|                             content.Headers.Clear(); | ||||
| @@ -103,16 +103,24 @@ namespace NadekoBot.Services.Impl | ||||
|                 catch { } | ||||
|             }, null, TimeSpan.FromHours(1), TimeSpan.FromHours(1)); | ||||
|         } | ||||
|  | ||||
|         public void Initialize() | ||||
|         { | ||||
|             var guilds = this.client.GetGuilds(); | ||||
|             _textChannels = guilds.Sum(g => g.Channels.Where(cx => cx is ITextChannel).Count()); | ||||
|             _voiceChannels = guilds.Sum(g => g.Channels.Count) - _textChannels; | ||||
|         } | ||||
|  | ||||
|         public Task<string> Print() | ||||
|         { | ||||
|             var curUser = client.CurrentUser(); | ||||
|             var curUser = client.CurrentUser; | ||||
|             return Task.FromResult($@" | ||||
| Author: [{Author}] | Library: [{Library}] | ||||
| Bot Version: [{BotVersion}] | ||||
| Bot ID: {curUser.Id} | ||||
| Owner ID(s): {string.Join(", ", NadekoBot.Credentials.OwnerIds)} | ||||
| Uptime: {GetUptimeString()} | ||||
| Servers: {client.GetGuildsCount()} | TextChannels: {TextChannels} | VoiceChannels: {VoiceChannels} | ||||
| Servers: {client.GetGuildCount()} | TextChannels: {TextChannels} | VoiceChannels: {VoiceChannels} | ||||
| Commands Ran this session: {CommandsRan} | ||||
| Messages: {MessageCounter} [{MessagesPerSecond:F2}/sec] Heap: [{Heap} MB]"); | ||||
|         } | ||||
|   | ||||
| @@ -60,7 +60,8 @@ namespace NadekoBot | ||||
|                 client.MessageReceived += arg1 => | ||||
|                 { | ||||
|                     if (arg1.Author == null || arg1.Author.IsBot) | ||||
|                         return Task.CompletedTask; MessageReceived(arg1); | ||||
|                         return Task.CompletedTask; | ||||
|                     MessageReceived(arg1); | ||||
|                     return Task.CompletedTask; | ||||
|                 }; | ||||
|                 client.UserLeft += arg1 => { UserLeft(arg1); return Task.CompletedTask; }; | ||||
| @@ -107,7 +108,7 @@ namespace NadekoBot | ||||
|         public DiscordSocketClient MainClient => | ||||
|             Clients[0]; | ||||
|  | ||||
|         public SocketSelfUser CurrentUser() => | ||||
|         public SocketSelfUser CurrentUser => | ||||
|             Clients[0].CurrentUser; | ||||
|  | ||||
|         public IEnumerable<SocketGuild> GetGuilds() => | ||||
| @@ -178,26 +179,9 @@ namespace NadekoBot | ||||
|         public Task SetGame(string game) => Task.WhenAll(Clients.Select(ms => ms.SetGameAsync(game))); | ||||
|  | ||||
|  | ||||
|         public Task SetStream(string name, string url) => Task.WhenAll(Clients.Select(ms => ms.SetGameAsync(name, url, StreamType.NotStreaming))); | ||||
|         public Task SetStream(string name, string url) => Task.WhenAll(Clients.Select(ms => ms.SetGameAsync(name, url, StreamType.Twitch))); | ||||
|  | ||||
|         public Task SetStatus(SettableUserStatus status) => Task.WhenAll(Clients.Select(ms => ms.SetStatusAsync(SettableUserStatusToUserStatus(status)))); | ||||
|  | ||||
|         private static UserStatus SettableUserStatusToUserStatus(SettableUserStatus sus) | ||||
|         { | ||||
|             switch (sus) | ||||
|             { | ||||
|                 case SettableUserStatus.Online: | ||||
|                     return UserStatus.Online; | ||||
|                 case SettableUserStatus.Invisible: | ||||
|                     return UserStatus.Invisible; | ||||
|                 case SettableUserStatus.Idle: | ||||
|                     return UserStatus.AFK; | ||||
|                 case SettableUserStatus.Dnd: | ||||
|                     return UserStatus.DoNotDisturb; | ||||
|             } | ||||
|  | ||||
|             return UserStatus.Online; | ||||
|         } | ||||
|         //public Task SetStatus(SettableUserStatus status) => Task.WhenAll(Clients.Select(ms => ms.SetStatusAsync(SettableUserStatusToUserStatus(status)))); | ||||
|     } | ||||
|  | ||||
|     public enum SettableUserStatus | ||||
|   | ||||
| @@ -24,10 +24,13 @@ namespace NadekoBot.Extensions | ||||
|         /// <summary> | ||||
|         /// danny kamisama | ||||
|         /// </summary> | ||||
|         public static async Task SendPaginatedConfirmAsync(this IMessageChannel channel, int currentPage, Func<int, EmbedBuilder> pageFunc, int? lastPage = null) | ||||
|         public static async Task SendPaginatedConfirmAsync(this IMessageChannel channel, int currentPage, Func<int, EmbedBuilder> pageFunc, int? lastPage = null, bool addPaginatedFooter = true) | ||||
|         { | ||||
|             lastPage += 1; | ||||
|             var embed = pageFunc(currentPage).AddPaginatedFooter(currentPage, lastPage); | ||||
|             var embed = pageFunc(currentPage); | ||||
|  | ||||
|             if(addPaginatedFooter) | ||||
|                 embed.AddPaginatedFooter(currentPage, lastPage); | ||||
|  | ||||
|             var msg = await channel.EmbedAsync(embed) as IUserMessage; | ||||
|  | ||||
| @@ -47,12 +50,20 @@ namespace NadekoBot.Extensions | ||||
|                     { | ||||
|                         if (currentPage == 1) | ||||
|                             return; | ||||
|                         await msg.ModifyAsync(x => x.Embed = pageFunc(--currentPage).AddPaginatedFooter(currentPage, lastPage).Build()).ConfigureAwait(false); | ||||
|                         var toSend = pageFunc(--currentPage); | ||||
|                         if (addPaginatedFooter) | ||||
|                             toSend.AddPaginatedFooter(currentPage, lastPage); | ||||
|                         await msg.ModifyAsync(x => x.Embed = toSend.Build()).ConfigureAwait(false); | ||||
|                     } | ||||
|                     else if (r.Emoji.Name == arrow_right) | ||||
|                     { | ||||
|                         if (lastPage == null || lastPage > currentPage) | ||||
|                             await msg.ModifyAsync(x => x.Embed = pageFunc(++currentPage).AddPaginatedFooter(currentPage, lastPage).Build()).ConfigureAwait(false); | ||||
|                         { | ||||
|                             var toSend = pageFunc(++currentPage); | ||||
|                             if (addPaginatedFooter) | ||||
|                                 toSend.AddPaginatedFooter(currentPage, lastPage); | ||||
|                             await msg.ModifyAsync(x => x.Embed = toSend.Build()).ConfigureAwait(false); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 catch (Exception ex) { Console.WriteLine(ex); } | ||||
| @@ -192,7 +203,7 @@ namespace NadekoBot.Extensions | ||||
|             await (await user.CreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(fileStream, fileName, caption, isTTS).ConfigureAwait(false); | ||||
|  | ||||
|         public static bool IsAuthor(this IUserMessage msg) => | ||||
|             NadekoBot.Client.CurrentUser().Id == msg.Author.Id; | ||||
|             NadekoBot.Client.CurrentUser.Id == msg.Author.Id; | ||||
|  | ||||
|         public static IEnumerable<IUser> Members(this IRole role) => | ||||
|             role.Guild.GetUsersAsync().GetAwaiter().GetResult().Where(u => u.RoleIds.Contains(role.Id)) ?? Enumerable.Empty<IUser>(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user