Exemplo n.º 1
0
 internal void RemoveEventHandler(IDiscordInterface e)
 {
     if (e is IDiscordAPIEvents a)
     {
         api.Remove(a);
     }
     if (e is IDiscordChannelEvents c)
     {
         channel.Remove(c);
     }
     if (e is IDiscordServerEvents s)
     {
         server.Remove(s);
     }
     if (e is IDiscordInviteEvents i)
     {
         invite.Remove(i);
     }
     if (e is IDiscordMessageEvents m)
     {
         message.Remove(m);
     }
     if (e is IDiscordStatusEvents st)
     {
         status.Remove(st);
     }
     if (e is IDiscordVoiceEvents v)
     {
         voice.Remove(v);
     }
     if (e is IDiscordWebhookEvents w)
     {
         webhook.Remove(w);
     }
 }
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            foreach (var token in await _apiTokenData.GetAllKeys())
            {
                _logger.Info($"Setting up discord client for Server {token.ServerName}");

                _discordSocketClient = new DiscordSocketClient(new DiscordSocketConfig
                {
                    MessageCacheSize    = 0,
                    ExclusiveBulkDelete = true,
                    AlwaysDownloadUsers = true,

                    GatewayIntents =
                        GatewayIntents.Guilds |
                        GatewayIntents.GuildMembers |
                        GatewayIntents.GuildMessageReactions |
                        GatewayIntents.GuildMessages |
                        GatewayIntents.GuildVoiceStates
                });

                _discordSocketClient.Log += message =>
                {
                    if (message.Exception != null)
                    {
                        _logger.Warn($"DiscordClient: {message.Message} - {message.Exception.Message}");
                    }
                    else
                    {
                        _logger.Info($"DiscordClient: {message.Message}");
                    }
                    return(Task.CompletedTask);
                };
                _discordSocketClient.Ready += () =>
                {
                    _logger.Info($"Discord client for {token.ServerName} is ready");
                    return(Task.CompletedTask);
                };

                _discordSocketClient.Disconnected += exception =>
                {
                    _logger.Error($"Discord Client disconnected: {exception.Message}");
                    return(Task.CompletedTask);
                };
                //TODO handle disconnected event and try to reconnect


                await _discordSocketClient.LoginAsync(TokenType.Bot, token.ApiKey);

                await _discordSocketClient.StartAsync();

                _discordInterface         = new DiscordInterface(_discordSocketClient);
                _commandProcessingService = new CommandProcessingService(_discordInterface, _schedulerFactory, _activityMonitor);
                await _commandProcessingService.StartAsync(CancellationToken.None);

                //TODO when monitoring users in channels create that service here

                break; //TODO only use 1 server at a time for now
            }
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="discordInterface">Interface to send and receive discord messages</param>
        /// <param name="schedulerFactory">Generator for Reactive Schedulers</param>
        /// <param name="activityMonitor">Allows the commands to log an event occuring</param>
        public CommandProcessingService(IDiscordInterface discordInterface, ISchedulerFactory schedulerFactory, IActivityMonitor activityMonitor)
        {
            _discordInterface = discordInterface;
            _schedulerFactory = schedulerFactory;
            _activityMonitor  = activityMonitor;
            _scheduler        = schedulerFactory.GenerateScheduler();

            _commandDict = new Dictionary <string, BaseDiscordCommand>();
        }
Exemplo n.º 4
0
        /// <summary>
        /// Runs a game of trivia with the provided trivia source.
        /// Expected args:
        ///    1. Trivia source name that matches a provider in _questionProviders
        ///    2. (Optional) The number of rounds to play, default is 10
        /// </summary>
        /// <param name="discordInterface"></param>
        /// <param name="args"></param>
        /// <param name="rawMessage"></param>
        protected override async Task Execute(IDiscordInterface discordInterface, string[] args, SocketMessage rawMessage)
        {
            if (!TryExtractArgs(args, out var questionProvider, out var gameLength))
            {
                // Command was used wrong, print usage info and exit
                await discordInterface.SendMessageAsync(rawMessage.Channel, FullHelpText);

                return;
            }

            Subject <DiscordMessage> subject = new Subject <DiscordMessage>();

            discordInterface.MessageReceived.ObserveOn(_scheduler)
            .Where(message => message.Channel.Id == rawMessage.Channel.Id)
            .Subscribe(message =>
            {
                subject.OnNext(new DiscordMessage(message.Channel, message.Author.Username, message.Content));
            });

            var gameResult = new GameResults();

            // Start asking questions
            var questions = await questionProvider.GetQuestions(gameLength); //TODO this might need to be async

            for (int i = 0; i < questions.Count; i++)
            {
                await discordInterface.SendMessageAsync(rawMessage.Channel, $"Question {i + 1}:\n{questions[i].Question}");

                var result = await questions[i].ExecuteQuestion(subject.AsObservable(), questionProvider.QuestionDuration);

                if (result.Scores.Count == 0)
                {
                    // No one was correct
                    await discordInterface.SendMessageAsync(rawMessage.Channel, $"No one was correct! Answer:\n{questions[i].Answer}");
                }
                else
                {
                    gameResult.CombineWith(result);
                    //Someone was correct
                    await discordInterface.SendMessageAsync(rawMessage.Channel, $"{String.Join(", ", result.Scores.Where(score => score.Value > 0).Select(score => score.Key))} was correct!\n" +
                                                            $"{gameResult.PrintScores()}");
                }
            }

            // Game is over, inform everyone of the winner
            await discordInterface.SendMessageAsync(rawMessage.Channel,
                                                    $"Game over, winner was {gameResult.GetWinner()}\n" +
                                                    $"{gameResult.PrintScores()}");
        }
Exemplo n.º 5
0
        protected override async Task Execute(IDiscordInterface discordInterface, string[] args, SocketMessage rawMessage)
        {
            var response = new StringBuilder();

            response.AppendLine("Test command:");
            response.AppendLine($"From User: {rawMessage.Author.Username}");
            response.AppendLine($"Channel: {rawMessage.Channel.Name}");

            for (int i = 0; i < args.Length; i++)
            {
                response.AppendLine($"Arg{i}: {args[i]}");
            }

            await discordInterface.SendMessageAsync(rawMessage.Channel, response.ToString());
        }
Exemplo n.º 6
0
        public async Task ExecuteCommand(IDiscordInterface discordInterface, string[] args, SocketMessage rawMessage)
        {
            try
            {
                bool   allowed = true;
                string reason  = "";

                // Check if we are allowed to do this command in this channel
                if (AllowedChannels.Length != 0 && !AllowedChannels.Contains(rawMessage.Channel.Name))
                {
                    allowed = false;
                    reason += $"In channel {rawMessage.Channel.Name} but allowed channels are {String.Join(',', AllowedChannels)}\n";
                }

                // Check if this user has a role that is in the whitelist
                if (AllowedRoles.Length != 0 && !rawMessage.Author.GetRolesAsString().ToList().Intersect(AllowedRoles).Any())
                {
                    allowed = false;
                    reason += $"Allowed roles are {String.Join(',', AllowedRoles)} but user {rawMessage.Author.Username} " +
                              $"only has roles {String.Join(',', rawMessage.Author.GetRolesAsString())}\n";
                }

                // Check if this user has a role that is in the blacklist
                if (DisallowedRoles.Length != 0 && rawMessage.Author.GetRolesAsString().Intersect(DisallowedRoles).Any())
                {
                    allowed = false;
                    reason += $"User {rawMessage.Author.Username} has blacklisted role/s " +
                              $"{String.Join(',', rawMessage.Author.GetRolesAsString().Intersect(DisallowedRoles))}\n";
                }

                if (allowed)
                {
                    await Execute(discordInterface, args, rawMessage);
                }
                else
                {
                    _logger.Warn($"User {rawMessage.Author.Username} tried to execute command {CommandString} but it failed because:\n{reason.Trim()}");
                }
            }
            catch (Exception e)
            {
                _logger.Error(e, $"Unexpected error when attmpeting to exectue a command: {e.Message}");
            }
        }
Exemplo n.º 7
0
 public static void UnregisterEventsHandler(IDiscordInterface e)
 => interfaces.RemoveEventHandler(e);
Exemplo n.º 8
0
 public static void RegisterEventsHandler(IDiscordInterface e)
 => interfaces.AddEventHandler(e);
Exemplo n.º 9
0
 /// <summary>
 /// Execute the discord command
 /// </summary>
 /// <param name="discordInterface"></param>
 /// <param name="args"></param>
 /// <param name="rawMessage"></param>
 /// <returns></returns>
 protected abstract Task Execute(IDiscordInterface discordInterface, string[] args, SocketMessage rawMessage);
Exemplo n.º 10
0
 protected override Task Execute(IDiscordInterface discordInterface, string[] args, SocketMessage rawMessage)
 {
     ExecuteCount++;
     return(Task.CompletedTask);
 }
Exemplo n.º 11
0
        protected override async Task Execute(IDiscordInterface discordInterface, string[] args, SocketMessage rawMessage)
        {
            // Get the current username. This can be either the current nickname, or the discord username, or the discord user id (if it is an integer)
            // Can also be surround in quotes f**k my life

            args = Utils.ArgumentParseUtils.ParseArgsWithQuotes(args);

            if (args.Length < 3)
            {
                await SendMessage("Read how to use this command you peppeg");

                _logger.Debug($"Received invalid Rename user: {String.Join(',', args)}");
                return;
            }

            var currentName = args[1];
            var newName     = args[2];

            SocketGuildUser user = null;

            // Try with user ID
            if (long.TryParse(currentName, out long userId))
            {
                try
                {
                    user = discordInterface.RawClient.GetUser((ulong)userId) as SocketGuildUser;
                }
                catch (Exception e)
                {
                    _logger.Error(e, $"Cannot find user with id {userId}: {e.Message}");
                }
            }

            // Try with nickname or username
            if (user == null)
            {
                foreach (var guild in discordInterface.RawClient.Guilds)
                {
                    user = guild.Users.FirstOrDefault(p => p.Username == currentName || p.Nickname == currentName);
                    if (user != null)
                    {
                        break;
                    }
                }
            }

            if (user != null)
            {
                try
                {
                    await user?.ModifyAsync(x => x.Nickname = newName);
                    await SendMessage($"Changed {currentName} to {newName}");

                    await ActivityMonitor.LogActivity(new Activity()
                    {
                        CommandName = CommandString,
                        Author      = rawMessage.Author.Username,
                        Channel     = rawMessage.Channel.Name,
                        Succeeded   = true,
                        Result      = $"Changed user {user.Username} nickname from {currentName} to {newName}"
                    });
                }
                catch (Exception e)
                {
                    await SendMessage($"ERROR: {e.Message}");

                    await ActivityMonitor.LogActivity(new Activity()
                    {
                        CommandName = CommandString,
                        Author      = rawMessage.Author.Username,
                        Channel     = rawMessage.Channel.Name,
                        Succeeded   = false,
                        Result      = $"Failed to change username for user {user.Username}: {e.Message}"
                    });
                }
            }
            else
            {
                await SendMessage($"Cannot find user with name {currentName}");

                await ActivityMonitor.LogActivity(new Activity()
                {
                    CommandName = CommandString,
                    Author      = rawMessage.Author.Username,
                    Channel     = rawMessage.Channel.Name,
                    Succeeded   = false,
                    Result      = $"Cannot find user with name {currentName}"
                });
            }

            async Task SendMessage(string message) => await discordInterface.SendMessageAsync(rawMessage.Channel, message);
        }