steamutils 1.0.45 → 1.0.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 +94 -58
- package/package.json +1 -1
- package/utils.js +35 -4
package/SteamClient.js
CHANGED
@@ -100,6 +100,38 @@ function SteamClient({
|
|
100
100
|
friendMessage: [],
|
101
101
|
friendTyping: [],
|
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
|
+
|
103
135
|
function callEvent(_events, data) {
|
104
136
|
_events.forEach((e) => {
|
105
137
|
e.callback?.(data)
|
@@ -111,6 +143,7 @@ function SteamClient({
|
|
111
143
|
})
|
112
144
|
_.remove(_events, e => e.once)
|
113
145
|
}
|
146
|
+
|
114
147
|
function onEvent(name, callback, once, timeout) {
|
115
148
|
if (!events[name]) {
|
116
149
|
events[name] = []
|
@@ -136,6 +169,7 @@ function SteamClient({
|
|
136
169
|
}
|
137
170
|
}
|
138
171
|
intervals[key] = setInterval(cb, timeout)
|
172
|
+
return key
|
139
173
|
}
|
140
174
|
|
141
175
|
function doClearIntervals() {
|
@@ -149,6 +183,10 @@ function SteamClient({
|
|
149
183
|
return [steamClient?.accountInfo?.name, steamClient?._logOnDetails?.account_name].filter(Boolean).join(" - ")
|
150
184
|
}
|
151
185
|
|
186
|
+
function log(...msg) {
|
187
|
+
console.log(`[${getAccountInfoName()}]`, ...msg)
|
188
|
+
}
|
189
|
+
|
152
190
|
async function getPersonas(steamIDs) {
|
153
191
|
steamIDs = steamIDs.map(steamID => steamID instanceof SteamID ? steamID.getSteamID64() : steamID)
|
154
192
|
const notCachesteamIDs = steamIDs.filter(id => !PersonasCache.some(p => p.id == id))
|
@@ -188,13 +226,12 @@ function SteamClient({
|
|
188
226
|
return cachedPersonas
|
189
227
|
}
|
190
228
|
|
191
|
-
|
229
|
+
function sleep(ms) {
|
192
230
|
return new Promise(resolve => {
|
193
231
|
setTimeout(resolve, ms)
|
194
232
|
})
|
195
233
|
}
|
196
234
|
|
197
|
-
const partySearchCallback = []
|
198
235
|
|
199
236
|
/**
|
200
237
|
* Get a list of lobbies (* = Unsure description could be wrong)
|
@@ -222,33 +259,26 @@ function SteamClient({
|
|
222
259
|
launcher: 0,
|
223
260
|
game_type: game_type === 'Competitive' ? 8 : 10
|
224
261
|
}))
|
225
|
-
|
226
|
-
setTimeout(resolve, timeout)
|
262
|
+
pushGCCallback('partySearch', resolve, timeout)
|
227
263
|
})
|
228
264
|
}
|
229
265
|
|
230
266
|
async function sendHello() {
|
231
|
-
console.log('sendHello', getAccountInfoName())
|
232
267
|
steamClient.sendToGC(appid, Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_MatchmakingClient2GCHello, {}, Buffer.alloc(0))
|
233
268
|
steamClient.sendToGC(appid, Protos.csgo.EGCBaseClientMsg.k_EMsgGCClientHello, {}, Buffer.alloc(0))
|
234
|
-
console.log('sendHello done', getAccountInfoName())
|
235
269
|
}
|
236
270
|
|
237
|
-
const requestCoPlaysCallback = []
|
238
|
-
|
239
271
|
async function requestCoPlays() {
|
240
|
-
console.log('sendMessageAccount_RequestCoPlays')
|
241
272
|
return new Promise(resolve => {
|
242
273
|
steamClient.sendToGC(appid, Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Account_RequestCoPlays, {}, Buffer.alloc(0))
|
243
|
-
|
244
|
-
setTimeout(resolve, 10000)
|
274
|
+
pushGCCallback('RequestCoPlays', resolve, 30000)
|
245
275
|
})
|
246
276
|
}
|
247
277
|
|
248
278
|
|
249
279
|
function bindEvent() {
|
250
280
|
steamClient.on('disconnected', async (eresult, msg) => {
|
251
|
-
|
281
|
+
log('disconnected', eresult, msg)
|
252
282
|
doClearIntervals()
|
253
283
|
})
|
254
284
|
steamClient.on('error', async (e) => {
|
@@ -271,7 +301,7 @@ function SteamClient({
|
|
271
301
|
errorStr = `Unknown: ${e.eresult}`
|
272
302
|
break
|
273
303
|
}
|
274
|
-
|
304
|
+
log('error', e?.message)
|
275
305
|
doClearIntervals()
|
276
306
|
})
|
277
307
|
|
@@ -285,12 +315,12 @@ function SteamClient({
|
|
285
315
|
const key = getECsgoGCMsgKey(msgType)
|
286
316
|
switch (msgType) {
|
287
317
|
case Protos.csgo.EMsg.k_EMsgClientChatInvite: {
|
288
|
-
|
318
|
+
log(payload)
|
289
319
|
break
|
290
320
|
}
|
291
321
|
case Protos.csgo.ECsgoGCMsg.k_EMsgClientMMSJoinLobbyResponse: {
|
292
322
|
let msg = protoDecode(Protos.csgo.CMsgClientMMSJoinLobbyResponse, payload)
|
293
|
-
|
323
|
+
log(msg)
|
294
324
|
break
|
295
325
|
}
|
296
326
|
case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Party_Invite: {
|
@@ -299,16 +329,16 @@ function SteamClient({
|
|
299
329
|
const personas = await getPersonas([sid64]);
|
300
330
|
const player_name = personas.find(p => p.id == sid64)?.player_name
|
301
331
|
if (player_name === undefined) {
|
302
|
-
|
332
|
+
log(sid64, personas);
|
303
333
|
}
|
304
|
-
|
334
|
+
log(player_name, `https://steamcommunity.com/profiles/${sid64}`);
|
305
335
|
// joinLobby(msg.lobbyid, msg.accountid)
|
306
336
|
break
|
307
337
|
}
|
308
338
|
case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Account_RequestCoPlays: {
|
309
339
|
const msg = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_Account_RequestCoPlays, payload);
|
310
340
|
const personas = msg.players.map(p => SteamID.fromIndividualAccountID(p.accountid));
|
311
|
-
|
341
|
+
callGCCallback('RequestCoPlays', personas)
|
312
342
|
break
|
313
343
|
}
|
314
344
|
case Protos.csgo.EGCBaseClientMsg.k_EMsgGCClientWelcome: {
|
@@ -331,7 +361,7 @@ function SteamClient({
|
|
331
361
|
break
|
332
362
|
}
|
333
363
|
default: {
|
334
|
-
|
364
|
+
log("cache_object.type_id", cache_object.type_id);
|
335
365
|
}
|
336
366
|
}
|
337
367
|
}
|
@@ -488,11 +518,7 @@ function SteamClient({
|
|
488
518
|
}
|
489
519
|
}
|
490
520
|
|
491
|
-
|
492
|
-
let _partySearchCallback = null
|
493
|
-
while ((_partySearchCallback = partySearchCallback.shift())) {
|
494
|
-
_partySearchCallback?.(players)
|
495
|
-
}
|
521
|
+
callGCCallback('partySearch', players)
|
496
522
|
break
|
497
523
|
}
|
498
524
|
case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_PlayersProfile: {
|
@@ -535,13 +561,11 @@ function SteamClient({
|
|
535
561
|
}]
|
536
562
|
|
537
563
|
const accountid = data?.[0]?.account_id
|
538
|
-
|
539
|
-
delete getPlayersProfileCallback[accountid]
|
540
|
-
cb?.(data?.[0])
|
564
|
+
callGCCallback('PlayersProfile' + accountid, data?.[0])
|
541
565
|
break
|
542
566
|
}
|
543
567
|
default:
|
544
|
-
|
568
|
+
log(`receivedFromGC ${msgType} ${key}`)
|
545
569
|
const results = Object.values(Protos.csgo).map(function (p) {
|
546
570
|
try {
|
547
571
|
return protoDecode(p, payload)
|
@@ -550,7 +574,7 @@ function SteamClient({
|
|
550
574
|
}).filter(function (result) {
|
551
575
|
return result && Object.keys(result).length
|
552
576
|
})
|
553
|
-
|
577
|
+
log(key, results)
|
554
578
|
}
|
555
579
|
})
|
556
580
|
|
@@ -598,7 +622,7 @@ function SteamClient({
|
|
598
622
|
await sleep(1000)
|
599
623
|
}
|
600
624
|
|
601
|
-
|
625
|
+
log(`app ${appid} launched`)
|
602
626
|
await sendHello()
|
603
627
|
|
604
628
|
callEvent(events.loggedOn)
|
@@ -608,14 +632,14 @@ function SteamClient({
|
|
608
632
|
const sid64 = user.getSteamID64();
|
609
633
|
const personas = await getPersonas([sid64]);
|
610
634
|
const player_name = personas[sid64]?.player_name || ''
|
611
|
-
|
635
|
+
log('friendMessage', sid64, message);
|
612
636
|
|
613
637
|
if ([`Inited you to play a game!`, `Đã mời bạn chơi một trò chơi!`].includes(message)) {
|
614
638
|
callEvent(events.friendMessage, {
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
639
|
+
player_name,
|
640
|
+
message,
|
641
|
+
invite: true,
|
642
|
+
sid64,
|
619
643
|
})
|
620
644
|
} else {
|
621
645
|
callEvent(events.friendMessage, {
|
@@ -638,28 +662,25 @@ function SteamClient({
|
|
638
662
|
}
|
639
663
|
|
640
664
|
|
641
|
-
const getPlayersProfileCallback = {};
|
642
|
-
|
643
665
|
function getPlayersProfile(accountid) {
|
644
666
|
steamClient.sendToGC(730, Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_ClientRequestPlayersProfile, {}, protoEncode(Protos.csgo.CMsgGCCStrike15_v2_ClientRequestPlayersProfile, {
|
645
667
|
account_id: accountid, // account_id: new SteamID('76561199184696945').accountid,
|
646
668
|
request_level: 32
|
647
669
|
}))
|
648
670
|
return new Promise(resolve => {
|
649
|
-
|
650
|
-
setTimeout(resolve, 30000)
|
671
|
+
pushGCCallback('PlayersProfile' + accountid, resolve, 30000)
|
651
672
|
})
|
652
673
|
}
|
653
674
|
|
654
675
|
async function checkPlayerPrimeStatus(accountid) {
|
655
676
|
const profile = await getPlayersProfile(accountid)
|
656
|
-
if(!profile) return false
|
677
|
+
if (!profile) return false
|
657
678
|
|
658
|
-
if(profile.ranking?.account_id){
|
679
|
+
if (profile.ranking?.account_id) {
|
659
680
|
return true
|
660
681
|
}
|
661
682
|
|
662
|
-
if(profile.player_level || profile.player_cur_xp){
|
683
|
+
if (profile.player_level || profile.player_cur_xp) {
|
663
684
|
return true
|
664
685
|
}
|
665
686
|
return false
|
@@ -709,7 +730,7 @@ function SteamClient({
|
|
709
730
|
return cookie
|
710
731
|
} else {
|
711
732
|
if (tryNewCookie) {
|
712
|
-
|
733
|
+
log('You are not logged in', cookie)
|
713
734
|
return null
|
714
735
|
} else {
|
715
736
|
return await loginWithCookie(await getNewCookie(cookie), true)
|
@@ -719,13 +740,13 @@ function SteamClient({
|
|
719
740
|
|
720
741
|
async function login() {
|
721
742
|
if (cookie) {
|
722
|
-
|
743
|
+
log('login with cookie')
|
723
744
|
const newCookie = await loginWithCookie(cookie)
|
724
745
|
if (newCookie) {
|
725
746
|
cookie = newCookie
|
726
747
|
}
|
727
748
|
} else if (username && password) {
|
728
|
-
|
749
|
+
log(`login with username ${username}`)
|
729
750
|
steamClient.logOn({
|
730
751
|
accountName: username, password: password, rememberPassword: true, machineName: 'Natri',
|
731
752
|
})
|
@@ -739,14 +760,16 @@ function SteamClient({
|
|
739
760
|
|
740
761
|
|
741
762
|
function partyRegister() {
|
742
|
-
_partyRegister(prime)
|
743
763
|
if (prime === null) {
|
744
764
|
_partyRegister(true)
|
765
|
+
_partyRegister(false)
|
766
|
+
} else {
|
767
|
+
_partyRegister(prime)
|
745
768
|
}
|
746
769
|
}
|
747
770
|
|
748
771
|
function _partyRegister(prime) {
|
749
|
-
|
772
|
+
log("partyRegister", prime);
|
750
773
|
steamClient.sendToGC(730, Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Party_Register, {}, protoEncode(Protos.csgo.CMsgGCCStrike15_v2_Party_Register, {
|
751
774
|
// id : 0,
|
752
775
|
ver: CSGO_VER, apr: prime ? 1 : 0,//prime
|
@@ -773,14 +796,16 @@ function SteamClient({
|
|
773
796
|
}
|
774
797
|
}
|
775
798
|
|
776
|
-
async function autoRequestFreeLicense(
|
799
|
+
async function autoRequestFreeLicense(shouldLog = false, max = 10) {
|
777
800
|
const steamUtils = new SteamUtils(getCookie())
|
778
801
|
|
779
|
-
const
|
802
|
+
const ownedApps = (await steamUtils.getDynamicStoreUserData())?.rgOwnedApps || []
|
803
|
+
const ownedAppsCount = shouldLog ? (ownedApps?.length || 0) : 0
|
780
804
|
let recommendedApps = Math.random() > 0.5 ? _.shuffle((await steamUtils.getDynamicStoreUserData())?.rgRecommendedApps || []) : []
|
781
805
|
if (!recommendedApps?.length) {
|
782
806
|
recommendedApps = (await axios.request({url: 'https://raw.githubusercontent.com/5x/easy-steam-free-packages/master/src/script/packages_db.json'}))?.data?.packages || []
|
783
807
|
}
|
808
|
+
_.remove(recommendedApps, app => ownedApps.includes(app))
|
784
809
|
|
785
810
|
if (max) {
|
786
811
|
recommendedApps.length = Math.min(recommendedApps.length, max)
|
@@ -795,16 +820,16 @@ function SteamClient({
|
|
795
820
|
try {
|
796
821
|
await steamClient.requestFreeLicense(recommendedApp)
|
797
822
|
} catch (e) {
|
798
|
-
|
823
|
+
log(e);
|
799
824
|
}
|
800
825
|
}
|
801
826
|
await sleep(2000)
|
802
827
|
}
|
803
|
-
if (
|
828
|
+
if (shouldLog) {
|
804
829
|
await sleep(20000)
|
805
830
|
const ownedAppsCount2 = (await steamUtils.getDynamicStoreUserData())?.rgOwnedApps?.length || 0
|
806
831
|
const increaseNumber = ownedAppsCount2 - ownedAppsCount;
|
807
|
-
|
832
|
+
log(`OwnedApps length ${ownedAppsCount2}, increase ${increaseNumber}`)
|
808
833
|
}
|
809
834
|
}
|
810
835
|
|
@@ -822,6 +847,22 @@ function SteamClient({
|
|
822
847
|
steamClient.setPersona(SteamUser.EPersonaState.LookingToPlay)
|
823
848
|
}
|
824
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
|
+
|
825
866
|
return {
|
826
867
|
init,
|
827
868
|
partySearch,
|
@@ -853,12 +894,7 @@ function SteamClient({
|
|
853
894
|
playCSGO,
|
854
895
|
doSetInterval,
|
855
896
|
doClearIntervals,
|
856
|
-
|
857
|
-
steamClient.gamesPlayed(apps);
|
858
|
-
await sleep(2000)
|
859
|
-
steamClient.setPersona(SteamUser.EPersonaState.LookingToPlay)
|
860
|
-
sendHello()
|
861
|
-
},
|
897
|
+
gamesPlayed,
|
862
898
|
sendHello,
|
863
899
|
checkPlayerPrimeStatus,
|
864
900
|
}
|
package/package.json
CHANGED
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
|
+
}
|