@tiktool/live 2.5.2 → 2.6.1

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/dist/index.mjs CHANGED
@@ -246,10 +246,24 @@ function parseUser(data) {
246
246
  }
247
247
  }
248
248
  const badges = [];
249
- const badgeBuf = getBytes(f, 64);
250
- if (badgeBuf) {
249
+ let payGrade;
250
+ const badgeBufs = getAllBytes(f, 64);
251
+ for (const badgeBuf of badgeBufs) {
251
252
  try {
252
253
  const badgeFields = decodeProto(badgeBuf);
254
+ const badgeCategory = getInt(badgeFields, 2);
255
+ const badgeSubCat = getInt(badgeFields, 3);
256
+ if (badgeCategory === 20 && badgeSubCat === 8 && !payGrade) {
257
+ const privBuf = getBytes(badgeFields, 12);
258
+ if (privBuf) {
259
+ const privFields = decodeProto(privBuf);
260
+ const levelStr = getStr(privFields, 5);
261
+ if (levelStr) {
262
+ const level = parseInt(levelStr, 10);
263
+ if (level > 0) payGrade = level;
264
+ }
265
+ }
266
+ }
253
267
  const badgeItems = getAllBytes(badgeFields, 21);
254
268
  for (const bi of badgeItems) {
255
269
  const bf = decodeProto(bi);
@@ -264,7 +278,8 @@ function parseUser(data) {
264
278
  nickname,
265
279
  uniqueId: uniqueId || nickname || id,
266
280
  profilePictureUrl: profilePicture,
267
- badges: badges.length > 0 ? badges : void 0
281
+ badges: badges.length > 0 ? badges : void 0,
282
+ payGrade
268
283
  };
269
284
  }
270
285
  function parseBattleTeamFromArmies(itemBuf) {
@@ -514,9 +529,27 @@ function parseWebcastMessage(method, payload) {
514
529
  return { ...base, type: "battle", battleId, status, battleDuration, teams, battleSettings };
515
530
  }
516
531
  case "WebcastLinkMicArmies": {
517
- const battleId = getIntStr(f, 1) || "";
532
+ const battleId = getIntStr(f, 2) || getIntStr(f, 1) || "";
518
533
  const battleStatus = getInt(f, 7);
519
534
  const teams = [];
535
+ let battleSettings;
536
+ const settingsBuf18 = getBytes(f, 18);
537
+ if (settingsBuf18) {
538
+ try {
539
+ const sf = decodeProto(settingsBuf18);
540
+ const startTimeMs = getInt(sf, 2);
541
+ const duration = getInt(sf, 3);
542
+ const endTimeMs = getInt(sf, 10);
543
+ battleSettings = {
544
+ startTimeMs: startTimeMs || void 0,
545
+ duration: duration || void 0,
546
+ endTimeMs: endTimeMs || void 0
547
+ };
548
+ } catch {
549
+ }
550
+ }
551
+ const scoreUpdateTime = getInt(f, 5);
552
+ const giftSentTime = getInt(f, 6);
520
553
  const itemBufs = getAllBytes(f, 3);
521
554
  for (const ib of itemBufs) {
522
555
  try {
@@ -529,7 +562,10 @@ function parseWebcastMessage(method, payload) {
529
562
  type: "battleArmies",
530
563
  battleId,
531
564
  teams,
532
- status: battleStatus
565
+ status: battleStatus,
566
+ battleSettings,
567
+ scoreUpdateTime,
568
+ giftSentTime
533
569
  };
534
570
  }
535
571
  case "WebcastSubNotifyMessage": {
@@ -828,6 +864,8 @@ var TikTokLive = class extends EventEmitter {
828
864
  _sessionId;
829
865
  _ttTargetIdc;
830
866
  proxyAgent;
867
+ _presetRoomId;
868
+ _presetTtwid;
831
869
  constructor(options) {
832
870
  super();
833
871
  this.uniqueId = options.uniqueId.replace(/^@/, "");
@@ -843,45 +881,51 @@ var TikTokLive = class extends EventEmitter {
843
881
  if (options.agent) {
844
882
  this.proxyAgent = options.agent;
845
883
  }
884
+ this._presetRoomId = options.roomId;
885
+ this._presetTtwid = options.ttwid;
846
886
  }
847
887
  async connect() {
848
888
  this.intentionalClose = false;
849
- const resp = await httpGet(`https://www.tiktok.com/@${this.uniqueId}/live`, {
850
- "User-Agent": DEFAULT_UA,
851
- "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
852
- "Accept-Encoding": "gzip, deflate, br",
853
- "Accept-Language": "en-US,en;q=0.9"
854
- }, this.proxyAgent);
855
- let ttwid = "";
856
- for (const sc of [resp.headers["set-cookie"] || []].flat()) {
857
- if (typeof sc === "string" && sc.startsWith("ttwid=")) {
858
- ttwid = sc.split(";")[0].split("=").slice(1).join("=");
859
- break;
860
- }
861
- }
862
- if (!ttwid) throw new Error("Failed to obtain session cookie");
863
- const html = resp.body.toString();
864
- let roomId = "";
889
+ let ttwid = this._presetTtwid || "";
890
+ let roomId = this._presetRoomId || "";
865
891
  let ownerUserId = "";
866
- const sigiMatch = html.match(/id="SIGI_STATE"[^>]*>([^<]+)/);
867
- if (sigiMatch) {
868
- try {
869
- const json = JSON.parse(sigiMatch[1]);
870
- const jsonStr = JSON.stringify(json);
871
- const m = jsonStr.match(/"roomId"\s*:\s*"(\d+)"/);
872
- if (m) roomId = m[1];
873
- const ownerUser = json?.LiveRoom?.liveRoomUserInfo?.user;
874
- if (ownerUser?.id) {
875
- ownerUserId = String(ownerUser.id);
892
+ let clusterRegion = "";
893
+ if (!roomId || !ttwid) {
894
+ const targetUrl = `https://www.tiktok.com/@${this.uniqueId}/live`;
895
+ const resp = await httpGet(targetUrl, {
896
+ "User-Agent": DEFAULT_UA,
897
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
898
+ "Accept-Encoding": "gzip, deflate, br",
899
+ "Accept-Language": "en-US,en;q=0.9"
900
+ }, this.proxyAgent);
901
+ for (const sc of [resp.headers["set-cookie"] || []].flat()) {
902
+ if (typeof sc === "string" && sc.startsWith("ttwid=")) {
903
+ ttwid = sc.split(";")[0].split("=").slice(1).join("=");
904
+ break;
905
+ }
906
+ }
907
+ if (!ttwid) throw new Error("Failed to obtain session cookie");
908
+ const html = resp.body.toString();
909
+ const sigiMatch = html.match(/id="SIGI_STATE"[^>]*>([^<]+)/);
910
+ if (sigiMatch) {
911
+ try {
912
+ const json = JSON.parse(sigiMatch[1]);
913
+ const jsonStr = JSON.stringify(json);
914
+ const m = jsonStr.match(/"roomId"\s*:\s*"(\d+)"/);
915
+ if (m) roomId = m[1];
916
+ const ownerUser = json?.LiveRoom?.liveRoomUserInfo?.user;
917
+ if (ownerUser?.id) {
918
+ ownerUserId = String(ownerUser.id);
919
+ }
920
+ } catch {
876
921
  }
877
- } catch {
878
922
  }
923
+ if (!roomId) throw new Error(`User @${this.uniqueId} is not currently live`);
924
+ const crMatch = html.match(/"clusterRegion"\s*:\s*"([^"]+)"/);
925
+ clusterRegion = crMatch ? crMatch[1] : "";
879
926
  }
880
- if (!roomId) throw new Error(`User @${this.uniqueId} is not currently live`);
881
927
  this._roomId = roomId;
882
928
  this._ownerUserId = ownerUserId;
883
- const crMatch = html.match(/"clusterRegion"\s*:\s*"([^"]+)"/);
884
- const clusterRegion = crMatch ? crMatch[1] : "";
885
929
  const wsHost = getWsHost(clusterRegion);
886
930
  const wsParams = new URLSearchParams({
887
931
  version_code: "270000",
@@ -935,9 +979,10 @@ var TikTokLive = class extends EventEmitter {
935
979
  wsUrl = rawWsUrl.replace(/^https:\/\//, "wss://");
936
980
  }
937
981
  return new Promise((resolve, reject) => {
938
- let cookieHeader = `ttwid=${ttwid}`;
982
+ let cookieHeader = ttwid ? `ttwid=${ttwid}` : "";
939
983
  if (this._sessionId) {
940
- cookieHeader += `; sessionid=${this._sessionId}; sessionid_ss=${this._sessionId}; sid_tt=${this._sessionId}`;
984
+ const sessionCookies = `sessionid=${this._sessionId}; sessionid_ss=${this._sessionId}; sid_tt=${this._sessionId}`;
985
+ cookieHeader = cookieHeader ? `${cookieHeader}; ${sessionCookies}` : sessionCookies;
941
986
  if (this._ttTargetIdc) {
942
987
  cookieHeader += `; tt-target-idc=${this._ttTargetIdc}`;
943
988
  }