fix: concurrency noi tu

This commit is contained in:
tramoc
2025-06-24 22:36:18 +07:00
parent 537be0c4ab
commit e4fc5d97cd
+44 -36
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('')
return
# Cập nhật game state with game.lock:
game.current_word = word if not is_valid(game.current_word, word):
game.used_words.add(word) return
game.last_player_id = message.author.id # Từ hợp lệ
game.last_player_name = message.author.display_name # Lưu tên người chơi await message.add_reaction('')
game.last_message_time = datetime.now()
# Reset timeout # Cập nhật game state
if game.timeout_task: game.current_word = word
game.timeout_task.cancel() game.used_words.add(word)
game.timeout_task = asyncio.create_task(game_timeout()) game.last_player_id = message.author.id
game.last_player_name = message.author.display_name # Lưu tên người chơi
game.last_message_time = datetime.now()
# Dừng timer task cũ nếu có # Reset timeout
if game.timer_task: if game.timeout_task:
game.timer_task.cancel() game.timeout_task.cancel()
game.timeout_task = asyncio.create_task(game_timeout())
# Thông báo từ tiếp theo # Dừng timer task cũ nếu có
next_hint = get_last_word(word).upper() if game.timer_task:
embed = discord.Embed( game.timer_task.cancel()
title="⏰ Còn lại: 30 giây",
color=discord.Color.blue()
)
# Gửi tin nhắn mới và lưu reference # Thông báo từ tiếp theo
game.timer_message = await message.channel.send(embed=embed) next_hint = get_last_word(word).upper()
embed = discord.Embed(
title="⏰ Còn lại: 30 giây",
color=discord.Color.blue()
)
# Bắt đầu task cập nhật thời gian # Gửi tin nhắn mới và lưu reference
game.timer_task = asyncio.create_task(update_timer_message()) 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())