steamutils 1.0.44 → 1.0.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/SteamClient.js +144 -74
  2. package/package.json +1 -1
  3. package/utils.js +35 -4
package/SteamClient.js CHANGED
@@ -95,11 +95,67 @@ function SteamClient({
95
95
 
96
96
  const events = {
97
97
  loggedOn: [],
98
+ csgoOnline: [],
98
99
  webSession: [],
99
100
  friendMessage: [],
100
101
  friendTyping: [],
101
102
  }
102
103
 
104
+ const gcCallback = {}
105
+
106
+ function pushGCCallback(name, cb, timeout) {
107
+ if (!gcCallback[name]) {
108
+ gcCallback[name] = {}
109
+ }
110
+ let t = null
111
+ let id = uuidv4()
112
+
113
+ function callback(...arg) {
114
+ if (t) {
115
+ clearTimeout(t)
116
+ }
117
+ delete gcCallback[name][id]
118
+ cb(arg)
119
+ }
120
+
121
+ if (timeout) {
122
+ t = setTimeout(callback, timeout)
123
+ }
124
+ gcCallback[name][id] = callback
125
+ }
126
+
127
+ function callGCCallback(name, ...arg) {
128
+ if (gcCallback[name]) {
129
+ for (let id in gcCallback[name]) {
130
+ gcCallback[name][id](arg)
131
+ }
132
+ }
133
+ }
134
+
135
+ function callEvent(_events, data) {
136
+ _events.forEach((e) => {
137
+ e.callback?.(data)
138
+ e.timeout && clearTimeout(e.timeout)
139
+ delete e.timeout
140
+ if (e.once) {
141
+ delete e.callback
142
+ }
143
+ })
144
+ _.remove(_events, e => e.once)
145
+ }
146
+
147
+ function onEvent(name, callback, once, timeout) {
148
+ if (!events[name]) {
149
+ events[name] = []
150
+ }
151
+ const t = timeout ? setTimeout(callback, timeout) : null
152
+ events[name].push({
153
+ once,
154
+ callback,
155
+ timeout: t,
156
+ })
157
+ }
158
+
103
159
  const intervals = {}
104
160
 
105
161
  function doSetInterval(cb, timeout, key) {
@@ -113,6 +169,7 @@ function SteamClient({
113
169
  }
114
170
  }
115
171
  intervals[key] = setInterval(cb, timeout)
172
+ return key
116
173
  }
117
174
 
118
175
  function doClearIntervals() {
@@ -126,6 +183,10 @@ function SteamClient({
126
183
  return [steamClient?.accountInfo?.name, steamClient?._logOnDetails?.account_name].filter(Boolean).join(" - ")
127
184
  }
128
185
 
186
+ function log(msg) {
187
+ console.log(`[${getAccountInfoName()}] ${msg}`)
188
+ }
189
+
129
190
  async function getPersonas(steamIDs) {
130
191
  steamIDs = steamIDs.map(steamID => steamID instanceof SteamID ? steamID.getSteamID64() : steamID)
131
192
  const notCachesteamIDs = steamIDs.filter(id => !PersonasCache.some(p => p.id == id))
@@ -165,13 +226,12 @@ function SteamClient({
165
226
  return cachedPersonas
166
227
  }
167
228
 
168
- const sleep = (ms) => {
229
+ function sleep(ms) {
169
230
  return new Promise(resolve => {
170
231
  setTimeout(resolve, ms)
171
232
  })
172
233
  }
173
234
 
174
- const partySearchCallback = []
175
235
 
176
236
  /**
177
237
  * Get a list of lobbies (* = Unsure description could be wrong)
@@ -199,33 +259,26 @@ function SteamClient({
199
259
  launcher: 0,
200
260
  game_type: game_type === 'Competitive' ? 8 : 10
201
261
  }))
202
- partySearchCallback.push(resolve)
203
- setTimeout(resolve, timeout)
262
+ pushGCCallback('partySearch', resolve, timeout)
204
263
  })
205
264
  }
206
265
 
207
266
  async function sendHello() {
208
- console.log('sendHello', getAccountInfoName())
209
267
  steamClient.sendToGC(appid, Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_MatchmakingClient2GCHello, {}, Buffer.alloc(0))
210
268
  steamClient.sendToGC(appid, Protos.csgo.EGCBaseClientMsg.k_EMsgGCClientHello, {}, Buffer.alloc(0))
211
- console.log('sendHello done', getAccountInfoName())
212
269
  }
213
270
 
214
- const requestCoPlaysCallback = []
215
-
216
271
  async function requestCoPlays() {
217
- console.log('sendMessageAccount_RequestCoPlays')
218
272
  return new Promise(resolve => {
219
273
  steamClient.sendToGC(appid, Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Account_RequestCoPlays, {}, Buffer.alloc(0))
220
- requestCoPlaysCallback.push(resolve)
221
- setTimeout(resolve, 10000)
274
+ pushGCCallback('RequestCoPlays', resolve, 30000)
222
275
  })
223
276
  }
224
277
 
225
278
 
226
279
  function bindEvent() {
227
280
  steamClient.on('disconnected', async (eresult, msg) => {
228
- console.log('disconnected', eresult, msg)
281
+ log('disconnected', eresult, msg)
229
282
  doClearIntervals()
230
283
  })
231
284
  steamClient.on('error', async (e) => {
@@ -248,26 +301,26 @@ function SteamClient({
248
301
  errorStr = `Unknown: ${e.eresult}`
249
302
  break
250
303
  }
251
- console.log('error', e?.message)
304
+ log('error', e?.message)
252
305
  doClearIntervals()
253
306
  })
254
307
 
255
308
  steamClient.on('webSession', (sessionID, cookies) => {
256
309
  const webSession = {sessionID, cookies};
257
310
  steamClient.webSession = webSession
258
- events.webSession.forEach(e => e?.(webSession))
311
+ callEvent(events.webSession, webSession)
259
312
  })
260
313
 
261
314
  steamClient.on('receivedFromGC', async (appid, msgType, payload) => {
262
315
  const key = getECsgoGCMsgKey(msgType)
263
316
  switch (msgType) {
264
317
  case Protos.csgo.EMsg.k_EMsgClientChatInvite: {
265
- console.log(payload)
318
+ log(payload)
266
319
  break
267
320
  }
268
321
  case Protos.csgo.ECsgoGCMsg.k_EMsgClientMMSJoinLobbyResponse: {
269
322
  let msg = protoDecode(Protos.csgo.CMsgClientMMSJoinLobbyResponse, payload)
270
- console.log(msg)
323
+ log(msg)
271
324
  break
272
325
  }
273
326
  case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Party_Invite: {
@@ -276,16 +329,16 @@ function SteamClient({
276
329
  const personas = await getPersonas([sid64]);
277
330
  const player_name = personas.find(p => p.id == sid64)?.player_name
278
331
  if (player_name === undefined) {
279
- console.log(sid64, personas);
332
+ log(sid64, personas);
280
333
  }
281
- console.log(getAccountInfoName(), player_name, `https://steamcommunity.com/profiles/${sid64}`);
334
+ log(getAccountInfoName(), player_name, `https://steamcommunity.com/profiles/${sid64}`);
282
335
  // joinLobby(msg.lobbyid, msg.accountid)
283
336
  break
284
337
  }
285
338
  case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Account_RequestCoPlays: {
286
339
  const msg = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_Account_RequestCoPlays, payload);
287
340
  const personas = msg.players.map(p => SteamID.fromIndividualAccountID(p.accountid));
288
- requestCoPlaysCallback?.shift()?.(personas)
341
+ callGCCallback('RequestCoPlays', personas)
289
342
  break
290
343
  }
291
344
  case Protos.csgo.EGCBaseClientMsg.k_EMsgGCClientWelcome: {
@@ -307,9 +360,13 @@ function SteamClient({
307
360
  }
308
361
  break
309
362
  }
363
+ default: {
364
+ log("cache_object.type_id", cache_object.type_id);
365
+ }
310
366
  }
311
367
  }
312
368
  }
369
+ callEvent(events.csgoOnline)
313
370
  break
314
371
  }
315
372
  case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_MatchmakingGC2ClientUpdate: {
@@ -461,11 +518,7 @@ function SteamClient({
461
518
  }
462
519
  }
463
520
 
464
-
465
- let _partySearchCallback = null
466
- while ((_partySearchCallback = partySearchCallback.shift())) {
467
- _partySearchCallback?.(players)
468
- }
521
+ callGCCallback('partySearch', players)
469
522
  break
470
523
  }
471
524
  case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_PlayersProfile: {
@@ -506,16 +559,13 @@ function SteamClient({
506
559
  player_cur_xp: 327682846,
507
560
  player_xp_bonus_flags: 0
508
561
  }]
509
- console.log(data);
510
562
 
511
563
  const accountid = data?.[0]?.account_id
512
- const cb = getPlayersProfileCallback[accountid]
513
- delete getPlayersProfileCallback[accountid]
514
- cb?.(data?.[0])
564
+ callGCCallback('PlayersProfile' + accountid, data?.[0])
515
565
  break
516
566
  }
517
567
  default:
518
- console.log(`receivedFromGC ${msgType} ${key}`)
568
+ log(`receivedFromGC ${msgType} ${key}`)
519
569
  const results = Object.values(Protos.csgo).map(function (p) {
520
570
  try {
521
571
  return protoDecode(p, payload)
@@ -524,7 +574,7 @@ function SteamClient({
524
574
  }).filter(function (result) {
525
575
  return result && Object.keys(result).length
526
576
  })
527
- console.log(key, results)
577
+ log(key, results)
528
578
  }
529
579
  })
530
580
 
@@ -572,38 +622,38 @@ function SteamClient({
572
622
  await sleep(1000)
573
623
  }
574
624
 
575
- console.log(`app ${appid} launched on account ${getAccountInfoName()}`)
625
+ log(`app ${appid} launched`)
576
626
  await sendHello()
577
627
 
578
- events.loggedOn.forEach(e => e?.())
628
+ callEvent(events.loggedOn)
579
629
  })
580
630
 
581
631
  steamClient.on('friendMessage', async (user, message) => {
582
632
  const sid64 = user.getSteamID64();
583
633
  const personas = await getPersonas([sid64]);
584
634
  const player_name = personas[sid64]?.player_name || ''
585
- console.log('friendMessage', sid64, message);
635
+ log('friendMessage', sid64, message);
586
636
 
587
- if ([`Invited you to play a game!`, `Đã mời bạn chơi một trò chơi!`].includes(message)) {
588
- if (events.friendMessage.length) {
589
- events.friendMessage.forEach(e => e?.({
590
- player_name,
591
- message,
592
- invite: true,
593
- sid64,
594
- }))
595
- }
637
+ if ([`Inited you to play a game!`, `Đã mời bạn chơi một trò chơi!`].includes(message)) {
638
+ callEvent(events.friendMessage, {
639
+ player_name,
640
+ message,
641
+ invite: true,
642
+ sid64,
643
+ })
596
644
  } else {
597
- events.friendMessage.forEach(e => e?.({
645
+ callEvent(events.friendMessage, {
598
646
  message,
599
647
  player_name,
600
648
  sid64,
601
- }))
649
+ })
602
650
  }
603
651
  });
604
652
 
605
653
  steamClient.on('friendTyping', async function (steamID, message) {
606
- events.friendTyping.forEach(e => e?.(steamID, message))
654
+ callEvent(events.friendTyping, {
655
+ steamID, message
656
+ })
607
657
  });
608
658
  }
609
659
 
@@ -612,19 +662,30 @@ function SteamClient({
612
662
  }
613
663
 
614
664
 
615
- const getPlayersProfileCallback = {};
616
-
617
665
  function getPlayersProfile(accountid) {
618
666
  steamClient.sendToGC(730, Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_ClientRequestPlayersProfile, {}, protoEncode(Protos.csgo.CMsgGCCStrike15_v2_ClientRequestPlayersProfile, {
619
667
  account_id: accountid, // account_id: new SteamID('76561199184696945').accountid,
620
668
  request_level: 32
621
669
  }))
622
670
  return new Promise(resolve => {
623
- getPlayersProfileCallback[accountid] = resolve
624
- setTimeout(resolve, 30000)
671
+ pushGCCallback('PlayersProfile' + accountid, resolve, 30000)
625
672
  })
626
673
  }
627
674
 
675
+ async function checkPlayerPrimeStatus(accountid) {
676
+ const profile = await getPlayersProfile(accountid)
677
+ if (!profile) return false
678
+
679
+ if (profile.ranking?.account_id) {
680
+ return true
681
+ }
682
+
683
+ if (profile.player_level || profile.player_cur_xp) {
684
+ return true
685
+ }
686
+ return false
687
+ }
688
+
628
689
  async function getNewCookie(cookie) {
629
690
  let response = (await axios.request({
630
691
  url: 'https://store.steampowered.com/', headers: {
@@ -669,7 +730,7 @@ function SteamClient({
669
730
  return cookie
670
731
  } else {
671
732
  if (tryNewCookie) {
672
- console.log('You are not logged in', cookie)
733
+ log('You are not logged in', cookie)
673
734
  return null
674
735
  } else {
675
736
  return await loginWithCookie(await getNewCookie(cookie), true)
@@ -679,13 +740,13 @@ function SteamClient({
679
740
 
680
741
  async function login() {
681
742
  if (cookie) {
682
- console.log('login with cookie')
743
+ log('login with cookie')
683
744
  const newCookie = await loginWithCookie(cookie)
684
745
  if (newCookie) {
685
746
  cookie = newCookie
686
747
  }
687
748
  } else if (username && password) {
688
- console.log(`login with username ${username}`)
749
+ log(`login with username ${username}`)
689
750
  steamClient.logOn({
690
751
  accountName: username, password: password, rememberPassword: true, machineName: 'Natri',
691
752
  })
@@ -699,14 +760,16 @@ function SteamClient({
699
760
 
700
761
 
701
762
  function partyRegister() {
702
- _partyRegister(prime)
703
763
  if (prime === null) {
704
764
  _partyRegister(true)
765
+ _partyRegister(false)
766
+ } else {
767
+ _partyRegister(prime)
705
768
  }
706
769
  }
707
770
 
708
771
  function _partyRegister(prime) {
709
- console.log("partyRegister", getAccountInfoName(), prime);
772
+ log("partyRegister", prime);
710
773
  steamClient.sendToGC(730, Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Party_Register, {}, protoEncode(Protos.csgo.CMsgGCCStrike15_v2_Party_Register, {
711
774
  // id : 0,
712
775
  ver: CSGO_VER, apr: prime ? 1 : 0,//prime
@@ -733,14 +796,16 @@ function SteamClient({
733
796
  }
734
797
  }
735
798
 
736
- async function autoRequestFreeLicense(log = false, max = 10) {
799
+ async function autoRequestFreeLicense(shouldLog = false, max = 10) {
737
800
  const steamUtils = new SteamUtils(getCookie())
738
801
 
739
- const ownedAppsCount = log ? ((await steamUtils.getDynamicStoreUserData())?.rgOwnedApps?.length || 0) : 0
802
+ const ownedApps = (await steamUtils.getDynamicStoreUserData())?.rgOwnedApps || []
803
+ const ownedAppsCount = shouldLog ? (ownedApps?.length || 0) : 0
740
804
  let recommendedApps = Math.random() > 0.5 ? _.shuffle((await steamUtils.getDynamicStoreUserData())?.rgRecommendedApps || []) : []
741
805
  if (!recommendedApps?.length) {
742
806
  recommendedApps = (await axios.request({url: 'https://raw.githubusercontent.com/5x/easy-steam-free-packages/master/src/script/packages_db.json'}))?.data?.packages || []
743
807
  }
808
+ _.remove(recommendedApps, app => ownedApps.includes(app))
744
809
 
745
810
  if (max) {
746
811
  recommendedApps.length = Math.min(recommendedApps.length, max)
@@ -755,16 +820,16 @@ function SteamClient({
755
820
  try {
756
821
  await steamClient.requestFreeLicense(recommendedApp)
757
822
  } catch (e) {
758
- console.log(e);
823
+ log(e);
759
824
  }
760
825
  }
761
826
  await sleep(2000)
762
827
  }
763
- if (log) {
828
+ if (shouldLog) {
764
829
  await sleep(20000)
765
830
  const ownedAppsCount2 = (await steamUtils.getDynamicStoreUserData())?.rgOwnedApps?.length || 0
766
831
  const increaseNumber = ownedAppsCount2 - ownedAppsCount;
767
- console.log(getAccountInfoName(), `OwnedApps length ${ownedAppsCount2}, increase ${increaseNumber}`)
832
+ log(getAccountInfoName(), `OwnedApps length ${ownedAppsCount2}, increase ${increaseNumber}`)
768
833
  }
769
834
  }
770
835
 
@@ -782,6 +847,22 @@ function SteamClient({
782
847
  steamClient.setPersona(SteamUser.EPersonaState.LookingToPlay)
783
848
  }
784
849
 
850
+ async function gamesPlayed(apps) {
851
+ steamClient.gamesPlayed(apps);
852
+ await sleep(2000)
853
+ steamClient.setPersona(SteamUser.EPersonaState.LookingToPlay)
854
+ sendHello()
855
+ // await sleep(10000)
856
+ // self.steamUser.uploadRichPresence(730, {
857
+ // status: 'bussssss',
858
+ // 'game:state': 'lobby',
859
+ // steam_display: '#display_watch',
860
+ // currentmap: '#gamemap_de_empire',
861
+ // connect: '+gcconnectG082AA752',
862
+ // 'game:mode': 'competitive'
863
+ // })
864
+ }
865
+
785
866
  return {
786
867
  init,
787
868
  partySearch,
@@ -795,15 +876,7 @@ function SteamClient({
795
876
  getLogOnDetails() {
796
877
  return steamClient?._logOnDetails
797
878
  },
798
- onEvent(name, cb) {
799
- if (!events[name]) {
800
- events[name] = []
801
- }
802
- events[name].push(cb)
803
- },
804
- onEventLoggedOn(cb) {
805
- events.loggedOn.push(cb)
806
- },
879
+ onEvent,
807
880
  setPersona(state, name) {
808
881
  steamClient.setPersona(state, name)
809
882
  },
@@ -821,12 +894,9 @@ function SteamClient({
821
894
  playCSGO,
822
895
  doSetInterval,
823
896
  doClearIntervals,
824
- async gamesPlayed(apps) {
825
- steamClient.gamesPlayed(apps);
826
- await sleep(2000)
827
- steamClient.setPersona(SteamUser.EPersonaState.LookingToPlay)
828
- sendHello()
829
- }
897
+ gamesPlayed,
898
+ sendHello,
899
+ checkPlayerPrimeStatus,
830
900
  }
831
901
  }
832
902
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "steamutils",
3
- "version": "1.0.44",
3
+ "version": "1.0.46",
4
4
  "dependencies": {
5
5
  "axios": "^1.3.4",
6
6
  "cheerio": "^1.0.0-rc.12",
package/utils.js CHANGED
@@ -34,7 +34,7 @@ const minDate = new Date(0),
34
34
  maxDate = new Date(parseInt('ffffffff', 16) * 1000)
35
35
 
36
36
  export function objectIdFromDate(date) {
37
- if(date < minDate || date > maxDate) {
37
+ if (date < minDate || date > maxDate) {
38
38
  return 'Error: date must be between ' + minDate.getFullYear() + ' and ' + maxDate.getFullYear()
39
39
  }
40
40
  var pad = '00000000'
@@ -56,13 +56,13 @@ export function console_log(...args) {
56
56
  }
57
57
 
58
58
  export function removeSpaceKeys(object) {//mutate object
59
- if(!object || Array.isArray(object)) {
59
+ if (!object || Array.isArray(object)) {
60
60
  return object
61
61
  }
62
62
 
63
63
  Object.entries(object).forEach(([key, value]) => {
64
64
  const newKey = key.replaceAll(/[^a-zA-Z0-9]/gi, '_')
65
- if(newKey !== key) {
65
+ if (newKey !== key) {
66
66
  delete object[key]
67
67
  object[newKey] = value
68
68
  }
@@ -71,7 +71,7 @@ export function removeSpaceKeys(object) {//mutate object
71
71
  }
72
72
 
73
73
  export function getCleanObject(object) {//like removeSpaceKeys but not mutate object
74
- if(!object || Array.isArray(object)) {
74
+ if (!object || Array.isArray(object)) {
75
75
  return object
76
76
  }
77
77
 
@@ -98,3 +98,34 @@ export function JSON_stringify(data) {
98
98
  return null
99
99
  }
100
100
  }
101
+
102
+
103
+ export async function throttle(fn, delay) {
104
+ let canFire = true
105
+ let queue = []
106
+
107
+ async function pop() {
108
+ if (queue.length < 1) return
109
+
110
+ const [that, args] = queue.pop()
111
+ await fn.apply(that, args)
112
+ canFire = false
113
+ setTimeout(async () => {
114
+ canFire = true
115
+ await pop()
116
+ }, delay)
117
+ }
118
+
119
+ async function push() {
120
+ queue.push([this, arguments])
121
+ if (canFire) {
122
+ await pop()
123
+ }
124
+ }
125
+
126
+ push.cancel = () => {
127
+ queue = []
128
+ }
129
+
130
+ return push
131
+ }