Esempio n. 1
0
        public async Task InitializeAsync()
        {
            await _logService.LogAsync(new LogMessage(LogSeverity.Info, "Bot", $"Fergun v{Constants.Version}"));

            Languages = new ReadOnlyDictionary <string, CultureInfo>(GetAvailableCultures().ToDictionary(x => x.TwoLetterISOLanguageName, x => x));
            await _logService.LogAsync(new LogMessage(LogSeverity.Verbose, "Bot", $"{Languages.Count} available language(s) ({string.Join(", ", Languages.Keys)})."));

            await _logService.LogAsync(new LogMessage(LogSeverity.Info, "Config", "Loading the config..."));

            Config = await LoadConfigAsync <FergunConfig>(Path.Combine(AppContext.BaseDirectory, Constants.BotConfigFile));

            if (Config == null)
            {
                Console.Write("Closing in 30 seconds... Press any key to exit now.");
                await ExitWithInputTimeoutAsync(30, 1);
            }
            try
            {
                if (Config != null)
                {
                    TokenUtils.ValidateToken(TokenType.Bot, IsDebugMode ? Config.DevToken : Config.Token);
                }
            }
            catch (ArgumentException e)
            {
                await _logService.LogAsync(new LogMessage(LogSeverity.Critical, "Config", $"Failed to validate {(IsDebugMode ? "dev " : "")}bot token", e));

                await _logService.LogAsync(new LogMessage(LogSeverity.Info, "Config", $"Make sure the value in key {(IsDebugMode ? "Dev" : "")}Token, in the config file ({Constants.BotConfigFile}) is valid."));

                Console.Write("Closing in 30 seconds... Press any key to exit now.");
                await ExitWithInputTimeoutAsync(30, 1);
            }

            // LogSeverity.Debug is too verbose
            if (Config.LavaConfig.LogSeverity == LogSeverity.Debug)
            {
                Config.LavaConfig.LogSeverity = LogSeverity.Verbose;
            }

            await _logService.LogAsync(new LogMessage(LogSeverity.Verbose, "Database", "Connecting to the database..."));

            bool      isDbConnected = false;
            Exception dbException   = null;

            try
            {
                Database      = new FergunDatabase(Constants.FergunDatabase, Config.DatabaseConfig.ConnectionString);
                isDbConnected = Database.IsConnected;
            }
            catch (TimeoutException e)
            {
                dbException = e;
            }

            if (isDbConnected)
            {
                await _logService.LogAsync(new LogMessage(LogSeverity.Verbose, "Database", "Connected to the database successfully."));
            }
            else
            {
                await _logService.LogAsync(new LogMessage(LogSeverity.Critical, "Database", "Could not connect to the database.", dbException));

                await _logService.LogAsync(new LogMessage(LogSeverity.Info, "Database", "Ensure the MongoDB server you're trying to log in is running"));

                await _logService.LogAsync(new LogMessage(LogSeverity.Info, "Database", $"and make sure the server credentials in the config file ({Constants.BotConfigFile}) are correct."));

                Console.Write("Closing in 30 seconds... Press any key to exit now.");
                await ExitWithInputTimeoutAsync(30, 1);
            }

            GuildUtils.Initialize();

            await _logService.LogAsync(new LogMessage(LogSeverity.Verbose, "Bot", $"Using presence intent: {Config.PresenceIntent}"));

            if (Config.PresenceIntent)
            {
                Constants.ClientConfig.GatewayIntents |= GatewayIntents.GuildPresences;
            }
            await _logService.LogAsync(new LogMessage(LogSeverity.Verbose, "Bot", $"Using server members intent: {Config.ServerMembersIntent}"));

            if (Config.ServerMembersIntent)
            {
                Constants.ClientConfig.GatewayIntents |= GatewayIntents.GuildMembers;
            }
            await _logService.LogAsync(new LogMessage(LogSeverity.Verbose, "Bot", $"Using reliability service: {Config.UseReliabilityService}"));

            if (Config.UseReliabilityService)
            {
                await _logService.LogAsync(new LogMessage(LogSeverity.Verbose, "Bot", "The bot will be shut down in case of deadlock. Remember to use a daemon!"));
            }
            Constants.ClientConfig.AlwaysDownloadUsers = Config.AlwaysDownloadUsers;
            await _logService.LogAsync(new LogMessage(LogSeverity.Verbose, "Bot", $"Always download users: {Constants.ClientConfig.AlwaysDownloadUsers}"));

            Constants.ClientConfig.MessageCacheSize = Config.MessageCacheSize;
            await _logService.LogAsync(new LogMessage(LogSeverity.Verbose, "Bot", $"Message cache size: {Constants.ClientConfig.MessageCacheSize}"));

            _client                      = new DiscordSocketClient(Constants.ClientConfig);
            _client.Ready               += ClientReady;
            _client.JoinedGuild         += JoinedGuild;
            _client.LeftGuild           += LeftGuild;
            _client.MessageUpdated      += MessageUpdated;
            _client.MessageDeleted      += MessageDeleted;
            _client.MessagesBulkDeleted += MessagesBulkDeleted;
            _client.UserJoined          += UserJoined;
            _client.UserLeft            += UserLeft;
            _client.UserBanned          += UserBanned;
            _client.UserUnbanned        += UserUnbanned;

            _logService.Dispose();
            _logService = new LogService(_client, _cmdService);
            if (Config.UseReliabilityService)
            {
                _reliabilityService = new ReliabilityService(_client, x => _ = _logService.LogAsync(x));
            }

            _commandCacheService = new CommandCacheService(_client, Constants.MessageCacheCapacity,
                                                           message => _ = _cmdHandlingService.HandleCommandAsync(message),
                                                           log => _     = _logService.LogAsync(log),
                                                           Constants.CommandCacheClearInterval, Constants.MaxCommandCacheLongevity);

            _services = SetupServices();

            _cmdHandlingService = new CommandHandlingService(_client, _cmdService, _logService, _services);
            await _cmdHandlingService.InitializeAsync();

            if (Config.LavaConfig.Hostname == "127.0.0.1" || Config.LavaConfig.Hostname == "0.0.0.0" || Config.LavaConfig.Hostname == "localhost")
            {
                await _logService.LogAsync(new LogMessage(LogSeverity.Info, "Lavalink", "Using local lavalink server. Updating and starting Lavalink..."));
                await UpdateLavalinkAsync();
                await StartLavalinkAsync();
            }
            else
            {
                await _logService.LogAsync(new LogMessage(LogSeverity.Info, "Lavalink", "Using remote lavalink server."));
            }

            await _client.LoginAsync(TokenType.Bot, IsDebugMode?Config.DevToken : Config.Token, false);

            await _client.StartAsync();

            if (!IsDebugMode)
            {
                await _client.SetActivityAsync(new Game($"{DatabaseConfig.GlobalPrefix}help"));
            }

            // Block this task until the program is closed.
            await Task.Delay(Timeout.Infinite);
        }