mirror of
https://github.com/LLOneBot/LLOneBot.git
synced 2024-11-22 01:56:33 +00:00
Compare commits
26 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
5562a3251d | ||
![]() |
019b590f36 | ||
![]() |
c2b3316603 | ||
![]() |
f8890b309b | ||
![]() |
b5e578733f | ||
![]() |
51602b987e | ||
![]() |
b501af6e0e | ||
![]() |
81821e74d8 | ||
![]() |
959eab441e | ||
![]() |
441c0c6946 | ||
![]() |
240cdade07 | ||
![]() |
0132d97bd9 | ||
![]() |
b34c7f045c | ||
![]() |
ab91313e69 | ||
![]() |
1f8966aaf4 | ||
![]() |
ec073da3f6 | ||
![]() |
80131e0472 | ||
![]() |
112ef202d1 | ||
![]() |
267052afbb | ||
![]() |
0c59371ed1 | ||
![]() |
655225e027 | ||
![]() |
bc49bf520c | ||
![]() |
dd03e384ce | ||
![]() |
ecd64529a4 | ||
![]() |
016482c9e5 | ||
![]() |
23be081d29 |
@@ -32,7 +32,7 @@ let config = {
|
|||||||
targets: [
|
targets: [
|
||||||
...external.map(genCpModule),
|
...external.map(genCpModule),
|
||||||
{src: './manifest.json', dest: 'dist'}, {src: './icon.jpg', dest: 'dist'},
|
{src: './manifest.json', dest: 'dist'}, {src: './icon.jpg', dest: 'dist'},
|
||||||
{src: './src/ntqqapi/external/ccpoke/poke-win32-x64.node', dest: 'dist/main/ccpoke/'},
|
{src: './src/ntqqapi/external/crychic/crychic-win32-x64.node', dest: 'dist/main/'},
|
||||||
]
|
]
|
||||||
})]
|
})]
|
||||||
},
|
},
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 4,
|
"manifest_version": 4,
|
||||||
"type": "extension",
|
"type": "extension",
|
||||||
"name": "LLOneBot v3.20.4",
|
"name": "LLOneBot v3.23.0",
|
||||||
"slug": "LLOneBot",
|
"slug": "LLOneBot",
|
||||||
"description": "使你的NTQQ支持OneBot11协议进行QQ机器人开发, 不支持商店在线更新",
|
"description": "使你的NTQQ支持OneBot11协议进行QQ机器人开发, 不支持商店在线更新",
|
||||||
"version": "3.20.4",
|
"version": "3.23.0",
|
||||||
"icon": "./icon.jpg",
|
"icon": "./icon.jpg",
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
|
@@ -39,6 +39,7 @@ export class ConfigUtil {
|
|||||||
enableWs: true,
|
enableWs: true,
|
||||||
enableWsReverse: false,
|
enableWsReverse: false,
|
||||||
messagePostFormat: "array",
|
messagePostFormat: "array",
|
||||||
|
enableHttpHeart: false
|
||||||
}
|
}
|
||||||
let defaultConfig: Config = {
|
let defaultConfig: Config = {
|
||||||
ob11: ob11Default,
|
ob11: ob11Default,
|
||||||
@@ -77,7 +78,7 @@ export class ConfigUtil {
|
|||||||
|
|
||||||
setConfig(config: Config) {
|
setConfig(config: Config) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
fsPromise.writeFile(this.configPath, JSON.stringify(config, null, 2), "utf-8").then()
|
fs.writeFileSync(this.configPath, JSON.stringify(config, null, 2), "utf-8")
|
||||||
}
|
}
|
||||||
|
|
||||||
private checkOldConfig(currentConfig: Config | OB11Config,
|
private checkOldConfig(currentConfig: Config | OB11Config,
|
||||||
|
@@ -28,7 +28,7 @@ export const llonebotError: LLOneBotError = {
|
|||||||
|
|
||||||
|
|
||||||
export async function getFriend(uinOrUid: string): Promise<Friend | undefined> {
|
export async function getFriend(uinOrUid: string): Promise<Friend | undefined> {
|
||||||
let filterKey = isNumeric(uinOrUid) ? "uin" : "uid"
|
let filterKey = isNumeric(uinOrUid.toString()) ? "uin" : "uid"
|
||||||
let filterValue = uinOrUid
|
let filterValue = uinOrUid
|
||||||
let friend = friends.find(friend => friend[filterKey] === filterValue.toString())
|
let friend = friends.find(friend => friend[filterKey] === filterValue.toString())
|
||||||
// if (!friend) {
|
// if (!friend) {
|
||||||
@@ -58,6 +58,15 @@ export async function getGroup(qq: string): Promise<Group | undefined> {
|
|||||||
return group
|
return group
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function deleteGroup(groupCode: string) {
|
||||||
|
const groupIndex = groups.findIndex(group => group.groupCode === groupCode.toString())
|
||||||
|
// log(groups, groupCode, groupIndex);
|
||||||
|
if (groupIndex !== -1) {
|
||||||
|
log("删除群", groupCode);
|
||||||
|
groups.splice(groupIndex, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function getGroupMember(groupQQ: string | number, memberUinOrUid: string | number) {
|
export async function getGroupMember(groupQQ: string | number, memberUinOrUid: string | number) {
|
||||||
groupQQ = groupQQ.toString()
|
groupQQ = groupQQ.toString()
|
||||||
memberUinOrUid = memberUinOrUid.toString()
|
memberUinOrUid = memberUinOrUid.toString()
|
||||||
|
@@ -95,6 +95,9 @@ export abstract class HttpServerBase {
|
|||||||
if (method == "get") {
|
if (method == "get") {
|
||||||
payload = req.query
|
payload = req.query
|
||||||
}
|
}
|
||||||
|
else if (req.query){
|
||||||
|
payload = {...req.query, ...req.body}
|
||||||
|
}
|
||||||
log("收到http请求", url, payload);
|
log("收到http请求", url, payload);
|
||||||
try {
|
try {
|
||||||
res.send(await handler(res, payload))
|
res.send(await handler(res, payload))
|
||||||
|
@@ -31,7 +31,9 @@ export class WebsocketServerBase {
|
|||||||
|
|
||||||
start(port: number) {
|
start(port: number) {
|
||||||
try {
|
try {
|
||||||
this.ws = new WebSocketServer({port});
|
this.ws = new WebSocketServer({port,
|
||||||
|
maxPayload: 1024 * 1024 * 1024
|
||||||
|
});
|
||||||
llonebotError.wsServerError = ''
|
llonebotError.wsServerError = ''
|
||||||
}catch (e) {
|
}catch (e) {
|
||||||
llonebotError.wsServerError = "正向ws服务启动失败, " + e.toString()
|
llonebotError.wsServerError = "正向ws服务启动失败, " + e.toString()
|
||||||
|
@@ -9,6 +9,7 @@ export interface OB11Config {
|
|||||||
enableWs?: boolean
|
enableWs?: boolean
|
||||||
enableWsReverse?: boolean
|
enableWsReverse?: boolean
|
||||||
messagePostFormat?: 'array' | 'string'
|
messagePostFormat?: 'array' | 'string'
|
||||||
|
enableHttpHeart?: boolean
|
||||||
}
|
}
|
||||||
export interface CheckVersion {
|
export interface CheckVersion {
|
||||||
result: boolean,
|
result: boolean,
|
||||||
|
@@ -6,7 +6,7 @@ import path from "node:path";
|
|||||||
import {DATA_DIR, TEMP_DIR} from "./index";
|
import {DATA_DIR, TEMP_DIR} from "./index";
|
||||||
import {v4 as uuidv4} from "uuid";
|
import {v4 as uuidv4} from "uuid";
|
||||||
import {getConfigUtil} from "../config";
|
import {getConfigUtil} from "../config";
|
||||||
import ffmpeg from "fluent-ffmpeg";
|
import {spawn} from "node:child_process"
|
||||||
|
|
||||||
export async function encodeSilk(filePath: string) {
|
export async function encodeSilk(filePath: string) {
|
||||||
function getFileHeader(filePath: string) {
|
function getFileHeader(filePath: string) {
|
||||||
@@ -64,50 +64,44 @@ export async function encodeSilk(filePath: string) {
|
|||||||
if (getFileHeader(filePath) !== "02232153494c4b") {
|
if (getFileHeader(filePath) !== "02232153494c4b") {
|
||||||
log(`语音文件${filePath}需要转换成silk`)
|
log(`语音文件${filePath}需要转换成silk`)
|
||||||
const _isWav = await isWavFile(filePath);
|
const _isWav = await isWavFile(filePath);
|
||||||
const wavPath = pttPath + ".wav"
|
const pcmPath = pttPath + ".pcm"
|
||||||
const convert = async () => {
|
let sampleRate = 0
|
||||||
return await new Promise((resolve, reject) => {
|
const convert = () => {
|
||||||
const ffmpegPath = getConfigUtil().getConfig().ffmpeg;
|
return new Promise<Buffer>((resolve, reject) => {
|
||||||
if (ffmpegPath) {
|
const ffmpegPath = getConfigUtil().getConfig().ffmpeg || process.env.FFMPEG_PATH || "ffmpeg"
|
||||||
ffmpeg.setFfmpegPath(ffmpegPath);
|
const cp = spawn(ffmpegPath, ["-y", "-i", filePath, "-ar", "24000", "-ac", "1", "-f", "s16le", pcmPath])
|
||||||
|
cp.on("error", err => {
|
||||||
|
log(`FFmpeg处理转换出错: `, err.message)
|
||||||
|
return reject(err)
|
||||||
|
})
|
||||||
|
cp.on("exit", (code, signal) => {
|
||||||
|
const EXIT_CODES = [0, 255]
|
||||||
|
if (code == null || EXIT_CODES.includes(code)) {
|
||||||
|
sampleRate = 24000
|
||||||
|
const data = fs.readFileSync(pcmPath)
|
||||||
|
fs.unlink(pcmPath, (err) => {
|
||||||
|
})
|
||||||
|
return resolve(data)
|
||||||
}
|
}
|
||||||
ffmpeg(filePath).toFormat("wav")
|
log(`FFmpeg exit: code=${code ?? "unknown"} sig=${signal ?? "unknown"}`)
|
||||||
.audioChannels(1)
|
reject(Error(`FFmpeg处理转换失败`))
|
||||||
.audioFrequency(24000)
|
|
||||||
.on('end', function () {
|
|
||||||
log('wav转换完成');
|
|
||||||
})
|
})
|
||||||
.on('error', function (err) {
|
|
||||||
log(`wav转换出错: `, err.message,);
|
|
||||||
reject(err);
|
|
||||||
})
|
|
||||||
.save(wavPath)
|
|
||||||
.on("end", () => {
|
|
||||||
filePath = wavPath
|
|
||||||
resolve(wavPath);
|
|
||||||
});
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
let wav: Buffer
|
let input: Buffer
|
||||||
if (!_isWav) {
|
if (!_isWav) {
|
||||||
log(`语音文件${filePath}正在转换成wav`)
|
input = await convert()
|
||||||
await convert()
|
|
||||||
} else {
|
} else {
|
||||||
wav = fs.readFileSync(filePath)
|
input = fs.readFileSync(filePath)
|
||||||
const allowSampleRate = [8000, 12000, 16000, 24000, 32000, 44100, 48000]
|
const allowSampleRate = [8000, 12000, 16000, 24000, 32000, 44100, 48000]
|
||||||
const {fmt} = getWavFileInfo(wav)
|
const {fmt} = getWavFileInfo(input)
|
||||||
// log(`wav文件信息`, fmt)
|
// log(`wav文件信息`, fmt)
|
||||||
if (!allowSampleRate.includes(fmt.sampleRate)) {
|
if (!allowSampleRate.includes(fmt.sampleRate)) {
|
||||||
wav = undefined
|
input = await convert()
|
||||||
await convert()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wav ||= fs.readFileSync(filePath);
|
const silk = await encode(input, sampleRate);
|
||||||
const silk = await encode(wav, 0);
|
|
||||||
fs.writeFileSync(pttPath, silk.data);
|
fs.writeFileSync(pttPath, silk.data);
|
||||||
fs.unlink(wavPath, (err) => {
|
|
||||||
});
|
|
||||||
// const gDuration = await guessDuration(pttPath)
|
|
||||||
log(`语音文件${filePath}转换成功!`, pttPath, `时长:`, silk.duration)
|
log(`语音文件${filePath}转换成功!`, pttPath, `时长:`, silk.duration)
|
||||||
return {
|
return {
|
||||||
converted: true,
|
converted: true,
|
||||||
@@ -127,7 +121,7 @@ export async function encodeSilk(filePath: string) {
|
|||||||
return {
|
return {
|
||||||
converted: false,
|
converted: false,
|
||||||
path: filePath,
|
path: filePath,
|
||||||
duration: duration,
|
duration,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@@ -34,7 +34,7 @@ import {
|
|||||||
GroupNotifyTypes,
|
GroupNotifyTypes,
|
||||||
RawMessage
|
RawMessage
|
||||||
} from "../ntqqapi/types";
|
} from "../ntqqapi/types";
|
||||||
import {ob11HTTPServer} from "../onebot11/server/http";
|
import {httpHeart, ob11HTTPServer} from "../onebot11/server/http";
|
||||||
import {OB11FriendRecallNoticeEvent} from "../onebot11/event/notice/OB11FriendRecallNoticeEvent";
|
import {OB11FriendRecallNoticeEvent} from "../onebot11/event/notice/OB11FriendRecallNoticeEvent";
|
||||||
import {OB11GroupRecallNoticeEvent} from "../onebot11/event/notice/OB11GroupRecallNoticeEvent";
|
import {OB11GroupRecallNoticeEvent} from "../onebot11/event/notice/OB11GroupRecallNoticeEvent";
|
||||||
import {postOB11Event} from "../onebot11/server/postOB11Event";
|
import {postOB11Event} from "../onebot11/server/postOB11Event";
|
||||||
@@ -47,7 +47,7 @@ import {dbUtil} from "../common/db";
|
|||||||
import {setConfig} from "./setConfig";
|
import {setConfig} from "./setConfig";
|
||||||
import {NTQQUserApi} from "../ntqqapi/api/user";
|
import {NTQQUserApi} from "../ntqqapi/api/user";
|
||||||
import {NTQQGroupApi} from "../ntqqapi/api/group";
|
import {NTQQGroupApi} from "../ntqqapi/api/group";
|
||||||
import {registerPokeHandler} from "../ntqqapi/external/ccpoke";
|
import {crychic} from "../ntqqapi/external/crychic";
|
||||||
import {OB11FriendPokeEvent, OB11GroupPokeEvent} from "../onebot11/event/notice/OB11PokeEvent";
|
import {OB11FriendPokeEvent, OB11GroupPokeEvent} from "../onebot11/event/notice/OB11PokeEvent";
|
||||||
import {checkNewVersion, upgradeLLOneBot} from "../common/utils/upgrade";
|
import {checkNewVersion, upgradeLLOneBot} from "../common/utils/upgrade";
|
||||||
import {log} from "../common/utils/log";
|
import {log} from "../common/utils/log";
|
||||||
@@ -108,6 +108,7 @@ function onLoad() {
|
|||||||
let error = `${otherError}\n${httpServerError}\n${wsServerError}\n${ffmpegError}`
|
let error = `${otherError}\n${httpServerError}\n${wsServerError}\n${ffmpegError}`
|
||||||
error = error.replace("\n\n", "\n")
|
error = error.replace("\n\n", "\n")
|
||||||
error = error.trim();
|
error = error.trim();
|
||||||
|
log("查询llonebot错误信息", error);
|
||||||
return error;
|
return error;
|
||||||
})
|
})
|
||||||
ipcMain.handle(CHANNEL_GET_CONFIG, async (event, arg) => {
|
ipcMain.handle(CHANNEL_GET_CONFIG, async (event, arg) => {
|
||||||
@@ -116,7 +117,9 @@ function onLoad() {
|
|||||||
})
|
})
|
||||||
ipcMain.on(CHANNEL_SET_CONFIG, (event, ask: boolean, config: Config) => {
|
ipcMain.on(CHANNEL_SET_CONFIG, (event, ask: boolean, config: Config) => {
|
||||||
if (!ask) {
|
if (!ask) {
|
||||||
setConfig(config).then();
|
setConfig(config).then().catch(e => {
|
||||||
|
log("保存设置失败", e.stack)
|
||||||
|
});
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dialog.showMessageBox(mainWindow, {
|
dialog.showMessageBox(mainWindow, {
|
||||||
@@ -128,7 +131,9 @@ function onLoad() {
|
|||||||
detail: 'LLOneBot配置已更改,是否保存?'
|
detail: 'LLOneBot配置已更改,是否保存?'
|
||||||
}).then(result => {
|
}).then(result => {
|
||||||
if (result.response === 0) {
|
if (result.response === 0) {
|
||||||
setConfig(config).then();
|
setConfig(config).then().catch(e => {
|
||||||
|
log("保存设置失败", e.stack)
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
@@ -143,7 +148,10 @@ function onLoad() {
|
|||||||
async function postReceiveMsg(msgList: RawMessage[]) {
|
async function postReceiveMsg(msgList: RawMessage[]) {
|
||||||
const {debug, reportSelfMessage} = getConfigUtil().getConfig();
|
const {debug, reportSelfMessage} = getConfigUtil().getConfig();
|
||||||
for (let message of msgList) {
|
for (let message of msgList) {
|
||||||
|
// 过滤启动之前的消息
|
||||||
|
if (parseInt(message.msgTime) < startTime / 1000) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// log("收到新消息", message.msgId, message.msgSeq)
|
// log("收到新消息", message.msgId, message.msgSeq)
|
||||||
// if (message.senderUin !== selfInfo.uin){
|
// if (message.senderUin !== selfInfo.uin){
|
||||||
message.msgShortId = await dbUtil.addMsg(message);
|
message.msgShortId = await dbUtil.addMsg(message);
|
||||||
@@ -178,7 +186,8 @@ function onLoad() {
|
|||||||
|
|
||||||
async function startReceiveHook() {
|
async function startReceiveHook() {
|
||||||
if (getConfigUtil().getConfig().enablePoke) {
|
if (getConfigUtil().getConfig().enablePoke) {
|
||||||
registerPokeHandler((id, isGroup) => {
|
crychic.loadNode()
|
||||||
|
crychic.registerPokeHandler((id, isGroup) => {
|
||||||
log(`收到戳一戳消息了!是否群聊:${isGroup},id:${id}`)
|
log(`收到戳一戳消息了!是否群聊:${isGroup},id:${id}`)
|
||||||
let pokeEvent: OB11FriendPokeEvent | OB11GroupPokeEvent;
|
let pokeEvent: OB11FriendPokeEvent | OB11GroupPokeEvent;
|
||||||
if (isGroup) {
|
if (isGroup) {
|
||||||
@@ -354,8 +363,9 @@ function onLoad() {
|
|||||||
|
|
||||||
registerReceiveHook<FriendRequestNotify>(ReceiveCmdS.FRIEND_REQUEST, async (payload) => {
|
registerReceiveHook<FriendRequestNotify>(ReceiveCmdS.FRIEND_REQUEST, async (payload) => {
|
||||||
for (const req of payload.data.buddyReqs) {
|
for (const req of payload.data.buddyReqs) {
|
||||||
if (req.isUnread && !friendRequests[req.sourceId] && (parseInt(req.reqTime) > startTime / 1000)) {
|
let flag = req.friendUid + req.reqTime;
|
||||||
friendRequests[req.sourceId] = req;
|
if (req.isUnread && (parseInt(req.reqTime) > startTime / 1000)) {
|
||||||
|
friendRequests[flag] = req;
|
||||||
log("有新的好友请求", req);
|
log("有新的好友请求", req);
|
||||||
let friendRequestEvent = new OB11FriendRequestEvent();
|
let friendRequestEvent = new OB11FriendRequestEvent();
|
||||||
try {
|
try {
|
||||||
@@ -364,7 +374,7 @@ function onLoad() {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
log("获取加好友者QQ号失败", e);
|
log("获取加好友者QQ号失败", e);
|
||||||
}
|
}
|
||||||
friendRequestEvent.flag = req.sourceId.toString();
|
friendRequestEvent.flag = flag;
|
||||||
friendRequestEvent.comment = req.extWords;
|
friendRequestEvent.comment = req.extWords;
|
||||||
postOB11Event(friendRequestEvent);
|
postOB11Event(friendRequestEvent);
|
||||||
}
|
}
|
||||||
@@ -372,7 +382,7 @@ function onLoad() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
let startTime = 0;
|
let startTime = 0; // 毫秒
|
||||||
|
|
||||||
async function start() {
|
async function start() {
|
||||||
log("llonebot pid", process.pid)
|
log("llonebot pid", process.pid)
|
||||||
@@ -395,6 +405,9 @@ function onLoad() {
|
|||||||
if (config.ob11.enableWsReverse) {
|
if (config.ob11.enableWsReverse) {
|
||||||
ob11ReverseWebsockets.start();
|
ob11ReverseWebsockets.start();
|
||||||
}
|
}
|
||||||
|
if (config.ob11.enableHttpHeart){
|
||||||
|
httpHeart.start();
|
||||||
|
}
|
||||||
|
|
||||||
log("LLOneBot start")
|
log("LLOneBot start")
|
||||||
}
|
}
|
||||||
|
@@ -1,13 +1,13 @@
|
|||||||
import {Config} from "../common/types";
|
import {Config} from "../common/types";
|
||||||
import {ob11HTTPServer} from "../onebot11/server/http";
|
import {httpHeart, ob11HTTPServer} from "../onebot11/server/http";
|
||||||
import {ob11WebsocketServer} from "../onebot11/server/ws/WebsocketServer";
|
import {ob11WebsocketServer} from "../onebot11/server/ws/WebsocketServer";
|
||||||
import {ob11ReverseWebsockets} from "../onebot11/server/ws/ReverseWebsocket";
|
import {ob11ReverseWebsockets} from "../onebot11/server/ws/ReverseWebsocket";
|
||||||
import {llonebotError} from "../common/data";
|
import {llonebotError} from "../common/data";
|
||||||
import {getConfigUtil} from "../common/config";
|
import {getConfigUtil} from "../common/config";
|
||||||
import {checkFfmpeg} from "../common/utils";
|
import {checkFfmpeg, log} from "../common/utils";
|
||||||
|
|
||||||
export async function setConfig(config: Config) {
|
export async function setConfig(config: Config) {
|
||||||
let oldConfig = getConfigUtil().getConfig();
|
let oldConfig = {...(getConfigUtil().getConfig())};
|
||||||
getConfigUtil().setConfig(config)
|
getConfigUtil().setConfig(config)
|
||||||
if (config.ob11.httpPort != oldConfig.ob11.httpPort && config.ob11.enableHttp) {
|
if (config.ob11.httpPort != oldConfig.ob11.httpPort && config.ob11.enableHttp) {
|
||||||
ob11HTTPServer.restart(config.ob11.httpPort);
|
ob11HTTPServer.restart(config.ob11.httpPort);
|
||||||
@@ -42,15 +42,27 @@ export async function setConfig(config: Config) {
|
|||||||
if (config.ob11.enableWsReverse) {
|
if (config.ob11.enableWsReverse) {
|
||||||
// 判断反向ws地址有变化
|
// 判断反向ws地址有变化
|
||||||
if (config.ob11.wsHosts.length != oldConfig.ob11.wsHosts.length) {
|
if (config.ob11.wsHosts.length != oldConfig.ob11.wsHosts.length) {
|
||||||
|
log("反向ws地址有变化, 重启反向ws服务")
|
||||||
ob11ReverseWebsockets.restart();
|
ob11ReverseWebsockets.restart();
|
||||||
} else {
|
} else {
|
||||||
for (const newHost of config.ob11.wsHosts) {
|
for (const newHost of config.ob11.wsHosts) {
|
||||||
if (!oldConfig.ob11.wsHosts.includes(newHost)) {
|
if (!oldConfig.ob11.wsHosts.includes(newHost)) {
|
||||||
|
log("反向ws地址有变化, 重启反向ws服务")
|
||||||
ob11ReverseWebsockets.restart();
|
ob11ReverseWebsockets.restart();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (config.ob11.enableHttpHeart){
|
||||||
|
// 启动http心跳
|
||||||
|
httpHeart.start();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
// 关闭http心跳
|
||||||
|
httpHeart.stop();
|
||||||
|
}
|
||||||
|
log("old config", oldConfig)
|
||||||
|
log("配置已更新", config)
|
||||||
checkFfmpeg(config.ffmpeg).then()
|
checkFfmpeg(config.ffmpeg).then()
|
||||||
}
|
}
|
@@ -37,10 +37,10 @@ export class NTQQFriendApi{
|
|||||||
}, null]
|
}, null]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
static async handleFriendRequest(sourceId: number, accept: boolean,) {
|
static async handleFriendRequest(flag: string, accept: boolean,) {
|
||||||
const request: FriendRequest = friendRequests[sourceId]
|
const request: FriendRequest = friendRequests[flag]
|
||||||
if (!request) {
|
if (!request) {
|
||||||
throw `sourceId ${sourceId}, 对应的好友请求不存在`
|
throw `flat: ${flag}, 对应的好友请求不存在`
|
||||||
}
|
}
|
||||||
const result = await callNTQQApi<GeneralCallResult>({
|
const result = await callNTQQApi<GeneralCallResult>({
|
||||||
methodName: NTQQApiMethod.HANDLE_FRIEND_REQUEST,
|
methodName: NTQQApiMethod.HANDLE_FRIEND_REQUEST,
|
||||||
@@ -54,7 +54,7 @@ export class NTQQFriendApi{
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
delete friendRequests[sourceId];
|
delete friendRequests[flag];
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import {ReceiveCmdS} from "../hook";
|
import {ReceiveCmdS} from "../hook";
|
||||||
import {Group, GroupMember, GroupMemberRole, GroupNotifies, GroupNotify, GroupRequestOperateTypes} from "../types";
|
import {Group, GroupMember, GroupMemberRole, GroupNotifies, GroupNotify, GroupRequestOperateTypes} from "../types";
|
||||||
import {callNTQQApi, GeneralCallResult, NTQQApiClass, NTQQApiMethod} from "../ntcall";
|
import {callNTQQApi, GeneralCallResult, NTQQApiClass, NTQQApiMethod} from "../ntcall";
|
||||||
import {uidMaps} from "../../common/data";
|
import {deleteGroup, uidMaps} from "../../common/data";
|
||||||
import {dbUtil} from "../../common/db";
|
import {dbUtil} from "../../common/db";
|
||||||
import {log} from "../../common/utils/log";
|
import {log} from "../../common/utils/log";
|
||||||
import {NTQQWindowApi, NTQQWindows} from "./window";
|
import {NTQQWindowApi, NTQQWindows} from "./window";
|
||||||
@@ -102,13 +102,17 @@ export class NTQQGroupApi{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
static async quitGroup(groupQQ: string) {
|
static async quitGroup(groupQQ: string) {
|
||||||
await callNTQQApi<GeneralCallResult>({
|
const result = await callNTQQApi<GeneralCallResult>({
|
||||||
methodName: NTQQApiMethod.QUIT_GROUP,
|
methodName: NTQQApiMethod.QUIT_GROUP,
|
||||||
args: [
|
args: [
|
||||||
{"groupCode": groupQQ},
|
{"groupCode": groupQQ},
|
||||||
null
|
null
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
if (result.result === 0){
|
||||||
|
deleteGroup(groupQQ);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
static async kickMember(groupQQ: string, kickUids: string[], refuseForever: boolean = false, kickReason: string = '') {
|
static async kickMember(groupQQ: string, kickUids: string[], refuseForever: boolean = false, kickReason: string = '') {
|
||||||
return await callNTQQApi<GeneralCallResult>(
|
return await callNTQQApi<GeneralCallResult>(
|
||||||
@@ -186,6 +190,17 @@ export class NTQQGroupApi{
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async getGroupAtAllRemainCount(groupCode: string){
|
||||||
|
return await callNTQQApi<GeneralCallResult & {"atInfo":{"canAtAll": boolean,"RemainAtAllCountForUin": number,"RemainAtAllCountForGroup": number,"atTimesMsg": string,"canNotAtAllMsg":""}}>({
|
||||||
|
methodName: NTQQApiMethod.GROUP_AT_ALL_REMAIN_COUNT,
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
groupCode
|
||||||
|
}, null
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 头衔不可用
|
// 头衔不可用
|
||||||
static async setGroupTitle(groupQQ: string, uid: string, title: string) {
|
static async setGroupTitle(groupQQ: string, uid: string, title: string) {
|
||||||
return await callNTQQApi<GeneralCallResult>({
|
return await callNTQQApi<GeneralCallResult>({
|
||||||
|
@@ -27,17 +27,27 @@ export class NTQQMsgApi {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static async activateGroupChat(groupCode: string) {
|
static async activateChat(peer: Peer) {
|
||||||
// await this.fetchRecentContact();
|
// await this.fetchRecentContact();
|
||||||
// await sleep(500);
|
// await sleep(500);
|
||||||
return await callNTQQApi<GeneralCallResult>({
|
return await callNTQQApi<GeneralCallResult>({
|
||||||
methodName: NTQQApiMethod.ADD_ACTIVE_CHAT,
|
methodName: NTQQApiMethod.ACTIVE_CHAT_PREVIEW,
|
||||||
args: [{peer:{peerUid: groupCode, chatType: ChatType.group}, cnt: 20}, null]
|
args: [{peer, cnt: 20}, null]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
static async activateChatAndGetHistory(peer: Peer) {
|
||||||
|
// await this.fetchRecentContact();
|
||||||
|
// await sleep(500);
|
||||||
|
return await callNTQQApi<GeneralCallResult>({
|
||||||
|
methodName: NTQQApiMethod.ACTIVE_CHAT_HISTORY,
|
||||||
|
// 参数似乎不是这样
|
||||||
|
args: [{peer, cnt: 20}, null]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
static async getMsgHistory(peer: Peer, msgId: string, count: number) {
|
static async getMsgHistory(peer: Peer, msgId: string, count: number) {
|
||||||
|
// 消息时间从旧到新
|
||||||
return await callNTQQApi<GeneralCallResult & {msgList: RawMessage[]}>({
|
return await callNTQQApi<GeneralCallResult & {msgList: RawMessage[]}>({
|
||||||
methodName: isQQ998 ? NTQQApiMethod.HISTORY_MSG_998 : NTQQApiMethod.HISTORY_MSG,
|
methodName: isQQ998 ? NTQQApiMethod.ACTIVE_CHAT_HISTORY : NTQQApiMethod.HISTORY_MSG,
|
||||||
args: [{
|
args: [{
|
||||||
peer,
|
peer,
|
||||||
msgId,
|
msgId,
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
import {callNTQQApi, GeneralCallResult, NTQQApiClass, NTQQApiMethod} from "../ntcall";
|
import {callNTQQApi, GeneralCallResult, NTQQApiClass, NTQQApiMethod} from "../ntcall";
|
||||||
import {SelfInfo, User} from "../types";
|
import {Group, SelfInfo, User} from "../types";
|
||||||
import {ReceiveCmdS} from "../hook";
|
import {ReceiveCmdS} from "../hook";
|
||||||
import {uidMaps} from "../../common/data";
|
import {selfInfo, uidMaps} from "../../common/data";
|
||||||
import {NTQQWindowApi, NTQQWindows} from "./window";
|
import {NTQQWindowApi, NTQQWindows} from "./window";
|
||||||
import {isQQ998, sleep} from "../../common/utils";
|
import {isQQ998, log, sleep} from "../../common/utils";
|
||||||
|
|
||||||
let userInfoCache: Record<string, User> = {}; // uid: User
|
let userInfoCache: Record<string, User> = {}; // uid: User
|
||||||
|
|
||||||
@@ -68,7 +68,8 @@ export class NTQQUserApi{
|
|||||||
return userInfo
|
return userInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
static async getPSkey() {
|
// return 'p_uin=o0xxx; p_skey=orXDssiGF8axxxxxxxxxxxxxx_; skey='
|
||||||
|
static async getCookieWithoutSkey() {
|
||||||
return await callNTQQApi<string>({
|
return await callNTQQApi<string>({
|
||||||
className: NTQQApiClass.GROUP_HOME_WORK,
|
className: NTQQApiClass.GROUP_HOME_WORK,
|
||||||
methodName: NTQQApiMethod.UPDATE_SKEY,
|
methodName: NTQQApiMethod.UPDATE_SKEY,
|
||||||
@@ -114,4 +115,34 @@ export class NTQQUserApi{
|
|||||||
// })
|
// })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async getCookie(group: Group){
|
||||||
|
let cookies = await this.getCookieWithoutSkey();
|
||||||
|
let skey = ""
|
||||||
|
for (let i = 0; i < 2; i++) {
|
||||||
|
skey = (await this.getSkey(group.groupName, group.groupCode)).data;
|
||||||
|
skey = skey.trim();
|
||||||
|
if (skey) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
await sleep(1000);
|
||||||
|
}
|
||||||
|
if (!skey) {
|
||||||
|
throw new Error("获取skey失败");
|
||||||
|
}
|
||||||
|
const bkn = NTQQUserApi.genBkn(skey);
|
||||||
|
cookies = cookies.replace("skey=;", `skey=${skey};`);
|
||||||
|
return {cookies, bkn};
|
||||||
|
}
|
||||||
|
|
||||||
|
static genBkn(sKey: string){
|
||||||
|
sKey = sKey || "";
|
||||||
|
let hash = 5381;
|
||||||
|
|
||||||
|
for (let i = 0; i < sKey.length; i++) {
|
||||||
|
const code = sKey.charCodeAt(i);
|
||||||
|
hash = hash + (hash << 5) + code;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (hash & 0x7FFFFFFF).toString();
|
||||||
|
}
|
||||||
}
|
}
|
@@ -29,22 +29,14 @@ export class WebApi{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private genBkn(sKey: string){
|
private genBkn(sKey: string){
|
||||||
sKey = sKey || "";
|
return NTQQUserApi.genBkn(sKey);
|
||||||
let hash = 5381;
|
|
||||||
|
|
||||||
for (let i = 0; i < sKey.length; i++) {
|
|
||||||
const code = sKey.charCodeAt(i);
|
|
||||||
hash = hash + (hash << 5) + code;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (hash & 0x7FFFFFFF).toString();
|
|
||||||
}
|
}
|
||||||
private async init(){
|
private async init(){
|
||||||
if (!WebApi.bkn) {
|
if (!WebApi.bkn) {
|
||||||
const group = groups[0];
|
const group = groups[0];
|
||||||
WebApi.skey = (await NTQQUserApi.getSkey(group.groupName, group.groupCode)).data;
|
WebApi.skey = (await NTQQUserApi.getSkey(group.groupName, group.groupCode)).data;
|
||||||
WebApi.bkn = this.genBkn(WebApi.skey);
|
WebApi.bkn = this.genBkn(WebApi.skey);
|
||||||
let cookie = await NTQQUserApi.getPSkey();
|
let cookie = await NTQQUserApi.getCookieWithoutSkey();
|
||||||
const pskeyRegex = /p_skey=([^;]+)/;
|
const pskeyRegex = /p_skey=([^;]+)/;
|
||||||
const match = cookie.match(pskeyRegex);
|
const match = cookie.match(pskeyRegex);
|
||||||
const pskeyValue = match ? match[1] : null;
|
const pskeyValue = match ? match[1] : null;
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
AtType,
|
AtType,
|
||||||
ElementType,
|
ElementType, FaceIndex,
|
||||||
|
FaceType,
|
||||||
PicType,
|
PicType,
|
||||||
SendArkElement,
|
SendArkElement,
|
||||||
SendFaceElement,
|
SendFaceElement,
|
||||||
@@ -18,9 +19,15 @@ import {calculateFileMD5, isGIF} from "../common/utils/file";
|
|||||||
import {log} from "../common/utils/log";
|
import {log} from "../common/utils/log";
|
||||||
import {defaultVideoThumb, getVideoInfo} from "../common/utils/video";
|
import {defaultVideoThumb, getVideoInfo} from "../common/utils/video";
|
||||||
import {encodeSilk} from "../common/utils/audio";
|
import {encodeSilk} from "../common/utils/audio";
|
||||||
|
import {isNull} from "../common/utils";
|
||||||
|
|
||||||
|
|
||||||
export class SendMsgElementConstructor {
|
export class SendMsgElementConstructor {
|
||||||
|
|
||||||
|
static poke(groupCode: string, uin: string) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
static text(content: string): SendTextElement {
|
static text(content: string): SendTextElement {
|
||||||
return {
|
return {
|
||||||
elementType: ElementType.TEXT,
|
elementType: ElementType.TEXT,
|
||||||
@@ -62,8 +69,8 @@ export class SendMsgElementConstructor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async pic(picPath: string, summary: string = "", subType: 0|1=0): Promise<SendPicElement> {
|
static async pic(picPath: string, summary: string = "", subType: 0 | 1 = 0): Promise<SendPicElement> {
|
||||||
const {md5, fileName, path, fileSize, ext} = await NTQQFileApi.uploadFile(picPath, ElementType.PIC, subType);
|
const {md5, fileName, path, fileSize} = await NTQQFileApi.uploadFile(picPath, ElementType.PIC, subType);
|
||||||
if (fileSize === 0) {
|
if (fileSize === 0) {
|
||||||
throw "文件异常,大小为0";
|
throw "文件异常,大小为0";
|
||||||
}
|
}
|
||||||
@@ -73,7 +80,7 @@ export class SendMsgElementConstructor {
|
|||||||
fileSize: fileSize.toString(),
|
fileSize: fileSize.toString(),
|
||||||
picWidth: imageSize.width,
|
picWidth: imageSize.width,
|
||||||
picHeight: imageSize.height,
|
picHeight: imageSize.height,
|
||||||
fileName: md5 + ext,
|
fileName: fileName,
|
||||||
sourcePath: path,
|
sourcePath: path,
|
||||||
original: true,
|
original: true,
|
||||||
picType: isGIF(picPath) ? PicType.gif : PicType.jpg,
|
picType: isGIF(picPath) ? PicType.gif : PicType.jpg,
|
||||||
@@ -115,8 +122,8 @@ export class SendMsgElementConstructor {
|
|||||||
throw "文件异常,大小为0";
|
throw "文件异常,大小为0";
|
||||||
}
|
}
|
||||||
const pathLib = require("path");
|
const pathLib = require("path");
|
||||||
let thumb = path.replace(`${pathLib.sep}Ori${pathLib.sep}`, `${pathLib.sep}Thumb${pathLib.sep}`)
|
let thumbDir = path.replace(`${pathLib.sep}Ori${pathLib.sep}`, `${pathLib.sep}Thumb${pathLib.sep}`)
|
||||||
thumb = pathLib.dirname(thumb)
|
thumbDir = pathLib.dirname(thumbDir)
|
||||||
// log("thumb 目录", thumb)
|
// log("thumb 目录", thumb)
|
||||||
let videoInfo = {
|
let videoInfo = {
|
||||||
width: 1920, height: 1080,
|
width: 1920, height: 1080,
|
||||||
@@ -133,33 +140,46 @@ export class SendMsgElementConstructor {
|
|||||||
}
|
}
|
||||||
const createThumb = new Promise<string>((resolve, reject) => {
|
const createThumb = new Promise<string>((resolve, reject) => {
|
||||||
const thumbFileName = `${md5}_0.png`
|
const thumbFileName = `${md5}_0.png`
|
||||||
const thumbPath = pathLib.join(thumb, thumbFileName)
|
const thumbPath = pathLib.join(thumbDir, thumbFileName)
|
||||||
|
log("开始生成视频缩略图", filePath);
|
||||||
|
let completed = false;
|
||||||
|
|
||||||
|
function useDefaultThumb() {
|
||||||
|
if (completed) return;
|
||||||
|
log("获取视频封面失败,使用默认封面");
|
||||||
|
fs.writeFile(thumbPath, defaultVideoThumb).then(() => {
|
||||||
|
resolve(thumbPath);
|
||||||
|
}).catch(reject)
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(useDefaultThumb, 5000);
|
||||||
ffmpeg(filePath)
|
ffmpeg(filePath)
|
||||||
.on("end", () => {
|
.on("end", () => {
|
||||||
})
|
})
|
||||||
.on("error", (err) => {
|
.on("error", (err) => {
|
||||||
log("获取视频封面失败,使用默认封面", err)
|
|
||||||
if (diyThumbPath) {
|
if (diyThumbPath) {
|
||||||
fs.copyFile(diyThumbPath, thumbPath).then(() => {
|
fs.copyFile(diyThumbPath, thumbPath).then(() => {
|
||||||
|
completed = true;
|
||||||
resolve(thumbPath);
|
resolve(thumbPath);
|
||||||
}).catch(reject)
|
}).catch(reject)
|
||||||
} else {
|
} else {
|
||||||
fs.writeFile(thumbPath, defaultVideoThumb).then(() => {
|
useDefaultThumb()
|
||||||
resolve(thumbPath);
|
|
||||||
}).catch(reject)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.screenshots({
|
.screenshots({
|
||||||
timestamps: [0],
|
timestamps: [0],
|
||||||
filename: thumbFileName,
|
filename: thumbFileName,
|
||||||
folder: thumb,
|
folder: thumbDir,
|
||||||
size: videoInfo.width + "x" + videoInfo.height
|
size: videoInfo.width + "x" + videoInfo.height
|
||||||
}).on("end", () => {
|
}).on("end", () => {
|
||||||
|
log("生成视频缩略图", thumbPath)
|
||||||
|
completed = true;
|
||||||
resolve(thumbPath);
|
resolve(thumbPath);
|
||||||
});
|
})
|
||||||
})
|
})
|
||||||
let thumbPath = new Map()
|
let thumbPath = new Map()
|
||||||
const _thumbPath = await createThumb;
|
const _thumbPath = await createThumb;
|
||||||
|
log("生成缩略图", _thumbPath)
|
||||||
const thumbSize = (await fs.stat(_thumbPath)).size;
|
const thumbSize = (await fs.stat(_thumbPath)).size;
|
||||||
// log("生成缩略图", _thumbPath)
|
// log("生成缩略图", _thumbPath)
|
||||||
thumbPath.set(0, _thumbPath)
|
thumbPath.set(0, _thumbPath)
|
||||||
@@ -190,6 +210,7 @@ export class SendMsgElementConstructor {
|
|||||||
// sourceVideoCodecFormat: 2
|
// sourceVideoCodecFormat: 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
log("videoElement", element)
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,12 +249,58 @@ export class SendMsgElementConstructor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static face(faceId: number): SendFaceElement {
|
static face(faceId: number): SendFaceElement {
|
||||||
|
faceId = parseInt(faceId.toString());
|
||||||
return {
|
return {
|
||||||
elementType: ElementType.FACE,
|
elementType: ElementType.FACE,
|
||||||
elementId: "",
|
elementId: "",
|
||||||
faceElement: {
|
faceElement: {
|
||||||
faceIndex: faceId,
|
faceIndex: faceId,
|
||||||
faceType: 1
|
faceType: faceId < 222 ? FaceType.normal : FaceType.normal2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static dice(resultId: number | null): SendFaceElement {
|
||||||
|
// 实际测试并不能控制结果
|
||||||
|
|
||||||
|
// 随机1到6
|
||||||
|
if (isNull(resultId)) resultId = Math.floor(Math.random() * 6) + 1;
|
||||||
|
return {
|
||||||
|
elementType: ElementType.FACE,
|
||||||
|
elementId: "",
|
||||||
|
faceElement: {
|
||||||
|
faceIndex: FaceIndex.dice,
|
||||||
|
faceType: FaceType.dice,
|
||||||
|
"faceText": "[骰子]",
|
||||||
|
"packId": "1",
|
||||||
|
"stickerId": "33",
|
||||||
|
"sourceType": 1,
|
||||||
|
"stickerType": 2,
|
||||||
|
resultId: resultId.toString(),
|
||||||
|
"surpriseId": "",
|
||||||
|
// "randomType": 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 猜拳(石头剪刀布)表情
|
||||||
|
static rps(resultId: number | null): SendFaceElement {
|
||||||
|
// 实际测试并不能控制结果
|
||||||
|
if (isNull(resultId)) resultId = Math.floor(Math.random() * 3) + 1;
|
||||||
|
return {
|
||||||
|
elementType: ElementType.FACE,
|
||||||
|
elementId: "",
|
||||||
|
faceElement: {
|
||||||
|
"faceIndex": FaceIndex.RPS,
|
||||||
|
"faceText": "[包剪锤]",
|
||||||
|
"faceType": 3,
|
||||||
|
"packId": "1",
|
||||||
|
"stickerId": "34",
|
||||||
|
"sourceType": 1,
|
||||||
|
"stickerType": 2,
|
||||||
|
"resultId": resultId.toString(),
|
||||||
|
"surpriseId": "",
|
||||||
|
// "randomType": 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
28
src/ntqqapi/external/ccpoke/index.ts
vendored
28
src/ntqqapi/external/ccpoke/index.ts
vendored
@@ -1,28 +0,0 @@
|
|||||||
import {log} from "../../../common/utils/log";
|
|
||||||
|
|
||||||
let pokeEngine: any = null
|
|
||||||
|
|
||||||
type PokeHandler = (id: string, isGroup: boolean)=>void
|
|
||||||
|
|
||||||
let pokeRecords: Record<string, number> = {}
|
|
||||||
export function registerPokeHandler(handler: PokeHandler){
|
|
||||||
if(!pokeEngine){
|
|
||||||
try {
|
|
||||||
pokeEngine = require("./ccpoke/poke-win32-x64.node")
|
|
||||||
pokeEngine.performHooks();
|
|
||||||
}catch (e) {
|
|
||||||
log("戳一戳引擎加载失败", e)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pokeEngine.setHandlerForPokeHook((id: string, isGroup: boolean)=>{
|
|
||||||
let existTime = pokeRecords[id]
|
|
||||||
if (existTime){
|
|
||||||
if (Date.now() - existTime < 1500){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pokeRecords[id] = Date.now()
|
|
||||||
handler(id, isGroup);
|
|
||||||
})
|
|
||||||
}
|
|
BIN
src/ntqqapi/external/ccpoke/poke-win32-x64.node
vendored
BIN
src/ntqqapi/external/ccpoke/poke-win32-x64.node
vendored
Binary file not shown.
BIN
src/ntqqapi/external/crychic/crychic-win32-x64.node
vendored
Normal file
BIN
src/ntqqapi/external/crychic/crychic-win32-x64.node
vendored
Normal file
Binary file not shown.
53
src/ntqqapi/external/crychic/index.ts
vendored
Normal file
53
src/ntqqapi/external/crychic/index.ts
vendored
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import {log} from "../../../common/utils";
|
||||||
|
import {NTQQApi} from "../../ntcall";
|
||||||
|
|
||||||
|
type PokeHandler = (id: string, isGroup: boolean) => void
|
||||||
|
type CrychicHandler = (event: string, id: string, isGroup: boolean) => void
|
||||||
|
|
||||||
|
let pokeRecords: Record<string, number> = {}
|
||||||
|
|
||||||
|
class Crychic{
|
||||||
|
private crychic: any = undefined
|
||||||
|
|
||||||
|
loadNode(){
|
||||||
|
if (!this.crychic){
|
||||||
|
try {
|
||||||
|
this.crychic = require("./crychic-win32-x64.node")
|
||||||
|
this.crychic.init()
|
||||||
|
}catch (e) {
|
||||||
|
log("crychic加载失败", e)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
registerPokeHandler(fn: PokeHandler){
|
||||||
|
this.registerHandler((event, id, isGroup)=>{
|
||||||
|
if (event === "poke"){
|
||||||
|
let existTime = pokeRecords[id]
|
||||||
|
if (existTime) {
|
||||||
|
if (Date.now() - existTime < 1500) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pokeRecords[id] = Date.now()
|
||||||
|
fn(id, isGroup);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
registerHandler(fn: CrychicHandler){
|
||||||
|
if (!this.crychic) return;
|
||||||
|
this.crychic.setCryHandler(fn)
|
||||||
|
}
|
||||||
|
sendFriendPoke(friendUid: string){
|
||||||
|
if (!this.crychic) return;
|
||||||
|
this.crychic.sendFriendPoke(parseInt(friendUid))
|
||||||
|
NTQQApi.fetchUnitedCommendConfig().then()
|
||||||
|
}
|
||||||
|
sendGroupPoke(groupCode: string, memberUin: string){
|
||||||
|
if (!this.crychic) return;
|
||||||
|
this.crychic.sendGroupPoke(parseInt(memberUin), parseInt(groupCode))
|
||||||
|
NTQQApi.fetchUnitedCommendConfig().then()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const crychic = new Crychic()
|
@@ -1,8 +1,17 @@
|
|||||||
import {BrowserWindow} from 'electron';
|
import {BrowserWindow} from 'electron';
|
||||||
import {NTQQApiClass} from "./ntcall";
|
import {NTQQApiClass, NTQQApiMethod} from "./ntcall";
|
||||||
import {NTQQMsgApi, sendMessagePool} from "./api/msg"
|
import {NTQQMsgApi, sendMessagePool} from "./api/msg"
|
||||||
import {ChatType, Group, GroupMember, GroupMemberRole, RawMessage, User} from "./types";
|
import {ChatType, Group, GroupMember, GroupMemberRole, RawMessage, User} from "./types";
|
||||||
import {friends, getGroupMember, groups, selfInfo, tempGroupCodeMap, uidMaps} from "../common/data";
|
import {
|
||||||
|
deleteGroup,
|
||||||
|
friends,
|
||||||
|
getFriend,
|
||||||
|
getGroupMember,
|
||||||
|
groups,
|
||||||
|
selfInfo,
|
||||||
|
tempGroupCodeMap,
|
||||||
|
uidMaps
|
||||||
|
} from "../common/data";
|
||||||
import {OB11GroupDecreaseEvent} from "../onebot11/event/notice/OB11GroupDecreaseEvent";
|
import {OB11GroupDecreaseEvent} from "../onebot11/event/notice/OB11GroupDecreaseEvent";
|
||||||
import {v4 as uuidv4} from "uuid"
|
import {v4 as uuidv4} from "uuid"
|
||||||
import {postOB11Event} from "../onebot11/server/postOB11Event";
|
import {postOB11Event} from "../onebot11/server/postOB11Event";
|
||||||
@@ -11,11 +20,13 @@ import fs from "fs";
|
|||||||
import {dbUtil} from "../common/db";
|
import {dbUtil} from "../common/db";
|
||||||
import {NTQQGroupApi} from "./api/group";
|
import {NTQQGroupApi} from "./api/group";
|
||||||
import {log} from "../common/utils/log";
|
import {log} from "../common/utils/log";
|
||||||
import {sleep} from "../common/utils/helper";
|
import {isNumeric, sleep} from "../common/utils/helper";
|
||||||
|
import {OB11Constructor} from "../onebot11/constructor";
|
||||||
|
|
||||||
export let hookApiCallbacks: Record<string, (apiReturn: any) => void> = {}
|
export let hookApiCallbacks: Record<string, (apiReturn: any) => void> = {}
|
||||||
|
|
||||||
export let ReceiveCmdS = {
|
export let ReceiveCmdS = {
|
||||||
|
RECENT_CONTACT: "nodeIKernelRecentContactListener/onRecentContactListChangedVer2",
|
||||||
UPDATE_MSG: "nodeIKernelMsgListener/onMsgInfoListUpdate",
|
UPDATE_MSG: "nodeIKernelMsgListener/onMsgInfoListUpdate",
|
||||||
UPDATE_ACTIVE_MSG: "nodeIKernelMsgListener/onActiveMsgInfoUpdate",
|
UPDATE_ACTIVE_MSG: "nodeIKernelMsgListener/onActiveMsgInfoUpdate",
|
||||||
NEW_MSG: `nodeIKernelMsgListener/onRecvMsg`,
|
NEW_MSG: `nodeIKernelMsgListener/onRecvMsg`,
|
||||||
@@ -59,6 +70,12 @@ let receiveHooks: Array<{
|
|||||||
id: string
|
id: string
|
||||||
}> = []
|
}> = []
|
||||||
|
|
||||||
|
let callHooks: Array<{
|
||||||
|
method: NTQQApiMethod[],
|
||||||
|
hookFunc: ((callParams: unknown[]) => void | Promise<void>)
|
||||||
|
}> = []
|
||||||
|
|
||||||
|
|
||||||
export function hookNTQQApiReceive(window: BrowserWindow) {
|
export function hookNTQQApiReceive(window: BrowserWindow) {
|
||||||
const originalSend = window.webContents.send;
|
const originalSend = window.webContents.send;
|
||||||
const patchSend = (channel: string, ...args: NTQQApiReturnData) => {
|
const patchSend = (channel: string, ...args: NTQQApiReturnData) => {
|
||||||
@@ -72,7 +89,7 @@ export function hookNTQQApiReceive(window: BrowserWindow) {
|
|||||||
if (!isLogger) {
|
if (!isLogger) {
|
||||||
try {
|
try {
|
||||||
HOOK_LOG && log(`received ntqq api message: ${channel}`, args)
|
HOOK_LOG && log(`received ntqq api message: ${channel}`, args)
|
||||||
}catch (e) {
|
} catch (e) {
|
||||||
log("hook log error", e, args)
|
log("hook log error", e, args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,7 +125,7 @@ export function hookNTQQApiReceive(window: BrowserWindow) {
|
|||||||
delete hookApiCallbacks[callbackId];
|
delete hookApiCallbacks[callbackId];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}catch (e) {
|
} catch (e) {
|
||||||
log("hookNTQQApiReceive error", e.stack.toString(), args)
|
log("hookNTQQApiReceive error", e.stack.toString(), args)
|
||||||
}
|
}
|
||||||
originalSend.call(window.webContents, channel, ...args);
|
originalSend.call(window.webContents, channel, ...args);
|
||||||
@@ -131,9 +148,30 @@ export function hookNTQQApiCall(window: BrowserWindow) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
if (!isLogger) {
|
if (!isLogger) {
|
||||||
try{
|
try {
|
||||||
HOOK_LOG && log("call NTQQ api", thisArg, args);
|
HOOK_LOG && log("call NTQQ api", thisArg, args);
|
||||||
}catch (e) {
|
} catch (e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const _args: unknown[] = args[3][1];
|
||||||
|
const cmdName: NTQQApiMethod = _args[0] as NTQQApiMethod;
|
||||||
|
const callParams = _args.slice(1);
|
||||||
|
callHooks.forEach(hook => {
|
||||||
|
if (hook.method.includes(cmdName)) {
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
let _ = hook.hookFunc(callParams)
|
||||||
|
if (hook.hookFunc.constructor.name === "AsyncFunction") {
|
||||||
|
(_ as Promise<void>).then()
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
log("hook call error", e, _args)
|
||||||
|
}
|
||||||
|
}).then()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,7 +197,7 @@ export function hookNTQQApiCall(window: BrowserWindow) {
|
|||||||
let ret = target.apply(thisArg, args);
|
let ret = target.apply(thisArg, args);
|
||||||
try {
|
try {
|
||||||
HOOK_LOG && log("call NTQQ invoke api return", ret)
|
HOOK_LOG && log("call NTQQ invoke api return", ret)
|
||||||
}catch (e) {
|
} catch (e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@@ -185,25 +223,41 @@ export function registerReceiveHook<PayloadType>(method: ReceiveCmd | ReceiveCmd
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function registerCallHook(method: NTQQApiMethod | NTQQApiMethod[], hookFunc: (callParams: unknown[]) => void | Promise<void>): void {
|
||||||
|
if (!Array.isArray(method)) {
|
||||||
|
method = [method]
|
||||||
|
}
|
||||||
|
callHooks.push({
|
||||||
|
method,
|
||||||
|
hookFunc
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export function removeReceiveHook(id: string) {
|
export function removeReceiveHook(id: string) {
|
||||||
const index = receiveHooks.findIndex(h => h.id === id)
|
const index = receiveHooks.findIndex(h => h.id === id)
|
||||||
receiveHooks.splice(index, 1);
|
receiveHooks.splice(index, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let activatedGroups: string[] = [];
|
let activatedGroups: string[] = [];
|
||||||
|
|
||||||
async function updateGroups(_groups: Group[], needUpdate: boolean = true) {
|
async function updateGroups(_groups: Group[], needUpdate: boolean = true) {
|
||||||
for (let group of _groups) {
|
for (let group of _groups) {
|
||||||
|
log("update group", group);
|
||||||
|
if (group.privilegeFlag === 0){
|
||||||
|
deleteGroup(group.groupCode);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
log("update group", group)
|
log("update group", group)
|
||||||
if (!activatedGroups.includes(group.groupCode)) {
|
// if (!activatedGroups.includes(group.groupCode)) {
|
||||||
NTQQMsgApi.activateGroupChat(group.groupCode).then((r) => {
|
NTQQMsgApi.activateChat({peerUid: group.groupCode, chatType: ChatType.group}).then((r) => {
|
||||||
activatedGroups.push(group.groupCode);
|
// activatedGroups.push(group.groupCode);
|
||||||
// log(`激活群聊天窗口${group.groupName}(${group.groupCode})`, r)
|
// log(`激活群聊天窗口${group.groupName}(${group.groupCode})`, r)
|
||||||
// if (r.result !== 0) {
|
// if (r.result !== 0) {
|
||||||
// setTimeout(() => NTQQMsgApi.activateGroupChat(group.groupCode).then(r => log(`再次激活群聊天窗口${group.groupName}(${group.groupCode})`, r)), 500);
|
// setTimeout(() => NTQQMsgApi.activateGroupChat(group.groupCode).then(r => log(`再次激活群聊天窗口${group.groupName}(${group.groupCode})`, r)), 500);
|
||||||
// }else {
|
// }else {
|
||||||
// }
|
// }
|
||||||
}).catch(log)
|
}).catch(log)
|
||||||
}
|
// }
|
||||||
let existGroup = groups.find(g => g.groupCode == group.groupCode);
|
let existGroup = groups.find(g => g.groupCode == group.groupCode);
|
||||||
if (existGroup) {
|
if (existGroup) {
|
||||||
Object.assign(existGroup, group);
|
Object.assign(existGroup, group);
|
||||||
@@ -222,7 +276,7 @@ async function updateGroups(_groups: Group[], needUpdate: boolean = true) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processGroupEvent(payload: {groupList: Group[]}) {
|
async function processGroupEvent(payload: { groupList: Group[] }) {
|
||||||
try {
|
try {
|
||||||
const newGroupList = payload.groupList;
|
const newGroupList = payload.groupList;
|
||||||
for (const group of newGroupList) {
|
for (const group of newGroupList) {
|
||||||
@@ -254,7 +308,9 @@ async function processGroupEvent(payload: {groupList: Group[]}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (group.privilegeFlag === 0){
|
||||||
|
deleteGroup(group.groupCode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,13 +345,17 @@ registerReceiveHook<{ groupList: Group[], updateType: number }>(ReceiveCmdS.GROU
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
registerReceiveHook<{groupCode: string, dataSource: number, members: Set<GroupMember>}>(ReceiveCmdS.GROUP_MEMBER_INFO_UPDATE, async (payload) => {
|
registerReceiveHook<{
|
||||||
|
groupCode: string,
|
||||||
|
dataSource: number,
|
||||||
|
members: Set<GroupMember>
|
||||||
|
}>(ReceiveCmdS.GROUP_MEMBER_INFO_UPDATE, async (payload) => {
|
||||||
const groupCode = payload.groupCode;
|
const groupCode = payload.groupCode;
|
||||||
const members = Array.from(payload.members.values());
|
const members = Array.from(payload.members.values());
|
||||||
// log("群成员信息变动", groupCode, members)
|
// log("群成员信息变动", groupCode, members)
|
||||||
for(const member of members) {
|
for (const member of members) {
|
||||||
const existMember = await getGroupMember(groupCode, member.uin);
|
const existMember = await getGroupMember(groupCode, member.uin);
|
||||||
if (existMember){
|
if (existMember) {
|
||||||
Object.assign(existMember, member);
|
Object.assign(existMember, member);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -322,6 +382,7 @@ registerReceiveHook<{
|
|||||||
for (const fData of payload.data) {
|
for (const fData of payload.data) {
|
||||||
const _friends = fData.buddyList;
|
const _friends = fData.buddyList;
|
||||||
for (let friend of _friends) {
|
for (let friend of _friends) {
|
||||||
|
NTQQMsgApi.activateChat({peerUid: friend.uid, chatType: ChatType.friend}).then()
|
||||||
let existFriend = friends.find(f => f.uin == friend.uin)
|
let existFriend = friends.find(f => f.uin == friend.uin)
|
||||||
if (!existFriend) {
|
if (!existFriend) {
|
||||||
friends.push(friend)
|
friends.push(friend)
|
||||||
@@ -338,9 +399,9 @@ registerReceiveHook<{ msgList: Array<RawMessage> }>([ReceiveCmdS.NEW_MSG, Receiv
|
|||||||
const uid = message.senderUid;
|
const uid = message.senderUid;
|
||||||
const uin = message.senderUin;
|
const uin = message.senderUin;
|
||||||
if (uid && uin) {
|
if (uid && uin) {
|
||||||
if (message.chatType === ChatType.temp){
|
if (message.chatType === ChatType.temp) {
|
||||||
dbUtil.getReceivedTempUinMap().then(receivedTempUinMap=>{
|
dbUtil.getReceivedTempUinMap().then(receivedTempUinMap => {
|
||||||
if (!receivedTempUinMap[uin]){
|
if (!receivedTempUinMap[uin]) {
|
||||||
receivedTempUinMap[uin] = uid;
|
receivedTempUinMap[uin] = uid;
|
||||||
dbUtil.setReceivedTempUinMap(receivedTempUinMap)
|
dbUtil.setReceivedTempUinMap(receivedTempUinMap)
|
||||||
}
|
}
|
||||||
@@ -410,3 +471,59 @@ registerReceiveHook<{ msgRecord: RawMessage }>(ReceiveCmdS.SELF_SEND_MSG, ({msgR
|
|||||||
registerReceiveHook<{ info: { status: number } }>(ReceiveCmdS.SELF_STATUS, (info) => {
|
registerReceiveHook<{ info: { status: number } }>(ReceiveCmdS.SELF_STATUS, (info) => {
|
||||||
selfInfo.online = info.info.status !== 20
|
selfInfo.online = info.info.status !== 20
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
let activatedPeerUids: string[] = []
|
||||||
|
registerReceiveHook<{
|
||||||
|
changedRecentContactLists: {
|
||||||
|
listType: number, sortedContactList: string[],
|
||||||
|
changedList: {
|
||||||
|
id: string, // peerUid
|
||||||
|
chatType: ChatType
|
||||||
|
}[]
|
||||||
|
}[]
|
||||||
|
}>(ReceiveCmdS.RECENT_CONTACT, async (payload) => {
|
||||||
|
for (const recentContact of payload.changedRecentContactLists) {
|
||||||
|
for (const changedContact of recentContact.changedList) {
|
||||||
|
if (activatedPeerUids.includes(changedContact.id)) continue;
|
||||||
|
activatedPeerUids.push(changedContact.id)
|
||||||
|
const peer = {peerUid: changedContact.id, chatType: changedContact.chatType}
|
||||||
|
if (changedContact.chatType === ChatType.temp) {
|
||||||
|
log("收到临时会话消息", peer)
|
||||||
|
NTQQMsgApi.activateChatAndGetHistory(peer).then(
|
||||||
|
() => {
|
||||||
|
NTQQMsgApi.getMsgHistory(peer, "", 20).then(({msgList}) => {
|
||||||
|
let lastTempMsg = msgList.pop()
|
||||||
|
log("激活窗口之前的第一条临时会话消息:", lastTempMsg)
|
||||||
|
if ((Date.now() / 1000) - parseInt(lastTempMsg.msgTime) < 5) {
|
||||||
|
OB11Constructor.message(lastTempMsg).then(r => postOB11Event(r))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
NTQQMsgApi.activateChat(peer).then()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
registerCallHook(NTQQApiMethod.DELETE_ACTIVE_CHAT, async (payload) => {
|
||||||
|
const peerUid = payload[0] as string;
|
||||||
|
log("激活的聊天窗口被删除,准备重新激活", peerUid);
|
||||||
|
let chatType = ChatType.friend;
|
||||||
|
if (isNumeric(peerUid)) {
|
||||||
|
chatType = ChatType.group;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
// 检查是否好友
|
||||||
|
if (!(await getFriend(peerUid))){
|
||||||
|
chatType = ChatType.temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const peer = {peerUid, chatType}
|
||||||
|
await sleep(1000);
|
||||||
|
NTQQMsgApi.activateChat(peer).then((r) => {
|
||||||
|
log("重新激活聊天窗口", peer, {result: r.result, errMsg: r.errMsg})
|
||||||
|
});
|
||||||
|
})
|
@@ -22,10 +22,11 @@ export enum NTQQApiClass {
|
|||||||
|
|
||||||
export enum NTQQApiMethod {
|
export enum NTQQApiMethod {
|
||||||
RECENT_CONTACT = "nodeIKernelRecentContactService/fetchAndSubscribeABatchOfRecentContact",
|
RECENT_CONTACT = "nodeIKernelRecentContactService/fetchAndSubscribeABatchOfRecentContact",
|
||||||
ADD_ACTIVE_CHAT = "nodeIKernelMsgService/getAioFirstViewLatestMsgsAndAddActiveChat", // 激活群助手内的聊天窗口,这样才能收到消息
|
ACTIVE_CHAT_PREVIEW = "nodeIKernelMsgService/getAioFirstViewLatestMsgsAndAddActiveChat", // 激活聊天窗口,有时候必须这样才能收到消息, 并返回最新预览消息
|
||||||
HISTORY_MSG_998 = "nodeIKernelMsgService/getMsgsIncludeSelfAndAddActiveChat",
|
ACTIVE_CHAT_HISTORY = "nodeIKernelMsgService/getMsgsIncludeSelfAndAddActiveChat", // 激活聊天窗口,有时候必须这样才能收到消息, 并返回历史消息
|
||||||
HISTORY_MSG = "nodeIKernelMsgService/getMsgsIncludeSelf",
|
HISTORY_MSG = "nodeIKernelMsgService/getMsgsIncludeSelf",
|
||||||
GET_MULTI_MSG = "nodeIKernelMsgService/getMultiMsg",
|
GET_MULTI_MSG = "nodeIKernelMsgService/getMultiMsg",
|
||||||
|
DELETE_ACTIVE_CHAT = "nodeIKernelMsgService/deleteActiveChatByUid",
|
||||||
|
|
||||||
LIKE_FRIEND = "nodeIKernelProfileLikeService/setBuddyProfileLike",
|
LIKE_FRIEND = "nodeIKernelProfileLikeService/setBuddyProfileLike",
|
||||||
SELF_INFO = "fetchAuthData",
|
SELF_INFO = "fetchAuthData",
|
||||||
@@ -50,6 +51,7 @@ export enum NTQQApiMethod {
|
|||||||
GET_GROUP_NOTICE = "nodeIKernelGroupService/getSingleScreenNotifies",
|
GET_GROUP_NOTICE = "nodeIKernelGroupService/getSingleScreenNotifies",
|
||||||
HANDLE_GROUP_REQUEST = "nodeIKernelGroupService/operateSysNotify",
|
HANDLE_GROUP_REQUEST = "nodeIKernelGroupService/operateSysNotify",
|
||||||
QUIT_GROUP = "nodeIKernelGroupService/quitGroup",
|
QUIT_GROUP = "nodeIKernelGroupService/quitGroup",
|
||||||
|
GROUP_AT_ALL_REMAIN_COUNT = "nodeIKernelGroupService/getGroupRemainAtTimes",
|
||||||
// READ_FRIEND_REQUEST = "nodeIKernelBuddyListener/onDoubtBuddyReqUnreadNumChange"
|
// READ_FRIEND_REQUEST = "nodeIKernelBuddyListener/onDoubtBuddyReqUnreadNumChange"
|
||||||
HANDLE_FRIEND_REQUEST = "nodeIKernelBuddyService/approvalFriendRequest",
|
HANDLE_FRIEND_REQUEST = "nodeIKernelBuddyService/approvalFriendRequest",
|
||||||
KICK_MEMBER = "nodeIKernelGroupService/kickMember",
|
KICK_MEMBER = "nodeIKernelGroupService/kickMember",
|
||||||
@@ -77,7 +79,9 @@ export enum NTQQApiMethod {
|
|||||||
|
|
||||||
SET_QQ_AVATAR = 'nodeIKernelProfileService/setHeader',
|
SET_QQ_AVATAR = 'nodeIKernelProfileService/setHeader',
|
||||||
GET_SKEY = "nodeIKernelTipOffService/getPskey",
|
GET_SKEY = "nodeIKernelTipOffService/getPskey",
|
||||||
UPDATE_SKEY = "updatePskey"
|
UPDATE_SKEY = "updatePskey",
|
||||||
|
|
||||||
|
FETCH_UNITED_COMMEND_CONFIG = "nodeIKernelUnitedConfigService/fetchUnitedCommendConfig" // 发包需要调用的
|
||||||
}
|
}
|
||||||
|
|
||||||
enum NTQQApiChannel {
|
enum NTQQApiChannel {
|
||||||
@@ -194,4 +198,15 @@ export class NTQQApi {
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async fetchUnitedCommendConfig() {
|
||||||
|
return await callNTQQApi<GeneralCallResult>({
|
||||||
|
methodName: NTQQApiMethod.FETCH_UNITED_COMMEND_CONFIG,
|
||||||
|
args:[
|
||||||
|
{
|
||||||
|
groups: ['100243']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
@@ -38,6 +38,7 @@ export enum GroupMemberRole {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface GroupMember {
|
export interface GroupMember {
|
||||||
|
memberSpecialTitle: string;
|
||||||
avatarPath: string;
|
avatarPath: string;
|
||||||
cardName: string;
|
cardName: string;
|
||||||
cardType: number;
|
cardType: number;
|
||||||
|
@@ -212,9 +212,28 @@ export interface GrayTipElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum FaceType {
|
||||||
|
normal=1, // 小黄脸
|
||||||
|
normal2=2, // 新小黄脸, 从faceIndex 222开始?
|
||||||
|
dice=3 // 骰子
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum FaceIndex {
|
||||||
|
dice = 358,
|
||||||
|
RPS = 359 // 石头剪刀布
|
||||||
|
}
|
||||||
|
|
||||||
export interface FaceElement {
|
export interface FaceElement {
|
||||||
faceIndex: number,
|
faceIndex: number,
|
||||||
faceType: 1
|
faceType: FaceType,
|
||||||
|
faceText?: string,
|
||||||
|
packId?: string,
|
||||||
|
stickerId?: string,
|
||||||
|
sourceType?: number,
|
||||||
|
stickerType?: number,
|
||||||
|
resultId?: string,
|
||||||
|
surpriseId?: string,
|
||||||
|
randomType?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MarketFaceElement {
|
export interface MarketFaceElement {
|
||||||
|
@@ -6,15 +6,25 @@ import {ActionName} from "../types";
|
|||||||
import {NTQQGroupApi} from "../../../ntqqapi/api";
|
import {NTQQGroupApi} from "../../../ntqqapi/api";
|
||||||
import {log} from "../../../common/utils";
|
import {log} from "../../../common/utils";
|
||||||
|
|
||||||
|
interface Payload {
|
||||||
|
no_cache: boolean
|
||||||
|
}
|
||||||
|
|
||||||
class GetGroupList extends BaseAction<null, OB11Group[]> {
|
class GetGroupList extends BaseAction<Payload, OB11Group[]> {
|
||||||
actionName = ActionName.GetGroupList
|
actionName = ActionName.GetGroupList
|
||||||
|
|
||||||
protected async _handle(payload: null) {
|
protected async _handle(payload: Payload) {
|
||||||
// if (groups.length === 0) {
|
if (groups.length === 0
|
||||||
// const groups = await NTQQGroupApi.getGroups(true)
|
// || payload.no_cache === true
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const groups = await NTQQGroupApi.getGroups(true)
|
||||||
// log("get groups", groups)
|
// log("get groups", groups)
|
||||||
// }
|
return OB11Constructor.groups(groups);
|
||||||
|
} catch (e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
return OB11Constructor.groups(groups);
|
return OB11Constructor.groups(groups);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -40,6 +40,7 @@ import GoCQHTTPDownloadFile from "./go-cqhttp/DownloadFile";
|
|||||||
import GoCQHTTPGetGroupMsgHistory from "./go-cqhttp/GetGroupMsgHistory";
|
import GoCQHTTPGetGroupMsgHistory from "./go-cqhttp/GetGroupMsgHistory";
|
||||||
import GetFile from "./file/GetFile";
|
import GetFile from "./file/GetFile";
|
||||||
import {GoCQHTTGetForwardMsgAction} from "./go-cqhttp/GetForwardMsg";
|
import {GoCQHTTGetForwardMsgAction} from "./go-cqhttp/GetForwardMsg";
|
||||||
|
import {GetCookies} from "./user/GetCookie";
|
||||||
|
|
||||||
export const actionHandlers = [
|
export const actionHandlers = [
|
||||||
new GetFile(),
|
new GetFile(),
|
||||||
@@ -72,7 +73,7 @@ export const actionHandlers = [
|
|||||||
new GetImage(),
|
new GetImage(),
|
||||||
new GetRecord(),
|
new GetRecord(),
|
||||||
new CleanCache(),
|
new CleanCache(),
|
||||||
|
new GetCookies(),
|
||||||
//以下为go-cqhttp api
|
//以下为go-cqhttp api
|
||||||
new GoCQHTTPSendForwardMsg(),
|
new GoCQHTTPSendForwardMsg(),
|
||||||
new GoCQHTTPSendGroupForwardMsg(),
|
new GoCQHTTPSendGroupForwardMsg(),
|
||||||
@@ -91,6 +92,8 @@ function initActionMap() {
|
|||||||
const actionMap = new Map<string, BaseAction<any, any>>();
|
const actionMap = new Map<string, BaseAction<any, any>>();
|
||||||
for (const action of actionHandlers) {
|
for (const action of actionHandlers) {
|
||||||
actionMap.set(action.actionName, action);
|
actionMap.set(action.actionName, action);
|
||||||
|
actionMap.set(action.actionName + '_async', action);
|
||||||
|
actionMap.set(action.actionName + '_rate_limited', action);
|
||||||
}
|
}
|
||||||
|
|
||||||
return actionMap
|
return actionMap
|
||||||
|
@@ -2,19 +2,15 @@ import {
|
|||||||
AtType,
|
AtType,
|
||||||
ChatType,
|
ChatType,
|
||||||
ElementType,
|
ElementType,
|
||||||
Group, PicSubType,
|
Friend,
|
||||||
|
Group,
|
||||||
|
GroupMemberRole,
|
||||||
|
PicSubType,
|
||||||
RawMessage,
|
RawMessage,
|
||||||
SendArkElement,
|
SendArkElement,
|
||||||
SendMessageElement
|
SendMessageElement
|
||||||
} from "../../../ntqqapi/types";
|
} from "../../../ntqqapi/types";
|
||||||
import {
|
import {friends, getFriend, getGroup, getGroupMember, getUidByUin, selfInfo,} from "../../../common/data";
|
||||||
friends,
|
|
||||||
getFriend,
|
|
||||||
getGroup,
|
|
||||||
getGroupMember,
|
|
||||||
getUidByUin,
|
|
||||||
selfInfo,
|
|
||||||
} from "../../../common/data";
|
|
||||||
import {
|
import {
|
||||||
OB11MessageCustomMusic,
|
OB11MessageCustomMusic,
|
||||||
OB11MessageData,
|
OB11MessageData,
|
||||||
@@ -23,7 +19,7 @@ import {
|
|||||||
OB11MessageNode,
|
OB11MessageNode,
|
||||||
OB11PostSendMsg
|
OB11PostSendMsg
|
||||||
} from '../../types';
|
} from '../../types';
|
||||||
import {Peer} from "../../../ntqqapi/api/msg";
|
import {NTQQMsgApi, Peer} from "../../../ntqqapi/api/msg";
|
||||||
import {SendMsgElementConstructor} from "../../../ntqqapi/constructor";
|
import {SendMsgElementConstructor} from "../../../ntqqapi/constructor";
|
||||||
import BaseAction from "../BaseAction";
|
import BaseAction from "../BaseAction";
|
||||||
import {ActionName, BaseCheckResult} from "../types";
|
import {ActionName, BaseCheckResult} from "../types";
|
||||||
@@ -31,10 +27,11 @@ import * as fs from "node:fs";
|
|||||||
import {decodeCQCode} from "../../cqcode";
|
import {decodeCQCode} from "../../cqcode";
|
||||||
import {dbUtil} from "../../../common/db";
|
import {dbUtil} from "../../../common/db";
|
||||||
import {ALLOW_SEND_TEMP_MSG} from "../../../common/config";
|
import {ALLOW_SEND_TEMP_MSG} from "../../../common/config";
|
||||||
import {NTQQMsgApi} from "../../../ntqqapi/api/msg";
|
|
||||||
import {log} from "../../../common/utils/log";
|
import {log} from "../../../common/utils/log";
|
||||||
import {sleep} from "../../../common/utils/helper";
|
import {sleep} from "../../../common/utils/helper";
|
||||||
import {uri2local} from "../../../common/utils";
|
import {uri2local} from "../../../common/utils";
|
||||||
|
import {crychic} from "../../../ntqqapi/external/crychic";
|
||||||
|
import {NTQQGroupApi} from "../../../ntqqapi/api";
|
||||||
|
|
||||||
function checkSendMessage(sendMsgList: OB11MessageData[]) {
|
function checkSendMessage(sendMsgList: OB11MessageData[]) {
|
||||||
function checkUri(uri: string): boolean {
|
function checkUri(uri: string): boolean {
|
||||||
@@ -77,15 +74,15 @@ export interface ReturnDataType {
|
|||||||
|
|
||||||
export function convertMessage2List(message: OB11MessageMixType, autoEscape = false) {
|
export function convertMessage2List(message: OB11MessageMixType, autoEscape = false) {
|
||||||
if (typeof message === "string") {
|
if (typeof message === "string") {
|
||||||
if (!autoEscape) {
|
if (autoEscape === true) {
|
||||||
message = decodeCQCode(message.toString())
|
|
||||||
} else {
|
|
||||||
message = [{
|
message = [{
|
||||||
type: OB11MessageDataType.text,
|
type: OB11MessageDataType.text,
|
||||||
data: {
|
data: {
|
||||||
text: message
|
text: message
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
|
} else {
|
||||||
|
message = decodeCQCode(message.toString())
|
||||||
}
|
}
|
||||||
} else if (!Array.isArray(message)) {
|
} else if (!Array.isArray(message)) {
|
||||||
message = [message]
|
message = [message]
|
||||||
@@ -93,7 +90,7 @@ export function convertMessage2List(message: OB11MessageMixType, autoEscape = fa
|
|||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createSendElements(messageData: OB11MessageData[], group: Group | undefined, ignoreTypes: OB11MessageDataType[] = []) {
|
export async function createSendElements(messageData: OB11MessageData[], target: Group | Friend | undefined, ignoreTypes: OB11MessageDataType[] = []) {
|
||||||
let sendElements: SendMessageElement[] = []
|
let sendElements: SendMessageElement[] = []
|
||||||
let deleteAfterSentFiles: string[] = []
|
let deleteAfterSentFiles: string[] = []
|
||||||
for (let sendMsg of messageData) {
|
for (let sendMsg of messageData) {
|
||||||
@@ -109,17 +106,31 @@ export async function createSendElements(messageData: OB11MessageData[], group:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OB11MessageDataType.at: {
|
case OB11MessageDataType.at: {
|
||||||
if (!group) {
|
if (!target) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
let atQQ = sendMsg.data?.qq;
|
let atQQ = sendMsg.data?.qq;
|
||||||
if (atQQ) {
|
if (atQQ) {
|
||||||
atQQ = atQQ.toString()
|
atQQ = atQQ.toString()
|
||||||
if (atQQ === "all") {
|
if (atQQ === "all") {
|
||||||
|
// todo:查询剩余的at全体次数
|
||||||
|
const groupCode = (target as Group)?.groupCode;
|
||||||
|
let remainAtAllCount = 1
|
||||||
|
let isAdmin: boolean = true;
|
||||||
|
if (groupCode) {
|
||||||
|
try {
|
||||||
|
remainAtAllCount = (await NTQQGroupApi.getGroupAtAllRemainCount(groupCode)).atInfo.RemainAtAllCountForUin
|
||||||
|
log(`群${groupCode}剩余at全体次数`, remainAtAllCount);
|
||||||
|
const self = await getGroupMember((target as Group)?.groupCode, selfInfo.uin);
|
||||||
|
isAdmin = self.role === GroupMemberRole.admin || self.role === GroupMemberRole.owner;
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
if(isAdmin && remainAtAllCount > 0) {
|
||||||
sendElements.push(SendMsgElementConstructor.at(atQQ, atQQ, AtType.atAll, "全体成员"))
|
sendElements.push(SendMsgElementConstructor.at(atQQ, atQQ, AtType.atAll, "全体成员"))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// const atMember = group?.members.find(m => m.uin == atQQ)
|
// const atMember = group?.members.find(m => m.uin == atQQ)
|
||||||
const atMember = await getGroupMember(group?.groupCode, atQQ);
|
const atMember = await getGroupMember((target as Group)?.groupCode, atQQ);
|
||||||
if (atMember) {
|
if (atMember) {
|
||||||
sendElements.push(SendMsgElementConstructor.at(atQQ, atMember.uid, AtType.atUser, atMember.cardName || atMember.nick))
|
sendElements.push(SendMsgElementConstructor.at(atQQ, atMember.uid, AtType.atUser, atMember.cardName || atMember.nick))
|
||||||
}
|
}
|
||||||
@@ -197,7 +208,30 @@ export async function createSendElements(messageData: OB11MessageData[], group:
|
|||||||
case OB11MessageDataType.json: {
|
case OB11MessageDataType.json: {
|
||||||
sendElements.push(SendMsgElementConstructor.ark(sendMsg.data.data))
|
sendElements.push(SendMsgElementConstructor.ark(sendMsg.data.data))
|
||||||
}
|
}
|
||||||
break
|
break;
|
||||||
|
case OB11MessageDataType.poke: {
|
||||||
|
let qq = sendMsg.data?.qq || sendMsg.data?.id
|
||||||
|
if (qq) {
|
||||||
|
if ("groupCode" in target) {
|
||||||
|
crychic.sendGroupPoke(target.groupCode, qq.toString())
|
||||||
|
} else {
|
||||||
|
if (!qq) {
|
||||||
|
qq = parseInt(target.uin)
|
||||||
|
}
|
||||||
|
crychic.sendFriendPoke(qq.toString())
|
||||||
|
}
|
||||||
|
sendElements.push(SendMsgElementConstructor.poke("", ""))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OB11MessageDataType.dice:{
|
||||||
|
const resultId = sendMsg.data?.result
|
||||||
|
sendElements.push(SendMsgElementConstructor.dice(resultId));
|
||||||
|
}break;
|
||||||
|
case OB11MessageDataType.RPS:{
|
||||||
|
const resultId = sendMsg.data?.result
|
||||||
|
sendElements.push(SendMsgElementConstructor.rps(resultId));
|
||||||
|
}break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -232,7 +266,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
|||||||
message: "转发消息不能和普通消息混在一起发送,转发需要保证message只有type为node的元素"
|
message: "转发消息不能和普通消息混在一起发送,转发需要保证message只有type为node的元素"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (payload.message_type !== "private" && payload.group_id &&!(await getGroup(payload.group_id))) {
|
if (payload.message_type !== "private" && payload.group_id && !(await getGroup(payload.group_id))) {
|
||||||
return {
|
return {
|
||||||
valid: false,
|
valid: false,
|
||||||
message: `群${payload.group_id}不存在`
|
message: `群${payload.group_id}不存在`
|
||||||
@@ -261,6 +295,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
|||||||
}
|
}
|
||||||
let isTempMsg = false;
|
let isTempMsg = false;
|
||||||
let group: Group | undefined = undefined;
|
let group: Group | undefined = undefined;
|
||||||
|
let friend: Friend | undefined = undefined;
|
||||||
const genGroupPeer = async () => {
|
const genGroupPeer = async () => {
|
||||||
group = await getGroup(payload.group_id.toString())
|
group = await getGroup(payload.group_id.toString())
|
||||||
peer.chatType = ChatType.group
|
peer.chatType = ChatType.group
|
||||||
@@ -269,7 +304,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const genFriendPeer = () => {
|
const genFriendPeer = () => {
|
||||||
const friend = friends.find(f => f.uin == payload.user_id.toString())
|
friend = friends.find(f => f.uin == payload.user_id.toString())
|
||||||
if (friend) {
|
if (friend) {
|
||||||
// peer.name = friend.nickName
|
// peer.name = friend.nickName
|
||||||
peer.peerUid = friend.uid
|
peer.peerUid = friend.uid
|
||||||
@@ -294,7 +329,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
|||||||
} else {
|
} else {
|
||||||
throw ("发送消息参数错误, 请指定group_id或user_id")
|
throw ("发送消息参数错误, 请指定group_id或user_id")
|
||||||
}
|
}
|
||||||
const messages = convertMessage2List(payload.message);
|
const messages = convertMessage2List(payload.message, payload.auto_escape === true || payload.auto_escape === 'true');
|
||||||
if (this.getSpecialMsgNum(payload, OB11MessageDataType.node)) {
|
if (this.getSpecialMsgNum(payload, OB11MessageDataType.node)) {
|
||||||
try {
|
try {
|
||||||
const returnMsg = await this.handleForwardNode(peer, messages as OB11MessageNode[], group)
|
const returnMsg = await this.handleForwardNode(peer, messages as OB11MessageNode[], group)
|
||||||
@@ -318,7 +353,12 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// log("send msg:", peer, sendElements)
|
// log("send msg:", peer, sendElements)
|
||||||
const {sendElements, deleteAfterSentFiles} = await createSendElements(messages, group)
|
const {sendElements, deleteAfterSentFiles} = await createSendElements(messages, group || friend)
|
||||||
|
if (sendElements.length === 1){
|
||||||
|
if (sendElements[0] === null){
|
||||||
|
return {message_id: 0}
|
||||||
|
}
|
||||||
|
}
|
||||||
const returnMsg = await sendMsg(peer, sendElements, deleteAfterSentFiles)
|
const returnMsg = await sendMsg(peer, sendElements, deleteAfterSentFiles)
|
||||||
deleteAfterSentFiles.map(f => fs.unlink(f, () => {
|
deleteAfterSentFiles.map(f => fs.unlink(f, () => {
|
||||||
}));
|
}));
|
||||||
@@ -468,6 +508,9 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
|||||||
// nodeIds.push(nodeMsg.msgId)
|
// nodeIds.push(nodeMsg.msgId)
|
||||||
// await sleep(500);
|
// await sleep(500);
|
||||||
// 开发转发
|
// 开发转发
|
||||||
|
if (nodeMsgIds.length === 0) {
|
||||||
|
throw Error("转发消息失败,节点为空")
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
log("开发转发", nodeMsgIds)
|
log("开发转发", nodeMsgIds)
|
||||||
return await NTQQMsgApi.multiForwardMsg(srcPeer, destPeer, nodeMsgIds)
|
return await NTQQMsgApi.multiForwardMsg(srcPeer, destPeer, nodeMsgIds)
|
||||||
@@ -478,8 +521,6 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private genMusicElement(url: string, audio: string, title: string, content: string, image: string): SendArkElement {
|
private genMusicElement(url: string, audio: string, title: string, content: string, image: string): SendArkElement {
|
||||||
const musicJson = {
|
const musicJson = {
|
||||||
app: 'com.tencent.structmsg',
|
app: 'com.tencent.structmsg',
|
||||||
|
@@ -50,6 +50,7 @@ export enum ActionName {
|
|||||||
GetImage = "get_image",
|
GetImage = "get_image",
|
||||||
GetRecord = "get_record",
|
GetRecord = "get_record",
|
||||||
CleanCache = "clean_cache",
|
CleanCache = "clean_cache",
|
||||||
|
GetCookies = "get_cookies",
|
||||||
// 以下为go-cqhttp api
|
// 以下为go-cqhttp api
|
||||||
GoCQHTTP_SendForwardMsg = "send_forward_msg",
|
GoCQHTTP_SendForwardMsg = "send_forward_msg",
|
||||||
GoCQHTTP_SendGroupForwardMsg = "send_group_forward_msg",
|
GoCQHTTP_SendGroupForwardMsg = "send_group_forward_msg",
|
||||||
|
12
src/onebot11/action/user/GetCookie.ts
Normal file
12
src/onebot11/action/user/GetCookie.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import BaseAction from "../BaseAction";
|
||||||
|
import {NTQQUserApi} from "../../../ntqqapi/api";
|
||||||
|
import {groups} from "../../../common/data";
|
||||||
|
import {ActionName} from "../types";
|
||||||
|
|
||||||
|
export class GetCookies extends BaseAction<null, {cookies: string, bkn: string}>{
|
||||||
|
actionName = ActionName.GetCookies;
|
||||||
|
|
||||||
|
protected async _handle() {
|
||||||
|
return NTQQUserApi.getCookie(groups[0])
|
||||||
|
}
|
||||||
|
}
|
@@ -13,7 +13,7 @@ export default class SetFriendAddRequest extends BaseAction<Payload, null> {
|
|||||||
|
|
||||||
protected async _handle(payload: Payload): Promise<null> {
|
protected async _handle(payload: Payload): Promise<null> {
|
||||||
const approve = payload.approve.toString() === "true";
|
const approve = payload.approve.toString() === "true";
|
||||||
await NTQQFriendApi.handleFriendRequest(parseInt(payload.flag), approve)
|
await NTQQFriendApi.handleFriendRequest(payload.flag, approve)
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -10,7 +10,7 @@ import {
|
|||||||
} from "./types";
|
} from "./types";
|
||||||
import {
|
import {
|
||||||
AtType,
|
AtType,
|
||||||
ChatType,
|
ChatType, FaceIndex,
|
||||||
GrayTipElementSubType,
|
GrayTipElementSubType,
|
||||||
Group,
|
Group,
|
||||||
GroupMember,
|
GroupMember,
|
||||||
@@ -22,7 +22,7 @@ import {
|
|||||||
User,
|
User,
|
||||||
VideoElement
|
VideoElement
|
||||||
} from '../ntqqapi/types';
|
} from '../ntqqapi/types';
|
||||||
import {getFriend, getGroupMember, selfInfo, tempGroupCodeMap} from '../common/data';
|
import {deleteGroup, getFriend, getGroupMember, groups, selfInfo, tempGroupCodeMap} from '../common/data';
|
||||||
import {EventType} from "./event/OB11BaseEvent";
|
import {EventType} from "./event/OB11BaseEvent";
|
||||||
import {encodeCQCode} from "./cqcode";
|
import {encodeCQCode} from "./cqcode";
|
||||||
import {dbUtil} from "../common/db";
|
import {dbUtil} from "../common/db";
|
||||||
@@ -39,6 +39,7 @@ import {getConfigUtil} from "../common/config";
|
|||||||
import {OB11GroupTitleEvent} from "./event/notice/OB11GroupTitleEvent";
|
import {OB11GroupTitleEvent} from "./event/notice/OB11GroupTitleEvent";
|
||||||
import {OB11GroupCardEvent} from "./event/notice/OB11GroupCardEvent";
|
import {OB11GroupCardEvent} from "./event/notice/OB11GroupCardEvent";
|
||||||
import {OB11GroupDecreaseEvent} from "./event/notice/OB11GroupDecreaseEvent";
|
import {OB11GroupDecreaseEvent} from "./event/notice/OB11GroupDecreaseEvent";
|
||||||
|
import {NTQQGroupApi} from "../ntqqapi/api";
|
||||||
|
|
||||||
let lastRKeyUpdateTime = 0;
|
let lastRKeyUpdateTime = 0;
|
||||||
|
|
||||||
@@ -158,8 +159,7 @@ export class OB11Constructor {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
message_data["data"]["url"] = IMAGE_HTTP_HOST + url
|
message_data["data"]["url"] = IMAGE_HTTP_HOST + url
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
// 有可能会碰到appid为1406的,这个不能使用新的NT域名,并且需要把appid改为1407才可访问
|
// 有可能会碰到appid为1406的,这个不能使用新的NT域名,并且需要把appid改为1407才可访问
|
||||||
message_data["data"]["url"] = `${IMAGE_HTTP_HOST}/download?appid=1407&fileid=${fileUuid}&rkey=${currentRKey}&spec=0`
|
message_data["data"]["url"] = `${IMAGE_HTTP_HOST}/download?appid=1407&fileid=${fileUuid}&rkey=${currentRKey}&spec=0`
|
||||||
}
|
}
|
||||||
@@ -227,15 +227,24 @@ export class OB11Constructor {
|
|||||||
message_data["type"] = OB11MessageDataType.json;
|
message_data["type"] = OB11MessageDataType.json;
|
||||||
message_data["data"]["data"] = element.arkElement.bytesData;
|
message_data["data"]["data"] = element.arkElement.bytesData;
|
||||||
} else if (element.faceElement) {
|
} else if (element.faceElement) {
|
||||||
|
const faceId = element.faceElement.faceIndex;
|
||||||
|
if (faceId === FaceIndex.dice) {
|
||||||
|
message_data["type"] = OB11MessageDataType.dice
|
||||||
|
message_data["data"]["result"] = element.faceElement.resultId;
|
||||||
|
} else if (faceId === FaceIndex.RPS) {
|
||||||
|
message_data["type"] = OB11MessageDataType.RPS
|
||||||
|
message_data["data"]["result"] = element.faceElement.resultId;
|
||||||
|
} else {
|
||||||
message_data["type"] = OB11MessageDataType.face;
|
message_data["type"] = OB11MessageDataType.face;
|
||||||
message_data["data"]["id"] = element.faceElement.faceIndex.toString();
|
message_data["data"]["id"] = element.faceElement.faceIndex.toString();
|
||||||
|
}
|
||||||
} else if (element.marketFaceElement) {
|
} else if (element.marketFaceElement) {
|
||||||
message_data["type"] = OB11MessageDataType.mface;
|
message_data["type"] = OB11MessageDataType.mface;
|
||||||
message_data["data"]["text"] = element.marketFaceElement.faceName;
|
message_data["data"]["text"] = element.marketFaceElement.faceName;
|
||||||
} else if (element.markdownElement){
|
} else if (element.markdownElement) {
|
||||||
message_data["type"] = OB11MessageDataType.markdown;
|
message_data["type"] = OB11MessageDataType.markdown;
|
||||||
message_data["data"]["data"] = element.markdownElement.content;
|
message_data["data"]["data"] = element.markdownElement.content;
|
||||||
} else if (element.multiForwardMsgElement){
|
} else if (element.multiForwardMsgElement) {
|
||||||
message_data["type"] = OB11MessageDataType.forward;
|
message_data["type"] = OB11MessageDataType.forward;
|
||||||
message_data["data"]["id"] = msg.msgId
|
message_data["data"]["id"] = msg.msgId
|
||||||
}
|
}
|
||||||
@@ -256,7 +265,7 @@ export class OB11Constructor {
|
|||||||
if (msg.chatType !== ChatType.group) {
|
if (msg.chatType !== ChatType.group) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (msg.senderUin){
|
if (msg.senderUin) {
|
||||||
let member = await getGroupMember(msg.peerUid, msg.senderUin);
|
let member = await getGroupMember(msg.peerUid, msg.senderUin);
|
||||||
if (member && member.cardName !== msg.sendMemberName) {
|
if (member && member.cardName !== msg.sendMemberName) {
|
||||||
const event = new OB11GroupCardEvent(parseInt(msg.peerUid), parseInt(msg.senderUin), msg.sendMemberName, member.cardName)
|
const event = new OB11GroupCardEvent(parseInt(msg.peerUid), parseInt(msg.senderUin), msg.sendMemberName, member.cardName)
|
||||||
@@ -306,13 +315,18 @@ export class OB11Constructor {
|
|||||||
if (memberUin && adminUin) {
|
if (memberUin && adminUin) {
|
||||||
return new OB11GroupBanEvent(parseInt(msg.peerUid), parseInt(memberUin), parseInt(adminUin), duration, sub_type);
|
return new OB11GroupBanEvent(parseInt(msg.peerUid), parseInt(memberUin), parseInt(adminUin), duration, sub_type);
|
||||||
}
|
}
|
||||||
}
|
} else if (groupElement.type == TipGroupElementType.kicked) {
|
||||||
else if (groupElement.type == TipGroupElementType.kicked){
|
log(`收到我被踢出或退群提示, 群${msg.peerUid}`, groupElement)
|
||||||
log("收到我被踢出提示", groupElement)
|
deleteGroup(msg.peerUid);
|
||||||
|
NTQQGroupApi.quitGroup(msg.peerUid).then()
|
||||||
|
try {
|
||||||
const adminUin = (await getGroupMember(msg.peerUid, groupElement.adminUid))?.uin || (await NTQQUserApi.getUserDetailInfo(groupElement.adminUid))?.uin
|
const adminUin = (await getGroupMember(msg.peerUid, groupElement.adminUid))?.uin || (await NTQQUserApi.getUserDetailInfo(groupElement.adminUid))?.uin
|
||||||
if (adminUin) {
|
if (adminUin) {
|
||||||
return new OB11GroupDecreaseEvent(parseInt(msg.peerUid), parseInt(selfInfo.uin), parseInt(adminUin), "kick_me");
|
return new OB11GroupDecreaseEvent(parseInt(msg.peerUid), parseInt(selfInfo.uin), parseInt(adminUin), "kick_me");
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
return new OB11GroupDecreaseEvent(parseInt(msg.peerUid), parseInt(selfInfo.uin), 0, "leave");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (element.fileElement) {
|
} else if (element.fileElement) {
|
||||||
return new OB11GroupUploadNoticeEvent(parseInt(msg.peerUid), parseInt(msg.senderUin), {
|
return new OB11GroupUploadNoticeEvent(parseInt(msg.peerUid), parseInt(msg.senderUin), {
|
||||||
@@ -371,6 +385,9 @@ export class OB11Constructor {
|
|||||||
const memberUin = json.items[1].param[0]
|
const memberUin = json.items[1].param[0]
|
||||||
const title = json.items[3].txt
|
const title = json.items[3].txt
|
||||||
log("收到群成员新头衔消息", json)
|
log("收到群成员新头衔消息", json)
|
||||||
|
getGroupMember(msg.peerUid, memberUin).then(member => {
|
||||||
|
member.memberSpecialTitle = title
|
||||||
|
})
|
||||||
return new OB11GroupTitleEvent(parseInt(msg.peerUid), parseInt(memberUin), title)
|
return new OB11GroupTitleEvent(parseInt(msg.peerUid), parseInt(memberUin), title)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -434,6 +451,7 @@ export class OB11Constructor {
|
|||||||
is_robot: member.isRobot,
|
is_robot: member.isRobot,
|
||||||
shut_up_timestamp: member.shutUpTime,
|
shut_up_timestamp: member.shutUpTime,
|
||||||
role: OB11Constructor.groupMemberRole(member.role),
|
role: OB11Constructor.groupMemberRole(member.role),
|
||||||
|
title: member.memberSpecialTitle || "",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,8 +1,11 @@
|
|||||||
import {Response} from "express";
|
import {Response} from "express";
|
||||||
import {OB11Response} from "../action/OB11Response";
|
import {OB11Response} from "../action/OB11Response";
|
||||||
import {HttpServerBase} from "../../common/server/http";
|
import {HttpServerBase} from "../../common/server/http";
|
||||||
import {actionHandlers} from "../action";
|
import {actionHandlers, actionMap} from "../action";
|
||||||
import {getConfigUtil} from "../../common/config";
|
import {getConfigUtil} from "../../common/config";
|
||||||
|
import {postOB11Event} from "./postOB11Event";
|
||||||
|
import {OB11HeartbeatEvent} from "../event/meta/OB11HeartbeatEvent";
|
||||||
|
import {selfInfo} from "../../common/data";
|
||||||
|
|
||||||
class OB11HTTPServer extends HttpServerBase {
|
class OB11HTTPServer extends HttpServerBase {
|
||||||
name = "OneBot V11 server"
|
name = "OneBot V11 server"
|
||||||
@@ -21,9 +24,32 @@ class OB11HTTPServer extends HttpServerBase {
|
|||||||
export const ob11HTTPServer = new OB11HTTPServer();
|
export const ob11HTTPServer = new OB11HTTPServer();
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
for (const action of actionHandlers) {
|
for (const [actionName, action] of actionMap) {
|
||||||
for (const method of ["post", "get"]) {
|
for (const method of ["post", "get"]) {
|
||||||
ob11HTTPServer.registerRouter(method, action.actionName, (res, payload) => action.handle(payload))
|
ob11HTTPServer.registerRouter(method, actionName, (res, payload) => action.handle(payload))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 0)
|
}, 0)
|
||||||
|
|
||||||
|
|
||||||
|
class HTTPHeart{
|
||||||
|
intervalId: NodeJS.Timeout | null = null
|
||||||
|
start(){
|
||||||
|
const {heartInterval} = getConfigUtil().getConfig();
|
||||||
|
if (this.intervalId) {
|
||||||
|
clearInterval(this.intervalId);
|
||||||
|
}
|
||||||
|
this.intervalId = setInterval(() => {
|
||||||
|
// ws的心跳是ws自己维护的
|
||||||
|
postOB11Event(new OB11HeartbeatEvent(selfInfo.online, true, heartInterval), false, false)
|
||||||
|
}, heartInterval)
|
||||||
|
}
|
||||||
|
|
||||||
|
stop(){
|
||||||
|
if (this.intervalId){
|
||||||
|
clearInterval(this.intervalId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const httpHeart = new HTTPHeart();
|
@@ -1,5 +1,5 @@
|
|||||||
import {OB11Message, OB11MessageAt, OB11MessageData} from "../types";
|
import {OB11Message, OB11MessageAt, OB11MessageData} from "../types";
|
||||||
import {getGroup, selfInfo} from "../../common/data";
|
import {getFriend, getGroup, getUidByUin, selfInfo} from "../../common/data";
|
||||||
import {OB11BaseMetaEvent} from "../event/meta/OB11BaseMetaEvent";
|
import {OB11BaseMetaEvent} from "../event/meta/OB11BaseMetaEvent";
|
||||||
import {OB11BaseNoticeEvent} from "../event/notice/OB11BaseNoticeEvent";
|
import {OB11BaseNoticeEvent} from "../event/notice/OB11BaseNoticeEvent";
|
||||||
import {WebSocket as WebSocketClass} from "ws";
|
import {WebSocket as WebSocketClass} from "ws";
|
||||||
@@ -69,7 +69,7 @@ export function postWsEvent(event: PostEventType) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function postOB11Event(msg: PostEventType, reportSelf = false) {
|
export function postOB11Event(msg: PostEventType, reportSelf = false, postWs = true) {
|
||||||
const config = getConfigUtil().getConfig();
|
const config = getConfigUtil().getConfig();
|
||||||
// 判断msg是否是event
|
// 判断msg是否是event
|
||||||
if (!config.reportSelfMessage && !reportSelf) {
|
if (!config.reportSelfMessage && !reportSelf) {
|
||||||
@@ -115,6 +115,7 @@ export function postOB11Event(msg: PostEventType, reportSelf = false) {
|
|||||||
peerUid: msg.user_id.toString()
|
peerUid: msg.user_id.toString()
|
||||||
}
|
}
|
||||||
if (msg.message_type == "private") {
|
if (msg.message_type == "private") {
|
||||||
|
peer.peerUid = getUidByUin(msg.user_id.toString())
|
||||||
if (msg.sub_type === "group") {
|
if (msg.sub_type === "group") {
|
||||||
peer.chatType = ChatType.temp
|
peer.chatType = ChatType.temp
|
||||||
}
|
}
|
||||||
@@ -139,6 +140,7 @@ export function postOB11Event(msg: PostEventType, reportSelf = false) {
|
|||||||
}
|
}
|
||||||
replyMessage = replyMessage.concat(convertMessage2List(reply, resJson.auto_escape))
|
replyMessage = replyMessage.concat(convertMessage2List(reply, resJson.auto_escape))
|
||||||
const {sendElements, deleteAfterSentFiles} = await createSendElements(replyMessage, group)
|
const {sendElements, deleteAfterSentFiles} = await createSendElements(replyMessage, group)
|
||||||
|
log(`发送消息给`, peer, sendElements)
|
||||||
sendMsg(peer, sendElements, deleteAfterSentFiles, false).then()
|
sendMsg(peer, sendElements, deleteAfterSentFiles, false).then()
|
||||||
} else if (resJson.delete) {
|
} else if (resJson.delete) {
|
||||||
NTQQMsgApi.recallMsg(peer, [rawMessage.msgId]).then()
|
NTQQMsgApi.recallMsg(peer, [rawMessage.msgId]).then()
|
||||||
@@ -156,7 +158,7 @@ export function postOB11Event(msg: PostEventType, reportSelf = false) {
|
|||||||
resJson = resJson as QuickActionFriendRequest
|
resJson = resJson as QuickActionFriendRequest
|
||||||
if (!isNull(resJson.approve)) {
|
if (!isNull(resJson.approve)) {
|
||||||
// todo: set remark
|
// todo: set remark
|
||||||
NTQQFriendApi.handleFriendRequest(parseInt((msg as OB11FriendRequestEvent).flag), resJson.approve).then()
|
NTQQFriendApi.handleFriendRequest(((msg as OB11FriendRequestEvent).flag), resJson.approve).then()
|
||||||
}
|
}
|
||||||
} else if ((msg as OB11GroupRequestEvent).request_type === "group") {
|
} else if ((msg as OB11GroupRequestEvent).request_type === "group") {
|
||||||
resJson = resJson as QuickActionGroupRequest
|
resJson = resJson as QuickActionGroupRequest
|
||||||
@@ -170,5 +172,7 @@ export function postOB11Event(msg: PostEventType, reportSelf = false) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (postWs){
|
||||||
postWsEvent(msg);
|
postWsEvent(msg);
|
||||||
|
}
|
||||||
}
|
}
|
@@ -78,6 +78,7 @@ export class ReverseWebsocket {
|
|||||||
private connect() {
|
private connect() {
|
||||||
const {token, heartInterval} = getConfigUtil().getConfig()
|
const {token, heartInterval} = getConfigUtil().getConfig()
|
||||||
this.websocket = new WebSocketClass(this.url, {
|
this.websocket = new WebSocketClass(this.url, {
|
||||||
|
maxPayload: 1024 * 1024 * 1024,
|
||||||
handshakeTimeout: 2000,
|
handshakeTimeout: 2000,
|
||||||
perMessageDeflate: false,
|
perMessageDeflate: false,
|
||||||
headers: {
|
headers: {
|
||||||
@@ -128,9 +129,14 @@ class OB11ReverseWebsockets {
|
|||||||
|
|
||||||
stop() {
|
stop() {
|
||||||
for (let rws of rwsList) {
|
for (let rws of rwsList) {
|
||||||
|
try {
|
||||||
rws.stop();
|
rws.stop();
|
||||||
|
}catch (e) {
|
||||||
|
log("反向ws关闭:", e.stack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
rwsList.length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
restart() {
|
restart() {
|
||||||
this.stop();
|
this.stop();
|
||||||
|
@@ -116,7 +116,10 @@ export enum OB11MessageDataType {
|
|||||||
markdown = "markdown",
|
markdown = "markdown",
|
||||||
node = "node", // 合并转发消息节点
|
node = "node", // 合并转发消息节点
|
||||||
forward = "forward", // 合并转发消息,用于上报
|
forward = "forward", // 合并转发消息,用于上报
|
||||||
xml = "xml"
|
xml = "xml",
|
||||||
|
poke = "poke",
|
||||||
|
dice = "dice",
|
||||||
|
RPS = "rps"
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OB11MessageMFace{
|
export interface OB11MessageMFace{
|
||||||
@@ -125,6 +128,20 @@ export interface OB11MessageMFace{
|
|||||||
text: string
|
text: string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface OB11MessageDice{
|
||||||
|
type: OB11MessageDataType.dice,
|
||||||
|
data: {
|
||||||
|
result: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export interface OB11MessageRPS{
|
||||||
|
type: OB11MessageDataType.RPS,
|
||||||
|
data: {
|
||||||
|
result: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export interface OB11MessageText {
|
export interface OB11MessageText {
|
||||||
type: OB11MessageDataType.text,
|
type: OB11MessageDataType.text,
|
||||||
data: {
|
data: {
|
||||||
@@ -132,6 +149,14 @@ export interface OB11MessageText {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface OB11MessagePoke{
|
||||||
|
type: OB11MessageDataType.poke
|
||||||
|
data: {
|
||||||
|
qq?: number,
|
||||||
|
id?: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
interface OB11MessageFileBase {
|
interface OB11MessageFileBase {
|
||||||
data: {
|
data: {
|
||||||
thumb?: string;
|
thumb?: string;
|
||||||
@@ -217,7 +242,8 @@ export type OB11MessageData =
|
|||||||
OB11MessageFace | OB11MessageMFace |
|
OB11MessageFace | OB11MessageMFace |
|
||||||
OB11MessageAt | OB11MessageReply |
|
OB11MessageAt | OB11MessageReply |
|
||||||
OB11MessageImage | OB11MessageRecord | OB11MessageFile | OB11MessageVideo |
|
OB11MessageImage | OB11MessageRecord | OB11MessageFile | OB11MessageVideo |
|
||||||
OB11MessageNode | OB11MessageCustomMusic | OB11MessageJson
|
OB11MessageNode | OB11MessageCustomMusic | OB11MessageJson | OB11MessagePoke |
|
||||||
|
OB11MessageDice | OB11MessageRPS
|
||||||
|
|
||||||
export interface OB11PostSendMsg {
|
export interface OB11PostSendMsg {
|
||||||
message_type?: "private" | "group"
|
message_type?: "private" | "group"
|
||||||
@@ -225,6 +251,7 @@ export interface OB11PostSendMsg {
|
|||||||
group_id?: string,
|
group_id?: string,
|
||||||
message: OB11MessageMixType;
|
message: OB11MessageMixType;
|
||||||
messages?: OB11MessageMixType; // 兼容 go-cqhttp
|
messages?: OB11MessageMixType; // 兼容 go-cqhttp
|
||||||
|
auto_escape?: boolean | string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OB11Version {
|
export interface OB11Version {
|
||||||
|
675
src/renderer/icon.ts
Normal file
675
src/renderer/icon.ts
Normal file
@@ -0,0 +1,675 @@
|
|||||||
|
export const iconSvg = `
|
||||||
|
<?xml version="2.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="50px" y="10px" width="262px" height="150" viewBox="0 0 212 262" enable-background="new 0 0 212 262" xml:space="preserve">
|
||||||
|
<image id="image0" width="212" height="210" x="0" y="-20" transform="rotate(180, 100, 100)"
|
||||||
|
xlink:href="data:image/png;base64,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" />
|
||||||
|
</svg>
|
||||||
|
`
|
@@ -3,11 +3,31 @@ import { CheckVersion } from '../common/types';
|
|||||||
import {SettingButton, SettingItem, SettingList, SettingSwitch, SettingSelect} from './components';
|
import {SettingButton, SettingItem, SettingList, SettingSwitch, SettingSelect} from './components';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import StyleRaw from './style.css?raw';
|
import StyleRaw from './style.css?raw';
|
||||||
|
import {iconSvg} from "./icon";
|
||||||
|
|
||||||
// 打开设置界面时触发
|
// 打开设置界面时触发
|
||||||
|
|
||||||
|
function aprilFoolsEgg(node: Element){
|
||||||
|
let today = new Date()
|
||||||
|
if(today.getMonth() === 3 && today.getDate() === 1){
|
||||||
|
console.log("超时空猫猫!!!")
|
||||||
|
node.querySelector(".name").innerHTML = "ChronoCat";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function initSideBar(){
|
||||||
|
document.querySelectorAll(".nav-item.liteloader").forEach((node) => {
|
||||||
|
if (node.textContent.startsWith("LLOneBot")) {
|
||||||
|
aprilFoolsEgg(node)
|
||||||
|
let iconEle = node.querySelector(".q-icon");
|
||||||
|
iconEle.innerHTML = iconSvg;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
async function onSettingWindowCreated(view: Element) {
|
async function onSettingWindowCreated(view: Element) {
|
||||||
window.llonebot.log("setting window created");
|
window.llonebot.log("setting window created");
|
||||||
|
initSideBar()
|
||||||
const isEmpty = (value: any) => value === undefined || value === null || value === '';
|
const isEmpty = (value: any) => value === undefined || value === null || value === '';
|
||||||
let config = await window.llonebot.getConfig();
|
let config = await window.llonebot.getConfig();
|
||||||
let ob11Config = {...config.ob11};
|
let ob11Config = {...config.ob11};
|
||||||
@@ -48,6 +68,9 @@ async function onSettingWindowCreated(view: Element) {
|
|||||||
`<div class="q-input"><input class="q-input__inner" data-config-key="ob11.httpPort" type="number" min="1" max="65534" value="${config.ob11.httpPort}" placeholder="${config.ob11.httpPort}" /></div>`,
|
`<div class="q-input"><input class="q-input__inner" data-config-key="ob11.httpPort" type="number" min="1" max="65534" value="${config.ob11.httpPort}" placeholder="${config.ob11.httpPort}" /></div>`,
|
||||||
'config-ob11-httpPort', config.ob11.enableHttp
|
'config-ob11-httpPort', config.ob11.enableHttp
|
||||||
),
|
),
|
||||||
|
SettingItem('启用 HTTP 心跳', null,
|
||||||
|
SettingSwitch('ob11.enableHttpHeart', config.ob11.enableHttpHeart, {'control-display-id': 'config-ob11-enableHttpHeart'}),
|
||||||
|
),
|
||||||
SettingItem('启用 HTTP 事件上报', null,
|
SettingItem('启用 HTTP 事件上报', null,
|
||||||
SettingSwitch('ob11.enableHttpPost', config.ob11.enableHttpPost, {'control-display-id': 'config-ob11-httpHosts'}),
|
SettingSwitch('ob11.enableHttpPost', config.ob11.enableHttpPost, {'control-display-id': 'config-ob11-httpHosts'}),
|
||||||
),
|
),
|
||||||
@@ -113,8 +136,8 @@ async function onSettingWindowCreated(view: Element) {
|
|||||||
]),
|
]),
|
||||||
SettingList([
|
SettingList([
|
||||||
SettingItem(
|
SettingItem(
|
||||||
'接收戳一戳消息, 暂时只支持Windows版的LLOneBot',
|
'戳一戳消息, 暂时只支持Windows版的LLOneBot',
|
||||||
`重启QQ后生效,如果导致QQ崩溃请勿开启此项`,
|
`重启QQ后生效,如果导致QQ崩溃请勿开启此项, 群戳一戳只能收到群号`,
|
||||||
SettingSwitch('enablePoke', config.enablePoke),
|
SettingSwitch('enablePoke', config.enablePoke),
|
||||||
),
|
),
|
||||||
SettingItem(
|
SettingItem(
|
||||||
@@ -182,13 +205,16 @@ async function onSettingWindowCreated(view: Element) {
|
|||||||
const showError = async () => {
|
const showError = async () => {
|
||||||
await (new Promise((res) => setTimeout(() => res(true), 1000)));
|
await (new Promise((res) => setTimeout(() => res(true), 1000)));
|
||||||
|
|
||||||
const errDom = doc.querySelector('#llonebot-error');
|
const errDom = document.querySelector('#llonebot-error') || doc.querySelector('#llonebot-error');
|
||||||
const errCodeDom = errDom.querySelector('code');
|
const errCodeDom = errDom.querySelector('code');
|
||||||
const errMsg = await window.llonebot.getError();
|
const errMsg = await window.llonebot.getError();
|
||||||
|
|
||||||
if (!errMsg) return;
|
if (!errMsg){
|
||||||
|
errDom.classList.remove('show');
|
||||||
|
}
|
||||||
|
else {
|
||||||
errDom.classList.add('show');
|
errDom.classList.add('show');
|
||||||
|
}
|
||||||
errCodeDom.innerHTML = errMsg;
|
errCodeDom.innerHTML = errMsg;
|
||||||
}
|
}
|
||||||
showError().then();
|
showError().then();
|
||||||
|
@@ -1 +1 @@
|
|||||||
export const version = "3.20.4"
|
export const version = "3.23.0"
|
Reference in New Issue
Block a user