diff --git a/plugins/namerena.py b/plugins/namerena.py index 14fd0ab..e221834 100644 --- a/plugins/namerena.py +++ b/plugins/namerena.py @@ -33,12 +33,17 @@ else: TailchatReciveMessage = TypeVar("TailchatReciveMessage") -_version_ = "0.7.1" +_version_ = "0.8.0" CMD_PREFIX = "/namer" EVAL_CMD = "/namerena" -EVAL_SIMPLE_CMD = f"{CMD_PREFIX}" # 用于简化输入 +EVAL_SIMPLE_CMD = f"{CMD_PREFIX}" # 用于简化输入 +# 评分四兄弟 +EVAL_PP_CMD = f"{CMD_PREFIX}-pp" +EVAL_PD_CMD = f"{CMD_PREFIX}-pd" +EVAL_QP_CMD = f"{CMD_PREFIX}-qp" +EVAL_QD_CMD = f"{CMD_PREFIX}-qd" CONVERT_CMD = f"{CMD_PREFIX}-peek" FIGHT_CMD = f"{CMD_PREFIX}-fight" HELP_CMD = f"{CMD_PREFIX}-help" @@ -49,11 +54,19 @@ HELP_MSG = f"""namerena-v[{_version_}] - {HELP_CMD} - 查看帮助 - {EVAL_CMD} - 运行名字竞技场, 每一行是一个输入, 输入格式与网页版相同 - {EVAL_SIMPLE_CMD} - 简化输入 +- {CMD_PREFIX}-[pd|pd|qp|qd] - 你懂的评分 + - 一行一个名字/+连接的多个名字 - {CONVERT_CMD} - 查看一个名字的属性, 每一行一个名字 - {FIGHT_CMD} - 1v1 战斗, 格式是 "AAA+BBB+[seed]" - 例如: "AAA+BBB+seed:123@!" 表示 AAA 和 BBB 以 123@! 为种子进行战斗 - 可以输入多行""" + +def out_msg(cost_time: float) -> str: + use_bun = CONFIG_DATA["use_bun"] + return f"耗时: {cost_time:.3f}s\n版本: {_version_}-{'bun' if use_bun else 'node'}" + + def convert_name(msg: ReciveMessage, client) -> None: # 也是多行 if msg.content.find("\n") == -1: @@ -83,6 +96,37 @@ def convert_name(msg: ReciveMessage, client) -> None: client.send_message(reply) +def run_namerena(input_text: str, fight_mode: bool = False) -> tuple[str, float]: + """运行namerena""" + root_path = Path(__file__).parent + use_bun = CONFIG_DATA["use_bun"] + runner_path = root_path / "md5" / ("md5-api.ts" if use_bun else "md5-api.js") + if not runner_path.exists(): + return "未找到namerena运行文件", 0.0 + run_cmd = ["bun" if use_bun else "node", runner_path] + if fight_mode: + run_cmd += ["fight"] + + start_time = time.time() + try: + with open(root_path / "md5" / "input.txt", "w", encoding="utf-8") as f: + f.write(input_text) + result = subprocess.run( + run_cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + check=False, + ) + if result.returncode == 0: + result = result.stdout.decode("utf-8") + else: + result = result.stderr.decode("utf-8") + except Exception as e: + result = f"发生错误: {e}\n{traceback.format_exc()}" + end_time = time.time() + return result.strip(), end_time - start_time + + def eval_fight(msg: ReciveMessage, client) -> None: if msg.content.find("\n") == -1: # 在判断一下是不是 /xxx xxxx @@ -93,8 +137,12 @@ def eval_fight(msg: ReciveMessage, client) -> None: ) ) return - # 去掉 prefix - names = msg.content[len(EVAL_CMD) :] + # 去掉 prefix, 先判断是完整的还是短的 + names = ( + msg.content[len(EVAL_CMD) :] + if msg.content.startswith(EVAL_CMD) + else msg.content[len(EVAL_SIMPLE_CMD) :] + ) # 去掉第一个 \n names = names[names.find("\n") + 1 :] # 判空, 别报错了 @@ -102,35 +150,8 @@ def eval_fight(msg: ReciveMessage, client) -> None: client.send_message(msg.reply_with("请输入名字")) return - start_time = time.time() - # 开始 try - try: - # 内容写入到 ./md5/input.txt - # 路径是插件文件的相对路径 - root_path = Path(__file__).parent - with open(root_path / "md5" / "input.txt", "w") as f: - f.write(names) - # 执行 node md5-api.js / bun md5-api.ts - use_bun = CONFIG_DATA["use_bun"] - runner_path = root_path / "md5" / ("md5-api.ts" if use_bun else "md5-api.js") - result = subprocess.run( - ["bun", "run", runner_path.absolute()] if use_bun else ["node", runner_path.absolute()], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) - # 获取结果 - out_result = result.stdout.decode("utf-8") - err_result = result.stderr.decode("utf-8") - # 发送结果 - end_time = time.time() - reply = msg.reply_with( - f"{out_result}{err_result}外部耗时:{end_time - start_time:.2f}s\n版本:{_version_}-{'bun' if use_bun else 'node'}" - ) - client.send_message(reply) - except Exception as e: - # 发送错误 - reply = msg.reply_with(f"发生错误:{e}\n{traceback.format_exc()}") - client.send_message(reply) + result = run_namerena(names) + client.send_message(msg.reply_with(f"{result[0]}\n{out_msg(result[1])}")) def run_fights(msg: ReciveMessage, client) -> None: @@ -155,28 +176,42 @@ def run_fights(msg: ReciveMessage, client) -> None: if len(names) < 2: results.append(f"输入错误, 只有{len(names)} 个部分") continue - # 丢进文件里 - root_path = Path(__file__).parent - with open(root_path / "md5" / "input.txt", "w") as f: - f.write("\n".join(names)) - # 执行 node md5-api.js / bun md5-api.ts - use_bun = CONFIG_DATA["use_bun"] - runner_path = root_path / "md5" / ("md5-api.ts" if use_bun else "md5-api.js") - result = subprocess.run( - ["bun", "run", runner_path.absolute(), "fight"] if use_bun else ["node", runner_path.absolute(), "fight"], # 调用 - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) - # 获取结果 - out_result = result.stdout.decode("utf-8") - err_result = result.stderr.decode("utf-8") - if out_result.strip() in names: - results.append(f"{names.index(out_result.strip())}") + result = run_namerena("\n".join(names), fight_mode=True)[0] + if result in names: + results.append(f"{names.index(result)}") else: - results.append(f"{out_result}{err_result}") + results.append(result) # 输出 end_time = time.time() - reply = msg.reply_with(f"{'|'.join(results)}\n耗时:{end_time - start_time:.2f}s\n版本:{_version_}-{'bun' if use_bun else 'node'}") + reply = msg.reply_with(f"{'|'.join(results)}\n{out_msg(end_time - start_time)}") + client.send_message(reply) + + +def eval_score(msg: ReciveMessage, client, template: str) -> None: + content = msg.content[len(EVAL_PP_CMD) :] + # 去掉第一个 \n + content = content[content.find("\n") + 1 :] + # 判空, 别报错了 + if content.strip() == "": + client.send_message(msg.reply_with("请输入名字")) + return + names = content.split("\n") + results = [] + start_time = time.time() + for name in names: + if name.strip() == "": + continue + name = name.split("+") + name = "\n".join(name) + runs = template.format(test=name) + result = run_namerena(runs) + # 只取最后一行括号之前的内容 + last_line = result[0].split("\n")[-1] + last_line = last_line.split("(")[0] + results.append([last_line, result[1]]) + end_time = time.time() + content = "\n".join((f"{score}-{cost_time:.2f}s" for (score, cost_time) in results)) + reply = msg.reply_with(f"{content}\n{out_msg(end_time - start_time)}") client.send_message(reply) @@ -192,6 +227,14 @@ def dispatch_msg(msg: ReciveMessage, client) -> None: run_fights(msg, client) elif msg.content.startswith(CONVERT_CMD): convert_name(msg, client) + elif msg.content.startswith(EVAL_PP_CMD): + eval_score(msg, client, "!test!\n\n{test}") + elif msg.content.startswith(EVAL_PD_CMD): + eval_score(msg, client, "!test!\n\n{test}\n{test}") + elif msg.content.startswith(EVAL_QP_CMD): + eval_score(msg, client, "!test!\n!\n\n{test}") + elif msg.content.startswith(EVAL_QD_CMD): + eval_score(msg, client, "!test!\n!\n\n{test}\n{test}") elif msg.content.startswith(EVAL_SIMPLE_CMD): # 放在最后, 避免覆盖 前面的命令 # 同时过滤掉别的 /namer-xxxxx @@ -208,7 +251,4 @@ def on_tailchat_message(msg: TailchatReciveMessage, client) -> None: def on_config() -> tuple[str, str]: - return ( - "namer.toml", - "use_bun = false # 是否使用 bun" - ) + return ("namer.toml", "use_bun = false # 是否使用 bun")