private void AddToQueue(RunningRepeater rep) { lock (_queueLocker) { var current = _repeaterQueue.First; if (current is null) { _repeaterQueue.AddFirst(rep); return; } while (!(current is null) && current.Value.NextTime < rep.NextTime) { current = current.Next; } if (current is null) { _repeaterQueue.AddLast(rep); } else { _repeaterQueue.AddBefore(current, rep); } } }
private async Task HandlePostExecute(RunningRepeater rep) { if (rep.ErrorCount >= 10) { await RemoveRepeaterInternal(rep.Repeater); return; } rep.UpdateNextTime(); AddToQueue(rep); }
public async Task <RunningRepeater?> AddRepeaterAsync( ulong channelId, ulong guildId, TimeSpan interval, string message, bool isNoRedundant, TimeSpan?startTimeOfDay ) { var rep = new Repeater() { ChannelId = channelId, GuildId = guildId, Interval = interval, Message = message, NoRedundant = isNoRedundant, LastMessageId = null, StartTimeOfDay = startTimeOfDay, DateAdded = DateTime.UtcNow }; using var uow = _db.GetDbContext(); if (await uow._context.Repeaters.CountAsyncEF(x => x.GuildId == guildId) < MAX_REPEATERS) { uow._context.Repeaters.Add(rep); } else { return(null); } await uow.SaveChangesAsync(); if (isNoRedundant) { _noRedundant.Add(rep.Id); } var runner = new RunningRepeater(rep); AddToQueue(runner); return(runner); }
private async Task Trigger(RunningRepeater rr) { var repeater = rr.Repeater; void ChannelMissingError() { rr.ErrorCount = Int32.MaxValue; Log.Warning("[Repeater] Channel [{Channelid}] for not found or insufficient permissions. " + "Repeater will be removed. ", repeater.ChannelId); } var channel = _client.GetChannel(repeater.ChannelId) as ITextChannel; if (channel is null) { channel = await _client.Rest.GetChannelAsync(repeater.ChannelId) as ITextChannel; } if (channel is null) { ChannelMissingError(); return; } var guild = _client.GetGuild(channel.GuildId); if (guild is null) { ChannelMissingError(); return; } if (_noRedundant.Contains(repeater.Id)) { try { var lastMsgInChannel = await channel.GetMessagesAsync(2).Flatten().FirstAsync(); if (lastMsgInChannel != null && lastMsgInChannel.Id == repeater.LastMessageId) { return; } } catch (Exception ex) { Log.Warning(ex, "[Repeater] Error while getting last channel message in {GuildId}/{ChannelId} " + "Bot probably doesn't have the permission to read message history", guild.Id, channel.Id); } } if (repeater.LastMessageId is ulong lastMessageId) { try { var oldMsg = await channel.GetMessageAsync(lastMessageId); if (oldMsg != null) { await oldMsg.DeleteAsync().ConfigureAwait(false); } } catch (Exception ex) { Log.Warning(ex, "[Repeater] Error while deleting previous message in {GuildId}/{ChannelId}", guild.Id, channel.Id); } } var rep = new ReplacementBuilder() .WithDefault(guild.CurrentUser, channel, guild, _client) .Build(); try { IMessage newMsg; if (CREmbed.TryParse(repeater.Message, out var crEmbed)) { rep.Replace(crEmbed); newMsg = await channel.EmbedAsync(crEmbed); } else { newMsg = await channel.SendMessageAsync(rep.Replace(repeater.Message)); } _ = newMsg.AddReactionAsync(new Emoji("🔄")); if (_noRedundant.Contains(repeater.Id)) { await SetRepeaterLastMessageInternal(repeater.Id, newMsg.Id); repeater.LastMessageId = newMsg.Id; } rr.ErrorCount = 0; } catch (Exception ex) { Log.Error(ex, "[Repeater] Error sending repeat message ({ErrorCount})", rr.ErrorCount++); } }