steamutils 1.3.45 → 1.3.47

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.
package/SteamClient.js CHANGED
@@ -1,2337 +1,2365 @@
1
- import NodeSteamUser from "steam-user";
2
- import _ from "lodash";
3
- import fs from "fs";
4
- import {protoDecode, protoEncode} from "./helpers/util.js";
5
- import SteamID from "steamid";
6
- import FriendCode from "csgo-friendcode";
7
- import axios from "axios";
8
- import helpers, {loadProfos} from "./helpers/protos.js";
9
- import {fileURLToPath} from "url";
10
- import path from "path";
11
- import SteamUser from "./index.js";
12
- import {v4 as uuidv4} from 'uuid';
13
- import EFriendRelationship from "steam-user/enums/EFriendRelationship.js";
14
- import SteamCommunity from "steamcommunity";
15
- import moment from "moment-timezone";
16
- import {encode, encodeUids} from "./bufferHelpers.js";
17
-
18
- const __filename = fileURLToPath(import.meta.url);
19
- const __dirname = path.dirname(__filename);
20
-
21
- const Protos = helpers([{
22
- name: 'csgo',
23
- protos: loadProfos(__dirname + '/protos/')
24
- }])
25
-
26
- export const RANKS = {
27
- 0: 'Unranked',
28
- 1: 'Silver I',
29
- 2: 'Silver II',
30
- 3: 'Silver III',
31
- 4: 'Silver IV',
32
- 5: 'Silver Elite',
33
- 6: 'Silver Elite Master',
34
- 7: 'Gold Nova I',
35
- 8: 'Gold Nova II',
36
- 9: 'Gold Nova III',
37
- 10: 'Gold Nova Master',
38
- 11: 'Master Guardian I',
39
- 12: 'Master Guardian II',
40
- 13: 'Master Guardian Elite',
41
- 14: 'Distinguished Master Guardian',
42
- 15: 'Legendary Eagle',
43
- 16: 'Legendary Eagle Master',
44
- 17: 'Supreme Master First Class',
45
- 18: 'The Global Elite'
46
- }
47
- export const LOCS = {
48
- 20054: 'VN',
49
- 23115: 'KZ',
50
- 20041: 'IN',
51
- 20035: 'CN',
52
- 17474: 'BD',
53
- 17481: 'ID',
54
- 22861: 'MY',
55
- 18516: 'TH',
56
- 22356: 'TW',
57
- 21067: 'KR',
58
- 19272: 'HK',
59
- 18512: 'PH',
60
- 21842: 'RU',
61
- 16716: 'LA',
62
- 20558: 'NP',
63
- 18259: 'SG',
64
- 19789: 'MM',
65
- 20045: 'MN',
66
- 18251: 'KG',
67
- 18507: 'KH',
68
- 22605: 'MX',
69
- 19280: 'PK',
70
- 20301: 'HK/MO',//hongkong or macau
71
- 21333: 'Unknown',
72
- 21825: 'AU',
73
- 20034: 'Unkown',
74
- }
75
-
76
-
77
- const AppID = 730
78
- export let CSGO_VER = 13960
79
- export const FreeAppList = JSON.parse(fs.readFileSync(path.join(__dirname, 'free_packages.json'))).packages
80
-
81
- SteamUser.getAppVersion(AppID).then(function (ver) {
82
- CSGO_VER = ver
83
- })
84
-
85
- const PersonasCache = []
86
- let isSendingFriendMessages = false;
87
-
88
- function SteamClient({
89
- username,
90
- password,
91
- cookie,
92
- clientJsToken,
93
- isAutoRequestFreeLicense = true,
94
- isFakeGameScore = true,
95
- isPartyRegister = true,
96
- isAutoPlay = false,
97
- isInvisible = false,
98
- autoAcceptTradeRequest = false,
99
- autoReconnect = true,
100
- MAX_GAME_PLAY = 10,
101
- games = null
102
- }) {
103
- const steamClient = new NodeSteamUser()
104
- let prime = null
105
- let state = 'Offline'//InGame, Online, Invisible
106
- let isLogOff = false
107
- let playingBlocked = null
108
- const richPresence = {}
109
- let sendMessageTimestamp = 0
110
- let lastTimePartyRegister = 0
111
- let lastTimePartySearch = 0
112
- const ownedApps = []
113
- let logOffEvent = null
114
-
115
- const currentLobby = {
116
- lobbyID: null,
117
- timestamp: 0
118
- }
119
-
120
- const onAnyCallbacks = []
121
-
122
- const events = {
123
- user: [],
124
- loggedOn: [],
125
- csgoOnline: [],
126
- csgoClientHello: [],
127
- webSession: [],
128
- friendMessage: [],
129
- friendTyping: [],
130
- disconnected: [],
131
- error: [],
132
- playersProfile: [],
133
- partyInvite: [],
134
- friendRelationship: [],
135
- tradeOffers: [],
136
- offlineMessages: [],
137
- friendsList: [],
138
- gifts: [],
139
- playingState: [],
140
- emailInfo: [],
141
- accountLimitations: [],
142
- }
143
-
144
- const gcCallback = {}
145
-
146
- function pushGCCallback(name, cb, timeout) {
147
- if (!gcCallback[name]) {
148
- gcCallback[name] = {}
149
- }
150
- let t = null
151
- let id = uuidv4()
152
-
153
- function callback(...arg) {
154
- if (t) {
155
- clearTimeout(t)
156
- }
157
- delete gcCallback[name][id]
158
- cb?.apply(null, arg)
159
- }
160
-
161
- if (timeout) {
162
- t = setTimeout(callback, timeout)
163
- }
164
- gcCallback[name][id] = callback
165
- }
166
-
167
- function callGCCallback(name, ...arg) {
168
- if (gcCallback[name]) {
169
- for (const id in gcCallback[name]) {
170
- gcCallback[name][id]?.(...arg)
171
- }
172
- }
173
- }
174
-
175
- function callEvent(_events, data) {
176
- const eventName = Object.keys(events).find(eventName => events[eventName] === _events)
177
- eventName && onAnyCallbacks.forEach(cb => cb?.({eventName, data}))
178
-
179
- _events?.forEach?.((e) => {
180
- e.callback?.(data)
181
- e.timeout && clearTimeout(e.timeout)
182
- delete e.timeout
183
- if (e.once) {
184
- delete e.callback
185
- }
186
- })
187
- _.remove(_events, e => !e || e?.once)
188
- }
189
-
190
- function onEvent(name, callback, once, timeout) {
191
- if (!events[name]) {
192
- events[name] = []
193
- }
194
- const t = timeout ? setTimeout(callback, timeout) : null
195
- events[name].push({
196
- once,
197
- callback,
198
- timeout: t,
199
- })
200
- }
201
-
202
-
203
- function offEvent(name) {
204
- if (Array.isArray(events[name])) {
205
- for (const eventElement of events[name]) {
206
- if (eventElement.timeout) {
207
- clearTimeout(eventElement.timeout)
208
- }
209
- }
210
- }
211
-
212
- delete events[name]
213
- }
214
-
215
- function onAnyEvent(callback) {
216
- onAnyCallbacks.push(callback)
217
- }
218
-
219
- function offAllEvent() {
220
- for (const name in events) {
221
- for (const event of events[name]) {
222
- if (event.timeout) {
223
- try {
224
- clearTimeout(event.timeout)
225
- } catch (e) {
226
- }
227
- delete event.timeout
228
- }
229
- }
230
- delete events[name]
231
- }
232
- onAnyCallbacks.length = 0
233
- }
234
-
235
- const intervals = {}
236
- const intervalRandoms = {}
237
-
238
- function doSetInterval(cb, timeout, key) {
239
- const isRandom = Array.isArray(timeout)
240
- if (!key) {
241
- key = uuidv4()
242
- }
243
- if (isRandom) {
244
- if (intervalRandoms[key] !== undefined) {
245
- try {
246
- clearTimeout(intervalRandoms[key])
247
- } catch (e) {
248
- }
249
- }
250
- intervalRandoms[key] = setTimeout(function () {
251
- doSetInterval(cb, timeout, key)
252
- if (state !== 'Offline') {
253
- cb()
254
- }
255
- }, _.random(timeout[0], timeout[1]))
256
- } else {
257
- if (intervals[key] !== undefined) {
258
- try {
259
- clearInterval(intervals[key])
260
- } catch (e) {
261
- }
262
- }
263
-
264
- intervals[key] = setInterval(function () {
265
- if (state !== 'Offline') {
266
- cb()
267
- }
268
- }, timeout)
269
- }
270
-
271
- return key
272
- }
273
-
274
- function doClearIntervals() {
275
- for (const key in intervals) {
276
- clearInterval(intervals[key])
277
- delete intervals[key]
278
- }
279
- for (const key in intervalRandoms) {
280
- clearTimeout(intervalRandoms[key])
281
- delete intervalRandoms[key]
282
- }
283
- }
284
-
285
- function doClearInterval(key) {
286
- try {
287
- clearInterval(intervals[key])
288
- } catch (e) {
289
- }
290
- delete intervals[key]
291
-
292
-
293
- try {
294
- clearTimeout(intervalRandoms[key])
295
- } catch (e) {
296
- }
297
- delete intervalRandoms[key]
298
- }
299
-
300
- function getAccountInfoName() {
301
- return [steamClient?.accountInfo?.name, steamClient?._logOnDetails?.account_name].filter(Boolean).join(" - ")
302
- }
303
-
304
- function getPersonaName() {
305
- return steamClient?.accountInfo?.name
306
- }
307
-
308
- function log(...msg) {
309
- const now = moment().tz('Asia/Ho_Chi_Minh').format("DD/MM/YYYY HH:mm:ss")
310
- console.log(`[${now}] [${getAccountInfoName()}]`, ...msg)
311
- }
312
-
313
- async function getPersonas(steamIDs) {
314
- steamIDs = steamIDs.map(steamId => steamId instanceof SteamID ? steamId.getSteamID64() : steamId)
315
- const notCachesteamIDs = steamIDs.filter(id => !PersonasCache.some(p => p.id == id))
316
- const cachedPersonas = PersonasCache.filter(p => steamIDs.includes(p.id))
317
-
318
- if (notCachesteamIDs.length) {
319
- let personas = null
320
- try {
321
- personas = (await steamClient.getPersonas(notCachesteamIDs))?.personas
322
- } catch (e) {
323
- }
324
- if (!personas || !Object.keys(personas).length) {
325
- try {
326
- personas = (await steamClient.getPersonas(notCachesteamIDs))?.personas
327
- } catch (e) {
328
- }
329
- }
330
- if (!personas || !Object.keys(personas).length) {
331
- try {
332
- personas = (await steamClient.getPersonas(notCachesteamIDs))?.personas
333
- } catch (e) {
334
- }
335
- }
336
- if (personas && Object.keys(personas).length) {
337
- for (let sid64 in personas) {
338
- personas[sid64].id = sid64
339
- personas[sid64].avatar_hash = Buffer.from(personas[sid64].avatar_hash).toString("hex")
340
- PersonasCache.push(personas[sid64])
341
- cachedPersonas.push(personas[sid64])
342
- }
343
- }
344
- }
345
-
346
- while (PersonasCache.length > 500) {
347
- PersonasCache.shift()
348
- }
349
- return cachedPersonas
350
- }
351
-
352
- function sleep(ms) {
353
- return new Promise(resolve => {
354
- setTimeout(resolve, ms)
355
- })
356
- }
357
-
358
- function getCookies() {
359
- return cookie || steamClient?.webSession?.cookies?.join?.(';')
360
- }
361
-
362
- async function getCookiesWait() {
363
- return getCookies() || new Promise(resolve => {
364
- onEvent('webSession', function (webSession) {
365
- resolve(webSession?.cookies)
366
- }, true, 30000)
367
- })
368
- }
369
-
370
- async function gamePlay() {
371
- if ((Array.isArray(games) && games.length) || (games && (typeof games === "number" || typeof games === "string"))) {
372
- return gamesPlayed(games)
373
- }
374
-
375
- let ownedApps = []
376
- for (let i = 0; i < 5; i++) {
377
- ownedApps = await getUserOwnedApps()
378
- if (ownedApps?.length) {
379
- break
380
- }
381
- }
382
- if (!ownedApps?.length) {
383
- gamesPlayed(730)
384
- } else {
385
- ownedApps = ownedApps.map(({appid}) => appid)
386
- ownedApps = _.shuffle(ownedApps)
387
- ownedApps.length = Math.min(ownedApps.length, MAX_GAME_PLAY - 1)
388
- _.remove(ownedApps, app => app == 730)
389
- gamesPlayed([...ownedApps, 730])
390
- }
391
- }
392
-
393
- async function autoGamePlay() {
394
- await gamePlay()
395
- doSetInterval(gamePlay, [15 * 60000, 30 * 60000], 'autoGamePlay')
396
- }
397
-
398
- async function offAutoGamePlay() {
399
- steamClient.gamesPlayed([])
400
- doClearInterval('autoGamePlay')
401
- }
402
-
403
-
404
- async function updateAutoGamePlay() {
405
- if (isAutoPlay) {
406
- autoGamePlay()
407
- } else {
408
- offAutoGamePlay()
409
- }
410
- }
411
-
412
-
413
- /**
414
- * Get a list of lobbies (* = Unsure description could be wrong)
415
- * @param {Number} ver Game version we are searching for
416
- * @param {Boolean} apr Prime or not*
417
- * @param {Number} ark Rank multiplied by 10*
418
- * @param {Array.<Number>} grps *
419
- * @param {Number} launcher If we are using the China CSGO launcher or not*
420
- * @param {Number} game_type Game type, 8 Competitive, 10 Wingman
421
- * @returns {Promise.<Object>}
422
- */
423
- async function partySearch({
424
- prime = false,
425
- game_type = 'Competitive',
426
- rank = 'Silver Elite',
427
- timeout = 5000,
428
- } = {}) {
429
- const players = await new Promise(resolve => {
430
- steamClient.sendToGC(AppID, Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Party_Search, {}, protoEncode(Protos.csgo.CMsgGCCStrike15_v2_Party_Search, {
431
- ver: CSGO_VER,
432
- apr: prime ? 1 : 0,
433
- ark: parseInt(Object.keys(RANKS).find(k => RANKS[k] === rank)) * 10,
434
- grps: [],
435
- launcher: 0,
436
- game_type: game_type === 'Competitive' ? 8 : 10
437
- }))
438
- lastTimePartySearch = new Date().getTime()
439
- pushGCCallback('partySearch', resolve, timeout)
440
- })
441
- if (Array.isArray(players) && players.length) {
442
- const personas = await getPersonas(players.map(p => p.steamId))
443
- for (const player of players) {
444
- const persona = personas.find(p => p.id == player.steamId)
445
- if (persona) {
446
- player.player_name = persona.player_name
447
- player.avatar_hash = persona.avatar_hash
448
- }
449
- }
450
- }
451
- return players
452
- }
453
-
454
- async function createLobby() {
455
- if (!steamClient.steamID) {
456
- return
457
- }
458
-
459
- return new Promise(resolve => {
460
- const timeout = setTimeout(function () {
461
- resolve()
462
- }, 30000)
463
-
464
- steamClient._send(
465
- {
466
- msg: Protos.csgo.EMsg.k_EMsgClientMMSCreateLobby,
467
- proto: {
468
- steamid: steamClient.steamID.getSteamID64(),
469
- routing_appid: 730
470
- }
471
- },
472
- protoEncode(Protos.csgo.CMsgClientMMSCreateLobby, {
473
- app_id: 730,
474
- max_members: 1,
475
- lobby_type: 1,
476
- lobby_flags: 1
477
- }), function (payload) {
478
- clearTimeout(timeout)
479
- const result = protoDecode(Protos.csgo.CMsgClientMMSCreateLobbyResponse, payload.toBuffer())
480
- const steam_id_lobby = result.steam_id_lobby.toString();
481
- currentLobby.lobbyID = steam_id_lobby
482
- currentLobby.timestamp = new Date().getTime()
483
- resolve(steam_id_lobby)
484
- }
485
- );
486
- })
487
-
488
- // return await getHandlerResult(Protos.csgo.EMsg.k_EMsgClientMMSCreateLobbyResponse, function (payload) {
489
- // const result = protoDecode(Protos.csgo.CMsgClientMMSCreateLobbyResponse, payload.toBuffer())
490
- // return result.steam_id_lobby.toString()
491
- // })
492
-
493
- // steamClient.sendToGC(730, Protos.csgo.EMsg.k_EMsgClientMMSCreateLobby, {
494
- // steamid: steamClient.steamID,
495
- // routing_appid: 730,
496
- // }, protoEncode(Protos.csgo.CMsgClientMMSCreateLobby, {
497
- // app_id: 730,
498
- // max_members: 1,
499
- // lobby_type: 1,
500
- // lobby_flags: 1
501
- // }))
502
- }
503
-
504
- async function updateLobby(lobbyID) {
505
- if (!steamClient.steamID) {
506
- return
507
- }
508
-
509
- return new Promise(resolve => {
510
- const timeout = setTimeout(function () {
511
- resolve()
512
- }, 30000)
513
-
514
- steamClient._send(
515
- {
516
- msg: Protos.csgo.EMsg.k_EMsgClientMMSSetLobbyData,
517
- proto: {
518
- steamid: steamClient.steamID.getSteamID64(),
519
- routing_appid: 730
520
- }
521
- },
522
- protoEncode(Protos.csgo.CMsgClientMMSSetLobbyData, {
523
- app_id: 730,
524
- steam_id_lobby: lobbyID,
525
- steam_id_member: '0',
526
- max_members: 10,
527
- lobby_type: 1,
528
- lobby_flags: 1,
529
- metadata: encode({
530
- 'game:ark': '0',
531
- // Country/Message
532
- 'game:loc': '',
533
- 'game:mapgroupname': 'mg_de_mirage',
534
- 'game:mode': 'competitive',
535
- 'game:prime': '1',
536
- 'game:type': 'classic',
537
- 'members:numPlayers': '1',
538
- 'options:action': 'custommatch',
539
- 'options:anytypemode': '0',
540
- 'system:access': 'private',
541
- 'system:network': 'LIVE',
542
- uids: [steamClient.steamID]
543
- }, [0x00, 0x00], [0x08], {uids: encodeUids}).toBuffer()
544
- }),
545
- function (payload) {
546
- clearTimeout(timeout)
547
- const result = protoDecode(Protos.csgo.CMsgClientMMSSetLobbyDataResponse, payload.toBuffer())
548
- const steam_id_lobby = result.steam_id_lobby.toString();
549
- currentLobby.lobbyID = steam_id_lobby
550
- currentLobby.timestamp = new Date().getTime()
551
- resolve(steam_id_lobby)
552
- }
553
- );
554
- })
555
-
556
- // return await getHandlerResult(Protos.csgo.EMsg.k_EMsgClientMMSSetLobbyDataResponse, function (payload) {
557
- // const result = protoDecode(Protos.csgo.CMsgClientMMSSetLobbyDataResponse, payload.toBuffer())
558
- // return result.steam_id_lobby.toString()
559
- // })
560
- }
561
-
562
- async function invite2Lobby(lobbyID, steamId) {
563
- if (!steamClient.steamID) {
564
- return
565
- }
566
-
567
- steamClient._send(
568
- {
569
- msg: Protos.csgo.EMsg.k_EMsgClientMMSInviteToLobby,
570
- proto: {
571
- steamid: steamClient.steamID.getSteamID64(),
572
- routing_appid: 730
573
- }
574
- },
575
- protoEncode(Protos.csgo.CMsgClientMMSInviteToLobby, {
576
- app_id: 730,
577
- steam_id_lobby: lobbyID,
578
- steam_id_user_invited: steamId,
579
- }));
580
-
581
- // lobbyID = new SteamID(lobbyID).accountid;
582
-
583
- // Protos.csgo.EMsg.k_EMsgGCHInviteUserToLobby
584
- // Protos.csgo.EMsg.k_EMsgClientMMSInviteToLobby
585
- // steamClient.sendToGC(730, Protos.csgo.EMsg.k_EMsgClientMMSInviteToLobby, {}, protoEncode(Protos.csgo.CMsgClientMMSInviteToLobby, {
586
- // app_id: 730,
587
- // steam_id_lobby: lobbyID,
588
- // steam_id_user_invited: accountid,
589
- // }), function (...args) {
590
- // console.log("invite2Lobby response", args)
591
- // })
592
- }
593
-
594
- async function createThenInvite2Lobby(steamIds, onInvite) {
595
- if (!steamClient.steamID) {
596
- return
597
- }
598
-
599
- if (!Array.isArray(steamIds)) {
600
- steamIds = [steamIds]
601
- }
602
-
603
- let lobbyID = null
604
- if (currentLobby.lobbyID && currentLobby.timestamp > new Date().getTime() - 30000) {//30 seconds
605
- lobbyID = currentLobby.lobbyID
606
- } else {
607
- lobbyID = await createLobby();
608
- lobbyID = await updateLobby(lobbyID)
609
- }
610
-
611
- for (const steamId of steamIds) {
612
- onInvite?.(lobbyID, steamId)
613
- await invite2Lobby(lobbyID, steamId)
614
- }
615
-
616
- return lobbyID
617
- }
618
-
619
-
620
- async function getLobbyData(lobbyID) {
621
- if (!steamClient.steamID) {
622
- return
623
- }
624
-
625
- return new Promise(resolve => {
626
- const timeout = setTimeout(function () {
627
- resolve()
628
- }, 30000)
629
-
630
- steamClient._send(
631
- {
632
- msg: Protos.csgo.EMsg.k_EMsgClientMMSGetLobbyData,
633
- proto: {
634
- steamid: steamClient.steamID.getSteamID64(),
635
- routing_appid: 730
636
- }
637
- },
638
- protoEncode(Protos.csgo.CMsgClientMMSGetLobbyData, {
639
- app_id: 730,
640
- steam_id_lobby: lobbyID.toString(),
641
- }),
642
- function (payload) {
643
- clearTimeout(timeout)
644
- const result = protoDecode(Protos.csgo.CMsgClientMMSLobbyData, payload.toBuffer())
645
- result.steam_id_lobby = result.steam_id_lobby.toString()
646
- resolve(result)
647
- }
648
- );
649
- })
650
- }
651
-
652
-
653
- async function joinLobby(lobbyID) {
654
- log("joinLobby", lobbyID);//SteamID.fromIndividualAccountID(lobbyId).accountid
655
-
656
- steamClient._send(
657
- {
658
- msg: Protos.csgo.EMsg.k_EMsgClientMMSJoinLobby,
659
- proto: {
660
- steamid: steamClient.steamID.getSteamID64(),
661
- routing_appid: 730
662
- }
663
- },//CMsgClientMMSUserJoinedLobby CMsgClientMMSJoinLobby
664
- protoEncode(Protos.csgo.CMsgClientMMSJoinLobby, {
665
- app_id: 730,
666
- steam_id_lobby: lobbyID,
667
- persona_name: steamClient.accountInfo.name,
668
- }),
669
- function (payload) {
670
- const result = protoDecode(Protos.csgo.CMsgClientMMSJoinLobbyResponse, payload.toBuffer())
671
- result.steam_id_lobby = result.steam_id_lobby.toString()
672
- result.steam_id_owner = result.steam_id_owner.toString()
673
- console.log(result);
674
- const resultExample = {
675
- members: [],
676
- app_id: 730,
677
- steam_id_lobby: "3641224920",
678
- chat_room_enter_response: 2,
679
- max_members: 0,
680
- lobby_type: 0,
681
- lobby_flags: 0,
682
- steam_id_owner: "0",
683
- metadata: null//Buffer
684
- }
685
- }
686
- )
687
- }
688
-
689
- async function sendHello() {
690
- steamClient.sendToGC(AppID, Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_MatchmakingClient2GCHello, {}, Buffer.alloc(0))
691
- steamClient.sendToGC(AppID, Protos.csgo.EGCBaseClientMsg.k_EMsgGCClientHello, {}, Buffer.alloc(0))
692
- }
693
-
694
- async function requestCoPlays() {
695
- return new Promise(resolve => {
696
- steamClient.sendToGC(AppID, Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Account_RequestCoPlays, {}, Buffer.alloc(0))
697
- pushGCCallback('RequestCoPlays', resolve, 30000)
698
- })
699
- }
700
-
701
-
702
- function bindEvent() {
703
- const _events = {
704
- async disconnected(eresult, msg) {
705
- state = 'Offline'
706
- log('disconnected', eresult, msg)
707
-
708
- callEvent(events.disconnected, {eresult, msg})
709
-
710
- if (['ServiceUnavailable', 'NoConnection'].includes(msg) && autoReconnect && !isLogOff) {
711
- async function relogin(retry) {
712
- if (isLogOff) {
713
- console.error("Cannot relogin (logoff)")
714
- return false
715
- } else if (retry <= 0) {
716
- console.error("Cannot relogin")
717
- return false
718
- } else {
719
- const isSuccess = await login(true)
720
- if (isSuccess) {
721
- const loggedOnResponse = await new Promise(resolve => {
722
- onEvent('loggedOn', resolve, true, 180000)
723
- })
724
- if (loggedOnResponse) {
725
- console.log("Relogin success")
726
- return true
727
- } else {
728
- const isLogOff = await new Promise((resolve, reject) => {
729
- logOffEvent = resolve
730
- setTimeout(resolve, 120000)
731
- })
732
- logOffEvent = null
733
- if (isLogOff === true) {
734
- return false
735
- }
736
- return await relogin(retry - 1)
737
- }
738
- } else {
739
- const isLogOff = await new Promise((resolve, reject) => {
740
- logOffEvent = resolve
741
- setTimeout(resolve, 120000)
742
- })
743
- logOffEvent = null
744
- if (isLogOff === true) {
745
- return false
746
- }
747
- return await relogin(retry - 1)
748
- }
749
- }
750
- }
751
-
752
- const isLogOff = await new Promise((resolve, reject) => {
753
- logOffEvent = resolve
754
- setTimeout(resolve, 60000)
755
- })
756
- logOffEvent = null
757
- if (isLogOff === true) {
758
- offAllEvent()
759
- doClearIntervals()
760
- } else {
761
- const isSuccess = await relogin(50)
762
- if (!isSuccess) {
763
- offAllEvent()
764
- doClearIntervals()
765
- }
766
- }
767
- } else {
768
- offAllEvent()
769
- doClearIntervals()
770
- }
771
- },
772
- async error(e) {
773
- let errorStr = ``
774
- switch (e.eresult) {
775
- case 5:
776
- errorStr = `Invalid Password`
777
- break
778
- case 6:
779
- case 34:
780
- errorStr = `Logged In Elsewhere`
781
- break
782
- case 84:
783
- errorStr = `Rate Limit Exceeded`
784
- break
785
- case 65:
786
- errorStr = `steam guard is invalid`
787
- break
788
- default:
789
- errorStr = `Unknown: ${e.eresult}`
790
- break
791
- }
792
- log(`error [isLogOff: ${isLogOff}]`, e?.message)
793
- doClearIntervals()
794
- callEvent(events.error, {eresult: e.eresult, msg: e.message, error: errorStr})
795
- },
796
- async webSession(sessionID, cookies) {
797
- const webSession = {sessionID, cookies};
798
- steamClient.webSession = webSession
799
- callEvent(events.webSession, webSession)
800
- },
801
- async receivedFromGC(appid, msgType, payload) {
802
- const key = getECsgoGCMsgKey(msgType)
803
- switch (msgType) {
804
- case Protos.csgo.EMsg.k_EMsgClientChatInvite: {
805
- log(payload)
806
- break
807
- }
808
- case Protos.csgo.ECsgoGCMsg.k_EMsgClientMMSJoinLobbyResponse: {
809
- const msg = protoDecode(Protos.csgo.CMsgClientMMSJoinLobbyResponse, payload);
810
- log(msg)
811
- break
812
- }
813
- case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Party_Invite: {
814
- const msg = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_Party_Invite, payload);
815
- const sid64 = SteamID.fromIndividualAccountID(msg.accountid).getSteamID64();
816
- if (events.partyInvite?.length) {
817
- const personas = await getPersonas([sid64]);
818
- const player_name = personas.find(p => p.id == sid64)?.player_name
819
- if (player_name === undefined) {
820
- log(sid64, personas);
821
- }
822
- callEvent(events.partyInvite, {player_name, steamId: sid64, lobbyId: msg.lobbyid})
823
- }
824
- // log(player_name, `https://steamcommunity.com/profiles/${sid64}`);
825
- // joinLobby(msg.lobbyid, msg.accountid)
826
- break
827
- }
828
- case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Account_RequestCoPlays: {
829
- const msg = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_Account_RequestCoPlays, payload);
830
- const personas = msg.players.map(p => SteamID.fromIndividualAccountID(p.accountid));
831
- callGCCallback('RequestCoPlays', personas)
832
- break
833
- }
834
- case Protos.csgo.EGCBaseClientMsg.k_EMsgGCClientWelcome: {
835
- prime = false
836
- const CMsgClientWelcome = protoDecode(Protos.csgo.CMsgClientWelcome, payload);
837
- const obj = {}
838
- for (const outofdate_cache of CMsgClientWelcome.outofdate_subscribed_caches) {
839
- for (const cache_object of outofdate_cache.objects) {
840
- for (const object_data of cache_object.object_data) {
841
- switch (cache_object.type_id) {
842
- case 1: {
843
- const result = protoDecode(Protos.csgo.CSOEconItem, object_data);
844
- result.id = result.id.toNumber()
845
- break
846
- }
847
- case 2: {
848
- const result = protoDecode(Protos.csgo.CSOPersonaDataPublic, object_data);
849
- obj.PersonaDataPublic = result
850
- const example = {
851
- player_level: 4,
852
- commendation: {
853
- cmd_friendly: 149,
854
- cmd_teaching: 108,
855
- cmd_leader: 115
856
- },
857
- elevated_state: true
858
- }
859
- break
860
- }
861
- case 5: {
862
- const result = protoDecode(Protos.csgo.CSOItemRecipe, object_data);
863
- break
864
- }
865
- case 7: {
866
- const CSOEconGameAccountClient = protoDecode(Protos.csgo.CSOEconGameAccountClient, object_data);
867
- const CSOEconGameAccountClientExample = {
868
- additional_backpack_slots: 0,
869
- bonus_xp_timestamp_refresh: 1688518800,//Wednesday 1:00:00 AM every week
870
- bonus_xp_usedflags: 19,
871
- elevated_state: 5,
872
- elevated_timestamp: 5
873
- } //1688518800
874
- if ((CSOEconGameAccountClient.bonus_xp_usedflags & 16) != 0) { // EXPBonusFlag::PrestigeEarned
875
- prime = true
876
- CSOEconGameAccountClient.prime = true
877
- }
878
- if (CSOEconGameAccountClient.elevated_state === 5) { // bought prime
879
- prime = true
880
- CSOEconGameAccountClient.prime = true
881
- }
882
- obj.GameAccountClient = CSOEconGameAccountClient
883
- break
884
- }
885
-
886
- case 35: {
887
- // const result =protoDecode(Protos.csgo.CSOSelectedItemPreset, object_data);
888
- break
889
- }
890
-
891
- case 36: {
892
- // const result =protoDecode(Protos.csgo.CSOEconItemPresetInstance, object_data);
893
- break
894
- }
895
- case 38: {
896
- const result = protoDecode(Protos.csgo.CSOEconItemDropRateBonus, object_data);
897
- break
898
- }
899
- case 39: {
900
- const result = protoDecode(Protos.csgo.CSOEconItemLeagueViewPass, object_data);
901
- break
902
- }
903
- case 40: {
904
- const result = protoDecode(Protos.csgo.CSOEconItemEventTicket, object_data);
905
- break
906
- }
907
- case 41: {
908
- const result = protoDecode(Protos.csgo.CSOAccountSeasonalOperation, object_data);
909
- break
910
- }
911
- case 42: {
912
- // const result =protoDecode(Protos.csgo.CSOEconItemTournamentPassport, object_data);
913
- break
914
- }
915
- case 43: {
916
- const result = protoDecode(Protos.csgo.CSOEconDefaultEquippedDefinitionInstanceClient, object_data);
917
- const example = {
918
- account_id: 1080136620,
919
- item_definition: 61,
920
- class_id: 3,
921
- slot_id: 2
922
- }
923
- break
924
- }
925
- case 45: {
926
- const result = protoDecode(Protos.csgo.CSOEconCoupon, object_data);
927
- break
928
- }
929
- case 46: {
930
- const result = protoDecode(Protos.csgo.CSOQuestProgress, object_data);
931
- break
932
- }
933
- case 4: {
934
- const result = protoDecode(Protos.csgo.CSOAccountItemPersonalStore, object_data);
935
- result.generation_time = result.generation_time * 1000
936
- if (Array.isArray(result.items)) {
937
- result.items = result.items.map(item => item.toNumber())
938
- }
939
- obj.personalStore = result
940
- break
941
- }
942
-
943
- default: {
944
- log("cache_object.type_id", cache_object.type_id);
945
- }
946
- }
947
- }
948
-
949
- }
950
- }
951
- callEvent(events.csgoOnline, obj)
952
-
953
- if (isPartyRegister) {
954
- partyRegister()
955
- doSetInterval(function () {
956
- partyRegister()
957
- }, [60000, 120000], 'autoPartyRegister')
958
- }
959
- break
960
- }
961
- case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_MatchmakingGC2ClientUpdate: {
962
- const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_MatchmakingGC2ClientUpdate, payload)
963
- break
964
- }
965
- case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_GC2ClientGlobalStats: {
966
- const result = protoDecode(Protos.csgo.CMsgClientUGSGetGlobalStatsResponse, payload)
967
- break
968
- }
969
- case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_ClientReportPlayer: {
970
- const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_ClientReportPlayer, payload)
971
- break
972
- }
973
- case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_GC2ClientTextMsg: {
974
- const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_GC2ClientTextMsg, payload)
975
- break
976
- }
977
- case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_MatchmakingGC2ClientHello: {
978
- const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_MatchmakingGC2ClientHello, payload)
979
- const example = {
980
- my_current_event_teams: [],
981
- my_current_event_stages: [],
982
- rankings: [],
983
- account_id: 1080136620,
984
- ongoingmatch: null,
985
- global_stats: {
986
- search_statistics: [
987
- {
988
- game_type: 520,
989
- search_time_avg: 0,
990
- players_searching: 5141
991
- },
992
- {
993
- game_type: 32776,
994
- search_time_avg: 0,
995
- players_searching: 6561
996
- },
997
- ],
998
- players_online: 617207,
999
- servers_online: 230638,
1000
- players_searching: 13550,
1001
- servers_available: 126352,
1002
- ongoing_matches: 23264,
1003
- search_time_avg: 95993,
1004
- main_post_url: "*XA=https://blast.tv/live*XT=https://www.twitch.tv/blastpremier*XB=https://live.bilibili.com/35*XG=playcast://https://gotv.blast.tv/major-a*T=SGTAB*L=2@https://steamcommunity.com/broadcast/watch/76561199492362089",
1005
- required_appid_version: 13879,
1006
- pricesheet_version: 1688084844,
1007
- twitch_streams_version: 2,
1008
- active_tournament_eventid: 21,
1009
- active_survey_id: 0,
1010
- rtime32_cur: 0,
1011
- rtime32_event_start: 0
1012
- },
1013
- penalty_seconds: 0,
1014
- penalty_reason: 0,
1015
- vac_banned: 0,
1016
- ranking: {
1017
- account_id: 1080136620,
1018
- rank_id: 10,
1019
- wins: 209,
1020
- rank_change: 0,
1021
- rank_type_id: 6,
1022
- tv_control: 0
1023
- },
1024
- commendation: {
1025
- cmd_friendly: 149,
1026
- cmd_teaching: 108,
1027
- cmd_leader: 115
1028
- },
1029
- medals: null,
1030
- my_current_event: null,
1031
- my_current_team: null,
1032
- survey_vote: 0,
1033
- activity: null,
1034
- player_level: 4,
1035
- player_cur_xp: 327684501,
1036
- player_xp_bonus_flags: 0
1037
- }
1038
- if (result?.global_stats?.required_appid_version && (!CSGO_VER || result.global_stats.required_appid_version > CSGO_VER)) {
1039
- CSGO_VER = result.global_stats.required_appid_version
1040
- }
1041
- callEvent(events.csgoClientHello, result)
1042
- break
1043
- }
1044
- case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_ClientReportResponse: {
1045
- const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_ClientReportResponse, payload)
1046
- break
1047
- }
1048
- case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_ClientCommendPlayerQueryResponse: {
1049
- const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_ClientCommendPlayer, payload)
1050
- break
1051
- }
1052
- case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_PlayerOverwatchCaseAssignment: {
1053
- const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_PlayerOverwatchCaseAssignment, payload)
1054
- break
1055
- }
1056
- case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_MatchList: {
1057
- const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_MatchList, payload)
1058
- break
1059
- }
1060
- case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_GetEventFavorites_Response: {
1061
- const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_GetEventFavorites_Response, payload)
1062
- break
1063
- }
1064
- case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_StartAgreementSessionInGame: {
1065
-
1066
- break
1067
- }
1068
- case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_ClientDeepStats: {
1069
- const result = protoDecode(Protos.csgo.CMsgGCCStrike15_ClientDeepStats, payload)
1070
- break
1071
- }
1072
- case Protos.csgo.EGCBaseClientMsg.k_EMsgGCClientConnectionStatus: {
1073
- const result = protoDecode(Protos.csgo.CMsgConnectionStatus, payload)
1074
- break
1075
- }
1076
- case Protos.csgo.EGCItemMsg.k_EMsgGCStoreGetUserDataResponse: {
1077
- const result = protoDecode(Protos.csgo.CMsgStoreGetUserDataResponse, payload)
1078
- break
1079
- }
1080
- case Protos.csgo.EGCItemMsg.k_EMsgGCStorePurchaseFinalizeResponse: {
1081
- const result = protoDecode(Protos.csgo.CMsgGCStorePurchaseFinalizeResponse, payload)
1082
- break
1083
- }
1084
- case Protos.csgo.EGCItemMsg.k_EMsgGCStorePurchaseCancelResponse: {
1085
- const result = protoDecode(Protos.csgo.CMsgGCStorePurchaseCancelResponse, payload)
1086
- break
1087
- }
1088
- case Protos.csgo.EGCItemMsg.k_EMsgGCStorePurchaseInitResponse: {
1089
- const result = protoDecode(Protos.csgo.CMsgGCStorePurchaseInitResponse, payload)
1090
- break
1091
- }
1092
- case Protos.csgo.EMsg.k_EMsgClientMMSCreateLobbyResponse: {
1093
- const result = protoDecode(Protos.csgo.CMsgClientMMSCreateLobbyResponse, payload)
1094
- console.log("k_EMsgClientMMSCreateLobbyResponse", result);
1095
- break
1096
- }
1097
- case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_ClientGCRankUpdate: {
1098
- const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_ClientGCRankUpdate, payload)
1099
- break
1100
- }
1101
- case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Party_Search: {
1102
- const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_Party_SearchResults, payload)
1103
- const entries = _.uniqBy(result.entries, 'id')
1104
- //{
1105
- // id: 144900402,
1106
- // grp: 0,
1107
- // game_type: 8,
1108
- // apr: 1,
1109
- // ark: 17,
1110
- // loc: 20041,
1111
- // accountid: 0
1112
- // }
1113
-
1114
-
1115
- //{
1116
- // id: "76561199265943339",
1117
- // rich_presence: [],
1118
- // persona_state: null,
1119
- // game_played_app_id: null,
1120
- // game_server_ip: null,
1121
- // game_server_port: null,
1122
- // persona_state_flags: null,
1123
- // online_session_instances: null,
1124
- // persona_set_by_user: null,
1125
- // player_name: "杀人不见血",
1126
- // query_port: null,
1127
- // steamid_source: null,
1128
- // avatar_hash: "33994e26f1fe7e2093f8c7dee66c1ac91531050d",
1129
- // last_logoff: null,
1130
- // last_logon: null,
1131
- // last_seen_online: null,
1132
- // clan_rank: null,
1133
- // game_name: null,
1134
- // gameid: null,
1135
- // game_data_blob: null,
1136
- // clan_data: null,
1137
- // clan_tag: null,
1138
- // broadcast_id: null,
1139
- // game_lobby_id: null,
1140
- // watching_broadcast_accountid: null,
1141
- // watching_broadcast_appid: null,
1142
- // watching_broadcast_viewers: null,
1143
- // watching_broadcast_title: null,
1144
- // is_community_banned: null,
1145
- // player_name_pending_review: null,
1146
- // avatar_pending_review: null,
1147
- // avatar_url_icon: "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/33/33994e26f1fe7e2093f8c7dee66c1ac91531050d.jpg",
1148
- // avatar_url_medium: "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/33/33994e26f1fe7e2093f8c7dee66c1ac91531050d_medium.jpg",
1149
- // avatar_url_full: "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/33/33994e26f1fe7e2093f8c7dee66c1ac91531050d_full.jpg"
1150
- // }
1151
-
1152
- const players = []
1153
- for (const player of entries) {
1154
- try {
1155
- const prime = player.apr === 1 ? 'PRIME' : 'NON-PRIME'
1156
- const loc = LOCS[player.loc] || player.loc
1157
- const steamId = SteamID.fromIndividualAccountID(player.id).getSteamID64()
1158
- const friendCode = FriendCode.encode(steamId)
1159
-
1160
- // if ((LOCS[player.loc] == 'VN' || !LOCS[player.loc])) {
1161
- players.push({
1162
- prime,
1163
- rank: RANKS[player.ark] !== undefined ? RANKS[player.ark] : player.ark,
1164
- loc,
1165
- steamId,
1166
- friendCode,
1167
- })
1168
- // }
1169
- } catch (e) {
1170
- }
1171
- }
1172
-
1173
- callGCCallback('partySearch', players)
1174
- break
1175
- }
1176
- case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_PlayersProfile: {
1177
- let data = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_PlayersProfile, payload)?.account_profiles
1178
- const dataExample = [{
1179
- my_current_event_teams: [],
1180
- my_current_event_stages: [],
1181
- rankings: [{
1182
- account_id: 1225887169,
1183
- rank_id: 0,
1184
- wins: 6,
1185
- rank_change: 0,
1186
- rank_type_id: 7,
1187
- tv_control: 0
1188
- }, {
1189
- account_id: 1225887169,
1190
- rank_id: 0,
1191
- wins: 0,
1192
- rank_change: 0,
1193
- rank_type_id: 10,
1194
- tv_control: 0
1195
- }],
1196
- account_id: 1225887169,
1197
- ongoingmatch: null,
1198
- global_stats: null,
1199
- penalty_seconds: 0,
1200
- penalty_reason: 0,
1201
- vac_banned: 0,
1202
- ranking: {
1203
- account_id: 1225887169,
1204
- rank_id: 8,
1205
- wins: 469,
1206
- rank_change: 0,
1207
- rank_type_id: 6,
1208
- tv_control: 0
1209
- },
1210
- commendation: {
1211
- cmd_friendly: 51, cmd_teaching: 40, cmd_leader: 40
1212
- },
1213
- medals: {
1214
- display_items_defidx: [4819, 4737], featured_display_item_defidx: 4819
1215
- },
1216
- my_current_event: null,
1217
- my_current_team: null,
1218
- survey_vote: 0,
1219
- activity: null,
1220
- player_level: 32,
1221
- player_cur_xp: 327682846,
1222
- player_xp_bonus_flags: 0
1223
- }]
1224
-
1225
- const player = data?.[0];
1226
- if (player) {
1227
- player.prime = !!(player.ranking?.account_id || player.player_level || player.player_cur_xp)
1228
- player.steamId = SteamID.fromIndividualAccountID(player.account_id).getSteamID64()
1229
- callGCCallback('PlayersProfile_' + player.account_id, player)
1230
- }
1231
- callEvent(events.playersProfile, player)
1232
- break
1233
- }
1234
- default:
1235
- log(`receivedFromGC ${msgType} ${key}`)
1236
- const results = Object.values(Protos.csgo).map(function (p) {
1237
- try {
1238
- return protoDecode(p, payload)
1239
- } catch (e) {
1240
- }
1241
- }).filter(function (result) {
1242
- return result && Object.keys(result).length
1243
- })
1244
- log(key, results)
1245
- }
1246
- },
1247
- async loggedOn(loggedOnResponse) {
1248
- callEvent(events.loggedOn, loggedOnResponse)
1249
- updateInvisible()
1250
- updateAutoRequestFreeLicense()
1251
- updateAutoGamePlay()
1252
- },
1253
- async user(steamId, data) {
1254
- callEvent(events.user, {steamId: steamId.getSteamID64(), data})
1255
- const dataExample = {
1256
- rich_presence: [
1257
- {
1258
- key: "status",
1259
- value: "Competitive Mirage [ 3 : 6 ]"
1260
- },
1261
- {
1262
- key: "version",
1263
- value: "13875"
1264
- },
1265
- {
1266
- key: "game:state",
1267
- value: "game"
1268
- },
1269
- {
1270
- key: "steam_display",
1271
- value: "#display_GameKnownMapScore"
1272
- },
1273
- {
1274
- key: "game:mode",
1275
- value: "competitive"
1276
- },
1277
- {
1278
- key: "game:mapgroupname",
1279
- value: "mg_de_mirage"
1280
- },
1281
- {
1282
- key: "game:map",
1283
- value: "de_mirage"
1284
- },
1285
- {
1286
- key: "game:server",
1287
- value: "kv"
1288
- },
1289
- {
1290
- key: "watch",
1291
- value: "1"
1292
- },
1293
- {
1294
- key: "steam_player_group",
1295
- value: "2134948645"
1296
- },
1297
- {
1298
- key: "game:score",
1299
- value: "[ 3 : 6 ]"
1300
- }
1301
- ],
1302
- friendid: "76561199405834425",
1303
- persona_state: 1,
1304
- game_played_app_id: 730,
1305
- game_server_ip: null,
1306
- game_server_port: null,
1307
- persona_state_flags: 1,
1308
- online_session_instances: 1,
1309
- persona_set_by_user: null,
1310
- player_name: "quỷ súng",
1311
- query_port: null,
1312
- steamid_source: "0",
1313
- avatar_hash: {
1314
- type: "Buffer",
1315
- data: [
1316
- 23,
1317
- 163,
1318
- 216,
1319
- 209,
1320
- 236,
1321
- 179,
1322
- 73,
1323
- 228,
1324
- 225,
1325
- 30,
1326
- 48,
1327
- 190,
1328
- 192,
1329
- 170,
1330
- 177,
1331
- 246,
1332
- 139,
1333
- 71,
1334
- 122,
1335
- 205
1336
- ]
1337
- },
1338
- last_logoff: 1683950268,
1339
- last_logon: 1683950281,
1340
- last_seen_online: 1683950268,
1341
- clan_rank: null,
1342
- game_name: "",
1343
- gameid: "730",
1344
- game_data_blob: {
1345
- type: "Buffer",
1346
- data: []
1347
- },
1348
- clan_data: null,
1349
- clan_tag: null,
1350
- broadcast_id: "0",
1351
- game_lobby_id: "0",
1352
- watching_broadcast_accountid: null,
1353
- watching_broadcast_appid: null,
1354
- watching_broadcast_viewers: null,
1355
- watching_broadcast_title: null,
1356
- is_community_banned: null,
1357
- player_name_pending_review: null,
1358
- avatar_pending_review: null
1359
- }
1360
- },
1361
- async playingState(playing_blocked, playing_app) {
1362
- playingBlocked = playing_blocked
1363
- if (playing_app === 0) {
1364
- playing_app = null
1365
- }
1366
- if (playing_blocked) {//true, false
1367
- console.log("Playing else where")
1368
- }
1369
- log('playingState', playing_blocked, playing_app);
1370
- callEvent(events.playingState, {playing_blocked, playing_app})
1371
- },
1372
- async friendRelationship(sid, relationship, previousRelationship) {
1373
- callEvent(events.friendRelationship, {
1374
- steamId: sid.getSteamID64(),
1375
- relationship,
1376
- previousRelationship
1377
- })
1378
- switch (relationship) {
1379
- case EFriendRelationship.None: {
1380
- //we got unfriended.
1381
- break
1382
- }
1383
- case EFriendRelationship.RequestRecipient: {
1384
- //we got invited as a friend
1385
- break
1386
- }
1387
- case EFriendRelationship.Friend: {
1388
- //we got added as a friend
1389
- break
1390
- }
1391
- }
1392
- },
1393
- async tradeOffers(count) {
1394
- callEvent(events.tradeOffers, count)
1395
- },
1396
- async offlineMessages(count, friends) {
1397
- callEvent(events.offlineMessages, {count, steamIdList: friends})
1398
- },
1399
- async tradeRequest(steamID, respond) {
1400
- if (autoAcceptTradeRequest) {
1401
- log(`Incoming trade request from ${steamID.getSteam3RenderedID()}, accepting`);
1402
- respond(true);
1403
- } else {
1404
- log(`Incoming trade request from ${steamID.getSteam3RenderedID()}, wating`);
1405
- }
1406
- },
1407
- async friendsList() {
1408
- callEvent(events.friendsList, getFriendList())
1409
- },
1410
- async gifts(gid, packageid, TimeCreated, TimeExpiration, TimeSent, TimeAcked, TimeRedeemed, RecipientAddress, SenderAddress, SenderName) {
1411
- callEvent(events.gifts, {
1412
- gid,
1413
- packageid,
1414
- TimeCreated,
1415
- TimeExpiration,
1416
- TimeSent,
1417
- TimeAcked,
1418
- TimeRedeemed,
1419
- RecipientAddress,
1420
- SenderAddress,
1421
- SenderName
1422
- })
1423
- },
1424
- async emailInfo(address, validated) {
1425
- callEvent(events.emailInfo, {address, validated})
1426
- },
1427
- async appLaunched() {
1428
- setTimeout(function () {
1429
- state = getPlayingAppIds().length ? 'InGame' : (isInvisible ? "Invisible" : 'Online')
1430
- }, 1000)
1431
- },
1432
- async appQuit() {
1433
- setTimeout(function () {
1434
- state = getPlayingAppIds().length ? 'InGame' : (isInvisible ? "Invisible" : 'Online')
1435
- }, 1000)
1436
- },
1437
- async accountLimitations(bis_limited_account, bis_community_banned, bis_locked_account, bis_limited_account_allowed_to_invite_friends) {
1438
- callEvent(events.accountLimitations, {
1439
- limited: bis_limited_account,
1440
- communityBanned: bis_community_banned,
1441
- locked: bis_locked_account,
1442
- canInviteFriends: bis_limited_account_allowed_to_invite_friends
1443
- })
1444
- },
1445
- }
1446
-
1447
- const _chatEvents = {
1448
- async friendMessage(data) {
1449
- if (!data) return
1450
- data.message_no_bbcode = data.message_no_bbcode?.replaceAll(`ː`, `:`)
1451
- data.message = data.message?.replaceAll(`ː`, `:`)
1452
- const example = {
1453
- steamid_friend: {
1454
- universe: 1,
1455
- type: 1,
1456
- instance: 1,
1457
- accountid: 1080136620
1458
- },
1459
- chat_entry_type: 1,
1460
- from_limited_account: false,
1461
- message: "xxx",
1462
- ordinal: 0,
1463
- local_echo: false,
1464
- message_no_bbcode: "xxx",
1465
- low_priority: false,
1466
- server_timestamp: "2023-05-14T09:26:25.000Z",
1467
- message_bbcode_parsed: [
1468
- "xxx"
1469
- ]
1470
- }
1471
- const timestamp = new Date(data.server_timestamp).getTime()
1472
- const steamId = data.steamid_friend.getSteamID64()
1473
- const invite = [`Invited you to play a game!`, `Đã mời bạn chơi một trò chơi!`].includes(data.message_no_bbcode || data.message)
1474
- const emotion = (data.message_no_bbcode || '').split(' ').find(m => m.startsWith(':') && m.endsWith(':'))
1475
-
1476
- callEvent(events.friendMessage, {
1477
- ...data,
1478
- message: data.message_no_bbcode,
1479
- invite,
1480
- steamId,
1481
- timestamp,
1482
- emotion,
1483
- })
1484
- },
1485
- async friendTyping(steamId, message) {
1486
- callEvent(events.friendTyping, {
1487
- steamId, message
1488
- })
1489
- },
1490
- }
1491
-
1492
- // steamClient.on('lobbyInvite', (inviterID, lobbyID ) => {
1493
- // joinLobby(lobbyID)
1494
- // })
1495
-
1496
- // steamClient.on('debug', (msg) => {
1497
- // if (!["ClientPersonaState","ClientClanState"].some(c => msg.includes(c))) {
1498
- // if(msg.startsWith("Received")){
1499
- // console.log(`------- ${msg}`)
1500
- // } else {
1501
- // console.log(msg)
1502
- // }
1503
- // }
1504
- // })
1505
-
1506
-
1507
- function getECsgoGCMsgKey(_key) {
1508
- for (let key in Protos.csgo.ECsgoGCMsg) {
1509
- if (Protos.csgo.ECsgoGCMsg[key] == _key) {
1510
- return key
1511
- }
1512
- }
1513
- for (let key in Protos.csgo.EGCBaseClientMsg) {
1514
- if (Protos.csgo.EGCBaseClientMsg[key] == _key) {
1515
- return key
1516
- }
1517
- }
1518
- for (let key in Protos.csgo.EMsg) {
1519
- if (Protos.csgo.EMsg[key] == _key) {
1520
- return key
1521
- }
1522
- }
1523
- for (let key in Protos.csgo.EGCItemMsg) {
1524
- if (Protos.csgo.EGCItemMsg[key] == _key) {
1525
- return key
1526
- }
1527
- }
1528
- }
1529
-
1530
-
1531
- for (const [name, _event] of Object.entries(_events)) {
1532
- steamClient.on(name, _event)
1533
- }
1534
-
1535
- for (const [name, _event] of Object.entries(_chatEvents)) {
1536
- steamClient.chat.on(name, _event)
1537
- }
1538
- }
1539
-
1540
- function getHandlerResult(msg, handler) {
1541
- const timeout = {current: null}
1542
- return new Promise(resolve => {
1543
-
1544
- function myhandler(...args) {
1545
- timeout.current && clearTimeout(timeout.current)
1546
- removeHandler()
1547
- resolve(handler?.(...args))
1548
- }
1549
-
1550
- function removeHandler() {
1551
- if (Array.isArray(steamClient._handlerManager._handlers[msg])) {
1552
- const index = steamClient._handlerManager._handlers[msg].findIndex(_handler => _handler === myhandler)
1553
- if (index > -1) {
1554
- steamClient._handlerManager._handlers[msg].splice(index, 1)
1555
- }
1556
- }
1557
- }
1558
-
1559
- timeout.current = setTimeout(function () {
1560
- removeHandler()
1561
- resolve()
1562
- }, 60000)
1563
- steamClient._handlerManager.add(msg, myhandler);
1564
- })
1565
- }
1566
-
1567
- function getFriendList() {
1568
- return Object.keys(steamClient.myFriends).filter(steamId => steamClient.myFriends[steamId] === NodeSteamUser.EFriendRelationship.Friend)
1569
- }
1570
-
1571
- function sendFriendTyping(steamId, callback) {
1572
- steamClient.chat.sendFriendTyping(steamId, callback)
1573
- }
1574
-
1575
-
1576
- /*
1577
- * usually take 400 -> 800 miliseconds
1578
- * */
1579
- function getPlayersProfile(steamId) {
1580
- const accountid = new SteamID(steamId).accountid
1581
- steamClient.sendToGC(730, Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_ClientRequestPlayersProfile, {}, protoEncode(Protos.csgo.CMsgGCCStrike15_v2_ClientRequestPlayersProfile, {
1582
- account_id: accountid, // account_id: new SteamID('76561199184696945').accountid,
1583
- request_level: 32
1584
- }))
1585
- return new Promise(resolve => {
1586
- pushGCCallback('PlayersProfile_' + accountid, resolve, 2000)
1587
- })
1588
- }
1589
-
1590
- async function checkPlayerPrimeStatus(steamId) {
1591
- const profile = await getPlayersProfile(steamId)
1592
- if (!profile) return false
1593
-
1594
- if (profile.ranking?.account_id) {
1595
- return true
1596
- }
1597
-
1598
- if (profile.player_level || profile.player_cur_xp) {
1599
- return true
1600
- }
1601
- return false
1602
- }
1603
-
1604
- async function _getStoreSteamPoweredResponse(cookie) {
1605
- let response = null
1606
- for (let i = 0; i < 50; i++) {
1607
- if (!response) {
1608
- try {
1609
- response = (await axios.request({
1610
- url: 'https://store.steampowered.com/', headers: {
1611
- cookie,
1612
- accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.75',
1613
- },
1614
- }))
1615
- } catch (e) {
1616
- await sleep(1000)
1617
- }
1618
- }
1619
- }
1620
- return response
1621
- }
1622
-
1623
- async function getNewCookie(cookie) {
1624
- if (!cookie) {
1625
- return
1626
- }
1627
- let response = await _getStoreSteamPoweredResponse(cookie)
1628
- if (!response) {
1629
- return
1630
- }
1631
- while (Array.isArray(response?.headers?.["set-cookie"])) {
1632
- console.log(cookie);
1633
- const cookieObj = cookie.split(';').reduce(function (accumulator, currentValue) {
1634
- accumulator[currentValue.trim().split('=')[0].trim()] = currentValue.trim().split('=')[1].trim()
1635
- return accumulator
1636
- }, {})
1637
- for (const mcookie of response.headers["set-cookie"]) {
1638
- const name = mcookie.split('=')[0].trim()
1639
- const value = mcookie.split('=')[1].split(";")[0].trim()
1640
- cookieObj[name] = value
1641
- }
1642
- cookie = Object.keys(cookieObj).map(name => `${name}=${cookieObj[name]}`).join(';')
1643
- response = await _getStoreSteamPoweredResponse(cookie)
1644
- }
1645
- return cookie
1646
- }
1647
-
1648
- async function loginWithCookie(cookie, tryNewCookie = false) {
1649
- let response;
1650
- for (let i = 0; i < 20; i++) {
1651
- try {
1652
- response = (await axios.request({
1653
- url: 'https://steamcommunity.com/chat/clientjstoken',
1654
- headers: {
1655
- cookie,
1656
- },
1657
- }));
1658
- } catch (e) {
1659
- await sleep(1000)
1660
- }
1661
- if (response) {
1662
- break;
1663
- }
1664
- }
1665
-
1666
- const result = response?.data
1667
- if (result?.logged_in) {
1668
- Object.assign(result, {
1669
- steamID: new SteamID(result.steamid), accountName: result.account_name, webLogonToken: result.token
1670
- })
1671
- steamClient.logOn(result)
1672
- return cookie
1673
- } else {
1674
- if (tryNewCookie) {
1675
- log('You are not logged in', cookie)
1676
- return null
1677
- } else {
1678
- const newCookie = await getNewCookie(cookie)
1679
- if (!newCookie) {
1680
- console.error("Cannot get new cookie")
1681
- return null
1682
- } else {
1683
- return await loginWithCookie(newCookie, true)
1684
- }
1685
- }
1686
- }
1687
- }
1688
-
1689
- async function login(reconnect = false) {
1690
- if (clientJsToken?.logged_in === true) {
1691
- log(reconnect ? 'reconnect with clientJsToken' : 'login with clientJsToken')
1692
- steamClient.logOn(clientJsToken)
1693
- setTimeout(function () {
1694
- clientJsToken = null
1695
- }, 1000)
1696
- return true
1697
- } else if (cookie) {
1698
- log(reconnect ? 'reconnect with cookie' : 'login with cookie')
1699
- const _clientJsToken = await new SteamUser(typeof cookie === "function" ? await cookie() : cookie).getClientJsToken()
1700
- if (_clientJsToken?.logged_in === true) {
1701
- try {
1702
- await steamClient.logOn(_clientJsToken)
1703
- return true
1704
- } catch (e) {
1705
- return false
1706
- }
1707
- } else {
1708
- return false
1709
- }
1710
- } else if (username && password) {
1711
- log(reconnect ? `reconnect with username ${username}` : `login with username ${username}`)
1712
- steamClient.logOn({
1713
- accountName: username, password: password, rememberPassword: true, machineName: 'Natri',
1714
- })
1715
- return true
1716
- }
1717
- }
1718
-
1719
- async function logOff() {
1720
- isLogOff = true
1721
- logOffEvent?.(true)
1722
- steamClient.logOff()
1723
- }
1724
-
1725
- function onCookie(callback) {
1726
- if (getCookies()) {
1727
- callback(getCookies())
1728
- } else {
1729
- onEvent('webSession', function (webSession) {
1730
- callback(webSession?.cookies?.join?.(';'))
1731
- }, true)
1732
- }
1733
- }
1734
-
1735
- function init() {
1736
- bindEvent()
1737
- login()
1738
-
1739
- steamClient._handlerManager.add(Protos.csgo.EMsg.k_EMsgClientRequestedClientStats, function (payload) {
1740
- const result = protoDecode(Protos.csgo.CMsgClientRequestedClientStats, payload.toBuffer())
1741
- // console.log("CMsgClientRequestedClientStats", result);
1742
- })
1743
- steamClient._handlerManager.add(Protos.csgo.EMsg.k_EMsgClientMMSLobbyData, function (payload) {
1744
- const result = protoDecode(Protos.csgo.CMsgClientMMSLobbyData, payload.toBuffer())
1745
- // console.log("CMsgClientMMSLobbyData", result, result.metadata);
1746
- })
1747
- }
1748
-
1749
-
1750
- function partyRegister() {
1751
- if (prime === null) {
1752
- _partyRegister(true)
1753
- _partyRegister(false)
1754
- } else {
1755
- _partyRegister(prime)
1756
- }
1757
- }
1758
-
1759
- function _partyRegister(prime) {
1760
- log("partyRegister", prime)
1761
- lastTimePartyRegister = new Date().getTime()
1762
- steamClient.sendToGC(730, Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Party_Register, {}, protoEncode(Protos.csgo.CMsgGCCStrike15_v2_Party_Register, {
1763
- // id : 0,
1764
- ver: CSGO_VER,
1765
- apr: prime ? 1 : 0,//prime
1766
- ark: prime ? 180 : 0, grps: [], launcher: 0, game_type: 8
1767
- }))
1768
- }
1769
-
1770
- async function sendFriendMessage(steamId, message) {
1771
- while (sendMessageTimestamp && new Date().getTime() - sendMessageTimestamp < 2000) {
1772
- await sleep(1000)
1773
- }
1774
-
1775
- while (isSendingFriendMessages) {
1776
- await sleep(5000)
1777
- }
1778
-
1779
- isSendingFriendMessages = true
1780
- const now = new Date().getTime()
1781
- while (new Date().getTime() - now < 2 * 60000) {//2 minutes
1782
- const result = await new Promise(resolve => {
1783
- steamClient.chat.sendFriendMessage(steamId, message, undefined, function (...arg) {
1784
- sendMessageTimestamp = new Date().getTime()
1785
- resolve(arg)
1786
- });
1787
- })
1788
-
1789
- if (result?.[1]?.server_timestamp) {
1790
- isSendingFriendMessages = false
1791
- return result?.[1]
1792
- } else if (result?.[0]?.message?.includes?.("RateLimitExceeded")) {
1793
- await sleep(5000)
1794
- } else {
1795
- isSendingFriendMessages = false
1796
- return result
1797
- }
1798
- }
1799
- isSendingFriendMessages = false
1800
- }
1801
-
1802
- async function autoRequestFreeLicense(shouldLog = false, max = 10) {
1803
- return
1804
- // const mCookies = await getCookiesWait()
1805
- // if (!mCookies) return
1806
- // let freeAppList = Array.isArray(steamClient.licenses) ? FreeAppList.filter(appId => steamClient.licenses.every(({package_id}) => package_id !== appId)) : FreeAppList;
1807
- const freeAppList = freeAppList.filter(appId => ownedApps.some(app => app.appid == appId))
1808
- const recommendedApps = _.shuffle(freeAppList)
1809
- if (max) {
1810
- recommendedApps.length = Math.min(recommendedApps.length, max)
1811
- }
1812
- try {
1813
- const response = await steamClient.requestFreeLicense(recommendedApps)
1814
- if (shouldLog) {
1815
- log(response)
1816
- }
1817
- } catch (e) {
1818
- log(e);
1819
- }
1820
- // if (Math.random() > 0.7) {
1821
- // for (const recommendedApp of recommendedApps) {
1822
- // try {
1823
- // await steamUtils.requestFreeLicense(recommendedApp)
1824
- // } catch (e) {
1825
- // }
1826
- // await sleep(2000)
1827
- // }
1828
- // } else {
1829
- // try {
1830
- // await steamClient.requestFreeLicense(recommendedApps)
1831
- // } catch (e) {
1832
- // log(e);
1833
- // }
1834
- // }
1835
-
1836
- // if (shouldLog) {
1837
- // await sleep(20000)
1838
- // const ownedAppsCount2 = (await steamUtils.getDynamicStoreUserData())?.rgOwnedApps?.length || 0
1839
- // const increaseNumber = ownedAppsCount2 - ownedAppsCount;
1840
- // log(`OwnedApps length ${ownedAppsCount2}, increase ${increaseNumber}`)
1841
- // }
1842
- }
1843
-
1844
- async function playCSGO() {
1845
- try {
1846
- await steamClient.requestFreeLicense(AppID)
1847
- await sleep(5000)
1848
- } catch (e) {
1849
- }
1850
- gamesPlayed(AppID)
1851
- }
1852
-
1853
- function doFakeGameScore() {
1854
- const maxRound = Math.random() > 0.7 ? 16 : 12
1855
- const maps = [
1856
- "ar_baggage",
1857
- "ar_dizzy",
1858
- "ar_monastery",
1859
- "ar_shoots",
1860
- "cs_agency",
1861
- "cs_assault",
1862
- "cs_italy",
1863
- "cs_militia",
1864
- "cs_office",
1865
- "de_ancient",
1866
- "de_anubis",
1867
- "de_bank",
1868
- "de_boyard",
1869
- "de_cache",
1870
- "de_canals",
1871
- "de_cbble",
1872
- "de_chalice",
1873
- "de_dust2",
1874
- "de_inferno",
1875
- "de_lake",
1876
- "de_mirage",
1877
- "de_nuke",
1878
- "de_overpass",
1879
- "de_safehouse",
1880
- // "de_shortnuke",
1881
- "de_stmarc",
1882
- "de_sugarcane",
1883
- "de_train",
1884
- "de_tuscan",
1885
- "de_vertigo",
1886
- "dz_ember",
1887
- "dz_vineyard",
1888
- "gd_cbble",
1889
- "training1"
1890
- ]
1891
-
1892
- if (richPresence.myScore === undefined) {
1893
- richPresence.myScore = _.random(0, maxRound)
1894
- }
1895
- if (richPresence.theirScore === undefined) {
1896
- richPresence.theirScore = _.random(0, maxRound)
1897
- }
1898
- if (richPresence.map === undefined) {
1899
- richPresence.map = maps[Math.floor(Math.random() * maps.length)]
1900
- }
1901
- if (richPresence.myScore === maxRound || richPresence.theirScore === maxRound) {
1902
- richPresence.myScore = 0
1903
- richPresence.theirScore = 0
1904
- richPresence.map = maps[Math.floor(Math.random() * maps.length)]
1905
- } else {
1906
- const isMyTeamWin = Math.random() > 0.5
1907
- if (isMyTeamWin) {
1908
- richPresence.myScore++
1909
- } else {
1910
- richPresence.theirScore++
1911
- }
1912
- }
1913
-
1914
- const score = richPresence.myScore === 0 && richPresence.theirScore === 0 ? '' : `[ ${richPresence.myScore} : ${richPresence.theirScore} ]`
1915
- steamClient.uploadRichPresence(730, {
1916
- 'game:state': 'game',
1917
- steam_display: '#display_GameKnownMapScore',
1918
- connect: '+gcconnectG082AA752',
1919
- version: CSGO_VER.toString(),
1920
- 'game:mode': 'competitive',
1921
- 'game:map': richPresence.map,
1922
- 'game:server': 'kv',
1923
- 'watch': _.random(1, 5).toString(),
1924
- 'game:score': score,
1925
- })
1926
- }
1927
-
1928
- function updateFakeGameScore() {
1929
- if (isFakeGameScore && getPlayingAppIds().some(a => a == 730)) {
1930
- doSetInterval(doFakeGameScore, [60000, 180000], 'uploadRichPresenceCSGO')
1931
- } else {
1932
- doClearInterval('uploadRichPresenceCSGO')
1933
- }
1934
- }
1935
-
1936
- function updateAutoRequestFreeLicense() {
1937
- if (isAutoRequestFreeLicense) {
1938
- doSetInterval(function () {
1939
- autoRequestFreeLicense(false, 50)
1940
- }, [5 * 60000, 10 * 60000], 'autoRequestFreeLicense')
1941
- } else {
1942
- doClearInterval('autoRequestFreeLicense')
1943
- }
1944
- }
1945
-
1946
- function updateInvisible() {
1947
- if (isInvisible) {
1948
- steamClient.setPersona(NodeSteamUser.EPersonaState.Invisible)
1949
- state = 'Invisible'
1950
- } else {
1951
- steamClient.setPersona(NodeSteamUser.EPersonaState.Online)
1952
- state = 'Online'
1953
- }
1954
- }
1955
-
1956
- async function gamesPlayed(apps) {
1957
- if (!Array.isArray(apps)) {
1958
- apps = [apps]
1959
- }
1960
-
1961
- steamClient.gamesPlayed(apps);
1962
- const shouldHello = apps.some(app => parseInt(app) === 730);
1963
- await sleep(1000)
1964
- if (shouldHello) {
1965
- await sendHello()
1966
- }
1967
- await sleep(1000)
1968
- if (shouldHello) {
1969
- await sendHello()
1970
- }
1971
- updateFakeGameScore()
1972
-
1973
- // await sleep(10000)
1974
- // self.steamUser.uploadRichPresence(730, {
1975
- // status: 'bussssss',
1976
- // 'game:state': 'lobby',
1977
- // steam_display: '#display_watch',
1978
- // currentmap: '#gamemap_de_empire',
1979
- // connect: '+gcconnectG082AA752',
1980
- // 'game:mode': 'competitive'
1981
- // })
1982
- }
1983
-
1984
- function getFriendsList() {
1985
- const methodName = "FriendsList.GetFriendsList#1"
1986
- const {users, myFriends} = steamClient//object
1987
- /*
1988
- users
1989
- * {
1990
- rich_presence: [],
1991
- player_name: "Kei #SkinsMonkey",
1992
- avatar_hash: [123,4543],
1993
- last_logoff: "2023-05-20T05:00:42.000Z",
1994
- last_logon: "2023-05-20T05:02:16.000Z",
1995
- last_seen_online: "2023-05-20T05:00:42.000Z",
1996
- avatar_url_icon: "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/3e/3e9da0b107ac2ec384759544368a8a977359537a.jpg",
1997
- avatar_url_medium: "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/3e/3e9da0b107ac2ec384759544368a8a977359537a_medium.jpg",
1998
- avatar_url_full: "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/3e/3e9da0b107ac2ec384759544368a8a977359537a_full.jpg"
1999
- }
2000
- *
2001
-
2002
- myFriends
2003
- {
2004
- 76561198365087582: 3,
2005
- 76561199490395123: 3
2006
- }
2007
- * */
2008
- /*steamClient._send({
2009
- msg: 151,
2010
- proto: {
2011
- target_job_name: methodName
2012
- }
2013
- }, Buffer.alloc(0), function (body, hdr) {
2014
- const result = hdr.proto.eresult
2015
- const errorMessage = hdr.proto.error_message
2016
- const responseData = body.toBuffer()
2017
- console.log(`xxx`, result)
2018
- })*/
2019
-
2020
- steamClient.sendToGC(730, 767, {}, Buffer.alloc(0))
2021
- }
2022
-
2023
- async function getUserOwnedApps(steamId = steamClient.steamID) {
2024
- if (!steamId) {
2025
- return []
2026
- }
2027
- if (typeof steamId?.getSteamID64 === "function") {
2028
- steamId = steamId.getSteamID64()
2029
- }
2030
- const isMe = steamId === steamClient.steamID.getSteamID64();
2031
- if (isMe && ownedApps.length) {
2032
- return ownedApps
2033
- }
2034
- let result = {}
2035
- try {
2036
- result = await steamClient.getUserOwnedApps(steamId)
2037
- } catch (e) {
2038
- try {
2039
- result = await steamClient.getUserOwnedApps(steamId)
2040
- } catch (e) {
2041
- result = {}
2042
- }
2043
- }
2044
- if (isMe && Array.isArray(result.apps)) {
2045
- ownedApps.length = 0
2046
- ownedApps.push(...result.apps)
2047
- }
2048
- return result.apps || []
2049
- const resultExample = {
2050
- app_count: 22,
2051
- apps: [
2052
- {
2053
- content_descriptorids: [],
2054
- appid: 208030,
2055
- name: "Moon Breakers",
2056
- playtime_2weeks: null,
2057
- playtime_forever: 0,
2058
- img_icon_url: "",
2059
- has_community_visible_stats: null,
2060
- playtime_windows_forever: 0,
2061
- playtime_mac_forever: 0,
2062
- playtime_linux_forever: 0,
2063
- rtime_last_played: 0,
2064
- capsule_filename: null,
2065
- sort_as: null,
2066
- has_workshop: null,
2067
- has_market: null,
2068
- has_dlc: null,
2069
- has_leaderboards: null
2070
- },
2071
- ]
2072
- }
2073
- }
2074
-
2075
- function getPlayingAppIds() {
2076
- return steamClient._playingAppIds || []
2077
- }
2078
-
2079
- return {
2080
- init,
2081
- partySearch,
2082
- invite2Lobby,
2083
- createLobby,
2084
- updateLobby,
2085
- createThenInvite2Lobby,
2086
- joinLobby,
2087
- getLobbyData,
2088
- partyRegister,
2089
- requestCoPlays,
2090
- getPersonas,
2091
- getUsername() {
2092
- return username
2093
- },
2094
- getCookies,
2095
- getCookiesWait,
2096
- getLogOnDetails() {
2097
- return steamClient?._logOnDetails
2098
- },
2099
- onEvent,
2100
- offEvent,
2101
- offAllEvent,
2102
- setPersona(state, name) {
2103
- steamClient.setPersona(state, name)
2104
- },
2105
- sendFriendMessage,
2106
- sendFriendTyping,
2107
- getSteamClient() {
2108
- return steamClient
2109
- },
2110
- getAccountInfoName,
2111
- getPersonaName,
2112
- async getPlayersProfile(steamId, retry = 3) {
2113
- for (let i = 0; i < retry; i++) {
2114
- const profile = await getPlayersProfile(steamId)
2115
- if (profile) {
2116
- return profile
2117
- }
2118
- }
2119
- return null
2120
- },
2121
- autoRequestFreeLicense,
2122
- playCSGO,
2123
- doSetInterval,
2124
- doClearIntervals,
2125
- gamesPlayed,
2126
- sendHello,
2127
- checkPlayerPrimeStatus,
2128
- doClearInterval,
2129
- gamePlay,
2130
- autoGamePlay,
2131
- offAutoGamePlay,
2132
- updateAutoGamePlay,
2133
- getFriendsList,
2134
- setIsPartyRegister(change) {
2135
- change = !!change
2136
- if (isPartyRegister !== change) {
2137
- isPartyRegister = change
2138
- if (!isPartyRegister) {
2139
- doClearInterval('autoPartyRegister')
2140
- } else {
2141
- sendHello()
2142
- }
2143
- }
2144
- },
2145
- setAutoPlay(change) {
2146
- change = !!change
2147
- if (isAutoPlay !== change) {
2148
- isAutoPlay = change
2149
- updateAutoGamePlay()
2150
- }
2151
- },
2152
- setIsInvisible(change) {
2153
- change = !!change
2154
- if (isInvisible !== change) {
2155
- isInvisible = change
2156
- updateInvisible()
2157
- }
2158
- },
2159
- setFakeGameScore(change) {
2160
- change = !!change
2161
- if (isFakeGameScore !== change) {
2162
- isFakeGameScore = change
2163
- updateFakeGameScore()
2164
- }
2165
- },
2166
- setAutoRequestFreeLicense(change) {
2167
- change = !!change
2168
- if (isAutoRequestFreeLicense !== change) {
2169
- isAutoRequestFreeLicense = change
2170
- updateAutoRequestFreeLicense()
2171
- }
2172
- },
2173
- getState() {
2174
- return state
2175
- },
2176
- log,
2177
- isPrime() {
2178
- return prime === true
2179
- },
2180
- getFriendList,
2181
- logOff,
2182
- isPlayingBlocked() {
2183
- return playingBlocked
2184
- },
2185
- async getChatHistory(steamId) {
2186
- if (!steamClient.steamID) return []
2187
- const mySteamId = typeof steamClient.steamID.getSteamID64 === "function" ? steamClient.steamID.getSteamID64() : steamClient.steamID
2188
- return new Promise(resolve => {
2189
- setTimeout(resolve, 90000)
2190
- steamClient.getChatHistory(steamId, async function (error, result) {
2191
- const messages = (result || []).map(function (msg) {
2192
- const fromSteamId = typeof msg.steamID?.getSteamID64 === "function" ? msg.steamID.getSteamID64() : msg.steamID
2193
- return {
2194
- message: msg.message,
2195
- from: fromSteamId,
2196
- to: fromSteamId == mySteamId ? steamId : mySteamId,
2197
- _id: new Date(msg.timestamp).getTime().toString(),
2198
- timestamp: new Date(msg.timestamp).getTime(),
2199
- isMe: fromSteamId !== steamId
2200
- };
2201
- })
2202
- resolve(messages)
2203
- })
2204
- })
2205
- },
2206
- onAnyEvent,
2207
- async redeemGift(gid) {
2208
- try {
2209
- const community = new SteamCommunity();
2210
- let cookies = await getCookiesWait();
2211
- community.setCookies(typeof cookies === "string" ? cookies.split(';') : cookies)
2212
- community.redeemGift(gid)
2213
- } catch (e) {
2214
- }
2215
- },
2216
- async requestFreeLicense(...args) {
2217
- try {
2218
- return await steamClient.requestFreeLicense(...args)
2219
- } catch (e) {
2220
- }
2221
- },
2222
- getSteamId() {
2223
- try {
2224
- return steamClient.steamID.getSteamID64()
2225
- } catch (e) {
2226
- }
2227
- },
2228
- getLastTimePartyRegister() {
2229
- return lastTimePartyRegister
2230
- },
2231
- getLastTimePartySearch() {
2232
- return lastTimePartySearch
2233
- },
2234
- getLicenses() {
2235
- return steamClient.licenses
2236
- const exampleLicenses = [{
2237
- package_id: 303386,
2238
- time_created: 1680491335,
2239
- time_next_process: 0,
2240
- minute_limit: 0,
2241
- minutes_used: 0,
2242
- payment_method: 1024,
2243
- flags: 512,
2244
- purchase_country_code: "VN",
2245
- license_type: 1,
2246
- territory_code: 0,
2247
- change_number: 20615891,
2248
- owner_id: 1530068060,
2249
- initial_period: 0,
2250
- initial_time_unit: 0,
2251
- renewal_period: 0,
2252
- renewal_time_unit: 0,
2253
- access_token: "8049398090486337961",
2254
- master_package_id: null
2255
- }]
2256
- },
2257
- uploadRichPresence(appid, richPresence) {
2258
- if (Array.isArray(richPresence)) {
2259
- richPresence = richPresence.reduce(function (previousValue, currentValue, currentIndex, array) {
2260
- if (currentValue.key) {
2261
- previousValue[currentValue.key] = currentValue.value?.toString() || ''
2262
- }
2263
- return previousValue
2264
- })
2265
- }
2266
- steamClient.uploadRichPresence(appid, richPresence)
2267
- },
2268
- getUserOwnedApps,
2269
- getPlayingAppIds,
2270
- getCurrentLobby() {
2271
- return currentLobby
2272
- }
2273
- }
2274
- }
2275
-
2276
- export default SteamClient
2277
-
2278
- export function increaseCSGO_VER() {
2279
- return ++CSGO_VER
2280
- }
2281
-
2282
- SteamClient.isAccountPlayable = async function isAccountPlayable(params, timeoutMs) {
2283
- let clientJsToken = params.clientJsToken
2284
- delete params.clientJsToken
2285
- if(!clientJsToken && params.cookie){
2286
- clientJsToken = await new SteamUser(typeof params.cookie === "function" ? await params.cookie() : params.cookie).getClientJsToken()
2287
- }
2288
- if (clientJsToken?.logged_in !== true) {
2289
- return false
2290
- }
2291
- params.clientJsToken = clientJsToken
2292
-
2293
- return await new Promise((resolve) => {
2294
- const timeout = setTimeout(() => {
2295
- doResolve();
2296
- }, timeoutMs || 30000);
2297
-
2298
- const steamClient = new SteamClient({
2299
- isFakeGameScore: false,
2300
- isAutoPlay: true,
2301
- isPartyRegister: false,
2302
- isInvisible: false,
2303
- MAX_GAME_PLAY: 10,
2304
- games: 730,
2305
- ...params,
2306
- });
2307
-
2308
- steamClient.onEvent("error", ({eresult, msg, error}) => {
2309
- doResolve();
2310
- });
2311
-
2312
- steamClient.onEvent("csgoOnline", ClientWelcome => {
2313
- doResolve(ClientWelcome);
2314
- });
2315
-
2316
- steamClient.onEvent("csgoClientHello", ClientHello => {
2317
- doResolve(ClientHello);
2318
- });
2319
-
2320
- steamClient.onEvent("playingState", ({playing_blocked, playing_app}) => {
2321
- if (playing_blocked) {
2322
- doResolve();
2323
- }
2324
- },
2325
- );
2326
-
2327
- steamClient.init();
2328
-
2329
- function doResolve(data) {
2330
- clearTimeout(timeout);
2331
- steamClient.doClearIntervals();
2332
- steamClient.offAllEvent();
2333
- steamClient.logOff();
2334
- return resolve(!!data);
2335
- }
2336
- });
2337
- }
1
+ import NodeSteamUser from "steam-user";
2
+ import _ from "lodash";
3
+ import fs from "fs";
4
+ import { protoDecode, protoEncode } from "./helpers/util.js";
5
+ import SteamID from "steamid";
6
+ import FriendCode from "csgo-friendcode";
7
+ import axios from "axios";
8
+ import helpers, { loadProfos } from "./helpers/protos.js";
9
+ import { fileURLToPath } from "url";
10
+ import path from "path";
11
+ import SteamUser from "./index.js";
12
+ import { v4 as uuidv4 } from "uuid";
13
+ import EFriendRelationship from "steam-user/enums/EFriendRelationship.js";
14
+ import SteamCommunity from "steamcommunity";
15
+ import moment from "moment-timezone";
16
+ import { encode, encodeUids } from "./bufferHelpers.js";
17
+
18
+ const __filename = fileURLToPath(import.meta.url);
19
+ const __dirname = path.dirname(__filename);
20
+
21
+ const Protos = helpers([
22
+ {
23
+ name: "csgo",
24
+ protos: loadProfos(`${__dirname}/protos/`),
25
+ },
26
+ ]);
27
+
28
+ export const RANKS = {
29
+ 0: "Unranked",
30
+ 1: "Silver I",
31
+ 2: "Silver II",
32
+ 3: "Silver III",
33
+ 4: "Silver IV",
34
+ 5: "Silver Elite",
35
+ 6: "Silver Elite Master",
36
+ 7: "Gold Nova I",
37
+ 8: "Gold Nova II",
38
+ 9: "Gold Nova III",
39
+ 10: "Gold Nova Master",
40
+ 11: "Master Guardian I",
41
+ 12: "Master Guardian II",
42
+ 13: "Master Guardian Elite",
43
+ 14: "Distinguished Master Guardian",
44
+ 15: "Legendary Eagle",
45
+ 16: "Legendary Eagle Master",
46
+ 17: "Supreme Master First Class",
47
+ 18: "The Global Elite",
48
+ };
49
+ export const LOCS = {
50
+ 20054: "VN",
51
+ 23115: "KZ",
52
+ 20041: "IN",
53
+ 20035: "CN",
54
+ 17474: "BD",
55
+ 17481: "ID",
56
+ 22861: "MY",
57
+ 18516: "TH",
58
+ 22356: "TW",
59
+ 21067: "KR",
60
+ 19272: "HK",
61
+ 18512: "PH",
62
+ 21842: "RU",
63
+ 16716: "LA",
64
+ 20558: "NP",
65
+ 18259: "SG",
66
+ 19789: "MM",
67
+ 20045: "MN",
68
+ 18251: "KG",
69
+ 18507: "KH",
70
+ 22605: "MX",
71
+ 19280: "PK",
72
+ 20301: "HK/MO", //hongkong or macau
73
+ 21333: "Unknown",
74
+ 21825: "AU",
75
+ 20034: "Unkown",
76
+ };
77
+
78
+ const AppID = 730;
79
+ export let CSGO_VER = 13960;
80
+ export const FreeAppList = JSON.parse(fs.readFileSync(path.join(__dirname, "free_packages.json"))).packages;
81
+
82
+ SteamUser.getAppVersion(AppID).then(function (ver) {
83
+ CSGO_VER = ver;
84
+ });
85
+
86
+ const PersonasCache = [];
87
+ let isSendingFriendMessages = false;
88
+
89
+ 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 }) {
90
+ const steamClient = new NodeSteamUser();
91
+ let prime = null;
92
+ let state = "Offline"; //InGame, Online, Invisible
93
+ let isLogOff = false;
94
+ let playingBlocked = null;
95
+ const richPresence = {};
96
+ let sendMessageTimestamp = 0;
97
+ let lastTimePartyRegister = 0;
98
+ let lastTimePartySearch = 0;
99
+ const ownedApps = [];
100
+ let logOffEvent = null;
101
+
102
+ const currentLobby = {
103
+ lobbyID: null,
104
+ timestamp: 0,
105
+ };
106
+
107
+ const onAnyCallbacks = [];
108
+
109
+ const events = {
110
+ user: [],
111
+ loggedOn: [],
112
+ csgoOnline: [],
113
+ csgoClientHello: [],
114
+ webSession: [],
115
+ friendMessage: [],
116
+ friendTyping: [],
117
+ disconnected: [],
118
+ error: [],
119
+ playersProfile: [],
120
+ fatalError: [],
121
+ partyInvite: [],
122
+ friendRelationship: [],
123
+ tradeOffers: [],
124
+ offlineMessages: [],
125
+ friendsList: [],
126
+ gifts: [],
127
+ playingState: [],
128
+ emailInfo: [],
129
+ accountLimitations: [],
130
+ };
131
+
132
+ const gcCallback = {};
133
+
134
+ function pushGCCallback(name, cb, timeout) {
135
+ if (!gcCallback[name]) {
136
+ gcCallback[name] = {};
137
+ }
138
+ let t = null;
139
+ let id = uuidv4();
140
+
141
+ function callback(...arg) {
142
+ if (t) {
143
+ clearTimeout(t);
144
+ }
145
+ delete gcCallback[name][id];
146
+ cb?.apply(null, arg);
147
+ }
148
+
149
+ if (timeout) {
150
+ t = setTimeout(callback, timeout);
151
+ }
152
+ gcCallback[name][id] = callback;
153
+ }
154
+
155
+ function callGCCallback(name, ...arg) {
156
+ if (gcCallback[name]) {
157
+ for (const id in gcCallback[name]) {
158
+ gcCallback[name][id]?.(...arg);
159
+ }
160
+ }
161
+ }
162
+
163
+ function callEvent(_events, data) {
164
+ const eventName = Object.keys(events).find((eventName) => events[eventName] === _events);
165
+ eventName && onAnyCallbacks.forEach((cb) => cb?.({ eventName, data }));
166
+
167
+ _events?.forEach?.((e) => {
168
+ e.callback?.(data);
169
+ e.timeout && clearTimeout(e.timeout);
170
+ delete e.timeout;
171
+ if (e.once) {
172
+ delete e.callback;
173
+ }
174
+ });
175
+ _.remove(_events, (e) => !e || e?.once);
176
+ }
177
+
178
+ function onEvent(name, callback, once, timeout) {
179
+ if (!events[name]) {
180
+ events[name] = [];
181
+ }
182
+ const t = timeout ? setTimeout(callback, timeout) : null;
183
+ events[name].push({
184
+ once,
185
+ callback,
186
+ timeout: t,
187
+ });
188
+ }
189
+
190
+ function offEvent(name) {
191
+ if (Array.isArray(events[name])) {
192
+ for (const eventElement of events[name]) {
193
+ if (eventElement.timeout) {
194
+ clearTimeout(eventElement.timeout);
195
+ }
196
+ }
197
+ }
198
+
199
+ delete events[name];
200
+ }
201
+
202
+ function onAnyEvent(callback) {
203
+ onAnyCallbacks.push(callback);
204
+ }
205
+
206
+ function offAllEvent() {
207
+ for (const name in events) {
208
+ for (const event of events[name]) {
209
+ if (event.timeout) {
210
+ try {
211
+ clearTimeout(event.timeout);
212
+ } catch (e) {}
213
+ delete event.timeout;
214
+ }
215
+ }
216
+ delete events[name];
217
+ }
218
+ onAnyCallbacks.length = 0;
219
+ }
220
+
221
+ const intervals = {};
222
+ const intervalRandoms = {};
223
+
224
+ function doSetInterval(cb, timeout, key) {
225
+ const isRandom = Array.isArray(timeout);
226
+ if (!key) {
227
+ key = uuidv4();
228
+ }
229
+ if (isRandom) {
230
+ if (intervalRandoms[key] !== undefined) {
231
+ try {
232
+ clearTimeout(intervalRandoms[key]);
233
+ } catch (e) {}
234
+ }
235
+ intervalRandoms[key] = setTimeout(
236
+ function () {
237
+ doSetInterval(cb, timeout, key);
238
+ if (state !== "Offline") {
239
+ cb();
240
+ }
241
+ },
242
+ _.random(timeout[0], timeout[1]),
243
+ );
244
+ } else {
245
+ if (intervals[key] !== undefined) {
246
+ try {
247
+ clearInterval(intervals[key]);
248
+ } catch (e) {}
249
+ }
250
+
251
+ intervals[key] = setInterval(function () {
252
+ if (state !== "Offline") {
253
+ cb();
254
+ }
255
+ }, timeout);
256
+ }
257
+
258
+ return key;
259
+ }
260
+
261
+ function doClearIntervals() {
262
+ for (const key in intervals) {
263
+ clearInterval(intervals[key]);
264
+ delete intervals[key];
265
+ }
266
+ for (const key in intervalRandoms) {
267
+ clearTimeout(intervalRandoms[key]);
268
+ delete intervalRandoms[key];
269
+ }
270
+ }
271
+
272
+ function doClearInterval(key) {
273
+ try {
274
+ clearInterval(intervals[key]);
275
+ } catch (e) {}
276
+ delete intervals[key];
277
+
278
+ try {
279
+ clearTimeout(intervalRandoms[key]);
280
+ } catch (e) {}
281
+ delete intervalRandoms[key];
282
+ }
283
+
284
+ function getAccountInfoName() {
285
+ return [steamClient?.accountInfo?.name, steamClient?._logOnDetails?.account_name].filter(Boolean).join(" - ");
286
+ }
287
+
288
+ function getPersonaName() {
289
+ return steamClient?.accountInfo?.name;
290
+ }
291
+
292
+ function log(...msg) {
293
+ const now = moment().tz("Asia/Ho_Chi_Minh").format("DD/MM/YYYY HH:mm:ss");
294
+ console.log(`[${now}] [${getAccountInfoName()}]`, ...msg);
295
+ }
296
+
297
+ async function getPersonas(steamIDs) {
298
+ steamIDs = steamIDs.map((steamId) => (steamId instanceof SteamID ? steamId.getSteamID64() : steamId));
299
+ const notCachesteamIDs = steamIDs.filter((id) => !PersonasCache.some((p) => p.id == id));
300
+ const cachedPersonas = PersonasCache.filter((p) => steamIDs.includes(p.id));
301
+
302
+ if (notCachesteamIDs.length) {
303
+ let personas = null;
304
+ try {
305
+ personas = (await steamClient.getPersonas(notCachesteamIDs))?.personas;
306
+ } catch (e) {}
307
+ if (!personas || !Object.keys(personas).length) {
308
+ try {
309
+ personas = (await steamClient.getPersonas(notCachesteamIDs))?.personas;
310
+ } catch (e) {}
311
+ }
312
+ if (!personas || !Object.keys(personas).length) {
313
+ try {
314
+ personas = (await steamClient.getPersonas(notCachesteamIDs))?.personas;
315
+ } catch (e) {}
316
+ }
317
+ if (personas && Object.keys(personas).length) {
318
+ for (let sid64 in personas) {
319
+ personas[sid64].id = sid64;
320
+ personas[sid64].avatar_hash = Buffer.from(personas[sid64].avatar_hash).toString("hex");
321
+ PersonasCache.push(personas[sid64]);
322
+ cachedPersonas.push(personas[sid64]);
323
+ }
324
+ }
325
+ }
326
+
327
+ while (PersonasCache.length > 500) {
328
+ PersonasCache.shift();
329
+ }
330
+ return cachedPersonas;
331
+ }
332
+
333
+ function sleep(ms) {
334
+ return new Promise((resolve) => {
335
+ setTimeout(resolve, ms);
336
+ });
337
+ }
338
+
339
+ function getCookies() {
340
+ return cookie || steamClient?.webSession?.cookies?.join?.(";");
341
+ }
342
+
343
+ async function getCookiesWait() {
344
+ return (
345
+ getCookies() ||
346
+ new Promise((resolve) => {
347
+ onEvent(
348
+ "webSession",
349
+ function (webSession) {
350
+ resolve(webSession?.cookies);
351
+ },
352
+ true,
353
+ 30000,
354
+ );
355
+ })
356
+ );
357
+ }
358
+
359
+ async function gamePlay() {
360
+ if ((Array.isArray(games) && games.length) || (games && (typeof games === "number" || typeof games === "string"))) {
361
+ return gamesPlayed(games);
362
+ }
363
+
364
+ let ownedApps = [];
365
+ for (let i = 0; i < 5; i++) {
366
+ ownedApps = await getUserOwnedApps();
367
+ if (ownedApps?.length) {
368
+ break;
369
+ }
370
+ }
371
+ if (!ownedApps?.length) {
372
+ gamesPlayed(730);
373
+ } else {
374
+ ownedApps = ownedApps.map(({ appid }) => appid);
375
+ ownedApps = _.shuffle(ownedApps);
376
+ ownedApps.length = Math.min(ownedApps.length, MAX_GAME_PLAY - 1);
377
+ _.remove(ownedApps, (app) => app == 730);
378
+ gamesPlayed([...ownedApps, 730]);
379
+ }
380
+ }
381
+
382
+ async function autoGamePlay() {
383
+ await gamePlay();
384
+ doSetInterval(gamePlay, [15 * 60000, 30 * 60000], "autoGamePlay");
385
+ }
386
+
387
+ async function offAutoGamePlay() {
388
+ steamClient.gamesPlayed([]);
389
+ doClearInterval("autoGamePlay");
390
+ }
391
+
392
+ async function updateAutoGamePlay() {
393
+ if (isAutoPlay) {
394
+ autoGamePlay();
395
+ } else {
396
+ offAutoGamePlay();
397
+ }
398
+ }
399
+
400
+ /**
401
+ * Get a list of lobbies (* = Unsure description could be wrong)
402
+ * @param {Number} ver Game version we are searching for
403
+ * @param {Boolean} apr Prime or not*
404
+ * @param {Number} ark Rank multiplied by 10*
405
+ * @param {Array.<Number>} grps *
406
+ * @param {Number} launcher If we are using the China CSGO launcher or not*
407
+ * @param {Number} game_type Game type, 8 Competitive, 10 Wingman
408
+ * @returns {Promise.<Object>}
409
+ */
410
+ async function partySearch({ prime = false, game_type = "Competitive", rank = "Silver Elite", timeout = 5000 } = {}) {
411
+ const players = await new Promise((resolve) => {
412
+ steamClient.sendToGC(
413
+ AppID,
414
+ Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Party_Search,
415
+ {},
416
+ protoEncode(Protos.csgo.CMsgGCCStrike15_v2_Party_Search, {
417
+ ver: CSGO_VER,
418
+ apr: prime ? 1 : 0,
419
+ ark: parseInt(Object.keys(RANKS).find((k) => RANKS[k] === rank)) * 10,
420
+ grps: [],
421
+ launcher: 0,
422
+ game_type: game_type === "Competitive" ? 8 : 10,
423
+ }),
424
+ );
425
+ lastTimePartySearch = new Date().getTime();
426
+ pushGCCallback("partySearch", resolve, timeout);
427
+ });
428
+ if (Array.isArray(players) && players.length) {
429
+ const personas = await getPersonas(players.map((p) => p.steamId));
430
+ for (const player of players) {
431
+ const persona = personas.find((p) => p.id == player.steamId);
432
+ if (persona) {
433
+ player.player_name = persona.player_name;
434
+ player.avatar_hash = persona.avatar_hash;
435
+ }
436
+ }
437
+ }
438
+ return players;
439
+ }
440
+
441
+ async function createLobby() {
442
+ if (!steamClient.steamID) {
443
+ return;
444
+ }
445
+
446
+ return new Promise((resolve) => {
447
+ const timeout = setTimeout(function () {
448
+ resolve();
449
+ }, 30000);
450
+
451
+ steamClient._send(
452
+ {
453
+ msg: Protos.csgo.EMsg.k_EMsgClientMMSCreateLobby,
454
+ proto: {
455
+ steamid: steamClient.steamID.getSteamID64(),
456
+ routing_appid: 730,
457
+ },
458
+ },
459
+ protoEncode(Protos.csgo.CMsgClientMMSCreateLobby, {
460
+ app_id: 730,
461
+ max_members: 1,
462
+ lobby_type: 1,
463
+ lobby_flags: 1,
464
+ }),
465
+ function (payload) {
466
+ clearTimeout(timeout);
467
+ const result = protoDecode(Protos.csgo.CMsgClientMMSCreateLobbyResponse, payload.toBuffer());
468
+ const steam_id_lobby = result.steam_id_lobby.toString();
469
+ currentLobby.lobbyID = steam_id_lobby;
470
+ currentLobby.timestamp = new Date().getTime();
471
+ resolve(steam_id_lobby);
472
+ },
473
+ );
474
+ });
475
+
476
+ // return await getHandlerResult(Protos.csgo.EMsg.k_EMsgClientMMSCreateLobbyResponse, function (payload) {
477
+ // const result = protoDecode(Protos.csgo.CMsgClientMMSCreateLobbyResponse, payload.toBuffer())
478
+ // return result.steam_id_lobby.toString()
479
+ // })
480
+
481
+ // steamClient.sendToGC(730, Protos.csgo.EMsg.k_EMsgClientMMSCreateLobby, {
482
+ // steamid: steamClient.steamID,
483
+ // routing_appid: 730,
484
+ // }, protoEncode(Protos.csgo.CMsgClientMMSCreateLobby, {
485
+ // app_id: 730,
486
+ // max_members: 1,
487
+ // lobby_type: 1,
488
+ // lobby_flags: 1
489
+ // }))
490
+ }
491
+
492
+ async function updateLobby(lobbyID) {
493
+ if (!steamClient.steamID) {
494
+ return;
495
+ }
496
+
497
+ return new Promise((resolve) => {
498
+ const timeout = setTimeout(function () {
499
+ resolve();
500
+ }, 30000);
501
+
502
+ steamClient._send(
503
+ {
504
+ msg: Protos.csgo.EMsg.k_EMsgClientMMSSetLobbyData,
505
+ proto: {
506
+ steamid: steamClient.steamID.getSteamID64(),
507
+ routing_appid: 730,
508
+ },
509
+ },
510
+ protoEncode(Protos.csgo.CMsgClientMMSSetLobbyData, {
511
+ app_id: 730,
512
+ steam_id_lobby: lobbyID,
513
+ steam_id_member: "0",
514
+ max_members: 10,
515
+ lobby_type: 1,
516
+ lobby_flags: 1,
517
+ metadata: encode(
518
+ {
519
+ "game:ark": "0",
520
+ // Country/Message
521
+ "game:loc": "",
522
+ "game:mapgroupname": "mg_de_mirage",
523
+ "game:mode": "competitive",
524
+ "game:prime": "1",
525
+ "game:type": "classic",
526
+ "members:numPlayers": "1",
527
+ "options:action": "custommatch",
528
+ "options:anytypemode": "0",
529
+ "system:access": "private",
530
+ "system:network": "LIVE",
531
+ uids: [steamClient.steamID],
532
+ },
533
+ [0x00, 0x00],
534
+ [0x08],
535
+ { uids: encodeUids },
536
+ ).toBuffer(),
537
+ }),
538
+ function (payload) {
539
+ clearTimeout(timeout);
540
+ const result = protoDecode(Protos.csgo.CMsgClientMMSSetLobbyDataResponse, payload.toBuffer());
541
+ const steam_id_lobby = result.steam_id_lobby.toString();
542
+ currentLobby.lobbyID = steam_id_lobby;
543
+ currentLobby.timestamp = new Date().getTime();
544
+ resolve(steam_id_lobby);
545
+ },
546
+ );
547
+ });
548
+
549
+ // return await getHandlerResult(Protos.csgo.EMsg.k_EMsgClientMMSSetLobbyDataResponse, function (payload) {
550
+ // const result = protoDecode(Protos.csgo.CMsgClientMMSSetLobbyDataResponse, payload.toBuffer())
551
+ // return result.steam_id_lobby.toString()
552
+ // })
553
+ }
554
+
555
+ async function invite2Lobby(lobbyID, steamId) {
556
+ if (!steamClient.steamID) {
557
+ return;
558
+ }
559
+
560
+ steamClient._send(
561
+ {
562
+ msg: Protos.csgo.EMsg.k_EMsgClientMMSInviteToLobby,
563
+ proto: {
564
+ steamid: steamClient.steamID.getSteamID64(),
565
+ routing_appid: 730,
566
+ },
567
+ },
568
+ protoEncode(Protos.csgo.CMsgClientMMSInviteToLobby, {
569
+ app_id: 730,
570
+ steam_id_lobby: lobbyID,
571
+ steam_id_user_invited: steamId,
572
+ }),
573
+ );
574
+
575
+ // lobbyID = new SteamID(lobbyID).accountid;
576
+
577
+ // Protos.csgo.EMsg.k_EMsgGCHInviteUserToLobby
578
+ // Protos.csgo.EMsg.k_EMsgClientMMSInviteToLobby
579
+ // steamClient.sendToGC(730, Protos.csgo.EMsg.k_EMsgClientMMSInviteToLobby, {}, protoEncode(Protos.csgo.CMsgClientMMSInviteToLobby, {
580
+ // app_id: 730,
581
+ // steam_id_lobby: lobbyID,
582
+ // steam_id_user_invited: accountid,
583
+ // }), function (...args) {
584
+ // console.log("invite2Lobby response", args)
585
+ // })
586
+ }
587
+
588
+ async function createThenInvite2Lobby(steamIds, onInvite) {
589
+ if (!steamClient.steamID) {
590
+ return;
591
+ }
592
+
593
+ if (!Array.isArray(steamIds)) {
594
+ steamIds = [steamIds];
595
+ }
596
+
597
+ let lobbyID = null;
598
+ if (currentLobby.lobbyID && currentLobby.timestamp > new Date().getTime() - 30000) {
599
+ //30 seconds
600
+ lobbyID = currentLobby.lobbyID;
601
+ } else {
602
+ lobbyID = await createLobby();
603
+ lobbyID = await updateLobby(lobbyID);
604
+ }
605
+
606
+ for (const steamId of steamIds) {
607
+ onInvite?.(lobbyID, steamId);
608
+ await invite2Lobby(lobbyID, steamId);
609
+ }
610
+
611
+ return lobbyID;
612
+ }
613
+
614
+ async function getLobbyData(lobbyID) {
615
+ if (!steamClient.steamID) {
616
+ return;
617
+ }
618
+
619
+ return new Promise((resolve) => {
620
+ const timeout = setTimeout(function () {
621
+ resolve();
622
+ }, 30000);
623
+
624
+ steamClient._send(
625
+ {
626
+ msg: Protos.csgo.EMsg.k_EMsgClientMMSGetLobbyData,
627
+ proto: {
628
+ steamid: steamClient.steamID.getSteamID64(),
629
+ routing_appid: 730,
630
+ },
631
+ },
632
+ protoEncode(Protos.csgo.CMsgClientMMSGetLobbyData, {
633
+ app_id: 730,
634
+ steam_id_lobby: lobbyID.toString(),
635
+ }),
636
+ function (payload) {
637
+ clearTimeout(timeout);
638
+ const result = protoDecode(Protos.csgo.CMsgClientMMSLobbyData, payload.toBuffer());
639
+ result.steam_id_lobby = result.steam_id_lobby.toString();
640
+ resolve(result);
641
+ },
642
+ );
643
+ });
644
+ }
645
+
646
+ async function joinLobby(lobbyID) {
647
+ log("joinLobby", lobbyID); //SteamID.fromIndividualAccountID(lobbyId).accountid
648
+
649
+ steamClient._send(
650
+ {
651
+ msg: Protos.csgo.EMsg.k_EMsgClientMMSJoinLobby,
652
+ proto: {
653
+ steamid: steamClient.steamID.getSteamID64(),
654
+ routing_appid: 730,
655
+ },
656
+ }, //CMsgClientMMSUserJoinedLobby CMsgClientMMSJoinLobby
657
+ protoEncode(Protos.csgo.CMsgClientMMSJoinLobby, {
658
+ app_id: 730,
659
+ steam_id_lobby: lobbyID,
660
+ persona_name: steamClient.accountInfo.name,
661
+ }),
662
+ function (payload) {
663
+ const result = protoDecode(Protos.csgo.CMsgClientMMSJoinLobbyResponse, payload.toBuffer());
664
+ result.steam_id_lobby = result.steam_id_lobby.toString();
665
+ result.steam_id_owner = result.steam_id_owner.toString();
666
+ console.log(result);
667
+ const resultExample = {
668
+ members: [],
669
+ app_id: 730,
670
+ steam_id_lobby: "3641224920",
671
+ chat_room_enter_response: 2,
672
+ max_members: 0,
673
+ lobby_type: 0,
674
+ lobby_flags: 0,
675
+ steam_id_owner: "0",
676
+ metadata: null, //Buffer
677
+ };
678
+ },
679
+ );
680
+ }
681
+
682
+ async function sendHello() {
683
+ steamClient.sendToGC(AppID, Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_MatchmakingClient2GCHello, {}, Buffer.alloc(0));
684
+ steamClient.sendToGC(AppID, Protos.csgo.EGCBaseClientMsg.k_EMsgGCClientHello, {}, Buffer.alloc(0));
685
+ }
686
+
687
+ async function requestCoPlays() {
688
+ return new Promise((resolve) => {
689
+ steamClient.sendToGC(AppID, Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Account_RequestCoPlays, {}, Buffer.alloc(0));
690
+ pushGCCallback("RequestCoPlays", resolve, 30000);
691
+ });
692
+ }
693
+
694
+ function bindEvent() {
695
+ const _events = {
696
+ async disconnected(eresult, msg) {
697
+ state = "Offline";
698
+ log("disconnected", eresult, msg);
699
+
700
+ callEvent(events.disconnected, { eresult, msg });
701
+
702
+ if (["ServiceUnavailable", "NoConnection"].includes(msg) && autoReconnect && !isLogOff) {
703
+ async function relogin(retry) {
704
+ if (isLogOff) {
705
+ console.error("Cannot relogin (logoff)");
706
+ return false;
707
+ } else if (retry <= 0) {
708
+ console.error("Cannot relogin");
709
+ return false;
710
+ } else {
711
+ const isSuccess = await login(true);
712
+ if (isSuccess) {
713
+ const loggedOnResponse = await new Promise((resolve) => {
714
+ onEvent("loggedOn", resolve, true, 180000);
715
+ });
716
+ if (loggedOnResponse) {
717
+ console.log("Relogin success");
718
+ return true;
719
+ } else {
720
+ const isLogOff = await new Promise((resolve, reject) => {
721
+ logOffEvent = resolve;
722
+ setTimeout(resolve, 120000);
723
+ });
724
+ logOffEvent = null;
725
+ if (isLogOff === true) {
726
+ return false;
727
+ }
728
+ return await relogin(retry - 1);
729
+ }
730
+ } else {
731
+ const isLogOff = await new Promise((resolve, reject) => {
732
+ logOffEvent = resolve;
733
+ setTimeout(resolve, 120000);
734
+ });
735
+ logOffEvent = null;
736
+ if (isLogOff === true) {
737
+ return false;
738
+ }
739
+ return await relogin(retry - 1);
740
+ }
741
+ }
742
+ }
743
+
744
+ const isLogOff = await new Promise((resolve, reject) => {
745
+ logOffEvent = resolve;
746
+ setTimeout(resolve, 60000);
747
+ });
748
+ logOffEvent = null;
749
+ if (isLogOff === true) {
750
+ offAllEvent();
751
+ doClearIntervals();
752
+ } else {
753
+ const isSuccess = await relogin(50);
754
+ if (!isSuccess) {
755
+ offAllEvent();
756
+ doClearIntervals();
757
+ }
758
+ }
759
+ } else {
760
+ offAllEvent();
761
+ doClearIntervals();
762
+ }
763
+ },
764
+ async error(e) {
765
+ let errorStr = "";
766
+ switch (e.eresult) {
767
+ case 5:
768
+ errorStr = "Invalid Password";
769
+ break;
770
+ case 6:
771
+ case 34:
772
+ errorStr = "Logged In Elsewhere";
773
+ break;
774
+ case 84:
775
+ errorStr = "Rate Limit Exceeded";
776
+ break;
777
+ case 65:
778
+ errorStr = "steam guard is invalid";
779
+ break;
780
+ default:
781
+ errorStr = `Unknown: ${e.eresult}`;
782
+ break;
783
+ }
784
+ log(`error [isLogOff: ${isLogOff}]`, e?.message);
785
+ doClearIntervals();
786
+ callEvent(events.error, { eresult: e.eresult, msg: e.message, error: errorStr });
787
+ },
788
+ async webSession(sessionID, cookies) {
789
+ const webSession = { sessionID, cookies };
790
+ steamClient.webSession = webSession;
791
+ callEvent(events.webSession, webSession);
792
+ },
793
+ async receivedFromGC(appid, msgType, payload) {
794
+ const key = getECsgoGCMsgKey(msgType);
795
+ switch (msgType) {
796
+ case Protos.csgo.EMsg.k_EMsgClientChatInvite: {
797
+ log(payload);
798
+ break;
799
+ }
800
+ case Protos.csgo.ECsgoGCMsg.k_EMsgClientMMSJoinLobbyResponse: {
801
+ const msg = protoDecode(Protos.csgo.CMsgClientMMSJoinLobbyResponse, payload);
802
+ log(msg);
803
+ break;
804
+ }
805
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Party_Invite: {
806
+ const msg = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_Party_Invite, payload);
807
+ const sid64 = SteamID.fromIndividualAccountID(msg.accountid).getSteamID64();
808
+ if (events.partyInvite?.length) {
809
+ const personas = await getPersonas([sid64]);
810
+ const player_name = personas.find((p) => p.id == sid64)?.player_name;
811
+ if (player_name === undefined) {
812
+ log(sid64, personas);
813
+ }
814
+ callEvent(events.partyInvite, { player_name, steamId: sid64, lobbyId: msg.lobbyid });
815
+ }
816
+ // log(player_name, `https://steamcommunity.com/profiles/${sid64}`);
817
+ // joinLobby(msg.lobbyid, msg.accountid)
818
+ break;
819
+ }
820
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Account_RequestCoPlays: {
821
+ const msg = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_Account_RequestCoPlays, payload);
822
+ const personas = msg.players.map((p) => SteamID.fromIndividualAccountID(p.accountid));
823
+ callGCCallback("RequestCoPlays", personas);
824
+ break;
825
+ }
826
+ case Protos.csgo.EGCBaseClientMsg.k_EMsgGCClientWelcome: {
827
+ prime = false;
828
+ const CMsgClientWelcome = protoDecode(Protos.csgo.CMsgClientWelcome, payload);
829
+ const obj = {};
830
+ for (const outofdate_cache of CMsgClientWelcome.outofdate_subscribed_caches) {
831
+ for (const cache_object of outofdate_cache.objects) {
832
+ for (const object_data of cache_object.object_data) {
833
+ switch (cache_object.type_id) {
834
+ case 1: {
835
+ const result = protoDecode(Protos.csgo.CSOEconItem, object_data);
836
+ result.id = result.id.toNumber();
837
+ break;
838
+ }
839
+ case 2: {
840
+ const result = protoDecode(Protos.csgo.CSOPersonaDataPublic, object_data);
841
+ obj.PersonaDataPublic = result;
842
+ const example = {
843
+ player_level: 4,
844
+ commendation: {
845
+ cmd_friendly: 149,
846
+ cmd_teaching: 108,
847
+ cmd_leader: 115,
848
+ },
849
+ elevated_state: true,
850
+ };
851
+ break;
852
+ }
853
+ case 5: {
854
+ const result = protoDecode(Protos.csgo.CSOItemRecipe, object_data);
855
+ break;
856
+ }
857
+ case 7: {
858
+ const CSOEconGameAccountClient = protoDecode(Protos.csgo.CSOEconGameAccountClient, object_data);
859
+ const CSOEconGameAccountClientExample = {
860
+ additional_backpack_slots: 0,
861
+ bonus_xp_timestamp_refresh: 1688518800, //Wednesday 1:00:00 AM every week
862
+ bonus_xp_usedflags: 19,
863
+ elevated_state: 5,
864
+ elevated_timestamp: 5,
865
+ }; //1688518800
866
+ if ((CSOEconGameAccountClient.bonus_xp_usedflags & 16) != 0) {
867
+ // EXPBonusFlag::PrestigeEarned
868
+ prime = true;
869
+ CSOEconGameAccountClient.prime = true;
870
+ }
871
+ if (CSOEconGameAccountClient.elevated_state === 5) {
872
+ // bought prime
873
+ prime = true;
874
+ CSOEconGameAccountClient.prime = true;
875
+ }
876
+ obj.GameAccountClient = CSOEconGameAccountClient;
877
+ break;
878
+ }
879
+
880
+ case 35: {
881
+ // const result =protoDecode(Protos.csgo.CSOSelectedItemPreset, object_data);
882
+ break;
883
+ }
884
+
885
+ case 36: {
886
+ // const result =protoDecode(Protos.csgo.CSOEconItemPresetInstance, object_data);
887
+ break;
888
+ }
889
+ case 38: {
890
+ const result = protoDecode(Protos.csgo.CSOEconItemDropRateBonus, object_data);
891
+ break;
892
+ }
893
+ case 39: {
894
+ const result = protoDecode(Protos.csgo.CSOEconItemLeagueViewPass, object_data);
895
+ break;
896
+ }
897
+ case 40: {
898
+ const result = protoDecode(Protos.csgo.CSOEconItemEventTicket, object_data);
899
+ break;
900
+ }
901
+ case 41: {
902
+ const result = protoDecode(Protos.csgo.CSOAccountSeasonalOperation, object_data);
903
+ break;
904
+ }
905
+ case 42: {
906
+ // const result =protoDecode(Protos.csgo.CSOEconItemTournamentPassport, object_data);
907
+ break;
908
+ }
909
+ case 43: {
910
+ const result = protoDecode(Protos.csgo.CSOEconDefaultEquippedDefinitionInstanceClient, object_data);
911
+ const example = {
912
+ account_id: 1080136620,
913
+ item_definition: 61,
914
+ class_id: 3,
915
+ slot_id: 2,
916
+ };
917
+ break;
918
+ }
919
+ case 45: {
920
+ const result = protoDecode(Protos.csgo.CSOEconCoupon, object_data);
921
+ break;
922
+ }
923
+ case 46: {
924
+ const result = protoDecode(Protos.csgo.CSOQuestProgress, object_data);
925
+ break;
926
+ }
927
+ case 4: {
928
+ const result = protoDecode(Protos.csgo.CSOAccountItemPersonalStore, object_data);
929
+ result.generation_time = result.generation_time * 1000;
930
+ if (Array.isArray(result.items)) {
931
+ result.items = result.items.map((item) => item.toNumber());
932
+ }
933
+ obj.personalStore = result;
934
+ break;
935
+ }
936
+
937
+ default: {
938
+ log("cache_object.type_id", cache_object.type_id);
939
+ }
940
+ }
941
+ }
942
+ }
943
+ }
944
+ callEvent(events.csgoOnline, obj);
945
+
946
+ if (isPartyRegister) {
947
+ partyRegister();
948
+ doSetInterval(
949
+ function () {
950
+ partyRegister();
951
+ },
952
+ [60000, 120000],
953
+ "autoPartyRegister",
954
+ );
955
+ }
956
+ break;
957
+ }
958
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_MatchmakingGC2ClientUpdate: {
959
+ const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_MatchmakingGC2ClientUpdate, payload);
960
+ break;
961
+ }
962
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_GC2ClientGlobalStats: {
963
+ const result = protoDecode(Protos.csgo.CMsgClientUGSGetGlobalStatsResponse, payload);
964
+ break;
965
+ }
966
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_ClientReportPlayer: {
967
+ const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_ClientReportPlayer, payload);
968
+ break;
969
+ }
970
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_GC2ClientTextMsg: {
971
+ const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_GC2ClientTextMsg, payload);
972
+ break;
973
+ }
974
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_MatchmakingGC2ClientHello: {
975
+ const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_MatchmakingGC2ClientHello, payload);
976
+ const example = {
977
+ my_current_event_teams: [],
978
+ my_current_event_stages: [],
979
+ rankings: [],
980
+ account_id: 1080136620,
981
+ ongoingmatch: null,
982
+ global_stats: {
983
+ search_statistics: [
984
+ {
985
+ game_type: 520,
986
+ search_time_avg: 0,
987
+ players_searching: 5141,
988
+ },
989
+ {
990
+ game_type: 32776,
991
+ search_time_avg: 0,
992
+ players_searching: 6561,
993
+ },
994
+ ],
995
+ players_online: 617207,
996
+ servers_online: 230638,
997
+ players_searching: 13550,
998
+ servers_available: 126352,
999
+ ongoing_matches: 23264,
1000
+ search_time_avg: 95993,
1001
+ main_post_url: "*XA=https://blast.tv/live*XT=https://www.twitch.tv/blastpremier*XB=https://live.bilibili.com/35*XG=playcast://https://gotv.blast.tv/major-a*T=SGTAB*L=2@https://steamcommunity.com/broadcast/watch/76561199492362089",
1002
+ required_appid_version: 13879,
1003
+ pricesheet_version: 1688084844,
1004
+ twitch_streams_version: 2,
1005
+ active_tournament_eventid: 21,
1006
+ active_survey_id: 0,
1007
+ rtime32_cur: 0,
1008
+ rtime32_event_start: 0,
1009
+ },
1010
+ penalty_seconds: 0,
1011
+ penalty_reason: 0,
1012
+ vac_banned: 0,
1013
+ ranking: {
1014
+ account_id: 1080136620,
1015
+ rank_id: 10,
1016
+ wins: 209,
1017
+ rank_change: 0,
1018
+ rank_type_id: 6,
1019
+ tv_control: 0,
1020
+ },
1021
+ commendation: {
1022
+ cmd_friendly: 149,
1023
+ cmd_teaching: 108,
1024
+ cmd_leader: 115,
1025
+ },
1026
+ medals: null,
1027
+ my_current_event: null,
1028
+ my_current_team: null,
1029
+ survey_vote: 0,
1030
+ activity: null,
1031
+ player_level: 4,
1032
+ player_cur_xp: 327684501,
1033
+ player_xp_bonus_flags: 0,
1034
+ };
1035
+ if (result?.global_stats?.required_appid_version && (!CSGO_VER || result.global_stats.required_appid_version > CSGO_VER)) {
1036
+ CSGO_VER = result.global_stats.required_appid_version;
1037
+ }
1038
+ callEvent(events.csgoClientHello, result);
1039
+ break;
1040
+ }
1041
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_ClientReportResponse: {
1042
+ const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_ClientReportResponse, payload);
1043
+ break;
1044
+ }
1045
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_ClientCommendPlayerQueryResponse: {
1046
+ const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_ClientCommendPlayer, payload);
1047
+ break;
1048
+ }
1049
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_PlayerOverwatchCaseAssignment: {
1050
+ const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_PlayerOverwatchCaseAssignment, payload);
1051
+ break;
1052
+ }
1053
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_MatchList: {
1054
+ const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_MatchList, payload);
1055
+ break;
1056
+ }
1057
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_GetEventFavorites_Response: {
1058
+ const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_GetEventFavorites_Response, payload);
1059
+ break;
1060
+ }
1061
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_StartAgreementSessionInGame: {
1062
+ break;
1063
+ }
1064
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_ClientDeepStats: {
1065
+ const result = protoDecode(Protos.csgo.CMsgGCCStrike15_ClientDeepStats, payload);
1066
+ break;
1067
+ }
1068
+ case Protos.csgo.EGCBaseClientMsg.k_EMsgGCClientConnectionStatus: {
1069
+ const result = protoDecode(Protos.csgo.CMsgConnectionStatus, payload);
1070
+ break;
1071
+ }
1072
+ case Protos.csgo.EGCItemMsg.k_EMsgGCStoreGetUserDataResponse: {
1073
+ const result = protoDecode(Protos.csgo.CMsgStoreGetUserDataResponse, payload);
1074
+ break;
1075
+ }
1076
+ case Protos.csgo.EGCItemMsg.k_EMsgGCStorePurchaseFinalizeResponse: {
1077
+ const result = protoDecode(Protos.csgo.CMsgGCStorePurchaseFinalizeResponse, payload);
1078
+ break;
1079
+ }
1080
+ case Protos.csgo.EGCItemMsg.k_EMsgGCStorePurchaseCancelResponse: {
1081
+ const result = protoDecode(Protos.csgo.CMsgGCStorePurchaseCancelResponse, payload);
1082
+ break;
1083
+ }
1084
+ case Protos.csgo.EGCItemMsg.k_EMsgGCStorePurchaseInitResponse: {
1085
+ const result = protoDecode(Protos.csgo.CMsgGCStorePurchaseInitResponse, payload);
1086
+ break;
1087
+ }
1088
+ case Protos.csgo.EMsg.k_EMsgClientMMSCreateLobbyResponse: {
1089
+ const result = protoDecode(Protos.csgo.CMsgClientMMSCreateLobbyResponse, payload);
1090
+ console.log("k_EMsgClientMMSCreateLobbyResponse", result);
1091
+ break;
1092
+ }
1093
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_ClientGCRankUpdate: {
1094
+ const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_ClientGCRankUpdate, payload);
1095
+ break;
1096
+ }
1097
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Party_Search: {
1098
+ const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_Party_SearchResults, payload);
1099
+ const entries = _.uniqBy(result.entries, "id");
1100
+ //{
1101
+ // id: 144900402,
1102
+ // grp: 0,
1103
+ // game_type: 8,
1104
+ // apr: 1,
1105
+ // ark: 17,
1106
+ // loc: 20041,
1107
+ // accountid: 0
1108
+ // }
1109
+
1110
+ //{
1111
+ // id: "76561199265943339",
1112
+ // rich_presence: [],
1113
+ // persona_state: null,
1114
+ // game_played_app_id: null,
1115
+ // game_server_ip: null,
1116
+ // game_server_port: null,
1117
+ // persona_state_flags: null,
1118
+ // online_session_instances: null,
1119
+ // persona_set_by_user: null,
1120
+ // player_name: "杀人不见血",
1121
+ // query_port: null,
1122
+ // steamid_source: null,
1123
+ // avatar_hash: "33994e26f1fe7e2093f8c7dee66c1ac91531050d",
1124
+ // last_logoff: null,
1125
+ // last_logon: null,
1126
+ // last_seen_online: null,
1127
+ // clan_rank: null,
1128
+ // game_name: null,
1129
+ // gameid: null,
1130
+ // game_data_blob: null,
1131
+ // clan_data: null,
1132
+ // clan_tag: null,
1133
+ // broadcast_id: null,
1134
+ // game_lobby_id: null,
1135
+ // watching_broadcast_accountid: null,
1136
+ // watching_broadcast_appid: null,
1137
+ // watching_broadcast_viewers: null,
1138
+ // watching_broadcast_title: null,
1139
+ // is_community_banned: null,
1140
+ // player_name_pending_review: null,
1141
+ // avatar_pending_review: null,
1142
+ // avatar_url_icon: "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/33/33994e26f1fe7e2093f8c7dee66c1ac91531050d.jpg",
1143
+ // avatar_url_medium: "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/33/33994e26f1fe7e2093f8c7dee66c1ac91531050d_medium.jpg",
1144
+ // avatar_url_full: "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/33/33994e26f1fe7e2093f8c7dee66c1ac91531050d_full.jpg"
1145
+ // }
1146
+
1147
+ const players = [];
1148
+ for (const player of entries) {
1149
+ try {
1150
+ const prime = player.apr === 1 ? "PRIME" : "NON-PRIME";
1151
+ const loc = LOCS[player.loc] || player.loc;
1152
+ const steamId = SteamID.fromIndividualAccountID(player.id).getSteamID64();
1153
+ const friendCode = FriendCode.encode(steamId);
1154
+
1155
+ // if ((LOCS[player.loc] == 'VN' || !LOCS[player.loc])) {
1156
+ players.push({
1157
+ prime,
1158
+ rank: RANKS[player.ark] !== undefined ? RANKS[player.ark] : player.ark,
1159
+ loc,
1160
+ steamId,
1161
+ friendCode,
1162
+ });
1163
+ // }
1164
+ } catch (e) {}
1165
+ }
1166
+
1167
+ callGCCallback("partySearch", players);
1168
+ break;
1169
+ }
1170
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_PlayersProfile: {
1171
+ let data = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_PlayersProfile, payload)?.account_profiles;
1172
+ const dataExample = [
1173
+ {
1174
+ my_current_event_teams: [],
1175
+ my_current_event_stages: [],
1176
+ rankings: [
1177
+ {
1178
+ account_id: 1225887169,
1179
+ rank_id: 0,
1180
+ wins: 6,
1181
+ rank_change: 0,
1182
+ rank_type_id: 7,
1183
+ tv_control: 0,
1184
+ },
1185
+ {
1186
+ account_id: 1225887169,
1187
+ rank_id: 0,
1188
+ wins: 0,
1189
+ rank_change: 0,
1190
+ rank_type_id: 10,
1191
+ tv_control: 0,
1192
+ },
1193
+ ],
1194
+ account_id: 1225887169,
1195
+ ongoingmatch: null,
1196
+ global_stats: null,
1197
+ penalty_seconds: 0,
1198
+ penalty_reason: 0,
1199
+ vac_banned: 0,
1200
+ ranking: {
1201
+ account_id: 1225887169,
1202
+ rank_id: 8,
1203
+ wins: 469,
1204
+ rank_change: 0,
1205
+ rank_type_id: 6,
1206
+ tv_control: 0,
1207
+ },
1208
+ commendation: {
1209
+ cmd_friendly: 51,
1210
+ cmd_teaching: 40,
1211
+ cmd_leader: 40,
1212
+ },
1213
+ medals: {
1214
+ display_items_defidx: [4819, 4737],
1215
+ featured_display_item_defidx: 4819,
1216
+ },
1217
+ my_current_event: null,
1218
+ my_current_team: null,
1219
+ survey_vote: 0,
1220
+ activity: null,
1221
+ player_level: 32,
1222
+ player_cur_xp: 327682846,
1223
+ player_xp_bonus_flags: 0,
1224
+ },
1225
+ ];
1226
+
1227
+ const player = data?.[0];
1228
+ if (player) {
1229
+ player.prime = !!(player.ranking?.account_id || player.player_level || player.player_cur_xp);
1230
+ player.steamId = SteamID.fromIndividualAccountID(player.account_id).getSteamID64();
1231
+ callGCCallback(`PlayersProfile_${player.account_id}`, player);
1232
+ }
1233
+ callEvent(events.playersProfile, player);
1234
+ break;
1235
+ }
1236
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_ClientLogonFatalError: {
1237
+ const data = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_ClientLogonFatalError, payload);
1238
+ console.log(data);
1239
+ const dataExample = {
1240
+ errorcode: 4,
1241
+ message: "",
1242
+ country: "VN",
1243
+ };
1244
+ callEvent(events.fatalError, data);
1245
+ break;
1246
+ }
1247
+ default:
1248
+ log(`receivedFromGC ${msgType} ${key}`);
1249
+ const results = Object.values(Protos.csgo)
1250
+ .map(function (p) {
1251
+ try {
1252
+ return protoDecode(p, payload);
1253
+ } catch (e) {}
1254
+ })
1255
+ .filter(function (result) {
1256
+ return result && Object.keys(result).length;
1257
+ });
1258
+ log(key, results);
1259
+ }
1260
+ },
1261
+ async loggedOn(loggedOnResponse) {
1262
+ callEvent(events.loggedOn, loggedOnResponse);
1263
+ updateInvisible();
1264
+ updateAutoRequestFreeLicense();
1265
+ updateAutoGamePlay();
1266
+ },
1267
+ async user(steamId, data) {
1268
+ callEvent(events.user, { steamId: steamId.getSteamID64(), data });
1269
+ const dataExample = {
1270
+ rich_presence: [
1271
+ {
1272
+ key: "status",
1273
+ value: "Competitive Mirage [ 3 : 6 ]",
1274
+ },
1275
+ {
1276
+ key: "version",
1277
+ value: "13875",
1278
+ },
1279
+ {
1280
+ key: "game:state",
1281
+ value: "game",
1282
+ },
1283
+ {
1284
+ key: "steam_display",
1285
+ value: "#display_GameKnownMapScore",
1286
+ },
1287
+ {
1288
+ key: "game:mode",
1289
+ value: "competitive",
1290
+ },
1291
+ {
1292
+ key: "game:mapgroupname",
1293
+ value: "mg_de_mirage",
1294
+ },
1295
+ {
1296
+ key: "game:map",
1297
+ value: "de_mirage",
1298
+ },
1299
+ {
1300
+ key: "game:server",
1301
+ value: "kv",
1302
+ },
1303
+ {
1304
+ key: "watch",
1305
+ value: "1",
1306
+ },
1307
+ {
1308
+ key: "steam_player_group",
1309
+ value: "2134948645",
1310
+ },
1311
+ {
1312
+ key: "game:score",
1313
+ value: "[ 3 : 6 ]",
1314
+ },
1315
+ ],
1316
+ friendid: "76561199405834425",
1317
+ persona_state: 1,
1318
+ game_played_app_id: 730,
1319
+ game_server_ip: null,
1320
+ game_server_port: null,
1321
+ persona_state_flags: 1,
1322
+ online_session_instances: 1,
1323
+ persona_set_by_user: null,
1324
+ player_name: "quỷ súng",
1325
+ query_port: null,
1326
+ steamid_source: "0",
1327
+ avatar_hash: {
1328
+ type: "Buffer",
1329
+ data: [23, 163, 216, 209, 236, 179, 73, 228, 225, 30, 48, 190, 192, 170, 177, 246, 139, 71, 122, 205],
1330
+ },
1331
+ last_logoff: 1683950268,
1332
+ last_logon: 1683950281,
1333
+ last_seen_online: 1683950268,
1334
+ clan_rank: null,
1335
+ game_name: "",
1336
+ gameid: "730",
1337
+ game_data_blob: {
1338
+ type: "Buffer",
1339
+ data: [],
1340
+ },
1341
+ clan_data: null,
1342
+ clan_tag: null,
1343
+ broadcast_id: "0",
1344
+ game_lobby_id: "0",
1345
+ watching_broadcast_accountid: null,
1346
+ watching_broadcast_appid: null,
1347
+ watching_broadcast_viewers: null,
1348
+ watching_broadcast_title: null,
1349
+ is_community_banned: null,
1350
+ player_name_pending_review: null,
1351
+ avatar_pending_review: null,
1352
+ };
1353
+ },
1354
+ async playingState(playing_blocked, playing_app) {
1355
+ playingBlocked = playing_blocked;
1356
+ if (playing_app === 0) {
1357
+ playing_app = null;
1358
+ }
1359
+ if (playing_blocked) {
1360
+ //true, false
1361
+ console.log("Playing else where");
1362
+ }
1363
+ log("playingState", playing_blocked, playing_app);
1364
+ callEvent(events.playingState, { playing_blocked, playing_app });
1365
+ },
1366
+ async friendRelationship(sid, relationship, previousRelationship) {
1367
+ callEvent(events.friendRelationship, {
1368
+ steamId: sid.getSteamID64(),
1369
+ relationship,
1370
+ previousRelationship,
1371
+ });
1372
+ switch (relationship) {
1373
+ case EFriendRelationship.None: {
1374
+ //we got unfriended.
1375
+ break;
1376
+ }
1377
+ case EFriendRelationship.RequestRecipient: {
1378
+ //we got invited as a friend
1379
+ break;
1380
+ }
1381
+ case EFriendRelationship.Friend: {
1382
+ //we got added as a friend
1383
+ break;
1384
+ }
1385
+ }
1386
+ },
1387
+ async tradeOffers(count) {
1388
+ callEvent(events.tradeOffers, count);
1389
+ },
1390
+ async offlineMessages(count, friends) {
1391
+ callEvent(events.offlineMessages, { count, steamIdList: friends });
1392
+ },
1393
+ async tradeRequest(steamID, respond) {
1394
+ if (autoAcceptTradeRequest) {
1395
+ log(`Incoming trade request from ${steamID.getSteam3RenderedID()}, accepting`);
1396
+ respond(true);
1397
+ } else {
1398
+ log(`Incoming trade request from ${steamID.getSteam3RenderedID()}, wating`);
1399
+ }
1400
+ },
1401
+ async friendsList() {
1402
+ callEvent(events.friendsList, getFriendList());
1403
+ },
1404
+ async gifts(gid, packageid, TimeCreated, TimeExpiration, TimeSent, TimeAcked, TimeRedeemed, RecipientAddress, SenderAddress, SenderName) {
1405
+ callEvent(events.gifts, {
1406
+ gid,
1407
+ packageid,
1408
+ TimeCreated,
1409
+ TimeExpiration,
1410
+ TimeSent,
1411
+ TimeAcked,
1412
+ TimeRedeemed,
1413
+ RecipientAddress,
1414
+ SenderAddress,
1415
+ SenderName,
1416
+ });
1417
+ },
1418
+ async emailInfo(address, validated) {
1419
+ callEvent(events.emailInfo, { address, validated });
1420
+ },
1421
+ async appLaunched() {
1422
+ setTimeout(function () {
1423
+ state = getPlayingAppIds().length ? "InGame" : isInvisible ? "Invisible" : "Online";
1424
+ }, 1000);
1425
+ },
1426
+ async appQuit() {
1427
+ setTimeout(function () {
1428
+ state = getPlayingAppIds().length ? "InGame" : isInvisible ? "Invisible" : "Online";
1429
+ }, 1000);
1430
+ },
1431
+ async accountLimitations(bis_limited_account, bis_community_banned, bis_locked_account, bis_limited_account_allowed_to_invite_friends) {
1432
+ callEvent(events.accountLimitations, {
1433
+ limited: bis_limited_account,
1434
+ communityBanned: bis_community_banned,
1435
+ locked: bis_locked_account,
1436
+ canInviteFriends: bis_limited_account_allowed_to_invite_friends,
1437
+ });
1438
+ },
1439
+ };
1440
+
1441
+ const _chatEvents = {
1442
+ async friendMessage(data) {
1443
+ if (!data) return;
1444
+ data.message_no_bbcode = data.message_no_bbcode?.replaceAll("ː", ":");
1445
+ data.message = data.message?.replaceAll("ː", ":");
1446
+ const example = {
1447
+ steamid_friend: {
1448
+ universe: 1,
1449
+ type: 1,
1450
+ instance: 1,
1451
+ accountid: 1080136620,
1452
+ },
1453
+ chat_entry_type: 1,
1454
+ from_limited_account: false,
1455
+ message: "xxx",
1456
+ ordinal: 0,
1457
+ local_echo: false,
1458
+ message_no_bbcode: "xxx",
1459
+ low_priority: false,
1460
+ server_timestamp: "2023-05-14T09:26:25.000Z",
1461
+ message_bbcode_parsed: ["xxx"],
1462
+ };
1463
+ const timestamp = new Date(data.server_timestamp).getTime();
1464
+ const steamId = data.steamid_friend.getSteamID64();
1465
+ const invite = ["Invited you to play a game!", "Đã mời bạn chơi một trò chơi!"].includes(data.message_no_bbcode || data.message);
1466
+ const emotion = (data.message_no_bbcode || "").split(" ").find((m) => m.startsWith(":") && m.endsWith(":"));
1467
+
1468
+ callEvent(events.friendMessage, {
1469
+ ...data,
1470
+ message: data.message_no_bbcode,
1471
+ invite,
1472
+ steamId,
1473
+ timestamp,
1474
+ emotion,
1475
+ });
1476
+ },
1477
+ async friendTyping(steamId, message) {
1478
+ callEvent(events.friendTyping, {
1479
+ steamId,
1480
+ message,
1481
+ });
1482
+ },
1483
+ };
1484
+
1485
+ // steamClient.on('lobbyInvite', (inviterID, lobbyID ) => {
1486
+ // joinLobby(lobbyID)
1487
+ // })
1488
+
1489
+ // steamClient.on('debug', (msg) => {
1490
+ // if (!["ClientPersonaState","ClientClanState"].some(c => msg.includes(c))) {
1491
+ // if(msg.startsWith("Received")){
1492
+ // console.log(`------- ${msg}`)
1493
+ // } else {
1494
+ // console.log(msg)
1495
+ // }
1496
+ // }
1497
+ // })
1498
+
1499
+ function getECsgoGCMsgKey(_key) {
1500
+ for (let key in Protos.csgo.ECsgoGCMsg) {
1501
+ if (Protos.csgo.ECsgoGCMsg[key] == _key) {
1502
+ return key;
1503
+ }
1504
+ }
1505
+ for (let key in Protos.csgo.EGCBaseClientMsg) {
1506
+ if (Protos.csgo.EGCBaseClientMsg[key] == _key) {
1507
+ return key;
1508
+ }
1509
+ }
1510
+ for (let key in Protos.csgo.EMsg) {
1511
+ if (Protos.csgo.EMsg[key] == _key) {
1512
+ return key;
1513
+ }
1514
+ }
1515
+ for (let key in Protos.csgo.EGCItemMsg) {
1516
+ if (Protos.csgo.EGCItemMsg[key] == _key) {
1517
+ return key;
1518
+ }
1519
+ }
1520
+ }
1521
+
1522
+ for (const [name, _event] of Object.entries(_events)) {
1523
+ steamClient.on(name, _event);
1524
+ }
1525
+
1526
+ for (const [name, _event] of Object.entries(_chatEvents)) {
1527
+ steamClient.chat.on(name, _event);
1528
+ }
1529
+ }
1530
+
1531
+ function getHandlerResult(msg, handler) {
1532
+ const timeout = { current: null };
1533
+ return new Promise((resolve) => {
1534
+ function myhandler(...args) {
1535
+ timeout.current && clearTimeout(timeout.current);
1536
+ removeHandler();
1537
+ resolve(handler?.(...args));
1538
+ }
1539
+
1540
+ function removeHandler() {
1541
+ if (Array.isArray(steamClient._handlerManager._handlers[msg])) {
1542
+ const index = steamClient._handlerManager._handlers[msg].findIndex((_handler) => _handler === myhandler);
1543
+ if (index > -1) {
1544
+ steamClient._handlerManager._handlers[msg].splice(index, 1);
1545
+ }
1546
+ }
1547
+ }
1548
+
1549
+ timeout.current = setTimeout(function () {
1550
+ removeHandler();
1551
+ resolve();
1552
+ }, 60000);
1553
+ steamClient._handlerManager.add(msg, myhandler);
1554
+ });
1555
+ }
1556
+
1557
+ function getFriendList() {
1558
+ return Object.keys(steamClient.myFriends).filter((steamId) => steamClient.myFriends[steamId] === NodeSteamUser.EFriendRelationship.Friend);
1559
+ }
1560
+
1561
+ function sendFriendTyping(steamId, callback) {
1562
+ steamClient.chat.sendFriendTyping(steamId, callback);
1563
+ }
1564
+
1565
+ /*
1566
+ * usually take 400 -> 800 miliseconds
1567
+ * */
1568
+ function getPlayersProfile(steamId) {
1569
+ const accountid = new SteamID(steamId).accountid;
1570
+ steamClient.sendToGC(
1571
+ 730,
1572
+ Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_ClientRequestPlayersProfile,
1573
+ {},
1574
+ protoEncode(Protos.csgo.CMsgGCCStrike15_v2_ClientRequestPlayersProfile, {
1575
+ account_id: accountid, // account_id: new SteamID('76561199184696945').accountid,
1576
+ request_level: 32,
1577
+ }),
1578
+ );
1579
+ return new Promise((resolve) => {
1580
+ pushGCCallback(`PlayersProfile_${accountid}`, resolve, 2000);
1581
+ });
1582
+ }
1583
+
1584
+ async function checkPlayerPrimeStatus(steamId) {
1585
+ const profile = await getPlayersProfile(steamId);
1586
+ if (!profile) return false;
1587
+
1588
+ if (profile.ranking?.account_id) {
1589
+ return true;
1590
+ }
1591
+
1592
+ if (profile.player_level || profile.player_cur_xp) {
1593
+ return true;
1594
+ }
1595
+ return false;
1596
+ }
1597
+
1598
+ async function _getStoreSteamPoweredResponse(cookie) {
1599
+ let response = null;
1600
+ for (let i = 0; i < 50; i++) {
1601
+ if (!response) {
1602
+ try {
1603
+ response = await axios.request({
1604
+ url: "https://store.steampowered.com/",
1605
+ headers: {
1606
+ cookie,
1607
+ accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.75",
1608
+ },
1609
+ });
1610
+ } catch (e) {
1611
+ await sleep(1000);
1612
+ }
1613
+ }
1614
+ }
1615
+ return response;
1616
+ }
1617
+
1618
+ async function getNewCookie(cookie) {
1619
+ if (!cookie) {
1620
+ return;
1621
+ }
1622
+ let response = await _getStoreSteamPoweredResponse(cookie);
1623
+ if (!response) {
1624
+ return;
1625
+ }
1626
+ while (Array.isArray(response?.headers?.["set-cookie"])) {
1627
+ console.log(cookie);
1628
+ const cookieObj = cookie.split(";").reduce(function (accumulator, currentValue) {
1629
+ accumulator[currentValue.trim().split("=")[0].trim()] = currentValue.trim().split("=")[1].trim();
1630
+ return accumulator;
1631
+ }, {});
1632
+ for (const mcookie of response.headers["set-cookie"]) {
1633
+ const name = mcookie.split("=")[0].trim();
1634
+ const value = mcookie.split("=")[1].split(";")[0].trim();
1635
+ cookieObj[name] = value;
1636
+ }
1637
+ cookie = Object.keys(cookieObj)
1638
+ .map((name) => `${name}=${cookieObj[name]}`)
1639
+ .join(";");
1640
+ response = await _getStoreSteamPoweredResponse(cookie);
1641
+ }
1642
+ return cookie;
1643
+ }
1644
+
1645
+ async function loginWithCookie(cookie, tryNewCookie = false) {
1646
+ let response;
1647
+ for (let i = 0; i < 20; i++) {
1648
+ try {
1649
+ response = await axios.request({
1650
+ url: "https://steamcommunity.com/chat/clientjstoken",
1651
+ headers: {
1652
+ cookie,
1653
+ },
1654
+ });
1655
+ } catch (e) {
1656
+ await sleep(1000);
1657
+ }
1658
+ if (response) {
1659
+ break;
1660
+ }
1661
+ }
1662
+
1663
+ const result = response?.data;
1664
+ if (result?.logged_in) {
1665
+ Object.assign(result, {
1666
+ steamID: new SteamID(result.steamid),
1667
+ accountName: result.account_name,
1668
+ webLogonToken: result.token,
1669
+ });
1670
+ steamClient.logOn(result);
1671
+ return cookie;
1672
+ } else {
1673
+ if (tryNewCookie) {
1674
+ log("You are not logged in", cookie);
1675
+ return null;
1676
+ } else {
1677
+ const newCookie = await getNewCookie(cookie);
1678
+ if (!newCookie) {
1679
+ console.error("Cannot get new cookie");
1680
+ return null;
1681
+ } else {
1682
+ return await loginWithCookie(newCookie, true);
1683
+ }
1684
+ }
1685
+ }
1686
+ }
1687
+
1688
+ async function login(reconnect = false) {
1689
+ if (clientJsToken?.logged_in === true) {
1690
+ log(reconnect ? "reconnect with clientJsToken" : "login with clientJsToken");
1691
+ steamClient.logOn(clientJsToken);
1692
+ setTimeout(function () {
1693
+ clientJsToken = null;
1694
+ }, 1000);
1695
+ return true;
1696
+ } else if (cookie) {
1697
+ log(reconnect ? "reconnect with cookie" : "login with cookie");
1698
+ const _clientJsToken = await new SteamUser(typeof cookie === "function" ? await cookie() : cookie).getClientJsToken();
1699
+ if (_clientJsToken?.logged_in === true) {
1700
+ try {
1701
+ await steamClient.logOn(_clientJsToken);
1702
+ return true;
1703
+ } catch (e) {
1704
+ return false;
1705
+ }
1706
+ } else {
1707
+ return false;
1708
+ }
1709
+ } else if (username && password) {
1710
+ log(reconnect ? `reconnect with username ${username}` : `login with username ${username}`);
1711
+ steamClient.logOn({
1712
+ accountName: username,
1713
+ password: password,
1714
+ rememberPassword: true,
1715
+ machineName: "Natri",
1716
+ });
1717
+ return true;
1718
+ }
1719
+ }
1720
+
1721
+ async function logOff() {
1722
+ isLogOff = true;
1723
+ logOffEvent?.(true);
1724
+ steamClient.logOff();
1725
+ }
1726
+
1727
+ function onCookie(callback) {
1728
+ if (getCookies()) {
1729
+ callback(getCookies());
1730
+ } else {
1731
+ onEvent(
1732
+ "webSession",
1733
+ function (webSession) {
1734
+ callback(webSession?.cookies?.join?.(";"));
1735
+ },
1736
+ true,
1737
+ );
1738
+ }
1739
+ }
1740
+
1741
+ function init() {
1742
+ bindEvent();
1743
+ login();
1744
+
1745
+ steamClient._handlerManager.add(Protos.csgo.EMsg.k_EMsgClientRequestedClientStats, function (payload) {
1746
+ const result = protoDecode(Protos.csgo.CMsgClientRequestedClientStats, payload.toBuffer());
1747
+ // console.log("CMsgClientRequestedClientStats", result);
1748
+ });
1749
+ steamClient._handlerManager.add(Protos.csgo.EMsg.k_EMsgClientMMSLobbyData, function (payload) {
1750
+ const result = protoDecode(Protos.csgo.CMsgClientMMSLobbyData, payload.toBuffer());
1751
+ // console.log("CMsgClientMMSLobbyData", result, result.metadata);
1752
+ });
1753
+ }
1754
+
1755
+ function partyRegister() {
1756
+ if (prime === null) {
1757
+ _partyRegister(true);
1758
+ _partyRegister(false);
1759
+ } else {
1760
+ _partyRegister(prime);
1761
+ }
1762
+ }
1763
+
1764
+ function _partyRegister(prime) {
1765
+ log("partyRegister", prime);
1766
+ lastTimePartyRegister = new Date().getTime();
1767
+ steamClient.sendToGC(
1768
+ 730,
1769
+ Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Party_Register,
1770
+ {},
1771
+ protoEncode(Protos.csgo.CMsgGCCStrike15_v2_Party_Register, {
1772
+ // id : 0,
1773
+ ver: CSGO_VER,
1774
+ apr: prime ? 1 : 0, //prime
1775
+ ark: prime ? 180 : 0,
1776
+ grps: [],
1777
+ launcher: 0,
1778
+ game_type: 8,
1779
+ }),
1780
+ );
1781
+ }
1782
+
1783
+ async function sendFriendMessage(steamId, message) {
1784
+ while (sendMessageTimestamp && new Date().getTime() - sendMessageTimestamp < 2000) {
1785
+ await sleep(1000);
1786
+ }
1787
+
1788
+ while (isSendingFriendMessages) {
1789
+ await sleep(5000);
1790
+ }
1791
+
1792
+ isSendingFriendMessages = true;
1793
+ const now = new Date().getTime();
1794
+ while (new Date().getTime() - now < 2 * 60000) {
1795
+ //2 minutes
1796
+ const result = await new Promise((resolve) => {
1797
+ steamClient.chat.sendFriendMessage(steamId, message, undefined, function (...arg) {
1798
+ sendMessageTimestamp = new Date().getTime();
1799
+ resolve(arg);
1800
+ });
1801
+ });
1802
+
1803
+ if (result?.[1]?.server_timestamp) {
1804
+ isSendingFriendMessages = false;
1805
+ return result?.[1];
1806
+ } else if (result?.[0]?.message?.includes?.("RateLimitExceeded")) {
1807
+ await sleep(5000);
1808
+ } else {
1809
+ isSendingFriendMessages = false;
1810
+ return result;
1811
+ }
1812
+ }
1813
+ isSendingFriendMessages = false;
1814
+ }
1815
+
1816
+ async function autoRequestFreeLicense(shouldLog = false, max = 10) {
1817
+ return;
1818
+ // const mCookies = await getCookiesWait()
1819
+ // if (!mCookies) return
1820
+ // let freeAppList = Array.isArray(steamClient.licenses) ? FreeAppList.filter(appId => steamClient.licenses.every(({package_id}) => package_id !== appId)) : FreeAppList;
1821
+ const freeAppList = freeAppList.filter((appId) => ownedApps.some((app) => app.appid == appId));
1822
+ const recommendedApps = _.shuffle(freeAppList);
1823
+ if (max) {
1824
+ recommendedApps.length = Math.min(recommendedApps.length, max);
1825
+ }
1826
+ try {
1827
+ const response = await steamClient.requestFreeLicense(recommendedApps);
1828
+ if (shouldLog) {
1829
+ log(response);
1830
+ }
1831
+ } catch (e) {
1832
+ log(e);
1833
+ }
1834
+ // if (Math.random() > 0.7) {
1835
+ // for (const recommendedApp of recommendedApps) {
1836
+ // try {
1837
+ // await steamUtils.requestFreeLicense(recommendedApp)
1838
+ // } catch (e) {
1839
+ // }
1840
+ // await sleep(2000)
1841
+ // }
1842
+ // } else {
1843
+ // try {
1844
+ // await steamClient.requestFreeLicense(recommendedApps)
1845
+ // } catch (e) {
1846
+ // log(e);
1847
+ // }
1848
+ // }
1849
+
1850
+ // if (shouldLog) {
1851
+ // await sleep(20000)
1852
+ // const ownedAppsCount2 = (await steamUtils.getDynamicStoreUserData())?.rgOwnedApps?.length || 0
1853
+ // const increaseNumber = ownedAppsCount2 - ownedAppsCount;
1854
+ // log(`OwnedApps length ${ownedAppsCount2}, increase ${increaseNumber}`)
1855
+ // }
1856
+ }
1857
+
1858
+ async function playCSGO() {
1859
+ try {
1860
+ await steamClient.requestFreeLicense(AppID);
1861
+ await sleep(5000);
1862
+ } catch (e) {}
1863
+ gamesPlayed(AppID);
1864
+ }
1865
+
1866
+ function doFakeGameScore() {
1867
+ const maxRound = Math.random() > 0.7 ? 16 : 12;
1868
+ const maps = [
1869
+ "ar_baggage",
1870
+ "ar_dizzy",
1871
+ "ar_monastery",
1872
+ "ar_shoots",
1873
+ "cs_agency",
1874
+ "cs_assault",
1875
+ "cs_italy",
1876
+ "cs_militia",
1877
+ "cs_office",
1878
+ "de_ancient",
1879
+ "de_anubis",
1880
+ "de_bank",
1881
+ "de_boyard",
1882
+ "de_cache",
1883
+ "de_canals",
1884
+ "de_cbble",
1885
+ "de_chalice",
1886
+ "de_dust2",
1887
+ "de_inferno",
1888
+ "de_lake",
1889
+ "de_mirage",
1890
+ "de_nuke",
1891
+ "de_overpass",
1892
+ "de_safehouse",
1893
+ // "de_shortnuke",
1894
+ "de_stmarc",
1895
+ "de_sugarcane",
1896
+ "de_train",
1897
+ "de_tuscan",
1898
+ "de_vertigo",
1899
+ "dz_ember",
1900
+ "dz_vineyard",
1901
+ "gd_cbble",
1902
+ "training1",
1903
+ ];
1904
+
1905
+ if (richPresence.myScore === undefined) {
1906
+ richPresence.myScore = _.random(0, maxRound);
1907
+ }
1908
+ if (richPresence.theirScore === undefined) {
1909
+ richPresence.theirScore = _.random(0, maxRound);
1910
+ }
1911
+ if (richPresence.map === undefined) {
1912
+ richPresence.map = maps[Math.floor(Math.random() * maps.length)];
1913
+ }
1914
+ if (richPresence.myScore === maxRound || richPresence.theirScore === maxRound) {
1915
+ richPresence.myScore = 0;
1916
+ richPresence.theirScore = 0;
1917
+ richPresence.map = maps[Math.floor(Math.random() * maps.length)];
1918
+ } else {
1919
+ const isMyTeamWin = Math.random() > 0.5;
1920
+ if (isMyTeamWin) {
1921
+ richPresence.myScore++;
1922
+ } else {
1923
+ richPresence.theirScore++;
1924
+ }
1925
+ }
1926
+
1927
+ const score = richPresence.myScore === 0 && richPresence.theirScore === 0 ? "" : `[ ${richPresence.myScore} : ${richPresence.theirScore} ]`;
1928
+ steamClient.uploadRichPresence(730, {
1929
+ "game:state": "game",
1930
+ steam_display: "#display_GameKnownMapScore",
1931
+ connect: "+gcconnectG082AA752",
1932
+ version: CSGO_VER.toString(),
1933
+ "game:mode": "competitive",
1934
+ "game:map": richPresence.map,
1935
+ "game:server": "kv",
1936
+ watch: _.random(1, 5).toString(),
1937
+ "game:score": score,
1938
+ });
1939
+ }
1940
+
1941
+ function updateFakeGameScore() {
1942
+ if (isFakeGameScore && getPlayingAppIds().some((a) => a == 730)) {
1943
+ doSetInterval(doFakeGameScore, [60000, 180000], "uploadRichPresenceCSGO");
1944
+ } else {
1945
+ doClearInterval("uploadRichPresenceCSGO");
1946
+ }
1947
+ }
1948
+
1949
+ function updateAutoRequestFreeLicense() {
1950
+ if (isAutoRequestFreeLicense) {
1951
+ doSetInterval(
1952
+ function () {
1953
+ autoRequestFreeLicense(false, 50);
1954
+ },
1955
+ [5 * 60000, 10 * 60000],
1956
+ "autoRequestFreeLicense",
1957
+ );
1958
+ } else {
1959
+ doClearInterval("autoRequestFreeLicense");
1960
+ }
1961
+ }
1962
+
1963
+ function updateInvisible() {
1964
+ if (isInvisible) {
1965
+ steamClient.setPersona(NodeSteamUser.EPersonaState.Invisible);
1966
+ state = "Invisible";
1967
+ } else {
1968
+ steamClient.setPersona(NodeSteamUser.EPersonaState.Online);
1969
+ state = "Online";
1970
+ }
1971
+ }
1972
+
1973
+ async function gamesPlayed(apps) {
1974
+ if (!Array.isArray(apps)) {
1975
+ apps = [apps];
1976
+ }
1977
+
1978
+ steamClient.gamesPlayed(apps);
1979
+ const shouldHello = apps.some((app) => parseInt(app) === 730);
1980
+ await sleep(10000);
1981
+ if (shouldHello) {
1982
+ await sendHello();
1983
+ }
1984
+ await sleep(1000);
1985
+ if (shouldHello) {
1986
+ await sendHello();
1987
+ }
1988
+ updateFakeGameScore();
1989
+
1990
+ // await sleep(10000)
1991
+ // self.steamUser.uploadRichPresence(730, {
1992
+ // status: 'bussssss',
1993
+ // 'game:state': 'lobby',
1994
+ // steam_display: '#display_watch',
1995
+ // currentmap: '#gamemap_de_empire',
1996
+ // connect: '+gcconnectG082AA752',
1997
+ // 'game:mode': 'competitive'
1998
+ // })
1999
+ }
2000
+
2001
+ function getFriendsList() {
2002
+ const methodName = "FriendsList.GetFriendsList#1";
2003
+ const { users, myFriends } = steamClient; //object
2004
+ /*
2005
+ users
2006
+ * {
2007
+ rich_presence: [],
2008
+ player_name: "Kei #SkinsMonkey",
2009
+ avatar_hash: [123,4543],
2010
+ last_logoff: "2023-05-20T05:00:42.000Z",
2011
+ last_logon: "2023-05-20T05:02:16.000Z",
2012
+ last_seen_online: "2023-05-20T05:00:42.000Z",
2013
+ avatar_url_icon: "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/3e/3e9da0b107ac2ec384759544368a8a977359537a.jpg",
2014
+ avatar_url_medium: "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/3e/3e9da0b107ac2ec384759544368a8a977359537a_medium.jpg",
2015
+ avatar_url_full: "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/3e/3e9da0b107ac2ec384759544368a8a977359537a_full.jpg"
2016
+ }
2017
+ *
2018
+
2019
+ myFriends
2020
+ {
2021
+ 76561198365087582: 3,
2022
+ 76561199490395123: 3
2023
+ }
2024
+ * */
2025
+ /*steamClient._send({
2026
+ msg: 151,
2027
+ proto: {
2028
+ target_job_name: methodName
2029
+ }
2030
+ }, Buffer.alloc(0), function (body, hdr) {
2031
+ const result = hdr.proto.eresult
2032
+ const errorMessage = hdr.proto.error_message
2033
+ const responseData = body.toBuffer()
2034
+ console.log(`xxx`, result)
2035
+ })*/
2036
+
2037
+ steamClient.sendToGC(730, 767, {}, Buffer.alloc(0));
2038
+ }
2039
+
2040
+ async function getUserOwnedApps(steamId = steamClient.steamID) {
2041
+ if (!steamId) {
2042
+ return [];
2043
+ }
2044
+ if (typeof steamId?.getSteamID64 === "function") {
2045
+ steamId = steamId.getSteamID64();
2046
+ }
2047
+ const isMe = steamId === steamClient.steamID.getSteamID64();
2048
+ if (isMe && ownedApps.length) {
2049
+ return ownedApps;
2050
+ }
2051
+ let result = {};
2052
+ try {
2053
+ result = await steamClient.getUserOwnedApps(steamId);
2054
+ } catch (e) {
2055
+ try {
2056
+ result = await steamClient.getUserOwnedApps(steamId);
2057
+ } catch (e) {
2058
+ result = {};
2059
+ }
2060
+ }
2061
+ if (isMe && Array.isArray(result.apps)) {
2062
+ ownedApps.length = 0;
2063
+ ownedApps.push(...result.apps);
2064
+ }
2065
+ return result.apps || [];
2066
+ const resultExample = {
2067
+ app_count: 22,
2068
+ apps: [
2069
+ {
2070
+ content_descriptorids: [],
2071
+ appid: 208030,
2072
+ name: "Moon Breakers",
2073
+ playtime_2weeks: null,
2074
+ playtime_forever: 0,
2075
+ img_icon_url: "",
2076
+ has_community_visible_stats: null,
2077
+ playtime_windows_forever: 0,
2078
+ playtime_mac_forever: 0,
2079
+ playtime_linux_forever: 0,
2080
+ rtime_last_played: 0,
2081
+ capsule_filename: null,
2082
+ sort_as: null,
2083
+ has_workshop: null,
2084
+ has_market: null,
2085
+ has_dlc: null,
2086
+ has_leaderboards: null,
2087
+ },
2088
+ ],
2089
+ };
2090
+ }
2091
+
2092
+ function getPlayingAppIds() {
2093
+ return steamClient._playingAppIds || [];
2094
+ }
2095
+
2096
+ return {
2097
+ init,
2098
+ partySearch,
2099
+ invite2Lobby,
2100
+ createLobby,
2101
+ updateLobby,
2102
+ createThenInvite2Lobby,
2103
+ joinLobby,
2104
+ getLobbyData,
2105
+ partyRegister,
2106
+ requestCoPlays,
2107
+ getPersonas,
2108
+ getUsername() {
2109
+ return username;
2110
+ },
2111
+ getCookies,
2112
+ getCookiesWait,
2113
+ getLogOnDetails() {
2114
+ return steamClient?._logOnDetails;
2115
+ },
2116
+ onEvent,
2117
+ offEvent,
2118
+ offAllEvent,
2119
+ setPersona(state, name) {
2120
+ steamClient.setPersona(state, name);
2121
+ },
2122
+ sendFriendMessage,
2123
+ sendFriendTyping,
2124
+ getSteamClient() {
2125
+ return steamClient;
2126
+ },
2127
+ getAccountInfoName,
2128
+ getPersonaName,
2129
+ async getPlayersProfile(steamId, retry = 3) {
2130
+ for (let i = 0; i < retry; i++) {
2131
+ const profile = await getPlayersProfile(steamId);
2132
+ if (profile) {
2133
+ return profile;
2134
+ }
2135
+ }
2136
+ return null;
2137
+ },
2138
+ autoRequestFreeLicense,
2139
+ playCSGO,
2140
+ doSetInterval,
2141
+ doClearIntervals,
2142
+ gamesPlayed,
2143
+ sendHello,
2144
+ checkPlayerPrimeStatus,
2145
+ doClearInterval,
2146
+ gamePlay,
2147
+ autoGamePlay,
2148
+ offAutoGamePlay,
2149
+ updateAutoGamePlay,
2150
+ getFriendsList,
2151
+ setIsPartyRegister(change) {
2152
+ change = !!change;
2153
+ if (isPartyRegister !== change) {
2154
+ isPartyRegister = change;
2155
+ if (!isPartyRegister) {
2156
+ doClearInterval("autoPartyRegister");
2157
+ } else {
2158
+ sendHello();
2159
+ }
2160
+ }
2161
+ },
2162
+ setAutoPlay(change) {
2163
+ change = !!change;
2164
+ if (isAutoPlay !== change) {
2165
+ isAutoPlay = change;
2166
+ updateAutoGamePlay();
2167
+ }
2168
+ },
2169
+ setIsInvisible(change) {
2170
+ change = !!change;
2171
+ if (isInvisible !== change) {
2172
+ isInvisible = change;
2173
+ updateInvisible();
2174
+ }
2175
+ },
2176
+ setFakeGameScore(change) {
2177
+ change = !!change;
2178
+ if (isFakeGameScore !== change) {
2179
+ isFakeGameScore = change;
2180
+ updateFakeGameScore();
2181
+ }
2182
+ },
2183
+ setAutoRequestFreeLicense(change) {
2184
+ change = !!change;
2185
+ if (isAutoRequestFreeLicense !== change) {
2186
+ isAutoRequestFreeLicense = change;
2187
+ updateAutoRequestFreeLicense();
2188
+ }
2189
+ },
2190
+ getState() {
2191
+ return state;
2192
+ },
2193
+ log,
2194
+ isPrime() {
2195
+ return prime === true;
2196
+ },
2197
+ getFriendList,
2198
+ logOff,
2199
+ isPlayingBlocked() {
2200
+ return playingBlocked;
2201
+ },
2202
+ async getChatHistory(steamId) {
2203
+ if (!steamClient.steamID) return [];
2204
+ const mySteamId = typeof steamClient.steamID.getSteamID64 === "function" ? steamClient.steamID.getSteamID64() : steamClient.steamID;
2205
+ return new Promise((resolve) => {
2206
+ setTimeout(resolve, 90000);
2207
+ steamClient.getChatHistory(steamId, async function (error, result) {
2208
+ const messages = (result || []).map(function (msg) {
2209
+ const fromSteamId = typeof msg.steamID?.getSteamID64 === "function" ? msg.steamID.getSteamID64() : msg.steamID;
2210
+ return {
2211
+ message: msg.message,
2212
+ from: fromSteamId,
2213
+ to: fromSteamId == mySteamId ? steamId : mySteamId,
2214
+ _id: new Date(msg.timestamp).getTime().toString(),
2215
+ timestamp: new Date(msg.timestamp).getTime(),
2216
+ isMe: fromSteamId !== steamId,
2217
+ };
2218
+ });
2219
+ resolve(messages);
2220
+ });
2221
+ });
2222
+ },
2223
+ onAnyEvent,
2224
+ async redeemGift(gid) {
2225
+ try {
2226
+ const community = new SteamCommunity();
2227
+ let cookies = await getCookiesWait();
2228
+ community.setCookies(typeof cookies === "string" ? cookies.split(";") : cookies);
2229
+ community.redeemGift(gid);
2230
+ } catch (e) {}
2231
+ },
2232
+ async requestFreeLicense(...args) {
2233
+ try {
2234
+ return await steamClient.requestFreeLicense(...args);
2235
+ } catch (e) {}
2236
+ },
2237
+ getSteamId() {
2238
+ try {
2239
+ return steamClient.steamID.getSteamID64();
2240
+ } catch (e) {}
2241
+ },
2242
+ getLastTimePartyRegister() {
2243
+ return lastTimePartyRegister;
2244
+ },
2245
+ getLastTimePartySearch() {
2246
+ return lastTimePartySearch;
2247
+ },
2248
+ getLicenses() {
2249
+ return steamClient.licenses;
2250
+ const exampleLicenses = [
2251
+ {
2252
+ package_id: 303386,
2253
+ time_created: 1680491335,
2254
+ time_next_process: 0,
2255
+ minute_limit: 0,
2256
+ minutes_used: 0,
2257
+ payment_method: 1024,
2258
+ flags: 512,
2259
+ purchase_country_code: "VN",
2260
+ license_type: 1,
2261
+ territory_code: 0,
2262
+ change_number: 20615891,
2263
+ owner_id: 1530068060,
2264
+ initial_period: 0,
2265
+ initial_time_unit: 0,
2266
+ renewal_period: 0,
2267
+ renewal_time_unit: 0,
2268
+ access_token: "8049398090486337961",
2269
+ master_package_id: null,
2270
+ },
2271
+ ];
2272
+ },
2273
+ uploadRichPresence(appid, richPresence) {
2274
+ if (Array.isArray(richPresence)) {
2275
+ richPresence = richPresence.reduce(function (previousValue, currentValue, currentIndex, array) {
2276
+ if (currentValue.key) {
2277
+ previousValue[currentValue.key] = currentValue.value?.toString() || "";
2278
+ }
2279
+ return previousValue;
2280
+ });
2281
+ }
2282
+ steamClient.uploadRichPresence(appid, richPresence);
2283
+ },
2284
+ getUserOwnedApps,
2285
+ getPlayingAppIds,
2286
+ getCurrentLobby() {
2287
+ return currentLobby;
2288
+ },
2289
+ };
2290
+ }
2291
+
2292
+ export default SteamClient;
2293
+
2294
+ export function increaseCSGO_VER() {
2295
+ return ++CSGO_VER;
2296
+ }
2297
+
2298
+ SteamClient.isAccountPlayable = async function isAccountPlayable(params, timeoutMs) {
2299
+ let clientJsToken = params.clientJsToken;
2300
+ delete params.clientJsToken;
2301
+ if (!clientJsToken && params.cookie) {
2302
+ clientJsToken = await new SteamUser(typeof params.cookie === "function" ? await params.cookie() : params.cookie).getClientJsToken();
2303
+ }
2304
+ if (clientJsToken?.logged_in !== true) {
2305
+ return false;
2306
+ }
2307
+ params.clientJsToken = clientJsToken;
2308
+
2309
+ return await new Promise((resolve) => {
2310
+ const timeouts = [
2311
+ setTimeout(() => {
2312
+ doResolve();
2313
+ }, timeoutMs || 30000),
2314
+ ];
2315
+
2316
+ const steamClient = new SteamClient({
2317
+ isFakeGameScore: false,
2318
+ isAutoPlay: true,
2319
+ isPartyRegister: false,
2320
+ isInvisible: false,
2321
+ MAX_GAME_PLAY: 10,
2322
+ games: 730,
2323
+ ...params,
2324
+ });
2325
+
2326
+ steamClient.onEvent("error", ({ eresult, msg, error }) => {
2327
+ doResolve();
2328
+ });
2329
+
2330
+ steamClient.onEvent("csgoOnline", (ClientWelcome) => {
2331
+ doResolve(ClientWelcome);
2332
+ });
2333
+
2334
+ steamClient.onEvent("csgoClientHello", (ClientHello) => {
2335
+ doResolve(ClientHello);
2336
+ });
2337
+
2338
+ steamClient.onEvent("playingState", ({ playing_blocked, playing_app }) => {
2339
+ if (playing_blocked) {
2340
+ doResolve();
2341
+ } else {
2342
+ timeouts.push(
2343
+ setTimeout(function () {
2344
+ const isBlocked = steamClient.isPlayingBlocked();
2345
+ doResolve(!isBlocked);
2346
+ }, 5000),
2347
+ );
2348
+ }
2349
+ });
2350
+
2351
+ steamClient.onEvent("fatalError", () => {
2352
+ doResolve();
2353
+ });
2354
+
2355
+ steamClient.init();
2356
+
2357
+ function doResolve(data) {
2358
+ timeouts.forEach((timeout) => clearTimeout(timeout));
2359
+ steamClient.doClearIntervals();
2360
+ steamClient.offAllEvent();
2361
+ steamClient.logOff();
2362
+ return resolve(!!data);
2363
+ }
2364
+ });
2365
+ };