diff --git a/db/levels_db.py b/db/levels_db.py index 8e8b1ea..f144bd0 100644 --- a/db/levels_db.py +++ b/db/levels_db.py @@ -76,8 +76,17 @@ class LevelsDBOperator(BaseDBOperator): self.execute_update(update_sql, (decayed, now, cur.get("user_id"), cur.get("group_id"))) return decayed, True + def _thresholds(self): + return [ + 0, + 300, 800, 1500, 2500, 4000, + 6000, 9000, 13000, 18000, 24000, + 32000, 42000, 54000, 70000, 90000, + 115000, 145000, 180000, 220000 + ] + def _compute_level(self, exp: int) -> int: - thresholds = [0, 500, 1000, 1200, 1500, 1800, 4000, 8000, 9000, 20000] + thresholds = self._thresholds() lvl = 1 for t in thresholds: if exp >= t: @@ -89,21 +98,44 @@ class LevelsDBOperator(BaseDBOperator): def level_title(self, level: int) -> str: titles = [ "凡人", + "练气期", "炼体期", "筑基期", "结丹期", "元婴期", "化神期", + "炼虚期", "合体期", "大乘期", "渡劫期", + "散仙", + "地仙", + "天仙", "真仙", + "金仙", + "玄仙", + "太乙金仙", + "大罗金仙", + "圣人", ] if level <= 0: return titles[0] idx = min(level - 1, len(titles) - 1) return titles[idx] + def get_progress(self, exp: int): + thresholds = self._thresholds() + level = self._compute_level(exp) + idx = max(0, min(level - 1, len(thresholds) - 1)) + current = thresholds[idx] + next_t = thresholds[idx + 1] if idx + 1 < len(thresholds) else None + if next_t is None: + return level, current, None, 1.0, 0 + denom = max(1, next_t - current) + percent = max(0.0, min(1.0, (exp - current) / denom)) + remaining = max(0, next_t - exp) + return level, current, next_t, percent, remaining + def add_exp(self, user_id: str, group_id: str, delta: int, reason: Optional[str] = None) -> Tuple[bool, Dict]: if not user_id or not group_id: return False, {"error": "invalid_identity"} diff --git a/utils/decorator/points_decorator.py b/utils/decorator/points_decorator.py index 89b7a57..a79c5e3 100644 --- a/utils/decorator/points_decorator.py +++ b/utils/decorator/points_decorator.py @@ -99,6 +99,11 @@ def points_reward_decorator(points_calculator: Union[int, Callable], source_type if ok and isinstance(lvl, dict) and "level" in lvl and "exp" in lvl: title = levels_db.level_title(int(lvl['level'])) level_msg = f"🔰 当前等级: {lvl['level']}({title}) 经验: {lvl['exp']}" + _, cur_t, next_t, pct, remain = levels_db.get_progress(int(lvl['exp'])) + if next_t is None: + level_msg += "\n📈 进度: 已满级" + else: + level_msg += f"\n📈 进度: {int(pct*100)}%(还差 {remain})" client_msg_id, create_time, new_msg_id = await bot.send_at_message( (roomid if roomid else sender), level_msg, [sender] @@ -178,6 +183,11 @@ def points_reward_decorator(points_calculator: Union[int, Callable], source_type if ok and isinstance(lvl, dict) and "level" in lvl and "exp" in lvl: title = levels_db.level_title(int(lvl['level'])) response += f"\n🔰 当前等级: {lvl['level']}({title}) 经验: {lvl['exp']}" + _, cur_t, next_t, pct, remain = levels_db.get_progress(int(lvl['exp'])) + if next_t is None: + response += "\n📈 进度: 已满级" + else: + response += f"\n📈 进度: {int(pct*100)}%(还差 {remain})" else: logger.warning(f"用户 {sender} 积分奖励失败: {reward_result}") except Exception as e: