steamutils 1.3.25 → 1.3.27

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
@@ -14,6 +14,7 @@ import EFriendRelationship from "steam-user/enums/EFriendRelationship.js";
14
14
  import SteamCommunity from "steamcommunity";
15
15
  import ELobbyType from "steam-user/enums/ELobbyType.js";
16
16
  import moment from "moment-timezone";
17
+ import {encode, encodeUids} from "./bufferHelpers.js";
17
18
 
18
19
  const __filename = fileURLToPath(import.meta.url);
19
20
  const __dirname = path.dirname(__filename);
@@ -344,22 +345,7 @@ function SteamClient({
344
345
  }
345
346
 
346
347
  async function gamePlay() {
347
- let ownedApps = []
348
- for (let i = 0; i < 5; i++) {
349
- ownedApps = await getUserOwnedApps()
350
- if (ownedApps?.length) {
351
- break
352
- }
353
- }
354
- if (!ownedApps?.length) {
355
- gamesPlayed(730)
356
- } else {
357
- ownedApps = ownedApps.map(({appid}) => appid)
358
- ownedApps = _.shuffle(ownedApps)
359
- ownedApps.length = Math.min(ownedApps.length, MAX_GAME_PLAY - 1)
360
- _.remove(ownedApps, app => app == 730)
361
- gamesPlayed([...ownedApps, 730])
362
- }
348
+ gamesPlayed(730)
363
349
  }
364
350
 
365
351
  async function autoGamePlay() {
@@ -425,34 +411,127 @@ function SteamClient({
425
411
 
426
412
  async function createLobby() {
427
413
  console.log("createLobby");
428
- steamClient.sendToGC(730, Protos.csgo.EMsg.k_EMsgClientMMSCreateLobby, null, protoEncode(Protos.csgo.CMsgClientMMSCreateLobby, {
429
- app_id: 730,
430
- routing_appid: 730,
431
- max_members: 10,
432
- lobby_type: ELobbyType.Public,
433
- lobby_flags: 1,
434
- cell_id: steamClient.cellID,
435
- public_ip: steamClient.logOnResult?.public_ip || {
436
- v4: steamClient.publicIP,
414
+ steamClient._send(
415
+ {
416
+ msg: Protos.csgo.EMsg.k_EMsgClientMMSCreateLobby,
417
+ proto: {
418
+ steamid: steamClient.steamID.getSteamID64(),
419
+ routing_appid: 730
420
+ }
437
421
  },
438
- persona_name_owner: steamClient.accountInfo.name,
439
- metadata: null,
440
- }))
422
+ protoEncode(Protos.csgo.CMsgClientMMSCreateLobby, {
423
+ app_id: 730,
424
+ max_members: 1,
425
+ lobby_type: 1,
426
+ lobby_flags: 1
427
+ })
428
+ );
429
+
430
+ return new Promise(resolve => {
431
+ const timeout = setTimeout(function () {
432
+ delete steamClient._handlerManager._handlers[Protos.csgo.EMsg.k_EMsgClientMMSCreateLobbyResponse];
433
+ resolve()
434
+ }, 60000)
435
+ steamClient._handlerManager.add(Protos.csgo.EMsg.k_EMsgClientMMSCreateLobbyResponse, (payload) => {
436
+ clearTimeout(timeout)
437
+ delete steamClient._handlerManager._handlers[Protos.csgo.EMsg.k_EMsgClientMMSCreateLobbyResponse];
438
+ const result = protoDecode(Protos.csgo.CMsgClientMMSCreateLobbyResponse, payload.toBuffer())
439
+ const steam_id_lobby = result.steam_id_lobby.toString();
440
+ resolve(steam_id_lobby);
441
+ });
442
+ })
443
+
444
+ // steamClient.sendToGC(730, Protos.csgo.EMsg.k_EMsgClientMMSCreateLobby, {
445
+ // steamid: steamClient.steamID,
446
+ // routing_appid: 730,
447
+ // }, protoEncode(Protos.csgo.CMsgClientMMSCreateLobby, {
448
+ // app_id: 730,
449
+ // max_members: 1,
450
+ // lobby_type: 1,
451
+ // lobby_flags: 1
452
+ // }))
453
+ }
454
+
455
+ async function updateLobby(lobbyID) {
456
+ console.log("updateLobby", lobbyID);
457
+ steamClient._send(
458
+ {
459
+ msg: Protos.csgo.EMsg.k_EMsgClientMMSSetLobbyData,
460
+ proto: {
461
+ steamid: steamClient.steamID.getSteamID64(),
462
+ routing_appid: 730
463
+ }
464
+ },
465
+ protoEncode(Protos.csgo.CMsgClientMMSSetLobbyData, {
466
+ app_id: 730,
467
+ steam_id_lobby: lobbyID,
468
+ steam_id_member: '0',
469
+ max_members: 10,
470
+ lobby_type: 1,
471
+ lobby_flags: 1,
472
+ metadata: encode({
473
+ 'game:ark': '0',
474
+ // Country/Message
475
+ 'game:loc': '',
476
+ 'game:mapgroupname': 'mg_de_mirage',
477
+ 'game:mode': 'competitive',
478
+ 'game:prime': '1',
479
+ 'game:type': 'classic',
480
+ 'members:numPlayers': '1',
481
+ 'options:action': 'custommatch',
482
+ 'options:anytypemode': '0',
483
+ 'system:access': 'private',
484
+ 'system:network': 'LIVE',
485
+ uids: [steamClient.steamID]
486
+ }, [0x00, 0x00], [0x08], {uids: encodeUids}).toBuffer()
487
+ })
488
+ );
489
+
490
+ return new Promise(resolve => {
491
+ const timeout = setTimeout(function () {
492
+ delete steamClient._handlerManager._handlers[Protos.csgo.EMsg.k_EMsgClientMMSSetLobbyDataResponse];
493
+ resolve()
494
+ }, 60000)
495
+ //ClientMMSLobbyData
496
+ steamClient._handlerManager.add(Protos.csgo.EMsg.k_EMsgClientMMSSetLobbyDataResponse, (payload) => {
497
+ clearTimeout(timeout)
498
+ delete steamClient._handlerManager._handlers[Protos.csgo.EMsg.k_EMsgClientMMSSetLobbyDataResponse];
499
+ const result = protoDecode(Protos.csgo.CMsgClientMMSSetLobbyDataResponse, payload.toBuffer())
500
+ const steam_id_lobby = result.steam_id_lobby.toString();
501
+ resolve(steam_id_lobby);
502
+ });
503
+ })
441
504
  }
442
505
 
443
506
  async function invite2Lobby(lobbyID, steamId) {
507
+ steamClient._send(
508
+ {
509
+ msg: Protos.csgo.EMsg.k_EMsgClientMMSInviteToLobby,
510
+ proto: {
511
+ steamid: steamClient.steamID.getSteamID64(),
512
+ routing_appid: 730
513
+ }
514
+ },
515
+ protoEncode(Protos.csgo.CMsgClientMMSInviteToLobby, {
516
+ app_id: 730,
517
+ steam_id_lobby: lobbyID,
518
+ steam_id_user_invited: steamId,
519
+ })
520
+ );
521
+
522
+
444
523
  const accountid = new SteamID(steamId).accountid;
445
524
  // lobbyID = new SteamID(lobbyID).accountid;
446
525
 
447
526
  // Protos.csgo.EMsg.k_EMsgGCHInviteUserToLobby
448
527
  // Protos.csgo.EMsg.k_EMsgClientMMSInviteToLobby
449
- steamClient.sendToGC(730, Protos.csgo.EMsg.k_EMsgClientMMSInviteToLobby, {}, protoEncode(Protos.csgo.CMsgClientMMSInviteToLobby, {
450
- app_id: 730,
451
- steam_id_lobby: lobbyID,
452
- steam_id_user_invited: accountid,
453
- }), function (...args) {
454
- console.log("invite2Lobby response", args)
455
- })
528
+ // steamClient.sendToGC(730, Protos.csgo.EMsg.k_EMsgClientMMSInviteToLobby, {}, protoEncode(Protos.csgo.CMsgClientMMSInviteToLobby, {
529
+ // app_id: 730,
530
+ // steam_id_lobby: lobbyID,
531
+ // steam_id_user_invited: accountid,
532
+ // }), function (...args) {
533
+ // console.log("invite2Lobby response", args)
534
+ // })
456
535
  }
457
536
 
458
537
 
@@ -861,6 +940,7 @@ function SteamClient({
861
940
  }
862
941
  case Protos.csgo.EMsg.k_EMsgClientMMSCreateLobbyResponse: {
863
942
  const result = protoDecode(Protos.csgo.CMsgClientMMSCreateLobbyResponse, payload)
943
+ console.log("k_EMsgClientMMSCreateLobbyResponse", result);
864
944
  break
865
945
  }
866
946
  case Protos.csgo.ECsgoGCMsg.k_EMsgGCCStrike15_v2_ClientGCRankUpdate: {
@@ -1141,7 +1221,11 @@ function SteamClient({
1141
1221
  callEvent(events.playingState, {playing_blocked, playing_app})
1142
1222
  },
1143
1223
  async friendRelationship(sid, relationship, previousRelationship) {
1144
- callEvent(events.friendRelationship, {steamId: sid.getSteamID64(), relationship, previousRelationship})
1224
+ callEvent(events.friendRelationship, {
1225
+ steamId: sid.getSteamID64(),
1226
+ relationship,
1227
+ previousRelationship
1228
+ })
1145
1229
  switch (relationship) {
1146
1230
  case EFriendRelationship.None: {
1147
1231
  //we got unfriended.
@@ -1781,6 +1865,7 @@ function SteamClient({
1781
1865
  partySearch,
1782
1866
  invite2Lobby,
1783
1867
  createLobby,
1868
+ updateLobby,
1784
1869
  joinLobby,
1785
1870
  partyRegister,
1786
1871
  requestCoPlays,
@@ -0,0 +1,115 @@
1
+ import ByteBuffer from 'bytebuffer';
2
+ import SteamID from 'steamid';
3
+
4
+ const Type = {
5
+ None : 0,
6
+ String : 1,
7
+ Int32 : 2,
8
+ Float32 : 3,
9
+ Pointer : 4,
10
+ WideString : 5,
11
+ Color : 6,
12
+ UInt64 : 7,
13
+ End : 8
14
+ }
15
+
16
+ // Encodes an object into a ByteBuffer
17
+ export const encode = (
18
+ _object,
19
+ prefix = [0x00, 0x00],
20
+ suffix = [],
21
+ customEncodeFields = {}
22
+ ) => {
23
+ // Create a copy of the input object to avoid modifying it
24
+ const object = { ..._object };
25
+ const buffer = new ByteBuffer();
26
+
27
+ // Write the prefix bytes to the buffer
28
+ for (let pre of prefix) {
29
+ buffer.writeByte(pre);
30
+ }
31
+
32
+ // Iterate through the object's properties and encode them
33
+ for (let item in object) {
34
+ if (object.hasOwnProperty(item) === false) {
35
+ continue;
36
+ }
37
+
38
+ // If a custom encoder function exists for the property, use it
39
+ if (typeof customEncodeFields[item] === 'function') {
40
+ object[item] = customEncodeFields[item](object[item]);
41
+ }
42
+ _encode(object[item], buffer, item);
43
+ }
44
+
45
+ // Write the suffix bytes to the buffer
46
+ for (let suf of suffix) {
47
+ buffer.writeByte(suf);
48
+ }
49
+
50
+ // Write an End marker to the buffer
51
+ buffer.writeByte(Type.End);
52
+ buffer.flip(); // Prepare the buffer for reading
53
+ return buffer;
54
+ };
55
+
56
+ // Encodes individual properties into the ByteBuffer
57
+ const _encode = (object, buffer, name) => {
58
+ if (object instanceof Buffer) {
59
+ // If the object is a Buffer
60
+ buffer.writeByte(Type.String);
61
+ buffer.writeCString(name);
62
+
63
+ // Convert the Buffer to a hexadecimal string, split into 2-character parts, and write each part as a byte
64
+ let parts = object
65
+ .toString('hex')
66
+ .toUpperCase()
67
+ .match(/.{1,2}/g);
68
+
69
+ for (let part of parts) {
70
+ buffer.writeByte(parseInt('0x' + part));
71
+ }
72
+ } else {
73
+ // If the object is not a Buffer, check its type
74
+ switch (typeof object) {
75
+ case 'object': {
76
+ buffer.writeByte(Type.None);
77
+ buffer.writeCString(name);
78
+
79
+ for (let index in object) {
80
+ _encode(object[index], buffer, index); // Recursively encode each property
81
+ }
82
+
83
+ buffer.writeByte(Type.End);
84
+ break;
85
+ }
86
+ case 'string': {
87
+ buffer.writeByte(Type.String);
88
+ buffer.writeCString(name);
89
+ buffer.writeCString(object ? object : '');
90
+ break;
91
+ }
92
+ case 'number': {
93
+ buffer.writeByte(Type.String);
94
+ buffer.writeCString(name);
95
+ buffer.writeCString(object.toString());
96
+ break;
97
+ }
98
+ }
99
+ }
100
+ };
101
+
102
+ // Encodes SteamIDs into a Buffer
103
+ export const encodeUids = (steamids) => {
104
+ const outputBuffer = [];
105
+
106
+ for (let id of steamids.map((s) => s.accountid)) {
107
+ while (id > 0x7f) {
108
+ outputBuffer.push((id | 0x80) & 0xff);
109
+ id >>= 7;
110
+ }
111
+ outputBuffer.push(id);
112
+ }
113
+ outputBuffer.push(0x00); // Null terminator
114
+ return Buffer.from(outputBuffer);
115
+ };
package/index.js CHANGED
@@ -5816,17 +5816,18 @@ class SteamUser {
5816
5816
 
5817
5817
  $('.profile_subpage_selector > a').each(function () {
5818
5818
  const text = $(this).text()
5819
- const link = $(this).attr('href')
5819
+ const link = _.trimEnd($(this).attr('href'), '/')
5820
5820
  let count = 0
5821
5821
  let offer = {}
5822
5822
  if (text.includes('(') && text.includes(')')) {
5823
5823
  count = parseInt(text.split('(')[1].split(')')[0].trim())
5824
5824
  }
5825
- if (text.startsWith('Incoming Offers')) {
5825
+ if (link.endsWith('tradeoffers')) {
5826
5826
  offer = IncomingOffers
5827
- } else if (text.startsWith('Sent Offers')) {
5827
+ } else if (link.endsWith('tradeoffers/sent')) {
5828
5828
  offer = SentOffers
5829
5829
  } else {
5830
+ console.error("getTradeOffer", link);
5830
5831
  //invalid text
5831
5832
  }
5832
5833
  offer.link = link
@@ -5841,30 +5842,65 @@ class SteamUser {
5841
5842
  $('.profile_leftcol > .tradeoffer').each(function () {
5842
5843
  const $1 = $(this);
5843
5844
  const id = $1.attr('id')
5844
- if (id.startsWith('tradeofferid_')) {
5845
- const tradeofferid = parseInt(id.split('tradeofferid_')[1])
5846
- let partner = $1.html().split('ReportTradeScam(')[1].split(');')[0].trim()
5847
- for (const s of [`&quot;`, `'`, `"`]) {
5848
- partner = _.trim(partner, s);
5849
- }
5850
- const partnerSteamId = partner.split(`',`)[0].trim()
5851
- let partnerName = partner.split(`', &quot;`)[1].trim();
5852
- const playerAvatar = $1.find('.playerAvatar')
5853
- const avatar = playerAvatar.find('img')?.attr('src')
5854
- const link = playerAvatar.find('a')?.attr('href')
5855
- const header = StringUtils.cleanSpace($1.find('.tradeoffer_header').text())
5856
- const active = $1.find('.tradeoffer_items_ctn').hasClass("active")
5857
-
5858
- tradeOffers.push({
5859
- tradeofferid, partner: {
5860
- steamId: partnerSteamId,
5861
- name: partnerName,
5862
- avatar,
5863
- link,
5864
- header,
5865
- },
5866
- })
5845
+ if (!id.startsWith('tradeofferid_')) {
5846
+ return;
5867
5847
  }
5848
+ const tradeofferid = parseInt(id.split('tradeofferid_')[1])
5849
+ if(!tradeofferid){
5850
+ return
5851
+ }
5852
+ let partner = $1.html().split('ReportTradeScam(')[1].split(');')[0].trim()
5853
+ for (const s of [`&quot;`, `'`, `"`]) {
5854
+ partner = _.trim(partner, s);
5855
+ }
5856
+ const partnerSteamId = partner.split(`',`)[0].trim()
5857
+ const partnerName = partner.split(`', &quot;`)[1].trim();
5858
+ const playerAvatar = $1.find('.playerAvatar')
5859
+ const avatar = playerAvatar.find('img')?.attr('src')
5860
+ const link = playerAvatar.find('a')?.attr('href')
5861
+ const header = StringUtils.cleanSpace($1.find('.tradeoffer_header').text())
5862
+ const active = $1.find('.tradeoffer_items_ctn').hasClass("active")
5863
+ const tradeoffer_items_primary = $1.find('.tradeoffer_items_ctn .tradeoffer_items.primary')
5864
+ const tradeoffer_items_secondary = $1.find('.tradeoffer_items_ctn .tradeoffer_items.secondary')
5865
+ const primarySteamId = (SteamID.fromIndividualAccountID(parseInt(tradeoffer_items_primary.find("a.tradeoffer_avatar").attr("data-miniprofile")))).getSteamID64()
5866
+ const primaryItems = [...tradeoffer_items_primary.find(".tradeoffer_item_list > .trade_item")].map(function (el) {
5867
+ el = $(el)
5868
+ const economyItem = el.attr("data-economy-item")//classinfo/730/310777338/302028390
5869
+ const img = el.find("img").attr("src")
5870
+ return {
5871
+ economyItem,
5872
+ img
5873
+ }
5874
+ })
5875
+ const secondarySteamId = (SteamID.fromIndividualAccountID(parseInt(tradeoffer_items_secondary.find("a.tradeoffer_avatar").attr("data-miniprofile")))).getSteamID64()
5876
+ const secondaryItems = [...tradeoffer_items_secondary.find(".tradeoffer_item_list > .trade_item")].map(function (el) {
5877
+ el = $(el)
5878
+ const economyItem = el.attr("data-economy-item")//classinfo/730/310777338/302028390
5879
+ const img = el.find("img").attr("src")
5880
+ return {
5881
+ economyItem,
5882
+ img
5883
+ }
5884
+ })
5885
+ tradeOffers.push({
5886
+ tradeofferid,
5887
+ partner: {
5888
+ steamId: partnerSteamId,
5889
+ name: partnerName,
5890
+ avatarHash: SteamUser.GetAvatarHashFromURL(avatar),
5891
+ link,
5892
+ header,
5893
+ },
5894
+ active,
5895
+ primary: {
5896
+ steamId: primarySteamId,
5897
+ items: primaryItems
5898
+ },
5899
+ secondary: {
5900
+ steamId: secondarySteamId,
5901
+ items: secondaryItems
5902
+ }
5903
+ })
5868
5904
  })
5869
5905
 
5870
5906
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "steamutils",
3
- "version": "1.3.25",
3
+ "version": "1.3.27",
4
4
  "main": "index.js",
5
5
  "dependencies": {
6
6
  "alpha-common-utils": "^1.0.5",