Slightly faster startup and database access. Shard 0 will now report total guild count
This commit is contained in:
		@@ -6,7 +6,7 @@
 | 
			
		||||
//using System;
 | 
			
		||||
//using System.Linq;
 | 
			
		||||
//using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
////todo Rewrite
 | 
			
		||||
//namespace NadekoBot.Modules.Utility
 | 
			
		||||
//{
 | 
			
		||||
//    public partial class Utility
 | 
			
		||||
 
 | 
			
		||||
@@ -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]
 | 
			
		||||
 
 | 
			
		||||
@@ -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<ILocalization>(Localization)
 | 
			
		||||
                    .Add<IStatsService>(Stats)
 | 
			
		||||
                    .Add<IImagesService>(Images)
 | 
			
		||||
                    .Add<IGoogleApiService>(GoogleApi)
 | 
			
		||||
                    .Add<IStatsService>(Stats)
 | 
			
		||||
                    .Add<IBotCredentials>(Credentials)
 | 
			
		||||
                    .Add<CommandService>(CommandService)
 | 
			
		||||
                    .Add<NadekoStrings>(Strings)
 | 
			
		||||
                    .Add<DiscordSocketClient>(Client)
 | 
			
		||||
                    .Add<BotConfig>(BotConfig)
 | 
			
		||||
                    .Add<CurrencyService>(Currency)
 | 
			
		||||
                    .Add<CommandHandler>(CommandHandler)
 | 
			
		||||
                    .Add<DbService>(Db)
 | 
			
		||||
                        //modules
 | 
			
		||||
                        .Add(commandMapService)
 | 
			
		||||
                        .Add(remindService)
 | 
			
		||||
                        .Add(repeaterService)
 | 
			
		||||
                        //.Add(converterService)
 | 
			
		||||
                        .Add(verboseErrorsService)
 | 
			
		||||
                        .Add(patreonRewardsService)
 | 
			
		||||
                        .Add(pruneService)
 | 
			
		||||
                    .Add<SearchesService>(searchesService)
 | 
			
		||||
                        .Add(streamNotificationService)
 | 
			
		||||
                        .Add(animeSearchService)
 | 
			
		||||
                    .Add<ClashOfClansService>(clashService)
 | 
			
		||||
                    .Add<MusicService>(musicService)
 | 
			
		||||
                    .Add<GreetSettingsService>(greetSettingsService)
 | 
			
		||||
                    .Add<CustomReactionsService>(crService)
 | 
			
		||||
                    .Add<HelpService>(helpService)
 | 
			
		||||
                    .Add<GamesService>(gamesService)
 | 
			
		||||
                        .Add(chatterBotService)
 | 
			
		||||
                        .Add(pollService)
 | 
			
		||||
                    .Add<AdministrationService>(administrationService)
 | 
			
		||||
                        .Add(selfService)
 | 
			
		||||
                        .Add(vcRoleService)
 | 
			
		||||
                        .Add(vPlusTService)
 | 
			
		||||
                        .Add(muteService)
 | 
			
		||||
                        .Add(ratelimitService)
 | 
			
		||||
                        .Add(playingRotateService)
 | 
			
		||||
                        .Add(gameVcService)
 | 
			
		||||
                        .Add(autoAssignRoleService)
 | 
			
		||||
                        .Add(protectionService)
 | 
			
		||||
                        .Add(logCommandService)
 | 
			
		||||
                        .Add(guildTimezoneService)
 | 
			
		||||
                    .Add<PermissionService>(permissionsService)
 | 
			
		||||
                        .Add(blacklistService)
 | 
			
		||||
                        .Add(cmdcdsService)
 | 
			
		||||
                        .Add(filterService)
 | 
			
		||||
                        .Add(globalPermsService)
 | 
			
		||||
                    .Add<PokemonService>(pokemonService)
 | 
			
		||||
                    .Add<NadekoBot>(this)
 | 
			
		||||
                    .Build();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                CommandHandler.AddServices(Services);
 | 
			
		||||
 | 
			
		||||
                //setup typereaders
 | 
			
		||||
                CommandService.AddTypeReader<PermissionAction>(new PermissionActionTypeReader());
 | 
			
		||||
                CommandService.AddTypeReader<CommandInfo>(new CommandTypeReader(CommandService, CommandHandler));
 | 
			
		||||
                CommandService.AddTypeReader<CommandOrCrInfo>(new CommandOrCrTypeReader(crService, CommandService, CommandHandler));
 | 
			
		||||
                CommandService.AddTypeReader<ModuleInfo>(new ModuleTypeReader(CommandService));
 | 
			
		||||
                CommandService.AddTypeReader<ModuleOrCrInfo>(new ModuleOrCrTypeReader(CommandService));
 | 
			
		||||
                CommandService.AddTypeReader<IGuild>(new GuildTypeReader(Client));
 | 
			
		||||
                CommandService.AddTypeReader<GuildDateTime>(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<ILocalization>(Localization)
 | 
			
		||||
                .Add<IStatsService>(Stats)
 | 
			
		||||
                .Add<IImagesService>(Images)
 | 
			
		||||
                .Add<IGoogleApiService>(GoogleApi)
 | 
			
		||||
                .Add<IStatsService>(Stats)
 | 
			
		||||
                .Add<IBotCredentials>(Credentials)
 | 
			
		||||
                .Add<CommandService>(CommandService)
 | 
			
		||||
                .Add<NadekoStrings>(Strings)
 | 
			
		||||
                .Add<DiscordSocketClient>(Client)
 | 
			
		||||
                .Add<BotConfig>(BotConfig)
 | 
			
		||||
                .Add<CurrencyService>(Currency)
 | 
			
		||||
                .Add<CommandHandler>(CommandHandler)
 | 
			
		||||
                .Add<DbService>(Db)
 | 
			
		||||
                    //modules
 | 
			
		||||
                    .Add(commandMapService)
 | 
			
		||||
                    .Add(remindService)
 | 
			
		||||
                    .Add(repeaterService)
 | 
			
		||||
                    //.Add(converterService)
 | 
			
		||||
                    .Add(verboseErrorsService)
 | 
			
		||||
                    .Add(patreonRewardsService)
 | 
			
		||||
                    .Add(pruneService)
 | 
			
		||||
                .Add<SearchesService>(searchesService)
 | 
			
		||||
                    .Add(streamNotificationService)
 | 
			
		||||
                    .Add(animeSearchService)
 | 
			
		||||
                .Add<ClashOfClansService>(clashService)
 | 
			
		||||
                .Add<MusicService>(musicService)
 | 
			
		||||
                .Add<GreetSettingsService>(greetSettingsService)
 | 
			
		||||
                .Add<CustomReactionsService>(crService)
 | 
			
		||||
                .Add<HelpService>(helpService)
 | 
			
		||||
                .Add<GamesService>(gamesService)
 | 
			
		||||
                    .Add(chatterBotService)
 | 
			
		||||
                    .Add(pollService)
 | 
			
		||||
                .Add<AdministrationService>(administrationService)
 | 
			
		||||
                    .Add(selfService)
 | 
			
		||||
                    .Add(vcRoleService)
 | 
			
		||||
                    .Add(vPlusTService)
 | 
			
		||||
                    .Add(muteService)
 | 
			
		||||
                    .Add(ratelimitService)
 | 
			
		||||
                    .Add(playingRotateService)
 | 
			
		||||
                    .Add(gameVcService)
 | 
			
		||||
                    .Add(autoAssignRoleService)
 | 
			
		||||
                    .Add(protectionService)
 | 
			
		||||
                    .Add(logCommandService)
 | 
			
		||||
                    .Add(guildTimezoneService)
 | 
			
		||||
                .Add<PermissionService>(permissionsService)
 | 
			
		||||
                    .Add(blacklistService)
 | 
			
		||||
                    .Add(cmdcdsService)
 | 
			
		||||
                    .Add(filterService)
 | 
			
		||||
                    .Add(globalPermsService)
 | 
			
		||||
                .Add<PokemonService>(pokemonService)
 | 
			
		||||
                .Add<NadekoBot>(this)
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            CommandHandler.AddServices(Services);
 | 
			
		||||
 | 
			
		||||
            //setup typereaders
 | 
			
		||||
            CommandService.AddTypeReader<PermissionAction>(new PermissionActionTypeReader());
 | 
			
		||||
            CommandService.AddTypeReader<CommandInfo>(new CommandTypeReader(CommandService, CommandHandler));
 | 
			
		||||
            CommandService.AddTypeReader<CommandOrCrInfo>(new CommandOrCrTypeReader(crService, CommandService, CommandHandler));
 | 
			
		||||
            CommandService.AddTypeReader<ModuleInfo>(new ModuleTypeReader(CommandService));
 | 
			
		||||
            CommandService.AddTypeReader<ModuleOrCrInfo>(new ModuleOrCrTypeReader(CommandService));
 | 
			
		||||
            CommandService.AddTypeReader<IGuild>(new GuildTypeReader(Client));
 | 
			
		||||
            CommandService.AddTypeReader<GuildDateTime>(new GuildDateTimeTypeReader(guildTimezoneService));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private Task LoginAsync(string token)
 | 
			
		||||
        private async Task LoginAsync(string token)
 | 
			
		||||
        {
 | 
			
		||||
            var clientReady = new TaskCompletionSource<bool>();
 | 
			
		||||
 | 
			
		||||
            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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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 () =>
 | 
			
		||||
            {
 | 
			
		||||
 
 | 
			
		||||
@@ -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<ulong, List<ClashWar>> 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<long> guilds)
 | 
			
		||||
        {
 | 
			
		||||
            _client = client;
 | 
			
		||||
            _db = db;
 | 
			
		||||
            _localization = localization;
 | 
			
		||||
            _strings = strings;
 | 
			
		||||
 | 
			
		||||
            using (var uow = _db.UnitOfWork)
 | 
			
		||||
            {
 | 
			
		||||
                ClashWars = new ConcurrentDictionary<ulong, List<ClashWar>>(
 | 
			
		||||
                    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<ulong, List<ClashWar>>(
 | 
			
		||||
                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 _ =>
 | 
			
		||||
            {
 | 
			
		||||
 
 | 
			
		||||
@@ -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<ulong, CustomReaction[]>(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<ulong, CustomReaction[]>(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();
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,6 @@ namespace NadekoBot.Services.Database.Repositories
 | 
			
		||||
{
 | 
			
		||||
    public interface IClashOfClansRepository : IRepository<ClashWar>
 | 
			
		||||
    {
 | 
			
		||||
        IEnumerable<ClashWar> GetAllWars();
 | 
			
		||||
        IEnumerable<ClashWar> GetAllWars(List<long> guilds);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -11,9 +11,11 @@ namespace NadekoBot.Services.Database.Repositories.Impl
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IEnumerable<ClashWar> GetAllWars()
 | 
			
		||||
        public IEnumerable<ClashWar> GetAllWars(List<long> 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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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 = ", ");
 | 
			
		||||
 
 | 
			
		||||
@@ -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<string, string> {
 | 
			
		||||
            //                    { "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<string, string> {
 | 
			
		||||
                                { "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()
 | 
			
		||||
 
 | 
			
		||||
@@ -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<Permissionv2>(x.Permissions)
 | 
			
		||||
                        });
 | 
			
		||||
                    }
 | 
			
		||||
                        Verbose = x.VerbosePermissions,
 | 
			
		||||
                        PermRole = x.PermissionRole,
 | 
			
		||||
                        Permissions = new PermissionsCollection<Permissionv2>(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<ulong, OldPermissionCache>(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();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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<StreamStatus> GetStreamStatus(FollowedStream stream, bool checkCache = true)
 | 
			
		||||
 
 | 
			
		||||
@@ -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<long> guilds)
 | 
			
		||||
        public RemindService(DiscordSocketClient client, BotConfig config, DbService db, 
 | 
			
		||||
            List<long> guilds, IUnitOfWork uow)
 | 
			
		||||
        {
 | 
			
		||||
            _config = config;
 | 
			
		||||
            _client = client;
 | 
			
		||||
@@ -42,11 +44,8 @@ namespace NadekoBot.Services.Utility
 | 
			
		||||
 | 
			
		||||
            cancelSource = new CancellationTokenSource();
 | 
			
		||||
            cancelAllToken = cancelSource.Token;
 | 
			
		||||
            List<Reminder> 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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user