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); }