积分打劫功能

This commit is contained in:
liuwei
2025-04-09 17:44:47 +08:00
parent 941ea3a435
commit d1bab5d585

View File

@@ -58,7 +58,7 @@ class PointTradePlugin(MessagePluginInterface):
self.message_util = context.get("message_util") self.message_util = context.get("message_util")
self.gbm = context.get("gbm") self.gbm = context.get("gbm")
self.db_manager = DBConnectionManager.get_instance() self.db_manager = DBConnectionManager.get_instance()
# 初始化积分数据库操作类 # 初始化积分数据库操作类
self.points_db = PointsDBOperator(self.db_manager) self.points_db = PointsDBOperator(self.db_manager)
@@ -70,7 +70,8 @@ class PointTradePlugin(MessagePluginInterface):
# 从配置中获取参数 # 从配置中获取参数
point_trade_config = self._config.get("PointTrade", {}) point_trade_config = self._config.get("PointTrade", {})
self._commands = point_trade_config.get("command", ["积分交易", "积分转账", "转账积分", "我的积分", "积分排行", "打劫"]) self._commands = point_trade_config.get("command",
["积分交易", "积分转账", "转账积分", "我的积分", "积分排行", "打劫"])
self.command_format = point_trade_config.get("command-format", """ self.command_format = point_trade_config.get("command-format", """
积分交易指令: 积分交易指令:
积分转账 积分数 @用户 - 转账给指定用户 积分转账 积分数 @用户 - 转账给指定用户
@@ -79,15 +80,15 @@ class PointTradePlugin(MessagePluginInterface):
打劫 @用户 - 尝试打劫用户积分(有风险) 打劫 @用户 - 尝试打劫用户积分(有风险)
""") """)
self.enable = point_trade_config.get("enable", True) self.enable = point_trade_config.get("enable", True)
# 打劫功能配置 # 打劫功能配置
self.rob_success_rate = point_trade_config.get("rob-success-rate", 0.3) # 打劫成功率 self.rob_success_rate = point_trade_config.get("rob-success-rate", 0.3) # 打劫成功率
self.rob_min_percent = point_trade_config.get("rob-min-percent", 0.1) # 打劫最小百分比 self.rob_min_percent = point_trade_config.get("rob-min-percent", 0.1) # 打劫最小百分比
self.rob_max_percent = point_trade_config.get("rob-max-percent", 0.3) # 打劫最大百分比 self.rob_max_percent = point_trade_config.get("rob-max-percent", 0.3) # 打劫最大百分比
self.rob_penalty_percent = point_trade_config.get("rob-penalty-percent", 0.2) # 打劫失败惩罚百分比 self.rob_penalty_percent = point_trade_config.get("rob-penalty-percent", 0.2) # 打劫失败惩罚百分比
self.rob_cooldown = point_trade_config.get("rob-cooldown", 1800) # 打劫冷却时间(秒) self.rob_cooldown = point_trade_config.get("rob-cooldown", 1800) # 打劫冷却时间(秒)
self.rob_min_points = point_trade_config.get("rob-min-points", 10) # 打劫最低积分要求 self.rob_min_points = point_trade_config.get("rob-min-points", 10) # 打劫最低积分要求
# 打劫冷却记录 {wxid: last_rob_time} # 打劫冷却记录 {wxid: last_rob_time}
self.rob_cooldown_records = {} self.rob_cooldown_records = {}
@@ -182,10 +183,10 @@ class PointTradePlugin(MessagePluginInterface):
try: try:
# 使用积分系统进行转账 # 使用积分系统进行转账
success, result = self.points_db.transfer_points( success, result = self.points_db.transfer_points(
trader_wxid, target_wxid, group_id, trader_wxid, target_wxid, group_id,
reward_points, f"积分转账命令执行" reward_points, f"积分转账命令执行"
) )
if not success: if not success:
error_msg = result.get("error", "未知错误") error_msg = result.get("error", "未知错误")
if "积分不足" in error_msg: if "积分不足" in error_msg:
@@ -198,18 +199,18 @@ class PointTradePlugin(MessagePluginInterface):
f"❌转账失败!\n{error_msg}", f"❌转账失败!\n{error_msg}",
(roomid if roomid else sender), sender) (roomid if roomid else sender), sender)
return True, f"转账失败: {error_msg}" return True, f"转账失败: {error_msg}"
# 获取转账后的积分信息 # 获取转账后的积分信息
from_user = result.get("from_user", {}) from_user = result.get("from_user", {})
to_user = result.get("to_user", {}) to_user = result.get("to_user", {})
# 获取用户昵称 # 获取用户昵称
from_user_info = self._get_user_record(trader_wxid, group_id) from_user_info = self._get_user_record(trader_wxid, group_id)
to_user_info = self._get_user_record(target_wxid, group_id) to_user_info = self._get_user_record(target_wxid, group_id)
from_user_name = from_user_info.get('wx_nick_name', trader_wxid) if from_user_info else trader_wxid from_user_name = from_user_info.get('wx_nick_name', trader_wxid) if from_user_info else trader_wxid
to_user_name = to_user_info.get('wx_nick_name', target_wxid) if to_user_info else target_wxid to_user_name = to_user_info.get('wx_nick_name', target_wxid) if to_user_info else target_wxid
output = ( output = (
f"✅积分转账成功!\n" f"✅积分转账成功!\n"
f"👤{from_user_name} 转给 👤{to_user_name} {reward_points} 积分\n" f"👤{from_user_name} 转给 👤{to_user_name} {reward_points} 积分\n"
@@ -231,23 +232,23 @@ class PointTradePlugin(MessagePluginInterface):
sender = message.get("sender") sender = message.get("sender")
roomid = message.get("roomid", "") roomid = message.get("roomid", "")
wcf: Wcf = message.get("wcf") wcf: Wcf = message.get("wcf")
try: try:
# 获取用户积分信息 # 获取用户积分信息
user_points = self.points_db.get_user_points(sender, roomid) user_points = self.points_db.get_user_points(sender, roomid)
if not user_points: if not user_points:
wcf.send_text(f"❌未找到你的积分记录!请先参与积分活动[签到,答题/t]。", wcf.send_text(f"❌未找到你的积分记录!请先参与积分活动[签到,答题/t]。",
(roomid if roomid else sender), sender) (roomid if roomid else sender), sender)
return True, "未找到积分记录" return True, "未找到积分记录"
# 获取用户昵称 # 获取用户昵称
user_info = self._get_user_record(sender, roomid) user_info = self._get_user_record(sender, roomid)
user_name = user_info.get('wx_nick_name', sender) if user_info else sender user_name = user_info.get('wx_nick_name', sender) if user_info else sender
# 获取用户积分交易记录 # 获取用户积分交易记录
transactions = self.points_db.get_user_transactions(sender, roomid, 5) transactions = self.points_db.get_user_transactions(sender, roomid, 5)
# 统计不同来源的积分 # 统计不同来源的积分
source_stats = {} source_stats = {}
for tx in transactions: for tx in transactions:
@@ -256,10 +257,10 @@ class PointTradePlugin(MessagePluginInterface):
if source not in source_stats: if source not in source_stats:
source_stats[source] = 0 source_stats[source] = 0
source_stats[source] += points source_stats[source] += points
# 构建积分详情消息 # 构建积分详情消息
source_details = "\n".join([f"- {source}: {points}" for source, points in source_stats.items()]) source_details = "\n".join([f"- {source}: {points}" for source, points in source_stats.items()])
# 构建最近交易记录 # 构建最近交易记录
recent_txs = "" recent_txs = ""
if transactions: if transactions:
@@ -270,55 +271,55 @@ class PointTradePlugin(MessagePluginInterface):
desc = tx.get('description', '无描述') desc = tx.get('description', '无描述')
date = tx.get('created_at', '').strftime('%m-%d %H:%M') if tx.get('created_at') else '未知时间' date = tx.get('created_at', '').strftime('%m-%d %H:%M') if tx.get('created_at') else '未知时间'
recent_txs += f"{i}. {date} {tx_type} {points} 积分 - {desc}\n" recent_txs += f"{i}. {date} {tx_type} {points} 积分 - {desc}\n"
output = ( output = (
f"📊 {user_name} 的积分详情\n" f"📊 {user_name} 的积分详情\n"
f"总积分: {user_points.get('total_points', 0)}\n" f"总积分: {user_points.get('total_points', 0)}\n"
f"\n积分来源统计:\n{source_details}" f"\n积分来源统计:\n{source_details}"
f"{recent_txs}" f"{recent_txs}"
) )
wcf.send_text(output, (roomid if roomid else sender), sender) wcf.send_text(output, (roomid if roomid else sender), sender)
return True, "查询积分成功" return True, "查询积分成功"
except Exception as e: except Exception as e:
self.LOG.error(f"查询积分出错: {e}") self.LOG.error(f"查询积分出错: {e}")
wcf.send_text(f"❌查询积分失败!请稍后重试。错误: {str(e)}", wcf.send_text(f"❌查询积分失败!请稍后重试。错误: {str(e)}",
(roomid if roomid else sender), sender) (roomid if roomid else sender), sender)
return True, f"处理出错: {str(e)}" return True, f"处理出错: {str(e)}"
def _handle_points_ranking(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: def _handle_points_ranking(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
"""处理积分排行榜命令""" """处理积分排行榜命令"""
sender = message.get("sender") sender = message.get("sender")
roomid = message.get("roomid", "") roomid = message.get("roomid", "")
wcf: Wcf = message.get("wcf") wcf: Wcf = message.get("wcf")
if not roomid: if not roomid:
wcf.send_text("❌积分排行榜仅在群聊中可用!", sender, "") wcf.send_text("❌积分排行榜仅在群聊中可用!", sender, "")
return True, "非群聊环境" return True, "非群聊环境"
try: try:
# 获取群内积分排行 # 获取群内积分排行
ranking = self.points_db.get_points_ranking(roomid, 10) ranking = self.points_db.get_points_ranking(roomid, 10)
if not ranking: if not ranking:
wcf.send_text("❌暂无积分排行数据!请先参与积分活动。", roomid, sender) wcf.send_text("❌暂无积分排行数据!请先参与积分活动。", roomid, sender)
return True, "无排行数据" return True, "无排行数据"
# 构建排行榜消息 # 构建排行榜消息
rank_list = [] rank_list = []
for i, user in enumerate(ranking, 1): for i, user in enumerate(ranking, 1):
user_id = user.get('user_id', '') user_id = user.get('user_id', '')
points = user.get('total_points', 0) points = user.get('total_points', 0)
# 获取用户昵称 # 获取用户昵称
user_info = self._get_user_record(user_id, roomid) user_info = self._get_user_record(user_id, roomid)
user_name = user_info.get('wx_nick_name', user_id) if user_info else user_id user_name = user_info.get('wx_nick_name', user_id) if user_info else user_id
# 添加排名标记 # 添加排名标记
rank_mark = "🥇" if i == 1 else "🥈" if i == 2 else "🥉" if i == 3 else f"{i}." rank_mark = "🥇" if i == 1 else "🥈" if i == 2 else "🥉" if i == 3 else f"{i}."
rank_list.append(f"{rank_mark} {user_name}: {points} 积分") rank_list.append(f"{rank_mark} {user_name}: {points} 积分")
output = ( output = (
f"🏆 积分排行榜 🏆\n" f"🏆 积分排行榜 🏆\n"
f"\n" f"\n"
@@ -326,10 +327,10 @@ class PointTradePlugin(MessagePluginInterface):
f"\n" f"\n"
f"更新时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}" f"更新时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
) )
wcf.send_text(output, roomid, sender) wcf.send_text(output, roomid, sender)
return True, "查询排行榜成功" return True, "查询排行榜成功"
except Exception as e: except Exception as e:
self.LOG.error(f"查询积分排行榜出错: {e}") self.LOG.error(f"查询积分排行榜出错: {e}")
wcf.send_text(f"❌查询积分排行榜失败!请稍后重试。错误: {str(e)}", roomid, sender) wcf.send_text(f"❌查询积分排行榜失败!请稍后重试。错误: {str(e)}", roomid, sender)
@@ -421,18 +422,18 @@ class PointTradePlugin(MessagePluginInterface):
"""处理打劫积分命令""" """处理打劫积分命令"""
import random import random
import time import time
content = str(message.get("content", "")).strip() content = str(message.get("content", "")).strip()
sender = message.get("sender") sender = message.get("sender")
roomid = message.get("roomid", "") roomid = message.get("roomid", "")
wcf: Wcf = message.get("wcf") wcf: Wcf = message.get("wcf")
xml = message.get("xml", "") xml = message.get("xml", "")
# 检查是否在群聊中 # 检查是否在群聊中
if not roomid: if not roomid:
wcf.send_text("❌打劫功能仅在群聊中可用!", sender, "") wcf.send_text("❌打劫功能仅在群聊中可用!", sender, "")
return True, "非群聊环境" return True, "非群聊环境"
# 检查冷却时间 # 检查冷却时间
current_time = time.time() current_time = time.time()
if sender in self.rob_cooldown_records: if sender in self.rob_cooldown_records:
@@ -441,82 +442,82 @@ class PointTradePlugin(MessagePluginInterface):
if time_passed < self.rob_cooldown: if time_passed < self.rob_cooldown:
remaining_time = int(self.rob_cooldown - time_passed) remaining_time = int(self.rob_cooldown - time_passed)
minutes, seconds = divmod(remaining_time, 60) minutes, seconds = divmod(remaining_time, 60)
wcf.send_text(f"❌你最近已经打劫过了,需要冷却 {minutes}{seconds}秒 后才能再次打劫!", wcf.send_text(f"❌你最近已经打劫过了,需要冷却 {minutes}{seconds}秒 后才能再次打劫!",
roomid, sender) roomid, sender)
return True, "冷却中" return True, "冷却中"
# 检查@用户是否有效 # 检查@用户是否有效
at_users = self.at_list(xml) at_users = self.at_list(xml)
if len(at_users) != 1: if len(at_users) != 1:
wcf.send_text(f"打劫失败❌\n请指定一个打劫目标!\n打劫 @用户", wcf.send_text(f"打劫失败❌\n请指定一个打劫目标!\n打劫 @用户",
roomid, sender) roomid, sender)
return True, "目标无效" return True, "目标无效"
target_wxid = next(iter(at_users)) target_wxid = next(iter(at_users))
robber_wxid = sender robber_wxid = sender
# 不能打劫自己 # 不能打劫自己
if target_wxid == robber_wxid: if target_wxid == robber_wxid:
wcf.send_text("❌你不能打劫自己!", roomid, sender) wcf.send_text("❌你不能打劫自己!", roomid, sender)
return True, "不能打劫自己" return True, "不能打劫自己"
try: try:
# 获取打劫者和目标的积分信息 # 获取打劫者和目标的积分信息
robber_points = self.points_db.get_user_points(robber_wxid, roomid) robber_points = self.points_db.get_user_points(robber_wxid, roomid)
target_points = self.points_db.get_user_points(target_wxid, roomid) target_points = self.points_db.get_user_points(target_wxid, roomid)
if not robber_points: if not robber_points:
wcf.send_text("❌你没有积分记录,无法进行打劫!请先参与积分活动。", roomid, sender) wcf.send_text("❌你没有积分记录,无法进行打劫!请先参与积分活动。", roomid, sender)
return True, "打劫者无积分" return True, "打劫者无积分"
if not target_points: if not target_points:
wcf.send_text("❌目标没有积分记录,无法进行打劫!", roomid, sender) wcf.send_text("❌目标没有积分记录,无法进行打劫!", roomid, sender)
return True, "目标无积分" return True, "目标无积分"
robber_total = robber_points.get('total_points', 0) robber_total = robber_points.get('total_points', 0)
target_total = target_points.get('total_points', 0) target_total = target_points.get('total_points', 0)
# 检查最低积分要求 # 检查最低积分要求
if robber_total < self.rob_min_points: if robber_total < self.rob_min_points:
wcf.send_text(f"❌你的积分不足 {self.rob_min_points} 点,无法进行打劫!", roomid, sender) wcf.send_text(f"❌你的积分不足 {self.rob_min_points} 点,无法进行打劫!", roomid, sender)
return True, "打劫者积分不足" return True, "打劫者积分不足"
if target_total < self.rob_min_points: if target_total < self.rob_min_points:
wcf.send_text(f"❌目标积分不足 {self.rob_min_points} 点,不值得打劫!", roomid, sender) wcf.send_text(f"❌目标积分不足 {self.rob_min_points} 点,不值得打劫!", roomid, sender)
return True, "目标积分不足" return True, "目标积分不足"
# 获取用户昵称 # 获取用户昵称
robber_info = self._get_user_record(robber_wxid, roomid) robber_info = self._get_user_record(robber_wxid, roomid)
target_info = self._get_user_record(target_wxid, roomid) target_info = self._get_user_record(target_wxid, roomid)
robber_name = robber_info.get('wx_nick_name', robber_wxid) if robber_info else robber_wxid robber_name = robber_info.get('wx_nick_name', robber_wxid) if robber_info else robber_wxid
target_name = target_info.get('wx_nick_name', target_wxid) if target_info else target_wxid target_name = target_info.get('wx_nick_name', target_wxid) if target_info else target_wxid
# 决定打劫是否成功 # 决定打劫是否成功
is_success = random.random() < self.rob_success_rate is_success = random.random() < self.rob_success_rate
# 更新冷却时间 # 更新冷却时间
self.rob_cooldown_records[sender] = current_time self.rob_cooldown_records[sender] = current_time
if is_success: if is_success:
# 打劫成功,随机获取目标一定比例的积分 # 打劫成功,随机获取目标一定比例的积分
rob_percent = random.uniform(self.rob_min_percent, self.rob_max_percent) rob_percent = random.uniform(self.rob_min_percent, self.rob_max_percent)
rob_amount = int(target_total * rob_percent) rob_amount = int(target_total * rob_percent)
# 确保至少抢到1点积分 # 确保至少抢到1点积分
rob_amount = max(1, rob_amount) rob_amount = max(1, rob_amount)
# 执行积分转移 # 执行积分转移
success, result = self.points_db.transfer_points( success, result = self.points_db.transfer_points(
target_wxid, robber_wxid, roomid, target_wxid, robber_wxid, roomid,
rob_amount, f"{robber_name}打劫" rob_amount, f"{robber_name}打劫"
) )
if success: if success:
# 获取转账后的积分信息 # 获取转账后的积分信息
from_user = result.get("from_user", {}) from_user = result.get("from_user", {})
to_user = result.get("to_user", {}) to_user = result.get("to_user", {})
# 构建打劫成功消息 # 构建打劫成功消息
output = ( output = (
f"🔫 打劫成功!\n" f"🔫 打劫成功!\n"
@@ -524,7 +525,7 @@ class PointTradePlugin(MessagePluginInterface):
f"👤{robber_name} 当前积分: {to_user.get('total_points', 0)}\n" f"👤{robber_name} 当前积分: {to_user.get('total_points', 0)}\n"
f"👤{target_name} 当前积分: {from_user.get('total_points', 0)}" f"👤{target_name} 当前积分: {from_user.get('total_points', 0)}"
) )
wcf.send_text(output, roomid, sender) wcf.send_text(output, roomid, sender)
return True, "打劫成功" return True, "打劫成功"
else: else:
@@ -533,32 +534,32 @@ class PointTradePlugin(MessagePluginInterface):
else: else:
# 打劫失败,扣除打劫者一定比例的积分作为惩罚 # 打劫失败,扣除打劫者一定比例的积分作为惩罚
penalty_amount = int(robber_total * self.rob_penalty_percent) penalty_amount = int(robber_total * self.rob_penalty_percent)
# 确保至少扣除1点积分 # 确保至少扣除1点积分
penalty_amount = max(1, penalty_amount) penalty_amount = max(1, penalty_amount)
# 记录积分变动 # 记录积分变动
success, result = self.points_db.add_points( success, result = self.points_db.transfer_points(
robber_wxid, roomid, -penalty_amount, robber_wxid, target_wxid, roomid,
PointSource.OTHER, f"打劫{target_name}失败的惩罚" penalty_amount, f"打劫{target_name}失败的惩罚"
) )
if success: if success:
# 构建打劫失败消息 # 构建打劫失败消息
output = ( output = (
f"🚨 打劫失败!\n" f"🚨 打劫失败!\n"
f"👤{robber_name} 试图打劫 👤{target_name} 但被当场抓获!\n" f"👤{robber_name} 试图打劫 👤{target_name} 但被当场抓获,并赔款\n"
f"👮‍♂️ 被罚款 {penalty_amount} 积分!\n" f"👮‍♂️ 被罚款 {penalty_amount} 积分!\n"
f"👤{robber_name} 当前积分: {result.get('total_points', 0)}" f"👤{robber_name} 当前积分: {result.get('total_points', 0)}"
) )
wcf.send_text(output, roomid, sender) wcf.send_text(output, roomid, sender)
return True, "打劫失败" return True, "打劫失败"
else: else:
wcf.send_text(f"❌处理打劫惩罚时出现问题:{result.get('error', '未知错误')}", roomid, sender) wcf.send_text(f"❌处理打劫惩罚时出现问题:{result.get('error', '未知错误')}", roomid, sender)
return True, "处理惩罚失败" return True, "处理惩罚失败"
except Exception as e: except Exception as e:
self.LOG.error(f"处理打劫请求出错: {e}") self.LOG.error(f"处理打劫请求出错: {e}")
wcf.send_text(f"❌打劫过程中出现意外:{str(e)}", roomid, sender) wcf.send_text(f"❌打劫过程中出现意外:{str(e)}", roomid, sender)
return True, f"处理出错: {str(e)}" return True, f"处理出错: {str(e)}"