兼容老的结构。

This commit is contained in:
liuwei
2025-11-19 08:59:58 +08:00
parent 7c5051cca6
commit 740e4fecd0
2 changed files with 223 additions and 183 deletions

View File

@@ -96,27 +96,24 @@ class LevelsDBOperator(BaseDBOperator):
return max(1, lvl - 1)
def level_title(self, level: int) -> str:
# 统一使用xiuxian插件的境界定义
# 与 plugins/xiuxian/config.toml 中的 realm_score 保持一致
titles = [
"凡人",
"练气期",
"炼体期",
"筑基期",
"结丹期",
"元婴期",
"化神期",
"炼虚期",
"合体期",
"大乘期",
"渡劫期",
"",
"",
"",
"真仙",
"金仙",
"玄仙",
"太乙金仙",
"大罗金仙",
"圣人",
"凡人", # 0
"炼气", # 1 (原"练气期")
"筑基", # 2 (原"炼体期"、"筑基期"合并)
"金丹", # 3 (原"结丹期")
"元婴", # 4
"化神", # 5
"合体", # 6 (原"炼虚期"、"合体期"合并)
"大乘", # 7
"渡劫", # 8
"真仙", # 9 (原"散仙"、"地仙"、"天仙"、"真仙"合并)
"金仙", # 10
"", # 11
"太乙金", # 12
"大罗金", # 13
"圣人", # 14
]
if level <= 0:
return titles[0]

View File

@@ -43,32 +43,63 @@ class XiuxianRedisDB:
def get_redis(self):
return self.db_manager.get_redis_connection()
def get_player(self, user_id: str) -> Optional[Dict[str, Any]]:
def get_player(self, user_id: str, group_id: str) -> Optional[Dict[str, Any]]:
"""读取玩家数据兼容旧格式无group_id和新格式有group_id"""
try:
with self.get_redis() as r:
data = r.get(f"{self.player_prefix}{user_id}")
# 优先尝试新格式xiuxian:cache:player:{group_id}:{user_id}
new_key = f"{self.player_prefix}{group_id}:{user_id}"
data = r.get(new_key)
if data:
if isinstance(data, bytes):
data = data.decode("utf-8")
return json.loads(data)
# 兼容旧格式xiuxian:cache:player:{user_id}
old_key = f"{self.player_prefix}{user_id}"
data = r.get(old_key)
if data:
if isinstance(data, bytes):
data = data.decode("utf-8")
player = json.loads(data)
# 如果旧数据没有 group_id使用传入的 group_id
if not player.get("group_id"):
player["group_id"] = group_id
# 迁移到新格式并删除旧格式
r.set(new_key, json.dumps(player, ensure_ascii=False))
r.delete(old_key)
return player
return None
except Exception as e:
logger.error(f"读取玩家数据失败: {e}")
return None
def save_player(self, player: Dict[str, Any]) -> bool:
"""保存玩家数据到新格式,同时删除旧格式(如果存在)"""
try:
with self.get_redis() as r:
r.set(f"{self.player_prefix}{player['user_id']}", json.dumps(player, ensure_ascii=False))
user_id = player.get("user_id")
group_id = player.get("group_id", "")
new_key = f"{self.player_prefix}{group_id}:{user_id}"
old_key = f"{self.player_prefix}{user_id}"
# 保存到新格式
r.set(new_key, json.dumps(player, ensure_ascii=False))
# 删除旧格式(如果存在),确保数据一致性
r.delete(old_key)
return True
except Exception as e:
logger.error(f"保存玩家数据失败: {e}")
return False
def invalidate_player(self, user_id: str):
def invalidate_player(self, user_id: str, group_id: str):
"""失效玩家缓存,同时删除新旧两种格式"""
try:
with self.get_redis() as r:
r.delete(f"{self.player_prefix}{user_id}")
new_key = f"{self.player_prefix}{group_id}:{user_id}"
old_key = f"{self.player_prefix}{user_id}"
r.delete(new_key)
r.delete(old_key) # 兼容删除旧格式
except Exception as e:
logger.error(f"失效玩家缓存失败: {e}")
@@ -422,22 +453,22 @@ class XiuxianPlugin(MessagePluginInterface):
if status in ("Unstable_Qi", "Injured") and until and now >= until:
player["status"] = "Idle"
player["status_until"] = None
self.redis_db.save_player(player)
self._save_player(player)
return player
async def _cmd_register(self, bot: WechatAPIClient, sender: str, roomid: str, content: str) -> Tuple[bool, str]:
dao_name = content.strip()
if not dao_name:
client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else sender), f"❌命令格式错误!\n{self.command_format}", sender)
if self.revoke:
self.revoke.add_message_to_revoke((roomid if roomid else sender), client_msg_id, create_time, new_msg_id, 5)
# client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else sender), f"❌命令格式错误!\n{self.command_format}", 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, "命令格式错误"
player = self.redis_db.get_player(sender)
player = self.redis_db.get_player(sender, roomid or "")
if player:
client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else 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)
self._rate_set(sender, "注册修仙")
# client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else 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)
# self._rate_set(sender, "注册修仙")
return True, "已注册"
root_name, mult = random.choice(self.spirit_roots) if self.spirit_roots else ("凡灵根", 1.0)
player = {
@@ -458,12 +489,7 @@ class XiuxianPlugin(MessagePluginInterface):
self.xdb.create_player(player)
except Exception:
pass
if self.xdb:
try:
self.xdb.update_player_fields(player.get("user_id"), {"status": player.get("status"), "status_until": player.get("status_until")})
except Exception:
pass
self.redis_db.save_player(player)
self._save_player(player)
self._rate_set(sender, "注册修仙")
# 初始化境界排行榜分值
self.redis_db.leaderboard_realm_add(sender, float(self._realm_score(player["realm"])) )
@@ -489,58 +515,53 @@ class XiuxianPlugin(MessagePluginInterface):
lines.append("加入门派 名称")
lines.append("积分购石 积分数")
msg = "\n".join(lines)
client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else sender), msg, sender)
if self.revoke:
self.revoke.add_message_to_revoke((roomid if roomid else sender), client_msg_id, create_time, new_msg_id, 30)
self._rate_set(sender, "帮助")
# client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else sender), msg, sender)
# if self.revoke:
# self.revoke.add_message_to_revoke((roomid if roomid else sender), client_msg_id, create_time, new_msg_id, 30)
# self._rate_set(sender, "帮助")
return True, "帮助"
async def _cmd_points_to_stone(self, bot: WechatAPIClient, sender: str, roomid: str, content: str) -> Tuple[bool, str]:
if not self.points_db:
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)
# 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, "积分未初始化"
player = self._get_player(sender)
player = self._get_player(sender, roomid or "")
if not player:
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)
# 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, "未注册"
try:
pts = int(content.strip())
except Exception:
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)
# 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 pts <= 0:
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)
# 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, "非法数量"
group_id = roomid or ""
ok, res = self.points_db.deduct_points(sender, group_id, pts, PointSource.PLUGIN, "修仙购买灵石")
if not ok:
cur = res.get("current_points", 0)
client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, f"积分不足,当前积分:{cur}", sender)
if self.revoke:
self.revoke.add_message_to_revoke((roomid if roomid else sender), client_msg_id, create_time, new_msg_id, 5)
# client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, f"积分不足,当前积分:{cur}", 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, "积分不足"
rate = int(self.point_to_stone_rate)
if pts < rate:
client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, f"积分不足以兑换1灵石至少需要{rate}积分", sender)
if self.revoke:
self.revoke.add_message_to_revoke((roomid if roomid else sender), client_msg_id, create_time, new_msg_id, 5)
# client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, f"积分不足以兑换1灵石至少需要{rate}积分", 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, "积分不足"
stones_gain = pts // rate
player["spirit_stone"] = int(player.get("spirit_stone", 0)) + stones_gain
if self.xdb:
try:
self.xdb.update_player_fields(sender, {"spirit_stone": player["spirit_stone"]})
except Exception:
pass
self.redis_db.save_player(player)
self._save_player(player)
self._rate_set(sender, "积分购石")
client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, f"✅ 兑换成功,消耗积分{pts},获得灵石{stones_gain}{rate}积分=1灵石", sender)
if self.revoke:
@@ -548,11 +569,11 @@ class XiuxianPlugin(MessagePluginInterface):
return True, "积分购石"
async def _cmd_status(self, bot: WechatAPIClient, sender: str, roomid: str) -> Tuple[bool, str]:
player = self.redis_db.get_player(sender)
player = self.redis_db.get_player(sender, roomid or "")
if not player:
client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else 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)
# client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else 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, "未注册"
player = self._check_status_update(player)
status_code = player.get("status")
@@ -575,21 +596,27 @@ class XiuxianPlugin(MessagePluginInterface):
return True, "状态展示"
async def _cmd_cultivate(self, bot: WechatAPIClient, sender: str, roomid: str) -> Tuple[bool, str]:
player = self.redis_db.get_player(sender)
player = self.redis_db.get_player(sender, roomid or "")
if not player:
client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else 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)
# client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else 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, "未注册"
player = self._check_status_update(player)
status = player.get("status", "Idle")
if status == "Cultivating":
client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else 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)
# client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else 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 status not in ("Idle", "Injured"):
client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else sender), f"当前状态[{status}]不可闭关", sender)
status_cn = {
"Idle": "空闲",
"Cultivating": "闭关",
"Unstable_Qi": "气息不稳",
"Injured": "受伤保护",
}.get(status, str(status))
client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else sender), f"当前状态[{status_cn}]不可闭关", 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, "状态不可闭关"
@@ -603,17 +630,17 @@ class XiuxianPlugin(MessagePluginInterface):
return True, "闭关成功"
async def _cmd_finish_cultivate(self, bot: WechatAPIClient, sender: str, roomid: str) -> Tuple[bool, str]:
player = self.redis_db.get_player(sender)
player = self.redis_db.get_player(sender, roomid or "")
if not player:
client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else 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)
# client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else 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, "未注册"
player = self._check_status_update(player)
if player.get("status") != "Cultivating":
client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else 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)
# client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else 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, "非闭关"
start_iso = player.get("last_cultivate_time")
@@ -643,24 +670,25 @@ class XiuxianPlugin(MessagePluginInterface):
return True, "出关结算"
async def _cmd_gather(self, bot: WechatAPIClient, sender: str, roomid: str, content: str) -> Tuple[bool, str]:
player = self.redis_db.get_player(sender)
player = self.redis_db.get_player(sender, roomid or "")
if not player:
client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else 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)
# client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else 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, "未注册"
player = self._check_status_update(player)
try:
qty = int(content.strip())
except Exception:
client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else sender), f"❌命令格式错误!\n{self.command_format}", sender)
if self.revoke:
self.revoke.add_message_to_revoke((roomid if roomid else sender), client_msg_id, create_time, new_msg_id, 5)
# client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else sender), f"❌命令格式错误!\n{self.command_format}", 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, "命令格式错误"
stones = int(player.get("spirit_stone", 0))
if qty <= 0 or stones < qty:
client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else 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)
# client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else 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, "灵石不足"
player["spirit_stone"] = stones - qty
player["cultivation_points"] = int(player.get("cultivation_points", 0)) + qty * 10
@@ -688,8 +716,8 @@ class XiuxianPlugin(MessagePluginInterface):
self._rate_set(sender, "排行榜")
return True, "排行榜"
def _get_player(self, user_id: str) -> Optional[Dict[str, Any]]:
return self.redis_db.get_player(user_id)
def _get_player(self, user_id: str, group_id: str) -> Optional[Dict[str, Any]]:
return self._get_player_with_cache(user_id, group_id)
def _save_player(self, player: Dict[str, Any]):
if self.xdb:
@@ -703,14 +731,13 @@ class XiuxianPlugin(MessagePluginInterface):
pass
self.redis_db.save_player(player)
def _get_player_with_cache(self, user_id: str) -> Optional[Dict[str, Any]]:
"""读取玩家:优先 Redis未命中则读 DB 并回填缓存。"""
p = self.redis_db.get_player(user_id)
def _get_player_with_cache(self, user_id: str, group_id: str) -> Optional[Dict[str, Any]]:
p = self.redis_db.get_player(user_id, group_id)
if p:
return p
if self.xdb:
dbp = self.xdb.get_player(user_id)
if dbp:
if dbp and dbp.get("group_id", "") == group_id:
dbp.setdefault("spirit_root_mult", 1.0)
dbp.setdefault("inventory", {})
self.redis_db.save_player(dbp)
@@ -742,7 +769,7 @@ class XiuxianPlugin(MessagePluginInterface):
if self.xdb:
try:
self.xdb.update_player_fields(user_id, {"realm": new_realm})
self.redis_db.invalidate_player(user_id)
self.redis_db.invalidate_player(user_id, player.get("group_id", ""))
except Exception:
pass
self._save_player(player)
@@ -762,16 +789,17 @@ class XiuxianPlugin(MessagePluginInterface):
self._set_realm(user_id, player, f"{prefix}{new_layer}")
async def _cmd_signin(self, bot: WechatAPIClient, sender: str, roomid: str) -> Tuple[bool, str]:
player = self._get_player(sender)
player = self._get_player(sender, roomid or "")
if not player:
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)
# 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, "未注册"
player = self._check_status_update(player)
if self.redis_db.check_rate_limited(sender, "签到"):
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)
# 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, "已签到"
reward = 50
player["spirit_stone"] = int(player.get("spirit_stone", 0)) + reward
@@ -795,36 +823,37 @@ class XiuxianPlugin(MessagePluginInterface):
async def _cmd_buy(self, bot: WechatAPIClient, sender: str, roomid: str, content: str) -> Tuple[bool, str]:
parts = content.split()
if len(parts) < 2:
client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, f"❌命令格式错误!\n购买 物品 数量", sender)
if self.revoke:
self.revoke.add_message_to_revoke((roomid if roomid else sender), client_msg_id, create_time, new_msg_id, 5)
# client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, f"❌命令格式错误!\n购买 物品 数量", 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, "命令格式错误"
item_name = parts[0]
try:
qty = int(parts[1])
except Exception:
client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, f"❌命令格式错误!\n购买 物品 数量", sender)
if self.revoke:
self.revoke.add_message_to_revoke((roomid if roomid else sender), client_msg_id, create_time, new_msg_id, 5)
# client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, f"❌命令格式错误!\n购买 物品 数量", 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, "命令格式错误"
player = self._get_player(sender)
player = self._get_player(sender, roomid or "")
if not player:
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)
# 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, "未注册"
player = self._check_status_update(player)
item = next((i for i in self.shop_items if i["name"] == item_name), None)
if not item:
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)
# 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, "商品不存在"
total = item["price"] * qty
stones = int(player.get("spirit_stone", 0))
if qty <= 0 or stones < total:
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)
# 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, "灵石不足"
player["spirit_stone"] = stones - total
inv = player.get("inventory") or {}
@@ -836,7 +865,7 @@ class XiuxianPlugin(MessagePluginInterface):
self.xdb.add_item(sender, item_name, item.get("type","other"), qty)
except Exception:
pass
self.redis_db.save_player(player)
self._save_player(player)
self._rate_set(sender, "购买")
client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, f"✅ 购买成功,{item_name} × {qty}", sender)
if self.revoke:
@@ -844,11 +873,11 @@ class XiuxianPlugin(MessagePluginInterface):
return True, "购买成功"
async def _cmd_bag(self, bot: WechatAPIClient, sender: str, roomid: str) -> Tuple[bool, str]:
player = self._get_player(sender)
player = self._get_player(sender, roomid or "")
if not player:
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)
# 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, "未注册"
inv = player.get("inventory") or {}
items = []
@@ -870,12 +899,13 @@ class XiuxianPlugin(MessagePluginInterface):
return True, "背包"
async def _cmd_breakthrough(self, bot: WechatAPIClient, sender: str, roomid: str) -> Tuple[bool, str]:
player = self._get_player(sender)
player = self._get_player(sender, roomid or "")
if not player:
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)
# 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, "未注册"
player = self._check_status_update(player)
points = int(player.get("cultivation_points", 0))
inv = player.get("inventory") or {}
# 读取当前瓶颈配置
@@ -911,7 +941,7 @@ class XiuxianPlugin(MessagePluginInterface):
try:
self.xdb.remove_item(sender, self.bt_pill_item, 1)
self.xdb.update_player_fields(sender, {"cultivation_points": player["cultivation_points"]})
self.redis_db.invalidate_player(sender)
self.redis_db.invalidate_player(sender, player.get("group_id", ""))
except Exception:
pass
roll = random.random()
@@ -925,6 +955,7 @@ class XiuxianPlugin(MessagePluginInterface):
self.revoke.add_message_to_revoke((roomid if roomid else sender), client_msg_id, create_time, new_msg_id, 10)
return True, "突破成功"
else:
# 失败时也要保存玩家数据
self._save_player(player)
self._rate_set(sender, "突破")
client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, "❌ 突破失败", sender)
@@ -933,12 +964,13 @@ class XiuxianPlugin(MessagePluginInterface):
return False, "突破失败"
async def _cmd_force_breakthrough(self, bot: WechatAPIClient, sender: str, roomid: str) -> Tuple[bool, str]:
player = self._get_player(sender)
player = self._get_player(sender, roomid or "")
if not player:
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)
# 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, "未注册"
player = self._check_status_update(player)
points = int(player.get("cultivation_points", 0))
# 读取当前瓶颈配置
cur_realm = player.get("realm", "炼气1层")
@@ -965,7 +997,7 @@ class XiuxianPlugin(MessagePluginInterface):
if self.xdb:
try:
self.xdb.update_player_fields(sender, {"cultivation_points": player["cultivation_points"]})
self.redis_db.invalidate_player(sender)
self.redis_db.invalidate_player(sender, player.get("group_id", ""))
except Exception:
pass
roll = random.random()
@@ -978,6 +1010,7 @@ class XiuxianPlugin(MessagePluginInterface):
self.revoke.add_message_to_revoke((roomid if roomid else sender), client_msg_id, create_time, new_msg_id, 10)
return True, "强行突破成功"
else:
# 失败时也要保存玩家数据
self._save_player(player)
self._rate_set(sender, "强行突破")
client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, "❌ 强行突破失败,灵气反噬!", sender)
@@ -988,21 +1021,21 @@ class XiuxianPlugin(MessagePluginInterface):
async def _cmd_rob(self, bot: WechatAPIClient, sender: str, roomid: str, content: str) -> Tuple[bool, str]:
target = content.strip().lstrip("@")
if not target:
client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, "命令格式:劫掠 目标wxid", sender)
if self.revoke:
self.revoke.add_message_to_revoke((roomid if roomid else sender), client_msg_id, create_time, new_msg_id, 5)
# client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, "命令格式:劫掠 目标wxid", 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 target == sender:
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)
# 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, "非法目标"
attacker = self._get_player(sender)
defender = self._get_player(target)
attacker = self._get_player(sender, roomid or "")
defender = self._get_player(target, roomid or "")
if not attacker or not defender:
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)
# 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, "未注册"
attacker = self._check_status_update(attacker)
defender = self._check_status_update(defender)
@@ -1049,8 +1082,8 @@ class XiuxianPlugin(MessagePluginInterface):
self.xdb.update_player_fields(attacker.get("user_id"), {"spirit_stone": attacker["spirit_stone"]})
except Exception:
pass
self.redis_db.save_player(defender)
self.redis_db.save_player(attacker)
self._save_player(defender)
self._save_player(attacker)
self._rate_set(sender, "劫掠")
client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, f"✅ 劫掠成功,获得灵石{gain}", sender)
if self.revoke:
@@ -1082,8 +1115,8 @@ 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, "命令格式错误"
giver = self._get_player_with_cache(sender)
receiver = self._get_player_with_cache(target)
giver = self._get_player_with_cache(sender, roomid or "")
receiver = self._get_player_with_cache(target, roomid or "")
if not giver or not receiver:
client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, "双方需已注册", sender)
if self.revoke:
@@ -1108,6 +1141,7 @@ class XiuxianPlugin(MessagePluginInterface):
self.xdb.update_player_fields(target, {"spirit_stone": receiver["spirit_stone"]})
except Exception:
pass
# 使用_save_player确保同时保存到Redis和MariaDB
self._save_player(giver)
self._save_player(receiver)
self._rate_set(sender, "赠与")
@@ -1119,25 +1153,25 @@ class XiuxianPlugin(MessagePluginInterface):
async def _cmd_give_item(self, bot: WechatAPIClient, sender: str, roomid: str, content: str) -> Tuple[bool, str]:
parts = content.strip().split()
if len(parts) < 3:
client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, "命令格式:赠送 目标wxid 物品 数量", sender)
if self.revoke:
self.revoke.add_message_to_revoke((roomid if roomid else sender), client_msg_id, create_time, new_msg_id, 5)
# client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, "命令格式:赠送 目标wxid 物品 数量", 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, "命令格式错误"
target = parts[0].lstrip("@")
item_name = parts[1]
try:
qty = int(parts[2])
except Exception:
client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, "命令格式:赠送 目标wxid 物品 数量", sender)
if self.revoke:
self.revoke.add_message_to_revoke((roomid if roomid else sender), client_msg_id, create_time, new_msg_id, 5)
# client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, "命令格式:赠送 目标wxid 物品 数量", 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, "命令格式错误"
giver = self._get_player(sender)
receiver = self._get_player(target)
giver = self._get_player(sender, roomid or "")
receiver = self._get_player(target, roomid or "")
if not giver or not receiver:
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)
# 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, "未注册"
inv_g = giver.get("inventory") or {}
if inv_g.get(item_name, 0) < qty or qty <= 0:
@@ -1157,8 +1191,8 @@ 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, "转移失败"
self.redis_db.invalidate_player(sender)
self.redis_db.invalidate_player(target)
self.redis_db.invalidate_player(sender, giver.get("group_id", ""))
self.redis_db.invalidate_player(target, receiver.get("group_id", ""))
self._save_player(giver)
self._save_player(receiver)
self._rate_set(sender, "赠送")
@@ -1174,11 +1208,11 @@ 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, "命令格式错误"
player = self._get_player_with_cache(sender)
player = self._get_player_with_cache(sender, roomid or "")
if not player:
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)
# 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, "未注册"
prefix, _ = self._parse_realm(player.get("realm", "炼气1层"))
allowed = {"元婴", "化神", "合体", "大乘", "渡劫", "真仙"}
@@ -1198,8 +1232,11 @@ class XiuxianPlugin(MessagePluginInterface):
if player and clan_id is not None:
player["clan_id"] = int(clan_id)
if self.xdb:
self.xdb.update_player_fields(sender, {"clan_id": player["clan_id"]})
self.redis_db.invalidate_player(sender)
try:
self.xdb.update_player_fields(sender, {"clan_id": player["clan_id"]})
self.redis_db.invalidate_player(sender, player.get("group_id", ""))
except Exception:
pass
self._save_player(player)
self._rate_set(sender, "创建门派")
client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, f"✅ 门派已创建:{name}", sender)
@@ -1214,7 +1251,7 @@ 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, "命令格式错误"
player = self._get_player_with_cache(sender)
player = self._get_player_with_cache(sender, roomid or "")
if not player:
client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, "未注册,请先发送:注册修仙 道号", sender)
if self.revoke:
@@ -1230,8 +1267,11 @@ class XiuxianPlugin(MessagePluginInterface):
return False, "门派不存在"
player["clan_id"] = int(cid) if isinstance(cid, str) else cid
if self.xdb:
self.xdb.update_player_fields(sender, {"clan_id": player["clan_id"]})
self.redis_db.invalidate_player(sender)
try:
self.xdb.update_player_fields(sender, {"clan_id": player["clan_id"]})
self.redis_db.invalidate_player(sender, player.get("group_id", ""))
except Exception:
pass
self._save_player(player)
self._rate_set(sender, "加入门派")
client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, f"✅ 已加入门派:{name}", sender)
@@ -1240,7 +1280,7 @@ class XiuxianPlugin(MessagePluginInterface):
return True, "加入门派"
async def _cmd_clan_exit(self, bot: WechatAPIClient, sender: str, roomid: str) -> Tuple[bool, str]:
player = self._get_player_with_cache(sender)
player = self._get_player_with_cache(sender, roomid or "")
if not player:
client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, "未注册,请先发送:注册修仙 道号", sender)
if self.revoke:
@@ -1248,8 +1288,11 @@ class XiuxianPlugin(MessagePluginInterface):
return False, "未注册"
player["clan_id"] = None
if self.xdb:
self.xdb.update_player_fields(sender, {"clan_id": None})
self.redis_db.invalidate_player(sender)
try:
self.xdb.update_player_fields(sender, {"clan_id": None})
self.redis_db.invalidate_player(sender, player.get("group_id", ""))
except Exception:
pass
self._save_player(player)
self._rate_set(sender, "退出门派")
client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, "✅ 已退出门派", sender)