@tiktool/live 2.5.2 → 2.6.0
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/README.md +5 -5
- package/dist/index.d.mts +581 -3
- package/dist/index.d.ts +581 -3
- package/dist/index.js +82 -37
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +82 -37
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -2
package/dist/index.js
CHANGED
|
@@ -284,10 +284,24 @@ function parseUser(data) {
|
|
|
284
284
|
}
|
|
285
285
|
}
|
|
286
286
|
const badges = [];
|
|
287
|
-
|
|
288
|
-
|
|
287
|
+
let payGrade;
|
|
288
|
+
const badgeBufs = getAllBytes(f, 64);
|
|
289
|
+
for (const badgeBuf of badgeBufs) {
|
|
289
290
|
try {
|
|
290
291
|
const badgeFields = decodeProto(badgeBuf);
|
|
292
|
+
const badgeCategory = getInt(badgeFields, 2);
|
|
293
|
+
const badgeSubCat = getInt(badgeFields, 3);
|
|
294
|
+
if (badgeCategory === 20 && badgeSubCat === 8 && !payGrade) {
|
|
295
|
+
const privBuf = getBytes(badgeFields, 12);
|
|
296
|
+
if (privBuf) {
|
|
297
|
+
const privFields = decodeProto(privBuf);
|
|
298
|
+
const levelStr = getStr(privFields, 5);
|
|
299
|
+
if (levelStr) {
|
|
300
|
+
const level = parseInt(levelStr, 10);
|
|
301
|
+
if (level > 0) payGrade = level;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
291
305
|
const badgeItems = getAllBytes(badgeFields, 21);
|
|
292
306
|
for (const bi of badgeItems) {
|
|
293
307
|
const bf = decodeProto(bi);
|
|
@@ -302,7 +316,8 @@ function parseUser(data) {
|
|
|
302
316
|
nickname,
|
|
303
317
|
uniqueId: uniqueId || nickname || id,
|
|
304
318
|
profilePictureUrl: profilePicture,
|
|
305
|
-
badges: badges.length > 0 ? badges : void 0
|
|
319
|
+
badges: badges.length > 0 ? badges : void 0,
|
|
320
|
+
payGrade
|
|
306
321
|
};
|
|
307
322
|
}
|
|
308
323
|
function parseBattleTeamFromArmies(itemBuf) {
|
|
@@ -552,9 +567,27 @@ function parseWebcastMessage(method, payload) {
|
|
|
552
567
|
return { ...base, type: "battle", battleId, status, battleDuration, teams, battleSettings };
|
|
553
568
|
}
|
|
554
569
|
case "WebcastLinkMicArmies": {
|
|
555
|
-
const battleId = getIntStr(f, 1) || "";
|
|
570
|
+
const battleId = getIntStr(f, 2) || getIntStr(f, 1) || "";
|
|
556
571
|
const battleStatus = getInt(f, 7);
|
|
557
572
|
const teams = [];
|
|
573
|
+
let battleSettings;
|
|
574
|
+
const settingsBuf18 = getBytes(f, 18);
|
|
575
|
+
if (settingsBuf18) {
|
|
576
|
+
try {
|
|
577
|
+
const sf = decodeProto(settingsBuf18);
|
|
578
|
+
const startTimeMs = getInt(sf, 2);
|
|
579
|
+
const duration = getInt(sf, 3);
|
|
580
|
+
const endTimeMs = getInt(sf, 10);
|
|
581
|
+
battleSettings = {
|
|
582
|
+
startTimeMs: startTimeMs || void 0,
|
|
583
|
+
duration: duration || void 0,
|
|
584
|
+
endTimeMs: endTimeMs || void 0
|
|
585
|
+
};
|
|
586
|
+
} catch {
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
const scoreUpdateTime = getInt(f, 5);
|
|
590
|
+
const giftSentTime = getInt(f, 6);
|
|
558
591
|
const itemBufs = getAllBytes(f, 3);
|
|
559
592
|
for (const ib of itemBufs) {
|
|
560
593
|
try {
|
|
@@ -567,7 +600,10 @@ function parseWebcastMessage(method, payload) {
|
|
|
567
600
|
type: "battleArmies",
|
|
568
601
|
battleId,
|
|
569
602
|
teams,
|
|
570
|
-
status: battleStatus
|
|
603
|
+
status: battleStatus,
|
|
604
|
+
battleSettings,
|
|
605
|
+
scoreUpdateTime,
|
|
606
|
+
giftSentTime
|
|
571
607
|
};
|
|
572
608
|
}
|
|
573
609
|
case "WebcastSubNotifyMessage": {
|
|
@@ -866,6 +902,8 @@ var TikTokLive = class extends import_events.EventEmitter {
|
|
|
866
902
|
_sessionId;
|
|
867
903
|
_ttTargetIdc;
|
|
868
904
|
proxyAgent;
|
|
905
|
+
_presetRoomId;
|
|
906
|
+
_presetTtwid;
|
|
869
907
|
constructor(options) {
|
|
870
908
|
super();
|
|
871
909
|
this.uniqueId = options.uniqueId.replace(/^@/, "");
|
|
@@ -881,45 +919,51 @@ var TikTokLive = class extends import_events.EventEmitter {
|
|
|
881
919
|
if (options.agent) {
|
|
882
920
|
this.proxyAgent = options.agent;
|
|
883
921
|
}
|
|
922
|
+
this._presetRoomId = options.roomId;
|
|
923
|
+
this._presetTtwid = options.ttwid;
|
|
884
924
|
}
|
|
885
925
|
async connect() {
|
|
886
926
|
this.intentionalClose = false;
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
|
890
|
-
"Accept-Encoding": "gzip, deflate, br",
|
|
891
|
-
"Accept-Language": "en-US,en;q=0.9"
|
|
892
|
-
}, this.proxyAgent);
|
|
893
|
-
let ttwid = "";
|
|
894
|
-
for (const sc of [resp.headers["set-cookie"] || []].flat()) {
|
|
895
|
-
if (typeof sc === "string" && sc.startsWith("ttwid=")) {
|
|
896
|
-
ttwid = sc.split(";")[0].split("=").slice(1).join("=");
|
|
897
|
-
break;
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
if (!ttwid) throw new Error("Failed to obtain session cookie");
|
|
901
|
-
const html = resp.body.toString();
|
|
902
|
-
let roomId = "";
|
|
927
|
+
let ttwid = this._presetTtwid || "";
|
|
928
|
+
let roomId = this._presetRoomId || "";
|
|
903
929
|
let ownerUserId = "";
|
|
904
|
-
|
|
905
|
-
if (
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
930
|
+
let clusterRegion = "";
|
|
931
|
+
if (!roomId || !ttwid) {
|
|
932
|
+
const targetUrl = `https://www.tiktok.com/@${this.uniqueId}/live`;
|
|
933
|
+
const resp = await httpGet(targetUrl, {
|
|
934
|
+
"User-Agent": DEFAULT_UA,
|
|
935
|
+
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
|
936
|
+
"Accept-Encoding": "gzip, deflate, br",
|
|
937
|
+
"Accept-Language": "en-US,en;q=0.9"
|
|
938
|
+
}, this.proxyAgent);
|
|
939
|
+
for (const sc of [resp.headers["set-cookie"] || []].flat()) {
|
|
940
|
+
if (typeof sc === "string" && sc.startsWith("ttwid=")) {
|
|
941
|
+
ttwid = sc.split(";")[0].split("=").slice(1).join("=");
|
|
942
|
+
break;
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
if (!ttwid) throw new Error("Failed to obtain session cookie");
|
|
946
|
+
const html = resp.body.toString();
|
|
947
|
+
const sigiMatch = html.match(/id="SIGI_STATE"[^>]*>([^<]+)/);
|
|
948
|
+
if (sigiMatch) {
|
|
949
|
+
try {
|
|
950
|
+
const json = JSON.parse(sigiMatch[1]);
|
|
951
|
+
const jsonStr = JSON.stringify(json);
|
|
952
|
+
const m = jsonStr.match(/"roomId"\s*:\s*"(\d+)"/);
|
|
953
|
+
if (m) roomId = m[1];
|
|
954
|
+
const ownerUser = json?.LiveRoom?.liveRoomUserInfo?.user;
|
|
955
|
+
if (ownerUser?.id) {
|
|
956
|
+
ownerUserId = String(ownerUser.id);
|
|
957
|
+
}
|
|
958
|
+
} catch {
|
|
914
959
|
}
|
|
915
|
-
} catch {
|
|
916
960
|
}
|
|
961
|
+
if (!roomId) throw new Error(`User @${this.uniqueId} is not currently live`);
|
|
962
|
+
const crMatch = html.match(/"clusterRegion"\s*:\s*"([^"]+)"/);
|
|
963
|
+
clusterRegion = crMatch ? crMatch[1] : "";
|
|
917
964
|
}
|
|
918
|
-
if (!roomId) throw new Error(`User @${this.uniqueId} is not currently live`);
|
|
919
965
|
this._roomId = roomId;
|
|
920
966
|
this._ownerUserId = ownerUserId;
|
|
921
|
-
const crMatch = html.match(/"clusterRegion"\s*:\s*"([^"]+)"/);
|
|
922
|
-
const clusterRegion = crMatch ? crMatch[1] : "";
|
|
923
967
|
const wsHost = getWsHost(clusterRegion);
|
|
924
968
|
const wsParams = new URLSearchParams({
|
|
925
969
|
version_code: "270000",
|
|
@@ -973,9 +1017,10 @@ var TikTokLive = class extends import_events.EventEmitter {
|
|
|
973
1017
|
wsUrl = rawWsUrl.replace(/^https:\/\//, "wss://");
|
|
974
1018
|
}
|
|
975
1019
|
return new Promise((resolve, reject) => {
|
|
976
|
-
let cookieHeader = `ttwid=${ttwid}
|
|
1020
|
+
let cookieHeader = ttwid ? `ttwid=${ttwid}` : "";
|
|
977
1021
|
if (this._sessionId) {
|
|
978
|
-
|
|
1022
|
+
const sessionCookies = `sessionid=${this._sessionId}; sessionid_ss=${this._sessionId}; sid_tt=${this._sessionId}`;
|
|
1023
|
+
cookieHeader = cookieHeader ? `${cookieHeader}; ${sessionCookies}` : sessionCookies;
|
|
979
1024
|
if (this._ttTargetIdc) {
|
|
980
1025
|
cookieHeader += `; tt-target-idc=${this._ttTargetIdc}`;
|
|
981
1026
|
}
|