From b7d0c26ad11ef526446340994b0f8b5463e1cafc Mon Sep 17 00:00:00 2001 From: Chun_Qiu Date: Sat, 8 Aug 2026 16:37:05 +0800 Subject: [PATCH] fix: danmaku template now uses event rules; rules apply instantly on save MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - _on_danmaku renders via event_text(rules, 'danmaku', ...) like all other events; hardcoded {uname}说、 {msg} format removed - Drop message_format param from DanmakuHandler/DanmakuClient/server/main - api_rules_post mutates the shared rules dict in place (clear+update) instead of rebinding, so running handlers pick up new templates immediately without restarting TTS - UI save toast: '规则已保存并即时生效' - Verified: custom template 卧槽!、是{uname}!、他说、 {msg} works; save-then-next-danmaku uses new template without restart --- danmaku_handler.py | 21 ++++++++------------- main.py | 3 --- server.py | 10 +++++----- static/index.html | 2 +- 4 files changed, 14 insertions(+), 22 deletions(-) diff --git a/danmaku_handler.py b/danmaku_handler.py index c1c22ca..973ead9 100644 --- a/danmaku_handler.py +++ b/danmaku_handler.py @@ -20,8 +20,6 @@ from event_rules import ( logger = logging.getLogger(__name__) -DANMAKU_FORMAT = "{uname}\u8bf4\u3001 {msg}" - INTERACT_TYPE_NAMES = { 3: "\u5206\u4eab", 4: "\u7279\u522b\u5173\u6ce8", 5: "\u4e92\u7c89", } @@ -32,12 +30,10 @@ class DanmakuHandler(blivedm.BaseHandler): _CMD_CALLBACK_DICT = blivedm.BaseHandler._CMD_CALLBACK_DICT.copy() - def __init__(self, queue: asyncio.Queue, rules: dict | None = None, - message_format: str = DANMAKU_FORMAT): + def __init__(self, queue: asyncio.Queue, rules: dict | None = None): super().__init__() self._queue = queue self._rules = rules or dict(DEFAULT_RULES) - self._message_format = message_format self._count = 0 # ── custom SEND_GIFT callback to capture blind-gift info ────────── @@ -62,11 +58,12 @@ class DanmakuHandler(blivedm.BaseHandler): def _on_danmaku(self, client: blivedm.BLiveClient, message: DanmakuMessage) -> None: if not message.msg.strip(): return - text = self._message_format.format( - uname=message.uname, - msg=message.msg, - uid=message.uid, - ) + text = event_text(self._rules, "danmaku", + uname=message.uname, + msg=message.msg, + uid=message.uid) + if not text: + return self._count += 1 if self._count % 20 == 1: logger.info("Danmaku #%d: %s", self._count, text) @@ -173,13 +170,11 @@ class DanmakuClient: queue: asyncio.Queue, cookies: Optional[dict[str, str]] = None, rules: dict | None = None, - message_format: str = DANMAKU_FORMAT, ): self._room_id = room_id self._queue = queue self._cookies = cookies self._rules = rules or dict(DEFAULT_RULES) - self._message_format = message_format self._client: Optional[blivedm.BLiveClient] = None self._session: Optional["aiohttp.ClientSession"] = None @@ -187,7 +182,7 @@ class DanmakuClient: import aiohttp self._session = await build_danmaku_session(self._cookies) self._client = blivedm.BLiveClient(self._room_id, session=self._session) - handler = DanmakuHandler(self._queue, self._rules, self._message_format) + handler = DanmakuHandler(self._queue, self._rules) self._client.set_handler(handler) self._client.start() logger.info("Connected to room %d", self._room_id) diff --git a/main.py b/main.py index 52022b4..5296be3 100644 --- a/main.py +++ b/main.py @@ -30,8 +30,6 @@ def parse_args() -> argparse.Namespace: choices=["f1", "f2", "m1", "m2", "dvd", "imd1", "jgr", "r1"]) parser.add_argument("--speed", "-s", type=int, default=DEFAULT_SPEED) parser.add_argument("--sessdata", type=str, default="") - parser.add_argument("--format", "-f", type=str, - default="{uname}\u8bf4\u3001 {msg}") parser.add_argument("--no-numbers", action="store_true") parser.add_argument("--list-devices", action="store_true") parser.add_argument("--debug", "-d", action="store_true") @@ -77,7 +75,6 @@ async def main_async(args: argparse.Namespace) -> int: room_id=args.room_id, queue=queue, cookies={"SESSDATA": args.sessdata} if args.sessdata else None, rules=rules, - message_format=args.format, ) async def handle_signal(): diff --git a/server.py b/server.py index 4fea7d4..7d15ad9 100644 --- a/server.py +++ b/server.py @@ -58,7 +58,6 @@ class TTSService: voice = config.get("voice", "f1") speed = config.get("speed", 100) self._volume = config.get("volume", 100) - message_format = config.get("format", "{uname}\u8bf4\u3001 {msg}") convert_numbers = config.get("convert_numbers", True) self.current_config = config self.recent_messages = [] @@ -71,7 +70,6 @@ class TTSService: self._danmaku_client = DanmakuClient( room_id=room_id, queue=self._queue, cookies=self._cookies, rules=event_rules, - message_format=message_format, ) await self._danmaku_client.start() self.running = True @@ -169,7 +167,6 @@ async def api_start(request: web.Request) -> web.Response: config.setdefault("voice", "f1") config.setdefault("speed", 100) config.setdefault("volume", 100) - config.setdefault("format", "{uname}\u8bf4\u3001 {msg}") config.setdefault("convert_numbers", True) if tts_service.running: try: @@ -248,7 +245,6 @@ async def api_rules_get(request: web.Request) -> web.Response: async def api_rules_post(request: web.Request) -> web.Response: - global event_rules try: new_rules = await request.json() except Exception: @@ -275,7 +271,11 @@ async def api_rules_post(request: web.Request) -> web.Response: save_rules(merged) except OSError as e: return web.json_response({"error": f"Failed to save rules: {e}"}, status=500) - event_rules = merged + + # Mutate in place so running handlers (which hold the same dict reference) + # pick up the new rules immediately without restarting TTS. + event_rules.clear() + event_rules.update(merged) return web.json_response({"status": "saved", "rules": event_rules}) diff --git a/static/index.html b/static/index.html index 547b595..f5739ed 100644 --- a/static/index.html +++ b/static/index.html @@ -634,7 +634,7 @@ async function saveRules() { const data = await resp.json(); if (data.error) { alert('保存失败: ' + data.error); return; } renderRules(data.rules); - alert('规则已保存。重启TTS后生效。'); + alert('规则已保存并即时生效。'); } catch(e) { alert('保存失败: ' + e.message); }