Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
        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>();
        }
Ejemplo n.º 3
0
        /// <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);
        }
Ejemplo n.º 4
0
        /// <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);
        }
Ejemplo n.º 5
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);
        }