Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Drops are not counted #138

Open
ReformedDoge opened this issue Aug 8, 2024 · 4 comments
Open

New Drops are not counted #138

ReformedDoge opened this issue Aug 8, 2024 · 4 comments

Comments

@ReformedDoge
Copy link

ReformedDoge commented Aug 8, 2024

I noticed today that I haven't received any webhook drop notifications since March, so I began investigating the issue.

I found that I hadn't set countDrops to any value in my config file. However, as I understand it, countDrops defaults to True. Therefore, this should not be the cause of the issue

self.countDrops = configFile.get("countDrops", True)

I tested the webhook by setting connectorTest to True, and it succeeded. This indicates that the webhook itself is working correctly.
I debugged currentDropsList, and it successfully retrieved and set the data.

Based on my findings, I suspect that the issue may be related to the following line of code:

newDropList = [drop for drop in stats.currentDropsList if (stats.lastDropCheckTime - 6000) <= drop.get("unlockedDateMillis", -1)]

If unlockedDateMillis is older than stats.lastDropCheckTime - 6000, that drop will not be included in the newDropList i think that's the issue

As I understand, stats.lastDropCheckTime is updated at the end of the checkNewDrops function. The frequency of checkNewDrops calls is influenced by delays and sleep periods in watchMatches function in (Match.py)

# Random numbers, used for random delay
randomDelay = randint(int(config.delay * 0.08), int(config.delay * 0.15))
newDelay = randomDelay * 10
nowTimeHour = int(time.localtime().tm_hour)
nowTimeDay = int(time.localtime().tm_mday)
liveUrlList = []
sleepEndTime = ""
# If you are not currently sleeping,
# get match information (including matches that are still counting down).
if isSleep is False:
log.info(_log("检查赛区直播状态..."))
liveUrlList = fetchLiveMatches(ignoreBroadCast=False, ignoreDisWatchMatches=True)
if liveUrlList == ["ERROR"]:
liveUrlList = self.getMatchInfo(ignoreBroadCast=False)
if config.autoSleep:
# When the next game time is correct, go into sleep judgment.
if self.nextMatchHour is not None and self.nextMatchDay is not None:
# If the next match is on the same day as now, but the current time has exceeded the match time, sober up.
if nowTimeDay == self.nextMatchDay and \
nowTimeHour >= self.nextMatchHour:
isSleep = False
# If the next match is on the same day as the current day,
# and there is still over an hour before the match starts,
# and no regions are currently live-streaming, then enter a one-hour sleep mode.
elif nowTimeDay == self.nextMatchDay and \
nowTimeHour < self.nextMatchHour - 1 and \
self.currentWindows == {} and liveUrlList == []:
isSleep = True
newDelay = 3599
# If the next game is the same day as now, but the current time is already an hour before the game, sober up.
elif nowTimeDay == self.nextMatchDay and \
nowTimeHour == self.nextMatchHour - 1:
isSleep = False
# If the next game date is greater than the current date, and there is no live game now,
# and the current time hours are less than 23, sleep is entered with an interval of one hour.
elif nowTimeDay < self.nextMatchDay and self.currentWindows == {} \
and nowTimeHour < 23 and liveUrlList == []:
isSleep = True
newDelay = 3599
elif nowTimeDay < self.nextMatchDay and nowTimeHour >= 23:
isSleep = False
elif (nowTimeDay == 31 or nowTimeDay == 30 or nowTimeDay == 29) and \
(self.nextMatchDay == 1 or self.nextMatchDay == 2 or self.nextMatchDay == 3) \
and nowTimeHour < 23 and liveUrlList == []:
isSleep = True
newDelay = 3599
else:
isSleep = False
# Stay awake when the next game time is wrong.
else:
isSleep = False
else:
if self.nextMatchHour is not None and self.nextMatchDay is not None:
if nowTimeDay < self.nextMatchDay and self.currentWindows == {} and nowTimeHour < 23 and liveUrlList == []:
newDelay = 3599
# When the time of the next game is longer than 1 hour from the current time, the check interval is one hour
elif nowTimeHour < self.nextMatchHour - 1 and self.currentWindows == {} and liveUrlList == []:
newDelay = 3599
# The sleep period set has a higher priority than the autoSleep function.
if self.sleepBeginList == [] and self.sleepEndList == []:
pass
else:
nowTimeHour = int(time.localtime().tm_hour)
for sleepBegin, sleepEnd in zip(self.sleepBeginList, self.sleepEndList):
if sleepBegin <= nowTimeHour < sleepEnd:
if nowTimeHour < sleepEnd - 1:
newDelay = 3599
else:
randomDelay = randint(
int(config.delay * 0.08), int(config.delay * 0.15))
newDelay = randomDelay * 10
isSleep = True
sleepEndTime = sleepEnd
break
else:
isSleep = False
if isSleep:
if sleepFlag is False:
log.info(_log("进入休眠时间"))
stats.info.append(f"{datetime.now().strftime('%H:%M:%S')} " + _("进入休眠时间", color="green"))
stats.liveRegions = []
stats.status = _("休眠", color="yellow")
self.closeAllTabs()
sleepFlag = True
else:
log.info(_log("处于休眠时间..."))
stats.status = _("休眠", color="yellow")
if sleepEndTime:
wakeTime = sleepEndTime
else:
wakeTime = stats.nextMatch.split("|")[1]
log.info(f'{_log("预计休眠状态将持续到")} {wakeTime}')
if not any(f'{_("预计休眠状态将持续到", color="bold yellow")} [cyan]{wakeTime}[/cyan]' in info for info in stats.info):
stats.info.append(f"{datetime.now().strftime('%H:%M:%S')} " +
f'{_("预计休眠状态将持续到", color="bold yellow")} [cyan]{wakeTime}[/cyan]')
log.info(
f"{_log('下次检查在:')} "
f"{(datetime.now() + timedelta(seconds=newDelay)).strftime('%m-%d %H:%M:%S')}")
stats.nextCheckTime = "[cyan]" + (datetime.now() + timedelta(seconds=newDelay)).strftime('%H:%M:%S') + "[/cyan]"
log.info(f"{'=' * 50}")
sleep(newDelay)
continue
elif sleepFlag is True:
log.info(_log("休眠时间结束"))
stats.info.append(f"{datetime.now().strftime('%H:%M:%S')} " + _("休眠时间结束", color="green"))
stats.lastCheckTime = "[cyan]" + datetime.now().strftime('%H:%M:%S') + "[/cyan]"
stats.nextCheckTime = ""
stats.status = _("检查中", color="green")
log.info(_log("开始检查..."))
sleepFlag = False
if config.countDrops:
self.driver.switch_to.window(self.rewardWindow)
self.rewardWindow = self.rewards.getRewardPage()
# Get the number of drops and total hours watched
if config.countDrops:
watchRegion = fetchWatchRegions()
if watchRegion != "ERROR":
stats.watchRegion = watchRegion
else:
stats.watchRegion = _log("未知")
log.info(f"{_log('观看属地')}: {stats.watchRegion}")
self.driver.switch_to.window(self.rewardWindow)
checkRewardPage(self.driver, isInit=False)
setTodayDropsNumber()
self.rewards.checkNewDrops()

Should we subtract the maximum possible delay or sleep time (whatever is greater) from stats.lastDropCheckTime to ensure that no drops are missed? Increasing the time window or adjusting the logic to account for potential delays might resolve the issue.
max sleep time as i understand is 1 hour

Please let me know if this adjustment would help or if there are any other factors to consider. Also, it would be useful to know if other users are experiencing the same issue. I have yet to test this change since I haven’t received any new drops recently.

Thank you!

@ReformedDoge
Copy link
Author

ReformedDoge commented Aug 8, 2024

Apologies, I accidentally closed the issue by mistake

Sorting the currentDropsList and tracking the latest drop timestamp can be a more efficient way to handle this problem
(Again, assuming it is indeed the cause. Here’s a possible approach)

class DropTracker:
    def __init__(self):
        self.latestProcessedDropTime = int(datetime.now().timestamp() * 1e3)  # Initialize with current time

    def checkNewDrops(self, currentDropsList):
        # Sort drops by unlockedDateMillis in descending order
        sorted_drops = sorted(currentDropsList, key=lambda drop: drop.get("unlockedDateMillis", 0), reverse=True)
        
        newDropList = []
        for drop in sorted_drops:
            unlockedDateMillis = drop.get("unlockedDateMillis", -1)
            
            # Early exit if we encounter a drop older than the latest processed drop time
            if unlockedDateMillis <= self.latestProcessedDropTime:
                break
            
            newDropList.append(drop)
            self.latestProcessedDropTime = unlockedDateMillis

        return newDropList

Create an instance of DropTracker somewhere in the script.
drop_tracker = DropTracker()
Use checkNewDrops to get the list of new drops.
new_drops = drop_tracker.checkNewDrops(currentDropsList)

This approach dynamically updates latestProcessedDropTime based on the most recent drop it processes. It does not use a fixed time window but instead ensures that only drops newer than the most recently processed one are considered. As a result, it inherently accounts for any delays or gaps between checks.

Here is the updated Rewards.py that I will be testing for the next couple of days.
ReformedDoge@80e6276

@ReformedDoge ReformedDoge reopened this Aug 8, 2024
@Yudaotor
Copy link
Owner

I don't think I've seen anyone else raise a similar issue and I've been busy lately, so let me know here if you get any results on your end!

ReformedDoge added a commit to ReformedDoge/EsportsHelper that referenced this issue Aug 14, 2024
This approach dynamically updates latestProcessedDropTime based on the most recent drop it processes. It does not use a fixed time window but instead ensures that only drops newer than the most recently processed one are considered. As a result, it inherently accounts for any delays or gaps between checks.

Yudaotor#138 (comment)
ReformedDoge added a commit to ReformedDoge/EsportsHelper that referenced this issue Aug 14, 2024
Issue: Yudaotor#138

To address this, I implemented a delay and retry logic. This ensures that the earnedDrops endpoint is always captured in the performance log when visiting the reward page. The key changes include adding a retry mechanism with delays, allowing sufficient time for the logs to populate.
@ReformedDoge
Copy link
Author

ReformedDoge commented Aug 14, 2024

Hi @Yudaotor

I’ve determined that the getRewardByLog function in NetworkHandler.py is the cause of the problem.

Issue Details

The issue occurs when revisiting the reward page after the initial visit. If the earnedDrops requests are not present in the performance log (driver.get_log('performance')), the stats object is not updated, and we end up with drop data from the initial request only.

Solution

To resolve this, I implemented a delay and retry mechanism. This approach ensures that the earnedDrops endpoint is always captured in the performance log when visiting the reward page. The key changes involve:

  • Adding a retry mechanism with delays.
  • Allowing additional time for the logs to populate before processing them.

With these changes, I’ve finally seen new drops reflected in the GUI after months of not being able to. The connector is now functioning properly as well:
image

Fix Commit: aeb9636cd2f8f761bd8ed453e6903c7339582131

Additional Enhancement: A new class to track new drops more effectively: 298dd54e2cdb1896fbf36a8d9c866c0564cd88b6

I can create a pull request if other users are experiencing the same issue, or if you would like to review and merge these changes. Please let me know how you'd like to proceed or if there's anything else I can assist with.

@DRCX
Copy link

DRCX commented Sep 27, 2024

I don't think I've seen anyone else raise a similar issue and I've been busy lately, so let me know here if you get any results on your end!我认为我没有看到其他人提出类似的问题,而且我最近很忙,所以如果你得到任何结果,请在这里告诉我!

入围赛确实没有一个罐子掉落,我2个号都是这样...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants