添加打劫保释功能
- 打劫失败后自动关押24小时 - 其他人可以使用"保释 @用户"命令花费30积分保释 - 在押期间无法进行打劫 - 保释后立即释放 - 所有记录都会保存在数据库中
This commit is contained in:
@@ -76,6 +76,23 @@ class PointsDBOperator(BaseDBOperator):
|
||||
) ENGINE=InnoDB CHARACTER SET utf8mb4;
|
||||
""")
|
||||
|
||||
# 创建关禁闭记录表
|
||||
self.execute_update("""
|
||||
CREATE TABLE IF NOT EXISTS t_prison_records (
|
||||
id INTEGER PRIMARY KEY AUTO_INCREMENT,
|
||||
user_id VARCHAR(100) NOT NULL,
|
||||
group_id VARCHAR(100) NOT NULL,
|
||||
start_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
end_time TIMESTAMP NOT NULL,
|
||||
reason VARCHAR(255),
|
||||
status TINYINT DEFAULT 1 COMMENT '1:在押 0:已释放',
|
||||
bailout_user_id VARCHAR(100),
|
||||
bailout_time TIMESTAMP,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY `idx_user_group` (user_id, group_id, status)
|
||||
) ENGINE=InnoDB CHARACTER SET utf8mb4;
|
||||
""")
|
||||
|
||||
self.logger.info("积分系统数据库表检查/创建完成")
|
||||
except Exception as e:
|
||||
self.logger.error(f"创建积分系统数据库表失败: {e}")
|
||||
@@ -227,7 +244,7 @@ class PointsDBOperator(BaseDBOperator):
|
||||
self.execute_update("""
|
||||
UPDATE t_sign_record
|
||||
SET points = points + %s
|
||||
WHERE wx_id = %s AND group_id = %s
|
||||
WHERE wx_id = %s AND group__id = %s
|
||||
""", (points, user_id, group_id))
|
||||
elif source == PointSource.GAME:
|
||||
self.execute_update("""
|
||||
@@ -575,4 +592,73 @@ class PointsDBOperator(BaseDBOperator):
|
||||
return stats
|
||||
except Exception as e:
|
||||
self.logger.error(f"获取群组积分统计信息失败: {e}")
|
||||
return stats
|
||||
return stats
|
||||
|
||||
def imprison_user(self, user_id: str, group_id: str, hours: int = 24, reason: str = None) -> bool:
|
||||
"""关押用户
|
||||
Args:
|
||||
user_id: 用户ID
|
||||
group_id: 群组ID
|
||||
hours: 关押时长(小时)
|
||||
reason: 关押原因
|
||||
"""
|
||||
try:
|
||||
end_time = datetime.now() + timedelta(hours=hours)
|
||||
self.execute_update("""
|
||||
INSERT INTO t_prison_records (user_id, group_id, end_time, reason)
|
||||
VALUES (%s, %s, %s, %s)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
start_time=CURRENT_TIMESTAMP, end_time=%s, reason=%s, status=1
|
||||
""", (user_id, group_id, end_time, reason, end_time, reason))
|
||||
return True
|
||||
except Exception as e:
|
||||
self.logger.error(f"关押用户失败: {e}")
|
||||
return False
|
||||
|
||||
def check_prison_status(self, user_id: str, group_id: str) -> Optional[Dict]:
|
||||
"""检查用户是否在押
|
||||
Returns:
|
||||
None: 不在押
|
||||
Dict: 在押信息
|
||||
"""
|
||||
try:
|
||||
records = self.execute_query("""
|
||||
SELECT * FROM t_prison_records
|
||||
WHERE user_id = %s AND group_id = %s AND status = 1
|
||||
AND end_time > CURRENT_TIMESTAMP
|
||||
LIMIT 1
|
||||
""", (user_id, group_id))
|
||||
return records[0] if records else None
|
||||
except Exception as e:
|
||||
self.logger.error(f"检查用户在押状态失败: {e}")
|
||||
return None
|
||||
|
||||
def bailout_user(self, prisoner_id: str, bailout_user_id: str, group_id: str) -> Tuple[bool, str]:
|
||||
"""保释用户
|
||||
Returns:
|
||||
(bool, str): (是否成功, 错误信息)
|
||||
"""
|
||||
try:
|
||||
# 检查是否在押
|
||||
prison_record = self.check_prison_status(prisoner_id, group_id)
|
||||
if not prison_record:
|
||||
return False, "该用户未被关押"
|
||||
|
||||
# 扣除保释金
|
||||
success, result = self.transfer_points(
|
||||
bailout_user_id, "SYSTEM", group_id, 30, "保释金"
|
||||
)
|
||||
if not success:
|
||||
return False, result.get("error", "保释失败")
|
||||
|
||||
# 释放用户
|
||||
self.execute_update("""
|
||||
UPDATE t_prison_records
|
||||
SET status = 0, bailout_user_id = %s, bailout_time = CURRENT_TIMESTAMP
|
||||
WHERE user_id = %s AND group_id = %s AND status = 1
|
||||
""", (bailout_user_id, prisoner_id, group_id))
|
||||
|
||||
return True, "保释成功"
|
||||
except Exception as e:
|
||||
self.logger.error(f"保释用户失败: {e}")
|
||||
return False, f"保释失败: {str(e)}"
|
||||
@@ -1,12 +1,13 @@
|
||||
[PointTrade]
|
||||
enable = true
|
||||
command = ["积分交易", "积分转账", "转账积分", "积分赠送", "赠送积分", "积分转移", "转移积分", "送积分", "积分送人", "送人积分", "积分赠予", "赠予", "我的积分", "积分排行", "打劫"]
|
||||
command = ["积分交易", "积分转账", "转账积分", "积分赠送", "赠送积分", "积分转移", "转移积分", "送积分", "积分送人", "送人积分", "积分赠予", "赠予", "我的积分", "积分排行", "打劫","保释"]
|
||||
command-format = """
|
||||
🔄转账积分:
|
||||
🔄积分交易指令:
|
||||
积分转账 积分数 @用户
|
||||
我的积分 - 查询个人积分详情
|
||||
积分排行 - 查看群内积分排行榜
|
||||
打劫 @用户 - 尝试打劫用户积分(有风险)
|
||||
保释 @用户 - 花费30积分保释他人
|
||||
"""
|
||||
|
||||
# 打劫功能配置
|
||||
|
||||
@@ -71,13 +71,15 @@ class PointTradePlugin(MessagePluginInterface):
|
||||
# 从配置中获取参数
|
||||
point_trade_config = self._config.get("PointTrade", {})
|
||||
self._commands = point_trade_config.get("command",
|
||||
["积分交易", "积分转账", "转账积分", "我的积分", "积分排行", "打劫"])
|
||||
["积分交易", "积分转账", "转账积分",
|
||||
"我的积分", "积分排行", "打劫", "保释"])
|
||||
self.command_format = point_trade_config.get("command-format", """
|
||||
积分交易指令:
|
||||
积分转账 积分数 @用户 - 转账给指定用户
|
||||
我的积分 - 查询个人积分详情
|
||||
积分排行 - 查看群内积分排行榜
|
||||
打劫 @用户 - 尝试打劫用户积分(有风险)
|
||||
保释 @用户 - 花费30积分保释他人
|
||||
""")
|
||||
self.enable = point_trade_config.get("enable", True)
|
||||
|
||||
@@ -141,6 +143,8 @@ class PointTradePlugin(MessagePluginInterface):
|
||||
return self._handle_points_ranking(message)
|
||||
elif command[0] == "打劫":
|
||||
return self._handle_rob_points(message)
|
||||
elif command[0] == "保释":
|
||||
return self._handle_bailout(message)
|
||||
elif command[0] in self._commands:
|
||||
return self._handle_transfer_points(message)
|
||||
else:
|
||||
@@ -551,10 +555,17 @@ class PointTradePlugin(MessagePluginInterface):
|
||||
wcf.send_text(f"❌打劫过程中出现问题:{result.get('error', '未知错误')}", roomid, sender)
|
||||
return True, "打劫失败"
|
||||
else:
|
||||
# 打劫失败,扣除打劫者一定比例的积分作为惩罚
|
||||
penalty_amount = int(robber_total * self.rob_penalty_percent)
|
||||
# 检查是否在押
|
||||
prison_status = self.points_db.check_prison_status(sender, roomid)
|
||||
if prison_status:
|
||||
remaining_time = prison_status['end_time'] - datetime.now()
|
||||
hours = int(remaining_time.total_seconds() / 3600)
|
||||
minutes = int((remaining_time.total_seconds() % 3600) / 60)
|
||||
wcf.send_text(f"❌你正在服刑!\n剩余时间: {hours}小时{minutes}分钟\n可请求他人花费30积分保释。", roomid, sender)
|
||||
return True, "在押状态"
|
||||
|
||||
# 确保至少扣除1点积分
|
||||
# 打劫失败处理
|
||||
penalty_amount = int(robber_total * self.rob_penalty_percent)
|
||||
penalty_amount = max(1, penalty_amount)
|
||||
|
||||
# 记录积分变动
|
||||
@@ -564,14 +575,22 @@ class PointTradePlugin(MessagePluginInterface):
|
||||
)
|
||||
|
||||
if success:
|
||||
# 关押处理
|
||||
self.points_db.imprison_user(
|
||||
robber_wxid, roomid, 24,
|
||||
f"打劫{target_name}失败被捕"
|
||||
)
|
||||
|
||||
# 获取转账后的积分信息
|
||||
from_user = result.get("from_user", {})
|
||||
to_user = result.get("to_user", {})
|
||||
|
||||
# 构建打劫失败消息
|
||||
output = (
|
||||
f"🚨 打劫失败!\n"
|
||||
f"👤{robber_name} 试图打劫 👤{target_name} 但被当场抓获,并赔款!\n"
|
||||
f"👮♂️ 被罚款 {penalty_amount} 积分!\n"
|
||||
f"👤{robber_name} 试图打劫 👤{target_name} 但被当场抓获!\n"
|
||||
f"👮♂️ 被罚款 {penalty_amount} 积分并关押24小时!\n"
|
||||
f"💰 可请求他人花费30积分进行保释\n"
|
||||
f"👤{robber_name} 当前积分: {from_user.get('total_points', 0)}"
|
||||
)
|
||||
|
||||
@@ -585,3 +604,57 @@ class PointTradePlugin(MessagePluginInterface):
|
||||
self.LOG.error(f"处理打劫请求出错: {e}")
|
||||
wcf.send_text(f"❌打劫过程中出现意外:{str(e)}", roomid, sender)
|
||||
return True, f"处理出错: {str(e)}"
|
||||
|
||||
def _handle_bailout(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
||||
"""处理保释命令"""
|
||||
sender = message.get("sender")
|
||||
roomid = message.get("roomid", "")
|
||||
wcf: Wcf = message.get("wcf")
|
||||
xml = message.get("xml", "")
|
||||
|
||||
# 检查是否在群聊中
|
||||
if not roomid:
|
||||
wcf.send_text("❌保释功能仅在群聊中可用!", sender, "")
|
||||
return True, "非群聊环境"
|
||||
|
||||
# 检查@用户是否有效
|
||||
at_users = self.at_list(xml)
|
||||
if len(at_users) != 1:
|
||||
wcf.send_text(f"保释失败❌\n请指定一个保释目标!\n保释 @用户",
|
||||
roomid, sender)
|
||||
return True, "目标无效"
|
||||
|
||||
prisoner_wxid = next(iter(at_users))
|
||||
bailout_wxid = sender
|
||||
|
||||
# 不能保释自己
|
||||
if prisoner_wxid == bailout_wxid:
|
||||
wcf.send_text("❌你不能保释自己!", roomid, sender)
|
||||
return True, "不能保释自己"
|
||||
|
||||
try:
|
||||
# 获取用户昵称
|
||||
prisoner_info = self._get_user_record(prisoner_wxid, roomid)
|
||||
bailout_info = self._get_user_record(bailout_wxid, roomid)
|
||||
|
||||
prisoner_name = prisoner_info.get('wx_nick_name', prisoner_wxid) if prisoner_info else prisoner_wxid
|
||||
bailout_name = bailout_info.get('wx_nick_name', bailout_wxid) if bailout_info else bailout_wxid
|
||||
|
||||
# 执行保释
|
||||
success, message = self.points_db.bailout_user(prisoner_wxid, bailout_wxid, roomid)
|
||||
|
||||
if success:
|
||||
output = (
|
||||
f"✅ 保释成功!\n"
|
||||
f"👤{bailout_name} 花费30积分保释了 👤{prisoner_name}"
|
||||
)
|
||||
wcf.send_text(output, roomid, sender)
|
||||
return True, "保释成功"
|
||||
else:
|
||||
wcf.send_text(f"❌保释失败: {message}", roomid, sender)
|
||||
return True, "保释失败"
|
||||
|
||||
except Exception as e:
|
||||
self.LOG.error(f"处理保释请求出错: {e}")
|
||||
wcf.send_text(f"❌保释过程中出现意外:{str(e)}", roomid, sender)
|
||||
return True, f"处理出错: {str(e)}"
|
||||
|
||||
Reference in New Issue
Block a user