From cbda64f6e7cf982ee3577d2dfb5520f64bcbc47a Mon Sep 17 00:00:00 2001 From: liuwei Date: Wed, 19 Nov 2025 09:26:36 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=B1=82=E7=BA=A7=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/xiuxian/config.toml | 68 ++++---------- plugins/xiuxian/main.py | 173 +++++++++++++++++++++++------------- 2 files changed, 130 insertions(+), 111 deletions(-) diff --git a/plugins/xiuxian/config.toml b/plugins/xiuxian/config.toml index d0baf00..3d702c6 100644 --- a/plugins/xiuxian/config.toml +++ b/plugins/xiuxian/config.toml @@ -65,60 +65,28 @@ items = [ "聚灵符:材料:100" ] -# 双轨制突破参数:丹药路径与强行路径 -# pill_threshold:丹药突破修为需求;pill_item:消耗的丹药名;pill_success:成功率 -# force_threshold:强行突破修为需求;force_success:成功率;force_next_realm:成功后的境界 -[Xiuxian.breakthrough] -pill_threshold = 5000 -pill_item = "筑基丹" -pill_success = 0.4 -force_threshold = 20000 -force_success = 0.1 -force_next_realm = "筑基2层" +# 统一的境界配置:定义所有境界的层级提升和突破规则 +# 格式:境界名称 = "每层修为阈值,境界分值,突破丹药名,丹药突破成功率,强行突破成功率,强行突破倍率" +# 突破修为要求自动计算 = 9层 × 每层阈值(达到10层所需修为) +# 强行突破修为要求 = 突破修为要求 × 强行突破倍率 +# 注意:TOML中中文键名需要用引号 +[Xiuxian.realms] +# 格式:境界名 = "每层阈值,境界分值,突破丹药,丹药成功率,强行成功率,强行倍率" +# 注意:每层阈值用于计算层级提升(1-10层),突破要求自动计算为 9×每层阈值 +"炼气" = "1000,10,筑基丹,0.4,0.1,2.0" +"筑基" = "5000,20,金元丹,0.2,0.05,2.0" +"金丹" = "50000,30,结婴丹,0.15,0.03,2.0" +"元婴" = "200000,40,化神丹,0.1,0.02,2.0" +"化神" = "1000000,50,合体丹,0.08,0.01,2.0" +"合体" = "5000000,60,大乘丹,0.05,0.005,2.0" +"大乘" = "10000000,70,渡劫丹,0.03,0.003,2.0" +"渡劫" = "50000000,80,飞升丹,0.02,0.001,2.0" +"真仙" = "0,100,,0,0,0" # 真仙为最高境界,无法再突破 [Xiuxian.leaderboard] # 排行榜键(Redis Sorted Set)。默认使用修为分数,也支持按境界分值映射。 key = "xiuxian:zset:leaderboard:cultivation" realm_key = "xiuxian:zset:leaderboard:realm" -[Xiuxian.realm_score] -# 境界分值映射:用于 realm 排行榜(基础值 + 层数),真仙为固定高分 -stages = [ - "凡人:0", - "炼气:10", - "筑基:20", - "金丹:30", - "元婴:40", - "化神:50", - "合体:60", - "大乘:70", - "渡劫:80", - "真仙:100" -] - -[Xiuxian.layer_up] -# 每提升一层的修为阈值(简化规则):按当前境界前缀应用固定阈值 -thresholds = [ - "炼气:1000", - "筑基:5000", - "金丹:50000", - "元婴:200000", - "化神:1000000", - "合体:5000000", - "大乘:10000000", - "渡劫:50000000" -] - -[Xiuxian.breakthrough_stages] -# 瓶颈突破定义:当前境界(10层):路径:修为消耗:成功率:目标境界 -# 注意:突破修为要求应该与达到10层所需修为一致或略高 -# 炼气10层需要9000修为(9×1000),所以突破要求应该≥9000 -# 筑基10层需要45000修为(9×5000),所以突破要求应该≥45000 -paths = [ - "炼气10层:pill:9000:0.4:筑基1层", # 修复:从5000改为9000,与达到10层所需修为一致 - "炼气10层:hard:18000:0.1:筑基2层", # 修复:从20000改为18000(2倍) - "筑基10层:pill:45000:0.2:金丹1层", # 修复:从50000改为45000,与达到10层所需修为一致 - "筑基10层:hard:90000:0.05:金丹2层" # 修复:从200000改为90000(2倍) -] [Xiuxian.points_exchange] -point_to_stone_rate = 10 \ No newline at end of file +point_to_stone_rate = 10 diff --git a/plugins/xiuxian/main.py b/plugins/xiuxian/main.py index b701e66..5e8f032 100644 --- a/plugins/xiuxian/main.py +++ b/plugins/xiuxian/main.py @@ -290,49 +290,90 @@ class XiuxianPlugin(MessagePluginInterface): pts_cfg = cfg.get("points_exchange", {}) self.point_to_stone_rate = int(pts_cfg.get("point_to_stone_rate", 10)) - bt_cfg = cfg.get("breakthrough", {}) - self.bt_pill_threshold = int(bt_cfg.get("pill_threshold", 5000)) - self.bt_pill_item = bt_cfg.get("pill_item", "筑基丹") - self.bt_pill_success = float(bt_cfg.get("pill_success", 0.4)) - self.bt_force_threshold = int(bt_cfg.get("force_threshold", 20000)) - self.bt_force_success = float(bt_cfg.get("force_success", 0.1)) - self.bt_force_next = bt_cfg.get("force_next_realm", "筑基2层") - - # 解析境界分值与层级提升阈值 - realm_score_cfg = self._config.get("Xiuxian", {}).get("realm_score", {}) - self.realm_score_map = {} - for s in realm_score_cfg.get("stages", []): + # 统一解析境界配置:每层阈值、境界分值、突破规则 + realms_cfg = self._config.get("Xiuxian", {}).get("realms", {}) + if not realms_cfg: + self.LOG.warning("未找到境界配置 [Xiuxian.realms],使用默认配置") + # 提供默认配置作为后备 + realms_cfg = { + "炼气": "1000,10,筑基丹,0.4,0.1,2.0", + "筑基": "5000,20,金元丹,0.2,0.05,2.0", + "金丹": "50000,30,结婴丹,0.15,0.03,2.0", + "元婴": "200000,40,化神丹,0.1,0.02,2.0", + "化神": "1000000,50,合体丹,0.08,0.01,2.0", + "合体": "5000000,60,大乘丹,0.05,0.005,2.0", + "大乘": "10000000,70,渡劫丹,0.03,0.003,2.0", + "渡劫": "50000000,80,飞升丹,0.02,0.001,2.0", + "真仙": "0,100,,0,0,0" + } + + self.realm_score_map = {} # 境界分值映射 + self.layer_threshold_map = {} # 每层修为阈值 + self.break_config = {} # 突破配置:{境界10层: {pill: {...}, hard: {...}}} + + # 境界顺序(用于计算下一个境界) + realm_order = ["炼气", "筑基", "金丹", "元婴", "化神", "合体", "大乘", "渡劫", "真仙"] + + self.LOG.info(f"开始解析境界配置,共{len(realms_cfg)}个境界") + for realm_name, config_str in realms_cfg.items(): try: - n, v = s.split(":") - self.realm_score_map[n] = int(v) + # 解析配置:每层阈值,境界分值,突破丹药,丹药成功率,强行成功率,强行倍率 + parts = config_str.split(",") + if len(parts) < 6: + self.LOG.warning(f"境界配置格式错误: {realm_name}={config_str}") + continue + + layer_threshold = int(parts[0].strip()) + realm_score = int(parts[1].strip()) + pill_item = parts[2].strip() if parts[2].strip() else None + pill_rate = float(parts[3].strip()) if parts[3].strip() else 0.0 + hard_rate = float(parts[4].strip()) if parts[4].strip() else 0.0 + hard_multiplier = float(parts[5].strip()) if parts[5].strip() else 2.0 + + # 存储层级阈值和境界分值 + self.layer_threshold_map[realm_name] = layer_threshold + self.realm_score_map[realm_name] = realm_score + + # 计算突破要求:达到10层需要9层×每层阈值 + breakthrough_cost = 9 * layer_threshold + hard_breakthrough_cost = int(breakthrough_cost * hard_multiplier) + + # 计算下一个境界 + next_realm = None + if realm_name != "真仙": + try: + current_idx = realm_order.index(realm_name) + if current_idx + 1 < len(realm_order): + next_realm = realm_order[current_idx + 1] + except ValueError: + pass + + # 构建突破配置 + if next_realm and layer_threshold > 0: + stage_key = f"{realm_name}10层" + self.break_config[stage_key] = {} + + # 丹药突破路径 + if pill_item and pill_rate > 0: + self.break_config[stage_key]["pill"] = { + "cost": breakthrough_cost, + "rate": pill_rate, + "target": f"{next_realm}1层", + "item": pill_item + } + + # 强行突破路径 + if hard_rate > 0: + self.break_config[stage_key]["hard"] = { + "cost": hard_breakthrough_cost, + "rate": hard_rate, + "target": f"{next_realm}2层" + } + except Exception as e: - self.LOG.warning(f"解析境界分值配置失败: {s}, 错误: {e}") - - layer_up_cfg = self._config.get("Xiuxian", {}).get("layer_up", {}) - self.layer_threshold_map = {} - for s in layer_up_cfg.get("thresholds", []): - try: - n, v = s.split(":") - self.layer_threshold_map[n] = int(v) - except Exception as e: - self.LOG.warning(f"解析层级阈值配置失败: {s}, 错误: {e}") - - # 解析突破阶段配置 - stage_cfg = self._config.get("Xiuxian", {}).get("breakthrough_stages", {}) - self.break_config = {} - for p in stage_cfg.get("paths", []): - try: - cur, path, cost, rate, target = p.split(":") - if cur not in self.break_config: - self.break_config[cur] = {} - self.break_config[cur][path] = { - "cost": int(cost), - "rate": float(rate), - "target": target - } - except Exception as e: - self.LOG.warning(f"解析突破阶段配置失败: {p}, 错误: {e}") - + self.LOG.warning(f"解析境界配置失败: {realm_name}={config_str}, 错误: {e}") + + self.LOG.info(f"境界配置解析完成:层级阈值{len(self.layer_threshold_map)}个,突破配置{len(self.break_config)}个") self.LOG.info(f"[{self.name}] 插件初始化完成,指令:{self._commands}") return True @@ -937,23 +978,6 @@ class XiuxianPlugin(MessagePluginInterface): return False, "未注册" player = self._check_status_update(player) points = int(player.get("cultivation_points", 0)) - # 优化:从数据库读取最新的背包数据,确保数据准确性 - pill_item_count = 0 - if self.xdb: - try: - items = self.xdb.get_inventory(sender) - for item in items: - if item["name"] == self.bt_pill_item: - pill_item_count = item["quantity"] - break - except Exception as e: - logger.warning(f"读取背包数据失败: {e}, user_id={sender}") - # 降级到使用内存中的inventory - inv = player.get("inventory") or {} - pill_item_count = inv.get(self.bt_pill_item, 0) - else: - inv = player.get("inventory") or {} - pill_item_count = inv.get(self.bt_pill_item, 0) # 读取当前瓶颈配置 cur_realm = player.get("realm", "炼气1层") @@ -977,24 +1001,51 @@ class XiuxianPlugin(MessagePluginInterface): if self.revoke: self.revoke.add_message_to_revoke((roomid if roomid else sender), client_msg_id, create_time, new_msg_id, 5) return False, "未配置" + + # 从配置中获取丹药名称 + pill_item_name = pill_conf.get("item") + if not pill_item_name: + client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, "突破丹药未配置", sender) + if self.revoke: + self.revoke.add_message_to_revoke((roomid if roomid else sender), client_msg_id, create_time, new_msg_id, 5) + return False, "丹药未配置" + + # 优化:从数据库读取最新的背包数据,确保数据准确性 + pill_item_count = 0 + if self.xdb: + try: + items = self.xdb.get_inventory(sender) + for item in items: + if item["name"] == pill_item_name: + pill_item_count = item["quantity"] + break + except Exception as e: + logger.warning(f"读取背包数据失败: {e}, user_id={sender}") + # 降级到使用内存中的inventory + inv = player.get("inventory") or {} + pill_item_count = inv.get(pill_item_name, 0) + else: + inv = player.get("inventory") or {} + pill_item_count = inv.get(pill_item_name, 0) + if points < pill_conf["cost"]: client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, "修为不足,无法突破", sender) if self.revoke: self.revoke.add_message_to_revoke((roomid if roomid else sender), client_msg_id, create_time, new_msg_id, 5) return False, "修为不足" if pill_item_count <= 0: - client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, f"缺少丹药:{self.bt_pill_item}", sender) + client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, f"缺少丹药:{pill_item_name}", sender) if self.revoke: self.revoke.add_message_to_revoke((roomid if roomid else sender), client_msg_id, create_time, new_msg_id, 5) return False, "缺少丹药" # 更新内存中的inventory(用于缓存) inv = player.get("inventory") or {} - inv[self.bt_pill_item] = pill_item_count - 1 + inv[pill_item_name] = pill_item_count - 1 player["inventory"] = inv player["cultivation_points"] = points - pill_conf["cost"] if self.xdb: try: - self.xdb.remove_item(sender, self.bt_pill_item, 1) + self.xdb.remove_item(sender, pill_item_name, 1) self.xdb.update_player_fields(sender, {"cultivation_points": player["cultivation_points"]}) self.redis_db.invalidate_player(sender, player.get("group_id", "")) except Exception as e: