thesadru / genshinstats

PLEASE USE GENSHIN.PY A python library that can get the stats of Genshin Impact players using Mihoyo's API. PLEASE USE GENSHIN.PY
https://thesadru.github.io/pdoc/genshinstats/
MIT License
265 stars 38 forks source link

Check In Rewards Redemption Failure #19

Closed KingWaffleIII closed 3 years ago

KingWaffleIII commented 3 years ago

Hello again, Apologise for frequenting too often and making your head spin, I'm sure, but I've found a problem and I don't think it's within my code. I'm running the following which claims all daily rewards every 24 hours. I also have a gs.set_cookies() function earlier up with connects everyone in the data base.

                while data[key]["check_in_recurring"] is True:
                    await asyncio.sleep(86400)
                    try:
                        gs.hoyolab_check_in(cookie={"ltuid": data[key]["ltuid"], "ltoken": data[key]["ltoken"]})
                        gs.claim_daily_reward(cookie={"ltuid": data[key]["ltuid"], "ltoken": data[key]["ltoken"]})
                        data[key]["last_check_in"] = f"{x.year}-{x.month}-{x.day} {x.hour}:{x.minute}:{x.second} UTC"
                        data[key]["last_check_in_fail"] = [False]
                        save_data()
                        info = gs.get_daily_reward_info(cookie={"ltuid": data[key]["ltuid"], "ltoken": data[key]["ltoken"]})
                        await ctx.send(f"You were checked into HoYoLab and your daily rewards were claimed! You have claimed {info[1]} rewards this month.")
                    except gs.SignInException:
                        data[key]["last_check_in"] = f"{x.year}-{x.month}-{x.day} {x.hour}:{x.minute}:{x.second} UTC"
                        data[key]["last_check_in_fail"] = [True, "already_checked_in_today"]
                        save_data()
                        await ctx.send("You have already checked in today. Please try again tomorrow.")

When I use this, it works perfectly but when another user of the bot tried it, they received the DM that confirms they've checked in and that they've claimed 5 rewards this month. Whereas in reality, they realised that they had not gotten any mail so they went to the page and it said on there that they had only claimed 4 rewards this month and they had to manually do it. Thoughts?

thesadru commented 3 years ago

It might be possible that hoyolab_check_in raises an error so claim_daily_reward never actually runs. Could you please try printing the error when catching it?

KingWaffleIII commented 3 years ago

Yep, I'll try that. It's unlikely though because if that returns a SignInException, it shouldn't say the rewards were claimed.

KingWaffleIII commented 3 years ago

So that's interesting. Before doing anything, the check-in page showed that I had claimed 6 rewards this month and today's reward. Then, after reducing the timer to 10 seconds, I enabled the recurring feature and then it said it had successfully claimed a reward today? The check-in page still shows 6 rewards. It did not return an exception that time but after retrying, it throws a SignInException as expected.

thesadru commented 3 years ago

From what you've said it seems that the request can be successful even when the user was signed in already. This looks more like a bug on mihoyo's side. I think I can solve it by simply checking if the amount of claimed rewards increased and raising an error manually if not.

I'll attempt to reproduce this myself just in case the code perhaps failed to raise the error. If you have any other clues about what this might be caused by I'd appreciate it.

thesadru commented 3 years ago

Ok so I've just gotten back to a computer and wanted to fix the bug but there's something I don't understand. You expect an exception to be raised yet if the reward could not be claimed then gs.claim_daily_reward would return None, not raise an error. Is it possible that your bug might just be caused by a misunderstanding of how the function works?

KingWaffleIII commented 3 years ago

I didn't actually know the function returned None; every case that I used it; it either worked or returned SignInException. I did read the documentation but may have skimmed over that part. Anyway, the user of the bot in question informed me yesterday that the check-in for him now works; we're still stumped as to why it failed before.

thesadru commented 3 years ago

Yeah, so what I think has happened:

  1. the user has already checked into hoyolab (not the daily reward), which means a SignInException was raised and a daily reward could not be claimed
  2. the user has already claimed their reward and since you assumed an exception would be raised in that case you didn't check the return. The code then proceeded as if all went correct and the user was told that a reward was somehow claimed.

This is how I'd fix your code snippet so it works properly:

while data[key]["check_in_recurring"]:
    await asyncio.sleep(86400)
    try:
        gs.hoyolab_check_in(cookie={"ltuid": data[key]["ltuid"], "ltoken": data[key]["ltoken"]})
    except gs.SignInException:
        data[key]["last_hoyolab_check_in"] = f"{x.year}-{x.month}-{x.day} {x.hour}:{x.minute}:{x.second} UTC"
        data[key]["last_hoyolab_check_in_fail"] = [True, "already_checked_in_today"]
    else:
        data[key]["last_hoyolab_check_in"] = f"{x.year}-{x.month}-{x.day} {x.hour}:{x.minute}:{x.second} UTC"
        data[key]["last_hoyolab_check_in_fail"] = [False]

    reward = gs.claim_daily_reward(cookie={"ltuid": data[key]["ltuid"], "ltoken": data[key]["ltoken"]})
    if reward is not None:
        signed, claimed = gs.get_daily_reward_info(cookie={"ltuid": data[key]["ltuid"], "ltoken": data[key]["ltoken"]})
        await ctx.send(f"Your daily rewards were claimed! ({reward['cnt']}x {reward['name']}) You have claimed {claimed} rewards this month.")
        data[key]["last_check_in"] = f"{x.year}-{x.month}-{x.day} {x.hour}:{x.minute}:{x.second} UTC"
        data[key]["last_check_in_fail"] = [False]
    else:
        data[key]["last_check_in"] = f"{x.year}-{x.month}-{x.day} {x.hour}:{x.minute}:{x.second} UTC"
        data[key]["last_check_in_fail"] = [True, "already_checked_in_today"]
        await ctx.send("Your daily rewards have already been claimed. Please try again tomorrow.")
    save_data()

Also, note that hoyolab_check_in is in no way related to claim_daily_reward! I personally think you should just claim the daily rewards since checking into hoyolab could cause some confusion.

KingWaffleIII commented 3 years ago

Thanks for the code snippet! Appreciate all the help. And the hoyolab_check_in() gives 5 XP on HoYoLab, doesn't it? I'm aware they do different things but it's still a daily "check-in" so I added it.

thesadru commented 3 years ago

Fair enough, I just thought it could cause some confusion as it did now. Since the bug has been resolved I'll be closing this issue now.