Citrinate / FreePackages

An ASF plugin for finding and redeeming free Steam games
Apache License 2.0
117 stars 6 forks source link

Change of rate-limit? #35

Closed woctezuma closed 3 months ago

woctezuma commented 4 months ago

For info, the rate-limit may have been changed from 50 to 30 free packages per hour on Valve's side.

Citrinate commented 4 months ago

Updated to the new limit and set the default to 25.

I see there may still be some unknowns concerning whether or not you need to wait the full hour after being rate limited, and that maybe sometimes you can get away with waiting for less. This isn't something I can take advantage of as packages here are sometimes activated using RequestFreeLicense, which just returns pass/fail and never tells you if you've been rate limited.

Citrinate commented 4 months ago

Also seems more important now to address the issue of invalid activation attempts and how they might impact the limit (#1).

I'm in the process of testing changes that would eliminate nearly all invalid attempts. If you'd like to test these changes you can find builds here: https://github.com/Citrinate/FreePackages/actions?query=branch%3A1.5

Latest build as of now: FreePackages V1.5.0

Citrinate commented 3 months ago

Today I've started to get a bunch of rate limit errors using the default limit of 25/hour. Either Valve has lowered the limit again, or there needs to be a larger delay in between requests.

First after 23 requests + 1 playtest

Jun 10 10:18:07 asf-asf[1096242]: INFO|ClaimFreeSub() Status: OK/NoDetail
Jun 10 10:18:14 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 10:18:20 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 10:18:27 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 10:18:33 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 10:18:39 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 10:18:45 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 10:18:52 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 10:18:59 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 10:19:05 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 10:19:11 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 10:19:17 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 10:19:24 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 10:19:30 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 10:19:36 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 10:19:43 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 10:19:49 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 10:19:55 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 10:20:01 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 10:20:07 asf-asf[1096242]: INFO|ClaimFreeSub() Status: OK/NoDetail
Jun 10 10:20:13 asf-asf[1096242]: INFO|ClaimPlaytest() Status: Waitlisted
Jun 10 10:20:21 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 10:20:28 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 10:20:35 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 10:20:40 asf-asf[1096242]: DEBUG|ClaimFreeSub() Status: Fail/RateLimited
Jun 10 10:20:40 asf-asf[1096242]: INFO|ProcessQueue() Free Package rate limit exceeded
Jun 10 10:20:40 asf-asf[1096242]: INFO|ProcessQueue() Pausing free package activations until 11:21:40 AM

Then an hour later after 20-21 requests:

Jun 10 11:21:42 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 11:21:51 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 11:21:58 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 11:22:05 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 11:22:12 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 11:22:19 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 11:22:26 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 11:22:32 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 11:22:39 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 11:22:46 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 11:22:52 asf-asf[1096242]: INFO|ClaimFreeSub() Status: OK/NoDetail
Jun 10 11:22:59 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 11:23:05 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 11:23:11 asf-asf[1096242]: INFO|ClaimFreeSub() Status: OK/NoDetail
Jun 10 11:23:18 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 11:23:24 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 11:23:31 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 11:23:38 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 11:23:45 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 11:23:51 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 11:23:57 asf-asf[1096242]: DEBUG|ClaimFreeApp() Status: Unknown
Jun 10 11:24:03 asf-asf[1096242]: DEBUG|ClaimFreeSub() Status: Fail/RateLimited
Jun 10 11:24:03 asf-asf[1096242]: INFO|ProcessQueue() Free Package rate limit exceeded
Jun 10 11:24:03 asf-asf[1096242]: INFO|ProcessQueue() Pausing free package activations until 12:25:03 PM

And another hour later after 22-24 requests

Jun 10 12:25:06 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 12:25:12 asf-asf[1096242]: INFO|ClaimFreeSub() Status: OK/NoDetail
Jun 10 12:25:19 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 12:25:27 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 12:25:34 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 12:25:39 asf-asf[1096242]: INFO|ClaimFreeSub() Status: OK/NoDetail
Jun 10 12:25:46 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 12:25:53 asf-asf[1096242]: INFO|ClaimFreeSub() Status: OK/NoDetail
Jun 10 12:26:00 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 12:26:07 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 12:26:13 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 12:26:20 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 12:26:27 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 12:26:33 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 12:26:39 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 12:26:46 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 12:26:52 asf-asf[1096242]: INFO|ClaimFreeSub() Status: OK/NoDetail
Jun 10 12:26:57 asf-asf[1096242]: INFO|ClaimFreeSub() Status: OK/NoDetail
Jun 10 12:27:04 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 12:27:09 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 12:27:15 asf-asf[1096242]: INFO|ClaimFreeSub() Status: OK/NoDetail
Jun 10 12:27:21 asf-asf[1096242]: INFO|ClaimFreeApp() Status: OK
Jun 10 12:27:27 asf-asf[1096242]: DEBUG|ClaimFreeApp() Status: Unknown
Jun 10 12:27:33 asf-asf[1096242]: DEBUG|ClaimFreeApp() Status: Unknown
Jun 10 12:27:38 asf-asf[1096242]: DEBUG|ClaimFreeSub() Status: Fail/RateLimited
Jun 10 12:27:38 asf-asf[1096242]: INFO|ProcessQueue() Free Package rate limit exceeded
Jun 10 12:27:38 asf-asf[1096242]: INFO|ProcessQueue() Pausing free package activations until 1:28:38 PM
Citrinate commented 3 months ago

I'm guessing that nothing has changed and that this functionally is already understood and I just misinterpreted it. From SteamDB:

Steam changed how activations are rate limited. You can only activate 30 packages, and then 1 package every 3 minutes.

I take this to mean that the rate limit doesn't reset after an hour anymore, it instead takes up to 90 minutes to fully reset. I'll do some testing to confirm this for myself before I make any changes.

For now, I seem to be successfully dodging the rate limit by setting FreePackagesPerHour to 20.

woctezuma commented 3 months ago

This is what SteamDB's maintainer believes as well:

Picture

Setting the plugin limit to 20 packages every 60 minutes is in line with this observation. That being said, using this setting, the plugin may try to activate 40 packages in a time-window of 90 minutes.

To be extra safe, a limit of 15 packages would avoid this scenario, as the plugin would try to activate at most 30 packages in a time-window of 120 minutes.

Citrinate commented 3 months ago

That being said, using this setting, the plugin may try to activate 40 packages in a time-window of 90 minutes.

I'm still testing, but I don't think this is a problem. My current understanding is that you don't get 1 activation every 3 minutes only after hitting the limit. You're getting 1 activation every 3 minutes all the time, and you can store a maximum of 30 activations. So if you activate 20 and then wait 60 minutes, you'll be back up to 30 activations that you can use.

The maximum number of packages you can activate in 90 minutes is 60. One way to do this is the way described by SteamDB: Redeem 30 at once, and then 1 every 3 minutes for 90 minutes. Another way I tested which also works is to redeem 15, wait 45 minutes, redeem another 15, wait another 45 minutes, and then redeem 30.

woctezuma commented 3 months ago

Ah, cool! That would make sense!