steamutils 1.0.3 → 1.0.5

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 ADDED
@@ -0,0 +1,539 @@
1
+ import SteamUser 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 from "./helpers/protos.js";
9
+ import {fileURLToPath} from "url";
10
+ import path from "path";
11
+
12
+ const __filename = fileURLToPath(import.meta.url);
13
+ const __dirname = path.dirname(__filename);
14
+
15
+ const Protos = helpers([{
16
+ name: 'csgo',
17
+ protos: fs.readdirSync(__dirname + '/protos/').filter(s => s.endsWith('.proto')).map(s => __dirname + '/protos/' + s)
18
+ }])
19
+
20
+ export const RANKS = {
21
+ 0: 'Unranked',
22
+ 1: 'Silver I',
23
+ 2: 'Silver II',
24
+ 3: 'Silver III',
25
+ 4: 'Silver IV',
26
+ 5: 'Silver Elite',
27
+ 6: 'Silver Elite Master',
28
+ 7: 'Gold Nova I',
29
+ 8: 'Gold Nova II',
30
+ 9: 'Gold Nova III',
31
+ 10: 'Gold Nova Master',
32
+ 11: 'Master Guardian I',
33
+ 12: 'Master Guardian II',
34
+ 13: 'Master Guardian Elite',
35
+ 14: 'Distinguished Master Guardian',
36
+ 15: 'Legendary Eagle',
37
+ 16: 'Legendary Eagle Master',
38
+ 17: 'Supreme Master First Class',
39
+ 18: 'The Global Elite'
40
+ }
41
+ export const LOCS = {
42
+ 20054: 'VN',
43
+ 23115: 'KZ',
44
+ 20041: 'IN',
45
+ 20035: 'CN',
46
+ 17474: 'BD',
47
+ 17481: 'ID',
48
+ 22861: 'MY',
49
+ 18516: 'TH',
50
+ 22356: 'TW',
51
+ 21067: 'KR',
52
+ 19272: 'HK',
53
+ 18512: 'PH',
54
+ 21842: 'RU',
55
+ 16716: 'LA',
56
+ 20558: 'NP',
57
+ 18259: 'SG',
58
+ 19789: 'MM',
59
+ 20045: 'MN',
60
+ 18251: 'KG',
61
+ 18507: 'KH',
62
+ 22605: 'MX',
63
+ 19280: 'PK',
64
+ 20301: 'HK/MO',//hongkong or macau
65
+ 21333: 'Unknown',
66
+ 21825: 'AU',
67
+ }
68
+
69
+
70
+ const appid = 730
71
+ let CSGO_VER = null
72
+ GetCurrentVersion(appid).then(function (ver) {
73
+ CSGO_VER = ver
74
+ })
75
+
76
+ async function GetCurrentVersion(appid) {
77
+ const result = await axios.request({
78
+ url: 'https://api.steampowered.com/ISteamApps/UpToDateCheck/v1/?format=json&appid=' + appid + '&version=0'
79
+ })
80
+ return result.data.response.required_version
81
+ }
82
+
83
+ function SteamClient({
84
+ username,
85
+ password,
86
+ cookie,
87
+ }) {
88
+ const steamClient = new SteamUser()
89
+ let prime = false
90
+ let gamename = null;
91
+
92
+ const events = {
93
+ loggedOn: []
94
+ }
95
+
96
+ const personasCache = []
97
+
98
+ async function getPersonas(steamIDs) {
99
+ const notCachesteamIDs = steamIDs.filter(id => !personasCache.some(p => p.id == id))
100
+ const cachedPersonas = personasCache.filter(p => steamIDs.includes(p.id))
101
+
102
+ if (notCachesteamIDs.length) {
103
+ let personas = null
104
+ try {
105
+ personas = (await steamClient.getPersonas(steamIDs))?.personas
106
+ } catch (e) {
107
+ }
108
+ if (!personas) {
109
+ try {
110
+ personas = (await steamClient.getPersonas(steamIDs))?.personas
111
+ } catch (e) {
112
+ }
113
+ }
114
+ if (!personas) {
115
+ return {}
116
+ } else {
117
+ for (let sid64 in personas) {
118
+ personas[sid64].avatar_hash = Buffer.from(personas[sid64].avatar_hash).toString("hex")
119
+ personasCache.push(personas[sid64])
120
+ cachedPersonas.push(personas[sid64])
121
+ }
122
+ }
123
+ }
124
+
125
+ while (personasCache.length > 500) {
126
+ personasCache.shift()
127
+ }
128
+ return cachedPersonas
129
+ }
130
+
131
+ const sleep = (ms) => {
132
+ return new Promise(resolve => {
133
+ setTimeout(resolve, ms)
134
+ })
135
+ }
136
+
137
+ const partySearchCallback = []
138
+
139
+ /**
140
+ * Get a list of lobbies (* = Unsure description could be wrong)
141
+ * @param {Number} ver Game version we are searching for
142
+ * @param {Boolean} apr Prime or not*
143
+ * @param {Number} ark Rank multiplied by 10*
144
+ * @param {Array.<Number>} grps *
145
+ * @param {Number} launcher If we are using the China CSGO launcher or not*
146
+ * @param {Number} game_type Game type, 8 Competitive, 10 Wingman
147
+ * @returns {Promise.<Object>}
148
+ */
149
+ async function partySearch({
150
+ prime = false, game_type = 'Competitive', rank = 'Silver Elite',
151
+ }) {
152
+
153
+ return new Promise(resolve => {
154
+ steamClient.sendToGC(appid, Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Party_Search, {}, protoEncode(Protos.csgo.CMsgGCCStrike15_v2_Party_Search, {
155
+ ver: CSGO_VER,
156
+ apr: prime ? 1 : 0,
157
+ ark: Object.keys(RANKS).find(k => RANKS[k] === rank) * 10,
158
+ grps: [],
159
+ launcher: 0,
160
+ game_type: game_type === 'Competitive' ? 8 : 10
161
+ }))
162
+ partySearchCallback.push(resolve)
163
+ setTimeout(resolve, 10000)
164
+ })
165
+ }
166
+
167
+ async function sendHello() {
168
+ console.log('sendHello')
169
+ steamClient.sendToGC(appid, Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_MatchmakingClient2GCHello, {}, Buffer.alloc(0))
170
+ steamClient.sendToGC(appid, Protos.csgo.EGCBaseClientMsg.k_EMsgGCClientHello, {}, Buffer.alloc(0))
171
+ console.log('sendHello done')
172
+ }
173
+
174
+ const requestCoPlaysCallback = []
175
+
176
+ async function requestCoPlays() {
177
+ console.log('sendMessageAccount_RequestCoPlays')
178
+ return new Promise(resolve => {
179
+ steamClient.sendToGC(appid, Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Account_RequestCoPlays, {}, Buffer.alloc(0))
180
+ requestCoPlaysCallback.push(resolve)
181
+ setTimeout(resolve, 10000)
182
+ })
183
+ }
184
+
185
+
186
+ function bindEvent() {
187
+ steamClient.on('disconnected', async (eresult, msg) => {
188
+ console.log('disconnected')
189
+ })
190
+ steamClient.on('error', async (e) => {
191
+ let errorStr = ``
192
+ switch (e.eresult) {
193
+ case 5:
194
+ errorStr = `Invalid Password`
195
+ break
196
+ case 6:
197
+ case 34:
198
+ errorStr = `Logged In Elsewhere`
199
+ break
200
+ case 84:
201
+ errorStr = `Rate Limit Exceeded`
202
+ break
203
+ case 65:
204
+ errorStr = `steam guard is invalid`
205
+ break
206
+ default:
207
+ errorStr = `Unknown: ${e.eresult}`
208
+ break
209
+ }
210
+ console.log('error', e?.message)
211
+ })
212
+
213
+ steamClient.on('webSession', (sessionID, cookies) => {
214
+ // console.log('webSession', sessionID, cookies);
215
+ })
216
+
217
+ steamClient.on('receivedFromGC', async (appid, msgType, payload) => {
218
+ const key = getECsgoGCMsgKey(msgType)
219
+ switch (msgType) {
220
+ case Protos.csgo.EMsg.k_EMsgClientChatInvite: {
221
+ console.log(payload)
222
+ break
223
+ }
224
+ case Protos.csgo.ECsgoGCMsg.k_EMsgClientMMSJoinLobbyResponse: {
225
+ let msg = protoDecode(Protos.csgo.CMsgClientMMSJoinLobbyResponse, payload)
226
+ console.log(msg)
227
+ break
228
+ }
229
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Party_Invite: {
230
+ let msg = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_Party_Invite, payload)
231
+ let sid = SteamID.fromIndividualAccountID(msg.accountid);
232
+ // console.log(msg)
233
+ let personas = await getPersonas([sid])
234
+ console.log(personas?.[sid]?.player_name, `https://steamcommunity.com/profiles/${sid.getSteamID64()}`);
235
+ // joinLobby(msg.lobbyid, msg.accountid)
236
+ break
237
+ }
238
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Account_RequestCoPlays: {
239
+ const msg = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_Account_RequestCoPlays, payload);
240
+ const personas = msg.players.map(p => SteamID.fromIndividualAccountID(p.accountid));
241
+ requestCoPlaysCallback?.shift()?.(personas)
242
+ break
243
+ }
244
+ case Protos.csgo.EGCBaseClientMsg.k_EMsgGCClientWelcome: {
245
+ const CMsgClientWelcome = protoDecode(Protos.csgo.CMsgClientWelcome, payload);
246
+ for (const outofdate_cache of CMsgClientWelcome.outofdate_subscribed_caches) {
247
+ for (const cache_object of outofdate_cache.objects) {
248
+ if (cache_object.object_data.length === 0) {
249
+ continue
250
+ }
251
+ switch (cache_object.type_id) {
252
+ case 7: {
253
+ let CSOEconGameAccountClient = protoDecode(Protos.csgo.CSOEconGameAccountClient, cache_object.object_data[0])
254
+ if ((CSOEconGameAccountClient.bonus_xp_usedflags & 16) != 0) { // EXPBonusFlag::PrestigeEarned
255
+ prime = true
256
+ }
257
+ if (CSOEconGameAccountClient.elevated_state == 5) { // bought prime
258
+ prime = true
259
+ }
260
+ break
261
+ }
262
+ }
263
+ }
264
+ }
265
+ break
266
+ }
267
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_MatchmakingGC2ClientUpdate: {
268
+ const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_MatchmakingGC2ClientUpdate, payload)
269
+ break
270
+ }
271
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_GC2ClientGlobalStats: {
272
+ const result = protoDecode(Protos.csgo.CMsgClientUGSGetGlobalStatsResponse, payload)
273
+ break
274
+ }
275
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_GC2ClientTextMsg: {
276
+ const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_GC2ClientTextMsg, payload)
277
+ break
278
+ }
279
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_MatchmakingGC2ClientHello: {
280
+ const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_MatchmakingGC2ClientHello, payload)
281
+ break
282
+ }
283
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_ClientReportResponse: {
284
+ const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_ClientReportResponse, payload)
285
+ break
286
+ }
287
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_ClientCommendPlayerQueryResponse: {
288
+ const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_ClientCommendPlayer, payload)
289
+ break
290
+ }
291
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_PlayerOverwatchCaseAssignment: {
292
+ const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_PlayerOverwatchCaseAssignment, payload)
293
+ break
294
+ }
295
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_MatchList: {
296
+ const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_MatchList, payload)
297
+ break
298
+ }
299
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_GetEventFavorites_Response: {
300
+ const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_GetEventFavorites_Response, payload)
301
+ break
302
+ }
303
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_StartAgreementSessionInGame: {
304
+
305
+ break
306
+ }
307
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_ClientDeepStats: {
308
+ const result = protoDecode(Protos.csgo.CMsgGCCStrike15_ClientDeepStats, payload)
309
+ break
310
+ }
311
+ case Protos.csgo.EGCBaseClientMsg.k_EMsgGCClientConnectionStatus: {
312
+ const result = protoDecode(Protos.csgo.CMsgConnectionStatus, payload)
313
+ break
314
+ }
315
+ case Protos.csgo.EGCItemMsg.k_EMsgGCStoreGetUserDataResponse: {
316
+ const result = protoDecode(Protos.csgo.CMsgStoreGetUserDataResponse, payload)
317
+ break
318
+ }
319
+ case Protos.csgo.EGCItemMsg.k_EMsgGCStorePurchaseFinalizeResponse: {
320
+ const result = protoDecode(Protos.csgo.CMsgGCStorePurchaseFinalizeResponse, payload)
321
+ break
322
+ }
323
+ case Protos.csgo.EGCItemMsg.k_EMsgGCStorePurchaseCancelResponse: {
324
+ const result = protoDecode(Protos.csgo.CMsgGCStorePurchaseCancelResponse, payload)
325
+ break
326
+ }
327
+ case Protos.csgo.EGCItemMsg.k_EMsgGCStorePurchaseInitResponse: {
328
+ const result = protoDecode(Protos.csgo.CMsgGCStorePurchaseInitResponse, payload)
329
+ break
330
+ }
331
+ case Protos.csgo.EMsg.k_EMsgClientMMSCreateLobbyResponse: {
332
+ const result = protoDecode(Protos.csgo.CMsgClientMMSCreateLobbyResponse, payload)
333
+ break
334
+ }
335
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_ClientGCRankUpdate: {
336
+ const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_ClientGCRankUpdate, payload)
337
+ break
338
+ }
339
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Party_Search: {
340
+ const result = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_Party_SearchResults, payload)
341
+ const entries = _.uniqBy(result.entries, 'id')
342
+
343
+ const players = []
344
+
345
+ const steamIDs = entries
346
+ .map(p => SteamID.fromIndividualAccountID(p.id).getSteamID64())
347
+ const personas = await getPersonas(steamIDs)
348
+
349
+ for (const player of entries) {
350
+ try {
351
+ const prime = player.apr === 1 ? 'PRIME' : 'NON-PRIME'
352
+ const loc = LOCS[player.loc] || player.loc
353
+ const steamID = SteamID.fromIndividualAccountID(player.id).getSteamID64()
354
+ const persona = personas.find(p => p.id == player.id)
355
+ const player_name = persona.player_name
356
+ const friendCode = FriendCode.encode(steamID)
357
+
358
+ if ((LOCS[player.loc] == 'VN' || !LOCS[player.loc])) {
359
+ players.push({
360
+ prime,
361
+ player_name: player_name,
362
+ rank: RANKS[player.ark],
363
+ loc: loc,
364
+ steamID,
365
+ friendCode,
366
+ avatar_hash: persona.avatar_hash,
367
+ })
368
+ }
369
+ } catch (e) {
370
+ }
371
+ }
372
+
373
+ partySearchCallback.shift()?.(players)
374
+ break
375
+ }
376
+ case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_PlayersProfile: {
377
+ let data = protoDecode(Protos.csgo.CMsgGCCStrike15_v2_PlayersProfile, payload)?.account_profiles
378
+ const dataExample = [{
379
+ my_current_event_teams: [],
380
+ my_current_event_stages: [],
381
+ rankings: [{
382
+ account_id: 1225887169, rank_id: 0, wins: 6, rank_change: 0, rank_type_id: 7, tv_control: 0
383
+ }, {
384
+ account_id: 1225887169, rank_id: 0, wins: 0, rank_change: 0, rank_type_id: 10, tv_control: 0
385
+ }],
386
+ account_id: 1225887169,
387
+ ongoingmatch: null,
388
+ global_stats: null,
389
+ penalty_seconds: 0,
390
+ penalty_reason: 0,
391
+ vac_banned: 0,
392
+ ranking: {
393
+ account_id: 1225887169,
394
+ rank_id: 8,
395
+ wins: 469,
396
+ rank_change: 0,
397
+ rank_type_id: 6,
398
+ tv_control: 0
399
+ },
400
+ commendation: {
401
+ cmd_friendly: 51, cmd_teaching: 40, cmd_leader: 40
402
+ },
403
+ medals: {
404
+ display_items_defidx: [4819, 4737], featured_display_item_defidx: 4819
405
+ },
406
+ my_current_event: null,
407
+ my_current_team: null,
408
+ survey_vote: 0,
409
+ activity: null,
410
+ player_level: 32,
411
+ player_cur_xp: 327682846,
412
+ player_xp_bonus_flags: 0
413
+ }]
414
+ console.log(data);
415
+ break
416
+ }
417
+ default:
418
+ console.log(`receivedFromGC ${msgType} ${key}`)
419
+ const results = Object.values(Protos.csgo).map(function (p) {
420
+ try {
421
+ return protoDecode(p, payload)
422
+ } catch (e) {
423
+ }
424
+ }).filter(function (result) {
425
+ return result && Object.keys(result).length
426
+ })
427
+ console.log(key, results)
428
+ }
429
+ })
430
+
431
+ function getECsgoGCMsgKey(_key) {
432
+ for (let key in Protos.csgo.ECsgoGCMsg) {
433
+ if (Protos.csgo.ECsgoGCMsg[key] == _key) {
434
+ return key
435
+ }
436
+ }
437
+ for (let key in Protos.csgo.EGCBaseClientMsg) {
438
+ if (Protos.csgo.EGCBaseClientMsg[key] == _key) {
439
+ return key
440
+ }
441
+ }
442
+ for (let key in Protos.csgo.EMsg) {
443
+ if (Protos.csgo.EMsg[key] == _key) {
444
+ return key
445
+ }
446
+ }
447
+ for (let key in Protos.csgo.EGCItemMsg) {
448
+ if (Protos.csgo.EGCItemMsg[key] == _key) {
449
+ return key
450
+ }
451
+ }
452
+ }
453
+
454
+ steamClient.on('loggedOn', async (loggedOnResponse) => {
455
+ await steamClient.requestFreeLicense(appid)
456
+ await sleep(5000)
457
+
458
+ if (gamename) {
459
+ steamClient.gamesPlayed([{
460
+ game_id: appid, game_extra_info: gamename
461
+ }], true);
462
+ } else {
463
+ steamClient.gamesPlayed(appid, true)
464
+ }
465
+
466
+ steamClient.setPersona(SteamUser.EPersonaState.LookingToPlay)
467
+
468
+ while (!steamClient.accountInfo) {
469
+ await sleep(500)
470
+ }
471
+
472
+ console.log(`app ${appid} launched on account ${steamClient.accountInfo.name}`)
473
+ await sendHello()
474
+
475
+ events.loggedOn.forEach(e => e?.invoke?.())
476
+ })
477
+ }
478
+
479
+ function getPlayersProfile(accountid) {
480
+ steamClient.sendToGC(730, Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_ClientRequestPlayersProfile, {}, protoEncode(Protos.csgo.CMsgGCCStrike15_v2_ClientRequestPlayersProfile, {
481
+ account_id: accountid, // account_id: new SteamID('76561199184696945').accountid,
482
+ request_level: 32
483
+ }))
484
+ }
485
+
486
+ async function login() {
487
+ if (cookie) {
488
+ console.log('login with cookie')
489
+ const result = (await axios.request({
490
+ url: 'https://steamcommunity.com/chat/clientjstoken', headers: {
491
+ cookie,
492
+ }
493
+ }))?.data
494
+ if (result) {
495
+ Object.assign(result, {
496
+ steamID: new SteamID(result.steamid), accountName: result.account_name, webLogonToken: result.token
497
+ })
498
+ steamClient.logOn(result)
499
+ }
500
+ } else if (username && password) {
501
+ console.log(`login with username ${username}`)
502
+ steamClient.logOn({
503
+ accountName: username, password: password, rememberPassword: true, machineName: 'Natri',
504
+ })
505
+ }
506
+ }
507
+
508
+ function init() {
509
+ bindEvent()
510
+ login()
511
+ }
512
+
513
+
514
+ function partyRegister() {
515
+ console.log("partyRegister", steamClient?.accountInfo?.name || username, prime);
516
+ steamClient.sendToGC(730, Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_Party_Register, {}, protoEncode(Protos.csgo.CMsgGCCStrike15_v2_Party_Register, {
517
+ // id : 0,
518
+ ver: CSGO_VER, apr: prime ? 1 : 0,//prime
519
+ ark: prime ? 180 : 0, grps: [], launcher: 0, game_type: 8
520
+ }))
521
+ }
522
+
523
+ return {
524
+ init, partySearch, partyRegister, requestCoPlays, getPersonas, getUsername: function () {
525
+ return username
526
+ }, onEvent: function (name, cb) {
527
+ if (!events[name]) {
528
+ events[name] = []
529
+ }
530
+ events[name].push(cb)
531
+ }, setPersona: function (state, name) {
532
+ steamClient.setPersona(state, name)
533
+ }, setGameName: function (name) {
534
+ gamename = name
535
+ },
536
+ }
537
+ }
538
+
539
+ export default SteamClient
@@ -0,0 +1,33 @@
1
+ import Protobuf from "protobufjs";
2
+ import fs from "fs";
3
+ import path from "path";
4
+
5
+ export default function Protos(protos, ignoreErrors = true) {
6
+ const protobufs = {};
7
+
8
+ for (let proto of protos) {
9
+ let root = new Protobuf.Root();
10
+ let files = Array.isArray(proto.protos) ? proto.protos : fs.readdirSync(proto.protos).map(file => path.join(proto.protos, file));
11
+
12
+ for (let file of files) {
13
+ if (!file.endsWith(".proto") || !fs.existsSync(file)) {
14
+ continue;
15
+ }
16
+
17
+ try {
18
+ root = root.loadSync(file, {
19
+ keepCase: true
20
+ });
21
+ } catch (err) {
22
+ if (!ignoreErrors) {
23
+ throw err;
24
+ }
25
+ }
26
+ ;
27
+ }
28
+
29
+ protobufs[proto.name] = root;
30
+ }
31
+
32
+ return protobufs;
33
+ }
@@ -0,0 +1,60 @@
1
+ export function penalty_reason_string(id) {
2
+ switch (id) {
3
+ case 0:
4
+ return 0;
5
+ case 1:
6
+ return "Kicked";
7
+ case 2:
8
+ return "TK Limit";
9
+ case 3:
10
+ return "TK Spawn";
11
+ case 4:
12
+ return "Disconnected Too Long";
13
+ case 5:
14
+ return "Abandon";
15
+ case 6:
16
+ return "TD Limit";
17
+ case 7:
18
+ return "TD Spawn";
19
+ case 8:
20
+ case 14:
21
+ return "Untrusted";
22
+ case 9:
23
+ return "Kicked Too Much";
24
+ case 10:
25
+ return "Overwatch (Cheat)";
26
+ case 11:
27
+ return "Overwatch (Grief)";
28
+ case 16:
29
+ return "Failed To Connect";
30
+ case 17:
31
+ return "Kick Abuse";
32
+ case 18:
33
+ case 19:
34
+ case 20:
35
+ return "Rank Calibration";
36
+ case 21:
37
+ return "Reports (Grief)"
38
+ default:
39
+ return `Unknown(${id})`;
40
+ }
41
+ }
42
+
43
+ export function penalty_reason_permanent(id) {
44
+ switch (id) {
45
+ case 8:
46
+ case 14:
47
+ case 10:
48
+ return true;
49
+ default:
50
+ return false;
51
+ }
52
+ }
53
+
54
+ export function protoDecode(proto, obj) {
55
+ return proto.toObject(proto.decode(obj), {defaults: true});
56
+ }
57
+
58
+ export function protoEncode(proto, obj) {
59
+ return proto.encode(proto.create(obj)).finish();
60
+ }
package/index.js CHANGED
@@ -1864,6 +1864,7 @@ class SteamUser {
1864
1864
  let result = (await this._httpRequest('chat/clientjstoken'))?.data
1865
1865
  if (!result?.steamid) {
1866
1866
  if (retry !== null && retry !== undefined && retry >= 0) {
1867
+ await sleep(2000)
1867
1868
  return await this.getClientJsToken(retry - 1)
1868
1869
  } else {
1869
1870
  return null
package/package.json CHANGED
@@ -1,13 +1,15 @@
1
1
  {
2
2
  "name": "steamutils",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "dependencies": {
5
5
  "axios": "^1.3.4",
6
6
  "cheerio": "^1.0.0-rc.12",
7
7
  "crypto-js": "^4.1.1",
8
+ "csgo-friendcode": "^3.0.3",
8
9
  "lodash": "^4.17.21",
9
10
  "moment": "^2.29.4",
10
11
  "node-bignumber": "^1.2.2",
12
+ "steam-user": "^4.28.1",
11
13
  "steamid": "^2.0.0",
12
14
  "url-parse": "^1.5.10",
13
15
  "xml-js": "^1.6.11",