private void UpdateRaid(RaidTarget target, DbSet <RaidParticipation> coll, RaidParticipation raid)
        {
            _log.Info($"Updating raid {raid.PublicID} / {raid.Raid.Raid} / {raid.Raid.Gym} in channel {target.Description}");

            lock (UpdatePublishedRaidsInChannels.SharedUpdateLock)
            {
                raid = coll.Find(x => x.UniqueID == raid.UniqueID).FirstOrDefault();
                if (raid.Raid.TelegramMessageID != null && raid.Raid.TelegramMessageID != 0 && raid.Raid.TelegramMessageID != -1)
                {
                    raid.LastRefresh = DateTime.UtcNow;
                    coll.Update(raid);
                }
                else
                {
                    return;
                }
            }

            try
            {
                RaidEventHandler.UpdateRaidMessage(target.ChannelID, raid.Raid.TelegramMessageID, null, raid.PublicID, "channel");
            }
            catch (Exception ex)
            {
                _log.Error(ex, "Failed to update raid message, marking as modified.");
                lock (UpdatePublishedRaidsInChannels.SharedUpdateLock)
                {
                    // error publishing, assume it wasn't updated and try again
                    raid = coll.Find(x => x.UniqueID == raid.UniqueID).FirstOrDefault();
                    raid.LastModificationTime = DateTime.UtcNow;
                    coll.Update(raid);
                }
            }
        }
示例#2
0
        private void UpdateRaid(RaidTarget target, DbSet <RaidParticipation> coll, RaidParticipation raid)
        {
            _log.Info($"Updating raid {raid.PublicID} / {raid.Raid.Raid} / {raid.Raid.Gym} in channel {target.Description}");

            lock (SharedUpdateLock)
            {
                raid = coll.Find(x => x.UniqueID == raid.UniqueID).FirstOrDefault();
                var pe = raid.Raid.Publications.Where(x => x.ChannelID == target.ChannelID).FirstOrDefault();
                if (null == pe)
                {
                    return;
                }
                raid.Raid.Publications.RemoveAll(x => x != pe && x.ChannelID == pe.ChannelID);
                if (pe.TelegramMessageID != -1)
                {
                    pe.LastModificationTimeUTC = DateTime.UtcNow;
                    coll.Update(raid);
                }
                else
                {
                    return;
                }
            }

            string url         = $"{SettingsManager.BotAddress}raids/{raid.PublicID}?r={rnd.Next()}";
            string messageText = $"[{TimeService.AsShortTime(raid.Raid.RaidUnlockTime)}-{TimeService.AsShortTime(raid.Raid.RaidEndTime)}] {MessageUtils.HtmlEscape(raid.Raid.Raid)} @ {MessageUtils.HtmlEscape(raid.Raid.Gym)} ({raid.NumberOfParticipants()})\n<a href=\"{url}\">Klik hier om in te schrijven.</a>";

            lock (SharedUpdateLock)
            {
                raid = coll.Find(x => x.UniqueID == raid.UniqueID).FirstOrDefault();
                var pe = raid.Raid.Publications.Where(x => x.ChannelID == target.ChannelID).FirstOrDefault();
                if (null == pe)
                {
                    return;
                }
                // We use -1 as a constant to indicate the message was not sent yet, or was delayed.
                if (pe.TelegramMessageID != -1)
                {
                    try
                    {
                        Client.EditMessageText($"{pe.ChannelID}", pe.TelegramMessageID, null, messageText, "HTML", true, null, "channel");
                    }
                    catch (Exception ex)
                    {
                        _log.Error(ex, "Failed to post new raid message.");

                        raid = coll.Find(x => x.UniqueID == raid.UniqueID).FirstOrDefault();
                        pe   = raid.Raid.Publications.Where(x => x.ChannelID == target.ChannelID).FirstOrDefault();
                        if (null == pe)
                        {
                            return;
                        }
                        raid.Raid.Publications.RemoveAll(x => x != pe && x.ChannelID == pe.ChannelID);

                        pe.LastModificationTimeUTC = raid.LastModificationTime - TimeSpan.FromMilliseconds(1);
                        coll.Update(raid);
                    }
                }
            }
        }
示例#3
0
 private static void LoadRaidIcon(XElement elem, ref RaidTarget icon)
 {
     try
     {
         icon = (RaidTarget)Enum.Parse(typeof(RaidTarget), elem.Value);
     }
     catch
     {
     }
 }
        private void DeleteRaid(RaidTarget target, DbSet <RaidParticipation> coll, RaidParticipation raid)
        {
            _log.Info($"Deleting raid {raid.PublicID} / {raid.Raid.Raid} / {raid.Raid.Gym} from channel {target.Description}");

            if (raid.Raid.TelegramMessageID != null && raid.Raid.TelegramMessageID != 0 && raid.Raid.TelegramMessageID != -1)
            {
                Client.DeleteMessage(target.ChannelID, raid.Raid.TelegramMessageID ?? 0);
            }
            else
            {
                return; // nothing happened.
            }

            // Only update the database when DELETE succeeded
            lock (UpdatePublishedRaidsInChannels.SharedUpdateLock)
            {
                raid = coll.Find(x => x.UniqueID == raid.UniqueID).FirstOrDefault();
                raid.Raid.TelegramMessageID = 0;
                coll.Update(raid);
            }
        }
示例#5
0
        private void DeleteRaid(RaidTarget target, DbSet <RaidParticipation> coll, RaidParticipation raid)
        {
            _log.Info($"Deleting raid {raid.PublicID} / {raid.Raid.Raid} / {raid.Raid.Gym} from channel {target.Description}");

            var pe = raid.Raid.Publications.Where(x => x.ChannelID == target.ChannelID).FirstOrDefault();

            if (null != pe && pe.TelegramMessageID != -1)
            {
                Client.DeleteMessage(target.ChannelID, pe.TelegramMessageID);
            }
            else
            {
                return; // nothing happened.
            }

            // Only update the database when DELETE succeeded
            lock (SharedUpdateLock)
            {
                raid = coll.Find(x => x.UniqueID == raid.UniqueID).FirstOrDefault();
                raid.Raid.Publications.RemoveAll(x => x.ChannelID == pe.ChannelID);
                coll.Update(raid);
            }
        }
        private void PostRaid(RaidTarget target, DbSet <RaidParticipation> coll, RaidParticipation raid)
        {
            _log.Info($"Posting raid {raid.PublicID} / {raid.Raid.Raid} / {raid.Raid.Gym} in channel {target.Description}");

            lock (UpdatePublishedRaidsInChannels.SharedUpdateLock)
            {
                // Mark the raid as updated with posting in progress, by setting the telegram message ID to -1
                raid = coll.Find(x => x.UniqueID == raid.UniqueID).FirstOrDefault();
                raid.Raid.TelegramMessageID = -1; // hardcoded to indicate the message was not sent
                coll.Update(raid);
            }

            try
            {
                var  message   = RaidEventHandler.ShareRaidToChat(raid, target.ChannelID);
                long messageID = message?.MessageID ?? default(long);

                lock (UpdatePublishedRaidsInChannels.SharedUpdateLock)
                {
                    // The record may have changed by now, so load it again, then update tge nessage ID
                    raid = coll.Find(x => x.UniqueID == raid.UniqueID).FirstOrDefault();
                    raid.Raid.TelegramMessageID = messageID;
                    coll.Update(raid);
                }
            }
            catch (Exception ex)
            {
                _log.Error(ex, "Failed to post new raid message, marking as 'new'.");
                lock (UpdatePublishedRaidsInChannels.SharedUpdateLock)
                {
                    // error publishing, assume it wasn't published and try again
                    raid = coll.Find(x => x.UniqueID == raid.UniqueID).FirstOrDefault();
                    raid.Raid.TelegramMessageID = 0;
                    coll.Update(raid);
                }
            }
        }
示例#7
0
        private void ThreadFunc(RaidTarget target)
        {
            _log.Info($"*** Starting channel update thread for {target.Description}");

            int[] delays           = new int[] { 500, 1000, 5000, 3000 };
            int   actionDelayIndex = 0;

            while (!_cts.IsCancellationRequested)
            {
                try
                {
                    var raidParticipationCollection = DB.GetCollection <RaidParticipation>();
                    // find all raids that end in the future, and that will unlock within the next hour (or are already unlocked)
                    var allActiveRaids = raidParticipationCollection.Find(x =>
                                                                          x.Raid.RaidEndTime >= DateTime.UtcNow &&
                                                                          DateTime.UtcNow + TimeSpan.FromHours(1) >= x.Raid.RaidUnlockTime &&
                                                                          x.Raid.Publications != null &&
                                                                          x.Raid.Publications.Any(p => p.ChannelID == target.ChannelID && p.TelegramMessageID != -1)).ToList();

                    // find new entries that still need to be posted
                    var firstRaidThatNeedsPosting = allActiveRaids.Where(x => x.Raid.Publications
                                                                         .Any(p => p.ChannelID == target.ChannelID && p.TelegramMessageID == default(long)))
                                                    .OrderBy(x => x.Raid.RaidUnlockTime).RandomOrDefault();
                    if (null != firstRaidThatNeedsPosting)
                    {
                        PostRaid(target, raidParticipationCollection, firstRaidThatNeedsPosting);
                        actionDelayIndex++;
                    }
                    else
                    {
                        var firstRaidThatNeedsUpdating = allActiveRaids.Where(x => x.Raid.Publications.Any(p => p.ChannelID == target.ChannelID && p.LastModificationTimeUTC < x.LastModificationTime)).OrderBy(x => x.LastModificationTime).RandomOrDefault();
                        if (null != firstRaidThatNeedsUpdating)
                        {
                            UpdateRaid(target, raidParticipationCollection, firstRaidThatNeedsUpdating);
                            actionDelayIndex++;
                        }
                        else
                        {
                            // Raid has ended, but there still is a telegram message for it
                            var firstRaidThatNeedsToBeDeleted = raidParticipationCollection.Find(x => x.Raid.RaidEndTime < DateTime.UtcNow && x.Raid.Publications != null && x.Raid.Publications.Any(p => p.ChannelID == target.ChannelID && p.TelegramMessageID != default(long) && p.TelegramMessageID != -1)).RandomOrDefault();
                            if (null != firstRaidThatNeedsToBeDeleted)
                            {
                                DeleteRaid(target, raidParticipationCollection, firstRaidThatNeedsToBeDeleted);
                                actionDelayIndex++;
                            }
                            else
                            {
                                actionDelayIndex = 0;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    _log.Error(ex, $"Something went wrong and we first caught it at top-level. Ignoring the problem.");
                }
                finally
                {
                    int delay = delays[Math.Min(delays.Length - 1, actionDelayIndex)];
                    Thread.Sleep(TimeSpan.FromMilliseconds(delay));
                }
            }
        }
示例#8
0
        private void PostRaid(RaidTarget target, DbSet <RaidParticipation> coll, RaidParticipation raid)
        {
            _log.Info($"Posting raid {raid.PublicID} / {raid.Raid.Raid} / {raid.Raid.Gym} in channel {target.Description}");

            lock (SharedUpdateLock)
            {
                // Mark the raid as updated with posting in progress, by setting the telegram message ID to -1
                raid = coll.Find(x => x.UniqueID == raid.UniqueID).FirstOrDefault();
                var pe = raid.Raid.Publications.Where(x => x.ChannelID == target.ChannelID).FirstOrDefault();
                if (null == pe)
                {
                    return;
                }
                raid.Raid.Publications.RemoveAll(x => x != pe && x.ChannelID == pe.ChannelID);
                pe.TelegramMessageID       = -1; // hardcoded to indicate the message was not sent
                pe.LastModificationTimeUTC = DateTime.UtcNow;
                coll.Update(raid);
            }

            // Next post the message, this may take some time if we managed to hit the rate limit
            string url         = $"{SettingsManager.BotAddress}raids/{raid.PublicID}?r={rnd.Next()}";
            string messageText = $"[{TimeService.AsShortTime(raid.Raid.RaidUnlockTime)}-{TimeService.AsShortTime(raid.Raid.RaidEndTime)}] {MessageUtils.HtmlEscape(raid.Raid.Raid)} @ {MessageUtils.HtmlEscape(raid.Raid.Gym)} ({raid.NumberOfParticipants()})\n<a href=\"{url}\">Klik hier om in te schrijven.</a>";

            try
            {
                var  message   = Client.SendMessageToChat(target.ChannelID, messageText, "HTML", true, true);
                long messageID = message?.MessageID ?? default(long);

                lock (SharedUpdateLock)
                {
                    // The record may have changed by now, so load it again, then update tge nessage ID
                    raid = coll.Find(x => x.UniqueID == raid.UniqueID).FirstOrDefault();
                    var pe = raid.Raid.Publications.Where(x => x.ChannelID == target.ChannelID).FirstOrDefault();
                    if (null == pe)
                    {
                        return;
                    }
                    raid.Raid.Publications.RemoveAll(x => x != pe && x.ChannelID == pe.ChannelID);
                    pe.TelegramMessageID = messageID;
                    coll.Update(raid);
                }
            }
            catch (Exception ex)
            {
                _log.Error(ex, "Failed to post new raid message, marking as 'new'.");
                lock (SharedUpdateLock)
                {
                    // The record may have changed by now, so load it again, then update tge nessage ID
                    raid = coll.Find(x => x.UniqueID == raid.UniqueID).FirstOrDefault();
                    var pe = raid.Raid.Publications.Where(x => x.ChannelID == target.ChannelID).FirstOrDefault();
                    if (null == pe)
                    {
                        return;
                    }
                    raid.Raid.Publications.RemoveAll(x => x != pe && x.ChannelID == pe.ChannelID);
                    pe.TelegramMessageID       = 0;
                    pe.LastModificationTimeUTC = DateTime.MinValue;
                    coll.Update(raid);
                }
            }
        }
示例#9
0
 private static void LoadRaidIcon(XElement elem, ref RaidTarget icon)
 {
     try
     {
         icon = (RaidTarget)Enum.Parse(typeof(RaidTarget), elem.Value);
     }
     catch
     {
     }
 }
        private void ThreadFunc(RaidTarget target)
        {
            _log.Info($"*** Starting channel update thread for {target.Description}");

            int[] delays           = new int[] { 500, 1000, 5000, 3000 };
            int   actionDelayIndex = 0;

            while (!_cts.IsCancellationRequested)
            {
                try
                {
                    var raidParticipationCollection = DB.GetCollection <RaidParticipation>();
                    // find all raids that end in the future, and that will unlock within the next hour (or are already unlocked)
                    var raid = raidParticipationCollection.Find(x =>
                                                                x.Raid.RaidEndTime >= DateTime.UtcNow &&
                                                                DateTime.UtcNow + TimeSpan.FromHours(1) >= x.Raid.RaidUnlockTime &&
                                                                x.IsPublished &&
                                                                (x.Raid.TelegramMessageID == null || x.Raid.TelegramMessageID == 0 || x.Raid.TelegramMessageID == -1)).ToList().RandomOrDefault();
                    if (null != raid)
                    {
                        PostRaid(target, raidParticipationCollection, raid);
                        actionDelayIndex++;
                    }
                    else
                    {
                        raid = raidParticipationCollection.Find(x => x.Raid.RaidEndTime >= DateTime.UtcNow &&
                                                                DateTime.UtcNow + TimeSpan.FromHours(1) >= x.Raid.RaidUnlockTime &&
                                                                x.IsPublished &&
                                                                x.LastRefresh < x.LastModificationTime &&
                                                                (x.Raid.TelegramMessageID != null && x.Raid.TelegramMessageID != 0 && x.Raid.TelegramMessageID != -1)).ToList().RandomOrDefault();
                        if (null != raid)
                        {
                            UpdateRaid(target, raidParticipationCollection, raid);
                            actionDelayIndex++;
                        }
                        else
                        {
                            raid = raidParticipationCollection.Find(x => x.Raid.RaidEndTime < DateTime.UtcNow &&
                                                                    x.IsPublished &&
                                                                    (x.Raid.TelegramMessageID != null && x.Raid.TelegramMessageID != 0 && x.Raid.TelegramMessageID != -1)).ToList().RandomOrDefault();
                            if (null != raid)
                            {
                                DeleteRaid(target, raidParticipationCollection, raid);
                                actionDelayIndex++;
                            }
                            else
                            {
                                actionDelayIndex = 0;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    _log.Error(ex, $"Something went wrong and we first caught it at top-level. Ignoring the problem.");
                }
                finally
                {
                    int delay = delays[Math.Min(delays.Length - 1, actionDelayIndex)];
                    Thread.Sleep(TimeSpan.FromMilliseconds(delay));
                }
            }
        }