steamutils 1.4.63 → 1.4.65

Sign up to get free protection for your applications and to get access to all the features.
Files changed (234) hide show
  1. package/.idea/codeStyles/Project.xml +1 -0
  2. package/.idea/deployment.xml +14 -0
  3. package/.prettierrc.json +3 -3
  4. package/SteamClient.js +701 -413
  5. package/_steamproto.js +33 -33
  6. package/axios.js +84 -84
  7. package/bufferHelpers.js +115 -115
  8. package/cheerio.js +103 -103
  9. package/const.js +458 -458
  10. package/create_proto.js +96 -96
  11. package/create_remote_file.js +66 -66
  12. package/full_steamproto.js +35 -0
  13. package/helpers/protos.js +48 -48
  14. package/index.js +7764 -7764
  15. package/package.json +1 -1
  16. package/protos/csgo/base_gcmessages.proto +553 -553
  17. package/protos/csgo/base_gcmessages_csgo.proto +547 -547
  18. package/protos/csgo/c_peer2peer_netmessages.proto +55 -55
  19. package/protos/csgo/clientmessages.proto +48 -48
  20. package/protos/csgo/connectionless_netmessages.proto +17 -17
  21. package/protos/csgo/cs_gameevents.proto +35 -35
  22. package/protos/csgo/cs_usercmd.proto +34 -34
  23. package/protos/csgo/cstrike15_gcmessages.proto +1431 -1431
  24. package/protos/csgo/cstrike15_usermessages.proto +592 -592
  25. package/protos/csgo/demo.proto +165 -165
  26. package/protos/csgo/econ_gcmessages.proto +219 -219
  27. package/protos/csgo/enums_clientserver.proto +1529 -1529
  28. package/protos/csgo/fatdemo.proto +125 -125
  29. package/protos/csgo/gameevents.proto +120 -120
  30. package/protos/csgo/gcsdk_gcmessages.proto +323 -323
  31. package/protos/csgo/gcsystemmsgs.proto +243 -243
  32. package/protos/csgo/netmessages.proto +618 -618
  33. package/protos/csgo/networkbasetypes.proto +246 -246
  34. package/protos/csgo/networksystem_protomessages.proto +17 -17
  35. package/protos/csgo/steamdatagram_messages_auth.proto +65 -65
  36. package/protos/csgo/steamdatagram_messages_sdr.proto +534 -534
  37. package/protos/csgo/steammessages_cloud.steamworkssdk.proto +68 -68
  38. package/protos/csgo/steammessages_gamenetworkingui.proto +61 -61
  39. package/protos/csgo/steammessages_helprequest.steamworkssdk.proto +22 -22
  40. package/protos/csgo/steammessages_oauth.steamworkssdk.proto +18 -18
  41. package/protos/csgo/steammessages_player.steamworkssdk.proto +254 -254
  42. package/protos/csgo/steammessages_publishedfile.steamworkssdk.proto +233 -233
  43. package/protos/csgo/steamnetworkingsockets_messages.proto +205 -205
  44. package/protos/csgo/steamnetworkingsockets_messages_certs.proto +39 -39
  45. package/protos/csgo/steamnetworkingsockets_messages_udp.proto +75 -75
  46. package/protos/csgo/te.proto +259 -259
  47. package/protos/csgo/uifontfile_format.proto +13 -13
  48. package/protos/csgo/usercmd.proto +39 -39
  49. package/protos/csgo/usermessages.proto +752 -752
  50. package/protos/google/protobuf/descriptor.proto +281 -281
  51. package/protos/steam/clientmetrics.proto +45 -45
  52. package/protos/steam/content_manifest.proto +62 -62
  53. package/protos/steam/contenthubs.proto +41 -41
  54. package/protos/steam/encrypted_app_ticket.proto +10 -10
  55. package/protos/steam/enums.proto +501 -501
  56. package/protos/steam/enums_clientserver.proto +1508 -1508
  57. package/protos/steam/enums_productinfo.proto +14 -14
  58. package/protos/steam/htmlmessages.proto +1039 -1039
  59. package/protos/steam/offline_ticket.proto +8 -8
  60. package/protos/steam/steamdatagram_messages_auth.proto +65 -65
  61. package/protos/steam/steamdatagram_messages_sdr.proto +533 -533
  62. package/protos/steam/steammessages_accounthardware.steamclient.proto +167 -167
  63. package/protos/steam/steammessages_appoverview.proto +204 -204
  64. package/protos/steam/steammessages_auth.steamclient.proto +375 -375
  65. package/protos/steam/steammessages_broadcast.steamclient.proto +618 -618
  66. package/protos/steam/steammessages_chat.steamclient.proto +1070 -1070
  67. package/protos/steam/steammessages_client_objects.proto +649 -649
  68. package/protos/steam/steammessages_clientlanp2p.proto +43 -43
  69. package/protos/steam/steammessages_clientmetrics.steamclient.proto +192 -192
  70. package/protos/steam/steammessages_clientnotificationtypes.proto +250 -250
  71. package/protos/steam/steammessages_clientserver.proto +392 -392
  72. package/protos/steam/steammessages_clientserver_2.proto +771 -771
  73. package/protos/steam/steammessages_clientserver_appinfo.proto +131 -131
  74. package/protos/steam/steammessages_clientserver_friends.proto +260 -260
  75. package/protos/steam/steammessages_clientserver_gameservers.proto +159 -159
  76. package/protos/steam/steammessages_clientserver_lbs.proto +70 -70
  77. package/protos/steam/steammessages_clientserver_login.proto +167 -167
  78. package/protos/steam/steammessages_clientserver_mms.proto +233 -233
  79. package/protos/steam/steammessages_clientserver_ucm.proto +207 -207
  80. package/protos/steam/steammessages_clientserver_uds.proto +125 -125
  81. package/protos/steam/steammessages_clientserver_ufs.proto +45 -45
  82. package/protos/steam/steammessages_clientserver_userstats.proto +80 -80
  83. package/protos/steam/steammessages_cloud.steamclient.proto +422 -422
  84. package/protos/steam/steammessages_contentsystem.steamclient.proto +123 -123
  85. package/protos/steam/steammessages_credentials.steamclient.proto +96 -96
  86. package/protos/steam/steammessages_datapublisher.steamclient.proto +102 -102
  87. package/protos/steam/steammessages_depotbuilder.steamclient.proto +99 -99
  88. package/protos/steam/steammessages_deviceauth.steamclient.proto +169 -169
  89. package/protos/steam/steammessages_econ.steamclient.proto +137 -137
  90. package/protos/steam/steammessages_familygroups.steamclient.proto +441 -441
  91. package/protos/steam/steammessages_friendmessages.steamclient.proto +141 -141
  92. package/protos/steam/steammessages_gamenetworking.steamclient.proto +25 -25
  93. package/protos/steam/steammessages_gamenetworkingui.proto +61 -61
  94. package/protos/steam/steammessages_gamenotifications.steamclient.proto +131 -131
  95. package/protos/steam/steammessages_gameservers.steamclient.proto +136 -136
  96. package/protos/steam/steammessages_hiddevices.proto +157 -157
  97. package/protos/steam/steammessages_inventory.steamclient.proto +172 -172
  98. package/protos/steam/steammessages_linkfilter.steamclient.proto +39 -39
  99. package/protos/steam/steammessages_lobbymatchmaking.steamclient.proto +29 -29
  100. package/protos/steam/steammessages_market.steamclient.proto +22 -22
  101. package/protos/steam/steammessages_marketingmessages.steamclient.proto +273 -273
  102. package/protos/steam/steammessages_offline.steamclient.proto +33 -33
  103. package/protos/steam/steammessages_parental.steamclient.proto +262 -262
  104. package/protos/steam/steammessages_parties.steamclient.proto +75 -75
  105. package/protos/steam/steammessages_partnerapps.steamclient.proto +106 -106
  106. package/protos/steam/steammessages_player.steamclient.proto +915 -915
  107. package/protos/steam/steammessages_publishedfile.steamclient.proto +737 -737
  108. package/protos/steam/steammessages_qms.steamclient.proto +111 -111
  109. package/protos/steam/steammessages_remoteclient.proto +100 -100
  110. package/protos/steam/steammessages_remoteclient_discovery.proto +244 -244
  111. package/protos/steam/steammessages_remoteclient_service.steamclient.proto +31 -31
  112. package/protos/steam/steammessages_remoteclient_service_messages.proto +217 -217
  113. package/protos/steam/steammessages_remoteplay.proto +975 -975
  114. package/protos/steam/steammessages_secrets.steamclient.proto +35 -35
  115. package/protos/steam/steammessages_shader.steamclient.proto +89 -89
  116. package/protos/steam/steammessages_site_license.steamclient.proto +103 -103
  117. package/protos/steam/steammessages_sitelicenseclient.proto +38 -38
  118. package/protos/steam/steammessages_siteserverui.proto +130 -130
  119. package/protos/steam/steammessages_steamtv.steamclient.proto +533 -533
  120. package/protos/steam/steammessages_store.steamclient.proto +404 -404
  121. package/protos/steam/steammessages_storebrowse.steamclient.proto +457 -457
  122. package/protos/steam/steammessages_timedtrial.steamclient.proto +40 -40
  123. package/protos/steam/steammessages_twofactor.steamclient.proto +157 -157
  124. package/protos/steam/steammessages_unified_test.steamclient.proto +51 -51
  125. package/protos/steam/steammessages_useraccount.steamclient.proto +211 -211
  126. package/protos/steam/steammessages_vac.steamclient.proto +37 -37
  127. package/protos/steam/steammessages_video.steamclient.proto +68 -68
  128. package/protos/steam/steammessages_virtualcontroller.proto +138 -138
  129. package/protos/steam/steammessages_workshop.steamclient.proto +19 -19
  130. package/protos/steam/steamnetworkingsockets_messages.proto +205 -205
  131. package/protos/steam/steamnetworkingsockets_messages_certs.proto +39 -39
  132. package/protos/steam/steamnetworkingsockets_messages_udp.proto +75 -75
  133. package/protos/steam/webuimessages_achievements.proto +29 -29
  134. package/protos/steam/webuimessages_gamenotes.proto +21 -21
  135. package/protos/steam/webuimessages_gamescope.proto +57 -57
  136. package/protos/steam/webuimessages_steamengine.proto +41 -41
  137. package/protos/steam/webuimessages_steamos.proto +114 -114
  138. package/protos/steam/webuimessages_storagedevicemanager.proto +110 -110
  139. package/protos/steam/webuimessages_systemmanager.proto +17 -17
  140. package/protos/steam/webuimessages_transport.proto +22 -22
  141. package/protos/steam/webuimessages_transportvalidation.proto +111 -111
  142. package/protos/webui/common.proto +4024 -4024
  143. package/protos/webui/service_accountcart.proto +153 -153
  144. package/protos/webui/service_accountlinking.proto +27 -27
  145. package/protos/webui/service_accountprivacy.proto +42 -42
  146. package/protos/webui/service_accountprivateapps.proto +34 -34
  147. package/protos/webui/service_auction.proto +97 -97
  148. package/protos/webui/service_authentication.proto +222 -222
  149. package/protos/webui/service_authenticationsupport.proto +74 -74
  150. package/protos/webui/service_broadcast.proto +562 -562
  151. package/protos/webui/service_chat.proto +11 -11
  152. package/protos/webui/service_chatroom.proto +810 -810
  153. package/protos/webui/service_chatusability.proto +107 -107
  154. package/protos/webui/service_checkout.proto +84 -84
  155. package/protos/webui/service_clan.proto +41 -41
  156. package/protos/webui/service_clanchatrooms.proto +25 -25
  157. package/protos/webui/service_clanfaqs.proto +202 -202
  158. package/protos/webui/service_clientcomm.proto +151 -151
  159. package/protos/webui/service_clientmetrics.proto +22 -22
  160. package/protos/webui/service_cloud.proto +222 -222
  161. package/protos/webui/service_cloudconfigstore.proto +51 -51
  162. package/protos/webui/service_cloudgaming.proto +30 -30
  163. package/protos/webui/service_community.proto +365 -365
  164. package/protos/webui/service_dailydeal.proto +89 -89
  165. package/protos/webui/service_econ.proto +134 -134
  166. package/protos/webui/service_embedded.proto +24 -24
  167. package/protos/webui/service_experimentservice.proto +6 -6
  168. package/protos/webui/service_familygroups.proto +355 -355
  169. package/protos/webui/service_fovasvideo.proto +15 -15
  170. package/protos/webui/service_friendmessages.proto +133 -133
  171. package/protos/webui/service_friendslist.proto +70 -70
  172. package/protos/webui/service_gamenotes.proto +15 -15
  173. package/protos/webui/service_gamerecording.proto +265 -265
  174. package/protos/webui/service_gamerecordingclip.proto +85 -85
  175. package/protos/webui/service_gamerecordingdebug.proto +52 -52
  176. package/protos/webui/service_helprequestlogs.proto +16 -16
  177. package/protos/webui/service_loyaltyrewards.proto +252 -252
  178. package/protos/webui/service_marketingmessages.proto +215 -215
  179. package/protos/webui/service_mobileapp.proto +18 -18
  180. package/protos/webui/service_mobileauth.proto +24 -24
  181. package/protos/webui/service_mobiledevice.proto +26 -26
  182. package/protos/webui/service_mobileperaccount.proto +31 -31
  183. package/protos/webui/service_news.proto +110 -110
  184. package/protos/webui/service_parental.proto +258 -258
  185. package/protos/webui/service_partnermembershipinvite.proto +34 -34
  186. package/protos/webui/service_partnerstorebrowse.proto +28 -28
  187. package/protos/webui/service_phone.proto +51 -51
  188. package/protos/webui/service_physicalgoods.proto +15 -15
  189. package/protos/webui/service_player.proto +918 -918
  190. package/protos/webui/service_promotioneventinvites.proto +109 -109
  191. package/protos/webui/service_promotionplanning.proto +186 -186
  192. package/protos/webui/service_promotionstats.proto +23 -23
  193. package/protos/webui/service_publishedfile.proto +714 -714
  194. package/protos/webui/service_publishing.proto +200 -200
  195. package/protos/webui/service_quest.proto +127 -127
  196. package/protos/webui/service_salefeature.proto +373 -373
  197. package/protos/webui/service_saleitemrewards.proto +54 -54
  198. package/protos/webui/service_shoppingcart.proto +152 -152
  199. package/protos/webui/service_steamawards.proto +76 -76
  200. package/protos/webui/service_steamcharts.proto +75 -75
  201. package/protos/webui/service_steamengine.proto +36 -36
  202. package/protos/webui/service_steamlearn.proto +876 -876
  203. package/protos/webui/service_steamnotification.proto +73 -73
  204. package/protos/webui/service_steamtv.proto +495 -495
  205. package/protos/webui/service_steamvrvoicechat.proto +67 -67
  206. package/protos/webui/service_steamvrwebrtc.proto +48 -48
  207. package/protos/webui/service_storagedevicemanager.proto +104 -104
  208. package/protos/webui/service_store.proto +359 -359
  209. package/protos/webui/service_storeappsimilarity.proto +76 -76
  210. package/protos/webui/service_storebrowse.proto +103 -103
  211. package/protos/webui/service_storemarketing.proto +44 -44
  212. package/protos/webui/service_storequery.proto +103 -103
  213. package/protos/webui/service_storesales.proto +87 -87
  214. package/protos/webui/service_storetopsellers.proto +44 -44
  215. package/protos/webui/service_systemmanager.proto +11 -11
  216. package/protos/webui/service_test_transporterror.proto +6 -6
  217. package/protos/webui/service_transportauth.proto +17 -17
  218. package/protos/webui/service_transportvalidation.proto +69 -69
  219. package/protos/webui/service_twofactor.proto +170 -170
  220. package/protos/webui/service_useraccount.proto +142 -142
  221. package/protos/webui/service_usergameactivity.proto +34 -34
  222. package/protos/webui/service_usergamenotes.proto +70 -70
  223. package/protos/webui/service_usernews.proto +68 -68
  224. package/protos/webui/service_userreviews.proto +97 -97
  225. package/protos/webui/service_video.proto +50 -50
  226. package/protos/webui/service_videoclip.proto +62 -62
  227. package/protos/webui/service_voicechat.proto +139 -139
  228. package/protos/webui/service_webrtc.proto +52 -52
  229. package/remote.js +6784 -6784
  230. package/steamproto.js +34 -34
  231. package/utils.js +986 -986
  232. package/.idea/gbrowser_project.xml +0 -11
  233. package/.idea/git_toolbox_blame.xml +0 -6
  234. package/.idea/git_toolbox_prj.xml +0 -15
package/SteamClient.js CHANGED
@@ -90,11 +90,11 @@ export const SteamClientEvents = {
90
90
  accountLimitations: "accountLimitations",
91
91
  wallet: "wallet",
92
92
  licenses: "licenses",
93
+ logOff: "logOff",
93
94
  };
94
- const PersonasCache = [];
95
95
  let isSendingFriendMessages = false;
96
96
 
97
- function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestFreeLicense = true, isFakeGameScore = true, isPartyRegister = true, isAutoPlay = false, isInvisible = false, autoAcceptTradeRequest = false, autoReconnect = true, MAX_GAME_PLAY = 10, games = null }) {
97
+ function SteamClient({ username, cookie, clientJsToken, isAutoRequestFreeLicense = true, isFakeGameScore = true, isPartyRegister = true, isAutoPlay = false, isInvisible = false, autoAcceptTradeRequest = false, autoReconnect = true, games = null }) {
98
98
  const steamClient = new NodeSteamUser();
99
99
  let prime = null;
100
100
  let state = "Offline"; //InGame, Online, Invisible
@@ -104,7 +104,7 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
104
104
  let lastTimePartyRegister = 0;
105
105
  let lastTimePartySearch = 0;
106
106
  const ownedApps = [];
107
- let logOffEvent = null;
107
+ const logOffEvents = {};
108
108
  let _cleanNodeSteamUserTimeout = null;
109
109
  let _cleanNodeSteamLicensesTimeout = null;
110
110
  let _cleanNodeSteamFriendTimeout = null;
@@ -119,79 +119,191 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
119
119
 
120
120
  const onAnyCallbacks = [];
121
121
 
122
- const events = { ...SteamClientEvents };
122
+ /**
123
+ * @type {Object.<string, Array>}
124
+ * @property {Array} user
125
+ * @property {Array} loggedOn
126
+ * @property {Array} csgoOnline
127
+ * @property {Array} csgoClientHello
128
+ * @property {Array} webSession
129
+ * @property {Array} friendMessage
130
+ * @property {Array} friendTyping
131
+ * @property {Array} disconnected
132
+ * @property {Array} error
133
+ * @property {Array} playersProfile
134
+ * @property {Array} fatalError
135
+ * @property {Array} partyInvite
136
+ * @property {Array} friendRelationship
137
+ * @property {Array} tradeOffers
138
+ * @property {Array} offlineMessages
139
+ * @property {Array} friendsList
140
+ * @property {Array} gifts
141
+ * @property {Array} playingState
142
+ * @property {Array} emailInfo
143
+ * @property {Array} accountLimitations
144
+ * @property {Array} wallet
145
+ * @property {Array} licenses
146
+ * @property {Array} logOff
147
+ */
148
+ const events = {};
123
149
  for (const name in SteamClientEvents) {
124
150
  events[name] = [];
125
151
  }
126
152
 
127
- const gcCallback = {};
153
+ /**
154
+ * @typedef {Object} GCEvents
155
+ * @property {Array} requestJoinFriendData
156
+ * @property {Array} requestCoPlays
157
+ * @property {Array} partySearch
158
+ * @property {Array} playersProfile
159
+ *
160
+ * @type {GCEvents}
161
+ */
162
+ const gcEvents = {
163
+ requestJoinFriendData: [],
164
+ requestCoPlays: [],
165
+ partySearch: [],
166
+ playersProfile: [],
167
+ };
128
168
 
129
- function pushGCCallback(name, cb, timeout) {
130
- if (!gcCallback[name]) {
131
- gcCallback[name] = {};
169
+ function onGCEvent({ name, id, key, callback, timeoutMs }) {
170
+ if (typeof name !== "string") {
171
+ name = Object.keys(gcEvents).find((k) => gcEvents[k] === name);
132
172
  }
133
- let t = null;
134
- let id = uuidv4();
135
173
 
136
- function callback(...arg) {
137
- if (t) {
138
- clearTimeout(t);
139
- }
140
- delete gcCallback[name][id];
141
- cb?.apply(null, arg);
174
+ if (!gcEvents[name]) {
175
+ gcEvents[name] = [];
176
+ }
177
+ if (!id) {
178
+ id = uuidv4();
142
179
  }
180
+ const timeout = timeoutMs
181
+ ? setTimeout(function () {
182
+ callback?.();
183
+ clearGCCallback(id);
184
+ }, timeoutMs)
185
+ : null;
186
+
187
+ gcEvents[name].push({
188
+ id,
189
+ key,
190
+ timeout,
191
+ callback,
192
+ });
193
+ return id;
194
+ }
143
195
 
144
- if (timeout) {
145
- t = setTimeout(callback, timeout);
196
+ function clearGCCallback(name) {
197
+ for (const [eventName, events] of Object.entries(gcEvents)) {
198
+ if (eventName === name) {
199
+ for (const event of events) {
200
+ if (event.timeout) {
201
+ clearTimeout(event.timeout);
202
+ }
203
+ }
204
+ events.length = 0;
205
+ } else {
206
+ const removedEvents = _.remove(events, function (e) {
207
+ return Object.values(e).some((v) => v === name);
208
+ });
209
+ for (const removedEvent of removedEvents) {
210
+ if (removedEvent.timeout) {
211
+ clearTimeout(removedEvent.timeout);
212
+ }
213
+ }
214
+ }
146
215
  }
147
- gcCallback[name][id] = callback;
148
216
  }
149
217
 
150
- function callGCCallback(name, ...arg) {
151
- if (gcCallback[name]) {
152
- for (const id in gcCallback[name]) {
153
- gcCallback[name][id]?.(...arg);
218
+ async function callGCCallback({ name, data, key }) {
219
+ if (typeof name !== "string") {
220
+ name = Object.keys(gcEvents).find((k) => gcEvents[k] === name);
221
+ }
222
+
223
+ if (!Array.isArray(gcEvents[name])) {
224
+ return;
225
+ }
226
+
227
+ const removedEvents = _.remove(gcEvents[name], (item) => !key || item.key === key);
228
+ let _data = null;
229
+ let calculated = false;
230
+
231
+ for (const removedEvent of removedEvents) {
232
+ if (removedEvent.timeout) {
233
+ clearTimeout(removedEvent.timeout);
234
+ delete removedEvent.timeout;
235
+ }
236
+
237
+ if (!calculated) {
238
+ calculated = true;
239
+ _data = typeof data === "function" ? await data() : data;
154
240
  }
241
+
242
+ removedEvent.callback(_data);
155
243
  }
156
244
  }
157
245
 
158
- function callEvent(_events, data) {
159
- const eventName = Object.keys(events).find((eventName) => events[eventName] === _events);
160
- eventName && onAnyCallbacks.forEach((cb) => cb?.({ eventName, data }));
246
+ function callEvent(name, data) {
247
+ if (typeof name !== "string") {
248
+ name = Object.keys(events).find((eventName) => events[eventName] === name);
249
+ }
161
250
 
162
- _events?.forEach?.((e) => {
251
+ const _events = events[name];
252
+ onAnyCallbacks.forEach((cb) => cb?.({ eventName: name, data }));
253
+ _events.forEach((e) => {
254
+ clearTimeout(e.timeout);
163
255
  e.callback?.(data);
164
- e.timeout && clearTimeout(e.timeout);
165
- delete e.timeout;
166
- if (e.once) {
167
- delete e.callback;
168
- }
169
256
  });
170
- _.remove(_events, (e) => !e || e?.once);
257
+ _.remove(_events, (e) => !e || e.once);
171
258
  }
172
259
 
173
- function onEvent(name, callback, once, timeout) {
260
+ function onEvent({ name, id, callback, once, timeout }) {
174
261
  if (!events[name]) {
175
262
  events[name] = [];
176
263
  }
177
- const t = timeout ? setTimeout(callback, timeout) : null;
264
+ if (!id) {
265
+ id = uuidv4();
266
+ }
267
+ const t = timeout
268
+ ? setTimeout(function () {
269
+ try {
270
+ callback?.();
271
+ } catch (e) {}
272
+ if (once) {
273
+ offEvent(id);
274
+ }
275
+ }, timeout)
276
+ : null;
178
277
  events[name].push({
278
+ id,
179
279
  once,
180
280
  callback,
181
281
  timeout: t,
182
282
  });
283
+ return id;
183
284
  }
184
285
 
286
+ // name, id, callback
185
287
  function offEvent(name) {
186
- if (Array.isArray(events[name])) {
187
- for (const eventElement of events[name]) {
188
- if (eventElement.timeout) {
189
- clearTimeout(eventElement.timeout);
288
+ for (const [eventName, _events] of Object.entries(events)) {
289
+ if (eventName === name) {
290
+ for (const event of _events) {
291
+ if (event.timeout) {
292
+ clearTimeout(event.timeout);
293
+ }
294
+ }
295
+ _events.length = 0;
296
+ } else {
297
+ const removedEvents = _.remove(_events, function (e) {
298
+ return Object.values(e).some((v) => v === name);
299
+ });
300
+ for (const removedEvent of removedEvents) {
301
+ if (removedEvent.timeout) {
302
+ clearTimeout(removedEvent.timeout);
303
+ }
190
304
  }
191
305
  }
192
306
  }
193
-
194
- events[name] = [];
195
307
  }
196
308
 
197
309
  function onAnyEvent(callback) {
@@ -208,7 +320,7 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
208
320
  delete event.timeout;
209
321
  }
210
322
  }
211
- events[name] = [];
323
+ events[name].length = 0;
212
324
  }
213
325
  onAnyCallbacks.length = 0;
214
326
  }
@@ -289,7 +401,13 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
289
401
  console.log(`[${now}] [${getAccountInfoName()}]`, ...msg);
290
402
  }
291
403
 
404
+ function error(...msg) {
405
+ const now = moment().tz("Asia/Ho_Chi_Minh").format("DD/MM/YYYY HH:mm:ss");
406
+ console.error(`[${now}] [${getAccountInfoName()}]`, ...msg);
407
+ }
408
+
292
409
  async function getPersonas(steamIDs) {
410
+ if (isLogOff) return [];
293
411
  if (!steamIDs) return [];
294
412
  if (!Array.isArray(steamIDs)) {
295
413
  steamIDs = [steamIDs];
@@ -352,22 +470,28 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
352
470
  }
353
471
 
354
472
  async function getCookiesWait() {
473
+ if (isLogOff) {
474
+ return;
475
+ }
355
476
  return (
356
477
  getCookies() ||
357
478
  new Promise((resolve) => {
358
- onEvent(
359
- "webSession",
360
- function (webSession) {
479
+ onEvent({
480
+ name: "webSession",
481
+ callback: function (webSession) {
361
482
  resolve(webSession?.cookies);
362
483
  },
363
- true,
364
- 30000,
365
- );
484
+ once: true,
485
+ timeout: 30000,
486
+ });
366
487
  })
367
488
  );
368
489
  }
369
490
 
370
491
  async function gamePlay() {
492
+ if (isLogOff) {
493
+ return;
494
+ }
371
495
  return await gamesPlayed(730);
372
496
  }
373
497
 
@@ -383,9 +507,9 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
383
507
 
384
508
  async function updateAutoGamePlay() {
385
509
  if (isAutoPlay) {
386
- autoGamePlay();
510
+ await autoGamePlay();
387
511
  } else {
388
- offAutoGamePlay();
512
+ await offAutoGamePlay();
389
513
  }
390
514
  }
391
515
 
@@ -398,6 +522,9 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
398
522
  * @returns {Promise.<Array>}
399
523
  */
400
524
  async function partySearch({ prime = false, game_type = "Premier", rank, timeout = 5000 } = {}) {
525
+ if (isLogOff) {
526
+ return;
527
+ }
401
528
  const gameTypeMap = {
402
529
  Competitive: 8,
403
530
  Wingman: 10,
@@ -408,23 +535,33 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
408
535
  rank = parseInt(Object.keys(RANKS).find((k) => RANKS[k] === rank)) * 10;
409
536
  }
410
537
 
411
- const players = await new Promise((resolve) => {
412
- steamClient.sendToGC(
413
- AppID,
414
- ESteamProto.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Party_Search,
415
- {},
416
- new SteamProto(SteamProtoType.CMsgGCCStrike15_v2_Party_Search).protoEncode({
417
- ver: CSGO_VER,
418
- apr: prime ? 1 : 0,
419
- ark: rank,
420
- grps: [],
421
- launcher: 0, // If we are using the China CSGO launcher or not*
422
- game_type: gameTypeMap[game_type],
423
- }),
424
- );
425
- lastTimePartySearch = Date.now();
426
- pushGCCallback("partySearch", resolve, timeout);
427
- });
538
+ const gcEventId = uuidv4();
539
+ const players = await ensureLogin(
540
+ new Promise((resolve) => {
541
+ lastTimePartySearch = Date.now();
542
+ onGCEvent({
543
+ name: gcEvents.partySearch,
544
+ id: gcEventId,
545
+ callback: resolve,
546
+ timeoutMs: timeout,
547
+ });
548
+ steamClient.sendToGC(
549
+ AppID,
550
+ ESteamProto.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Party_Search,
551
+ {},
552
+ new SteamProto(SteamProtoType.CMsgGCCStrike15_v2_Party_Search).protoEncode({
553
+ ver: CSGO_VER,
554
+ apr: prime ? 1 : 0,
555
+ ark: rank,
556
+ grps: [],
557
+ launcher: 0, // If we are using the China CSGO launcher or not*
558
+ game_type: gameTypeMap[game_type],
559
+ }),
560
+ );
561
+ }),
562
+ );
563
+ clearGCCallback(gcEventId);
564
+
428
565
  if (Array.isArray(players) && players.length) {
429
566
  const personas = await getPersonas(players.map((p) => p.steamId));
430
567
  for (const player of players) {
@@ -434,11 +571,14 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
434
571
  player.avatar_hash = persona.avatar_hash;
435
572
  }
436
573
  }
574
+ return players;
437
575
  }
438
- return players;
439
576
  }
440
577
 
441
578
  async function createLobby() {
579
+ if (isLogOff) {
580
+ return;
581
+ }
442
582
  if (!steamClient.steamID) {
443
583
  return;
444
584
  }
@@ -490,6 +630,9 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
490
630
  }
491
631
 
492
632
  async function updateLobby(lobbyID) {
633
+ if (isLogOff) {
634
+ return;
635
+ }
493
636
  if (!steamClient.steamID) {
494
637
  return;
495
638
  }
@@ -553,6 +696,9 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
553
696
  }
554
697
 
555
698
  async function invite2Lobby(lobbyID, steamId) {
699
+ if (isLogOff) {
700
+ return;
701
+ }
556
702
  if (!steamClient.steamID) {
557
703
  return;
558
704
  }
@@ -586,6 +732,9 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
586
732
  }
587
733
 
588
734
  async function createThenInvite2Lobby(steamIds, onInvite) {
735
+ if (isLogOff) {
736
+ return;
737
+ }
589
738
  if (!steamClient.steamID) {
590
739
  return;
591
740
  }
@@ -612,6 +761,9 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
612
761
  }
613
762
 
614
763
  async function getLobbyData(lobbyID) {
764
+ if (isLogOff) {
765
+ return;
766
+ }
615
767
  if (!steamClient.steamID) {
616
768
  return;
617
769
  }
@@ -644,6 +796,9 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
644
796
  }
645
797
 
646
798
  async function joinLobby(lobbyID) {
799
+ if (isLogOff) {
800
+ return;
801
+ }
647
802
  log("joinLobby", lobbyID); //SteamID.fromIndividualAccountID(lobbyId).accountid
648
803
 
649
804
  steamClient._send(
@@ -680,6 +835,9 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
680
835
  }
681
836
 
682
837
  async function sendHello() {
838
+ if (isLogOff) {
839
+ return;
840
+ }
683
841
  steamClient.sendToGC(AppID, ESteamProto.ECsgoGCMsg.k_EMsgGCCStrike15_v2_MatchmakingClient2GCHello, {}, Buffer.alloc(0));
684
842
  // steamClient.sendToGC(AppID, ESteamProto.EGCBaseClientMsg.k_EMsgGCClientHello, {}, Buffer.alloc(0));
685
843
 
@@ -697,10 +855,23 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
697
855
  }
698
856
 
699
857
  async function requestCoPlays() {
700
- return new Promise((resolve) => {
701
- steamClient.sendToGC(AppID, ESteamProto.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Account_RequestCoPlays, {}, Buffer.alloc(0));
702
- pushGCCallback("RequestCoPlays", resolve, 30000);
703
- });
858
+ if (isLogOff) {
859
+ return;
860
+ }
861
+ const gcEventId = uuidv4();
862
+ const response = await ensureLogin(
863
+ new Promise((resolve) => {
864
+ onGCEvent({
865
+ name: gcEvents.requestCoPlays,
866
+ id: gcEventId,
867
+ callback: resolve,
868
+ timeoutMs: 30000,
869
+ });
870
+ steamClient.sendToGC(AppID, ESteamProto.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Account_RequestCoPlays, {}, Buffer.alloc(0));
871
+ }),
872
+ );
873
+ clearGCCallback(gcEventId);
874
+ return response;
704
875
  }
705
876
 
706
877
  function bindEvent() {
@@ -712,62 +883,7 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
712
883
  callEvent(events.disconnected, { eresult, msg });
713
884
 
714
885
  if (["ServiceUnavailable", "NoConnection"].includes(msg) && autoReconnect && !isLogOff) {
715
- async function relogin(retry) {
716
- if (isLogOff) {
717
- console.error("Cannot relogin (logoff)");
718
- return false;
719
- } else if (retry <= 0) {
720
- console.error("Cannot relogin");
721
- return false;
722
- } else {
723
- const isSuccess = await login(true);
724
- if (isSuccess) {
725
- const loggedOnResponse = await new Promise((resolve) => {
726
- onEvent(SteamClientEvents.loggedOn, resolve, true, 180000);
727
- });
728
- if (loggedOnResponse) {
729
- console.log("Relogin success");
730
- return true;
731
- } else {
732
- const isLogOff = await new Promise((resolve, reject) => {
733
- logOffEvent = resolve;
734
- setTimeout(resolve, 120000);
735
- });
736
- logOffEvent = null;
737
- if (isLogOff === true) {
738
- return false;
739
- }
740
- return await relogin(retry - 1);
741
- }
742
- } else {
743
- const isLogOff = await new Promise((resolve, reject) => {
744
- logOffEvent = resolve;
745
- setTimeout(resolve, 120000);
746
- });
747
- logOffEvent = null;
748
- if (isLogOff === true) {
749
- return false;
750
- }
751
- return await relogin(retry - 1);
752
- }
753
- }
754
- }
755
-
756
- const isLogOff = await new Promise((resolve, reject) => {
757
- logOffEvent = resolve;
758
- setTimeout(resolve, 60000);
759
- });
760
- logOffEvent = null;
761
- if (isLogOff === true) {
762
- offAllEvent();
763
- doClearIntervals();
764
- } else {
765
- const isSuccess = await relogin(50);
766
- if (!isSuccess) {
767
- offAllEvent();
768
- doClearIntervals();
769
- }
770
- }
886
+ reLogin();
771
887
  } else {
772
888
  offAllEvent();
773
889
  doClearIntervals();
@@ -802,7 +918,7 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
802
918
  steamClient.webSession = webSession;
803
919
  callEvent(events.webSession, webSession);
804
920
  },
805
- async receivedFromGC(appid, msgType, payload) {
921
+ receivedFromGC: async function (appid, msgType, payload) {
806
922
  const key = getECsgoGCMsgKey(msgType);
807
923
  switch (msgType) {
808
924
  case ESteamProto.EMsg.k_EMsgClientChatInvite: {
@@ -830,9 +946,13 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
830
946
  break;
831
947
  }
832
948
  case ESteamProto.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Account_RequestCoPlays: {
833
- const msg = new SteamProto(SteamProtoType.CMsgGCCStrike15_v2_Account_RequestCoPlays).protoDecode(payload);
834
- const personas = msg.players.map((p) => SteamID.fromIndividualAccountID(p.accountid));
835
- callGCCallback("RequestCoPlays", personas);
949
+ callGCCallback({
950
+ name: gcEvents.requestCoPlays,
951
+ data() {
952
+ const msg = new SteamProto(SteamProtoType.CMsgGCCStrike15_v2_Account_RequestCoPlays).protoDecode(payload);
953
+ return msg.players.map((p) => SteamID.fromIndividualAccountID(p.accountid));
954
+ },
955
+ });
836
956
  break;
837
957
  }
838
958
  case ESteamProto.EGCBaseClientMsg.k_EMsgGCClientWelcome: {
@@ -1127,79 +1247,83 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
1127
1247
  break;
1128
1248
  }
1129
1249
  case ESteamProto.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Party_Search: {
1130
- const result = new SteamProto(SteamProtoType.CMsgGCCStrike15_v2_Party_SearchResults).protoDecode(payload);
1131
- const entries = _.uniqBy(result.entries, "id");
1132
- //{
1133
- // id: 144900402,
1134
- // grp: 0,
1135
- // game_type: 8,
1136
- // apr: 1,
1137
- // ark: 17,
1138
- // loc: 20041,
1139
- // accountid: 0
1140
- // }
1141
-
1142
- //{
1143
- // id: "76561199265943339",
1144
- // rich_presence: [],
1145
- // persona_state: null,
1146
- // game_played_app_id: null,
1147
- // game_server_ip: null,
1148
- // game_server_port: null,
1149
- // persona_state_flags: null,
1150
- // online_session_instances: null,
1151
- // persona_set_by_user: null,
1152
- // player_name: "杀人不见血",
1153
- // query_port: null,
1154
- // steamid_source: null,
1155
- // avatar_hash: "33994e26f1fe7e2093f8c7dee66c1ac91531050d",
1156
- // last_logoff: null,
1157
- // last_logon: null,
1158
- // last_seen_online: null,
1159
- // clan_rank: null,
1160
- // game_name: null,
1161
- // gameid: null,
1162
- // game_data_blob: null,
1163
- // clan_data: null,
1164
- // clan_tag: null,
1165
- // broadcast_id: null,
1166
- // game_lobby_id: null,
1167
- // watching_broadcast_accountid: null,
1168
- // watching_broadcast_appid: null,
1169
- // watching_broadcast_viewers: null,
1170
- // watching_broadcast_title: null,
1171
- // is_community_banned: null,
1172
- // player_name_pending_review: null,
1173
- // avatar_pending_review: null,
1174
- // avatar_url_icon: "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/33/33994e26f1fe7e2093f8c7dee66c1ac91531050d.jpg",
1175
- // avatar_url_medium: "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/33/33994e26f1fe7e2093f8c7dee66c1ac91531050d_medium.jpg",
1176
- // avatar_url_full: "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/33/33994e26f1fe7e2093f8c7dee66c1ac91531050d_full.jpg"
1177
- // }
1178
-
1179
- const players = [];
1180
- if (entries.length) {
1181
- const FriendCode = (await import("csgo-friendcode")).default;
1182
- for (const player of entries) {
1183
- try {
1184
- const prime = player.apr === 1 ? "PRIME" : "NON-PRIME";
1185
- const loc = LOCS[player.loc] || player.loc;
1186
- const steamId = SteamID.fromIndividualAccountID(player.id).getSteamID64();
1187
- const friendCode = FriendCode.encode(steamId);
1188
-
1189
- // if ((LOCS[player.loc] == 'VN' || !LOCS[player.loc])) {
1190
- players.push({
1191
- prime,
1192
- rank: RANKS[player.ark] !== undefined ? RANKS[player.ark] : player.ark,
1193
- loc,
1194
- steamId,
1195
- friendCode,
1196
- });
1197
- // }
1198
- } catch (e) {}
1199
- }
1200
- }
1201
-
1202
- callGCCallback("partySearch", players);
1250
+ callGCCallback({
1251
+ name: gcEvents.partySearch,
1252
+ async data() {
1253
+ const result = new SteamProto(SteamProtoType.CMsgGCCStrike15_v2_Party_SearchResults).protoDecode(payload);
1254
+ const entries = _.uniqBy(result.entries, "id");
1255
+ //{
1256
+ // id: 144900402,
1257
+ // grp: 0,
1258
+ // game_type: 8,
1259
+ // apr: 1,
1260
+ // ark: 17,
1261
+ // loc: 20041,
1262
+ // accountid: 0
1263
+ // }
1264
+
1265
+ //{
1266
+ // id: "76561199265943339",
1267
+ // rich_presence: [],
1268
+ // persona_state: null,
1269
+ // game_played_app_id: null,
1270
+ // game_server_ip: null,
1271
+ // game_server_port: null,
1272
+ // persona_state_flags: null,
1273
+ // online_session_instances: null,
1274
+ // persona_set_by_user: null,
1275
+ // player_name: "杀人不见血",
1276
+ // query_port: null,
1277
+ // steamid_source: null,
1278
+ // avatar_hash: "33994e26f1fe7e2093f8c7dee66c1ac91531050d",
1279
+ // last_logoff: null,
1280
+ // last_logon: null,
1281
+ // last_seen_online: null,
1282
+ // clan_rank: null,
1283
+ // game_name: null,
1284
+ // gameid: null,
1285
+ // game_data_blob: null,
1286
+ // clan_data: null,
1287
+ // clan_tag: null,
1288
+ // broadcast_id: null,
1289
+ // game_lobby_id: null,
1290
+ // watching_broadcast_accountid: null,
1291
+ // watching_broadcast_appid: null,
1292
+ // watching_broadcast_viewers: null,
1293
+ // watching_broadcast_title: null,
1294
+ // is_community_banned: null,
1295
+ // player_name_pending_review: null,
1296
+ // avatar_pending_review: null,
1297
+ // avatar_url_icon: "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/33/33994e26f1fe7e2093f8c7dee66c1ac91531050d.jpg",
1298
+ // avatar_url_medium: "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/33/33994e26f1fe7e2093f8c7dee66c1ac91531050d_medium.jpg",
1299
+ // avatar_url_full: "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/33/33994e26f1fe7e2093f8c7dee66c1ac91531050d_full.jpg"
1300
+ // }
1301
+
1302
+ const players = [];
1303
+ if (entries.length) {
1304
+ const FriendCode = (await import("csgo-friendcode")).default;
1305
+ for (const player of entries) {
1306
+ try {
1307
+ const prime = player.apr === 1 ? "PRIME" : "NON-PRIME";
1308
+ const loc = LOCS[player.loc] || player.loc;
1309
+ const steamId = SteamID.fromIndividualAccountID(player.id).getSteamID64();
1310
+ const friendCode = FriendCode.encode(steamId);
1311
+
1312
+ // if ((LOCS[player.loc] == 'VN' || !LOCS[player.loc])) {
1313
+ players.push({
1314
+ prime,
1315
+ rank: RANKS[player.ark] !== undefined ? RANKS[player.ark] : player.ark,
1316
+ loc,
1317
+ steamId,
1318
+ friendCode,
1319
+ });
1320
+ // }
1321
+ } catch (e) {}
1322
+ }
1323
+ }
1324
+ return players;
1325
+ },
1326
+ });
1203
1327
  break;
1204
1328
  }
1205
1329
  case ESteamProto.ECsgoGCMsg.k_EMsgGCCStrike15_v2_PlayersProfile: {
@@ -1270,7 +1394,11 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
1270
1394
  player.elo = ranking.rank_id;
1271
1395
  }
1272
1396
  }
1273
- callGCCallback(`PlayersProfile_${player.account_id}`, player);
1397
+ callGCCallback({
1398
+ name: gcEvents.playersProfile,
1399
+ data: player,
1400
+ key: player.account_id,
1401
+ });
1274
1402
  }
1275
1403
  callEvent(events.playersProfile, player);
1276
1404
  break;
@@ -1298,7 +1426,11 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
1298
1426
  res: null,
1299
1427
  errormsg: "Game is full",
1300
1428
  };
1301
- callGCCallback(`requestJoinFriendData_${data.account_id}`, data);
1429
+ callGCCallback({
1430
+ name: gcEvents.requestJoinFriendData,
1431
+ data,
1432
+ key: data.account_id,
1433
+ });
1302
1434
  break;
1303
1435
  }
1304
1436
  default:
@@ -1316,6 +1448,36 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
1316
1448
  }
1317
1449
  },
1318
1450
  async loggedOn(loggedOnResponse) {
1451
+ const example = {
1452
+ eresult: 1,
1453
+ legacy_out_of_game_heartbeat_seconds: 9,
1454
+ heartbeat_seconds: 9,
1455
+ deprecated_public_ip: 250140346,
1456
+ rtime32_server_time: 1727758337,
1457
+ account_flags: 2642053,
1458
+ cell_id: 71,
1459
+ email_domain: null,
1460
+ steam2_ticket: null,
1461
+ eresult_extended: null,
1462
+ webapi_authenticate_user_nonce: null,
1463
+ cell_id_ping_threshold: 2147483647,
1464
+ deprecated_use_pics: null,
1465
+ vanity_url: "",
1466
+ public_ip: {
1467
+ v4: 250140346,
1468
+ },
1469
+ client_supplied_steamid: "76561190347696",
1470
+ ip_country_code: "VN",
1471
+ parental_settings: null,
1472
+ parental_setting_signature: null,
1473
+ count_loginfailures_to_migrate: 0,
1474
+ count_disconnects_to_migrate: 0,
1475
+ ogs_data_report_time_window: null,
1476
+ client_instance_id: "4130450042302948",
1477
+ force_client_update_check: false,
1478
+ agreement_session_url: null,
1479
+ token_id: null,
1480
+ };
1319
1481
  callEvent(events.loggedOn, loggedOnResponse);
1320
1482
  updateInvisible();
1321
1483
  updateAutoRequestFreeLicense();
@@ -1657,29 +1819,49 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
1657
1819
  }
1658
1820
 
1659
1821
  function sendFriendTyping(steamId, callback) {
1822
+ if (isLogOff) {
1823
+ return;
1824
+ }
1660
1825
  steamClient.chat.sendFriendTyping(steamId, callback);
1661
1826
  }
1662
1827
 
1663
1828
  /*
1664
1829
  * usually take 400 -> 800 miliseconds
1665
1830
  * */
1666
- function getPlayersProfile(steamId) {
1831
+ async function getPlayersProfile(steamId) {
1832
+ if (isLogOff) {
1833
+ return;
1834
+ }
1667
1835
  const accountid = new SteamID(steamId).accountid;
1668
- steamClient.sendToGC(
1669
- 730,
1670
- ESteamProto.ECsgoGCMsg.k_EMsgGCCStrike15_v2_ClientRequestPlayersProfile,
1671
- {},
1672
- new SteamProto(SteamProtoType.CMsgGCCStrike15_v2_ClientRequestPlayersProfile).protoEncode({
1673
- account_id: accountid, // account_id: new SteamID('76561199184696945').accountid,
1674
- request_level: 32,
1836
+ const gcEventId = uuidv4();
1837
+ const result = await ensureLogin(
1838
+ new Promise((resolve) => {
1839
+ onGCEvent({
1840
+ name: gcEvents.playersProfile,
1841
+ key: accountid,
1842
+ id: gcEventId,
1843
+ callback: resolve,
1844
+ timeoutMs: 5000,
1845
+ });
1846
+ steamClient.sendToGC(
1847
+ 730,
1848
+ ESteamProto.ECsgoGCMsg.k_EMsgGCCStrike15_v2_ClientRequestPlayersProfile,
1849
+ {},
1850
+ new SteamProto(SteamProtoType.CMsgGCCStrike15_v2_ClientRequestPlayersProfile).protoEncode({
1851
+ account_id: accountid, // account_id: new SteamID('76561199184696945').accountid,
1852
+ request_level: 32,
1853
+ }),
1854
+ );
1675
1855
  }),
1676
1856
  );
1677
- return new Promise((resolve) => {
1678
- pushGCCallback(`PlayersProfile_${accountid}`, resolve, 2000);
1679
- });
1857
+ clearGCCallback(gcEventId);
1858
+ return result;
1680
1859
  }
1681
1860
 
1682
1861
  async function checkPlayerPrimeStatus(steamId) {
1862
+ if (isLogOff) {
1863
+ return;
1864
+ }
1683
1865
  const profile = await getPlayersProfile(steamId);
1684
1866
  if (!profile) return false;
1685
1867
 
@@ -1783,23 +1965,114 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
1783
1965
  }
1784
1966
  }
1785
1967
 
1786
- async function login(reconnect = false) {
1787
- function logOn(clientJsToken) {
1788
- try {
1789
- steamClient.logOn({
1790
- ...clientJsToken,
1791
- steamId: new SteamID(clientJsToken.steamid),
1792
- steamID: new SteamID(clientJsToken.steamid),
1793
- accountName: clientJsToken.account_name,
1794
- webLogonToken: clientJsToken.token,
1795
- });
1796
- return true;
1797
- } catch (e) {
1798
- console.error(e);
1799
- return false;
1800
- }
1968
+ /**
1969
+ * Logs on to the Steam client using the provided token.
1970
+ *
1971
+ * @async
1972
+ * @function logOn
1973
+ *
1974
+ * @param {Object} [token] - The token object containing credentials and other information. Defaults to a pre-filled sample token.
1975
+ * @param {boolean} [token.logged_in=true] - Indicates whether the user is logged in.
1976
+ * @param {string} [token.steamid="76561199027696"] - The user's SteamID in string format.
1977
+ * @param {number} [token.accountid=10671968] - The user's account ID.
1978
+ * @param {string} [token.account_name="helloword"] - The user's account name.
1979
+ * @param {string} [token.accountName="helloword"] - The user's account name (duplicate).
1980
+ * @param {boolean} [token.is_support=false] - Whether the user is a support member.
1981
+ * @param {boolean} [token.is_limited=true] - Indicates if the user's account is limited.
1982
+ * @param {boolean} [token.is_partner_member=false] - Whether the user is a partner member.
1983
+ * @param {string} [token.country_code="CN"] - The user's country code.
1984
+ * @param {string} [token.token="AAAAAAAAAAAAAAA"] - The web logon token.
1985
+ * @param {string} [token.webLogonToken="AAAAAAAAAAAAAAA"] - The web logon token (duplicate).
1986
+ * @param {string} [token.token_use_id="e6a33a62c1d403b71761301c"] - The token use ID.
1987
+ * @param {Object} [token.steamId] - SteamID details.
1988
+ * @param {Object} [token.steamID] - Duplicate SteamID object (legacy support).
1989
+ *
1990
+ * @returns {Promise<boolean>} Resolves to `true` if login is successful, `false` otherwise.
1991
+ *
1992
+ * @throws Will log an error to the console if the login fails.
1993
+ */
1994
+ async function logOn(token) {
1995
+ try {
1996
+ isLogOff = false;
1997
+ steamClient.logOn({
1998
+ ...token,
1999
+ steamId: new SteamID(token.steamid),
2000
+ steamID: new SteamID(token.steamid),
2001
+ accountName: token.account_name,
2002
+ webLogonToken: token.token,
2003
+ });
2004
+ let timeout = null;
2005
+ const eventIds = [];
2006
+ const loggedOnResponse = await Promise.race([
2007
+ new Promise((resolve) => {
2008
+ timeout = setTimeout(function () {
2009
+ resolve();
2010
+ }, 180000);
2011
+ }),
2012
+ new Promise((resolve) => {
2013
+ eventIds.push(
2014
+ onEvent({
2015
+ name: SteamClientEvents.loggedOn,
2016
+ callback: resolve,
2017
+ once: true,
2018
+ }),
2019
+ onEvent({
2020
+ name: SteamClientEvents.logOff,
2021
+ callback: function () {
2022
+ resolve();
2023
+ },
2024
+ once: true,
2025
+ }),
2026
+ onEvent({
2027
+ name: SteamClientEvents.error,
2028
+ callback: function () {
2029
+ resolve();
2030
+ },
2031
+ once: true,
2032
+ }),
2033
+ );
2034
+ }),
2035
+ ]);
2036
+ clearTimeout(timeout);
2037
+ offEvent(eventIds);
2038
+ return loggedOnResponse?.eresult === 1;
2039
+ } catch (e) {
2040
+ console.error("logOn", e);
2041
+ return false;
2042
+ }
2043
+ }
2044
+
2045
+ async function reLogin(retry = 50) {
2046
+ if (isLogOff || retry <= 0) {
2047
+ offAllEvent();
2048
+ doClearIntervals();
2049
+
2050
+ error(`Cannot relogin (${isLogOff ? "logoff" : "retry limit reached"})`);
2051
+ return false;
2052
+ }
2053
+
2054
+ const isSuccess = await login(true);
2055
+ if (isSuccess) {
2056
+ log("Relogin success");
2057
+ return true;
2058
+ }
2059
+
2060
+ if (isLogOff) {
2061
+ offAllEvent();
2062
+ doClearIntervals();
2063
+ error(`Cannot relogin (${isLogOff ? "logoff" : "retry limit reached"})`);
2064
+ return false;
1801
2065
  }
1802
2066
 
2067
+ if (retry > 1) {
2068
+ await sleep(60000);
2069
+ return await reLogin(retry - 1);
2070
+ } else {
2071
+ return false;
2072
+ }
2073
+ }
2074
+
2075
+ async function login(reconnect = false) {
1803
2076
  if (clientJsToken?.logged_in === true) {
1804
2077
  log(`[${clientJsToken.steamid}] ${reconnect ? "reconnect with clientJsToken" : "login with clientJsToken"}`);
1805
2078
  setTimeout(function () {
@@ -1814,27 +2087,36 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
1814
2087
  return logOn(_clientJsToken);
1815
2088
  } else {
1816
2089
  log(`Account not logged in ${clientJsToken?.account_name || steamUser.getSteamIdUser() || ""}`);
1817
- console.log(clientJsToken);
1818
- return false;
1819
2090
  }
1820
- } else if (username && password) {
1821
- log(reconnect ? `reconnect with username ${username}` : `login with username ${username}`);
1822
- steamClient.logOn({
1823
- accountName: username,
1824
- password: password,
1825
- rememberPassword: true,
1826
- machineName: "Natri",
1827
- });
1828
- return true;
1829
2091
  } else {
1830
2092
  log(`Account not logged in ${clientJsToken?.account_name || ""}`);
1831
2093
  return false;
1832
2094
  }
1833
2095
  }
1834
2096
 
1835
- function logOff() {
2097
+ function clearLogOffEvent(id) {
2098
+ if (typeof id === "string") {
2099
+ delete logOffEvents[id];
2100
+ return id;
2101
+ } else if (typeof id === "function") {
2102
+ for (const idKey in logOffEvents) {
2103
+ if (logOffEvents[idKey] === id) {
2104
+ delete logOffEvents[idKey];
2105
+ return idKey;
2106
+ }
2107
+ }
2108
+ }
2109
+ }
2110
+
2111
+ async function logOff() {
2112
+ log("logOff");
1836
2113
  isLogOff = true;
1837
- logOffEvent?.(true);
2114
+
2115
+ MessageQueue.length = 0;
2116
+
2117
+ callEvent(events.logOff);
2118
+ events.logOff = [];
2119
+
1838
2120
  if (_cleanNodeSteamUserTimeout) {
1839
2121
  clearTimeout(_cleanNodeSteamUserTimeout);
1840
2122
  }
@@ -1849,25 +2131,44 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
1849
2131
  steamClient.licenses = [];
1850
2132
 
1851
2133
  steamClient.logOff();
1852
- }
1853
-
1854
- function onCookie(callback) {
1855
- if (getCookies()) {
1856
- callback(getCookies());
1857
- } else {
1858
- onEvent(
1859
- "webSession",
1860
- function (webSession) {
1861
- callback(webSession?.cookies?.join?.(";"));
1862
- },
1863
- true,
1864
- );
2134
+ await sleep(5000);
2135
+ delete steamClient._logOnDetails;
2136
+ delete steamClient.logOnResult;
2137
+ delete steamClient._httpClient;
2138
+ delete steamClient._lastChosenCM;
2139
+ steamClient._connection.end(true);
2140
+
2141
+ for (const connKey in steamClient._connection) {
2142
+ delete steamClient._connection[connKey];
2143
+ }
2144
+ delete steamClient._connection;
2145
+ delete steamClient.accountInfo;
2146
+ delete steamClient.emailInfo;
2147
+ delete steamClient.limitations;
2148
+ delete steamClient.vac;
2149
+ delete steamClient.wallet;
2150
+ delete steamClient.licenses;
2151
+ delete steamClient.gifts;
2152
+ delete steamClient.myGroups;
2153
+ delete steamClient.playingState;
2154
+
2155
+ delete steamClient._heartbeatInterval;
2156
+ delete steamClient.chat;
2157
+ delete steamClient._httpClient;
2158
+ delete steamClient._events;
2159
+ delete steamClient.picsCache;
2160
+ delete steamClient.options;
2161
+
2162
+ for (const key in steamClient) {
2163
+ delete steamClient[key];
1865
2164
  }
1866
2165
  }
1867
2166
 
1868
2167
  async function init() {
2168
+ isLogOff = false;
1869
2169
  bindEvent();
1870
- if (await login()) {
2170
+ const logged = await login();
2171
+ if (logged) {
1871
2172
  steamClient._handlerManager.add(ESteamProto.EMsg.k_EMsgClientRequestedClientStats, function (payload) {
1872
2173
  const result = new SteamProto(SteamProtoType.CMsgClientRequestedClientStats).protoDecode(payload.toBuffer());
1873
2174
  // console.log("CMsgClientRequestedClientStats", result);
@@ -1880,6 +2181,9 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
1880
2181
  }
1881
2182
 
1882
2183
  function partyRegister() {
2184
+ if (isLogOff) {
2185
+ return;
2186
+ }
1883
2187
  if (prime === null) {
1884
2188
  _partyRegister(true);
1885
2189
  _partyRegister(false);
@@ -1889,6 +2193,10 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
1889
2193
  }
1890
2194
 
1891
2195
  function _partyRegister(prime) {
2196
+ if (isLogOff) {
2197
+ return;
2198
+ }
2199
+
1892
2200
  log("partyRegister", prime);
1893
2201
  lastTimePartyRegister = Date.now();
1894
2202
  steamClient.sendToGC(
@@ -1910,6 +2218,10 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
1910
2218
  const MessageQueue = [];
1911
2219
 
1912
2220
  async function _execMessageQueue() {
2221
+ if (isLogOff) {
2222
+ return;
2223
+ }
2224
+
1913
2225
  if (isSendingFriendMessages) {
1914
2226
  return;
1915
2227
  }
@@ -1928,6 +2240,9 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
1928
2240
  async function _sendFriendMessage(steamId, message) {
1929
2241
  let result = null;
1930
2242
  for (let i = 0; i < 10; i++) {
2243
+ if (isLogOff) {
2244
+ return;
2245
+ }
1931
2246
  result = await new Promise((resolve) => {
1932
2247
  steamClient.chat.sendFriendMessage(steamId, message, undefined, function (...arg) {
1933
2248
  resolve(arg);
@@ -1945,6 +2260,9 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
1945
2260
  }
1946
2261
 
1947
2262
  async function sendFriendMessage(steamId, message) {
2263
+ if (isLogOff) {
2264
+ return;
2265
+ }
1948
2266
  return new Promise((resolve) => {
1949
2267
  MessageQueue.push({ steamId, message, callback: resolve });
1950
2268
  _execMessageQueue();
@@ -1998,44 +2316,61 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
1998
2316
  isInvisible = false;
1999
2317
  isAutoPlay = true;
2000
2318
  isPartyRegister = false;
2001
- const online = await new Promise((resolve) => {
2002
- const timeout = setTimeout(function () {
2003
- resolve(false);
2004
- }, 60000);
2005
2319
 
2006
- onEvent(
2007
- SteamClientEvents.csgoOnline,
2008
- function () {
2009
- clearTimeout(timeout);
2010
- resolve(true);
2011
- },
2012
- true,
2013
- );
2014
- onEvent(
2015
- SteamClientEvents.error,
2016
- function () {
2017
- clearTimeout(timeout);
2018
- resolve(false);
2019
- },
2020
- true,
2021
- );
2022
- onEvent(
2023
- SteamClientEvents.playingState,
2024
- function ({ playing_blocked, playing_app }) {
2025
- if (playing_blocked) {
2026
- clearTimeout(timeout);
2027
- resolve(false);
2028
- }
2029
- },
2030
- true,
2031
- );
2032
- init();
2033
- });
2034
- offAllEvent();
2320
+ let timeout = null;
2321
+ const eventIds = [];
2322
+
2323
+ const online = await Promise.race([
2324
+ new Promise((resolve) => {
2325
+ setTimeout(function () {
2326
+ resolve();
2327
+ }, 60000);
2328
+ }),
2329
+ new Promise((resolve) => {
2330
+ eventIds.push(
2331
+ onEvent({
2332
+ name: SteamClientEvents.logOff,
2333
+ callback: function () {
2334
+ resolve(false);
2335
+ },
2336
+ once: true,
2337
+ }),
2338
+ onEvent({
2339
+ name: SteamClientEvents.csgoOnline,
2340
+ callback: function () {
2341
+ resolve(true);
2342
+ },
2343
+ once: true,
2344
+ }),
2345
+ onEvent({
2346
+ name: SteamClientEvents.error,
2347
+ callback: function () {
2348
+ resolve(false);
2349
+ },
2350
+ once: true,
2351
+ }),
2352
+ onEvent({
2353
+ name: SteamClientEvents.playingState,
2354
+ callback: function ({ playing_blocked }) {
2355
+ if (playing_blocked) {
2356
+ resolve(false);
2357
+ }
2358
+ },
2359
+ }),
2360
+ );
2361
+ init();
2362
+ }),
2363
+ ]);
2364
+
2365
+ clearTimeout(timeout);
2366
+ offEvent(eventIds);
2035
2367
  return online;
2036
2368
  }
2037
2369
 
2038
2370
  function doFakeGameScore() {
2371
+ if (isLogOff) {
2372
+ return;
2373
+ }
2039
2374
  const maxRound = Math.random() > 0.7 ? 16 : 12;
2040
2375
  const maps = ["cs_agency", "cs_assault", "cs_italy", "cs_militia", "cs_office", "de_ancient", "de_anubis", "de_bank", "de_boyard", "de_cache", "de_canals", "de_cbble", "de_chalice", "de_dust2", "de_inferno", "de_lake", "de_mirage", "de_nuke", "de_overpass", "de_safehouse", "de_sugarcane", "de_train", "de_tuscan", "de_vertigo", "de_thera", "de_mills", "de_memento", "de_assembly", "training1"];
2041
2376
 
@@ -2117,6 +2452,9 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
2117
2452
  }
2118
2453
 
2119
2454
  async function gamesPlayed(apps) {
2455
+ if (isLogOff) {
2456
+ return;
2457
+ }
2120
2458
  if (!Array.isArray(apps)) {
2121
2459
  apps = [apps];
2122
2460
  }
@@ -2154,6 +2492,9 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
2154
2492
  }
2155
2493
 
2156
2494
  function getFriendsList() {
2495
+ if (isLogOff) {
2496
+ return;
2497
+ }
2157
2498
  const methodName = "FriendsList.GetFriendsList#1";
2158
2499
  const { users, myFriends } = steamClient; //object
2159
2500
  /*
@@ -2193,6 +2534,9 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
2193
2534
  }
2194
2535
 
2195
2536
  async function getUserOwnedApps(steamId = steamClient.steamID) {
2537
+ if (isLogOff) {
2538
+ return;
2539
+ }
2196
2540
  if (!steamId) {
2197
2541
  return [];
2198
2542
  }
@@ -2248,7 +2592,10 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
2248
2592
  return steamClient._playingAppIds || [];
2249
2593
  }
2250
2594
 
2251
- function requestJoinFriendData(token, version) {
2595
+ async function requestJoinFriendData(token, version) {
2596
+ if (isLogOff) {
2597
+ return;
2598
+ }
2252
2599
  if (!steamClient.steamID) {
2253
2600
  return;
2254
2601
  }
@@ -2263,23 +2610,37 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
2263
2610
  let accountID = conBuf.readInt32BE(4);
2264
2611
  let joinIpp = conBuf.readInt32BE(8);
2265
2612
 
2266
- return new Promise((resolve) => {
2267
- pushGCCallback(`requestJoinFriendData_${accountID}`, resolve, 30000);
2268
- steamClient.sendToGC(
2269
- AppID,
2270
- ESteamProto.ECsgoGCMsg.k_EMsgGCCStrike15_v2_ClientRequestJoinFriendData,
2271
- {},
2272
- new SteamProto(SteamProtoType.CMsgGCCStrike15_v2_ClientRequestJoinFriendData).protoEncode({
2273
- version: version || CSGO_VER,
2274
- account_id: accountID,
2275
- join_token: joinToken,
2276
- join_ipp: joinIpp,
2277
- }),
2278
- );
2279
- });
2613
+ const gcEventId = uuidv4();
2614
+ const response = await ensureLogin(
2615
+ new Promise((resolve) => {
2616
+ onGCEvent({
2617
+ name: gcEvents.requestJoinFriendData,
2618
+ id: gcEventId,
2619
+ key: accountID,
2620
+ callback: resolve,
2621
+ timeoutMs: 30000,
2622
+ });
2623
+ steamClient.sendToGC(
2624
+ AppID,
2625
+ ESteamProto.ECsgoGCMsg.k_EMsgGCCStrike15_v2_ClientRequestJoinFriendData,
2626
+ {},
2627
+ new SteamProto(SteamProtoType.CMsgGCCStrike15_v2_ClientRequestJoinFriendData).protoEncode({
2628
+ version: version || CSGO_VER,
2629
+ account_id: accountID,
2630
+ join_token: joinToken,
2631
+ join_ipp: joinIpp,
2632
+ }),
2633
+ );
2634
+ }),
2635
+ );
2636
+ clearGCCallback(gcEventId);
2637
+ return response;
2280
2638
  }
2281
2639
 
2282
2640
  function redeemFreeReward(itemIds, generation_time) {
2641
+ if (isLogOff) {
2642
+ return;
2643
+ }
2283
2644
  console.log(`Sent message to GC: AppID ${AppID}, MessageType ${ESteamProto.ECsgoGCMsg.k_EMsgGCCStrike15_v2_ClientRedeemFreeReward}`);
2284
2645
 
2285
2646
  const encodedMessages = new SteamProto(SteamProtoType.CMsgGCCstrike15_v2_ClientRedeemFreeReward).protoEncode({
@@ -2300,6 +2661,9 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
2300
2661
  }
2301
2662
 
2302
2663
  function requestRankingInfo() {
2664
+ if (isLogOff) {
2665
+ return;
2666
+ }
2303
2667
  return new Promise((resolve) => {
2304
2668
  const timeout = setTimeout(function () {
2305
2669
  resolve();
@@ -2335,6 +2699,9 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
2335
2699
  }
2336
2700
 
2337
2701
  function acknowledgePenalty() {
2702
+ if (isLogOff) {
2703
+ return;
2704
+ }
2338
2705
  steamClient.sendToGC(
2339
2706
  730,
2340
2707
  ESteamProto.ECsgoGCMsg.k_EMsgGCCStrike15_v2_AcknowledgePenalty,
@@ -2345,6 +2712,28 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
2345
2712
  );
2346
2713
  }
2347
2714
 
2715
+ async function ensureLogin(promise) {
2716
+ if (isLogOff) {
2717
+ return null;
2718
+ }
2719
+ const logOffEventId = uuidv4();
2720
+ const result = await Promise.race([
2721
+ new Promise((resolve) => {
2722
+ onEvent({
2723
+ name: SteamClientEvents.logOff,
2724
+ id: logOffEventId,
2725
+ callback: function () {
2726
+ resolve(null);
2727
+ },
2728
+ once: true,
2729
+ });
2730
+ }),
2731
+ promise,
2732
+ ]);
2733
+ offEvent(logOffEventId);
2734
+ return result;
2735
+ }
2736
+
2348
2737
  return {
2349
2738
  init,
2350
2739
  partySearch,
@@ -2380,6 +2769,9 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
2380
2769
  getPersonaName,
2381
2770
  async getPlayersProfile(steamId, retry = 3) {
2382
2771
  for (let i = 0; i < retry; i++) {
2772
+ if (isLogOff) {
2773
+ return;
2774
+ }
2383
2775
  const profile = await getPlayersProfile(steamId);
2384
2776
  if (profile) {
2385
2777
  return profile;
@@ -2443,6 +2835,7 @@ function SteamClient({ username, password, cookie, clientJsToken, isAutoRequestF
2443
2835
  return state;
2444
2836
  },
2445
2837
  log,
2838
+ error,
2446
2839
  isPrime() {
2447
2840
  return prime === true;
2448
2841
  },
@@ -2563,111 +2956,6 @@ export function increaseCSGO_VER() {
2563
2956
  return ++CSGO_VER;
2564
2957
  }
2565
2958
 
2566
- SteamClient.isAccountPlayable = async function isAccountPlayable({ cookie, clientJsToken, timeoutMs, onPlayable, onNotPlayable, keepLoginWhenPlayable, ...rest }) {
2567
- if (!clientJsToken && cookie) {
2568
- clientJsToken = await new SteamUser(typeof cookie === "function" ? await cookie() : cookie).getClientJsToken();
2569
- }
2570
- if (clientJsToken?.logged_in !== true) {
2571
- if (typeof onNotPlayable === "function") {
2572
- await onNotPlayable(null);
2573
- }
2574
- return { invalidClientJsToken: true };
2575
- }
2576
- return await new Promise((resolve) => {
2577
- const timeouts = [
2578
- setTimeout(() => {
2579
- doResolve({ timedOut: true });
2580
- }, timeoutMs || 30000),
2581
- ];
2582
-
2583
- const steamClient = new SteamClient({
2584
- isFakeGameScore: false,
2585
- isAutoPlay: true,
2586
- isPartyRegister: false,
2587
- isInvisible: true,
2588
- MAX_GAME_PLAY: 10,
2589
- games: 730,
2590
- clientJsToken,
2591
- ...rest,
2592
- });
2593
-
2594
- steamClient.onEvent(
2595
- SteamClientEvents.error,
2596
- ({ eresult, msg, error }) => {
2597
- doResolve({ eresult, msg, error });
2598
- },
2599
- true,
2600
- );
2601
-
2602
- steamClient.onEvent(
2603
- SteamClientEvents.csgoOnline,
2604
- (ClientWelcome) => {
2605
- doResolve({ playable: true });
2606
- },
2607
- true,
2608
- );
2609
-
2610
- steamClient.onEvent(
2611
- SteamClientEvents.csgoClientHello,
2612
- (ClientHello) => {
2613
- doResolve({ playable: true });
2614
- },
2615
- true,
2616
- );
2617
-
2618
- steamClient.onEvent(SteamClientEvents.playingState, ({ playing_blocked, playing_app }) => {
2619
- if (playing_blocked) {
2620
- doResolve({ playable: false });
2621
- } else {
2622
- timeouts.push(
2623
- setTimeout(function () {
2624
- const isBlocked = steamClient.isPlayingBlocked();
2625
- doResolve({ playable: !isBlocked });
2626
- }, 5000),
2627
- );
2628
- }
2629
- });
2630
-
2631
- // steamClient.onEvent("fatalError", () => {
2632
- // doResolve();
2633
- // });
2634
-
2635
- steamClient.init();
2636
-
2637
- async function doResolve(data) {
2638
- const playable = data?.playable === true;
2639
- timeouts.forEach((timeout) => clearTimeout(timeout));
2640
-
2641
- if (!playable || !keepLoginWhenPlayable) {
2642
- steamClient.doClearIntervals();
2643
- steamClient.offAllEvent();
2644
- }
2645
-
2646
- if (playable) {
2647
- if (typeof onPlayable === "function") {
2648
- try {
2649
- await onPlayable(steamClient);
2650
- } catch (e) {}
2651
- }
2652
- } else {
2653
- if (typeof onNotPlayable === "function") {
2654
- try {
2655
- await onNotPlayable(steamClient);
2656
- } catch (e) {}
2657
- }
2658
- }
2659
-
2660
- if (!playable || !keepLoginWhenPlayable) {
2661
- steamClient.logOff();
2662
- return resolve(data);
2663
- } else {
2664
- steamClient.offAllEvent();
2665
- return resolve({ ...data, steamClient });
2666
- }
2667
- }
2668
- });
2669
- };
2670
-
2671
2959
  class XpBonuxFlagsHelper {
2672
2960
  static kCSXpBonusFlags_EarnedXpThisPeriod = 1 << 0;
2673
2961
  static kCSXpBonusFlags_FirstReward = 1 << 1;