fix: concurrency noi tu

This commit is contained in:
tramoc
2025-06-24 22:36:18 +07:00
parent 537be0c4ab
commit e4fc5d97cd
+51 -43
View File
@@ -5,6 +5,7 @@ from core.bot import bot
from discord.ext import commands from discord.ext import commands
from typing import Dict, Set, Optional from typing import Dict, Set, Optional
from datetime import datetime, timedelta from datetime import datetime, timedelta
import threading
# Lazy load repository để tránh lỗi database connection # Lazy load repository để tránh lỗi database connection
noi_tu_repo = None noi_tu_repo = None
@@ -34,6 +35,7 @@ class NoiTuGame:
self.timer_message = None # Tin nhắn hiển thị thời gian self.timer_message = None # Tin nhắn hiển thị thời gian
self.timer_task = None # Task cập nhật thời gian self.timer_task = None # Task cập nhật thời gian
self.start_time = None # Thời gian bắt đầu game self.start_time = None # Thời gian bắt đầu game
self.lock = threading.Lock()
# Khởi tạo game state # Khởi tạo game state
game = NoiTuGame() game = NoiTuGame()
@@ -52,6 +54,9 @@ def get_first_word(word: str) -> str:
def get_last_word(word: str) -> str: def get_last_word(word: str) -> str:
return word.strip().split()[-1] if word else '' return word.strip().split()[-1] if word else ''
def is_valid(prev, next: str) -> bool:
return get_last_word(prev) == get_first_word(next)
def format_time_remaining(seconds: int) -> str: def format_time_remaining(seconds: int) -> str:
"""Format thời gian còn lại""" """Format thời gian còn lại"""
if seconds <= 0: if seconds <= 0:
@@ -324,6 +329,8 @@ async def handle_game_message(message):
# Kiểm tra xem tin nhắn có phải là từ không # Kiểm tra xem tin nhắn có phải là từ không
word = message.content.strip().lower() word = message.content.strip().lower()
if len(word.split()) != 2:
return
# Kiểm tra từ có hợp lệ không # Kiểm tra từ có hợp lệ không
if not await get_noi_tu_repo().is_valid_word(word): if not await get_noi_tu_repo().is_valid_word(word):
@@ -331,14 +338,11 @@ async def handle_game_message(message):
# Kiểm tra người vừa trả lời có trả lời tiếp không # Kiểm tra người vừa trả lời có trả lời tiếp không
if game.last_player_id == message.author.id: if game.last_player_id == message.author.id:
await message.add_reaction('') # ignore
await message.channel.send(f"❌ **{message.author.display_name}**, hãy để người khác trả lời!") # await message.add_reaction('❌')
# await message.channel.send(f"❌ **{message.author.display_name}**, hãy để người khác trả lời!")
return return
# Kiểm tra từ có tồn tại trong DB không
if not await get_noi_tu_repo().is_exist(word):
await message.add_reaction('')
return
# Kiểm tra từ đã được sử dụng chưa # Kiểm tra từ đã được sử dụng chưa
if word in game.used_words: if word in game.used_words:
@@ -348,42 +352,46 @@ async def handle_game_message(message):
# Kiểm tra quy tắc nối từ ghép # Kiểm tra quy tắc nối từ ghép
if game.current_word: if game.current_word:
last = get_last_word(game.current_word) if not is_valid(game.current_word, word):
first = get_first_word(word)
if first != last:
await message.add_reaction('')
await message.channel.send(f"❌ Từ mới phải bắt đầu bằng từ: '{last.upper()}'!")
return return
# Từ hợp lệ # Kiểm tra từ có tồn tại trong DB không
await message.add_reaction('') if not await get_noi_tu_repo().is_exist(word):
await message.add_reaction('')
# Cập nhật game state return
game.current_word = word
game.used_words.add(word) with game.lock:
game.last_player_id = message.author.id if not is_valid(game.current_word, word):
game.last_player_name = message.author.display_name # Lưu tên người chơi return
game.last_message_time = datetime.now() # Từ hợp lệ
await message.add_reaction('')
# Reset timeout
if game.timeout_task: # Cập nhật game state
game.timeout_task.cancel() game.current_word = word
game.timeout_task = asyncio.create_task(game_timeout()) game.used_words.add(word)
game.last_player_id = message.author.id
# Dừng timer task cũ nếu có game.last_player_name = message.author.display_name # Lưu tên người chơi
if game.timer_task: game.last_message_time = datetime.now()
game.timer_task.cancel()
# Reset timeout
# Thông báo từ tiếp theo if game.timeout_task:
next_hint = get_last_word(word).upper() game.timeout_task.cancel()
embed = discord.Embed( game.timeout_task = asyncio.create_task(game_timeout())
title="⏰ Còn lại: 30 giây",
color=discord.Color.blue() # Dừng timer task cũ nếu có
) if game.timer_task:
game.timer_task.cancel()
# Gửi tin nhắn mới và lưu reference
game.timer_message = await message.channel.send(embed=embed) # Thông báo từ tiếp theo
next_hint = get_last_word(word).upper()
# Bắt đầu task cập nhật thời gian embed = discord.Embed(
game.timer_task = asyncio.create_task(update_timer_message()) title="⏰ Còn lại: 30 giây",
color=discord.Color.blue()
)
# Gửi tin nhắn mới và lưu reference
game.timer_message = await message.channel.send(embed=embed)
# Bắt đầu task cập nhật thời gian
game.timer_task = asyncio.create_task(update_timer_message())