steamutils 1.4.63 → 1.4.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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;