From b381ee00b6ca69d05cbac4193fa022e128f43f09 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Mon, 19 Jun 2017 15:42:10 +0200 Subject: [PATCH] Huge changes to make shards run in separate processes --- .../ModuleBehaviors/IEarlyBlockingExecutor.cs | 2 +- .../ModuleBehaviors/ILateBlocker.cs | 2 +- .../ModuleBehaviors/ILateExecutor.cs | 2 +- .../ShardCom/IShardComMessage.cs | 16 +++ .../DataStructures/ShardCom/ShardComClient.cs | 22 +++ .../DataStructures/ShardCom/ShardComServer.cs | 36 +++++ .../TypeReaders/GuildTypeReader.cs | 4 +- .../Commands/SelfAssignedRolesCommand.cs | 2 +- .../Administration/Commands/SelfCommands.cs | 54 +++---- .../Commands/TimeZoneCommands.cs | 2 +- .../CustomReactions/CustomReactions.cs | 4 +- .../Modules/Gambling/Commands/AnimalRacing.cs | 8 +- .../Gambling/Commands/CurrencyEvents.cs | 8 +- .../Modules/Gambling/Commands/FlowerShop.cs | 4 +- .../Modules/Games/Commands/Acropobia.cs | 8 +- .../Games/Commands/Hangman/HangmanGame.cs | 4 +- .../Modules/Games/Commands/HangmanCommands.cs | 4 +- .../Games/Commands/Models/TypingGame.cs | 4 +- .../Modules/Games/Commands/PollCommands.cs | 4 +- .../Games/Commands/SpeedTypingCommands.cs | 4 +- .../Modules/Games/Commands/TicTacToe.cs | 8 +- .../Games/Commands/Trivia/TriviaGame.cs | 4 +- .../Modules/Games/Commands/TriviaCommands.cs | 4 +- src/NadekoBot/Modules/Music/Music.cs | 4 +- src/NadekoBot/Modules/NadekoModule.cs | 7 +- .../Permissions/Commands/FilterCommands.cs | 2 +- .../Utility/Commands/CommandMapCommands.cs | 4 +- .../Modules/Utility/Commands/InfoCommands.cs | 4 +- .../Utility/Commands/RepeatCommands.cs | 4 +- src/NadekoBot/Modules/Utility/Utility.cs | 80 ++++++----- src/NadekoBot/NadekoBot.cs | 136 ++++++++++++------ src/NadekoBot/Program.cs | 11 +- src/NadekoBot/Properties/launchSettings.json | 8 ++ .../Administration/AutoAssignRoleService.cs | 4 +- .../Administration/GameVoiceChannelService.cs | 4 +- .../Administration/LogCommandService.cs | 80 +++++------ .../Services/Administration/MuteService.cs | 4 +- .../Administration/PlayingRotateService.cs | 26 ++-- .../Administration/ProtectionService.cs | 4 +- .../Administration/RatelimitService.cs | 4 +- .../Services/Administration/SelfService.cs | 24 ++-- .../Services/Administration/VcRoleService.cs | 4 +- .../Services/Administration/VplusTService.cs | 4 +- .../ClashOfClans/ClashOfClansService.cs | 4 +- src/NadekoBot/Services/CommandHandler.cs | 4 +- .../CustomReactions/CustomReactionsService.cs | 9 +- .../Services/CustomReactions/Extensions.cs | 12 +- .../Repositories/IGuildConfigRepository.cs | 2 +- .../Impl/GuildConfigRepository.cs | 6 +- .../Discord/SocketMessageEventWrapper.cs | 4 +- .../Services/Games/ChatterbotService.cs | 6 +- src/NadekoBot/Services/Games/GamesService.cs | 4 +- src/NadekoBot/Services/Games/Poll.cs | 4 +- src/NadekoBot/Services/Games/PollService.cs | 6 +- .../Services/GreetSettingsService.cs | 4 +- src/NadekoBot/Services/Help/HelpService.cs | 2 +- src/NadekoBot/Services/IBotCredentials.cs | 1 + src/NadekoBot/Services/IImagesService.cs | 2 +- src/NadekoBot/Services/Impl/ImagesService.cs | 8 +- src/NadekoBot/Services/Impl/StatsService.cs | 53 +++---- src/NadekoBot/Services/LogSetup.cs | 28 ++++ .../Services/Permissions/CmdCdService.cs | 2 +- .../Services/Permissions/FilterService.cs | 2 +- .../Permissions/GlobalPermissionService.cs | 2 +- .../Permissions/PermissionsService.cs | 5 +- .../Services/Searches/SearchesService.cs | 4 +- .../Searches/StreamNotificationService.cs | 4 +- .../Utility/MessageRepeaterService.cs | 2 +- .../Services/Utility/RemindService.cs | 4 +- .../Services/Utility/RepeatRunner.cs | 2 +- .../Services/Utility/UtilityService.cs | 4 +- src/NadekoBot/ShardsCoordinator.cs | 95 ++++++++++++ src/NadekoBot/_Extensions/Extensions.cs | 4 +- 73 files changed, 586 insertions(+), 331 deletions(-) create mode 100644 src/NadekoBot/DataStructures/ShardCom/IShardComMessage.cs create mode 100644 src/NadekoBot/DataStructures/ShardCom/ShardComClient.cs create mode 100644 src/NadekoBot/DataStructures/ShardCom/ShardComServer.cs create mode 100644 src/NadekoBot/Properties/launchSettings.json create mode 100644 src/NadekoBot/Services/LogSetup.cs create mode 100644 src/NadekoBot/ShardsCoordinator.cs diff --git a/src/NadekoBot/DataStructures/ModuleBehaviors/IEarlyBlockingExecutor.cs b/src/NadekoBot/DataStructures/ModuleBehaviors/IEarlyBlockingExecutor.cs index f28eaf4f..a3e004b1 100644 --- a/src/NadekoBot/DataStructures/ModuleBehaviors/IEarlyBlockingExecutor.cs +++ b/src/NadekoBot/DataStructures/ModuleBehaviors/IEarlyBlockingExecutor.cs @@ -13,6 +13,6 @@ namespace NadekoBot.DataStructures.ModuleBehaviors /// Try to execute some logic within some module's service. /// /// Whether it should block other command executions after it. - Task TryExecuteEarly(DiscordShardedClient client, IGuild guild, IUserMessage msg); + Task TryExecuteEarly(DiscordSocketClient client, IGuild guild, IUserMessage msg); } } diff --git a/src/NadekoBot/DataStructures/ModuleBehaviors/ILateBlocker.cs b/src/NadekoBot/DataStructures/ModuleBehaviors/ILateBlocker.cs index 3b3fc020..68f33206 100644 --- a/src/NadekoBot/DataStructures/ModuleBehaviors/ILateBlocker.cs +++ b/src/NadekoBot/DataStructures/ModuleBehaviors/ILateBlocker.cs @@ -6,7 +6,7 @@ namespace NadekoBot.DataStructures.ModuleBehaviors { public interface ILateBlocker { - Task TryBlockLate(DiscordShardedClient client, IUserMessage msg, IGuild guild, + Task TryBlockLate(DiscordSocketClient client, IUserMessage msg, IGuild guild, IMessageChannel channel, IUser user, string moduleName, string commandName); } } diff --git a/src/NadekoBot/DataStructures/ModuleBehaviors/ILateExecutor.cs b/src/NadekoBot/DataStructures/ModuleBehaviors/ILateExecutor.cs index 3cf11603..a7b3e52e 100644 --- a/src/NadekoBot/DataStructures/ModuleBehaviors/ILateExecutor.cs +++ b/src/NadekoBot/DataStructures/ModuleBehaviors/ILateExecutor.cs @@ -9,6 +9,6 @@ namespace NadekoBot.DataStructures.ModuleBehaviors /// public interface ILateExecutor { - Task LateExecute(DiscordShardedClient client, IGuild guild, IUserMessage msg); + Task LateExecute(DiscordSocketClient client, IGuild guild, IUserMessage msg); } } diff --git a/src/NadekoBot/DataStructures/ShardCom/IShardComMessage.cs b/src/NadekoBot/DataStructures/ShardCom/IShardComMessage.cs new file mode 100644 index 00000000..9fb1f5d0 --- /dev/null +++ b/src/NadekoBot/DataStructures/ShardCom/IShardComMessage.cs @@ -0,0 +1,16 @@ +using Discord; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NadekoBot.DataStructures.ShardCom +{ + public class ShardComMessage + { + public int ShardId { get; set; } + public ConnectionState ConnectionState { get; set; } + public int Guilds { get; set; } + } +} diff --git a/src/NadekoBot/DataStructures/ShardCom/ShardComClient.cs b/src/NadekoBot/DataStructures/ShardCom/ShardComClient.cs new file mode 100644 index 00000000..a8857f3e --- /dev/null +++ b/src/NadekoBot/DataStructures/ShardCom/ShardComClient.cs @@ -0,0 +1,22 @@ +using Newtonsoft.Json; +using System; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; + +namespace NadekoBot.DataStructures.ShardCom +{ + public class ShardComClient + { + public async Task Send(ShardComMessage data) + { + var msg = JsonConvert.SerializeObject(data); + using (var client = new UdpClient()) + { + var bytes = Encoding.UTF8.GetBytes(msg); + await client.SendAsync(bytes, bytes.Length, IPAddress.Loopback.ToString(), ShardComServer.Port).ConfigureAwait(false); + } + } + } +} diff --git a/src/NadekoBot/DataStructures/ShardCom/ShardComServer.cs b/src/NadekoBot/DataStructures/ShardCom/ShardComServer.cs new file mode 100644 index 00000000..61c35a85 --- /dev/null +++ b/src/NadekoBot/DataStructures/ShardCom/ShardComServer.cs @@ -0,0 +1,36 @@ +using Newtonsoft.Json; +using System; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; + +namespace NadekoBot.DataStructures.ShardCom +{ + public class ShardComServer : IDisposable + { + public const int Port = 5664; + private readonly UdpClient _client = new UdpClient(Port); + + public void Start() + { + Task.Run(async () => + { + var ip = new IPEndPoint(IPAddress.Any, 0); + while (true) + { + var recv = await _client.ReceiveAsync(); + var data = Encoding.UTF8.GetString(recv.Buffer); + var _ = OnDataReceived(JsonConvert.DeserializeObject(data)); + } + }); + } + + public void Dispose() + { + _client.Dispose(); + } + + public event Func OnDataReceived = delegate { return Task.CompletedTask; }; + } +} diff --git a/src/NadekoBot/DataStructures/TypeReaders/GuildTypeReader.cs b/src/NadekoBot/DataStructures/TypeReaders/GuildTypeReader.cs index 63971f5a..3bb72d4c 100644 --- a/src/NadekoBot/DataStructures/TypeReaders/GuildTypeReader.cs +++ b/src/NadekoBot/DataStructures/TypeReaders/GuildTypeReader.cs @@ -7,9 +7,9 @@ namespace NadekoBot.TypeReaders { public class GuildTypeReader : TypeReader { - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; - public GuildTypeReader(DiscordShardedClient client) + public GuildTypeReader(DiscordSocketClient client) { _client = client; } diff --git a/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs b/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs index 9815fa1b..3ad63210 100644 --- a/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs +++ b/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs @@ -140,7 +140,7 @@ namespace NadekoBot.Modules.Administration await uow.CompleteAsync(); } - await Context.Channel.SendPaginatedConfirmAsync((DiscordShardedClient)Context.Client, page, (curPage) => + await Context.Channel.SendPaginatedConfirmAsync((DiscordSocketClient)Context.Client, page, (curPage) => { return new EmbedBuilder() .WithTitle(GetText("self_assign_list", roleCnt)) diff --git a/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs b/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs index aa99eeab..5e5ecb33 100644 --- a/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs @@ -13,6 +13,7 @@ using NadekoBot.Services; using NadekoBot.Services.Database.Models; using Microsoft.EntityFrameworkCore; using NadekoBot.Services.Administration; +using System.Diagnostics; namespace NadekoBot.Modules.Administration { @@ -25,10 +26,10 @@ namespace NadekoBot.Modules.Administration private static readonly object _locker = new object(); private readonly SelfService _service; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly IImagesService _images; - public SelfCommands(DbService db, SelfService service, DiscordShardedClient client, + public SelfCommands(DbService db, SelfService service, DiscordSocketClient client, IImagesService images) { _db = db; @@ -204,28 +205,29 @@ namespace NadekoBot.Modules.Administration } - [NadekoCommand, Usage, Description, Aliases] - [OwnerOnly] - public async Task ConnectShard(int shardid) - { - var shard = _client.GetShard(shardid); + //todo 2 shard commands + //[NadekoCommand, Usage, Description, Aliases] + //[OwnerOnly] + //public async Task ConnectShard(int shardid) + //{ + // var shard = _client.GetShard(shardid); - if (shard == null) - { - await ReplyErrorLocalized("no_shard_id").ConfigureAwait(false); - return; - } - try - { - await ReplyConfirmLocalized("shard_reconnecting", Format.Bold("#" + shardid)).ConfigureAwait(false); - await shard.StartAsync().ConfigureAwait(false); - await ReplyConfirmLocalized("shard_reconnected", Format.Bold("#" + shardid)).ConfigureAwait(false); - } - catch (Exception ex) - { - _log.Warn(ex); - } - } + // if (shard == null) + // { + // await ReplyErrorLocalized("no_shard_id").ConfigureAwait(false); + // return; + // } + // try + // { + // await ReplyConfirmLocalized("shard_reconnecting", Format.Bold("#" + shardid)).ConfigureAwait(false); + // await shard.StartAsync().ConfigureAwait(false); + // await ReplyConfirmLocalized("shard_reconnected", Format.Bold("#" + shardid)).ConfigureAwait(false); + // } + // catch (Exception ex) + // { + // _log.Warn(ex); + // } + //} [NadekoCommand, Usage, Description, Aliases] [OwnerOnly] @@ -417,8 +419,10 @@ namespace NadekoBot.Modules.Administration [OwnerOnly] public async Task ReloadImages() { - var time = _images.Reload(); - await ReplyConfirmLocalized("images_loaded", time.TotalSeconds.ToString("F3")).ConfigureAwait(false); + var sw = Stopwatch.StartNew(); + _images.Reload(); + sw.Stop(); + await ReplyConfirmLocalized("images_loaded", sw.Elapsed.TotalSeconds.ToString("F3")).ConfigureAwait(false); } private static UserStatus SettableUserStatusToUserStatus(SettableUserStatus sus) diff --git a/src/NadekoBot/Modules/Administration/Commands/TimeZoneCommands.cs b/src/NadekoBot/Modules/Administration/Commands/TimeZoneCommands.cs index e054288c..c97fdbca 100644 --- a/src/NadekoBot/Modules/Administration/Commands/TimeZoneCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/TimeZoneCommands.cs @@ -36,7 +36,7 @@ namespace NadekoBot.Modules.Administration .ToArray(); var timezonesPerPage = 20; - await Context.Channel.SendPaginatedConfirmAsync((DiscordShardedClient)Context.Client, page, + await Context.Channel.SendPaginatedConfirmAsync((DiscordSocketClient)Context.Client, page, (curPage) => new EmbedBuilder() .WithOkColor() .WithTitle(GetText("timezones_available")) diff --git a/src/NadekoBot/Modules/CustomReactions/CustomReactions.cs b/src/NadekoBot/Modules/CustomReactions/CustomReactions.cs index 5dac3b9c..ae033cad 100644 --- a/src/NadekoBot/Modules/CustomReactions/CustomReactions.cs +++ b/src/NadekoBot/Modules/CustomReactions/CustomReactions.cs @@ -17,10 +17,10 @@ namespace NadekoBot.Modules.CustomReactions private readonly IBotCredentials _creds; private readonly DbService _db; private readonly CustomReactionsService _crs; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; public CustomReactions(IBotCredentials creds, DbService db, CustomReactionsService crs, - DiscordShardedClient client) + DiscordSocketClient client) { _creds = creds; _db = db; diff --git a/src/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs b/src/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs index 4db985e5..46cd25b3 100644 --- a/src/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs +++ b/src/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs @@ -22,12 +22,12 @@ namespace NadekoBot.Modules.Gambling { private readonly BotConfig _bc; private readonly CurrencyService _cs; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; public static ConcurrentDictionary AnimalRaces { get; } = new ConcurrentDictionary(); - public AnimalRacing(BotConfig bc, CurrencyService cs, DiscordShardedClient client) + public AnimalRacing(BotConfig bc, CurrencyService cs, DiscordSocketClient client) { _bc = bc; _cs = cs; @@ -82,14 +82,14 @@ namespace NadekoBot.Modules.Gambling private readonly ITextChannel _raceChannel; private readonly BotConfig _bc; private readonly CurrencyService _cs; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly ILocalization _localization; private readonly NadekoStrings _strings; public bool Started { get; private set; } public AnimalRace(ulong serverId, ITextChannel channel, string prefix, BotConfig bc, - CurrencyService cs, DiscordShardedClient client, ILocalization localization, + CurrencyService cs, DiscordSocketClient client, ILocalization localization, NadekoStrings strings) { _prefix = prefix; diff --git a/src/NadekoBot/Modules/Gambling/Commands/CurrencyEvents.cs b/src/NadekoBot/Modules/Gambling/Commands/CurrencyEvents.cs index 76369c15..644823bc 100644 --- a/src/NadekoBot/Modules/Gambling/Commands/CurrencyEvents.cs +++ b/src/NadekoBot/Modules/Gambling/Commands/CurrencyEvents.cs @@ -34,11 +34,11 @@ namespace NadekoBot.Modules.Gambling .ToArray(); private string _secretCode = string.Empty; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly BotConfig _bc; private readonly CurrencyService _cs; - public CurrencyEvents(DiscordShardedClient client, BotConfig bc, CurrencyService cs) + public CurrencyEvents(DiscordSocketClient client, BotConfig bc, CurrencyService cs) { _client = client; _bc = bc; @@ -151,7 +151,7 @@ namespace NadekoBot.Modules.Gambling { private readonly ConcurrentHashSet _flowerReactionAwardedUsers = new ConcurrentHashSet(); private readonly Logger _log; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly CurrencyService _cs; private IUserMessage StartingMessage { get; set; } @@ -159,7 +159,7 @@ namespace NadekoBot.Modules.Gambling private CancellationTokenSource Source { get; } private CancellationToken CancelToken { get; } - public FlowerReactionEvent(DiscordShardedClient client, CurrencyService cs) + public FlowerReactionEvent(DiscordSocketClient client, CurrencyService cs) { _log = LogManager.GetCurrentClassLogger(); _client = client; diff --git a/src/NadekoBot/Modules/Gambling/Commands/FlowerShop.cs b/src/NadekoBot/Modules/Gambling/Commands/FlowerShop.cs index dfc8d648..dd4fd309 100644 --- a/src/NadekoBot/Modules/Gambling/Commands/FlowerShop.cs +++ b/src/NadekoBot/Modules/Gambling/Commands/FlowerShop.cs @@ -22,7 +22,7 @@ namespace NadekoBot.Modules.Gambling private readonly BotConfig _bc; private readonly DbService _db; private readonly CurrencyService _cs; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; public enum Role { @@ -34,7 +34,7 @@ namespace NadekoBot.Modules.Gambling List } - public FlowerShop(BotConfig bc, DbService db, CurrencyService cs, DiscordShardedClient client) + public FlowerShop(BotConfig bc, DbService db, CurrencyService cs, DiscordSocketClient client) { _db = db; _bc = bc; diff --git a/src/NadekoBot/Modules/Games/Commands/Acropobia.cs b/src/NadekoBot/Modules/Games/Commands/Acropobia.cs index 0d8e337f..44b64808 100644 --- a/src/NadekoBot/Modules/Games/Commands/Acropobia.cs +++ b/src/NadekoBot/Modules/Games/Commands/Acropobia.cs @@ -20,12 +20,12 @@ namespace NadekoBot.Modules.Games [Group] public class Acropobia : NadekoSubmodule { - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; //channelId, game public static ConcurrentDictionary AcrophobiaGames { get; } = new ConcurrentDictionary(); - public Acropobia(DiscordShardedClient client) + public Acropobia(DiscordSocketClient client) { _client = client; } @@ -86,10 +86,10 @@ namespace NadekoBot.Modules.Games //text, votes private readonly ConcurrentDictionary _votes = new ConcurrentDictionary(); private readonly Logger _log; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly NadekoStrings _strings; - public AcrophobiaGame(DiscordShardedClient client, NadekoStrings strings, ITextChannel channel, int time) + public AcrophobiaGame(DiscordSocketClient client, NadekoStrings strings, ITextChannel channel, int time) { _log = LogManager.GetCurrentClassLogger(); _client = client; diff --git a/src/NadekoBot/Modules/Games/Commands/Hangman/HangmanGame.cs b/src/NadekoBot/Modules/Games/Commands/Hangman/HangmanGame.cs index 24ca87c9..eddd00fc 100644 --- a/src/NadekoBot/Modules/Games/Commands/Hangman/HangmanGame.cs +++ b/src/NadekoBot/Modules/Games/Commands/Hangman/HangmanGame.cs @@ -56,7 +56,7 @@ namespace NadekoBot.Modules.Games.Hangman public class HangmanGame: IDisposable { private readonly Logger _log; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; public IMessageChannel GameChannel { get; } public HashSet Guesses { get; } = new HashSet(); @@ -82,7 +82,7 @@ namespace NadekoBot.Modules.Games.Hangman public event Action OnEnded; - public HangmanGame(DiscordShardedClient client, IMessageChannel channel, string type) + public HangmanGame(DiscordSocketClient client, IMessageChannel channel, string type) { _log = LogManager.GetCurrentClassLogger(); _client = client; diff --git a/src/NadekoBot/Modules/Games/Commands/HangmanCommands.cs b/src/NadekoBot/Modules/Games/Commands/HangmanCommands.cs index 633be81f..c515c0b8 100644 --- a/src/NadekoBot/Modules/Games/Commands/HangmanCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/HangmanCommands.cs @@ -15,9 +15,9 @@ namespace NadekoBot.Modules.Games [Group] public class HangmanCommands : NadekoSubmodule { - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; - public HangmanCommands(DiscordShardedClient client) + public HangmanCommands(DiscordSocketClient client) { _client = client; } diff --git a/src/NadekoBot/Modules/Games/Commands/Models/TypingGame.cs b/src/NadekoBot/Modules/Games/Commands/Models/TypingGame.cs index db670fd2..92b01eb3 100644 --- a/src/NadekoBot/Modules/Games/Commands/Models/TypingGame.cs +++ b/src/NadekoBot/Modules/Games/Commands/Models/TypingGame.cs @@ -20,13 +20,13 @@ namespace NadekoBot.Modules.Games.Models public bool IsActive { get; private set; } private readonly Stopwatch sw; private readonly List finishedUserIds; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly GamesService _games; private readonly string _prefix; private Logger _log { get; } - public TypingGame(GamesService games, DiscordShardedClient client, ITextChannel channel, string prefix) //kek@prefix + public TypingGame(GamesService games, DiscordSocketClient client, ITextChannel channel, string prefix) //kek@prefix { _log = LogManager.GetCurrentClassLogger(); _games = games; diff --git a/src/NadekoBot/Modules/Games/Commands/PollCommands.cs b/src/NadekoBot/Modules/Games/Commands/PollCommands.cs index 487473f0..1cf5b951 100644 --- a/src/NadekoBot/Modules/Games/Commands/PollCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/PollCommands.cs @@ -13,10 +13,10 @@ namespace NadekoBot.Modules.Games [Group] public class PollCommands : NadekoSubmodule { - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly PollService _polls; - public PollCommands(DiscordShardedClient client, PollService polls) + public PollCommands(DiscordSocketClient client, PollService polls) { _client = client; _polls = polls; diff --git a/src/NadekoBot/Modules/Games/Commands/SpeedTypingCommands.cs b/src/NadekoBot/Modules/Games/Commands/SpeedTypingCommands.cs index 72663094..6cce5191 100644 --- a/src/NadekoBot/Modules/Games/Commands/SpeedTypingCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/SpeedTypingCommands.cs @@ -20,9 +20,9 @@ namespace NadekoBot.Modules.Games { public static ConcurrentDictionary RunningContests = new ConcurrentDictionary(); private readonly GamesService _games; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; - public SpeedTypingCommands(DiscordShardedClient client, GamesService games) + public SpeedTypingCommands(DiscordSocketClient client, GamesService games) { _games = games; _client = client; diff --git a/src/NadekoBot/Modules/Games/Commands/TicTacToe.cs b/src/NadekoBot/Modules/Games/Commands/TicTacToe.cs index 7de40565..6f626325 100644 --- a/src/NadekoBot/Modules/Games/Commands/TicTacToe.cs +++ b/src/NadekoBot/Modules/Games/Commands/TicTacToe.cs @@ -21,9 +21,9 @@ namespace NadekoBot.Modules.Games private static readonly Dictionary _games = new Dictionary(); private readonly SemaphoreSlim _sem = new SemaphoreSlim(1, 1); - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; - public TicTacToeCommands(DiscordShardedClient client) + public TicTacToeCommands(DiscordSocketClient client) { _client = client; } @@ -87,9 +87,9 @@ namespace NadekoBot.Modules.Games private IUserMessage _previousMessage; private Timer _timeoutTimer; private readonly NadekoStrings _strings; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; - public TicTacToe(NadekoStrings strings, DiscordShardedClient client, ITextChannel channel, IGuildUser firstUser) + public TicTacToe(NadekoStrings strings, DiscordSocketClient client, ITextChannel channel, IGuildUser firstUser) { _channel = channel; _strings = strings; diff --git a/src/NadekoBot/Modules/Games/Commands/Trivia/TriviaGame.cs b/src/NadekoBot/Modules/Games/Commands/Trivia/TriviaGame.cs index ea6e1e2c..b1b7d477 100644 --- a/src/NadekoBot/Modules/Games/Commands/Trivia/TriviaGame.cs +++ b/src/NadekoBot/Modules/Games/Commands/Trivia/TriviaGame.cs @@ -20,7 +20,7 @@ namespace NadekoBot.Modules.Games.Trivia private readonly SemaphoreSlim _guessLock = new SemaphoreSlim(1, 1); private readonly Logger _log; private readonly NadekoStrings _strings; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly BotConfig _bc; private readonly CurrencyService _cs; @@ -43,7 +43,7 @@ namespace NadekoBot.Modules.Games.Trivia public int WinRequirement { get; } - public TriviaGame(NadekoStrings strings, DiscordShardedClient client, BotConfig bc, + public TriviaGame(NadekoStrings strings, DiscordSocketClient client, BotConfig bc, CurrencyService cs, IGuild guild, ITextChannel channel, bool showHints, int winReq, bool isPokemon) { diff --git a/src/NadekoBot/Modules/Games/Commands/TriviaCommands.cs b/src/NadekoBot/Modules/Games/Commands/TriviaCommands.cs index d38e04dd..ac9cdcc3 100644 --- a/src/NadekoBot/Modules/Games/Commands/TriviaCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/TriviaCommands.cs @@ -18,12 +18,12 @@ namespace NadekoBot.Modules.Games public class TriviaCommands : NadekoSubmodule { private readonly CurrencyService _cs; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly BotConfig _bc; public static ConcurrentDictionary RunningTrivias { get; } = new ConcurrentDictionary(); - public TriviaCommands(DiscordShardedClient client, BotConfig bc, CurrencyService cs) + public TriviaCommands(DiscordSocketClient client, BotConfig bc, CurrencyService cs) { _cs = cs; _client = client; diff --git a/src/NadekoBot/Modules/Music/Music.cs b/src/NadekoBot/Modules/Music/Music.cs index afd60bb2..ebec33c5 100644 --- a/src/NadekoBot/Modules/Music/Music.cs +++ b/src/NadekoBot/Modules/Music/Music.cs @@ -22,12 +22,12 @@ namespace NadekoBot.Modules.Music public class Music : NadekoTopLevelModule { private static MusicService _music; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly IBotCredentials _creds; private readonly IGoogleApiService _google; private readonly DbService _db; - public Music(DiscordShardedClient client, IBotCredentials creds, IGoogleApiService google, + public Music(DiscordSocketClient client, IBotCredentials creds, IGoogleApiService google, DbService db, MusicService music) { _client = client; diff --git a/src/NadekoBot/Modules/NadekoModule.cs b/src/NadekoBot/Modules/NadekoModule.cs index dae471d4..45abaea9 100644 --- a/src/NadekoBot/Modules/NadekoModule.cs +++ b/src/NadekoBot/Modules/NadekoModule.cs @@ -86,13 +86,12 @@ namespace NadekoBot.Modules var text = GetText(textKey, replacements); return Context.Channel.SendConfirmAsync(Context.User.Mention + " " + text); } - - // todo maybe make this generic and use - // TypeConverter typeConverter = TypeDescriptor.GetConverter(propType); + + // TypeConverter typeConverter = TypeDescriptor.GetConverter(propType); ? public async Task GetUserInputAsync(ulong userId, ulong channelId) { var userInputTask = new TaskCompletionSource(); - var dsc = (DiscordShardedClient)Context.Client; + var dsc = (DiscordSocketClient)Context.Client; try { dsc.MessageReceived += MessageReceived; diff --git a/src/NadekoBot/Modules/Permissions/Commands/FilterCommands.cs b/src/NadekoBot/Modules/Permissions/Commands/FilterCommands.cs index 371678ff..1329fc0b 100644 --- a/src/NadekoBot/Modules/Permissions/Commands/FilterCommands.cs +++ b/src/NadekoBot/Modules/Permissions/Commands/FilterCommands.cs @@ -195,7 +195,7 @@ namespace NadekoBot.Modules.Permissions var fws = fwHash.ToArray(); - await channel.SendPaginatedConfirmAsync((DiscordShardedClient)Context.Client, + await channel.SendPaginatedConfirmAsync((DiscordSocketClient)Context.Client, page, (curPage) => new EmbedBuilder() diff --git a/src/NadekoBot/Modules/Utility/Commands/CommandMapCommands.cs b/src/NadekoBot/Modules/Utility/Commands/CommandMapCommands.cs index d38cfb90..03316135 100644 --- a/src/NadekoBot/Modules/Utility/Commands/CommandMapCommands.cs +++ b/src/NadekoBot/Modules/Utility/Commands/CommandMapCommands.cs @@ -21,9 +21,9 @@ namespace NadekoBot.Modules.Utility { private readonly CommandMapService _service; private readonly DbService _db; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; - public CommandMapCommands(CommandMapService service, DbService db, DiscordShardedClient client) + public CommandMapCommands(CommandMapService service, DbService db, DiscordSocketClient client) { _service = service; _db = db; diff --git a/src/NadekoBot/Modules/Utility/Commands/InfoCommands.cs b/src/NadekoBot/Modules/Utility/Commands/InfoCommands.cs index 3a5b8fe8..e3c625c4 100644 --- a/src/NadekoBot/Modules/Utility/Commands/InfoCommands.cs +++ b/src/NadekoBot/Modules/Utility/Commands/InfoCommands.cs @@ -16,10 +16,10 @@ namespace NadekoBot.Modules.Utility [Group] public class InfoCommands : NadekoSubmodule { - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly IStatsService _stats; - public InfoCommands(DiscordShardedClient client, IStatsService stats, CommandHandler ch) + public InfoCommands(DiscordSocketClient client, IStatsService stats, CommandHandler ch) { _client = client; _stats = stats; diff --git a/src/NadekoBot/Modules/Utility/Commands/RepeatCommands.cs b/src/NadekoBot/Modules/Utility/Commands/RepeatCommands.cs index 6561712d..89619c1c 100644 --- a/src/NadekoBot/Modules/Utility/Commands/RepeatCommands.cs +++ b/src/NadekoBot/Modules/Utility/Commands/RepeatCommands.cs @@ -22,10 +22,10 @@ namespace NadekoBot.Modules.Utility public class RepeatCommands : NadekoSubmodule { private readonly MessageRepeaterService _service; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly DbService _db; - public RepeatCommands(MessageRepeaterService service, DiscordShardedClient client, DbService db) + public RepeatCommands(MessageRepeaterService service, DiscordSocketClient client, DbService db) { _service = service; _client = client; diff --git a/src/NadekoBot/Modules/Utility/Utility.cs b/src/NadekoBot/Modules/Utility/Utility.cs index 4774a266..4fecdf5e 100644 --- a/src/NadekoBot/Modules/Utility/Utility.cs +++ b/src/NadekoBot/Modules/Utility/Utility.cs @@ -24,15 +24,17 @@ namespace NadekoBot.Modules.Utility public partial class Utility : NadekoTopLevelModule { private static ConcurrentDictionary _rotatingRoleColors = new ConcurrentDictionary(); - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly IStatsService _stats; private readonly IBotCredentials _creds; + private readonly NadekoBot _bot; - public Utility(DiscordShardedClient client, IStatsService stats, IBotCredentials creds) + public Utility(NadekoBot bot, DiscordSocketClient client, IStatsService stats, IBotCredentials creds) { _client = client; _stats = stats; _creds = creds; + _bot = bot; } //[NadekoCommand, Usage, Description, Aliases] @@ -352,56 +354,56 @@ namespace NadekoBot.Modules.Utility await Context.Channel.SendConfirmAsync($"{Context.User.Mention} https://discord.gg/{invite.Code}"); } + //todo 2 shard commands + //[NadekoCommand, Usage, Description, Aliases] + //public async Task ShardStats(int page = 1) + //{ + // if (--page < 0) + // return; - [NadekoCommand, Usage, Description, Aliases] - public async Task ShardStats(int page = 1) - { - if (--page < 0) - return; + // var status = string.Join(", ", _client.Shards.GroupBy(x => x.ConnectionState) + // .Select(x => $"{x.Count()} {x.Key}") + // .ToArray()); - var status = string.Join(", ", _client.Shards.GroupBy(x => x.ConnectionState) - .Select(x => $"{x.Count()} {x.Key}") - .ToArray()); - - var allShardStrings = _client.Shards - .Select(x => - GetText("shard_stats_txt", x.ShardId.ToString(), - Format.Bold(x.ConnectionState.ToString()), Format.Bold(x.Guilds.Count.ToString()))) - .ToArray(); + // var allShardStrings = _client.Shards + // .Select(x => + // GetText("shard_stats_txt", x.ShardId.ToString(), + // Format.Bold(x.ConnectionState.ToString()), Format.Bold(x.Guilds.Count.ToString()))) + // .ToArray(); - await Context.Channel.SendPaginatedConfirmAsync(_client, page, (curPage) => - { + // await Context.Channel.SendPaginatedConfirmAsync(_client, page, (curPage) => + // { - var str = string.Join("\n", allShardStrings.Skip(25 * curPage).Take(25)); + // var str = string.Join("\n", allShardStrings.Skip(25 * curPage).Take(25)); - if (string.IsNullOrWhiteSpace(str)) - str = GetText("no_shards_on_page"); + // if (string.IsNullOrWhiteSpace(str)) + // str = GetText("no_shards_on_page"); - return new EmbedBuilder() - .WithAuthor(a => a.WithName(GetText("shard_stats"))) - .WithTitle(status) - .WithOkColor() - .WithDescription(str); - }, allShardStrings.Length / 25); - } + // return new EmbedBuilder() + // .WithAuthor(a => a.WithName(GetText("shard_stats"))) + // .WithTitle(status) + // .WithOkColor() + // .WithDescription(str); + // }, allShardStrings.Length / 25); + //} - [NadekoCommand, Usage, Description, Aliases] - public async Task ShardId(IGuild guild) - { - var shardId = _client.GetShardIdFor(guild); + //[NadekoCommand, Usage, Description, Aliases] + //public async Task ShardId(IGuild guild) + //{ + // var shardId = _client.GetShardIdFor(guild); - await Context.Channel.SendConfirmAsync(shardId.ToString()).ConfigureAwait(false); - } + // await Context.Channel.SendConfirmAsync(shardId.ToString()).ConfigureAwait(false); + //} [NadekoCommand, Usage, Description, Aliases] public async Task Stats() { - var shardId = Context.Guild != null - ? _client.GetShardIdFor(Context.Guild) - : 0; - + //var shardId = Context.Guild != null + // ? _client.GetShardIdFor(Context.Guild) + // : 0; + await Context.Channel.EmbedAsync( new EmbedBuilder().WithOkColor() .WithAuthor(eab => eab.WithName($"NadekoBot v{StatsService.BotVersion}") @@ -409,7 +411,7 @@ namespace NadekoBot.Modules.Utility .WithIconUrl("https://cdn.discordapp.com/avatars/116275390695079945/b21045e778ef21c96d175400e779f0fb.jpg")) .AddField(efb => efb.WithName(GetText("author")).WithValue(_stats.Author).WithIsInline(true)) .AddField(efb => efb.WithName(GetText("botid")).WithValue(_client.CurrentUser.Id.ToString()).WithIsInline(true)) - .AddField(efb => efb.WithName(GetText("shard")).WithValue($"#{shardId} / {_client.Shards.Count}").WithIsInline(true)) + .AddField(efb => efb.WithName(GetText("shard")).WithValue($"#{_bot.ShardId} / {_creds.TotalShards}").WithIsInline(true)) .AddField(efb => efb.WithName(GetText("commands_ran")).WithValue(_stats.CommandsRan.ToString()).WithIsInline(true)) .AddField(efb => efb.WithName(GetText("messages")).WithValue($"{_stats.MessageCounter} ({_stats.MessagesPerSecond:F2}/sec)").WithIsInline(true)) .AddField(efb => efb.WithName(GetText("memory")).WithValue($"{_stats.Heap} MB").WithIsInline(true)) diff --git a/src/NadekoBot/NadekoBot.cs b/src/NadekoBot/NadekoBot.cs index 44802af6..1c086a7e 100644 --- a/src/NadekoBot/NadekoBot.cs +++ b/src/NadekoBot/NadekoBot.cs @@ -27,8 +27,7 @@ using NadekoBot.Services.Utility; using NadekoBot.Services.Help; using System.IO; using NadekoBot.Services.Pokemon; -using NadekoBot.DataStructures; -using NadekoBot.Extensions; +using NadekoBot.DataStructures.ShardCom; namespace NadekoBot { @@ -45,47 +44,74 @@ namespace NadekoBot public static Color OkColor { get; private set; } public static Color ErrorColor { get; private set; } - public ImmutableArray AllGuildConfigs { get; } + public ImmutableArray AllGuildConfigs { get; private set; } public BotConfig BotConfig { get; } public DbService Db { get; } public CommandService CommandService { get; } public CommandHandler CommandHandler { get; private set; } - public Localization Localization { get; } - public NadekoStrings Strings { get; } - public StatsService Stats { get; } + public Localization Localization { get; private set; } + public NadekoStrings Strings { get; private set; } + public StatsService Stats { get; private set; } public ImagesService Images { get; } public CurrencyService Currency { get; } public GoogleApiService GoogleApi { get; } - public DiscordShardedClient Client { get; } + public DiscordSocketClient Client { get; } public bool Ready { get; private set; } public INServiceProvider Services { get; private set; } public BotCredentials Credentials { get; } - public NadekoBot() + private const string _mutexName = @"Global\nadeko_shards_lock"; + private readonly Semaphore sem = new Semaphore(1, 1, _mutexName); + public int ShardId { get; } + private readonly Thread waitForParentKill; + private readonly ShardComClient _comClient = new ShardComClient(); + + public NadekoBot(int shardId, int parentProcessId) { - SetupLogger(); + if (shardId < 0) + throw new ArgumentOutOfRangeException(nameof(shardId)); + + ShardId = shardId; + + LogSetup.SetupLogger(); _log = LogManager.GetCurrentClassLogger(); TerribleElevatedPermissionCheck(); - + + waitForParentKill = new Thread(new ThreadStart(() => + { + try + { + var p = Process.GetProcessById(parentProcessId); + if (p == null) + return; + p.WaitForExit(); + } + finally + { + Environment.Exit(10); + } + })); + waitForParentKill.Start(); + Credentials = new BotCredentials(); Db = new DbService(Credentials); using (var uow = Db.UnitOfWork) { - AllGuildConfigs = uow.GuildConfigs.GetAllGuildConfigs().ToImmutableArray(); BotConfig = uow.BotConfig.GetOrCreate(); OkColor = new Color(Convert.ToUInt32(BotConfig.OkColor, 16)); ErrorColor = new Color(Convert.ToUInt32(BotConfig.ErrorColor, 16)); } - Client = new DiscordShardedClient(new DiscordSocketConfig + Client = new DiscordSocketClient(new DiscordSocketConfig { MessageCacheSize = 10, LogLevel = LogSeverity.Warning, - TotalShards = Credentials.TotalShards, ConnectionTimeout = int.MaxValue, + TotalShards = Credentials.TotalShards, + ShardId = shardId, AlwaysDownloadUsers = false, }); @@ -96,21 +122,45 @@ namespace NadekoBot }); //foundation services - Localization = new Localization(BotConfig.Locale, AllGuildConfigs.ToDictionary(x => x.GuildId, x => x.Locale), Db); - Strings = new NadekoStrings(Localization); - CommandHandler = new CommandHandler(Client, Db, BotConfig, AllGuildConfigs, CommandService, Credentials, this); - Stats = new StatsService(Client, CommandHandler, Credentials); Images = new ImagesService(); Currency = new CurrencyService(BotConfig, Db); GoogleApi = new GoogleApiService(Credentials); + StartSendingData(); + #if GLOBAL_NADEKO Client.Log += Client_Log; #endif } + private void StartSendingData() + { + Task.Run(async () => + { + while (true) + { + await _comClient.Send(new ShardComMessage() + { + ConnectionState = Client.ConnectionState, + Guilds = Client.ConnectionState == ConnectionState.Connected ? Client.Guilds.Count : 0, + ShardId = Client.ShardId, + }); + await Task.Delay(1000); + } + }); + } + private void AddServices() { + using (var uow = Db.UnitOfWork) + { + AllGuildConfigs = uow.GuildConfigs.GetAllGuildConfigs(Client.Guilds.Select(x => (long)x.Id).ToList()).ToImmutableArray(); + } + Localization = new Localization(BotConfig.Locale, AllGuildConfigs.ToDictionary(x => x.GuildId, x => x.Locale), Db); + Strings = new NadekoStrings(Localization); + CommandHandler = new CommandHandler(Client, Db, BotConfig, AllGuildConfigs, CommandService, Credentials, this); + Stats = new StatsService(Client, CommandHandler, Credentials); + var soundcloudApiService = new SoundCloudApiService(Credentials); #region help @@ -185,7 +235,7 @@ namespace NadekoBot .Add(Credentials) .Add(CommandService) .Add(Strings) - .Add(Client) + .Add(Client) .Add(BotConfig) .Add(Currency) .Add(CommandHandler) @@ -242,19 +292,30 @@ namespace NadekoBot CommandService.AddTypeReader(new GuildDateTimeTypeReader(guildTimezoneService)); } - private async Task LoginAsync(string token) + private Task LoginAsync(string token) { - _log.Info("Logging in..."); //connect - await Client.LoginAsync(TokenType.Bot, token).ConfigureAwait(false); - await Client.StartAsync().ConfigureAwait(false); - - _log.Info("Waiting for all shards to connect..."); - while (!Client.Shards.All(x => x.ConnectionState == ConnectionState.Connected)) + try { sem.WaitOne(); } catch (AbandonedMutexException) { } + _log.Info("Shard {0} logging in ...", ShardId); + try { - _log.Info("Connecting... {0}/{1}", Client.Shards.Count(x => x.ConnectionState == ConnectionState.Connected), Client.Shards.Count); - await Task.Delay(1000).ConfigureAwait(false); + Client.LoginAsync(TokenType.Bot, token).GetAwaiter().GetResult(); + Client.StartAsync().GetAwaiter().GetResult(); + while (Client.ConnectionState != ConnectionState.Connected) + Task.Delay(100).GetAwaiter().GetResult(); } + finally + { + _log.Info("Shard {0} logged in ...", ShardId); + sem.Release(); + } + return Task.CompletedTask; + //_log.Info("Waiting for all shards to connect..."); + //while (!Client.Shards.All(x => x.ConnectionState == ConnectionState.Connected)) + //{ + // _log.Info("Connecting... {0}/{1}", Client.Shards.Count(x => x.ConnectionState == ConnectionState.Connected), Client.Shards.Count); + // await Task.Delay(1000).ConfigureAwait(false); + //} } public async Task RunAsync(params string[] args) @@ -265,11 +326,11 @@ namespace NadekoBot await LoginAsync(Credentials.Token).ConfigureAwait(false); - _log.Info("Loading services..."); + _log.Info($"Shard {ShardId} loading services..."); AddServices(); sw.Stop(); - _log.Info($"Connected in {sw.Elapsed.TotalSeconds:F2} s"); + _log.Info($"Shard {ShardId} connected in {sw.Elapsed.TotalSeconds:F2} s"); var stats = Services.GetService(); stats.Initialize(); @@ -298,7 +359,8 @@ namespace NadekoBot .ForEach(x => CommandService.RemoveModuleAsync(x)); #endif Ready = true; - _log.Info(await stats.Print().ConfigureAwait(false)); + _log.Info($"Shard {ShardId} ready."); + //_log.Info(await stats.Print().ConfigureAwait(false)); } private Task Client_Log(LogMessage arg) @@ -330,19 +392,5 @@ namespace NadekoBot Environment.Exit(2); } } - - private static void SetupLogger() - { - var logConfig = new LoggingConfiguration(); - var consoleTarget = new ColoredConsoleTarget() - { - Layout = @"${date:format=HH\:mm\:ss} ${logger} | ${message}" - }; - logConfig.AddTarget("Console", consoleTarget); - - logConfig.LoggingRules.Add(new LoggingRule("*", LogLevel.Debug, consoleTarget)); - - LogManager.Configuration = logConfig; - } } } diff --git a/src/NadekoBot/Program.cs b/src/NadekoBot/Program.cs index 0c8832e2..20f3a052 100644 --- a/src/NadekoBot/Program.cs +++ b/src/NadekoBot/Program.cs @@ -2,7 +2,14 @@ { public class Program { - public static void Main(string[] args) => - new NadekoBot().RunAndBlockAsync(args).GetAwaiter().GetResult(); + public static void Main(string[] args) + { + if (args.Length == 0) + return; + if (args[0].ToLowerInvariant() == "main") + new ShardsCoordinator().RunAndBlockAsync(args).GetAwaiter().GetResult(); + else if (int.TryParse(args[0], out int shardId) && int.TryParse(args[1], out int parentProcessId)) + new NadekoBot(shardId, parentProcessId).RunAndBlockAsync(args).GetAwaiter().GetResult(); + } } } diff --git a/src/NadekoBot/Properties/launchSettings.json b/src/NadekoBot/Properties/launchSettings.json new file mode 100644 index 00000000..77336a17 --- /dev/null +++ b/src/NadekoBot/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "NadekoBot": { + "commandName": "Project", + "commandLineArgs": "main" + } + } +} \ No newline at end of file diff --git a/src/NadekoBot/Services/Administration/AutoAssignRoleService.cs b/src/NadekoBot/Services/Administration/AutoAssignRoleService.cs index 14679b6d..7c8b8711 100644 --- a/src/NadekoBot/Services/Administration/AutoAssignRoleService.cs +++ b/src/NadekoBot/Services/Administration/AutoAssignRoleService.cs @@ -12,12 +12,12 @@ namespace NadekoBot.Services.Administration public class AutoAssignRoleService { private readonly Logger _log; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; //guildid/roleid public ConcurrentDictionary AutoAssignedRoles { get; } - public AutoAssignRoleService(DiscordShardedClient client, IEnumerable gcs) + public AutoAssignRoleService(DiscordSocketClient client, IEnumerable gcs) { _log = LogManager.GetCurrentClassLogger(); _client = client; diff --git a/src/NadekoBot/Services/Administration/GameVoiceChannelService.cs b/src/NadekoBot/Services/Administration/GameVoiceChannelService.cs index 14f9c6c6..52ea08f7 100644 --- a/src/NadekoBot/Services/Administration/GameVoiceChannelService.cs +++ b/src/NadekoBot/Services/Administration/GameVoiceChannelService.cs @@ -16,9 +16,9 @@ namespace NadekoBot.Services.Administration private readonly Logger _log; private readonly DbService _db; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; - public GameVoiceChannelService(DiscordShardedClient client, DbService db, IEnumerable gcs) + public GameVoiceChannelService(DiscordSocketClient client, DbService db, IEnumerable gcs) { _log = LogManager.GetCurrentClassLogger(); _db = db; diff --git a/src/NadekoBot/Services/Administration/LogCommandService.cs b/src/NadekoBot/Services/Administration/LogCommandService.cs index 84555345..420ada80 100644 --- a/src/NadekoBot/Services/Administration/LogCommandService.cs +++ b/src/NadekoBot/Services/Administration/LogCommandService.cs @@ -16,7 +16,7 @@ namespace NadekoBot.Services.Administration public class LogCommandService { - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly Logger _log; private string PrettyCurrentTime => $"【{DateTime.UtcNow:HH:mm:ss}】"; @@ -31,7 +31,7 @@ namespace NadekoBot.Services.Administration private readonly MuteService _mute; private readonly ProtectionService _prot; - public LogCommandService(DiscordShardedClient client, NadekoStrings strings, + public LogCommandService(DiscordSocketClient client, NadekoStrings strings, IEnumerable gcs, DbService db, MuteService mute, ProtectionService prot) { _client = client; @@ -74,7 +74,7 @@ namespace NadekoBot.Services.Administration _client.UserUnbanned += _client_UserUnbanned; _client.UserJoined += _client_UserJoined; _client.UserLeft += _client_UserLeft; - _client.UserPresenceUpdated += _client_UserPresenceUpdated; + //_client.UserPresenceUpdated += _client_UserPresenceUpdated; _client.UserVoiceStateUpdated += _client_UserVoiceStateUpdated; _client.UserVoiceStateUpdated += _client_UserVoiceStateUpdated_TTS; _client.GuildMemberUpdated += _client_GuildUserUpdated; @@ -576,48 +576,48 @@ namespace NadekoBot.Services.Administration return Task.CompletedTask; } - private Task _client_UserPresenceUpdated(Optional optGuild, SocketUser usr, SocketPresence before, SocketPresence after) - { - var _ = Task.Run(async () => - { - try - { - var guild = optGuild.GetValueOrDefault() ?? (usr as SocketGuildUser)?.Guild; + //private Task _client_UserPresenceUpdated(Optional optGuild, SocketUser usr, SocketPresence before, SocketPresence after) + //{ + // var _ = Task.Run(async () => + // { + // try + // { + // var guild = optGuild.GetValueOrDefault() ?? (usr as SocketGuildUser)?.Guild; - if (guild == null) - return; + // if (guild == null) + // return; - if (!GuildLogSettings.TryGetValue(guild.Id, out LogSetting logSetting) - || (logSetting.LogUserPresenceId == null) - || before.Status == after.Status) - return; + // if (!GuildLogSettings.TryGetValue(guild.Id, out LogSetting logSetting) + // || (logSetting.LogUserPresenceId == null) + // || before.Status == after.Status) + // return; - ITextChannel logChannel; - if ((logChannel = await TryGetLogChannel(guild, logSetting, LogType.UserPresence)) == null) - return; - string str = ""; - if (before.Status != after.Status) - str = "🎭" + Format.Code(PrettyCurrentTime) + - GetText(logChannel.Guild, "user_status_change", - "👤" + Format.Bold(usr.Username), - Format.Bold(after.Status.ToString())); + // ITextChannel logChannel; + // if ((logChannel = await TryGetLogChannel(guild, logSetting, LogType.UserPresence)) == null) + // return; + // string str = ""; + // if (before.Status != after.Status) + // str = "🎭" + Format.Code(PrettyCurrentTime) + + // GetText(logChannel.Guild, "user_status_change", + // "👤" + Format.Bold(usr.Username), + // Format.Bold(after.Status.ToString())); - //if (before.Game?.Name != after.Game?.Name) - //{ - // if (str != "") - // str += "\n"; - // str += $"👾`{prettyCurrentTime}`👤__**{usr.Username}**__ is now playing **{after.Game?.Name}**."; - //} + // //if (before.Game?.Name != after.Game?.Name) + // //{ + // // if (str != "") + // // str += "\n"; + // // str += $"👾`{prettyCurrentTime}`👤__**{usr.Username}**__ is now playing **{after.Game?.Name}**."; + // //} - PresenceUpdates.AddOrUpdate(logChannel, new List() { str }, (id, list) => { list.Add(str); return list; }); - } - catch - { - // ignored - } - }); - return Task.CompletedTask; - } + // PresenceUpdates.AddOrUpdate(logChannel, new List() { str }, (id, list) => { list.Add(str); return list; }); + // } + // catch + // { + // // ignored + // } + // }); + // return Task.CompletedTask; + //} private Task _client_UserLeft(IGuildUser usr) { diff --git a/src/NadekoBot/Services/Administration/MuteService.cs b/src/NadekoBot/Services/Administration/MuteService.cs index 7ed9062a..87bde743 100644 --- a/src/NadekoBot/Services/Administration/MuteService.cs +++ b/src/NadekoBot/Services/Administration/MuteService.cs @@ -33,10 +33,10 @@ namespace NadekoBot.Services.Administration private static readonly OverwritePermissions denyOverwrite = new OverwritePermissions(sendMessages: PermValue.Deny, attachFiles: PermValue.Deny); private readonly Logger _log = LogManager.GetCurrentClassLogger(); - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly DbService _db; - public MuteService(DiscordShardedClient client, IEnumerable gcs, DbService db) + public MuteService(DiscordSocketClient client, IEnumerable gcs, DbService db) { _client = client; _db = db; diff --git a/src/NadekoBot/Services/Administration/PlayingRotateService.cs b/src/NadekoBot/Services/Administration/PlayingRotateService.cs index 7662b7ca..c7a1bf41 100644 --- a/src/NadekoBot/Services/Administration/PlayingRotateService.cs +++ b/src/NadekoBot/Services/Administration/PlayingRotateService.cs @@ -17,7 +17,7 @@ namespace NadekoBot.Services.Administration public List RotatingStatusMessages { get; } public volatile bool RotatingStatuses; private readonly Timer _t; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly BotConfig _bc; private readonly MusicService _music; private readonly Logger _log; @@ -27,7 +27,7 @@ namespace NadekoBot.Services.Administration public int Index { get; set; } } - public PlayingRotateService(DiscordShardedClient client, BotConfig bc, MusicService music) + public PlayingRotateService(DiscordSocketClient client, BotConfig bc, MusicService music) { _client = client; _bc = bc; @@ -36,7 +36,7 @@ namespace NadekoBot.Services.Administration RotatingStatusMessages = _bc.RotatingStatusMessages; RotatingStatuses = _bc.RotatingStatuses; - + _t = new Timer(async (objState) => { try @@ -52,17 +52,12 @@ namespace NadekoBot.Services.Administration var status = RotatingStatusMessages[state.Index++].Status; if (string.IsNullOrWhiteSpace(status)) return; - PlayingPlaceholders.ForEach(e => status = status.Replace(e.Key, e.Value(_client,_music))); - var shards = _client.Shards; - for (int i = 0; i < shards.Count; i++) + PlayingPlaceholders.ForEach(e => status = status.Replace(e.Key, e.Value(_client, _music))); + ShardSpecificPlaceholders.ForEach(e => status = status.Replace(e.Key, e.Value(client))); + try { await client.SetGameAsync(status).ConfigureAwait(false); } + catch (Exception ex) { - var curShard = shards.ElementAt(i); - ShardSpecificPlaceholders.ForEach(e => status = status.Replace(e.Key, e.Value(curShard))); - try { await shards.ElementAt(i).SetGameAsync(status).ConfigureAwait(false); } - catch (Exception ex) - { - _log.Warn(ex); - } + _log.Warn(ex); } } catch (Exception ex) @@ -72,8 +67,8 @@ namespace NadekoBot.Services.Administration }, new TimerState(), TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1)); } - public Dictionary> PlayingPlaceholders { get; } = - new Dictionary> { + public Dictionary> PlayingPlaceholders { get; } = + new Dictionary> { { "%servers%", (c, ms) => c.Guilds.Count.ToString()}, { "%users%", (c, ms) => c.Guilds.Sum(s => s.Users.Count).ToString()}, { "%playing%", (c, ms) => { @@ -90,7 +85,6 @@ namespace NadekoBot.Services.Administration }, { "%queued%", (c, ms) => ms.MusicPlayers.Sum(kvp => kvp.Value.Playlist.Count).ToString()}, { "%time%", (c, ms) => DateTime.Now.ToString("HH:mm " + TimeZoneInfo.Local.StandardName.GetInitials()) }, - { "%shardcount%", (c, ms) => c.Shards.Count.ToString() }, }; public Dictionary> ShardSpecificPlaceholders { get; } = diff --git a/src/NadekoBot/Services/Administration/ProtectionService.cs b/src/NadekoBot/Services/Administration/ProtectionService.cs index 23bca7ad..6a2ae99b 100644 --- a/src/NadekoBot/Services/Administration/ProtectionService.cs +++ b/src/NadekoBot/Services/Administration/ProtectionService.cs @@ -21,10 +21,10 @@ namespace NadekoBot.Services.Administration public event Func OnAntiProtectionTriggered = delegate { return Task.CompletedTask; }; private readonly Logger _log; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly MuteService _mute; - public ProtectionService(DiscordShardedClient client, IEnumerable gcs, MuteService mute) + public ProtectionService(DiscordSocketClient client, IEnumerable gcs, MuteService mute) { _log = LogManager.GetCurrentClassLogger(); _client = client; diff --git a/src/NadekoBot/Services/Administration/RatelimitService.cs b/src/NadekoBot/Services/Administration/RatelimitService.cs index b344930f..a0f4171f 100644 --- a/src/NadekoBot/Services/Administration/RatelimitService.cs +++ b/src/NadekoBot/Services/Administration/RatelimitService.cs @@ -19,9 +19,9 @@ namespace NadekoBot.Services.Administration public ConcurrentDictionary> IgnoredUsers = new ConcurrentDictionary>(); private readonly Logger _log; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; - public SlowmodeService(DiscordShardedClient client, IEnumerable gcs) + public SlowmodeService(DiscordSocketClient client, IEnumerable gcs) { _log = LogManager.GetCurrentClassLogger(); _client = client; diff --git a/src/NadekoBot/Services/Administration/SelfService.cs b/src/NadekoBot/Services/Administration/SelfService.cs index f3148d5a..8e8a4a13 100644 --- a/src/NadekoBot/Services/Administration/SelfService.cs +++ b/src/NadekoBot/Services/Administration/SelfService.cs @@ -23,11 +23,11 @@ namespace NadekoBot.Services.Administration private readonly Logger _log; private readonly ILocalization _localization; private readonly NadekoStrings _strings; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly IBotCredentials _creds; private ImmutableArray> ownerChannels = new ImmutableArray>(); - public SelfService(DiscordShardedClient client, NadekoBot bot, CommandHandler cmdHandler, DbService db, + public SelfService(DiscordSocketClient client, NadekoBot bot, CommandHandler cmdHandler, DbService db, BotConfig bc, ILocalization localization, NadekoStrings strings, IBotCredentials creds) { _bot = bot; @@ -69,10 +69,7 @@ namespace NadekoBot.Services.Administration LoadOwnerChannels(); - if (!ownerChannels.Any()) - _log.Warn("No owner channels created! Make sure you've specified correct OwnerId in the credentials.json file."); - else - _log.Info($"Created {ownerChannels.Length} out of {_creds.OwnerIds.Length} owner message channels."); + }); } @@ -81,11 +78,9 @@ namespace NadekoBot.Services.Administration var hs = new HashSet(_creds.OwnerIds); var channels = new Dictionary>(); - foreach (var s in _client.Shards) + if (hs.Count > 0) { - if (hs.Count == 0) - break; - foreach (var g in s.Guilds) + foreach (var g in _client.Guilds) { if (hs.Count == 0) break; @@ -101,14 +96,19 @@ namespace NadekoBot.Services.Administration } } } - + ownerChannels = channels.OrderBy(x => _creds.OwnerIds.IndexOf(x.Key)) .Select(x => x.Value) .ToImmutableArray(); + + if (!ownerChannels.Any()) + _log.Warn("No owner channels created! Make sure you've specified correct OwnerId in the credentials.json file."); + else + _log.Info($"Created {ownerChannels.Length} out of {_creds.OwnerIds.Length} owner message channels."); } // forwards dms - public async Task LateExecute(DiscordShardedClient client, IGuild guild, IUserMessage msg) + public async Task LateExecute(DiscordSocketClient client, IGuild guild, IUserMessage msg) { if (msg.Channel is IDMChannel && ForwardDMs && ownerChannels.Length > 0) { diff --git a/src/NadekoBot/Services/Administration/VcRoleService.cs b/src/NadekoBot/Services/Administration/VcRoleService.cs index 49dbe9ff..10252833 100644 --- a/src/NadekoBot/Services/Administration/VcRoleService.cs +++ b/src/NadekoBot/Services/Administration/VcRoleService.cs @@ -14,11 +14,11 @@ namespace NadekoBot.Services.Administration { private readonly Logger _log; private readonly DbService _db; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; public ConcurrentDictionary> VcRoles { get; } - public VcRoleService(DiscordShardedClient client, IEnumerable gcs, DbService db) + public VcRoleService(DiscordSocketClient client, IEnumerable gcs, DbService db) { _log = LogManager.GetCurrentClassLogger(); _db = db; diff --git a/src/NadekoBot/Services/Administration/VplusTService.cs b/src/NadekoBot/Services/Administration/VplusTService.cs index 3d9e86cd..b4e3122d 100644 --- a/src/NadekoBot/Services/Administration/VplusTService.cs +++ b/src/NadekoBot/Services/Administration/VplusTService.cs @@ -20,12 +20,12 @@ namespace NadekoBot.Services.Administration public readonly ConcurrentHashSet VoicePlusTextCache; private readonly ConcurrentDictionary _guildLockObjects = new ConcurrentDictionary(); - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly NadekoStrings _strings; private readonly DbService _db; private readonly Logger _log; - public VplusTService(DiscordShardedClient client, IEnumerable gcs, NadekoStrings strings, + public VplusTService(DiscordSocketClient client, IEnumerable gcs, NadekoStrings strings, DbService db) { _client = client; diff --git a/src/NadekoBot/Services/ClashOfClans/ClashOfClansService.cs b/src/NadekoBot/Services/ClashOfClans/ClashOfClansService.cs index edb78512..042afa1b 100644 --- a/src/NadekoBot/Services/ClashOfClans/ClashOfClansService.cs +++ b/src/NadekoBot/Services/ClashOfClans/ClashOfClansService.cs @@ -17,7 +17,7 @@ namespace NadekoBot.Services.ClashOfClans // shouldn't be here public class ClashOfClansService { - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly DbService _db; private readonly ILocalization _localization; private readonly NadekoStrings _strings; @@ -25,7 +25,7 @@ namespace NadekoBot.Services.ClashOfClans public ConcurrentDictionary> ClashWars { get; set; } - public ClashOfClansService(DiscordShardedClient client, DbService db, ILocalization localization, NadekoStrings strings) + public ClashOfClansService(DiscordSocketClient client, DbService db, ILocalization localization, NadekoStrings strings) { _client = client; _db = db; diff --git a/src/NadekoBot/Services/CommandHandler.cs b/src/NadekoBot/Services/CommandHandler.cs index 2177ce01..a1de8871 100644 --- a/src/NadekoBot/Services/CommandHandler.cs +++ b/src/NadekoBot/Services/CommandHandler.cs @@ -28,7 +28,7 @@ namespace NadekoBot.Services { public const int GlobalCommandsCooldown = 750; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly CommandService _commandService; private readonly Logger _log; private readonly IBotCredentials _creds; @@ -48,7 +48,7 @@ namespace NadekoBot.Services public ConcurrentHashSet UsersOnShortCooldown { get; } = new ConcurrentHashSet(); private readonly Timer _clearUsersOnShortCooldown; - public CommandHandler(DiscordShardedClient client, DbService db, BotConfig bc, IEnumerable gcs, CommandService commandService, IBotCredentials credentials, NadekoBot bot) + public CommandHandler(DiscordSocketClient client, DbService db, BotConfig bc, IEnumerable gcs, CommandService commandService, IBotCredentials credentials, NadekoBot bot) { _client = client; _commandService = commandService; diff --git a/src/NadekoBot/Services/CustomReactions/CustomReactionsService.cs b/src/NadekoBot/Services/CustomReactions/CustomReactionsService.cs index 206b0bd9..bb7fb8d9 100644 --- a/src/NadekoBot/Services/CustomReactions/CustomReactionsService.cs +++ b/src/NadekoBot/Services/CustomReactions/CustomReactionsService.cs @@ -22,13 +22,13 @@ namespace NadekoBot.Services.CustomReactions private readonly Logger _log; private readonly DbService _db; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly PermissionService _perms; private readonly CommandHandler _cmd; private readonly BotConfig _bc; public CustomReactionsService(PermissionService perms, DbService db, - DiscordShardedClient client, CommandHandler cmd, BotConfig bc) + DiscordSocketClient client, CommandHandler cmd, BotConfig bc) { _log = LogManager.GetCurrentClassLogger(); _db = db; @@ -37,15 +37,12 @@ namespace NadekoBot.Services.CustomReactions _cmd = cmd; _bc = bc; - var sw = Stopwatch.StartNew(); using (var uow = _db.UnitOfWork) { var items = uow.CustomReactions.GetAll(); GuildReactions = new ConcurrentDictionary(items.Where(g => g.GuildId != null && g.GuildId != 0).GroupBy(k => k.GuildId.Value).ToDictionary(g => g.Key, g => g.ToArray())); GlobalReactions = items.Where(g => g.GuildId == null || g.GuildId == 0).ToArray(); } - sw.Stop(); - _log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s"); } public void ClearStats() => ReactionStats.Clear(); @@ -98,7 +95,7 @@ namespace NadekoBot.Services.CustomReactions return greaction; } - public async Task TryExecuteEarly(DiscordShardedClient client, IGuild guild, IUserMessage msg) + public async Task TryExecuteEarly(DiscordSocketClient client, IGuild guild, IUserMessage msg) { // maybe this message is a custom reaction var cr = await Task.Run(() => TryGetCustomReaction(msg)).ConfigureAwait(false); diff --git a/src/NadekoBot/Services/CustomReactions/Extensions.cs b/src/NadekoBot/Services/CustomReactions/Extensions.cs index e2c5481f..4d6d4d06 100644 --- a/src/NadekoBot/Services/CustomReactions/Extensions.cs +++ b/src/NadekoBot/Services/CustomReactions/Extensions.cs @@ -40,7 +40,7 @@ namespace NadekoBot.Services.CustomReactions } }, }; - public static Dictionary> placeholders = new Dictionary>() + public static Dictionary> placeholders = new Dictionary>() { {"%mention%", (ctx, client) => { return $"<@{client.CurrentUser.Id}>"; } }, {"%user%", (ctx, client) => { return ctx.Author.Mention; } }, @@ -94,7 +94,7 @@ namespace NadekoBot.Services.CustomReactions } } }; - private static string ResolveTriggerString(this string str, IUserMessage ctx, DiscordShardedClient client) + private static string ResolveTriggerString(this string str, IUserMessage ctx, DiscordSocketClient client) { foreach (var ph in placeholders) { @@ -104,7 +104,7 @@ namespace NadekoBot.Services.CustomReactions return str; } - private static async Task ResolveResponseStringAsync(this string str, IUserMessage ctx, DiscordShardedClient client, string resolvedTrigger) + private static async Task ResolveResponseStringAsync(this string str, IUserMessage ctx, DiscordSocketClient client, string resolvedTrigger) { foreach (var ph in placeholders) { @@ -127,13 +127,13 @@ namespace NadekoBot.Services.CustomReactions return str; } - public static string TriggerWithContext(this CustomReaction cr, IUserMessage ctx, DiscordShardedClient client) + public static string TriggerWithContext(this CustomReaction cr, IUserMessage ctx, DiscordSocketClient client) => cr.Trigger.ResolveTriggerString(ctx, client); - public static Task ResponseWithContextAsync(this CustomReaction cr, IUserMessage ctx, DiscordShardedClient client) + public static Task ResponseWithContextAsync(this CustomReaction cr, IUserMessage ctx, DiscordSocketClient client) => cr.Response.ResolveResponseStringAsync(ctx, client, cr.Trigger.ResolveTriggerString(ctx, client)); - public static async Task Send(this CustomReaction cr, IUserMessage context, DiscordShardedClient client, CustomReactionsService crs) + public static async Task Send(this CustomReaction cr, IUserMessage context, DiscordSocketClient client, CustomReactionsService crs) { var channel = cr.DmResponse ? await context.Author.CreateDMChannelAsync() : context.Channel; diff --git a/src/NadekoBot/Services/Database/Repositories/IGuildConfigRepository.cs b/src/NadekoBot/Services/Database/Repositories/IGuildConfigRepository.cs index cca54609..52332cfb 100644 --- a/src/NadekoBot/Services/Database/Repositories/IGuildConfigRepository.cs +++ b/src/NadekoBot/Services/Database/Repositories/IGuildConfigRepository.cs @@ -11,7 +11,7 @@ namespace NadekoBot.Services.Database.Repositories GuildConfig For(ulong guildId, Func, IQueryable> includes = null); GuildConfig LogSettingsFor(ulong guildId); IEnumerable OldPermissionsForAll(); - IEnumerable GetAllGuildConfigs(); + IEnumerable GetAllGuildConfigs(List availableGuilds); IEnumerable GetAllFollowedStreams(); void SetCleverbotEnabled(ulong id, bool cleverbotEnabled); IEnumerable Permissionsv2ForAll(); diff --git a/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs b/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs index f3ed3566..25dd52fe 100644 --- a/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs +++ b/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs @@ -24,8 +24,10 @@ namespace NadekoBot.Services.Database.Repositories.Impl } }; - public IEnumerable GetAllGuildConfigs() => - _set.Include(gc => gc.LogSetting) + public IEnumerable GetAllGuildConfigs(List availableGuilds) => + _set + .Where(gc => availableGuilds.Contains((long)gc.GuildId)) + .Include(gc => gc.LogSetting) .ThenInclude(ls => ls.IgnoredChannels) .Include(gc => gc.MutedUsers) .Include(gc => gc.CommandAliases) diff --git a/src/NadekoBot/Services/Discord/SocketMessageEventWrapper.cs b/src/NadekoBot/Services/Discord/SocketMessageEventWrapper.cs index 58b3a1e5..4903fd66 100644 --- a/src/NadekoBot/Services/Discord/SocketMessageEventWrapper.cs +++ b/src/NadekoBot/Services/Discord/SocketMessageEventWrapper.cs @@ -12,7 +12,7 @@ namespace NadekoBot.Services.Discord public event Action OnReactionRemoved = delegate { }; public event Action OnReactionsCleared = delegate { }; - public ReactionEventWrapper(DiscordShardedClient client, IUserMessage msg) + public ReactionEventWrapper(DiscordSocketClient client, IUserMessage msg) { Message = msg ?? throw new ArgumentNullException(nameof(msg)); _client = client; @@ -69,7 +69,7 @@ namespace NadekoBot.Services.Discord } private bool disposing = false; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; public void Dispose() { diff --git a/src/NadekoBot/Services/Games/ChatterbotService.cs b/src/NadekoBot/Services/Games/ChatterbotService.cs index 8039b79d..ad295dec 100644 --- a/src/NadekoBot/Services/Games/ChatterbotService.cs +++ b/src/NadekoBot/Services/Games/ChatterbotService.cs @@ -15,14 +15,14 @@ namespace NadekoBot.Services.Games { public class ChatterBotService : IEarlyBlockingExecutor { - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly Logger _log; private readonly PermissionService _perms; private readonly CommandHandler _cmd; public ConcurrentDictionary> ChatterBotGuilds { get; } - public ChatterBotService(DiscordShardedClient client, PermissionService perms, IEnumerable gcs, CommandHandler cmd) + public ChatterBotService(DiscordSocketClient client, PermissionService perms, IEnumerable gcs, CommandHandler cmd) { _client = client; _log = LogManager.GetCurrentClassLogger(); @@ -83,7 +83,7 @@ namespace NadekoBot.Services.Games return true; } - public async Task TryExecuteEarly(DiscordShardedClient client, IGuild guild, IUserMessage usrMsg) + public async Task TryExecuteEarly(DiscordSocketClient client, IGuild guild, IUserMessage usrMsg) { if (!(guild is SocketGuild sg)) return false; diff --git a/src/NadekoBot/Services/Games/GamesService.cs b/src/NadekoBot/Services/Games/GamesService.cs index 24139906..e677990b 100644 --- a/src/NadekoBot/Services/Games/GamesService.cs +++ b/src/NadekoBot/Services/Games/GamesService.cs @@ -23,7 +23,7 @@ namespace NadekoBot.Services.Games public readonly ImmutableArray EightBallResponses; private readonly Timer _t; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly NadekoStrings _strings; private readonly IImagesService _images; private readonly Logger _log; @@ -33,7 +33,7 @@ namespace NadekoBot.Services.Games public List TypingArticles { get; } = new List(); - public GamesService(DiscordShardedClient client, BotConfig bc, IEnumerable gcs, + public GamesService(DiscordSocketClient client, BotConfig bc, IEnumerable gcs, NadekoStrings strings, IImagesService images, CommandHandler cmdHandler) { _bc = bc; diff --git a/src/NadekoBot/Services/Games/Poll.cs b/src/NadekoBot/Services/Games/Poll.cs index 8feb4cb5..1a6bbf20 100644 --- a/src/NadekoBot/Services/Games/Poll.cs +++ b/src/NadekoBot/Services/Games/Poll.cs @@ -18,7 +18,7 @@ namespace NadekoBot.Services.Games private string[] answers { get; } private readonly ConcurrentDictionary _participants = new ConcurrentDictionary(); private readonly string _question; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly NadekoStrings _strings; private bool running = false; private HashSet _guildUsers; @@ -27,7 +27,7 @@ namespace NadekoBot.Services.Games public bool IsPublic { get; } - public Poll(DiscordShardedClient client, NadekoStrings strings, IUserMessage umsg, string question, IEnumerable enumerable, bool isPublic = false) + public Poll(DiscordSocketClient client, NadekoStrings strings, IUserMessage umsg, string question, IEnumerable enumerable, bool isPublic = false) { _client = client; _strings = strings; diff --git a/src/NadekoBot/Services/Games/PollService.cs b/src/NadekoBot/Services/Games/PollService.cs index a421bd77..ce8852a7 100644 --- a/src/NadekoBot/Services/Games/PollService.cs +++ b/src/NadekoBot/Services/Games/PollService.cs @@ -13,10 +13,10 @@ namespace NadekoBot.Services.Games { public ConcurrentDictionary ActivePolls = new ConcurrentDictionary(); private readonly Logger _log; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly NadekoStrings _strings; - public PollService(DiscordShardedClient client, NadekoStrings strings) + public PollService(DiscordSocketClient client, NadekoStrings strings) { _log = LogManager.GetCurrentClassLogger(); _client = client; @@ -45,7 +45,7 @@ namespace NadekoBot.Services.Games return false; } - public async Task TryExecuteEarly(DiscordShardedClient client, IGuild guild, IUserMessage msg) + public async Task TryExecuteEarly(DiscordSocketClient client, IGuild guild, IUserMessage msg) { if (guild == null) { diff --git a/src/NadekoBot/Services/GreetSettingsService.cs b/src/NadekoBot/Services/GreetSettingsService.cs index 6e2e630d..3296c602 100644 --- a/src/NadekoBot/Services/GreetSettingsService.cs +++ b/src/NadekoBot/Services/GreetSettingsService.cs @@ -17,10 +17,10 @@ namespace NadekoBot.Services private readonly DbService _db; public readonly ConcurrentDictionary GuildConfigsCache; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly Logger _log; - public GreetSettingsService(DiscordShardedClient client, IEnumerable guildConfigs, DbService db) + public GreetSettingsService(DiscordSocketClient client, IEnumerable guildConfigs, DbService db) { _db = db; _client = client; diff --git a/src/NadekoBot/Services/Help/HelpService.cs b/src/NadekoBot/Services/Help/HelpService.cs index 25a91f16..83b64927 100644 --- a/src/NadekoBot/Services/Help/HelpService.cs +++ b/src/NadekoBot/Services/Help/HelpService.cs @@ -24,7 +24,7 @@ namespace NadekoBot.Services.Help _strings = strings; } - public async Task LateExecute(DiscordShardedClient client, IGuild guild, IUserMessage msg) + public async Task LateExecute(DiscordSocketClient client, IGuild guild, IUserMessage msg) { try { diff --git a/src/NadekoBot/Services/IBotCredentials.cs b/src/NadekoBot/Services/IBotCredentials.cs index c6c42f87..7fa661bd 100644 --- a/src/NadekoBot/Services/IBotCredentials.cs +++ b/src/NadekoBot/Services/IBotCredentials.cs @@ -20,6 +20,7 @@ namespace NadekoBot.Services string OsuApiKey { get; } bool IsOwner(IUser u); + int TotalShards { get; } } public class DBConfig diff --git a/src/NadekoBot/Services/IImagesService.cs b/src/NadekoBot/Services/IImagesService.cs index 0a76175d..31e6c32a 100644 --- a/src/NadekoBot/Services/IImagesService.cs +++ b/src/NadekoBot/Services/IImagesService.cs @@ -18,6 +18,6 @@ namespace NadekoBot.Services ImmutableArray WifeMatrix { get; } ImmutableArray RategirlDot { get; } - TimeSpan Reload(); + void Reload(); } } diff --git a/src/NadekoBot/Services/Impl/ImagesService.cs b/src/NadekoBot/Services/Impl/ImagesService.cs index 4bce6148..95930464 100644 --- a/src/NadekoBot/Services/Impl/ImagesService.cs +++ b/src/NadekoBot/Services/Impl/ImagesService.cs @@ -47,12 +47,10 @@ namespace NadekoBot.Services.Impl this.Reload(); } - public TimeSpan Reload() + public void Reload() { try { - _log.Info("Loading images..."); - var sw = Stopwatch.StartNew(); Heads = File.ReadAllBytes(_headsPath).ToImmutableArray(); Tails = File.ReadAllBytes(_tailsPath).ToImmutableArray(); @@ -79,10 +77,6 @@ namespace NadekoBot.Services.Impl WifeMatrix = File.ReadAllBytes(_wifeMatrixPath).ToImmutableArray(); RategirlDot = File.ReadAllBytes(_rategirlDot).ToImmutableArray(); - - sw.Stop(); - _log.Info($"Images loaded after {sw.Elapsed.TotalSeconds:F2}s!"); - return sw.Elapsed; } catch (Exception ex) { diff --git a/src/NadekoBot/Services/Impl/StatsService.cs b/src/NadekoBot/Services/Impl/StatsService.cs index bcd4a092..5d93196d 100644 --- a/src/NadekoBot/Services/Impl/StatsService.cs +++ b/src/NadekoBot/Services/Impl/StatsService.cs @@ -13,7 +13,7 @@ namespace NadekoBot.Services.Impl { public class StatsService : IStatsService { - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly IBotCredentials _creds; private readonly DateTime _started; @@ -36,7 +36,7 @@ namespace NadekoBot.Services.Impl private readonly Timer _carbonitexTimer; - public StatsService(DiscordShardedClient client, CommandHandler cmdHandler, IBotCredentials creds) + public StatsService(DiscordSocketClient client, CommandHandler cmdHandler, IBotCredentials creds) { _client = client; _creds = creds; @@ -121,31 +121,32 @@ namespace NadekoBot.Services.Impl return Task.CompletedTask; }; - _carbonitexTimer = new Timer(async (state) => - { - if (string.IsNullOrWhiteSpace(_creds.CarbonKey)) - return; - try - { - using (var http = new HttpClient()) - { - using (var content = new FormUrlEncodedContent( - new Dictionary { - { "servercount", _client.Guilds.Count.ToString() }, - { "key", _creds.CarbonKey }})) - { - content.Headers.Clear(); - content.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); + //todo carbonitex update + //_carbonitexTimer = new Timer(async (state) => + //{ + // if (string.IsNullOrWhiteSpace(_creds.CarbonKey)) + // return; + // try + // { + // using (var http = new HttpClient()) + // { + // using (var content = new FormUrlEncodedContent( + // new Dictionary { + // { "servercount", _client.Guilds.Count.ToString() }, + // { "key", _creds.CarbonKey }})) + // { + // content.Headers.Clear(); + // content.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); - await http.PostAsync("https://www.carbonitex.net/discord/data/botdata.php", content).ConfigureAwait(false); - } - } - } - catch - { - // ignored - } - }, null, TimeSpan.FromHours(1), TimeSpan.FromHours(1)); + // await http.PostAsync("https://www.carbonitex.net/discord/data/botdata.php", content).ConfigureAwait(false); + // } + // } + // } + // catch + // { + // // ignored + // } + //}, null, TimeSpan.FromHours(1), TimeSpan.FromHours(1)); } public void Initialize() diff --git a/src/NadekoBot/Services/LogSetup.cs b/src/NadekoBot/Services/LogSetup.cs new file mode 100644 index 00000000..159b447e --- /dev/null +++ b/src/NadekoBot/Services/LogSetup.cs @@ -0,0 +1,28 @@ +using NLog; +using NLog.Config; +using NLog.Targets; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NadekoBot.Services +{ + public class LogSetup + { + public static void SetupLogger() + { + var logConfig = new LoggingConfiguration(); + var consoleTarget = new ColoredConsoleTarget() + { + Layout = @"${date:format=HH\:mm\:ss} ${logger} | ${message}" + }; + logConfig.AddTarget("Console", consoleTarget); + + logConfig.LoggingRules.Add(new LoggingRule("*", LogLevel.Debug, consoleTarget)); + + LogManager.Configuration = logConfig; + } + } +} diff --git a/src/NadekoBot/Services/Permissions/CmdCdService.cs b/src/NadekoBot/Services/Permissions/CmdCdService.cs index 0a1cbf47..7a44a292 100644 --- a/src/NadekoBot/Services/Permissions/CmdCdService.cs +++ b/src/NadekoBot/Services/Permissions/CmdCdService.cs @@ -21,7 +21,7 @@ namespace NadekoBot.Services.Permissions v => new ConcurrentHashSet(v.CommandCooldowns))); } - public Task TryBlockLate(DiscordShardedClient client, IUserMessage msg, IGuild guild, + public Task TryBlockLate(DiscordSocketClient client, IUserMessage msg, IGuild guild, IMessageChannel channel, IUser user, string moduleName, string commandName) { if (guild == null) diff --git a/src/NadekoBot/Services/Permissions/FilterService.cs b/src/NadekoBot/Services/Permissions/FilterService.cs index 2dbd375d..adbe0aee 100644 --- a/src/NadekoBot/Services/Permissions/FilterService.cs +++ b/src/NadekoBot/Services/Permissions/FilterService.cs @@ -41,7 +41,7 @@ namespace NadekoBot.Services.Permissions return words; } - public FilterService(DiscordShardedClient _client, IEnumerable gcs) + public FilterService(DiscordSocketClient _client, IEnumerable gcs) { _log = LogManager.GetCurrentClassLogger(); diff --git a/src/NadekoBot/Services/Permissions/GlobalPermissionService.cs b/src/NadekoBot/Services/Permissions/GlobalPermissionService.cs index 633a81a3..419f77f3 100644 --- a/src/NadekoBot/Services/Permissions/GlobalPermissionService.cs +++ b/src/NadekoBot/Services/Permissions/GlobalPermissionService.cs @@ -19,7 +19,7 @@ namespace NadekoBot.Services.Permissions BlockedCommands = new ConcurrentHashSet(bc.BlockedCommands.Select(x => x.Name)); } - public async Task TryBlockLate(DiscordShardedClient client, IUserMessage msg, IGuild guild, IMessageChannel channel, IUser user, string moduleName, string commandName) + public async Task TryBlockLate(DiscordSocketClient client, IUserMessage msg, IGuild guild, IMessageChannel channel, IUser user, string moduleName, string commandName) { await Task.Yield(); commandName = commandName.ToLowerInvariant(); diff --git a/src/NadekoBot/Services/Permissions/PermissionsService.cs b/src/NadekoBot/Services/Permissions/PermissionsService.cs index 765cb131..27b547be 100644 --- a/src/NadekoBot/Services/Permissions/PermissionsService.cs +++ b/src/NadekoBot/Services/Permissions/PermissionsService.cs @@ -1,4 +1,5 @@ -using Microsoft.EntityFrameworkCore; + +using Microsoft.EntityFrameworkCore; using NadekoBot.DataStructures.ModuleBehaviors; using NadekoBot.Services.Database.Models; using NLog; @@ -183,7 +184,7 @@ WHERE secondaryTargetName LIKE '.%' OR }); } - public async Task TryBlockLate(DiscordShardedClient client, IUserMessage msg, IGuild guild, IMessageChannel channel, IUser user, string moduleName, string commandName) + public async Task TryBlockLate(DiscordSocketClient client, IUserMessage msg, IGuild guild, IMessageChannel channel, IUser user, string moduleName, string commandName) { await Task.Yield(); if (guild == null) diff --git a/src/NadekoBot/Services/Searches/SearchesService.cs b/src/NadekoBot/Services/Searches/SearchesService.cs index 864c9522..8c98a22e 100644 --- a/src/NadekoBot/Services/Searches/SearchesService.cs +++ b/src/NadekoBot/Services/Searches/SearchesService.cs @@ -15,7 +15,7 @@ namespace NadekoBot.Services.Searches { public class SearchesService { - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly IGoogleApiService _google; private readonly DbService _db; private readonly Logger _log; @@ -31,7 +31,7 @@ namespace NadekoBot.Services.Searches public List WowJokes { get; } = new List(); public List MagicItems { get; } = new List(); - public SearchesService(DiscordShardedClient client, IGoogleApiService google, DbService db) + public SearchesService(DiscordSocketClient client, IGoogleApiService google, DbService db) { _client = client; _google = google; diff --git a/src/NadekoBot/Services/Searches/StreamNotificationService.cs b/src/NadekoBot/Services/Searches/StreamNotificationService.cs index 3fdbb9ac..9b8480fc 100644 --- a/src/NadekoBot/Services/Searches/StreamNotificationService.cs +++ b/src/NadekoBot/Services/Searches/StreamNotificationService.cs @@ -20,10 +20,10 @@ namespace NadekoBot.Services.Searches private readonly ConcurrentDictionary _cachedStatuses = new ConcurrentDictionary(); private readonly DbService _db; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly NadekoStrings _strings; - public StreamNotificationService(DbService db, DiscordShardedClient client, NadekoStrings strings) + public StreamNotificationService(DbService db, DiscordSocketClient client, NadekoStrings strings) { _db = db; _client = client; diff --git a/src/NadekoBot/Services/Utility/MessageRepeaterService.cs b/src/NadekoBot/Services/Utility/MessageRepeaterService.cs index 57873ef1..cc402aa8 100644 --- a/src/NadekoBot/Services/Utility/MessageRepeaterService.cs +++ b/src/NadekoBot/Services/Utility/MessageRepeaterService.cs @@ -15,7 +15,7 @@ namespace NadekoBot.Services.Utility public ConcurrentDictionary> Repeaters { get; set; } public bool RepeaterReady { get; private set; } - public MessageRepeaterService(NadekoBot bot, DiscordShardedClient client, IEnumerable gcs) + public MessageRepeaterService(NadekoBot bot, DiscordSocketClient client, IEnumerable gcs) { var _ = Task.Run(async () => { diff --git a/src/NadekoBot/Services/Utility/RemindService.cs b/src/NadekoBot/Services/Utility/RemindService.cs index a6dd276b..545e8648 100644 --- a/src/NadekoBot/Services/Utility/RemindService.cs +++ b/src/NadekoBot/Services/Utility/RemindService.cs @@ -30,10 +30,10 @@ namespace NadekoBot.Services.Utility private readonly CancellationTokenSource cancelSource; private readonly CancellationToken cancelAllToken; private readonly BotConfig _config; - private readonly DiscordShardedClient _client; + private readonly DiscordSocketClient _client; private readonly DbService _db; - public RemindService(DiscordShardedClient client, BotConfig config, DbService db) + public RemindService(DiscordSocketClient client, BotConfig config, DbService db) { _config = config; _client = client; diff --git a/src/NadekoBot/Services/Utility/RepeatRunner.cs b/src/NadekoBot/Services/Utility/RepeatRunner.cs index 8c96dc8b..abfa21b1 100644 --- a/src/NadekoBot/Services/Utility/RepeatRunner.cs +++ b/src/NadekoBot/Services/Utility/RepeatRunner.cs @@ -22,7 +22,7 @@ namespace NadekoBot.Services.Utility private IUserMessage oldMsg = null; private Timer _t; - public RepeatRunner(DiscordShardedClient client, Repeater repeater) + public RepeatRunner(DiscordSocketClient client, Repeater repeater) { _log = LogManager.GetCurrentClassLogger(); Repeater = repeater; diff --git a/src/NadekoBot/Services/Utility/UtilityService.cs b/src/NadekoBot/Services/Utility/UtilityService.cs index 660984b2..14af97e8 100644 --- a/src/NadekoBot/Services/Utility/UtilityService.cs +++ b/src/NadekoBot/Services/Utility/UtilityService.cs @@ -13,9 +13,9 @@ namespace NadekoBot.Services.Utility { public readonly ConcurrentDictionary> Subscribers = new ConcurrentDictionary>(); - private DiscordShardedClient _client; + private DiscordSocketClient _client; - public CrossServerTextService(IEnumerable guildConfigs, DiscordShardedClient client) + public CrossServerTextService(IEnumerable guildConfigs, DiscordSocketClient client) { _client = client; _client.MessageReceived += Client_MessageReceived; diff --git a/src/NadekoBot/ShardsCoordinator.cs b/src/NadekoBot/ShardsCoordinator.cs new file mode 100644 index 00000000..6db3aade --- /dev/null +++ b/src/NadekoBot/ShardsCoordinator.cs @@ -0,0 +1,95 @@ +using NadekoBot.DataStructures.ShardCom; +using NadekoBot.Services; +using NadekoBot.Services.Impl; +using NLog; +using System; +using System.Diagnostics; +using System.Linq; +using System.Threading.Tasks; + +namespace NadekoBot +{ + public class ShardsCoordinator + { + private readonly BotCredentials Credentials; + private Process[] ShardProcesses; + private ShardComMessage[] Statuses; + private readonly Logger _log; + private readonly ShardComServer _comServer; + + public ShardsCoordinator() + { + LogSetup.SetupLogger(); + Credentials = new BotCredentials(); + ShardProcesses = new Process[Credentials.TotalShards]; + Statuses = new ShardComMessage[Credentials.TotalShards]; + _log = LogManager.GetCurrentClassLogger(); + + _comServer = new ShardComServer(); + _comServer.Start(); + + _comServer.OnDataReceived += _comServer_OnDataReceived; + } + + private Task _comServer_OnDataReceived(ShardComMessage msg) + { + Statuses[msg.ShardId] = msg; + if (msg.ConnectionState == Discord.ConnectionState.Disconnected || msg.ConnectionState == Discord.ConnectionState.Disconnecting) + _log.Error("!!! SHARD {0} IS IN {1} STATE", msg.ShardId, msg.ConnectionState); + return Task.CompletedTask; + } + + public async Task RunAsync(params string[] args) + { + var curProcessId = Process.GetCurrentProcess().Id; + for (int i = 0; i < Credentials.TotalShards; i++) + { + var p = Process.Start(new ProcessStartInfo() + { + FileName = "dotnet", + Arguments = $"run -c Debug -- {i} {curProcessId}", + }); + await Task.Delay(5000); + + //Task.Run(() => { while (!p.HasExited) _log.Info($"S-{i}|" + p.StandardOutput.ReadLine()); }); + //Task.Run(() => { while (!p.HasExited) _log.Error($"S-{i}|" + p.StandardError.ReadLine()); }); + } + } + + public async Task RunAndBlockAsync(params string[] args) + { + try + { + await RunAsync(args).ConfigureAwait(false); + } + catch (Exception ex) + { + _log.Error(ex); + } + await Task.Run(() => + { + string input; + while ((input = Console.ReadLine()?.ToLowerInvariant()) != "quit") + { + switch (input) + { + case "ls": + var groupStr = string.Join(",", Statuses + .Where(x => x != null) + .GroupBy(x => x.ConnectionState) + .Select(x => x.Count() + " " + x.Key)); + _log.Info(string.Join("\n", Statuses.Select(x => $"Shard {x.ShardId} is in {x.ConnectionState.ToString()} state with {x.Guilds} servers")) + "\n" + groupStr); + break; + default: + break; + } + } + }); + foreach (var p in ShardProcesses) + { + try { p.Kill(); } catch { } + try { p.Dispose(); } catch { } + } + } + } +} diff --git a/src/NadekoBot/_Extensions/Extensions.cs b/src/NadekoBot/_Extensions/Extensions.cs index cafb5d32..10e97e14 100644 --- a/src/NadekoBot/_Extensions/Extensions.cs +++ b/src/NadekoBot/_Extensions/Extensions.cs @@ -70,7 +70,7 @@ namespace NadekoBot.Extensions /// /// danny kamisama /// - public static async Task SendPaginatedConfirmAsync(this IMessageChannel channel, DiscordShardedClient client, int currentPage, Func pageFunc, int? lastPage = null, bool addPaginatedFooter = true) + public static async Task SendPaginatedConfirmAsync(this IMessageChannel channel, DiscordSocketClient client, int currentPage, Func pageFunc, int? lastPage = null, bool addPaginatedFooter = true) { var embed = pageFunc(currentPage); @@ -134,7 +134,7 @@ namespace NadekoBot.Extensions return embed.WithFooter(efb => efb.WithText(curPage.ToString())); } - public static ReactionEventWrapper OnReaction(this IUserMessage msg, DiscordShardedClient client, Action reactionAdded, Action reactionRemoved = null) + public static ReactionEventWrapper OnReaction(this IUserMessage msg, DiscordSocketClient client, Action reactionAdded, Action reactionRemoved = null) { if (reactionRemoved == null) reactionRemoved = delegate { };