/// <summary> /// Discord bot. /// </summary> /// <param name="modules">List of modules for the bot.</param> /// <param name="settings">Settings used to connect to Discord.</param> /// <param name="logger">Application logger.</param> public Bot(IList <IModule> modules, IDiscordSettings settings, ILogger <Bot> logger, DiscordSocketClient client) { Modules = modules; Logger = logger; Client = client; Client.Log += Log; // Log when the bot is disconnected. Client.Disconnected += exception => { Logger.LogCritical("Bot has been disconnected!"); return(Task.CompletedTask); }; // Set bot game. Client.Ready += () => { Task.Run(async() => { for (;;) { var memberCount = Client.Guilds.Sum(guild => guild.MemberCount); await Client.SetGameAsync($"volvox.tech | {Client.Guilds.Count} servers > {memberCount} members"); await Task.Delay(TimeSpan.FromMinutes(15)); } }); return(Task.CompletedTask); }; // Announce to Volvox when the bot joins a guild. Client.JoinedGuild += async guild => { await Client.GetGuild(VolvoxGuildId).GetTextChannel(VolvoxGuildLogsChannelId) .SendMessageAsync($"Joined Guild: {guild.Name} [{guild.MemberCount} Members]"); }; // Announce to Volvox when the bot leaves a guild. Client.LeftGuild += async guild => { await Client.GetGuild(VolvoxGuildId).GetTextChannel(VolvoxGuildLogsChannelId) .SendMessageAsync($"Left Guild: {guild.Name} [{guild.MemberCount} Members]"); }; // Add reliability service. _ = new ReliabilityService(Client, logger); Connector = new BotConnector(settings, Client); }
async Task InitializeServices() { var services = ConfigureServices(); _config = await services.GetRequiredService <Configuration>().BuildConfig().ConfigureAwait(false); _client = services.GetRequiredService <DiscordSocketClient>(); _cmdHandler = services.GetRequiredService <CommandHandlerService>(); await _cmdHandler.InitializeAsync().ConfigureAwait(false); _logger = services.GetRequiredService <LoggingService>(); _reliabilityService = services.GetRequiredService <ReliabilityService>(); }
/// <summary> /// Discord bot. /// </summary> /// <param name="modules">List of modules for the bot.</param> /// <param name="settings">Settings used to connect to Discord.</param> /// <param name="logger">Application logger.</param> public Bot(IList <IModule> modules, IDiscordSettings settings, ILogger <Bot> logger) { Modules = modules; Logger = logger; // TODO: Convert logging to module Client = new DiscordSocketClient(new DiscordSocketConfig() { LogLevel = LogSeverity.Verbose }); Client.Log += Log; // Log when the bot is disconnected. Client.Disconnected += exception => { Logger.LogCritical("Bot has been disconnected!"); return(Task.CompletedTask); }; // Set bot game. Client.Ready += () => { Task.Run(async() => { for (;;) { await Client.SetGameAsync($"volvox.tech | with {Client.Guilds.Count} servers"); await Task.Delay(TimeSpan.FromMinutes(15)); } }); return(Task.CompletedTask); }; // Add reliability service. _ = new ReliabilityService(Client, logger); Connector = new BotConnector(settings, Client); }
/// <summary> /// Discord bot. /// </summary> /// <param name="modules">List of modules for the bot.</param> /// <param name="settings">Settings used to connect to Discord.</param> /// <param name="logger">Application logger.</param> public Bot(IList <IModule> modules, IDiscordSettings settings, ILogger <Bot> logger, DiscordSocketClient client) { Modules = modules; Logger = logger; Client = client; Client.Log += Log; // Log when the bot is disconnected. Client.Disconnected += exception => { Logger.LogCritical("Bot has been disconnected!"); return(Task.CompletedTask); }; // Set bot game. Client.Ready += () => { Task.Run(async() => { for (;;) { var memberCount = Client.Guilds.Sum(guild => guild.MemberCount); var version = System.Reflection.Assembly.GetEntryAssembly().GetName().Version; await Client.SetGameAsync( $"volvox.tech | {Client.Guilds.Count} servers | {memberCount} members | v{version.Major}.{version.Minor}.{version.Build}"); await Task.Delay(TimeSpan.FromMinutes(15)); } }); return(Task.CompletedTask); }; // Announce to Volvox when the bot joins a guild. Client.JoinedGuild += async guild => { var channel = Client.GetGuild(VolvoxGuildId)?.GetTextChannel(VolvoxGuildLogsChannelId); if (channel != null) { var builder = new EmbedBuilder(); builder.Title = "New Guild"; builder.Color = EmbedColors.GuildJoinColor; await channel.SendMessageAsync("", false, CreateEmbed(builder, guild)); } }; // Announce to Volvox when the bot leaves a guild. Client.LeftGuild += async guild => { var channel = Client.GetGuild(VolvoxGuildId)?.GetTextChannel(VolvoxGuildLogsChannelId); if (channel != null) { var builder = new EmbedBuilder(); builder.Title = "Left Guild"; builder.Color = EmbedColors.ErrorColor; await channel.SendMessageAsync("", false, CreateEmbed(builder, guild)); } }; // Add reliability service. _ = new ReliabilityService(Client, logger); Connector = new BotConnector(settings, Client); }
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); }