Files
WPSBot/games/points.py

226 lines
7.2 KiB
Python
Raw Normal View History

2025-10-29 11:32:43 +08:00
"""积分系统游戏模块"""
import random
import logging
from datetime import datetime
from games.base import BaseGame
from utils.parser import CommandParser
from core.database import get_db
logger = logging.getLogger(__name__)
class PointsGame(BaseGame):
"""积分系统游戏"""
def __init__(self):
"""初始化游戏"""
super().__init__()
self.db = get_db()
async def handle(self, command: str, chat_id: int, user_id: int) -> str:
"""处理积分相关指令
Args:
command: 指令 ".points", ".checkin", ".leaderboard"
chat_id: 会话ID
user_id: 用户ID
Returns:
回复消息
"""
try:
# 提取参数
_, args = CommandParser.extract_command_args(command)
args = args.strip().lower()
# 每日签到
if args in ['checkin', '签到', '打卡']:
return self._daily_checkin(user_id)
# 积分排行榜
elif args in ['leaderboard', '排行榜', '排行']:
return self._get_leaderboard()
# 积分记录
elif args in ['records', '记录', '历史']:
return self._get_points_records(user_id)
# 默认:查看个人积分
else:
return self._get_user_points(user_id)
except Exception as e:
logger.error(f"处理积分指令错误: {e}", exc_info=True)
return f"❌ 处理指令出错: {str(e)}"
def _daily_checkin(self, user_id: int) -> str:
"""每日签到
Args:
user_id: 用户ID
Returns:
签到结果消息
"""
# 固定签到积分
checkin_points = 10
# 检查是否已签到
today = datetime.now().strftime('%Y-%m-%d')
if self.db.check_daily_checkin(user_id, today):
return f"❌ 今日已签到,明天再来吧!\n\n📅 签到日期:{today}"
# 执行签到
if self.db.daily_checkin(user_id, checkin_points):
# 获取用户积分信息
points_info = self.db.get_user_points(user_id)
text = f"## ✅ 签到成功!\n\n"
text += f"**获得积分**+{checkin_points}\n\n"
text += f"**当前积分**{points_info['available_points']}\n\n"
text += f"**总积分**{points_info['total_points']}\n\n"
text += f"📅 签到日期:{today}\n\n"
text += "💡 提示:每天签到可获得固定积分奖励!"
return text
else:
return "❌ 签到失败,请稍后重试"
def _get_user_points(self, user_id: int) -> str:
"""获取用户积分信息
Args:
user_id: 用户ID
Returns:
积分信息消息
"""
points_info = self.db.get_user_points(user_id)
text = f"## 💎 个人积分\n\n"
text += f"**可用积分**{points_info['available_points']}\n\n"
text += f"**总积分**{points_info['total_points']}\n\n"
text += f"**注册时间**{datetime.fromtimestamp(points_info['created_at']).strftime('%Y-%m-%d %H:%M')}\n\n"
text += "---\n\n"
text += "💡 提示:\n"
text += "• 每日签到可获得 10 积分\n"
text += "• 查看运势可获得随机积分\n"
text += "• 使用 `.points records` 查看积分记录"
return text
def _get_points_records(self, user_id: int, limit: int = 10) -> str:
"""获取用户积分记录
Args:
user_id: 用户ID
limit: 限制数量
Returns:
积分记录消息
"""
records = self.db.get_points_records(user_id, limit)
if not records:
return "📝 暂无积分记录"
text = f"## 📝 积分记录(最近 {len(records)} 条)\n\n"
for record in records:
timestamp = datetime.fromtimestamp(record['created_at']).strftime('%m-%d %H:%M')
points_str = f"+{record['points']}" if record['points'] > 0 else str(record['points'])
source_map = {
'daily_checkin': '每日签到',
'fortune': '运势奖励',
'game_reward': '游戏奖励'
}
source = source_map.get(record['source'], record['source'])
text += f"**{timestamp}** {points_str} 分 - {source}\n"
if record.get('description'):
text += f" *{record['description']}*\n"
text += "\n"
return text
def _get_leaderboard(self, limit: int = 10) -> str:
"""获取积分排行榜
Args:
limit: 限制数量
Returns:
排行榜消息
"""
leaderboard = self.db.get_points_leaderboard(limit)
if not leaderboard:
return "📊 暂无排行榜数据"
text = f"## 🏆 积分排行榜(前 {len(leaderboard)} 名)\n\n"
medals = ["🥇", "🥈", "🥉"] + ["🏅"] * (limit - 3)
for i, user in enumerate(leaderboard):
rank = i + 1
medal = medals[i] if i < len(medals) else "🏅"
username = user.get('username', f"用户{user['user_id']}")
total_points = user.get('total_points', 0)
available_points = user.get('available_points', 0)
text += f"{medal} **第 {rank} 名** {username}\n"
text += f" 总积分:{total_points} 分 | 可用:{available_points}\n\n"
text += "---\n\n"
text += "💡 提示:使用 `.points` 查看个人积分"
return text
def add_fortune_points(self, user_id: int) -> int:
"""为运势游戏添加随机积分奖励
Args:
user_id: 用户ID
Returns:
获得的积分数量
"""
# 随机积分范围1-20分
points = random.randint(1, 20)
if self.db.add_points(user_id, points, "fortune", "运势奖励"):
logger.info(f"用户 {user_id} 通过运势获得 {points} 积分")
return points
else:
logger.error(f"用户 {user_id} 运势积分奖励失败")
return 0
def get_help(self) -> str:
"""获取帮助信息"""
return """## 💎 积分系统
### 基础用法
- `.points` - 查看个人积分
- `.checkin` - 每日签到
- `.points leaderboard` - 积分排行榜
- `.points records` - 积分记录
### 积分获取方式
- **每日签到**固定 10 积分
- **运势占卜**随机 1-20 积分
- **游戏奖励**根据游戏表现获得
### 示例
```
.points
.checkin
.points leaderboard
.points records
```
### 说明
- 每日签到只能进行一次
- 运势积分每次查看都有机会获得
- 积分记录保留最近 20
"""