98 lines
3.7 KiB
Python
98 lines
3.7 KiB
Python
|
|
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
|