from nonebot import on_command, logger from nonebot.plugin import PluginMetadata from nonebot.adapters.onebot.v11 import MessageEvent from hexi.plugins.core.message_handle import MessageState from nonebot.adapters.onebot.v11 import MessageEvent, MessageSegment from nonebot.typing import T_State import subprocess import chardet import websockets import asyncio import re __plugin_meta__ = PluginMetadata( name="启动服务器", description="测试", usage="测试", type="application", ) test = on_command("启动服务器", aliases={"启动服务器"}) # WebSocket 服务器地址 websocket_server_url = "ws://127.0.0.1:25595/rec_log" bat_ad_path = r"E:/Earth3/Server/run.bat" @test.handle() async def handle_test(event: MessageEvent): try: await test.send("正在启动服务器") await execute_bat_file(bat_ad_path) await test.finish(f"启动服务器成功") except Exception as err: await test.finish(f"服务器启动失败:{err}") async def execute_bat_file(bat_path): process = await asyncio.create_subprocess_exec(bat_path, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False) try: async with websockets.connect(websocket_server_url) as ws: while True: # 读取批处理文件的输出,设置超时时间 output, _ = await asyncio.wait_for(process.stdout.read(), timeout=1.0) if output: # 检测输出的编码类型 encoding = chardet.detect(output)['encoding'] # 使用检测到的编码解码输出 log_line = output.decode(encoding, errors='ignore').strip() print(log_line) # 这里用 print 代替 logger.info # 过滤日志内容 filtered_log = await filter_logs(log_line) if filtered_log: message = f"{filtered_log}" await ws.send(message) else: # 如果没有输出,表示命令已执行完毕 break except asyncio.TimeoutError: pass # 忽略超时异常 except Exception as err: print(err) # 异常处理 finally: process.terminate() # 终止子进程 async def filter_logs(log_content): result = log_to_dict(log_content) return result def log_to_dict(loginfo: str) -> dict: """ 转换log信息 :param loginfo:log信息 """ pattern_join = (r"\[(\d{3}月\d{4} \d{2}:\d{2}:\d{2}.\d{3})\] \[Server thread/INFO\] \[" r"net.minecraft.server.MinecraftServer/]: ([^\s]+) joined the game") pattern_left = (r"\[(\d{3}月\d{4} \d{2}:\d{2}:\d{2}.\d{3})\] \[Server thread/INFO\] \[" r"net.minecraft.server.MinecraftServer/]: ([^\s]+) left the game") pattern_chat = (r"\[(\d{3}月\d{4} \d{2}:\d{2}:\d{2}.\d{3})\] \[Server thread/INFO\] \[" r"net.minecraft.server.MinecraftServer/]: \[.*\] <([^>]+)> (.*)") # 匹配玩家加入信息 join_match = re.match(pattern_join, loginfo) # # 匹配玩家发送消息信息 # chat_match = re.match(pattern_chat, loginfo) # 匹配玩家离开服务器 left_match = re.match(pattern_left, loginfo) if join_match: return {"nickname": join_match.group(2), "message": "加入了服务器"} # elif chat_match: # return {"nickname": chat_match.group(2), "message": chat_match.group(3)} elif left_match: return {"nickname": left_match.group(2), "message": "离开了服务器"} else: return None