public async Task <IUserMessage> SendAsync(IMessageChannel channel, string command, CancellationToken cancellationToken = default)
        {
            var client = await _discord.GetClientAsync();

            var watch = Stopwatch.StartNew();

            await MudaeSemaphore.semaphoreSlim.WaitAsync(cancellationToken);

            try
            {
                await client.SendMessageAsync(channel.Id, command);

                try
                {
                    var response = await ReceiveAsync(client, channel, cancellationToken);

                    _logger.LogDebug($"Sent command '{command}' in channel '{channel.Name}' ({channel.Id}) and received Mudae response '{response.Content}' ({response.Embeds.Count} embeds) in {watch.Elapsed.TotalMilliseconds}ms.");

                    return(response);
                }
                catch (OperationCanceledException)
                {
                    _logger.LogWarning($"Sent command '{command}' in channel '{channel.Name}' ({channel.Id}) but did not receive expected Mudae response.");
                    throw;
                }
            }
            finally
            {
                MudaeSemaphore.semaphoreSlim.Release();
            }
        }
Example #2
0
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            var client = await _discord.GetClientAsync();

            Task handleReactionAdded(ReactionAddedEventArgs args)
            {
                // this needs to run in background because it waiting for Mudae output blocks message receive
                var _ = Task.Run(() => HandleReactionAdded(args), stoppingToken);

                return(Task.CompletedTask);
            }

            client.MessageReceived += HandleMessageReceived;
            client.ReactionAdded   += handleReactionAdded;

            try
            {
                await Task.Delay(-1, stoppingToken);
            }
            finally
            {
                client.MessageReceived -= HandleMessageReceived;
                client.ReactionAdded   -= handleReactionAdded;
            }
        }
Example #3
0
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            // this is a bit hacky; we will wait for discord to get fully initialized and then read auto-update setting
            await _discord.GetClientAsync();

            while (!stoppingToken.IsCancellationRequested)
            {
                if (_options.CurrentValue.AutoUpdate)
                {
                    await CheckAsync(stoppingToken);
                }

                await Task.Delay(TimeSpan.FromHours(6), stoppingToken);
            }
        }
Example #4
0
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            var client = await _discord.GetClientAsync();

            var rollers = new Dictionary <ulong, Roller>();

            void handleChange(BotChannelList o)
            {
                var items = o.Items.GroupBy(x => x.Id).ToDictionary(x => x.Key, x => x.First());

                lock (rollers)
                {
                    foreach (var(id, item) in items)
                    {
                        if (!rollers.TryGetValue(id, out var roller) || !roller.CurrentItem.Equals(item))
                        {
                            roller?.Cancellation.Cancel();
                            roller?.Cancellation.Dispose();

                            var newRoller         = new Roller(item, stoppingToken);
                            var cancellationToken = newRoller.Cancellation.Token;

                            rollers[id] = newRoller;

                            Task.Run(async() =>
                            {
                                try
                                {
                                    await RunAsync(client, item, cancellationToken);
                                }
                                catch (OperationCanceledException) { }
                            }, cancellationToken);
                        }
                    }

                    foreach (var id in rollers.Keys.ToArray())
                    {
                        if (!items.ContainsKey(id) && rollers.Remove(id, out var roller))
                        {
                            roller.Cancellation.Cancel();
                            roller.Cancellation.Dispose();
                        }
                    }
                }
            }

            var monitor = _channelList.OnChange(handleChange);

            try
            {
                handleChange(_channelList.CurrentValue);

                await Task.Delay(-1, stoppingToken);
            }
            finally
            {
                monitor.Dispose();

                lock (rollers)
                {
                    foreach (var roller in rollers.Values)
                    {
                        roller.Cancellation.Dispose();
                    }

                    rollers.Clear();
                }
            }
        }