Files
abot/game_task/game_task_encyclopedia.py

450 lines
17 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import random
from datetime import datetime
import pymysql
from game_task.game_chatgpt_qa import game_question_json, game_answer_json
# 数据库连接配置
db_config = {
'host': '192.168.2.32',
'user': 'root',
'password': 'lw123456',
'database': 'message_archive',
'charset': 'utf8mb4',
'cursorclass': pymysql.cursors.DictCursor
}
# 连接数据库
def get_db_connection():
return pymysql.connect(**db_config)
# 添加群聊
def add_group(group_id, player_id):
conn = get_db_connection()
cursor = conn.cursor()
try:
cursor.execute(
"INSERT INTO t_encyclopedia_groups (group_id) VALUES (%s)",
(group_id,)
)
conn.commit()
return True # 添加成功
except pymysql.err.IntegrityError:
return True # 已存在也视为成功
finally:
cursor.close()
conn.close()
# 获取所有群聊ID
def get_group_ids():
conn = get_db_connection()
cursor = conn.cursor()
try:
cursor.execute("SELECT group_id FROM t_encyclopedia_groups")
return [row['group_id'] for row in cursor.fetchall()]
finally:
cursor.close()
conn.close()
# 确保游戏启动(自动初始化群聊和玩家)
def ensure_game_started(group_id, player_id, player_name="未知玩家"):
conn = get_db_connection()
cursor = conn.cursor()
try:
# 检查并添加群聊
cursor.execute("SELECT group_id FROM t_encyclopedia_groups WHERE group_id = %s", (group_id,))
if not cursor.fetchone():
add_group(group_id, player_id)
# 检查并添加玩家
cursor.execute(
"SELECT player_name FROM t_encyclopedia_players WHERE group_id = %s AND player_id = %s",
(group_id, player_id)
)
existing_player = cursor.fetchone()
if not existing_player:
cursor.execute(
"INSERT INTO t_encyclopedia_players (player_id, group_id, player_name) VALUES (%s, %s, %s)",
(player_id, group_id, player_name)
)
conn.commit()
return (
f"🎉 欢迎加入,{player_name}\n"
f"🌟 已就位\n"
f"🎈 群 {group_id} 等你来玩\n"
f"🌈 快来接任务吧!指令: /t"
)
return None # 已存在则无需额外反馈
finally:
cursor.close()
conn.close()
# 随机分配任务
def assign_random_task(group_id, player_id=None):
conn = get_db_connection()
cursor = conn.cursor()
try:
cursor.execute("SELECT player_id, player_name FROM t_encyclopedia_players WHERE group_id = %s", (group_id,))
players = cursor.fetchall()
if not players:
return (
f"😔 哎呀,群 {group_id} 好安静\n"
f"🌟 没有小伙伴加入\n"
f"🎈 快叫朋友来玩吧!"
)
if player_id:
player_dict = {p['player_id']: p['player_name'] for p in players}
if player_id not in player_dict:
return (
f"😅 嘿,小朋友\n"
f"🌟 ID: {player_id} 还没加入群 {group_id}\n"
f"🎈 用 /s 先报名吧!"
)
holder_id = player_id
holder_name = player_dict[player_id]
else:
holder = random.choice(players)
holder_id = holder['player_id']
holder_name = holder['player_name']
task = game_question_json("请从不同的学科领域生成一个全新问题。")
question = task["question"]
answer = task["answer"]
score = int(task["score"])
description = task.get("description", "")
cursor.execute(
"INSERT INTO t_encyclopedia_active_tasks (group_id, question, answer, score, description, holder_id) VALUES (%s, %s, %s, %s, %s, %s)",
(group_id, question, answer, score, description, holder_id)
)
conn.commit()
cursor.execute(
"SELECT active_task_id FROM t_encyclopedia_active_tasks WHERE group_id = %s AND question = %s AND holder_id = %s ORDER BY assigned_at DESC LIMIT 1",
(group_id, question, holder_id)
)
active_task_id = cursor.fetchone()['active_task_id']
if player_id:
return (
f"🎁 {holder_name},你的新任务来啦!\n"
f"🎈 问题:{question}\n"
f"🌈 群 {group_id} 等你作答\n"
f"🎀 任务ID: {active_task_id}\n"
f"🌼 积分:{score}"
)
else:
return (
f"🎁 新任务来啦!\n"
f"🌟 幸运玩家:{holder_name} \n"
f"🎈 问题:{question}\n"
f"🌈 群 {group_id} 等你抢答\n"
f"🎀 任务ID: {active_task_id}\n"
f"🌼 积分:{score}"
)
finally:
cursor.close()
conn.close()
# 提交答案并计分
def submit_answer(group_id, player_id, task_id, answer):
conn = get_db_connection()
cursor = conn.cursor()
try:
cursor.execute("SELECT player_name FROM t_encyclopedia_players WHERE group_id = %s AND player_id = %s",
(group_id, player_id))
player_row = cursor.fetchone()
if not player_row:
return (
f"😅 嘿,小朋友\n"
f"🌟 ID: {player_id} 还没加入群 {group_id}\n"
f"🎈 用 /s 先报名吧!"
)
player_name = player_row['player_name']
if not task_id.isdigit():
return (
f"😅 哎呀,小调皮\n"
f"🌟 任务ID格式不对哦\n"
f"🎈 应该是纯数字\n"
f"🌈 比如1\n"
f"🎀 再试一次吧!"
)
active_task_id = int(task_id)
cursor.execute(
"SELECT question, answer, score, holder_id, status FROM t_encyclopedia_active_tasks WHERE group_id = %s AND active_task_id = %s",
(group_id, active_task_id)
)
task_data = cursor.fetchone()
if not task_data:
return (
f"😔 哎呀,小伙伴\n"
f"🌼 群 {group_id} 的任务 task_{active_task_id} 不见了\n"
f"🎀 可能已经被抢答或过期啦!"
)
if task_data['status'] == 'completed':
return (
f"😄 哈哈,太慢啦!\n"
f"🌟 任务 task_{active_task_id} 已完成\n"
f"🎈 群 {group_id} 等你抢新任务哦!"
)
question, correct_answer_db, top_score, holder_id, _ = task_data['question'], task_data['answer'].lower(), \
task_data['score'], task_data['holder_id'], task_data['status']
cursor.execute("SELECT player_name FROM t_encyclopedia_players WHERE group_id = %s AND player_id = %s",
(group_id, holder_id))
holder_name = cursor.fetchone()['player_name']
answer_json = {"question": question, "top_score": str(top_score), "answer": answer}
result = game_answer_json(answer_json)
points = int(result["score"])
description = result["description"]
is_correct = points > 0
if is_correct:
cursor.execute(
"UPDATE t_encyclopedia_players SET points = points + %s WHERE group_id = %s AND player_id = %s",
(points, group_id, player_id)
)
cursor.execute(
"UPDATE t_encyclopedia_active_tasks SET status = 'completed' WHERE group_id = %s AND active_task_id = %s",
(group_id, active_task_id)
)
if player_id == holder_id:
message = (
f"🎉 {player_name} 太棒啦!\n"
f"🌟 任务:{question}\n"
f"🎈 答对了,真厉害!\n"
f"🌈 奖励:{points}\n"
f"🎀 提示:{description}"
)
else:
message = (
f"🎉 {player_name} 抢答成功!\n"
f"🌟 任务:{question}\n"
f"🎈 原主:{holder_name}\n"
f"🌈 获得 {points} 分,太棒了!\n"
f"🎀 提示:{description}"
)
else:
cursor.execute(
"UPDATE t_encyclopedia_players SET points = GREATEST(points - 1, 0) WHERE group_id = %s AND player_id = %s",
(group_id, player_id)
)
points = -1
message = (
f"😅 {player_name} 有点小遗憾!\n"
f"🌼 任务:{question}\n"
f"🎈 你答:{answer}\n"
f"🌟 正确答案:{correct_answer_db}\n"
f"🌈 扣 1 分,别灰心!\n"
f"🎀 提示:{description}\n"
f"🌟 任务ID: {active_task_id} 仍可抢答哦!"
)
cursor.execute(
"INSERT INTO t_encyclopedia_task_history (group_id, active_task_id, player_id, answer, is_correct, points_earned) VALUES (%s, %s, %s, %s, %s, %s)",
(group_id, active_task_id, player_id, answer, is_correct, points)
)
conn.commit()
return message
except ValueError as e:
print(f"submit_answer:{e}")
return (
f"😅 哎呀,小调皮\n"
f"🌟 任务ID格式不对哦\n"
f"🎈 应该是纯数字\n"
f"🌈 比如1\n"
f"🎀 再试一次吧!"
)
except Exception as e:
print(f"submit_answer:{e}")
return (
f"😅 哎呀,小调皮\n"
f"🌟 任务ID格式不对哦\n"
f"🎈 应该是纯数字\n"
f"🌈 比如1\n"
f"🎀 再试一次吧!"
)
finally:
cursor.close()
conn.close()
# 显示排行榜
def show_rank(group_id, player_id):
conn = get_db_connection()
cursor = conn.cursor()
try:
cursor.execute(
"SELECT player_name, points FROM t_encyclopedia_players WHERE group_id = %s ORDER BY points DESC LIMIT 10",
(group_id,)
)
ranks = cursor.fetchall()
if not ranks:
return (
f"😔 群 {group_id} 好安静\n"
f"🌟 排行榜还没有人\n"
f"🎈 快来一起玩吧!"
)
rank_text = f"🎉 群 {group_id} 排行榜Top 10\n"
for i, row in enumerate(ranks, 1):
rank_text += f"🌈 {i}. {row['player_name']}: {row['points']}\n"
return rank_text
finally:
cursor.close()
conn.close()
# 显示当前活跃任务
def show_active_tasks(group_id, player_id):
conn = get_db_connection()
cursor = conn.cursor()
try:
cursor.execute("""
SELECT a.active_task_id, a.question, p.player_name, p.player_id
FROM t_encyclopedia_active_tasks a
JOIN t_encyclopedia_players p ON a.holder_id = p.player_id AND a.group_id = p.group_id
WHERE a.group_id = %s AND a.status = 'pending'
""", (group_id,))
tasks = cursor.fetchall()
if not tasks:
return (
f"😄 群 {group_id} 现在很平静\n"
f"🌟 没有活跃任务哦\n"
f"🎈 用 /t 拿一个吧!"
)
task_text = f"🎉 群 {group_id} 当前活跃任务:\n"
for task in tasks:
task_text += (
f"🌈 任务ID: task_{task['active_task_id']}\n"
f"🎀 问题:{task['question']}\n"
f"🌼 持有者:{task['player_name']} \n"
)
return task_text
finally:
cursor.close()
conn.close()
# 列举所有未完成任务
def list_uncompleted_tasks(group_id, player_id):
conn = get_db_connection()
cursor = conn.cursor()
try:
cursor.execute("""
SELECT a.active_task_id, a.question, p.player_name, p.player_id
FROM t_encyclopedia_active_tasks a
JOIN t_encyclopedia_players p ON a.holder_id = p.player_id AND a.group_id = p.group_id
WHERE a.group_id = %s AND a.status = 'pending'
""", (group_id,))
tasks = cursor.fetchall()
if not tasks:
return (
f"😄 群 {group_id} 任务都完成啦\n"
f"🌟 目前没有未完成任务\n"
f"🎈 用 /t 再来一个吧!"
)
task_text = f"🎉 群 {group_id} 所有未完成任务列表:\n"
for task in tasks:
task_text += (
f"🌈 任务ID: task_{task['active_task_id']}\n"
f"🎀 问题:{task['question']}\n"
f"🌼 所属:{task['player_name']}\n"
)
return task_text
finally:
cursor.close()
conn.close()
# 定时任务整点触发排除23:00-08:00
def run_random_task_assignment(group_id):
current_hour = datetime.now().hour
if current_hour >= 23 or current_hour < 9:
print(f"{datetime.now()}{group_id} 当前时间 {current_hour}:00 在23:00-08:00区间跳过任务发放")
return
result = assign_random_task(group_id)
print(f"{datetime.now()} {result}")
# 处理群聊消息
def game_process_message(group_id, player_id, message, player_name="未知玩家"):
# 自动初始化群聊和玩家
init_message = ensure_game_started(group_id, player_id, player_name)
if message == "/s": # 可选:显式加入游戏
return init_message if init_message else (
f"😄 你好呀,{player_name}\n"
f"🌼 已加入游戏 {group_id}\n"
f"🎶 快来一起乐呵吧!\n"
f"🌈 指令:/t 获取任务"
)
elif message == "/ts": # 查看活跃任务
if init_message:
return init_message + "\n🌟 用 /ts 查看当前任务吧!"
return show_active_tasks(group_id, player_id)
elif message == "/l": # 列出未完成任务
if init_message:
return init_message + "\n🌟 用 /l 查看未完成任务吧!"
return list_uncompleted_tasks(group_id, player_id)
elif message.startswith("/a"): # 提交答案
if init_message:
return init_message + "\n🌟 用 /a [任务ID] [答案] 提交答案吧!"
parts = message.split(" ", 2)
if len(parts) < 3:
return (
f"😅 哎呀,小朋友\n"
f"🌟 格式不对哦\n"
f"🎈 正确用法:/a [任务ID] [答案]\n"
f"🌈 例如:/a 1 钒"
)
task_id, answer = parts[1], parts[2]
return submit_answer(group_id, player_id, task_id, answer)
elif message == "/r": # 查看排行榜
if init_message:
return init_message + "\n🌟 用 /r 查看排行榜吧!"
return show_rank(group_id, player_id)
elif message == "/ag": # 可选:手动添加群聊
if init_message:
return init_message # 已自动添加
return add_group(group_id, player_id)
elif message == "/t": # 获取任务
if init_message:
return init_message + "\n🌟 已为你准备任务:"
current_hour = datetime.now().hour
if current_hour >= 23 or current_hour < 9:
return (
f"😴 现在是 {current_hour}:00\n"
f"🌙 太晚啦,小伙伴们休息中\n"
f"🌞 9点到22点再来玩吧"
)
return assign_random_task(group_id, player_id)
else:
return (
f"😄 嘿,小调皮\n"
f"🌟 指令不对哦\n"
f"🎈 可用指令:\n"
f"🌈 /s - 加入游戏(可选)\n"
f"🎀 /ts - 查看活跃任务\n"
f"🌼 /l - 未完成任务\n"
f"🌟 /a [任务ID] [答案] - 提交答案\n"
f"🎈 /ag - 添加群聊(可选)\n"
f"🌈 /t - 主动拿任务\n"
f"🎀 /r - 查看排行榜"
)
# 设置定时任务
def setup_schedule():
group_ids = get_group_ids()
for gid in group_ids:
run_random_task_assignment(group_id=gid)
# 主程序
if __name__ == "__main__":
# 测试用例
print(game_process_message("45317011307@chatroom", "Jyunere", "/t")) # 新用户获取任务
print(game_process_message("45317011307@chatroom", "Jyunere", "/a 18 罗马斗兽场")) # 提交答案
print(game_process_message("45317011307@chatroom", "Jyunere", "/r")) # 查看排行榜