diff --git a/danding_bot/plugins/group_horse_racing/commands/race.py b/danding_bot/plugins/group_horse_racing/commands/race.py index 0049550..e9a3c56 100644 --- a/danding_bot/plugins/group_horse_racing/commands/race.py +++ b/danding_bot/plugins/group_horse_racing/commands/race.py @@ -7,6 +7,7 @@ from .shared import ( _send_to_scope, _build_race_image_message, _get_user_name, _get_horses_in_order, _format_horse_label, run_race_with_settlement, points_service, + _is_admin_or_owner, ) from ..models import RoomState, HorseState @@ -64,17 +65,7 @@ async def handle_start(bot: Bot, event: Event): return is_participant = user_id in [h.owner_id for h in room.horses.values()] - is_admin = False - if isinstance(event, GroupMessageEvent): - try: - member_info = await bot.get_group_member_info( - group_id=event.group_id, - user_id=int(user_id) - ) - role = member_info.get("role", "") - is_admin = role in ("admin", "owner") - except Exception: - pass + is_admin = await _is_admin_or_owner(bot, event) if not is_participant and not is_admin: await start_cmd.finish("只有参赛者或群管理员可以开赛") @@ -114,17 +105,7 @@ async def handle_cancel_race(bot: Bot, event: Event): return is_participant = user_id in [h.owner_id for h in room.horses.values()] - is_admin = False - if isinstance(event, GroupMessageEvent): - try: - member_info = await bot.get_group_member_info( - group_id=event.group_id, - user_id=int(user_id) - ) - role = member_info.get("role", "") - is_admin = role in ("admin", "owner") - except Exception: - pass + is_admin = await _is_admin_or_owner(bot, event) if not is_participant and not is_admin: await cancel_race_cmd.finish("只有参赛者或群管理员可以取消比赛") diff --git a/danding_bot/plugins/group_horse_racing/commands/shared.py b/danding_bot/plugins/group_horse_racing/commands/shared.py index 4ab9cf8..75b8f96 100644 --- a/danding_bot/plugins/group_horse_racing/commands/shared.py +++ b/danding_bot/plugins/group_horse_racing/commands/shared.py @@ -132,6 +132,21 @@ def _describe_points_delta(delta: int) -> str: return "略有损失" +async def _is_admin_or_owner(bot: Bot, event: Event) -> bool: + """Check if the event sender is a group admin or owner.""" + if not isinstance(event, GroupMessageEvent): + return False + try: + member_info = await bot.get_group_member_info( + group_id=event.group_id, + user_id=int(event.get_user_id()), + ) + return member_info.get("role", "") in ("admin", "owner") + except Exception: + return False + + + def _build_point_changes(room: Room, odds: dict[str, float]) -> tuple[dict[str, int], dict[str, str]]: point_changes: dict[str, int] = {} diff --git a/danding_bot/plugins/group_horse_racing/room_store.py b/danding_bot/plugins/group_horse_racing/room_store.py index 1ee97f9..8a42a23 100644 --- a/danding_bot/plugins/group_horse_racing/room_store.py +++ b/danding_bot/plugins/group_horse_racing/room_store.py @@ -120,22 +120,28 @@ class RoomStore: room.champion_name = champion_name or "" room.tick_count = tick_count or 0 # Restore horses - horses_data = json.loads(horses_json) + try: + horses_data = json.loads(horses_json) if horses_json else {} + except (json.JSONDecodeError, TypeError): + horses_data = {} for name, h_data in horses_data.items(): horse = Horse( - owner_id=h_data["owner_id"], - name=h_data["name"], - index=h_data["index"], + owner_id=h_data.get("owner_id", ""), + name=h_data.get("name", name), + index=h_data.get("index", 0), ) horse.position = h_data.get("position", 0.0) room.horses[name] = horse # Restore bets - bets_data = json.loads(bets_json) + try: + bets_data = json.loads(bets_json) if bets_json else [] + except (json.JSONDecodeError, TypeError): + bets_data = [] for b in bets_data: room.bets.append(Bet( - user_id=b["user_id"], - horse_name=b["horse_name"], - amount=b["amount"], + user_id=b.get("user_id", ""), + horse_name=b.get("horse_name", ""), + amount=b.get("amount", 0), )) room.next_horse_index = max((h.index for h in room.horses.values()), default=0) + 1 self.rooms[scope] = room