diff --git a/src/NadekoBot/Modules/Utility/Commands/UnitConversion.cs b/src/NadekoBot/Modules/Utility/Commands/UnitConversion.cs index 603093c4..f325c402 100644 --- a/src/NadekoBot/Modules/Utility/Commands/UnitConversion.cs +++ b/src/NadekoBot/Modules/Utility/Commands/UnitConversion.cs @@ -6,7 +6,7 @@ //using System; //using System.Linq; //using System.Threading.Tasks; - +////todo Rewrite //namespace NadekoBot.Modules.Utility //{ // public partial class Utility diff --git a/src/NadekoBot/Modules/Utility/Utility.cs b/src/NadekoBot/Modules/Utility/Utility.cs index 51f24efc..3ae25163 100644 --- a/src/NadekoBot/Modules/Utility/Utility.cs +++ b/src/NadekoBot/Modules/Utility/Utility.cs @@ -319,11 +319,7 @@ namespace NadekoBot.Modules.Utility [NadekoCommand, Usage, Description, Aliases] public async Task Stats() - { - //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}") @@ -339,13 +335,7 @@ namespace NadekoBot.Modules.Utility .AddField(efb => efb.WithName(GetText("uptime")).WithValue(_stats.GetUptimeString("\n")).WithIsInline(true)) .AddField(efb => efb.WithName(GetText("presence")).WithValue( GetText("presence_txt", - _client.Guilds.Count, _stats.TextChannels, _stats.VoiceChannels)).WithIsInline(true)) -#if !GLOBAL_NADEKO - //.WithFooter(efb => efb.WithText(GetText("stats_songs", - // _music.MusicPlayers.Count(mp => mp.Value.CurrentSong != null), - // _music.MusicPlayers.Sum(mp => mp.Value.Playlist.Count)))) -#endif - ); + _stats.GuildCount, _stats.TextChannels, _stats.VoiceChannels)).WithIsInline(true))); } [NadekoCommand, Usage, Description, Aliases] diff --git a/src/NadekoBot/NadekoBot.cs b/src/NadekoBot/NadekoBot.cs index 8f6e926b..9025a0a3 100644 --- a/src/NadekoBot/NadekoBot.cs +++ b/src/NadekoBot/NadekoBot.cs @@ -139,169 +139,179 @@ namespace NadekoBot private void AddServices() { var startingGuildIdList = Client.Guilds.Select(x => (long)x.Id).ToList(); + + //this unit of work will be used for initialization of all modules too, to prevent multiple queries from running using (var uow = Db.UnitOfWork) { AllGuildConfigs = uow.GuildConfigs.GetAllGuildConfigs(startingGuildIdList).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, ShardCoord); + + var soundcloudApiService = new SoundCloudApiService(Credentials); + + #region help + var helpService = new HelpService(BotConfig, CommandHandler, Strings); + #endregion + + //module services + //todo 90 - autodiscover, DI, and add instead of manual like this + #region utility + var remindService = new RemindService(Client, BotConfig, Db, startingGuildIdList, uow); + var repeaterService = new MessageRepeaterService(this, Client, AllGuildConfigs); + //var converterService = new ConverterService(Db); + var commandMapService = new CommandMapService(AllGuildConfigs); + var patreonRewardsService = new PatreonRewardsService(Credentials, Db, Currency); + var verboseErrorsService = new VerboseErrorsService(AllGuildConfigs, Db, CommandHandler, helpService); + var pruneService = new PruneService(); + #endregion + + #region permissions + var permissionsService = new PermissionService(Client, Db, BotConfig, CommandHandler); + var blacklistService = new BlacklistService(BotConfig); + var cmdcdsService = new CmdCdService(AllGuildConfigs); + var filterService = new FilterService(Client, AllGuildConfigs); + var globalPermsService = new GlobalPermissionService(BotConfig); + #endregion + + #region Searches + var searchesService = new SearchesService(Client, GoogleApi, Db); + var streamNotificationService = new StreamNotificationService(Db, Client, Strings); + var animeSearchService = new AnimeSearchService(); + #endregion + + var clashService = new ClashOfClansService(Client, Db, Localization, Strings, uow, startingGuildIdList); + var musicService = new MusicService(GoogleApi, Strings, Localization, Db, soundcloudApiService, Credentials, AllGuildConfigs); + var crService = new CustomReactionsService(permissionsService, Db, Client, CommandHandler, BotConfig, uow); + + #region Games + var gamesService = new GamesService(Client, BotConfig, AllGuildConfigs, Strings, Images, CommandHandler); + var chatterBotService = new ChatterBotService(Client, permissionsService, AllGuildConfigs, CommandHandler); + var pollService = new PollService(Client, Strings); + #endregion + + #region administration + var administrationService = new AdministrationService(AllGuildConfigs, CommandHandler); + var greetSettingsService = new GreetSettingsService(Client, AllGuildConfigs, Db); + var selfService = new SelfService(Client, this, CommandHandler, Db, BotConfig, Localization, Strings, Credentials); + var vcRoleService = new VcRoleService(Client, AllGuildConfigs, Db); + var vPlusTService = new VplusTService(Client, AllGuildConfigs, Strings, Db); + var muteService = new MuteService(Client, AllGuildConfigs, Db); + var ratelimitService = new SlowmodeService(Client, AllGuildConfigs); + var protectionService = new ProtectionService(Client, AllGuildConfigs, muteService); + var playingRotateService = new PlayingRotateService(Client, BotConfig, musicService); + var gameVcService = new GameVoiceChannelService(Client, Db, AllGuildConfigs); + var autoAssignRoleService = new AutoAssignRoleService(Client, AllGuildConfigs); + var logCommandService = new LogCommandService(Client, Strings, AllGuildConfigs, Db, muteService, protectionService); + var guildTimezoneService = new GuildTimezoneService(AllGuildConfigs, Db); + #endregion + + #region pokemon + var pokemonService = new PokemonService(); + #endregion + + + + //initialize Services + Services = new NServiceProvider.ServiceProviderBuilder() + .Add(Localization) + .Add(Stats) + .Add(Images) + .Add(GoogleApi) + .Add(Stats) + .Add(Credentials) + .Add(CommandService) + .Add(Strings) + .Add(Client) + .Add(BotConfig) + .Add(Currency) + .Add(CommandHandler) + .Add(Db) + //modules + .Add(commandMapService) + .Add(remindService) + .Add(repeaterService) + //.Add(converterService) + .Add(verboseErrorsService) + .Add(patreonRewardsService) + .Add(pruneService) + .Add(searchesService) + .Add(streamNotificationService) + .Add(animeSearchService) + .Add(clashService) + .Add(musicService) + .Add(greetSettingsService) + .Add(crService) + .Add(helpService) + .Add(gamesService) + .Add(chatterBotService) + .Add(pollService) + .Add(administrationService) + .Add(selfService) + .Add(vcRoleService) + .Add(vPlusTService) + .Add(muteService) + .Add(ratelimitService) + .Add(playingRotateService) + .Add(gameVcService) + .Add(autoAssignRoleService) + .Add(protectionService) + .Add(logCommandService) + .Add(guildTimezoneService) + .Add(permissionsService) + .Add(blacklistService) + .Add(cmdcdsService) + .Add(filterService) + .Add(globalPermsService) + .Add(pokemonService) + .Add(this) + .Build(); + + + CommandHandler.AddServices(Services); + + //setup typereaders + CommandService.AddTypeReader(new PermissionActionTypeReader()); + CommandService.AddTypeReader(new CommandTypeReader(CommandService, CommandHandler)); + CommandService.AddTypeReader(new CommandOrCrTypeReader(crService, CommandService, CommandHandler)); + CommandService.AddTypeReader(new ModuleTypeReader(CommandService)); + CommandService.AddTypeReader(new ModuleOrCrTypeReader(CommandService)); + CommandService.AddTypeReader(new GuildTypeReader(Client)); + CommandService.AddTypeReader(new GuildDateTimeTypeReader(guildTimezoneService)); + } - 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 - var helpService = new HelpService(BotConfig, CommandHandler, Strings); - #endregion - - //module services - //todo 90 - autodiscover, DI, and add instead of manual like this - #region utility - var remindService = new RemindService(Client, BotConfig, Db, startingGuildIdList); - var repeaterService = new MessageRepeaterService(this, Client, AllGuildConfigs); - //var converterService = new ConverterService(Db); - var commandMapService = new CommandMapService(AllGuildConfigs); - var patreonRewardsService = new PatreonRewardsService(Credentials, Db, Currency); - var verboseErrorsService = new VerboseErrorsService(AllGuildConfigs, Db, CommandHandler, helpService); - var pruneService = new PruneService(); - #endregion - - #region permissions - var permissionsService = new PermissionService(Client, Db, BotConfig, CommandHandler); - var blacklistService = new BlacklistService(BotConfig); - var cmdcdsService = new CmdCdService(AllGuildConfigs); - var filterService = new FilterService(Client, AllGuildConfigs); - var globalPermsService = new GlobalPermissionService(BotConfig); - #endregion - - #region Searches - var searchesService = new SearchesService(Client, GoogleApi, Db); - var streamNotificationService = new StreamNotificationService(Db, Client, Strings); - var animeSearchService = new AnimeSearchService(); - #endregion - - var clashService = new ClashOfClansService(Client, Db, Localization, Strings); - var musicService = new MusicService(GoogleApi, Strings, Localization, Db, soundcloudApiService, Credentials, AllGuildConfigs); - var crService = new CustomReactionsService(permissionsService, Db, Client, CommandHandler, BotConfig); - - #region Games - var gamesService = new GamesService(Client, BotConfig, AllGuildConfigs, Strings, Images, CommandHandler); - var chatterBotService = new ChatterBotService(Client, permissionsService, AllGuildConfigs, CommandHandler); - var pollService = new PollService(Client, Strings); - #endregion - - #region administration - var administrationService = new AdministrationService(AllGuildConfigs, CommandHandler); - var greetSettingsService = new GreetSettingsService(Client, AllGuildConfigs, Db); - var selfService = new SelfService(Client, this, CommandHandler, Db, BotConfig, Localization, Strings, Credentials); - var vcRoleService = new VcRoleService(Client, AllGuildConfigs, Db); - var vPlusTService = new VplusTService(Client, AllGuildConfigs, Strings, Db); - var muteService = new MuteService(Client, AllGuildConfigs, Db); - var ratelimitService = new SlowmodeService(Client, AllGuildConfigs); - var protectionService = new ProtectionService(Client, AllGuildConfigs, muteService); - var playingRotateService = new PlayingRotateService(Client, BotConfig, musicService); - var gameVcService = new GameVoiceChannelService(Client, Db, AllGuildConfigs); - var autoAssignRoleService = new AutoAssignRoleService(Client, AllGuildConfigs); - var logCommandService = new LogCommandService(Client, Strings, AllGuildConfigs, Db, muteService, protectionService); - var guildTimezoneService = new GuildTimezoneService(AllGuildConfigs, Db); - #endregion - - #region pokemon - var pokemonService = new PokemonService(); - #endregion - - - //initialize Services - Services = new NServiceProvider.ServiceProviderBuilder() - .Add(Localization) - .Add(Stats) - .Add(Images) - .Add(GoogleApi) - .Add(Stats) - .Add(Credentials) - .Add(CommandService) - .Add(Strings) - .Add(Client) - .Add(BotConfig) - .Add(Currency) - .Add(CommandHandler) - .Add(Db) - //modules - .Add(commandMapService) - .Add(remindService) - .Add(repeaterService) - //.Add(converterService) - .Add(verboseErrorsService) - .Add(patreonRewardsService) - .Add(pruneService) - .Add(searchesService) - .Add(streamNotificationService) - .Add(animeSearchService) - .Add(clashService) - .Add(musicService) - .Add(greetSettingsService) - .Add(crService) - .Add(helpService) - .Add(gamesService) - .Add(chatterBotService) - .Add(pollService) - .Add(administrationService) - .Add(selfService) - .Add(vcRoleService) - .Add(vPlusTService) - .Add(muteService) - .Add(ratelimitService) - .Add(playingRotateService) - .Add(gameVcService) - .Add(autoAssignRoleService) - .Add(protectionService) - .Add(logCommandService) - .Add(guildTimezoneService) - .Add(permissionsService) - .Add(blacklistService) - .Add(cmdcdsService) - .Add(filterService) - .Add(globalPermsService) - .Add(pokemonService) - .Add(this) - .Build(); - - CommandHandler.AddServices(Services); - - //setup typereaders - CommandService.AddTypeReader(new PermissionActionTypeReader()); - CommandService.AddTypeReader(new CommandTypeReader(CommandService, CommandHandler)); - CommandService.AddTypeReader(new CommandOrCrTypeReader(crService, CommandService, CommandHandler)); - CommandService.AddTypeReader(new ModuleTypeReader(CommandService)); - CommandService.AddTypeReader(new ModuleOrCrTypeReader(CommandService)); - CommandService.AddTypeReader(new GuildTypeReader(Client)); - CommandService.AddTypeReader(new GuildDateTimeTypeReader(guildTimezoneService)); } - private Task LoginAsync(string token) + private async Task LoginAsync(string token) { + var clientReady = new TaskCompletionSource(); + + Task SetClientReady() + { + clientReady.TrySetResult(true); + return Task.CompletedTask; + } + //connect try { sem.WaitOne(); } catch (AbandonedMutexException) { } + _log.Info("Shard {0} logging in ...", ShardId); + try { Client.LoginAsync(TokenType.Bot, token).GetAwaiter().GetResult(); Client.StartAsync().GetAwaiter().GetResult(); - while (Client.ConnectionState != ConnectionState.Connected) - Task.Delay(100).GetAwaiter().GetResult(); + Client.Ready += SetClientReady; + await clientReady.Task.ConfigureAwait(false); + Client.Ready -= SetClientReady; } 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) diff --git a/src/NadekoBot/Services/Administration/SelfService.cs b/src/NadekoBot/Services/Administration/SelfService.cs index 0a288a0b..336f9970 100644 --- a/src/NadekoBot/Services/Administration/SelfService.cs +++ b/src/NadekoBot/Services/Administration/SelfService.cs @@ -39,12 +39,8 @@ namespace NadekoBot.Services.Administration _client = client; _creds = creds; - using (var uow = _db.UnitOfWork) - { - var config = uow.BotConfig.GetOrCreate(); - ForwardDMs = config.ForwardMessages; - ForwardDMsToAllOwners = config.ForwardToAllOwners; - } + ForwardDMs = bc.ForwardMessages; + ForwardDMsToAllOwners = bc.ForwardToAllOwners; var _ = Task.Run(async () => { diff --git a/src/NadekoBot/Services/ClashOfClans/ClashOfClansService.cs b/src/NadekoBot/Services/ClashOfClans/ClashOfClansService.cs index 042afa1b..dcdd6376 100644 --- a/src/NadekoBot/Services/ClashOfClans/ClashOfClansService.cs +++ b/src/NadekoBot/Services/ClashOfClans/ClashOfClansService.cs @@ -1,6 +1,7 @@ using Discord; using Discord.WebSocket; using NadekoBot.Extensions; +using NadekoBot.Services.Database; using NadekoBot.Services.Database.Models; using System; using System.Collections.Concurrent; @@ -25,28 +26,27 @@ namespace NadekoBot.Services.ClashOfClans public ConcurrentDictionary> ClashWars { get; set; } - public ClashOfClansService(DiscordSocketClient client, DbService db, ILocalization localization, NadekoStrings strings) + public ClashOfClansService(DiscordSocketClient client, DbService db, + ILocalization localization, NadekoStrings strings, IUnitOfWork uow, + List guilds) { _client = client; _db = db; _localization = localization; _strings = strings; - using (var uow = _db.UnitOfWork) - { - ClashWars = new ConcurrentDictionary>( - uow.ClashOfClans - .GetAllWars() - .Select(cw => - { - cw.Channel = _client.GetGuild(cw.GuildId)? - .GetTextChannel(cw.ChannelId); - return cw; - }) - .Where(cw => cw.Channel != null) - .GroupBy(cw => cw.GuildId) - .ToDictionary(g => g.Key, g => g.ToList())); - } + ClashWars = new ConcurrentDictionary>( + uow.ClashOfClans + .GetAllWars(guilds) + .Select(cw => + { + cw.Channel = _client.GetGuild(cw.GuildId)? + .GetTextChannel(cw.ChannelId); + return cw; + }) + .Where(cw => cw.Channel != null) + .GroupBy(cw => cw.GuildId) + .ToDictionary(g => g.Key, g => g.ToList())); checkWarTimer = new Timer(async _ => { diff --git a/src/NadekoBot/Services/CustomReactions/CustomReactionsService.cs b/src/NadekoBot/Services/CustomReactions/CustomReactionsService.cs index bb7fb8d9..ecf0dede 100644 --- a/src/NadekoBot/Services/CustomReactions/CustomReactionsService.cs +++ b/src/NadekoBot/Services/CustomReactions/CustomReactionsService.cs @@ -10,6 +10,7 @@ using System; using System.Threading.Tasks; using NadekoBot.Services.Permissions; using NadekoBot.Extensions; +using NadekoBot.Services.Database; namespace NadekoBot.Services.CustomReactions { @@ -28,7 +29,7 @@ namespace NadekoBot.Services.CustomReactions private readonly BotConfig _bc; public CustomReactionsService(PermissionService perms, DbService db, - DiscordSocketClient client, CommandHandler cmd, BotConfig bc) + DiscordSocketClient client, CommandHandler cmd, BotConfig bc, IUnitOfWork uow) { _log = LogManager.GetCurrentClassLogger(); _db = db; @@ -36,13 +37,10 @@ namespace NadekoBot.Services.CustomReactions _perms = perms; _cmd = cmd; _bc = bc; - - 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(); - } + + 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(); } public void ClearStats() => ReactionStats.Clear(); diff --git a/src/NadekoBot/Services/Database/Repositories/IClashOfClansRepository.cs b/src/NadekoBot/Services/Database/Repositories/IClashOfClansRepository.cs index 756e9789..14edcea8 100644 --- a/src/NadekoBot/Services/Database/Repositories/IClashOfClansRepository.cs +++ b/src/NadekoBot/Services/Database/Repositories/IClashOfClansRepository.cs @@ -5,6 +5,6 @@ namespace NadekoBot.Services.Database.Repositories { public interface IClashOfClansRepository : IRepository { - IEnumerable GetAllWars(); + IEnumerable GetAllWars(List guilds); } } diff --git a/src/NadekoBot/Services/Database/Repositories/Impl/ClashOfClansRepository.cs b/src/NadekoBot/Services/Database/Repositories/Impl/ClashOfClansRepository.cs index 54a391fa..828c4bce 100644 --- a/src/NadekoBot/Services/Database/Repositories/Impl/ClashOfClansRepository.cs +++ b/src/NadekoBot/Services/Database/Repositories/Impl/ClashOfClansRepository.cs @@ -11,9 +11,11 @@ namespace NadekoBot.Services.Database.Repositories.Impl { } - public IEnumerable GetAllWars() + public IEnumerable GetAllWars(List guilds) { - var toReturn = _set.Include(cw => cw.Bases) + var toReturn = _set + .Where(cw => guilds.Contains((long)cw.GuildId)) + .Include(cw => cw.Bases) .ToList(); toReturn.ForEach(cw => cw.Bases = cw.Bases.Where(w => w.SequenceNumber != null).OrderBy(w => w.SequenceNumber).ToList()); return toReturn; diff --git a/src/NadekoBot/Services/IStatsService.cs b/src/NadekoBot/Services/IStatsService.cs index a7735fc8..d187c413 100644 --- a/src/NadekoBot/Services/IStatsService.cs +++ b/src/NadekoBot/Services/IStatsService.cs @@ -13,6 +13,7 @@ namespace NadekoBot.Services double MessagesPerSecond { get; } long TextChannels { get; } long VoiceChannels { get; } + int GuildCount { get; } TimeSpan GetUptime(); string GetUptimeString(string separator = ", "); diff --git a/src/NadekoBot/Services/Impl/StatsService.cs b/src/NadekoBot/Services/Impl/StatsService.cs index 5d93196d..8cce6936 100644 --- a/src/NadekoBot/Services/Impl/StatsService.cs +++ b/src/NadekoBot/Services/Impl/StatsService.cs @@ -35,11 +35,16 @@ namespace NadekoBot.Services.Impl public long CommandsRan => Interlocked.Read(ref _commandsRan); private readonly Timer _carbonitexTimer; + private readonly ShardsCoordinator _sc; - public StatsService(DiscordSocketClient client, CommandHandler cmdHandler, IBotCredentials creds) + public int GuildCount => + _sc?.GuildCount ?? _client.Guilds.Count(); + + public StatsService(DiscordSocketClient client, CommandHandler cmdHandler, IBotCredentials creds, ShardsCoordinator sc) { _client = client; _creds = creds; + _sc = sc; _started = DateTime.UtcNow; _client.MessageReceived += _ => Task.FromResult(Interlocked.Increment(ref _messageCounter)); @@ -122,31 +127,34 @@ namespace NadekoBot.Services.Impl }; //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"); + if (sc != null) + { + _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", sc.GuildCount.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/Permissions/PermissionsService.cs b/src/NadekoBot/Services/Permissions/PermissionsService.cs index 7ca39a03..00794d2d 100644 --- a/src/NadekoBot/Services/Permissions/PermissionsService.cs +++ b/src/NadekoBot/Services/Permissions/PermissionsService.cs @@ -11,6 +11,7 @@ using System.Threading.Tasks; using Discord; using Discord.WebSocket; using NadekoBot.Extensions; +using NadekoBot.Services; namespace NadekoBot.Services.Permissions { @@ -31,24 +32,21 @@ namespace NadekoBot.Services.Permissions _cmd = cmd; var sw = Stopwatch.StartNew(); - TryMigratePermissions(bc); + if (client.ShardId == 0) + TryMigratePermissions(bc); - client.Ready += delegate + using (var uow = _db.UnitOfWork) { - using (var uow = _db.UnitOfWork) + foreach (var x in uow.GuildConfigs.Permissionsv2ForAll(client.Guilds.ToArray().Select(x => (long)x.Id).ToList())) { - foreach (var x in uow.GuildConfigs.Permissionsv2ForAll(client.Guilds.Select(x => (long)x.Id).ToList())) + Cache.TryAdd(x.GuildId, new PermissionCache() { - Cache.TryAdd(x.GuildId, new PermissionCache() - { - Verbose = x.VerbosePermissions, - PermRole = x.PermissionRole, - Permissions = new PermissionsCollection(x.Permissions) - }); - } + Verbose = x.VerbosePermissions, + PermRole = x.PermissionRole, + Permissions = new PermissionsCollection(x.Permissions) + }); } - return Task.CompletedTask; - }; + } sw.Stop(); _log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s"); @@ -74,10 +72,9 @@ namespace NadekoBot.Services.Permissions private void TryMigratePermissions(BotConfig bc) { var log = LogManager.GetCurrentClassLogger(); - using (var uow = _db.UnitOfWork) + if (bc.PermissionVersion <= 1) { - var _bc = uow.BotConfig.GetOrCreate(); - if (_bc.PermissionVersion <= 1) + using (var uow = _db.UnitOfWork) { log.Info("Permission version is 1, upgrading to 2."); var oldCache = new ConcurrentDictionary(uow.GuildConfigs @@ -132,9 +129,13 @@ namespace NadekoBot.Services.Permissions log.Info("Permission migration to v2 is done."); } - _bc.PermissionVersion = 2; + bc.PermissionVersion = 2; + uow.Complete(); } - if (_bc.PermissionVersion <= 2) + } + if (bc.PermissionVersion <= 2) + { + using (var uow = _db.UnitOfWork) { var oldPrefixes = new[] { ".", ";", "!!", "!m", "!", "+", "-", "$", ">" }; uow._context.Database.ExecuteSqlCommand( @@ -150,9 +151,9 @@ WHERE secondaryTargetName LIKE '.%' OR secondaryTargetName LIKE '>%' OR secondaryTargetName LIKE '-%' OR secondaryTargetName LIKE '!%';"); - _bc.PermissionVersion = 3; + bc.PermissionVersion = 3; + uow.Complete(); } - uow.Complete(); } } diff --git a/src/NadekoBot/Services/Searches/StreamNotificationService.cs b/src/NadekoBot/Services/Searches/StreamNotificationService.cs index a5846362..c077e4e1 100644 --- a/src/NadekoBot/Services/Searches/StreamNotificationService.cs +++ b/src/NadekoBot/Services/Searches/StreamNotificationService.cs @@ -1,6 +1,8 @@ using Discord; using Discord.WebSocket; using NadekoBot.Extensions; +using NadekoBot.Services; +using NadekoBot.Services.Database; using NadekoBot.Services.Database.Models; using Newtonsoft.Json; using System; @@ -73,7 +75,7 @@ namespace NadekoBot.Services.Searches })); firstStreamNotifPass = false; - }, null, TimeSpan.Zero, TimeSpan.FromSeconds(60)); + }, null, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(60)); } public async Task GetStreamStatus(FollowedStream stream, bool checkCache = true) diff --git a/src/NadekoBot/Services/Utility/RemindService.cs b/src/NadekoBot/Services/Utility/RemindService.cs index 16d6d451..8629712d 100644 --- a/src/NadekoBot/Services/Utility/RemindService.cs +++ b/src/NadekoBot/Services/Utility/RemindService.cs @@ -1,6 +1,7 @@ using Discord; using Discord.WebSocket; using NadekoBot.Extensions; +using NadekoBot.Services.Database; using NadekoBot.Services.Database.Models; using NLog; using System; @@ -33,7 +34,8 @@ namespace NadekoBot.Services.Utility private readonly DiscordSocketClient _client; private readonly DbService _db; - public RemindService(DiscordSocketClient client, BotConfig config, DbService db, List guilds) + public RemindService(DiscordSocketClient client, BotConfig config, DbService db, + List guilds, IUnitOfWork uow) { _config = config; _client = client; @@ -42,11 +44,8 @@ namespace NadekoBot.Services.Utility cancelSource = new CancellationTokenSource(); cancelAllToken = cancelSource.Token; - List reminders; - using (var uow = _db.UnitOfWork) - { - reminders = uow.Reminders.GetIncludedReminders(guilds).ToList(); - } + + var reminders = uow.Reminders.GetIncludedReminders(guilds).ToList(); RemindMessageFormat = _config.RemindMessageFormat; foreach (var r in reminders) diff --git a/src/NadekoBot/ShardsCoordinator.cs b/src/NadekoBot/ShardsCoordinator.cs index 4ed8247f..3fe6da58 100644 --- a/src/NadekoBot/ShardsCoordinator.cs +++ b/src/NadekoBot/ShardsCoordinator.cs @@ -14,6 +14,10 @@ namespace NadekoBot private readonly BotCredentials Credentials; private Process[] ShardProcesses; public ShardComMessage[] Statuses { get; } + public int GuildCount => Statuses.ToArray() + .Where(x => x != null) + .Sum(x => x.Guilds); + private readonly Logger _log; private readonly ShardComServer _comServer;