From 31dc13f5f0d5444f252bb288598bc2e2c14884bb Mon Sep 17 00:00:00 2001 From: MackerelFish Date: Wed, 4 Sep 2024 18:19:24 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=A2=9E=E5=8A=A0minimap=5Frenderer?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config_default.hjson | 10 +++++++++- config_example.json | 6 +++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/config_default.hjson b/config_default.hjson index 384c20e..5361ac6 100644 --- a/config_default.hjson +++ b/config_default.hjson @@ -29,5 +29,13 @@ //渲染内核,chromium/firefox,默认chromium,性能大约为firefox三倍 "use_broswer":"chromium", //是否使用http2,默认启用 - "http2":true + "http2":true, + //是否启用minimap_renderer + "minimap_renderer_on" = false, + //minimap_renderer地址 + "minimap_renderer_url" = "http://localhost:9876", + //鉴权用户名 参考minimap_renderer的token.json文件 + "minimap_renderer_user_name" = "yuyuko", + //鉴权用户密码 参考minimap_renderer的token.json文件 + "minimap_renderer_password" = "yuyuko" } \ No newline at end of file diff --git a/config_example.json b/config_example.json index 6006b17..b08d9b5 100644 --- a/config_example.json +++ b/config_example.json @@ -8,5 +8,9 @@ "ocr_url":"http://ocr.benx1n.com:23338", "http2":true, "browser":"chromium", - "listen_admin":[1119809439,2622749113] + "listen_admin":[1119809439,2622749113], + "minimap_renderer_on":false, + "minimap_renderer_url":"http://localhost:9876", + "minimap_renderer_user_name":"yuyuko", + "minimap_renderer_password":"yuyuko" } \ No newline at end of file From dee3233f02514f843f2b8b6a47dbdb38fc4ff9c6 Mon Sep 17 00:00:00 2001 From: MackerelFish Date: Wed, 4 Sep 2024 18:33:16 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=B7=BB=E5=8A=A0minimap=5Frenderer?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __init__.py | 29 +++++++++++++++- game/minimap_renderer.py | 74 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 game/minimap_renderer.py diff --git a/__init__.py b/__init__.py index a759926..422cd97 100644 --- a/__init__.py +++ b/__init__.py @@ -10,13 +10,14 @@ from hikari_core.model import Hikari_Model from hikari_core.moudle.wws_real_game import get_diff_ship from hoshino import Service, get_bot, priv -from hoshino.typing import CQEvent, MessageSegment +from hoshino.typing import CQEvent, MessageSegment, NoticeSession from hoshino.util import DailyNumberLimiter, FreqLimiter from loguru import logger from nonebot.exceptions import CQHttpError from .data_source import config, dir_path from .game.ocr import downlod_OcrResult, get_Random_Ocr_Pic, pic2txt_byOCR, upload_OcrResult +from .game.minimap_renderer import get_file, get_rep from .game.pupu import get_pupu_msg from .utils import bytes2b64 @@ -267,3 +268,29 @@ async def OCR_listen(bot, ev: CQEvent): except Exception: logger.error(traceback.format_exc()) return + +@sv.on_notice('group_upload') +async def handle_group_file_upload(session: NoticeSession): + try: + if not config['minimap_renderer_on']: + return + + upload_file = session.ctx.get('file') + upload_file_id = upload_file.get('id') + # 判断文件是否是需要处理的类型 + if not upload_file.get('name').endswith('.wowsreplay'): + return + + if 'url' in upload_file: + base64_file = await get_file(upload_file.get('url')) + await get_rep(base64_file, session) + else: + base64_file = await session.bot.get_file(file_id=upload_file_id) + if 'base64' not in base64_file: + await get_rep(base64_file['url'], session) + else: + await get_rep(base64_file['base64'], session) + + except Exception: + logger.error(traceback.format_exc()) + await session.send(MessageSegment.text('请求minimap_renderer服务异常')) \ No newline at end of file diff --git a/game/minimap_renderer.py b/game/minimap_renderer.py new file mode 100644 index 0000000..932ce8d --- /dev/null +++ b/game/minimap_renderer.py @@ -0,0 +1,74 @@ +import asyncio +import base64 +import hashlib +import os + +import requests +from hoshino.typing import MessageSegment, NoticeSession +from requests.auth import HTTPBasicAuth +from concurrent.futures import ThreadPoolExecutor + +from ..data_source import config + +minimap_renderer_url = config['minimap_renderer_url'] +minimap_renderer_user_name = config['minimap_renderer_user_name'] +minimap_renderer_password = config['minimap_renderer_password'] + +minimap_renderer_temp = "minimap_renderer_temp" +executor = ThreadPoolExecutor() + + +async def get_rep(wows_rep_file_base64: str, session: NoticeSession): + if wows_rep_file_base64.__contains__(".wowsreplay"): + wowsrepla_file = wows_rep_file_base64 + else: + file_hex = hashlib.sha256(wows_rep_file_base64.encode('utf-8')).hexdigest() + file_bytes = base64.b64decode(wows_rep_file_base64) + file_path_temp = os.getcwd() + os.sep + minimap_renderer_temp + os.sep + file_hex + f_d = os.getcwd() + os.sep + minimap_renderer_temp + if not os.path.exists(f_d): + os.makedirs(f_d) + wowsrepla_file = file_path_temp + ".wowsreplay" + with open(wowsrepla_file, 'wb') as f: + f.write(file_bytes) + f.close() + if not os.path.exists(wowsrepla_file): + await session.send(MessageSegment.text("文件不存在,ll和nc 部署的请检查服务是否在一个服务器上,否则请开启base64功能")) + else: + await session.send(MessageSegment.text("正在处理replays文件.预计耗时1分钟")) + loop = asyncio.get_running_loop() + result = await loop.run_in_executor(executor, lambda: upload_http(wowsrepla_file)) + if result is None: + await session.send(MessageSegment.text("生成视频文件异常!请检查 minimap_renderer 是否要更新.")) + else: + await send_video(session, result) + + +def upload_http(wowsrepla_file: str): + upload_url = f'{minimap_renderer_url}/upload_replays_video_url' + with open(wowsrepla_file, 'rb') as file: + files = {'file': file} + response = requests.post(upload_url, files=files, auth=HTTPBasicAuth(minimap_renderer_user_name, minimap_renderer_password), timeout=600) + if response.status_code == 200: + return response.text + return None + + +async def send_video(session: NoticeSession, url: str): + # 构造视频文件消息 + data = str(minimap_renderer_url + "/video_url?file_name=" + url.replace("\"", "")) + await session.send(MessageSegment.video(data)) + + +def get_file(url: str): + response = requests.get(url) + # 确保请求成功 + if response.status_code == 200: + # 获取文件内容 + file_content = response.content + + # 对文件内容进行 Base64 编码 + encoded_content = base64.b64encode(file_content) + + # 将编码后的内容转换为字符串 + return encoded_content.decode('utf-8') \ No newline at end of file