feature: config ui

This commit is contained in:
linyuchen 2023-11-16 16:34:36 +08:00
parent 3cf47884b3
commit e0624cfe44
5 changed files with 113 additions and 53 deletions

5
src/global.d.ts vendored
View File

@ -1,4 +1,4 @@
import {Group, GroupMemberInfo, MessageElement, Peer, PostDataSendMsg, SendMessage, User} from "./types";
import {Config, Group, GroupMemberInfo, MessageElement, Peer, PostDataSendMsg, SendMessage, User} from "./types";
declare var LLAPI: {
@ -31,11 +31,14 @@ declare var llonebot: {
updateGroupMembers: (data: { groupMembers: User[], group_id: string }) => void
startExpress: () => void
log(data: any): void,
setConfig(config: Config):void;
getConfig():Promise<Config>;
};
declare global {
interface Window {
LLAPI: typeof LLAPI;
llonebot: typeof llonebot;
LiteLoader: any;
}
}

View File

@ -1,9 +1,12 @@
// 运行在 Electron 主进程 下的插件入口
import * as path from "path";
const fs = require('fs');
import {ipcMain, webContents} from 'electron';
const express = require("express");
import {Group, PostDataSendMsg, User} from "./types";
import {Config, Group, PostDataSendMsg, User} from "./types";
const CHANNEL_SEND_MSG = "llonebot_sendMsg"
const CHANNEL_RECALL_MSG = "llonebot_recallMsg"
@ -11,7 +14,7 @@ const CHANNEL_RECALL_MSG = "llonebot_recallMsg"
let groups: Group[] = []
let friends: User[] = []
function sendIPCMsg(channel: string, data: any){
function sendIPCMsg(channel: string, data: any) {
let contents = webContents.getAllWebContents();
for (const content of contents) {
try {
@ -25,7 +28,7 @@ function sendIPCCallSendQQMsg(postData: PostDataSendMsg) {
sendIPCMsg(CHANNEL_SEND_MSG, postData);
}
function log(msg: any){
function log(msg: any) {
let currentDateTime = new Date().toLocaleString();
fs.appendFile("./llonebot.log", currentDateTime + ":" + msg + "\n", (err: any) => {
@ -33,11 +36,9 @@ function log(msg: any){
}
function startExpress(event: any) {
function startExpress(event: any, port: number) {
// const original_send = (window.webContents.__qqntim_original_object && window.webContents.__qqntim_original_object.send) || window.webContents.send;
const app = express();
const port = 3000;
// 中间件用于解析POST请求的请求体
app.use(express.urlencoded({extended: true}));
@ -47,7 +48,7 @@ function startExpress(event: any) {
res.send('llonebot已启动');
})
function handlePost(jsonData: any){
function handlePost(jsonData: any) {
let resData = {
status: 0,
retcode: 0,
@ -56,8 +57,7 @@ function startExpress(event: any) {
}
if (jsonData.action == "send_private_msg" || jsonData.action == "send_group_msg") {
sendIPCCallSendQQMsg(jsonData);
}
else if (jsonData.action == "get_group_list"){
} else if (jsonData.action == "get_group_list") {
resData["data"] = groups.map(group => {
return {
group_id: group.uid,
@ -71,10 +71,9 @@ function startExpress(event: any) {
})
}
})
}
else if (jsonData.action == "get_group_member_list"){
} else if (jsonData.action == "get_group_member_list") {
let group = groups.find(group => group.uid == jsonData.params.group_id)
if (group){
if (group) {
resData["data"] = group?.members?.map(member => {
let role = "member"
switch (member.role) {
@ -82,11 +81,11 @@ function startExpress(event: any) {
role = "owner"
break;
}
case 3:{
case 3: {
role = "admin"
break
}
case 2:{
case 2: {
role = "member"
break
}
@ -102,24 +101,22 @@ function startExpress(event: any) {
}
}) || []
}
else{
} else {
resData["data"] = []
}
}
else if (jsonData.action == "get_friend_list"){
resData["data"] = friends.map(friend=>{
} else if (jsonData.action == "get_friend_list") {
resData["data"] = friends.map(friend => {
return {
user_id: friend.uin,
user_name: friend.nickName,
}
})
}
else if (jsonData.action == "delete_msg"){
sendIPCMsg(CHANNEL_RECALL_MSG, jsonData as {message_id: string})
} else if (jsonData.action == "delete_msg") {
sendIPCMsg(CHANNEL_RECALL_MSG, jsonData as { message_id: string })
}
return resData
}
// 处理POST请求的路由
app.post('/', (req: any, res: any) => {
let jsonData: PostDataSendMsg = req.body;
@ -140,17 +137,14 @@ function startExpress(event: any) {
})
app.post('/send_msg', (req: any, res: any) => {
let jsonData: PostDataSendMsg = req.body;
if (jsonData.message_type == "private"){
if (jsonData.message_type == "private") {
jsonData.action = "send_private_msg"
}
else if (jsonData.message_type == "group"){
} else if (jsonData.message_type == "group") {
jsonData.action = "send_group_msg"
}
else {
if (jsonData.params.group_id){
} else {
if (jsonData.params.group_id) {
jsonData.action = "send_group_msg"
}
else{
} else {
jsonData.action = "send_private_msg"
}
}
@ -163,7 +157,7 @@ function startExpress(event: any) {
let resData = handlePost(jsonData)
res.send(resData)
})
app.listen(port,"0.0.0.0", () => {
app.listen(port, "0.0.0.0", () => {
console.log(`服务器已启动,监听端口 ${port}`);
});
}
@ -171,30 +165,37 @@ function startExpress(event: any) {
// 加载插件时触发
function onLoad(plugin: any) {
function getConfig(): Config{
if (!fs.existsSync(configFilePath)) {
return {"port":3000, "host": "http://localhost:5000/"}
} else {
const data = fs.readFileSync(configFilePath, "utf-8");
return JSON.parse(data);
}
}
ipcMain.on("startExpress", (event: any, arg: any) => {
startExpress(event)
startExpress(event, getConfig().port)
})
ipcMain.on("updateGroups", (event: any, arg: Group[]) => {
for(const group of arg){
for (const group of arg) {
let existGroup = groups.find(g => g.uid == group.uid)
if (existGroup){
if (!existGroup.members){
if (existGroup) {
if (!existGroup.members) {
existGroup.members = []
}
existGroup.name = group.name
for (const member of group.members || []){
for (const member of group.members || []) {
let existMember = existGroup.members?.find(m => m.uin == member.uin)
if (existMember){
if (existMember) {
existMember.nick = member.nick
existMember.cardName = member.cardName
}
else{
} else {
existGroup.members?.push(member)
}
}
}
else{
} else {
groups.push(group)
}
}
@ -206,14 +207,14 @@ function onLoad(plugin: any) {
})
ipcMain.on("postOnebotData", (event: any, arg: any) => {
// try {
// // const fetch2 = require("./electron-fetch");
// }catch (e) {
// log(e)
// }
// try {
// // const fetch2 = require("./electron-fetch");
// }catch (e) {
// log(e)
// }
log("开始post新消息事件到服务器")
try {
fetch("http://192.168.1.5:5000/", {
fetch(getConfig().host, {
method: "POST",
headers: {
"Content-Type": "application/json"
@ -224,7 +225,7 @@ function onLoad(plugin: any) {
}, (err: any) => {
log("新消息事件上传失败:" + err + JSON.stringify(arg));
});
}catch (e: any){
} catch (e: any) {
log(e.toString())
}
})
@ -232,6 +233,17 @@ function onLoad(plugin: any) {
ipcMain.on("llonebot_log", (event: any, arg: any) => {
log(arg)
})
if (!fs.existsSync(plugin.path.data)) {
fs.mkdirSync(plugin.path.data, {recursive: true});
}
const configFilePath = path.join(plugin.path.data, "config.json")
ipcMain.handle("llonebot_getConfig", (event: any, arg: any) => {
return getConfig()
})
ipcMain.on("llonebot_setConfig", (event: any, arg: Config) => {
fs.writeFileSync(configFilePath, JSON.stringify(arg, null, 2), "utf-8")
})
}

View File

@ -1,6 +1,6 @@
// Electron 主进程 与 渲染进程 交互的桥梁
import {Group, PostDataSendMsg, User} from "./types";
import {Config, Group, PostDataSendMsg, User} from "./types";
// type Group = import( "./types").Group;
// type PostDataSendMsg = import( "./types").PostDataSendMsg;
// type User = import( "./types").User;
@ -35,6 +35,12 @@ contextBridge.exposeInMainWorld("llonebot", {
},
log: (data: any) => {
ipcRenderer.send("log", data);
},
setConfig: (config: Config)=>{
ipcRenderer.send("llonebot_setConfig", config);
},
getConfig: async () => {
return ipcRenderer.invoke("llonebot_getConfig");
}
// startExpress,
});

View File

@ -361,8 +361,42 @@ function onLoad() {
}
// 打开设置界面时触发
function onConfigView(view: any) {
async function onConfigView(view: any) {
// 插件本体的路径
// const plugin_path = (window as any).LiteLoader.plugins.LLOneBot.path;
const {port, host} = await window.llonebot.getConfig()
const html = `
<section>
<div>
<label></label>
<input id="port" type="number" value="${port}"/>
</div>
<div>
<label>(http)</label>
<input id="host" type="text" value="${host}"/>
</div>
<button id="save">(QQ后生效)</button>
</section>
`
const parser = new DOMParser();
const doc = parser.parseFromString(html, "text/html");
doc.getElementById("save")?.addEventListener("click",
() => {
const portEle: HTMLInputElement = document.getElementById("port") as HTMLInputElement
const hostEle: HTMLInputElement = document.getElementById("host") as HTMLInputElement
// const port = doc.querySelector("input[type=number]")?.value
// const host = doc.querySelector("input[type=text]")?.value
// 获取端口和host
const port = portEle.value
const host = hostEle.value
if (port && host) {
window.llonebot.setConfig({
port: parseInt(port),
host: host
})
}
})
doc.querySelectorAll("section").forEach((node) => view.appendChild(node));
}
export {

View File

@ -137,4 +137,9 @@ export type PostDataSendMsg = {
user_id: string,
group_id: string,
message: SendMessage[];
}
}
export type Config = {
port: number,
host: string,
}