feat(bot): use runtime api for bot data
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import logging
|
||||
import asyncio
|
||||
import logging
|
||||
import asyncio
|
||||
from datetime import datetime
|
||||
from uuid import uuid4
|
||||
|
||||
from nonebot.adapters.onebot.v11 import Bot, Event, GroupMessageEvent, Message, MessageSegment, PrivateMessageEvent
|
||||
|
||||
@@ -27,8 +29,8 @@ async def _get_user_name(bot: Bot, scope: str, user_id: str) -> str:
|
||||
group_id = int(scope.split("_", 1)[1])
|
||||
info = await bot.get_group_member_info(group_id=group_id, user_id=int(user_id))
|
||||
return info.get("card") or info.get("nickname") or user_id
|
||||
except Exception:
|
||||
pass
|
||||
except Exception as exc:
|
||||
logger.debug("获取赛马用户昵称失败 scope=%s user_id=%s error=%s", scope, user_id, exc)
|
||||
return user_id
|
||||
|
||||
|
||||
@@ -142,13 +144,14 @@ async def _is_admin_or_owner(bot: Bot, event: Event) -> bool:
|
||||
user_id=int(event.get_user_id()),
|
||||
)
|
||||
return member_info.get("role", "") in ("admin", "owner")
|
||||
except Exception:
|
||||
return False
|
||||
except Exception as exc:
|
||||
logger.debug("检查赛马管理员权限失败 user_id=%s error=%s", getattr(event, "user_id", ""), exc)
|
||||
return False
|
||||
|
||||
|
||||
|
||||
def _build_point_changes(room: Room, odds: dict[str, float]) -> tuple[dict[str, int], dict[str, str]]:
|
||||
point_changes: dict[str, int] = {}
|
||||
def _build_point_changes(room: Room, odds: dict[str, float]) -> tuple[dict[str, int], dict[str, str]]:
|
||||
point_changes: dict[str, int] = {}
|
||||
|
||||
for horse in room.horses.values():
|
||||
point_changes[horse.owner_id] = point_changes.get(horse.owner_id, 0) + config.PARTICIPANT_REWARD
|
||||
@@ -168,8 +171,23 @@ def _build_point_changes(room: Room, odds: dict[str, float]) -> tuple[dict[str,
|
||||
point_summaries = {
|
||||
user_id: _describe_points_delta(delta)
|
||||
for user_id, delta in point_changes.items()
|
||||
}
|
||||
return point_changes, point_summaries
|
||||
}
|
||||
return point_changes, point_summaries
|
||||
|
||||
|
||||
def _build_participants_snapshot(room: Room) -> list[str]:
|
||||
"""生成赛果归档所需的参赛马名快照。"""
|
||||
|
||||
return [horse.name for horse in _get_horses_in_order(room)]
|
||||
|
||||
|
||||
def _build_bet_distribution(room: Room) -> dict[str, int]:
|
||||
"""按马名汇总下注分布,供 xapi 原样归档。"""
|
||||
|
||||
distribution = {horse.name: 0 for horse in _get_horses_in_order(room)}
|
||||
for bet in room.bets:
|
||||
distribution[bet.horse_name] = distribution.get(bet.horse_name, 0) + bet.amount
|
||||
return distribution
|
||||
|
||||
|
||||
async def _send_to_scope(bot: Bot, scope: str, message: str, message_type: str = "race_update", critical: bool = False):
|
||||
@@ -243,10 +261,10 @@ async def settle_race(room: Room) -> tuple[RaceResult, dict[str, float]] | None:
|
||||
for bet in room.bets:
|
||||
user_ids.add(bet.user_id)
|
||||
|
||||
# Record pre-balances
|
||||
pre_balances: dict[str, int] = {}
|
||||
for uid in user_ids:
|
||||
pre_balances[uid] = points_service.get_balance(uid)
|
||||
# Record pre-balances
|
||||
pre_balances: dict[str, int] = {}
|
||||
for uid in user_ids:
|
||||
pre_balances[uid] = await points_service.get_balance(uid)
|
||||
|
||||
# 1. Reward all participants
|
||||
for horse in room.horses.values():
|
||||
@@ -271,10 +289,10 @@ async def settle_race(room: Room) -> tuple[RaceResult, dict[str, float]] | None:
|
||||
except Exception as e:
|
||||
logger.warning(f"payout_winnings failed for {bet.user_id}: {e}")
|
||||
|
||||
# Record post-balances and compute deltas
|
||||
post_balances: dict[str, int] = {}
|
||||
for uid in user_ids:
|
||||
post_balances[uid] = points_service.get_balance(uid)
|
||||
# Record post-balances and compute deltas
|
||||
post_balances: dict[str, int] = {}
|
||||
for uid in user_ids:
|
||||
post_balances[uid] = await points_service.get_balance(uid)
|
||||
|
||||
point_changes: dict[str, int] = {}
|
||||
for uid in user_ids:
|
||||
@@ -285,13 +303,20 @@ async def settle_race(room: Room) -> tuple[RaceResult, dict[str, float]] | None:
|
||||
# Build human-readable summaries
|
||||
_, point_change_summaries = _build_point_changes(room, odds)
|
||||
|
||||
result = RaceResult(
|
||||
champion_name=room.champion_name,
|
||||
champion_owner=champion.owner_id,
|
||||
point_changes=point_changes,
|
||||
point_change_summaries=point_change_summaries,
|
||||
)
|
||||
return result, odds
|
||||
result = RaceResult(
|
||||
race_id=str(uuid4()),
|
||||
scope=room.scope,
|
||||
champion_name=room.champion_name,
|
||||
champion_owner=champion.owner_id,
|
||||
participants=_build_participants_snapshot(room),
|
||||
bet_distribution=_build_bet_distribution(room),
|
||||
duration_ticks=room.tick_count,
|
||||
completed_at=datetime.now(),
|
||||
point_changes=point_changes,
|
||||
point_change_summaries=point_change_summaries,
|
||||
odds_snapshot=odds,
|
||||
)
|
||||
return result, odds
|
||||
|
||||
|
||||
async def run_race_with_settlement(bot: Bot, room: Room, scope: str):
|
||||
@@ -343,12 +368,15 @@ async def run_race_with_settlement(bot: Bot, room: Room, scope: str):
|
||||
if result:
|
||||
result_lines.extend(await _format_point_change_lines(room, result.point_changes, result.point_change_summaries, name_map))
|
||||
|
||||
await message_service.recall_previous_of_type(bot, scope, "race_update")
|
||||
await _send_to_scope(bot, scope, "\n".join(result_lines), "race_result")
|
||||
|
||||
race_engine.stop_race(scope)
|
||||
room_store.delete_room(scope)
|
||||
message_service.clear_pending_recalls(scope)
|
||||
await message_service.recall_previous_of_type(bot, scope, "race_update")
|
||||
await _send_to_scope(bot, scope, "\n".join(result_lines), "race_result")
|
||||
|
||||
if result:
|
||||
await room_store.save_race_result(result)
|
||||
|
||||
race_engine.stop_race(scope)
|
||||
room_store.delete_room(scope)
|
||||
message_service.clear_pending_recalls(scope)
|
||||
|
||||
|
||||
# Import and re-export access functions from access.py (canonical source)
|
||||
|
||||
Reference in New Issue
Block a user