mirror of
https://github.com/A-Minos/nonebot-plugin-tetris-stats.git
synced 2026-03-05 05:36:54 +08:00
🐛 修复 leagueflow 没有有效数据爆炸 (#508)
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
from typing import NamedTuple
|
from typing import Literal, NamedTuple
|
||||||
|
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
@@ -28,11 +28,16 @@ class Point(NamedTuple):
|
|||||||
|
|
||||||
class Data(BaseModel):
|
class Data(BaseModel):
|
||||||
start_time: datetime = Field(..., alias='startTime')
|
start_time: datetime = Field(..., alias='startTime')
|
||||||
points: list[Point]
|
points: list[Point] = Field(..., min_length=1)
|
||||||
|
|
||||||
|
|
||||||
|
class Empty(BaseModel):
|
||||||
|
start_time: Literal[9007199254740991] = Field(..., alias='startTime')
|
||||||
|
points: list = Field(..., max_length=0)
|
||||||
|
|
||||||
|
|
||||||
class LeagueFlowSuccess(BaseSuccessModel):
|
class LeagueFlowSuccess(BaseSuccessModel):
|
||||||
data: Data
|
data: Data | Empty
|
||||||
|
|
||||||
|
|
||||||
LeagueFlow = LeagueFlowSuccess | FailedModel
|
LeagueFlow = LeagueFlowSuccess | FailedModel
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from zoneinfo import ZoneInfo
|
|||||||
|
|
||||||
from ....utils.exception import FallbackError
|
from ....utils.exception import FallbackError
|
||||||
from ....utils.render.schemas.tetrio.user.base import TetraLeagueHistoryData
|
from ....utils.render.schemas.tetrio.user.base import TetraLeagueHistoryData
|
||||||
from ..api.schemas.labs.leagueflow import LeagueFlowSuccess
|
from ..api.schemas.labs.leagueflow import Empty, LeagueFlowSuccess
|
||||||
from ..api.schemas.summaries.league import LeagueSuccessModel, NeverPlayedData, NeverRatedData, RatedData
|
from ..api.schemas.summaries.league import LeagueSuccessModel, NeverPlayedData, NeverRatedData, RatedData
|
||||||
|
|
||||||
|
|
||||||
@@ -13,6 +13,8 @@ def flow_to_history(
|
|||||||
leagueflow: LeagueFlowSuccess,
|
leagueflow: LeagueFlowSuccess,
|
||||||
handle: Callable[[list[TetraLeagueHistoryData]], list[TetraLeagueHistoryData]] | None = None,
|
handle: Callable[[list[TetraLeagueHistoryData]], list[TetraLeagueHistoryData]] | None = None,
|
||||||
) -> list[TetraLeagueHistoryData]:
|
) -> list[TetraLeagueHistoryData]:
|
||||||
|
if isinstance(leagueflow.data, Empty):
|
||||||
|
raise FallbackError
|
||||||
start_time = leagueflow.data.start_time.astimezone(ZoneInfo('Asia/Shanghai'))
|
start_time = leagueflow.data.start_time.astimezone(ZoneInfo('Asia/Shanghai'))
|
||||||
ret = [
|
ret = [
|
||||||
TetraLeagueHistoryData(
|
TetraLeagueHistoryData(
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from hashlib import md5
|
|||||||
|
|
||||||
from yarl import URL
|
from yarl import URL
|
||||||
|
|
||||||
|
from ....utils.exception import FallbackError
|
||||||
from ....utils.host import HostPage, get_self_netloc
|
from ....utils.host import HostPage, get_self_netloc
|
||||||
from ....utils.metrics import get_metrics
|
from ....utils.metrics import get_metrics
|
||||||
from ....utils.render import render
|
from ....utils.render import render
|
||||||
@@ -49,89 +50,89 @@ async def make_query_image_v2(player: Player) -> bytes:
|
|||||||
play_time = f'{game_time:.0f}s'
|
play_time = f'{game_time:.0f}s'
|
||||||
else:
|
else:
|
||||||
play_time = game_time
|
play_time = game_time
|
||||||
|
try:
|
||||||
|
history = flow_to_history(leagueflow, lambda x: x[-100:])
|
||||||
|
except FallbackError:
|
||||||
|
history = None
|
||||||
netloc = get_self_netloc()
|
netloc = get_self_netloc()
|
||||||
async with (
|
async with HostPage(
|
||||||
HostPage(
|
await render(
|
||||||
await render(
|
'v2/tetrio/user/info',
|
||||||
'v2/tetrio/user/info',
|
Info(
|
||||||
Info(
|
user=User(
|
||||||
user=User(
|
id=user.ID,
|
||||||
id=user.ID,
|
name=user.name.upper(),
|
||||||
name=user.name.upper(),
|
bio=user_info.data.bio,
|
||||||
bio=user_info.data.bio,
|
banner=str(
|
||||||
banner=str(
|
URL(f'http://{netloc}/host/resource/tetrio/banners/{user.ID}') % {'revision': banner_revision}
|
||||||
URL(f'http://{netloc}/host/resource/tetrio/banners/{user.ID}')
|
)
|
||||||
% {'revision': banner_revision}
|
if banner_revision is not None and banner_revision != 0
|
||||||
)
|
else None,
|
||||||
if banner_revision is not None and banner_revision != 0
|
avatar=str(
|
||||||
else None,
|
URL(f'http://{netloc}/host/resource/tetrio/avatars/{user.ID}') % {'revision': avatar_revision}
|
||||||
avatar=str(
|
)
|
||||||
URL(f'http://{netloc}/host/resource/tetrio/avatars/{user.ID}')
|
if avatar_revision is not None and avatar_revision != 0
|
||||||
% {'revision': avatar_revision}
|
else Avatar(
|
||||||
)
|
type='identicon',
|
||||||
if avatar_revision is not None and avatar_revision != 0
|
hash=md5(user.ID.encode()).hexdigest(), # noqa: S324
|
||||||
else Avatar(
|
|
||||||
type='identicon',
|
|
||||||
hash=md5(user.ID.encode()).hexdigest(), # noqa: S324
|
|
||||||
),
|
|
||||||
badges=[
|
|
||||||
Badge(
|
|
||||||
id=i.id,
|
|
||||||
description=i.label,
|
|
||||||
group=i.group,
|
|
||||||
receive_at=i.ts if isinstance(i.ts, datetime) else None,
|
|
||||||
)
|
|
||||||
for i in user_info.data.badges
|
|
||||||
],
|
|
||||||
country=user_info.data.country,
|
|
||||||
role=user_info.data.role,
|
|
||||||
xp=user_info.data.xp,
|
|
||||||
friend_count=user_info.data.friend_count,
|
|
||||||
supporter_tier=user_info.data.supporter_tier,
|
|
||||||
bad_standing=user_info.data.badstanding or False,
|
|
||||||
playtime=play_time,
|
|
||||||
join_at=user_info.data.ts,
|
|
||||||
),
|
),
|
||||||
tetra_league=TetraLeague(
|
badges=[
|
||||||
rank=league.data.rank,
|
Badge(
|
||||||
highest_rank='z' if isinstance(league.data, NeverRatedData) else league.data.bestrank,
|
id=i.id,
|
||||||
tr=round(league.data.tr, 2),
|
description=i.label,
|
||||||
glicko=round(league.data.glicko, 2),
|
group=i.group,
|
||||||
rd=round(league.data.rd, 2),
|
receive_at=i.ts if isinstance(i.ts, datetime) else None,
|
||||||
global_rank=league.data.standing,
|
)
|
||||||
country_rank=league.data.standing_local,
|
for i in user_info.data.badges
|
||||||
pps=(metrics := get_metrics(pps=league.data.pps, apm=league.data.apm, vs=league.data.vs)).pps,
|
],
|
||||||
apm=metrics.apm,
|
country=user_info.data.country,
|
||||||
apl=metrics.apl,
|
role=user_info.data.role,
|
||||||
vs=metrics.vs,
|
xp=user_info.data.xp,
|
||||||
adpl=metrics.adpl,
|
friend_count=user_info.data.friend_count,
|
||||||
statistic=TetraLeagueStatistic(total=league.data.gamesplayed, wins=league.data.gameswon),
|
supporter_tier=user_info.data.supporter_tier,
|
||||||
decaying=league.data.decaying,
|
bad_standing=user_info.data.badstanding or False,
|
||||||
history=flow_to_history(leagueflow, lambda x: x[-100:]),
|
playtime=play_time,
|
||||||
)
|
join_at=user_info.data.ts,
|
||||||
if not isinstance(league.data, NeverPlayedData)
|
|
||||||
else None,
|
|
||||||
statistic=Statistic(
|
|
||||||
total=handling_special_value(user_info.data.gamesplayed),
|
|
||||||
wins=handling_special_value(user_info.data.gameswon),
|
|
||||||
),
|
|
||||||
sprint=Sprint(
|
|
||||||
time=sprint_value,
|
|
||||||
global_rank=sprint.data.rank,
|
|
||||||
play_at=sprint.data.record.ts,
|
|
||||||
)
|
|
||||||
if sprint.data.record is not None
|
|
||||||
else None,
|
|
||||||
blitz=Blitz(
|
|
||||||
score=blitz.data.record.results.stats.score,
|
|
||||||
global_rank=blitz.data.rank,
|
|
||||||
play_at=blitz.data.record.ts,
|
|
||||||
)
|
|
||||||
if blitz.data.record is not None
|
|
||||||
else None,
|
|
||||||
zen=Zen(level=zen.data.level, score=zen.data.score),
|
|
||||||
),
|
),
|
||||||
|
tetra_league=TetraLeague(
|
||||||
|
rank=league.data.rank,
|
||||||
|
highest_rank='z' if isinstance(league.data, NeverRatedData) else league.data.bestrank,
|
||||||
|
tr=round(league.data.tr, 2),
|
||||||
|
glicko=round(league.data.glicko, 2),
|
||||||
|
rd=round(league.data.rd, 2),
|
||||||
|
global_rank=league.data.standing,
|
||||||
|
country_rank=league.data.standing_local,
|
||||||
|
pps=(metrics := get_metrics(pps=league.data.pps, apm=league.data.apm, vs=league.data.vs)).pps,
|
||||||
|
apm=metrics.apm,
|
||||||
|
apl=metrics.apl,
|
||||||
|
vs=metrics.vs,
|
||||||
|
adpl=metrics.adpl,
|
||||||
|
statistic=TetraLeagueStatistic(total=league.data.gamesplayed, wins=league.data.gameswon),
|
||||||
|
decaying=league.data.decaying,
|
||||||
|
history=history,
|
||||||
|
)
|
||||||
|
if not isinstance(league.data, NeverPlayedData)
|
||||||
|
else None,
|
||||||
|
statistic=Statistic(
|
||||||
|
total=handling_special_value(user_info.data.gamesplayed),
|
||||||
|
wins=handling_special_value(user_info.data.gameswon),
|
||||||
|
),
|
||||||
|
sprint=Sprint(
|
||||||
|
time=sprint_value,
|
||||||
|
global_rank=sprint.data.rank,
|
||||||
|
play_at=sprint.data.record.ts,
|
||||||
|
)
|
||||||
|
if sprint.data.record is not None
|
||||||
|
else None,
|
||||||
|
blitz=Blitz(
|
||||||
|
score=blitz.data.record.results.stats.score,
|
||||||
|
global_rank=blitz.data.rank,
|
||||||
|
play_at=blitz.data.record.ts,
|
||||||
|
)
|
||||||
|
if blitz.data.record is not None
|
||||||
|
else None,
|
||||||
|
zen=Zen(level=zen.data.level, score=zen.data.score),
|
||||||
),
|
),
|
||||||
) as page_hash
|
),
|
||||||
):
|
) as page_hash:
|
||||||
return await screenshot(f'http://{netloc}/host/{page_hash}.html')
|
return await screenshot(f'http://{netloc}/host/{page_hash}.html')
|
||||||
|
|||||||
Reference in New Issue
Block a user