protected sealed override async Task UpdateInternal(DiscordLink plugin, DLEventType trigger, object data) { // Avoid hitting the rate limitation by not allowig events that can be fired often to pass straight through. if ((trigger & HighFrequencyTriggerFlags) == trigger) { if (_HighFrequencyEventTimer == null) { _HighFrequencyEventTimer = new Timer(this.TriggerTimedUpdate, null, HighFrequencyEventDelayMS, Timeout.Infinite); } return; } if (_dirty || _targetDisplays.Count <= 0) { await FindMessages(plugin); if (_dirty || _targetDisplays.Count <= 0) { return; // If something went wrong, we should just retry later } } bool createdOrDestroyedMessage = false; List <string> matchedTags = new List <string>(); List <DiscordMessage> unmatchedMessages = new List <DiscordMessage>(); foreach (TargetDisplayData channelDisplayData in _targetDisplays) { DiscordTarget target = channelDisplayData.Target; ChannelLink channelLink = target as ChannelLink; UserLink userLink = target as UserLink; if (channelLink == null && userLink == null) { continue; } DiscordChannel targetChannel = null; if (channelLink != null) { // Get the channel and verify permissions DiscordGuild discordGuild = plugin.GuildByNameOrId(channelLink.DiscordGuild); if (discordGuild == null) { continue; } targetChannel = discordGuild.ChannelByNameOrId(channelLink.DiscordChannel); if (targetChannel == null) { continue; } if (!DiscordUtil.ChannelHasPermission(targetChannel, Permissions.ReadMessageHistory)) { continue; } } else if (userLink != null) { targetChannel = await userLink.Member.CreateDmChannelAsync(); } GetDisplayContent(target, out List <Tuple <string, DiscordLinkEmbed> > tagsAndContent); foreach (ulong messageID in channelDisplayData.MessageIDs) { DiscordMessage message = await DiscordUtil.GetMessageAsync(targetChannel, messageID); if (message == null) { _dirty = true; return; // We cannot know which messages are wrong and duplicates may be created if we continue. } if (!message.Content.StartsWith(BaseTag)) { continue; // The message belongs to a different display } bool found = false; foreach (var tagAndContent in tagsAndContent) { if (message.Content.Contains(tagAndContent.Item1)) { _ = DiscordUtil.ModifyAsync(message, tagAndContent.Item1, tagAndContent.Item2); matchedTags.Add(tagAndContent.Item1); found = true; ++_opsCount; break; } } if (!found) { unmatchedMessages.Add(message); } } // Delete the messages that are no longer relevant foreach (DiscordMessage message in unmatchedMessages) { DiscordUtil.DeleteAsync(message).Wait(); createdOrDestroyedMessage = true; ++_opsCount; } unmatchedMessages.Clear(); // Send the messages that didn't already exist foreach (var tagAndContent in tagsAndContent) { if (!matchedTags.Contains(tagAndContent.Item1)) { DiscordUtil.SendAsync(targetChannel, tagAndContent.Item1, tagAndContent.Item2).Wait(); createdOrDestroyedMessage = true; ++_opsCount; } } matchedTags.Clear(); } if (createdOrDestroyedMessage) { await FindMessages(plugin); } LastUpdateTime = DateTime.Now; }