public ShardsCoordinator()
        {
            //load main stuff
            LogSetup.LoggerSetup(-1);
            _log   = LogManager.GetCurrentClassLogger();
            _creds = new CoreCredentials();

            _log.Info("Starting CoreBot v" + StatsService.BotVersion);

            //_key = _creds.RedisKey();
//_redis = ConnectionMultiplexer.Connect("127.0.0.1");

            //new RedisImagesCache(_redis, _creds).Reload(); //reload images into redis

            //setup initial shard statuses
            _defaultShardState = new ShardComMessage()
            {
                Guilds = 0,
                Time   = DateTime.UtcNow
            };
            var db = _redis.GetDatabase();

            //clear previous statuses
            db.KeyDelete(_key + "_shardstats");

            _shardProcesses = new Process[_creds.TotalShards];
            for (int i = 0; i < _creds.TotalShards; i++)
            {
                //add it to the list of shards which should be started
#if DEBUG
                if (i > 0)
                {
                    _shardStartQueue.Enqueue(i);
                }
                else
                {
                    _shardProcesses[i] = Process.GetCurrentProcess();
                }
#else
                _shardStartQueue.Enqueue(i);
#endif
                //set the shard's initial state in redis cache
                var msg = _defaultShardState.Clone();
                msg.ShardId = i;
                //this is to avoid the shard coordinator thinking that
                //the shard is unresponsive while startup up
                var delay = 45;
#if GLOBAL_NADEKO
                delay = 180;
#endif
                msg.Time = DateTime.UtcNow + TimeSpan.FromSeconds(delay * (i + 1));
                db.ListRightPush(_key + "_shardstats",
                                 JsonConvert.SerializeObject(msg),
                                 flags: CommandFlags.FireAndForget);
            }

            _curProcessId = Process.GetCurrentProcess().Id;

            //subscribe to shardcoord events
            var sub = _redis.GetSubscriber();

            //send is called when shard status is updated. Every 7.5 seconds atm
            sub.Subscribe(_key + "_shardcoord_send",
                          OnDataReceived,
                          CommandFlags.FireAndForget);

            //restart is called when shzard should be stopped and then started again
            sub.Subscribe(_key + "_shardcoord_restart",
                          OnRestart,
                          CommandFlags.FireAndForget);

            //called to kill the shard
            sub.Subscribe(_key + "_shardcoord_stop",
                          OnStop,
                          CommandFlags.FireAndForget);

            //called kill the bot
            sub.Subscribe(_key + "_die",
                          (ch, x) => Environment.Exit(0),
                          CommandFlags.FireAndForget);
        }
Exemple #2
0
        public Core(int ParentId, int shardId)
        {
            //check if shardId assigned is < 0
            if (shardId < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(shardId));
            }

            //set up credentials
            LogSetup.LoggerSetup(shardId);
            _config     = new BotConfig();
            _log        = LogManager.GetCurrentClassLogger();
            Credentials = new CoreCredentials();
            _db         = new DbService(Credentials);
            var coreConfig = new DiscordConfiguration
            {
                AutoReconnect           = true,
                LargeThreshold          = 250,
                LogLevel                = DSharpPlus.LogLevel.Debug,
                Token                   = Credentials.Token,
                TokenType               = Credentials.UseUserToken ? TokenType.Bot : TokenType.Bot,
                UseInternalLogHandler   = false,
                ShardId                 = shardId,
                ShardCount              = Credentials.TotalShards,
                GatewayCompressionLevel = GatewayCompressionLevel.Stream,
                MessageCacheSize        = 50,
                AutomaticGuildSync      = true,
                DateTimeFormat          = "dd-MM-yyyy HH:mm:ss zzz"
            };

            _discord = new DiscordClient(coreConfig);

            //attach Discord events
            _discord.DebugLogger.LogMessageReceived += this.DebugLogger_LogMessageReceived;
            _discord.Ready             += this.Discord_Ready;
            _discord.GuildAvailable    += this.Discord_GuildAvailable;
            _discord.MessageCreated    += this.Discord_MessageCreated;
            _discord.ClientErrored     += this.Discord_ClientErrored;
            _discord.SocketErrored     += this.Discord_SocketError;
            _discord.GuildCreated      += this.Discord_GuildAvailable;
            _discord.VoiceStateUpdated += this.Discord_VoiceStateUpdated;

            var voiceConfig = new VoiceNextConfiguration
            {
                VoiceApplication = DSharpPlus.VoiceNext.Codec.VoiceApplication.Music,
                EnableIncoming   = false
            };

            _discord.UseVoiceNext(voiceConfig);
            var googleService = new GoogleApiService(Credentials);
            //enable voice service

            IGoogleApiService googleApiService = new GoogleApiService(Credentials);
            CoreMusicService  cms = new CoreMusicService(_discord, _db, Credentials, this, googleApiService);
            var depoBuild         = new ServiceCollection();

            //taken from NadeoBot's Service loading
            depoBuild.AddSingleton <DiscordClient>(_discord);
            depoBuild.AddSingleton <CoreCredentials>(Credentials);
            depoBuild.AddSingleton <IGoogleApiService>(googleApiService);
            depoBuild.AddSingleton(_db);
            depoBuild.AddSingleton(cms);

            //add dependency here

            using (var uow = _db.UnitOfWork)
            {
                _config = uow.BotConfig.GetOrCreate();
            }

            //build command configuration
            //see Dsharpplus configuration
            _log.Info($"{_config.DefaultPrefix}");

            var commandConfig = new CommandsNextConfiguration
            {
                StringPrefix         = _config.DefaultPrefix,
                EnableDms            = true,
                EnableMentionPrefix  = true,
                CaseSensitive        = true,
                Services             = depoBuild.BuildServiceProvider(),
                Selfbot              = Credentials.UseUserToken,
                IgnoreExtraArguments = false
            };

            //attach command events
            this.CommandsNextService = _discord.UseCommandsNext(commandConfig);

            this.CommandsNextService.CommandErrored += this.CommandsNextService_CommandErrored;

            this.CommandsNextService.CommandExecuted += this.CommandsNextService_CommandExecuted;

            this.CommandsNextService.RegisterCommands(typeof(CoreCommands).GetTypeInfo().Assembly);

            this.CommandsNextService.SetHelpFormatter <CoreBotHelpFormatter>();

            //interactive service

            var interConfig = new InteractivityConfiguration()
            {
                PaginationBehaviour = TimeoutBehaviour.DeleteMessage,
                //default paginationtimeout (30 seconds)
                PaginationTimeout = TimeSpan.FromSeconds(30),
                //timeout for current action
                Timeout = TimeSpan.FromMinutes(2)
            };

            //attach interactive component
            this.InteractivityService = _discord.UseInteractivity(interConfig);
            //this.CommandsNextService.RegisterCommands<CoreInteractivityModuleCommands>();
            //register commands from coreinteractivitymodulecommands
            //this.CommandsNextService.RegisterCommands(typeof(CoreInteractivityModuleCommands).GetTypeInfo().Assembly);
        }