floating-live 0.12.0 → 0.13.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 +7 -8
- package/index.d.ts +3 -3
- package/index.js +3 -3
- package/package.json +4 -2
- package/plugin/acfun/acfunLive.d.ts +3 -3
- package/plugin/acfun/acfunLive.js +10 -10
- package/plugin/acfun/index.d.ts +1 -0
- package/plugin/acfun/index.js +3 -2
- package/plugin/bilibili/index.d.ts +1 -0
- package/plugin/bilibili/index.js +17 -4
- package/plugin/bilibili/parser.d.ts +6 -0
- package/plugin/bilibili/{bilibiliLive.js → parser.js} +132 -231
- package/plugin/bilibili/room.d.ts +77 -0
- package/plugin/bilibili/room.js +261 -0
- package/plugin/bilibili/types.d.ts +424 -0
- package/plugin/bilibili/utils.d.ts +16 -0
- package/plugin/bilibili/utils.js +140 -0
- package/plugin/chatPrint/chatPrint.d.ts +2 -2
- package/plugin/chatPrint/chatPrint.js +16 -6
- package/plugin/chatPrint/index.d.ts +1 -0
- package/plugin/chatPrint/index.js +2 -1
- package/plugin/consoleEvent/index.d.ts +1 -0
- package/plugin/consoleEvent/index.js +16 -21
- package/plugin/msgSave/index.d.ts +3 -1
- package/plugin/msgSave/index.js +25 -30
- package/plugin/msgSave/msgSave.d.ts +5 -5
- package/plugin/msgSave/msgSave.js +25 -9
- package/src/abstract/LiveRoom.d.ts +44 -0
- package/src/{lib → abstract}/LiveRoom.js +12 -7
- package/src/enum.d.ts +4 -2
- package/src/enum.js +9 -7
- package/src/index.d.ts +13 -37
- package/src/index.js +12 -74
- package/src/module/ModAuth.d.ts +8 -0
- package/src/module/ModAuth.js +14 -0
- package/src/module/ModCommand.d.ts +3 -0
- package/src/module/ModCommand.js +6 -0
- package/src/module/ModMessage.d.ts +9 -0
- package/src/module/ModMessage.js +12 -0
- package/src/module/{Plugin.d.ts → ModPlugin.d.ts} +2 -6
- package/src/module/{Plugin.js → ModPlugin.js} +20 -18
- package/src/module/ModRooms.d.ts +36 -0
- package/src/module/{Room.js → ModRooms.js} +50 -31
- package/src/types/index.d.ts +1 -2
- package/src/types/index.js +1 -2
- package/src/types/message.d.ts +210 -0
- package/src/types/plugin.d.ts +4 -5
- package/src/types/room.d.ts +48 -2
- package/src/utils.d.ts +2 -0
- package/src/{tool.js → utils.js} +4 -4
- package/test/type/bilibili_getInfoByRoom.d.ts +492 -0
- package/plugin/bilibili/bilibiliLive.d.ts +0 -58
- package/src/lib/LiveRoom.d.ts +0 -89
- package/src/module/Command.d.ts +0 -3
- package/src/module/Command.js +0 -6
- package/src/module/Room.d.ts +0 -26
- package/src/tool.d.ts +0 -2
- package/src/types/message/AttributeInfo.d.ts +0 -67
- package/src/types/message/MessageData.d.ts +0 -166
- /package/{src/types/message/AttributeInfo.js → plugin/bilibili/types.js} +0 -0
- /package/src/{lib → abstract}/Reglist.d.ts +0 -0
- /package/src/{lib → abstract}/Reglist.js +0 -0
- /package/src/types/{message/MessageData.js → message.js} +0 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.checkLoginQRcode = exports.printQRcode = exports.generateLoginQRcode = exports.getKey = exports.getBuvid = exports.getLoginUid = exports.parseCookieString = void 0;
|
|
7
|
+
const qrcode_1 = __importDefault(require("qrcode"));
|
|
8
|
+
const USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.36";
|
|
9
|
+
/** API-当前登录用户信息 */
|
|
10
|
+
const UID_INIT_URL = "https://api.bilibili.com/x/web-interface/nav";
|
|
11
|
+
/** API-获取BUVID */
|
|
12
|
+
const BUVID_INIT_URL = "https://data.bilibili.com/v/";
|
|
13
|
+
const ROOM_INIT_URL = "https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByRoom";
|
|
14
|
+
const DANMAKU_SERVER_CONF_URL = "https://api.live.bilibili.com/xlive/web-room/v1/index/getDanmuInfo";
|
|
15
|
+
function parseCookieString(str) {
|
|
16
|
+
const cookie = {};
|
|
17
|
+
str.split(";").forEach((item) => {
|
|
18
|
+
if (!item) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const arr = item.split("=");
|
|
22
|
+
const key = arr[0]?.trim();
|
|
23
|
+
const val = arr[1]?.trim();
|
|
24
|
+
cookie[key] = val;
|
|
25
|
+
});
|
|
26
|
+
return cookie;
|
|
27
|
+
}
|
|
28
|
+
exports.parseCookieString = parseCookieString;
|
|
29
|
+
/** 获取登录用户的uid */
|
|
30
|
+
async function getLoginUid(cookie = "") {
|
|
31
|
+
// cookie若缺少SESSDATA,一定属于未登录状态,uid返回0
|
|
32
|
+
if (!parseCookieString(cookie)["SESSDATA"])
|
|
33
|
+
return 0;
|
|
34
|
+
const res = await fetch(UID_INIT_URL, {
|
|
35
|
+
headers: {
|
|
36
|
+
Cookie: cookie,
|
|
37
|
+
"User-Agent": USER_AGENT,
|
|
38
|
+
},
|
|
39
|
+
}).then((res) => res.json());
|
|
40
|
+
if (res.code == 0) {
|
|
41
|
+
return res.data.mid;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
// code = -101 => 账号未登录
|
|
45
|
+
return 0;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.getLoginUid = getLoginUid;
|
|
49
|
+
/** 获取buvid */
|
|
50
|
+
async function getBuvid(cookie = "") {
|
|
51
|
+
const res = await fetch(BUVID_INIT_URL, {
|
|
52
|
+
headers: {
|
|
53
|
+
Cookie: cookie,
|
|
54
|
+
"User-Agent": USER_AGENT,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
const resCookie = res.headers.get("set-cookie");
|
|
58
|
+
if (!resCookie)
|
|
59
|
+
return;
|
|
60
|
+
return parseCookieString(resCookie)["buvid2"];
|
|
61
|
+
}
|
|
62
|
+
exports.getBuvid = getBuvid;
|
|
63
|
+
/** 获取直播间弹幕token */
|
|
64
|
+
async function getKey(roomId, cookie = "") {
|
|
65
|
+
const res = await fetch(`${DANMAKU_SERVER_CONF_URL}?id=${roomId}`, {
|
|
66
|
+
headers: {
|
|
67
|
+
Cookie: cookie,
|
|
68
|
+
"User-Agent": USER_AGENT,
|
|
69
|
+
},
|
|
70
|
+
}).then((res) => res.json());
|
|
71
|
+
return res.data.token;
|
|
72
|
+
}
|
|
73
|
+
exports.getKey = getKey;
|
|
74
|
+
/** 生成登录二维码 */
|
|
75
|
+
async function generateLoginQRcode() {
|
|
76
|
+
const res = await fetch("https://passport.bilibili.com/x/passport-login/web/qrcode/generate", {
|
|
77
|
+
headers: {
|
|
78
|
+
"User-Agent": USER_AGENT,
|
|
79
|
+
},
|
|
80
|
+
}).then((res) => res.json());
|
|
81
|
+
return {
|
|
82
|
+
url: res.data.url,
|
|
83
|
+
key: res.data.qrcode_key,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
exports.generateLoginQRcode = generateLoginQRcode;
|
|
87
|
+
/** 在终端打印登录二维码 */
|
|
88
|
+
function printQRcode(url) {
|
|
89
|
+
qrcode_1.default.toString(url, { type: "terminal" }, function (err, qr) {
|
|
90
|
+
console.log(qr);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
exports.printQRcode = printQRcode;
|
|
94
|
+
/** 检测登录二维码 */
|
|
95
|
+
function checkLoginQRcode(key) {
|
|
96
|
+
return new Promise((resolve, reject) => {
|
|
97
|
+
let timer = 0;
|
|
98
|
+
const pollFuction = async () => {
|
|
99
|
+
clearTimeout(timer);
|
|
100
|
+
const res = await fetch(`https://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key=${key}`, {
|
|
101
|
+
headers: {
|
|
102
|
+
"User-Agent": USER_AGENT,
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
const { code, message } = (await res.json()).data;
|
|
106
|
+
if (code == 86101) {
|
|
107
|
+
console.log("未扫码");
|
|
108
|
+
timer = setTimeout(pollFuction, 1000);
|
|
109
|
+
}
|
|
110
|
+
else if (code == 86090) {
|
|
111
|
+
console.log("等待确认");
|
|
112
|
+
timer = setTimeout(pollFuction, 1000);
|
|
113
|
+
}
|
|
114
|
+
else if (code == 0) {
|
|
115
|
+
console.log("登录成功");
|
|
116
|
+
const a = res.headers.get("set-cookie");
|
|
117
|
+
resolve(a);
|
|
118
|
+
}
|
|
119
|
+
else if (code == 86038) {
|
|
120
|
+
console.log("二维码失效");
|
|
121
|
+
resolve("");
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
console.log(`${code} ${message}`);
|
|
125
|
+
resolve("");
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
timer = setTimeout(pollFuction, 1000);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
exports.checkLoginQRcode = checkLoginQRcode;
|
|
132
|
+
/** 轮询登录二维码 */
|
|
133
|
+
async function pollLoginQRCode(key) {
|
|
134
|
+
const res = await fetch(`https://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key=${key}`, {
|
|
135
|
+
headers: {
|
|
136
|
+
"User-Agent": USER_AGENT,
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FloatingLive } from "../..";
|
|
2
2
|
import { UserInfo } from "../..";
|
|
3
|
-
import {
|
|
3
|
+
import { Message } from "../..";
|
|
4
4
|
export declare class chatPrint {
|
|
5
5
|
/** 主模块 */
|
|
6
6
|
main: FloatingLive;
|
|
@@ -16,5 +16,5 @@ export declare class chatPrint {
|
|
|
16
16
|
/** 获取特权粉丝名称 */
|
|
17
17
|
getPriviliegeName(platform: string, level: number | boolean): string | number | boolean;
|
|
18
18
|
/** 记录在控制台上 */
|
|
19
|
-
log(message:
|
|
19
|
+
log(message: Message.All): void;
|
|
20
20
|
}
|
|
@@ -7,15 +7,23 @@ class chatPrint {
|
|
|
7
7
|
this.main = main;
|
|
8
8
|
let hidden = [];
|
|
9
9
|
this.hideType = new Set(hidden); // 隐藏类型
|
|
10
|
-
this.main.on("
|
|
10
|
+
this.main.on("live:message", (msg) => {
|
|
11
|
+
this.log(msg);
|
|
12
|
+
});
|
|
11
13
|
}
|
|
12
14
|
/** 获取用户信息 */
|
|
13
15
|
getUserInfo(message) {
|
|
14
16
|
let user = message.info.user; // 用户信息
|
|
15
17
|
let name = `${"\x1b[33m"}${user.name}`; // 用户名
|
|
16
|
-
let medal = user.medal
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
let medal = user.medal
|
|
19
|
+
? `${"\x1b[32m"}[${user.medal.name}(${user.medal.level})] `
|
|
20
|
+
: ""; // 粉丝牌
|
|
21
|
+
let membership = user.membership
|
|
22
|
+
? `${"\x1b[36m"}[${this.getPriviliegeName(message.platform, user.membership)}]`
|
|
23
|
+
: ""; // 特权粉丝
|
|
24
|
+
let admin = user.type
|
|
25
|
+
? `${"\x1b[95m"}[${{ [__1.UserType.admin]: "房管", [__1.UserType.anchor]: "主播" }[user.type]}]`
|
|
26
|
+
: ""; // 房管
|
|
19
27
|
return `${medal}${membership}${admin}${name}${"\x1b[0m"}`; //[粉丝牌(等级)] [特权][房管]用户名
|
|
20
28
|
}
|
|
21
29
|
/** 获取特权粉丝名称 */
|
|
@@ -81,7 +89,9 @@ class chatPrint {
|
|
|
81
89
|
}
|
|
82
90
|
case "block": {
|
|
83
91
|
let user = this.getUserInfo(message);
|
|
84
|
-
let operator = message.info.operator.
|
|
92
|
+
let operator = message.info.operator.type
|
|
93
|
+
? { [__1.UserType.admin]: "房管", [__1.UserType.anchor]: "主播" }[message.info.operator.type]
|
|
94
|
+
: "";
|
|
85
95
|
console.log(`${user} 已被${operator}禁言`);
|
|
86
96
|
break;
|
|
87
97
|
}
|
|
@@ -98,7 +108,7 @@ class chatPrint {
|
|
|
98
108
|
}
|
|
99
109
|
case "live_end": {
|
|
100
110
|
let roomKey = `${message.platform}:${message.room}`;
|
|
101
|
-
console.log(`[
|
|
111
|
+
console.log(`[-] ${"\x1b[1;31m"}直播间${"\x1b[40;33m"} ${roomKey} ${"\x1b[1;31m"}已结束直播${"\x1b[0m"}`);
|
|
102
112
|
}
|
|
103
113
|
}
|
|
104
114
|
}
|
|
@@ -1,56 +1,51 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const initEventConsole = (ctx) => {
|
|
3
|
-
ctx.on("
|
|
4
|
-
console.log(`[controller]记录已开始: ${ctx.timestamp}`);
|
|
5
|
-
});
|
|
6
|
-
ctx.on("end", () => {
|
|
7
|
-
console.log(`[controller]记录已结束: ${ctx.timestamp}`);
|
|
8
|
-
});
|
|
9
|
-
ctx.on("room_connect", (key) => {
|
|
3
|
+
ctx.on("room:connect", (key) => {
|
|
10
4
|
console.log(`[${key}]已连接到直播服务器`);
|
|
11
5
|
});
|
|
12
|
-
ctx.on("
|
|
6
|
+
ctx.on("room:disconnect", (key) => {
|
|
13
7
|
console.log(`[${key}]与直播服务器的连接已断开`);
|
|
14
8
|
});
|
|
15
|
-
ctx.on("
|
|
9
|
+
ctx.on("room:info", (key) => {
|
|
16
10
|
console.log(`[${key}]已获取到房间信息`);
|
|
17
11
|
});
|
|
18
|
-
ctx.on("
|
|
12
|
+
ctx.on("room:update", (key) => {
|
|
19
13
|
console.log(`[${key}]直播间信息更新`);
|
|
20
14
|
});
|
|
21
|
-
ctx.on("
|
|
15
|
+
ctx.on("room:open", (key) => {
|
|
22
16
|
console.log(`[${key}]房间已打开`);
|
|
23
17
|
});
|
|
24
|
-
ctx.on("
|
|
18
|
+
ctx.on("room:close", (key) => {
|
|
25
19
|
console.log(`[${key}]房间已关闭`);
|
|
26
20
|
});
|
|
27
|
-
ctx.on("
|
|
21
|
+
ctx.on("room:add", (key) => {
|
|
28
22
|
console.log(`[room]已添加房间: ${key}`);
|
|
29
23
|
});
|
|
30
|
-
ctx.on("
|
|
24
|
+
ctx.on("room:remove", (key) => {
|
|
31
25
|
console.log(`[room]已移除房间: ${key}`);
|
|
32
26
|
});
|
|
33
|
-
ctx.on("
|
|
27
|
+
ctx.on("room:exist", (key) => {
|
|
34
28
|
console.log(`[room]房间已存在: ${key}`);
|
|
35
29
|
});
|
|
36
|
-
ctx.on("
|
|
30
|
+
ctx.on("room:unexist", (key) => {
|
|
37
31
|
console.log(`[room]房间不存在: ${key}`);
|
|
38
32
|
});
|
|
39
|
-
ctx.on("
|
|
33
|
+
ctx.on("plugin:add", (name) => {
|
|
40
34
|
console.log(`[plugin]已添加插件: ${name}`);
|
|
41
35
|
});
|
|
42
|
-
ctx.on("
|
|
36
|
+
ctx.on("plugin:remove", (name) => {
|
|
43
37
|
console.log(`[plugin]已移除插件: ${name}`);
|
|
44
38
|
});
|
|
45
|
-
ctx.on("
|
|
39
|
+
ctx.on("plugin:unexist", (name) => {
|
|
46
40
|
console.log(`[plugin]插件不存在: ${name}`);
|
|
47
41
|
});
|
|
48
|
-
ctx.on("
|
|
42
|
+
ctx.on("plugin:duplicate", (name) => {
|
|
49
43
|
console.log(`[plugin]插件名称重复: ${name}`);
|
|
50
44
|
});
|
|
51
45
|
};
|
|
52
46
|
module.exports = () => {
|
|
53
47
|
return {
|
|
54
|
-
|
|
48
|
+
name: "consoleEvent",
|
|
49
|
+
register: initEventConsole,
|
|
55
50
|
};
|
|
56
51
|
};
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { FloatingLive } from "../..";
|
|
2
2
|
import MsgSave from "./msgSave";
|
|
3
3
|
export declare const messageSave: () => {
|
|
4
|
+
name: string;
|
|
4
5
|
register: (ctx: FloatingLive) => MsgSave;
|
|
5
6
|
};
|
|
6
|
-
export declare const
|
|
7
|
+
export declare const messageSaveRaw: () => {
|
|
8
|
+
name: string;
|
|
7
9
|
register: (ctx: FloatingLive) => MsgSave;
|
|
8
10
|
};
|
package/plugin/msgSave/index.js
CHANGED
|
@@ -3,84 +3,79 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.messageSaveRaw = exports.messageSave = void 0;
|
|
7
7
|
const msgSave_1 = __importDefault(require("./msgSave"));
|
|
8
8
|
const messageSave = () => {
|
|
9
9
|
return {
|
|
10
|
+
name: "messageSave",
|
|
10
11
|
register: (ctx) => {
|
|
11
12
|
const saveMessage = new msgSave_1.default(ctx, {
|
|
12
13
|
filePath: `./save`,
|
|
13
14
|
sliceByStatus: true,
|
|
14
15
|
});
|
|
15
16
|
// 直播状态改变时,更新保存信息
|
|
16
|
-
ctx.on("
|
|
17
|
-
const { platform, id } = ctx.
|
|
17
|
+
ctx.on("room:status", (roomKey, status, { timestamp }) => {
|
|
18
|
+
const { platform, id } = ctx.rooms.get(roomKey).info;
|
|
18
19
|
saveMessage.setSaveInfo({
|
|
19
20
|
platform,
|
|
20
21
|
room: id,
|
|
21
22
|
status,
|
|
22
23
|
timestamp,
|
|
23
|
-
statusChanged: true
|
|
24
|
+
statusChanged: true,
|
|
24
25
|
});
|
|
25
26
|
});
|
|
26
27
|
// 打开直播间时,设置保存信息
|
|
27
|
-
ctx.on("
|
|
28
|
+
ctx.on("room:open", (roomKey, roomInfo) => {
|
|
28
29
|
const { platform, id, status } = roomInfo;
|
|
29
30
|
saveMessage.setSaveInfo({
|
|
30
31
|
platform,
|
|
31
32
|
room: id,
|
|
32
33
|
status,
|
|
33
34
|
timestamp: Date.now(),
|
|
34
|
-
statusChanged: false
|
|
35
|
+
statusChanged: false,
|
|
35
36
|
});
|
|
36
37
|
});
|
|
37
38
|
// 关闭直播间时,移除保存信息
|
|
38
|
-
ctx.on("
|
|
39
|
+
ctx.on("room:close", (roomKey, roomInfo) => {
|
|
39
40
|
saveMessage.removeSaveInfo(roomKey);
|
|
40
41
|
});
|
|
41
|
-
ctx.on("
|
|
42
|
+
ctx.on("live:message", (msg) => {
|
|
42
43
|
saveMessage.write(msg, msg);
|
|
43
44
|
});
|
|
44
|
-
ctx.on("start", () => {
|
|
45
|
-
saveMessage.start();
|
|
46
|
-
});
|
|
47
|
-
ctx.on("end", () => { saveMessage.pause(); });
|
|
48
45
|
return saveMessage;
|
|
49
|
-
}
|
|
46
|
+
},
|
|
50
47
|
};
|
|
51
48
|
};
|
|
52
49
|
exports.messageSave = messageSave;
|
|
53
|
-
const
|
|
50
|
+
const messageSaveRaw = () => {
|
|
54
51
|
return {
|
|
52
|
+
name: "messageSaveRaw",
|
|
55
53
|
register: (ctx) => {
|
|
56
|
-
const
|
|
54
|
+
const saveRaw = new msgSave_1.default(ctx, {
|
|
57
55
|
filePath: `./save`,
|
|
58
|
-
suffix: `.
|
|
56
|
+
suffix: `.raw`,
|
|
59
57
|
});
|
|
60
58
|
// 打开直播间时,设置保存信息
|
|
61
|
-
ctx.on("
|
|
59
|
+
ctx.on("room:open", (roomKey, roomInfo) => {
|
|
62
60
|
const { platform, id, status } = roomInfo;
|
|
63
|
-
|
|
61
|
+
saveRaw.setSaveInfo({
|
|
64
62
|
platform,
|
|
65
63
|
room: id,
|
|
66
64
|
status,
|
|
67
65
|
timestamp: Date.now(),
|
|
68
|
-
statusChanged: false
|
|
66
|
+
statusChanged: false,
|
|
69
67
|
});
|
|
70
68
|
});
|
|
71
69
|
// 关闭直播间时,移除保存信息
|
|
72
|
-
ctx.on("
|
|
73
|
-
|
|
74
|
-
});
|
|
75
|
-
ctx.on("live_origin", (msg, { platform, room }) => {
|
|
76
|
-
saveOrigin.write(msg, { platform, room });
|
|
70
|
+
ctx.on("room:close", (roomKey, roomInfo) => {
|
|
71
|
+
saveRaw.removeSaveInfo(roomKey);
|
|
77
72
|
});
|
|
78
|
-
ctx.on("
|
|
79
|
-
|
|
73
|
+
ctx.on("live:raw", (msg, { platform, room }) => {
|
|
74
|
+
saveRaw.write(msg, { platform, room });
|
|
80
75
|
});
|
|
81
|
-
|
|
82
|
-
return
|
|
83
|
-
}
|
|
76
|
+
saveRaw.start();
|
|
77
|
+
return saveRaw;
|
|
78
|
+
},
|
|
84
79
|
};
|
|
85
80
|
};
|
|
86
|
-
exports.
|
|
81
|
+
exports.messageSaveRaw = messageSaveRaw;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RoomStatus } from
|
|
1
|
+
import { RoomStatus } from "../..";
|
|
2
2
|
import { FloatingLive } from "../..";
|
|
3
3
|
interface SaveInfoConfig {
|
|
4
4
|
platform: string;
|
|
@@ -32,7 +32,7 @@ declare class SaveInfo implements SaveInfoConfig {
|
|
|
32
32
|
sliceByCount: number;
|
|
33
33
|
/** 分块id */
|
|
34
34
|
part: number;
|
|
35
|
-
constructor({ platform, room, status, timestamp, statusChanged, sliceByStatus, sliceByCount }: SaveInfoConfig & {
|
|
35
|
+
constructor({ platform, room, status, timestamp, statusChanged, sliceByStatus, sliceByCount, }: SaveInfoConfig & {
|
|
36
36
|
sliceByStatus?: boolean;
|
|
37
37
|
sliceByCount?: number;
|
|
38
38
|
});
|
|
@@ -54,7 +54,7 @@ declare class MsgSave {
|
|
|
54
54
|
paused: boolean;
|
|
55
55
|
/** 列表 */
|
|
56
56
|
list: Map<string, SaveInfo>;
|
|
57
|
-
constructor(main: FloatingLive, { filePath, prefix, suffix, open, sliceByStatus, sliceByCount }: {
|
|
57
|
+
constructor(main: FloatingLive, { filePath, prefix, suffix, open, sliceByStatus, sliceByCount, }: {
|
|
58
58
|
filePath: string;
|
|
59
59
|
prefix?: string;
|
|
60
60
|
suffix?: string;
|
|
@@ -69,9 +69,9 @@ declare class MsgSave {
|
|
|
69
69
|
start(): void;
|
|
70
70
|
pause(): void;
|
|
71
71
|
/** 设置保存信息 */
|
|
72
|
-
setSaveInfo({ platform, room, status, timestamp, statusChanged }: SaveInfoConfig): void;
|
|
72
|
+
setSaveInfo({ platform, room, status, timestamp, statusChanged, }: SaveInfoConfig): void;
|
|
73
73
|
/** 创建保存信息,用于记录信息可能不存在的情况 */
|
|
74
|
-
createSaveInfo({ platform, room }: {
|
|
74
|
+
createSaveInfo({ platform, room, }: {
|
|
75
75
|
platform: string;
|
|
76
76
|
room: string | number;
|
|
77
77
|
}): SaveInfo;
|
|
@@ -8,7 +8,18 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
function getTimeStr(timestamp) {
|
|
10
10
|
let startDate = new Date(timestamp);
|
|
11
|
-
return `${startDate.getFullYear()}${(startDate.getMonth() + 1)
|
|
11
|
+
return `${startDate.getFullYear()}${(startDate.getMonth() + 1)
|
|
12
|
+
.toString()
|
|
13
|
+
.padStart(2, "0")}${startDate
|
|
14
|
+
.getDate()
|
|
15
|
+
.toString()
|
|
16
|
+
.padStart(2, "0")}_${startDate
|
|
17
|
+
.getHours()
|
|
18
|
+
.toString()
|
|
19
|
+
.padStart(2, "0")}${startDate
|
|
20
|
+
.getMinutes()
|
|
21
|
+
.toString()
|
|
22
|
+
.padStart(2, "0")}${startDate.getSeconds().toString().padStart(2, "0")}`;
|
|
12
23
|
}
|
|
13
24
|
/** 获取当次记录状态
|
|
14
25
|
* S=直播开始 L=直播中 E=直播结束 O=未开播
|
|
@@ -24,7 +35,7 @@ function getRecordStatus(status, statusChanged) {
|
|
|
24
35
|
}
|
|
25
36
|
}
|
|
26
37
|
class SaveInfo {
|
|
27
|
-
constructor({ platform, room, status, timestamp, statusChanged, sliceByStatus = false, sliceByCount = 0 }) {
|
|
38
|
+
constructor({ platform, room, status, timestamp, statusChanged, sliceByStatus = false, sliceByCount = 0, }) {
|
|
28
39
|
/** 文件是否存在 */
|
|
29
40
|
this.exist = false;
|
|
30
41
|
/** 记录状态是否已更改 */
|
|
@@ -54,7 +65,7 @@ class SaveInfo {
|
|
|
54
65
|
}
|
|
55
66
|
}
|
|
56
67
|
class MsgSave {
|
|
57
|
-
constructor(main, { filePath, prefix = "", suffix = "", open = true, sliceByStatus = false, sliceByCount = 0 }) {
|
|
68
|
+
constructor(main, { filePath, prefix = "", suffix = "", open = true, sliceByStatus = false, sliceByCount = 0, }) {
|
|
58
69
|
/** 列表 */
|
|
59
70
|
this.list = new Map();
|
|
60
71
|
this.paused = !open;
|
|
@@ -93,7 +104,7 @@ class MsgSave {
|
|
|
93
104
|
this.paused = true;
|
|
94
105
|
}
|
|
95
106
|
/** 设置保存信息 */
|
|
96
|
-
setSaveInfo({ platform, room, status, timestamp, statusChanged }) {
|
|
107
|
+
setSaveInfo({ platform, room, status, timestamp, statusChanged, }) {
|
|
97
108
|
const saveInfo = new SaveInfo({
|
|
98
109
|
platform,
|
|
99
110
|
room,
|
|
@@ -109,11 +120,13 @@ class MsgSave {
|
|
|
109
120
|
this.list.set(roomKey, saveInfo);
|
|
110
121
|
}
|
|
111
122
|
/** 创建保存信息,用于记录信息可能不存在的情况 */
|
|
112
|
-
createSaveInfo({ platform, room }) {
|
|
113
|
-
const { status, timestamp } = this.main.
|
|
123
|
+
createSaveInfo({ platform, room, }) {
|
|
124
|
+
const { status, timestamp } = this.main.rooms.get(`${platform}:${room}`)
|
|
125
|
+
?.info || { status: __1.RoomStatus.off, timestamp: 0 };
|
|
114
126
|
const saveInfoConfig = {
|
|
115
127
|
platform,
|
|
116
|
-
room,
|
|
128
|
+
room,
|
|
129
|
+
status,
|
|
117
130
|
timestamp,
|
|
118
131
|
statusChanged: false,
|
|
119
132
|
sliceByStatus: this.sliceByStatus,
|
|
@@ -140,9 +153,12 @@ class MsgSave {
|
|
|
140
153
|
statusChanged: saveInfo.statusChanged,
|
|
141
154
|
index: saveInfo.totalCount,
|
|
142
155
|
part: saveInfo.part,
|
|
143
|
-
roomInfo: this.main.
|
|
156
|
+
roomInfo: this.main.rooms.get(roomKey)?.info,
|
|
144
157
|
};
|
|
145
|
-
fs_extra_1.default.writeFileSync(file, JSON.stringify(message) + ",", {
|
|
158
|
+
fs_extra_1.default.writeFileSync(file, JSON.stringify(message) + ",", {
|
|
159
|
+
encoding: "utf8",
|
|
160
|
+
flag: "a",
|
|
161
|
+
});
|
|
146
162
|
}
|
|
147
163
|
/** 移除记录信息 */
|
|
148
164
|
removeSaveInfo(roomKey) {
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { EventEmitter } from "events";
|
|
3
|
+
import { RoomStatus } from "../enum";
|
|
4
|
+
import { RoomDetail, RoomInfo, RoomStatsInfo } from "../types";
|
|
5
|
+
import { Message, UserInfo } from "../types/message";
|
|
6
|
+
export declare abstract class LiveRoom extends EventEmitter implements RoomInfo {
|
|
7
|
+
constructor();
|
|
8
|
+
/** 平台 */
|
|
9
|
+
abstract readonly platform: string;
|
|
10
|
+
/** 房间id */
|
|
11
|
+
abstract readonly id: string | number;
|
|
12
|
+
/** 房间详情 */
|
|
13
|
+
abstract detail: RoomDetail;
|
|
14
|
+
/** 统计信息 */
|
|
15
|
+
stats?: RoomStatsInfo;
|
|
16
|
+
/** 主播信息 */
|
|
17
|
+
abstract anchor: UserInfo;
|
|
18
|
+
/** 直播状态 */
|
|
19
|
+
status: RoomStatus;
|
|
20
|
+
/** 时间戳 */
|
|
21
|
+
timestamp: number;
|
|
22
|
+
/** 当前直播id */
|
|
23
|
+
liveId?: string;
|
|
24
|
+
/** 房间是否打开 */
|
|
25
|
+
opened: boolean;
|
|
26
|
+
/** 房间是否可用 */
|
|
27
|
+
abstract available: boolean;
|
|
28
|
+
/** 是否连接上房间 */
|
|
29
|
+
abstract connected: boolean;
|
|
30
|
+
/** 打开连接 */
|
|
31
|
+
abstract open(): void;
|
|
32
|
+
/** 关闭连接 */
|
|
33
|
+
abstract close(): void;
|
|
34
|
+
/** 从服务器获取信息 */
|
|
35
|
+
abstract getInfo(): void;
|
|
36
|
+
/** 销毁事件 */
|
|
37
|
+
protected onDestory?(): void;
|
|
38
|
+
/** 销毁 */
|
|
39
|
+
destroy(): void;
|
|
40
|
+
protected emitMsg(msg: Message.All): void;
|
|
41
|
+
protected emitRaw(msg: any): void;
|
|
42
|
+
get info(): RoomInfo;
|
|
43
|
+
get key(): string;
|
|
44
|
+
}
|
|
@@ -11,10 +11,10 @@ class LiveRoom extends events_1.EventEmitter {
|
|
|
11
11
|
/** 时间戳 */
|
|
12
12
|
this.timestamp = 0;
|
|
13
13
|
/** 房间是否打开 */
|
|
14
|
-
this.
|
|
14
|
+
this.opened = false;
|
|
15
15
|
}
|
|
16
16
|
/** 销毁 */
|
|
17
|
-
|
|
17
|
+
destroy() {
|
|
18
18
|
this.close();
|
|
19
19
|
this.removeAllListeners();
|
|
20
20
|
this.onDestory?.();
|
|
@@ -27,7 +27,10 @@ class LiveRoom extends events_1.EventEmitter {
|
|
|
27
27
|
case "live_start":
|
|
28
28
|
this.status = enum_1.RoomStatus.live;
|
|
29
29
|
this.timestamp = msg.timestamp;
|
|
30
|
-
this.emit("status", enum_1.RoomStatus.live, {
|
|
30
|
+
this.emit("status", enum_1.RoomStatus.live, {
|
|
31
|
+
timestamp: msg.timestamp,
|
|
32
|
+
id: msg.info.id,
|
|
33
|
+
});
|
|
31
34
|
break;
|
|
32
35
|
case "live_detail":
|
|
33
36
|
this.detail = Object.assign(this.detail, msg.info);
|
|
@@ -42,14 +45,16 @@ class LiveRoom extends events_1.EventEmitter {
|
|
|
42
45
|
this.emit("msg", msg);
|
|
43
46
|
this.status = msg.status || enum_1.RoomStatus.off;
|
|
44
47
|
this.timestamp = msg.timestamp;
|
|
45
|
-
this.emit("status", msg.status || enum_1.RoomStatus.off, {
|
|
48
|
+
this.emit("status", msg.status || enum_1.RoomStatus.off, {
|
|
49
|
+
timestamp: msg.timestamp,
|
|
50
|
+
});
|
|
46
51
|
return;
|
|
47
52
|
}
|
|
48
53
|
this.emit("msg", msg);
|
|
49
54
|
}
|
|
50
55
|
// 发送源消息
|
|
51
|
-
|
|
52
|
-
this.emit("
|
|
56
|
+
emitRaw(msg) {
|
|
57
|
+
this.emit("raw", msg, { platform: this.platform, room: this.id });
|
|
53
58
|
}
|
|
54
59
|
get info() {
|
|
55
60
|
return {
|
|
@@ -62,7 +67,7 @@ class LiveRoom extends events_1.EventEmitter {
|
|
|
62
67
|
status: this.status,
|
|
63
68
|
liveId: this.liveId,
|
|
64
69
|
available: this.available,
|
|
65
|
-
|
|
70
|
+
opened: this.opened,
|
|
66
71
|
connected: this.connected,
|
|
67
72
|
key: this.key,
|
|
68
73
|
};
|
package/src/enum.d.ts
CHANGED