@@ -58,7 +58,7 @@ public sealed class ArchiWebHandler : IDisposable {
5858 private const byte MaxTradeOfferMessageLength = 128 ;
5959 private const byte MinimumSessionValidityInSeconds = 10 ;
6060 private const byte SessionIDLength = 24 ; // For maximum compatibility, should be divisible by 2 and match the length of "sessionid" property that Steam uses across their websites
61- private const string SteamAppsService = "ISteamApps " ;
61+ private const string SteamStoreService = "IStoreService " ;
6262
6363 [ PublicAPI ]
6464 public static Uri SteamCheckoutURL => new ( "https://checkout.steampowered.com" ) ;
@@ -1640,62 +1640,86 @@ internal async Task<bool> ChangePrivacySettings(UserPrivacy userPrivacy) {
16401640 }
16411641
16421642 internal async Task < HashSet < uint > ? > GetAppList ( ) {
1643+ string ? accessToken = Bot . AccessToken ;
1644+
1645+ if ( string . IsNullOrEmpty ( accessToken ) ) {
1646+ return null ;
1647+ }
1648+
16431649 const string endpoint = "GetAppList" ;
16441650 HttpMethod method = HttpMethod . Get ;
16451651
1646- using WebAPI . AsyncInterface steamAppsService = Bot . SteamConfiguration . GetAsyncWebAPIInterface ( SteamAppsService ) ;
1652+ // Extra entry for last_appid that will end up here for sure
1653+ Dictionary < string , object ? > arguments = new ( 3 , StringComparer . Ordinal ) {
1654+ { "access_token" , accessToken } ,
1655+ { "max_results" , 50000 }
1656+ } ;
1657+
1658+ HashSet < uint > ? result = null ;
1659+
1660+ using WebAPI . AsyncInterface steamAppsService = Bot . SteamConfiguration . GetAsyncWebAPIInterface ( SteamStoreService ) ;
16471661
16481662 steamAppsService . Timeout = WebBrowser . Timeout ;
16491663
1650- KeyValue ? response = null ;
1664+ while ( true ) {
1665+ KeyValue ? response = null ;
16511666
1652- for ( byte i = 0 ; ( i < WebBrowser . MaxTries ) && ( response == null ) ; i ++ ) {
1653- if ( ( i > 0 ) && ( WebLimiterDelay > 0 ) ) {
1654- await Task . Delay ( WebLimiterDelay ) . ConfigureAwait ( false ) ;
1655- }
1667+ for ( byte i = 0 ; ( i < WebBrowser . MaxTries ) && ( response == null ) ; i ++ ) {
1668+ if ( ( i > 0 ) && ( WebLimiterDelay > 0 ) ) {
1669+ await Task . Delay ( WebLimiterDelay ) . ConfigureAwait ( false ) ;
1670+ }
16561671
1657- if ( Debugging . IsUserDebugging ) {
1658- Bot . ArchiLogger . LogGenericDebug ( $ "{ method } { Bot . SteamConfiguration . WebAPIBaseAddress } { SteamAppsService } /{ endpoint } ") ;
1672+ if ( Debugging . IsUserDebugging ) {
1673+ Bot . ArchiLogger . LogGenericDebug ( $ "{ method } { Bot . SteamConfiguration . WebAPIBaseAddress } { SteamStoreService } /{ endpoint } ") ;
1674+ }
1675+
1676+ try {
1677+ response = await WebLimitRequest (
1678+ Bot . SteamConfiguration . WebAPIBaseAddress ,
1679+
1680+ // ReSharper disable once AccessToDisposedClosure
1681+ async ( ) => await steamAppsService . CallAsync ( method , endpoint , args : arguments ) . ConfigureAwait ( false )
1682+ ) . ConfigureAwait ( false ) ;
1683+ } catch ( TaskCanceledException e ) {
1684+ Bot . ArchiLogger . LogGenericDebuggingException ( e ) ;
1685+ } catch ( Exception e ) {
1686+ Bot . ArchiLogger . LogGenericWarningException ( e ) ;
1687+ }
16591688 }
16601689
1661- try {
1662- response = await WebLimitRequest (
1663- Bot . SteamConfiguration . WebAPIBaseAddress ,
1690+ if ( response == null ) {
1691+ Bot . ArchiLogger . LogGenericWarning ( Strings . FormatErrorRequestFailedTooManyTimes ( WebBrowser . MaxTries ) ) ;
16641692
1665- // ReSharper disable once AccessToDisposedClosure
1666- async ( ) => await steamAppsService . CallAsync ( method , endpoint , 2 ) . ConfigureAwait ( false )
1667- ) . ConfigureAwait ( false ) ;
1668- } catch ( TaskCanceledException e ) {
1669- Bot . ArchiLogger . LogGenericDebuggingException ( e ) ;
1670- } catch ( Exception e ) {
1671- Bot . ArchiLogger . LogGenericWarningException ( e ) ;
1693+ return null ;
16721694 }
1673- }
16741695
1675- if ( response == null ) {
1676- Bot . ArchiLogger . LogGenericWarning ( Strings . FormatErrorRequestFailedTooManyTimes ( WebBrowser . MaxTries ) ) ;
1696+ List < KeyValue > apps = response [ "apps" ] . Children ;
16771697
1678- return null ;
1679- }
1698+ if ( apps . Count == 0 ) {
1699+ Bot . ArchiLogger . LogGenericWarning ( Strings . FormatErrorIsEmpty ( nameof ( apps ) ) ) ;
16801700
1681- List < KeyValue > apps = response [ "apps" ] . Children ;
1701+ return null ;
1702+ }
16821703
1683- if ( apps . Count == 0 ) {
1684- Bot . ArchiLogger . LogGenericWarning ( Strings . FormatErrorIsEmpty ( nameof ( apps ) ) ) ;
1704+ result ??= new HashSet < uint > ( apps . Count ) ;
16851705
1686- return null ;
1687- }
1706+ foreach ( uint appID in apps . Select ( static app => app [ "appid" ] . AsUnsignedInteger ( ) ) ) {
1707+ if ( appID == 0 ) {
1708+ Bot . ArchiLogger . LogNullError ( appID ) ;
1709+
1710+ return null ;
1711+ }
16881712
1689- HashSet < uint > result = new ( apps . Count ) ;
1713+ result . Add ( appID ) ;
1714+ }
16901715
1691- foreach ( uint appID in apps . Select ( static app => app [ "appid" ] . AsUnsignedInteger ( ) ) ) {
1692- if ( appID == 0 ) {
1693- Bot . ArchiLogger . LogNullError ( appID ) ;
1716+ uint lastAppID = response [ "last_appid" ] . AsUnsignedInteger ( ) ;
16941717
1695- return null ;
1718+ if ( lastAppID == 0 ) {
1719+ break ;
16961720 }
16971721
1698- result . Add ( appID ) ;
1722+ arguments [ "last_appid" ] = lastAppID ;
16991723 }
17001724
17011725 return result ;
0 commit comments